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