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