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 TIMER_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 group_t delta_ret;
00122 for_all_const_states(istate, input)
00123 {
00124 for_all_const_(letter_to_letterid_t, iletter, letter_to_letterid)
00125 {
00126 delta_ret.clear ();
00127 if (not Transposed)
00128 input.letter_deltac(delta_ret, *istate, iletter->first,
00129 delta_kind::states());
00130 else
00131 input.letter_rdeltac(delta_ret, *istate, iletter->first,
00132 delta_kind::states());
00133 if (not delta_ret.empty())
00134 aut_view[*istate][iletter->second] = *delta_ret.begin();
00135 }
00136 }
00137
00138
00139
00140
00141
00142
00143 int last_group = 1;
00144 for (bool group_modified = true; group_modified;)
00145 {
00146 group_modified = false;
00147 for_all_groups(igroup, groupid_to_group)
00148 {
00149 if (igroup->empty())
00150 break;
00151
00152 hstate_t first_state = *(igroup->begin());
00153 bool group_created = false;
00154
00155 for_all_state_in_groups(istate, *igroup)
00156 {
00157 int i;
00158 for (i = 0; i < letter_count; ++i)
00159 if (state_to_groupid[aut_view[first_state][i]] !=
00160 state_to_groupid[aut_view[*istate][i]])
00161 break;
00162 if (i != letter_count)
00163 {
00164 typename group_t::iterator istate_save = istate;
00165
00166 istate_save--;
00167 if (group_created == false)
00168 {
00169 last_group++;
00170 group_created = true;
00171 group_modified = true;
00172 }
00173 groupid_to_group[last_group].insert(*istate);
00174 state_to_groupid[*istate] = last_group;
00175 igroup->erase(*istate);
00176 istate = istate_save;
00177 }
00178 }
00179 }
00180 }
00181
00182
00183
00184
00185
00186
00187 std::vector<hstate_t> new_states(last_group + 1);
00188
00189
00190 for (int i = 0; i <= last_group; ++i)
00191 new_states[i] = output.add_state();
00192
00193
00194 for (int i = 0; i <= last_group; ++i)
00195 {
00196 hstate_t repres = *(groupid_to_group[i].begin());
00197
00198 for_all_const_(letter_to_letterid_t, iletter, letter_to_letterid)
00199 if (aut_view[repres][iletter->second] != NullState)
00200 {
00201 if (not Transposed)
00202 output.add_letter_transition(new_states[i],
00203 new_states[state_to_groupid
00204 [aut_view[repres]
00205 [iletter->second]]],
00206 iletter->first);
00207 else
00208 output.add_letter_transition(new_states[state_to_groupid
00209 [aut_view[repres]
00210 [iletter->second]]],
00211 new_states[i],
00212 iletter->first);
00213 }
00214 }
00215
00216
00217 if (not Transposed)
00218 {
00219 output.set_final(new_states[0]);
00220 output.set_initial(new_states[state_to_groupid[*input.initial().begin()]]);
00221 }
00222 else
00223 {
00224 output.set_initial(new_states[0]);
00225 output.set_final(new_states[state_to_groupid[*input.final().begin()]]);
00226 }
00227
00228 }
00229
00230
00231 template<typename A, typename AI>
00232 void
00233 minimization_moore_here(Element<A, AI>& a)
00234 {
00235 precondition(is_deterministic(a));
00236 precondition(is_complete(a));
00237 Element<A, AI> output(a.structure());
00238 do_minimization_moore<A, AI, false>(a, output);
00239 a = output;
00240 }
00241
00242
00243 template<typename A, typename AI>
00244 Element<A, AI>
00245 minimization_moore(const Element<A, AI>& a)
00246 {
00247 precondition(is_deterministic(a));
00248 precondition(is_complete(a));
00249 Element<A, AI> output(a.structure());
00250 do_minimization_moore<A, AI, false>(a, output);
00251 return output;
00252 }
00253
00254 template<typename A, typename AI>
00255 void
00256 co_minimization_moore_here(Element<A, AI>& a)
00257 {
00258 precondition(is_deterministic(transpose(a)));
00259 precondition(is_complete(transpose(a)));
00260 Element<A, AI> output(a.structure());
00261 do_minimization_moore<A, AI, true>(a, output);
00262 a = output;
00263 }
00264
00265
00266 template<typename A, typename AI>
00267 Element<A, AI>
00268 co_minimization_moore(const Element<A, AI>& a)
00269 {
00270 precondition(is_deterministic(transpose(a)));
00271 precondition(is_complete(transpose(a)));
00272 Element<A, AI> output(a.structure());
00273 do_minimization_moore<A, AI, true>(a, output);
00274 return output;
00275 }
00276
00277 }
00278
00279
00280 # undef for_all_groups
00281 # undef for_all_state_in_groups
00282
00283
00284 #endif // ! VCSN_ALGORITHMS_MINIMIZATION_MOORE_HXX