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