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