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