00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef VCSN_ALGORITHMS_AUT_TO_EXP_HXX
00018 # define VCSN_ALGORITHMS_AUT_TO_EXP_HXX
00019
00020 # include <vaucanson/algorithms/aut_to_exp.hh>
00021
00022 # include <vaucanson/automata/concept/handlers.hh>
00023 # include <vaucanson/algorithms/normalized.hh>
00024 # include <vaucanson/misc/usual_macros.hh>
00025 # include <vaucanson/misc/contract.hh>
00026 # include <vaucanson/misc/limits.hh>
00027 # include <vaucanson/misc/random.hh>
00028 # include <vaucanson/automata/concept/automata_base.hh>
00029
00030 # include <list>
00031 # include <set>
00032 # include <vector>
00033
00034 # include <stdlib.h>
00035 # include <time.h>
00036
00037 namespace vcsn {
00038
00039
00040
00041
00042
00043 template <class Auto_>
00044 typename Auto_::hstate_t
00045 DefaultChooser::operator()(const Auto_& a) const
00046 {
00047 assertion(a.states().size() > 0);
00048 typename Auto_::state_iterator s = a.states().begin();
00049 typename Auto_::state_iterator k = s;
00050 while ((k != a.states().end()) &&
00051 ((a.is_initial(*k)) || (a.is_final(*k))))
00052 ++k;
00053 s = k;
00054 return *s;
00055 }
00056
00057
00058
00059
00060
00061 template <class Auto_>
00062 typename Auto_::hstate_t
00063 RandomChooser::operator()(const Auto_& a) const
00064 {
00065 assertion(a.states().size() > 0);
00066
00067 int n_init = 0;
00068 int n_final = 0;
00069 for (typename Auto_::state_iterator i = a.states().begin();
00070 i != a.states().end();
00071 ++i)
00072 {
00073 if (a.is_initial(*i))
00074 ++n_init;
00075 if (a.is_final(*i))
00076 ++n_final;
00077 }
00078
00079 unsigned n = misc::random::generate((unsigned) 0,
00080 a.states().size() -
00081 (n_init + n_final));
00082
00083 typename Auto_::state_iterator k = a.states().begin();
00084 unsigned kk = 0;
00085 while (kk <= n || k == a.states().end() ||
00086 ((a.is_initial(*k)) || (a.is_final(*k))))
00087 {
00088 if (k == a.states().end())
00089 {
00090 k = a.states().begin();
00091 continue;
00092 }
00093 ++k;
00094 ++kk;
00095 }
00096 return *k;
00097 }
00098
00099
00100
00101
00102
00103
00104 template <class Auto_>
00105 typename Auto_::hstate_t
00106 HChooser::operator()(const Auto_& a) const
00107 {
00108 assertion(a.states().size() > 0);
00109
00110 std::list<typename Auto_::htransition_t> delta_in;
00111 std::list<typename Auto_::htransition_t> delta_out;
00112
00113 typename Auto_::state_iterator s = a.states().begin();
00114 unsigned int d_in = 0;
00115 unsigned int d_out = 0;
00116 unsigned int max = misc::limits<unsigned int>::max();
00117 bool has_loop = false;
00118 bool has_loop_old = false;
00119
00120 for (typename Auto_::state_iterator i = a.states().begin();
00121 i != a.states().end();
00122 ++i)
00123 {
00124 if (a.is_final(*i) || a.is_initial(*i))
00125 continue;
00126 has_loop = false;
00127
00128 for (typename Auto_::delta_iterator j(a.value(), *i);
00129 ! j.done();
00130 j.next())
00131 delta_out.push_back(*j);
00132 for (typename Auto_::rdelta_iterator j(a.value(), *i);
00133 ! j.done();
00134 j.next())
00135 delta_in.push_back(*j);
00136 for (typename std::list<typename Auto_::htransition_t>::iterator j = delta_out.begin();
00137 j != delta_out.end();
00138 ++j)
00139 if (*i == a.dst_of(*j))
00140 has_loop = true;
00141
00142
00143 if (has_loop)
00144 d_in = delta_in.size() - 1;
00145 else
00146 d_in = delta_in.size();
00147 d_out = delta_out.size();
00148
00149
00150 if (d_in * d_out < max ||
00151 (d_in * d_out == max &&
00152 has_loop_old && not has_loop))
00153 {
00154 s = i;
00155 max = d_in * d_out;
00156 has_loop_old = has_loop;
00157 }
00158 delta_out.clear();
00159 delta_in.clear();
00160 }
00161 return *s;
00162 }
00163
00164
00165
00166
00167
00168
00169
00170 template <class Auto_>
00171 typename Auto_::hstate_t
00172 DMChooser::operator()(const Auto_& a) const
00173 {
00174 assertion(a.states().size() > 0);
00175
00176 std::list<typename Auto_::htransition_t> delta_in;
00177 std::list<typename Auto_::htransition_t> delta_out;
00178 typename Auto_::state_iterator s = a.states().begin();
00179
00180 int weight_min = misc::limits<int>::max();
00181 for (typename Auto_::state_iterator i = a.states().begin();
00182 i != a.states().end();
00183 ++i)
00184 {
00185 if (a.is_final(*i) || a.is_initial(*i))
00186 continue;
00187 unsigned int n_loops = 0;
00188 unsigned int in = 0;
00189 unsigned int out = 0;
00190
00191 int weight = 0;
00192
00193 delta_in.clear();
00194 delta_out.clear();
00195 for (typename Auto_::delta_iterator j(a.value(), *i);
00196 ! j.done();
00197 j.next())
00198 delta_out.push_back(*j);
00199 for (typename Auto_::rdelta_iterator j(a.value(), *i);
00200 ! j.done();
00201 j.next())
00202 delta_in.push_back(*j);
00203
00204 for (typename std::list<typename Auto_::htransition_t>::iterator j = delta_out.begin();
00205 j != delta_out.end();
00206 ++j)
00207 if (*i == a.dst_of(*j))
00208 ++n_loops;
00209
00210 in = delta_in.size() - n_loops;
00211 out = delta_out.size() - n_loops;
00212
00213
00214 for (typename std::list<typename Auto_::htransition_t>::iterator j = delta_in.begin();
00215 j != delta_in.end();
00216 ++j)
00217 if (*i != a.dst_of(*j))
00218 {
00219 weight += a.series_value_of(*j).length() * (out - 1);
00220 }
00221
00222
00223 for (typename std::list<typename Auto_::htransition_t>::iterator j = delta_out.begin();
00224 j != delta_out.end();
00225 ++j)
00226 if (*i != a.dst_of(*j))
00227 {
00228 weight += a.series_value_of(*j).length() * (in - 1);
00229 }
00230
00231
00232 for (typename std::list<typename Auto_::htransition_t>::iterator j = delta_out.begin();
00233 j != delta_out.end();
00234 ++j)
00235 if (*i == a.dst_of(*j))
00236 {
00237 weight += a.series_value_of(*j).length() * (in * out - 1);
00238 }
00239
00240 if (weight < weight_min)
00241 {
00242 s = i;
00243 weight_min = weight;
00244 }
00245 }
00246 return *s;
00247 }
00248
00249
00250
00251
00252
00253 inline ListChooser::ListChooser(const std::list<unsigned int>& l) :
00254 list_(l),
00255 pos_(l.begin())
00256 {
00257 }
00258
00259 template <class Auto_>
00260 typename Auto_::hstate_t
00261 ListChooser::operator() (const Auto_& a)
00262 {
00263 assertion(pos_ != list_.end());
00264 return a.get_state(*pos_++);
00265 }
00266
00267
00268
00269
00270
00271 template <class A, typename AI, typename Chooser>
00272 typename Element<A, AI>::series_set_elt_t
00273 do_in_aut_to_exp(const AutomataBase<A>& a_set,
00274 Element<A, AI>& a,
00275 Chooser chooser)
00276 {
00277 typedef Element<A, AI> automaton_t;
00278 AUTOMATON_TYPES(automaton_t);
00279 typedef typename automaton_t::series_set_t series_set_t;
00280 typedef typename automaton_t::series_set_elt_t series_set_elt_t;
00281
00282 typedef typename std::list<htransition_t> htransition_set_t;
00283 typedef std::map<hstate_t, series_set_elt_t> sums_t;
00284
00285 typename htransition_set_t::const_iterator i, j;
00286 hstate_t q;
00287 htransition_set_t transitions;
00288 std::list<htransition_t> transitions_to_remove;
00289 normalize_here(a);
00290
00291
00292 while (a.states().size() != 2)
00293 {
00294 series_set_elt_t loop_sum(a_set.series());
00295 sums_t in_sums, out_sums;
00296
00297 q = chooser(a);
00298 if (a.is_initial(q) || a.is_final(q))
00299 continue;
00300
00301 transitions.clear();
00302 for (delta_iterator e(a.value(), q); ! e.done(); e.next())
00303 transitions.push_back(*e);
00304 for (i = transitions.begin(); i != transitions.end(); i = j)
00305 {
00306 j = i; ++j;
00307
00308 if (a.dst_of(*i) == q)
00309 loop_sum += a.series_of(*i);
00310 else
00311 {
00312 typename sums_t::iterator f = out_sums.find(a.dst_of(*i));
00313 if (f == out_sums.end())
00314 f = out_sums.insert
00315 (std::make_pair(a.dst_of(*i),
00316 series_set_elt_t(a_set.series()))).first;
00317 f->second += a.series_of(*i);
00318 }
00319 a.del_transition(*i);
00320 }
00321 transitions.clear();
00322 for (rdelta_iterator e(a.value(), q); ! e.done(); e.next())
00323 transitions.push_back(*e);
00324 for (i = transitions.begin(); i != transitions.end(); i = j)
00325 {
00326 j = i; ++j;
00327
00328 typename sums_t::iterator f = in_sums.find(a.src_of(*i));
00329 if (f == in_sums.end())
00330 f = in_sums.insert
00331 (std::make_pair(a.src_of(*i),
00332 series_set_elt_t(a_set.series()))).first;
00333
00334 f->second += a.series_of(*i);
00335 a.del_transition(*i);
00336 }
00337 loop_sum.star();
00338
00339 for_all_const_(sums_t, in, in_sums)
00340 for_all_const_(sums_t, out, out_sums)
00341 {
00342 series_set_elt_t res = in->second * loop_sum * out->second;
00343 a.add_series_transition(in->first, out->first, res);
00344 }
00345 a.del_state(q);
00346 }
00347 series_set_elt_t final(a_set.series());
00348 for_all_const_transitions(i, a)
00349 final += a.label_of(*i);
00350 return final;
00351 }
00352
00353
00354
00355
00356
00357 template<typename A, typename AI, typename Chooser>
00358 typename Element<A, AI>::series_set_elt_t
00359 aut_to_exp(const Element<A, AI>& a, const Chooser& c)
00360 {
00361 BENCH_TASK_SCOPED("aut_to_exp");
00362 Element<A, AI> ret(a);
00363 return do_in_aut_to_exp(ret.structure(), ret, c);
00364 }
00365
00366 template<typename A, typename AI>
00367 typename Element<A, AI>::series_set_elt_t
00368 aut_to_exp(const Element<A, AI>& a)
00369 {
00370 return aut_to_exp(a, DefaultChooser());
00371 }
00372
00373 }
00374
00375 #endif // ! VCSN_ALGORITHMS_AUT_TO_EXP_HXX