00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef VCSN_ALGORITHMS_MINIMIZATION_MOORE_HXX
00018 # define VCSN_ALGORITHMS_MINIMIZATION_MOORE_HXX
00019
00020 # include <vaucanson/algorithms/minimization_moore.hh>
00021 # include <vaucanson/algorithms/complete.hh>
00022 # include <vaucanson/algorithms/transpose.hh>
00023
00024 # ifndef VCSN_NDEBUG
00025 # include <vaucanson/algorithms/is_deterministic.hh>
00026 # endif // ! VCSN_NDEBUG
00027
00028 # include <vaucanson/automata/concept/handlers.hh>
00029 # include <vaucanson/automata/concept/delta_kind.hh>
00030 # include <vaucanson/misc/usual_macros.hh>
00031 # include <vaucanson/misc/contract.hh>
00032
00033 # include <map>
00034 # include <set>
00035 # include <vector>
00036
00037
00038
00039
00040 # define for_all_groups(I, P) \
00041 for (typename groupid_to_group_t::iterator I = ((P).begin()); I != (P).end(); ++I)
00042
00043
00044
00045 # define for_all_state_in_groups(I, P) \
00046 for (typename group_t::iterator I = ++((P).begin()); I != (P).end(); ++I)
00047
00048 namespace vcsn {
00049
00050
00051
00052
00053
00054
00055 template<typename A, typename AI, bool Transposed>
00056 void
00057 do_minimization_moore(const Element<A, AI>& input, Element<A, AI>& output)
00058 {
00059 BENCH_TASK_SCOPED("minimization_moore");
00060 typedef Element<A, AI> automaton_t;
00061 AUTOMATON_TYPES(automaton_t);
00062 AUTOMATON_FREEMONOID_TYPES(automaton_t);
00063 using std::map;
00064 using std::vector;
00065 using std::set;
00066
00067
00068
00069 const hstate_t NullState;
00070 const hstate_t NullGroup;
00071 const alphabet_t& alphabet (input.series().monoid().alphabet());
00072
00073
00074
00075 typedef int letterid_t;
00076 typedef int groupid_t;
00077
00078 typedef set<hstate_t> group_t;
00079 typedef vector<group_t> groupid_to_group_t;
00080
00081 typedef vector<hstate_t> letterid_to_state_t;
00082
00083 typedef map<hstate_t, letterid_to_state_t> state_to_letterid_to_state_t;
00084
00085 typedef map<hstate_t, groupid_t> state_to_groupid_t;
00086 typedef map<letter_t, letterid_t> letter_to_letterid_t;
00087
00088
00089
00090
00091
00092 precondition(input.exists());
00093
00094 groupid_to_group_t groupid_to_group(input.states().size());
00095
00096 state_to_groupid_t state_to_groupid;
00097 state_to_groupid[NullState] = NullGroup;
00098
00099 letter_to_letterid_t letter_to_letterid;
00100 int letter_count = 0;
00101 for_all_const_letters(iletter, alphabet)
00102 letter_to_letterid[*iletter] = letter_count++;
00103
00104 state_to_letterid_to_state_t aut_view;
00105 for_all_const_states(istate, input)
00106 {
00107 aut_view[*istate] = letterid_to_state_t(letter_count, NullState);
00108 if ((not Transposed and input.is_final(*istate)) or
00109 (Transposed and input.is_initial(*istate)))
00110 {
00111 groupid_to_group[0].insert(*istate);
00112 state_to_groupid[*istate] = 0;
00113 }
00114 else
00115 {
00116 groupid_to_group[1].insert(*istate);
00117 state_to_groupid[*istate] = 1;
00118 }
00119 }
00120
00121 for_all_const_states(istate, input)
00122 {
00123 for_all_const_(letter_to_letterid_t, iletter, letter_to_letterid)
00124 {
00125 bool empty = true;
00126 hstate_t first;
00127 if (not Transposed)
00128 {
00129 for (delta_iterator t(input.value(), *istate);
00130 ! t.done() && empty;
00131 t.next())
00132 {
00133 monoid_elt_t w(input.series_of(*t).structure().monoid(), iletter->first);
00134 if (input.series_of(*t).get(w) != input.series().semiring().wzero_)
00135 {
00136 empty = false;
00137 first = input.dst_of(*t);
00138 break;
00139 }
00140 }
00141 }
00142 else
00143 {
00144 for (rdelta_iterator t(input.value(), *istate);
00145 ! t.done() && empty;
00146 t.next())
00147 {
00148 monoid_elt_t w(input.series_of(*t).structure().monoid(), iletter->first);
00149 if (input.series_of(*t).get(w) != input.series().semiring().wzero_)
00150 {
00151 empty = false;
00152 first = input.src_of(*t);
00153 break;
00154 }
00155 }
00156 }
00157 if (not empty)
00158 aut_view[*istate][iletter->second] = first;
00159 }
00160 }
00161
00162
00163
00164
00165
00166
00167 int last_group = 1;
00168 for (bool group_modified = true; group_modified;)
00169 {
00170 group_modified = false;
00171 for_all_groups(igroup, groupid_to_group)
00172 {
00173 if (igroup->empty())
00174 break;
00175
00176 hstate_t first_state = *(igroup->begin());
00177 bool group_created = false;
00178
00179 for_all_state_in_groups(istate, *igroup)
00180 {
00181 int i;
00182 for (i = 0; i < letter_count; ++i)
00183 if (state_to_groupid[aut_view[first_state][i]] !=
00184 state_to_groupid[aut_view[*istate][i]])
00185 break;
00186 if (i != letter_count)
00187 {
00188 typename group_t::iterator istate_save = istate;
00189
00190 istate_save--;
00191 if (group_created == false)
00192 {
00193 last_group++;
00194 group_created = true;
00195 group_modified = true;
00196 }
00197 groupid_to_group[last_group].insert(*istate);
00198 state_to_groupid[*istate] = last_group;
00199 igroup->erase(*istate);
00200 istate = istate_save;
00201 }
00202 }
00203 }
00204 }
00205
00206
00207
00208
00209
00210
00211 std::vector<hstate_t> new_states(last_group + 1);
00212
00213
00214 for (int i = 0; i <= last_group; ++i)
00215 new_states[i] = output.add_state();
00216
00217
00218 for (int i = 0; i <= last_group; ++i)
00219 {
00220 hstate_t repres = *(groupid_to_group[i].begin());
00221
00222 for_all_const_(letter_to_letterid_t, iletter, letter_to_letterid)
00223 if (aut_view[repres][iletter->second] != NullState)
00224 {
00225 if (not Transposed)
00226 output.add_letter_transition(new_states[i],
00227 new_states[state_to_groupid
00228 [aut_view[repres]
00229 [iletter->second]]],
00230 iletter->first);
00231 else
00232 output.add_letter_transition(new_states[state_to_groupid
00233 [aut_view[repres]
00234 [iletter->second]]],
00235 new_states[i],
00236 iletter->first);
00237 }
00238 }
00239
00240
00241 if (not Transposed)
00242 {
00243 output.set_final(new_states[0]);
00244 output.set_initial(new_states[state_to_groupid[*input.initial().begin()]]);
00245 }
00246 else
00247 {
00248 output.set_initial(new_states[0]);
00249 output.set_final(new_states[state_to_groupid[*input.final().begin()]]);
00250 }
00251
00252 }
00253
00254
00255 template<typename A, typename AI>
00256 void
00257 minimization_moore_here(Element<A, AI>& a)
00258 {
00259 precondition(is_deterministic(a));
00260 precondition(is_complete(a));
00261 Element<A, AI> output(a.structure());
00262 do_minimization_moore<A, AI, false>(a, output);
00263 a = output;
00264 }
00265
00266
00267 template<typename A, typename AI>
00268 Element<A, AI>
00269 minimization_moore(const Element<A, AI>& a)
00270 {
00271 precondition(is_deterministic(a));
00272 precondition(is_complete(a));
00273 Element<A, AI> output(a.structure());
00274 do_minimization_moore<A, AI, false>(a, output);
00275 return output;
00276 }
00277
00278 template<typename A, typename AI>
00279 void
00280 co_minimization_moore_here(Element<A, AI>& a)
00281 {
00282 precondition(is_deterministic(transpose(a)));
00283 precondition(is_complete(transpose(a)));
00284 Element<A, AI> output(a.structure());
00285 do_minimization_moore<A, AI, true>(a, output);
00286 a = output;
00287 }
00288
00289
00290 template<typename A, typename AI>
00291 Element<A, AI>
00292 co_minimization_moore(const Element<A, AI>& a)
00293 {
00294 precondition(is_deterministic(transpose(a)));
00295 precondition(is_complete(transpose(a)));
00296 Element<A, AI> output(a.structure());
00297 do_minimization_moore<A, AI, true>(a, output);
00298 return output;
00299 }
00300
00301 }
00302
00303
00304 # undef for_all_groups
00305 # undef for_all_state_in_groups
00306
00307
00308 #endif // ! VCSN_ALGORITHMS_MINIMIZATION_MOORE_HXX