00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef VCSN_ALGORITHMS_DETERMINIZE_HXX
00018 # define VCSN_ALGORITHMS_DETERMINIZE_HXX
00019
00020 # include <map>
00021 # include <set>
00022 # include <queue>
00023 # include <vaucanson/misc/usual_macros.hh>
00024 # include <vaucanson/automata/concept/automata_base.hh>
00025
00026 # ifndef VCSN_NDEBUG
00027 # include <vaucanson/algorithms/realtime.hh>
00028 # endif // ! VCSN_NDEBUG
00029
00030 namespace vcsn {
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 template <typename A, typename input_t, typename output_t>
00043 void
00044 do_subset_construction(const AutomataBase<A>& ,
00045 output_t& output,
00046 const input_t& input,
00047 std::map<typename output_t::hstate_t,
00048 std::set<typename input_t::hstate_t> >& m =
00049 std::map<typename output_t::hstate_t,
00050 std::set<typename input_t::hstate_t> >())
00051 {
00052
00053
00054
00055
00056
00057 AUTOMATON_TYPES(input_t);
00058 AUTOMATON_FREEMONOID_TYPES(input_t);
00059 typedef typename std::set<typename input_t::hstate_t> subset_t;
00060 typedef typename std::map<subset_t, typename output_t::hstate_t>
00061 subset_set_t;
00062 typedef std::pair<subset_t, typename output_t::hstate_t> subset_set_pair_t;
00063 typedef std::vector<typename input_t::hstate_t> delta_ret_t;
00064
00065
00066
00067
00068
00069
00070 typename output_t::hstate_t qi_hstate = output.add_state();
00071 subset_t qi;
00072 bool is_final = false;
00073 for_all_const_initial_states(i, input)
00074 {
00075 qi.insert(*i);
00076 is_final |= input.is_final(*i);
00077 }
00078 output.set_initial(qi_hstate);
00079
00080 if (is_final)
00081 output.set_final(qi_hstate);
00082
00083 subset_set_t subset_set;
00084 subset_set[qi] = qi_hstate;
00085 m[qi_hstate] = qi;
00086
00087
00088
00089
00090
00091
00092 subset_t q;
00093 const alphabet_t& alphabet(input.structure().series().monoid().alphabet());
00094 delta_ret_t dst;
00095 dst.reserve(input.states().size());
00096 std::queue<subset_t> path;
00097 path.push(qi);
00098 while (!path.empty())
00099 {
00100 subset_t s = path.front();
00101 typename input_t::hstate_t s_hstate = subset_set[s];
00102 path.pop();
00103
00104 for_all_const_letters(e, alphabet)
00105 {
00106 q.clear ();
00107 bool is_final = false;
00108 for_all_const_ (subset_t, j, s)
00109 {
00110 std::list<hstate_t> st;
00111 input.letter_deltac(st, *j, *e, delta_kind::states());
00112 for (typename std::list<hstate_t>::const_iterator s = st.begin(); s != st.end(); ++s)
00113 {
00114 q.insert(*s);
00115 is_final |= input.is_final(*s);
00116 }
00117 }
00118 typename subset_set_t::const_iterator current = subset_set.find(q);
00119 if (current == subset_set.end())
00120 {
00121 typename output_t::hstate_t qs = output.add_state();
00122 current = (subset_set.insert(subset_set_pair_t(q, qs))).first;
00123 m[qs] = q;
00124
00125 if (is_final)
00126 output.set_final(current->second);
00127 path.push(q);
00128 }
00129 output.add_letter_transition(s_hstate, (*current).second, *e);
00130 }
00131 }
00132 }
00133
00134 template<typename A, typename AI>
00135 Element<A, AI>
00136 subset_construction(const Element<A, AI>& a)
00137 {
00138 Element<A, AI> res(a.structure());
00139 do_subset_construction(res.structure(), res, a);
00140 return res;
00141 }
00142
00143
00144
00145
00146 template <typename A, typename AI>
00147 void
00148 do_determinize(const AutomataBase<A>& a_set,
00149 Element<A, AI>& output,
00150 const Element<A, AI>& input,
00151 std::map<typename Element<A, AI>::hstate_t,
00152 std::set<typename Element<A, AI>::hstate_t> >& m)
00153 {
00154 TIMER_SCOPED ("determinize");
00155 precondition(is_realtime(input));
00156 do_subset_construction(a_set, output, input, m);
00157 }
00158
00159 template<typename A, typename AI>
00160 Element<A, AI>
00161 determinize(const Element<A, AI>& a,
00162 std::map<typename Element<A, AI>::hstate_t,
00163 std::set<typename Element<A, AI>::hstate_t> >& m)
00164 {
00165 Element<A, AI> ret(a.structure());
00166 do_determinize(ret.structure(), ret, a, m);
00167 return ret;
00168 }
00169
00170 template<typename A, typename AI>
00171 Element<A, AI>
00172 determinize(const Element<A, AI>& a)
00173 {
00174 std::map<typename Element<A, AI>::hstate_t,
00175 std::set<typename Element<A, AI>::hstate_t> > m;
00176 return determinize(a, m);
00177 }
00178
00179 }
00180
00181 #endif // ! VCSN_ALGORITHMS_DETERMINIZE_HXX