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