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 a.deltac(delta_out, *i, delta_kind::transitions());
00129 a.rdeltac(delta_in, *i, delta_kind::transitions());
00130 for (typename std::list<typename Auto_::htransition_t>::iterator j = delta_out.begin();
00131 j != delta_out.end();
00132 ++j)
00133 if (*i == a.dst_of(*j))
00134 has_loop = true;
00135
00136
00137 if (has_loop)
00138 d_in = delta_in.size() - 1;
00139 else
00140 d_in = delta_in.size();
00141 d_out = delta_out.size();
00142
00143
00144 if (d_in * d_out < max ||
00145 (d_in * d_out == max &&
00146 has_loop_old && not has_loop))
00147 {
00148 s = i;
00149 max = d_in * d_out;
00150 has_loop_old = has_loop;
00151 }
00152 delta_out.clear();
00153 delta_in.clear();
00154 }
00155 return *s;
00156 }
00157
00158
00159
00160
00161
00162
00163
00164 template <class Auto_>
00165 typename Auto_::hstate_t
00166 DMChooser::operator()(const Auto_& a) const
00167 {
00168 assertion(a.states().size() > 0);
00169
00170 std::list<typename Auto_::htransition_t> delta_in;
00171 std::list<typename Auto_::htransition_t> delta_out;
00172 typename Auto_::state_iterator s = a.states().begin();
00173
00174 int weight_min = misc::limits<int>::max();
00175 for (typename Auto_::state_iterator i = a.states().begin();
00176 i != a.states().end();
00177 ++i)
00178 {
00179 if (a.is_final(*i) || a.is_initial(*i))
00180 continue;
00181 unsigned int n_loops = 0;
00182 unsigned int in = 0;
00183 unsigned int out = 0;
00184
00185 int weight = 0;
00186
00187 delta_in.clear();
00188 delta_out.clear();
00189 a.deltac(delta_out, *i, delta_kind::transitions());
00190 a.rdeltac(delta_in, *i, delta_kind::transitions());
00191
00192 for (typename std::list<typename Auto_::htransition_t>::iterator j = delta_out.begin();
00193 j != delta_out.end();
00194 ++j)
00195 if (*i == a.dst_of(*j))
00196 ++n_loops;
00197
00198 in = delta_in.size() - n_loops;
00199 out = delta_out.size() - n_loops;
00200
00201
00202 for (typename std::list<typename Auto_::htransition_t>::iterator j = delta_in.begin();
00203 j != delta_in.end();
00204 ++j)
00205 if (*i != a.dst_of(*j))
00206 {
00207 weight += a.series_value_of(*j).length() * (out - 1);
00208 }
00209
00210
00211 for (typename std::list<typename Auto_::htransition_t>::iterator j = delta_out.begin();
00212 j != delta_out.end();
00213 ++j)
00214 if (*i != a.dst_of(*j))
00215 {
00216 weight += a.series_value_of(*j).length() * (in - 1);
00217 }
00218
00219
00220 for (typename std::list<typename Auto_::htransition_t>::iterator j = delta_out.begin();
00221 j != delta_out.end();
00222 ++j)
00223 if (*i == a.dst_of(*j))
00224 {
00225 weight += a.series_value_of(*j).length() * (in * out - 1);
00226 }
00227
00228 if (weight < weight_min)
00229 {
00230 s = i;
00231 weight_min = weight;
00232 }
00233 }
00234 return *s;
00235 }
00236
00237
00238
00239
00240
00241 inline ListChooser::ListChooser(const std::list<unsigned int>& l) :
00242 list_(l),
00243 pos_(l.begin())
00244 {
00245 }
00246
00247 template <class Auto_>
00248 typename Auto_::hstate_t
00249 ListChooser::operator() (const Auto_& a)
00250 {
00251 assertion(pos_ != list_.end());
00252 return a.get_state(*pos_++);
00253 }
00254
00255
00256
00257
00258
00259 template <class A, typename AI, typename Chooser>
00260 typename Element<A, AI>::series_set_elt_t
00261 do_in_aut_to_exp(const AutomataBase<A>& a_set,
00262 Element<A, AI>& a,
00263 Chooser chooser)
00264 {
00265 typedef Element<A, AI> automaton_t;
00266 AUTOMATON_TYPES(automaton_t);
00267 typedef typename automaton_t::series_set_t series_set_t;
00268 typedef typename automaton_t::series_set_elt_t series_set_elt_t;
00269
00270 typedef typename std::list<htransition_t> htransition_set_t;
00271 typedef std::map<hstate_t, series_set_elt_t> sums_t;
00272
00273 typename htransition_set_t::const_iterator i, j;
00274 hstate_t q;
00275 htransition_set_t transitions;
00276 std::list<htransition_t> transitions_to_remove;
00277 normalize_here(a);
00278
00279
00280 while (a.states().size() != 2)
00281 {
00282 series_set_elt_t loop_sum(a_set.series());
00283 sums_t in_sums, out_sums;
00284
00285 q = chooser(a);
00286 if (a.is_initial(q) || a.is_final(q))
00287 continue;
00288
00289 transitions.clear();
00290
00291 a.deltac(transitions, q, delta_kind::transitions());
00292 for (i = transitions.begin(); i != transitions.end(); i = j)
00293 {
00294 j = i; ++j;
00295
00296 if (a.dst_of(*i) == q)
00297 loop_sum += a.series_of(*i);
00298 else
00299 {
00300 typename sums_t::iterator f = out_sums.find(a.dst_of(*i));
00301 if (f == out_sums.end())
00302 f = out_sums.insert
00303 (std::make_pair(a.dst_of(*i),
00304 series_set_elt_t(a_set.series()))).first;
00305 f->second += a.series_of(*i);
00306 }
00307 a.del_transition(*i);
00308 }
00309 transitions.clear();
00310
00311 a.rdeltac(transitions, q, delta_kind::transitions());
00312 for (i = transitions.begin(); i != transitions.end(); i = j)
00313 {
00314 j = i; ++j;
00315
00316 typename sums_t::iterator f = in_sums.find(a.src_of(*i));
00317 if (f == in_sums.end())
00318 f = in_sums.insert
00319 (std::make_pair(a.src_of(*i),
00320 series_set_elt_t(a_set.series()))).first;
00321
00322 f->second += a.series_of(*i);
00323 a.del_transition(*i);
00324 }
00325 loop_sum.star();
00326
00327 for_all_const_(sums_t, in, in_sums)
00328 for_all_const_(sums_t, out, out_sums)
00329 {
00330 series_set_elt_t res = in->second * loop_sum * out->second;
00331 a.add_series_transition(in->first, out->first, res);
00332 }
00333 a.del_state(q);
00334 }
00335 series_set_elt_t final(a_set.series());
00336 for_all_const_transitions(i, a)
00337 final += a.label_of(*i);
00338 return final;
00339 }
00340
00341
00342
00343
00344
00345 template<typename A, typename AI, typename Chooser>
00346 typename Element<A, AI>::series_set_elt_t
00347 aut_to_exp(const Element<A, AI>& a, const Chooser& c)
00348 {
00349 TIMER_SCOPED("aut_to_exp");
00350 Element<A, AI> ret(a);
00351 return do_in_aut_to_exp(ret.structure(), ret, c);
00352 }
00353
00354 template<typename A, typename AI>
00355 typename Element<A, AI>::series_set_elt_t
00356 aut_to_exp(const Element<A, AI>& a)
00357 {
00358 return aut_to_exp(a, DefaultChooser());
00359 }
00360
00361 }
00362
00363 #endif // ! VCSN_ALGORITHMS_AUT_TO_EXP_HXX