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