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