00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 #ifndef VCSN_ALGORITHMS_STANDARD_HXX
00019 # define VCSN_ALGORITHMS_STANDARD_HXX
00020 
00021 # include <vaucanson/algorithms/standard.hh>
00022 # include <vaucanson/algorithms/internal/has_neighbour.hh>
00023 
00024 # include <vaucanson/algorithms/sum.hh>
00025 # include <vaucanson/algorithms/accessible.hh>
00026 # include <vaucanson/automata/concept/automata_base.hh>
00027 # include <vaucanson/misc/usual_macros.hh>
00028 
00029 # include <set>
00030 
00031 namespace vcsn {
00032 
00033   
00034 
00035 
00036   template <class A, typename AI>
00037   void
00038   do_in_standardize(const AutomataBase<A>&, Element<A, AI>& a)
00039   {
00040     BENCH_TASK_SCOPED("standardize");
00041     typedef Element<A, AI> automaton_t;
00042     AUTOMATON_TYPES(automaton_t);
00043 
00044     hstate_t i = a.add_state();
00045     std::list<htransition_t> transition_oi;
00046     series_set_elt_t final_series =
00047       algebra::zero_as<series_set_elt_value_t>::of(a.series());
00048 
00049     for_all_const_initial_states(oi, a)
00050     {
00051       series_set_elt_t s = a.get_initial(*oi);
00052 
00053       
00054       transition_oi.clear();
00055       for (delta_iterator oil(a.value(), *oi);
00056            ! oil.done();
00057            oil.next())
00058         transition_oi.push_back(*oil);
00059       for_all_const_(std::list<htransition_t>, oil, transition_oi)
00060       {
00061         series_set_elt_t t = s * a.series_of(*oil);
00062         a.add_series_transition(i, a.dst_of(*oil), t);
00063       }
00064       
00065       final_series += s * a.get_final(*oi);
00066     }
00067 
00068     
00069     
00070     
00071     
00072     for (initial_iterator oi = a.initial().begin(), next = oi;
00073          oi != a.initial().end();
00074          oi = next)
00075     {
00076       ++next;
00077       if (!has_predecessors(a, *oi))
00078         a.del_state(*oi);
00079     }
00080     a.clear_initial();
00081     a.set_initial(i);
00082     a.set_final(i, final_series);
00083   }
00084 
00085   template<typename A, typename AI>
00086   void
00087   standardize(Element<A, AI>& a)
00088   {
00089     do_in_standardize(a.structure(), a);
00090   }
00091 
00092   
00093 
00094 
00095 
00096   template <typename A, typename AI1, typename AI2>
00097   void
00098   do_union_of_standard_here(const AutomataBase<A>&,
00099                             Element<A, AI1>& lhs,
00100                             const Element<A, AI2>& rhs)
00101   {
00102     precondition(is_standard(lhs));
00103     precondition(is_standard(rhs));
00104 
00105     BENCH_TASK_SCOPED("union_of_standard");
00106 
00107     typedef Element<A, AI1> lhs_t;
00108 
00109     
00110     typename lhs_t::hstate_t new_i = *lhs.initial().begin();
00111     sum_here(lhs, rhs);
00112 
00113     assertion (lhs.initial().size() == 2);
00114     typename lhs_t::initial_iterator i = lhs.initial().begin();
00115     typename lhs_t::hstate_t old_i = *i != new_i ? *i : *++i;
00116 
00117     union_of_standard_here_common(lhs.structure(), lhs, new_i, old_i);
00118   }
00119 
00120   
00121   
00122   
00123   
00124   template<typename A, typename AI>
00125   void
00126   union_of_standard_here_common(const AutomataBase<A>&,
00127                                 Element<A, AI>& a,
00128                                 typename Element<A, AI>::hstate_t& new_i,
00129                                 typename Element<A, AI>::hstate_t& old_i)
00130   {
00131     typedef Element<A, AI>                       automaton_t;
00132     typedef typename automaton_t::htransition_t  htransition_t;
00133     typedef typename automaton_t::delta_iterator delta_iterator_t;
00134     typedef std::list<htransition_t>             delta_ret_t;
00135 
00136     
00137     
00138     a.set_final(new_i,
00139                 a.get_final(new_i) + a.get_final(old_i));
00140 
00141     
00142     
00143     
00144     
00145     
00146     
00147     delta_ret_t dst;
00148 
00149     for (delta_iterator_t i(a.value(), old_i);
00150          ! i.done();
00151          i.next())
00152       dst.push_back(*i);
00153 
00154     for_all_const_(delta_ret_t, d, dst)
00155     {
00156       a.add_series_transition(new_i,
00157                               a.dst_of(*d),
00158                               a.series_of(*d));
00159       a.del_transition(*d);
00160     }
00161 
00162     a.del_state(old_i);
00163   }
00164 
00165   template<typename A, typename AI1, typename AI2>
00166   void
00167   union_of_standard_here(Element<A, AI1>& lhs, const Element<A, AI2>& rhs)
00168   {
00169     do_union_of_standard_here(lhs.structure(), lhs, rhs);
00170   }
00171 
00172   template<typename A, typename AI1, typename AI2>
00173   Element<A, AI1>
00174   union_of_standard(const Element<A, AI1>& lhs, const Element<A, AI2>& rhs)
00175   {
00176     Element<A, AI1> ret(lhs);
00177     union_of_standard_here(ret, rhs);
00178     return ret;
00179   }
00180 
00181   
00182 
00183 
00184   template<typename A, typename AI>
00185   bool
00186   do_is_standard(const AutomataBase<A>&, const Element<A, AI>& a)
00187   {
00188     BENCH_TASK_SCOPED("is_standard");
00189     typedef Element<A, AI> automaton_t;
00190     typedef typename automaton_t::series_set_elt_value_t        series_set_elt_value_t;
00191 
00192     
00193     if (a.initial().size() != 1)
00194       return false;
00195 
00196     
00197     typename automaton_t::hstate_t s = *a.initial().begin();
00198     if (a.get_initial(s)
00199         != a.series().identity(SELECT(series_set_elt_value_t)))
00200       return false;
00201 
00202     
00203     return !has_predecessors(a, s);
00204   }
00205 
00206   template<typename A, typename AI>
00207   bool
00208   is_standard(const Element<A, AI>& a)
00209   {
00210     return do_is_standard(a.structure(), a);
00211   }
00212 
00213   
00214 
00215 
00216   template <typename A, typename AI1, typename AI2>
00217   void
00218   do_concat_of_standard_here(const AutomataBase<A>&,
00219                              Element<A, AI1>& lhs,
00220                              const Element<A, AI2>& rhs)
00221   {
00222     precondition(is_standard(lhs));
00223     precondition(is_standard(rhs));
00224 
00225     BENCH_TASK_SCOPED("concat_of_standard");
00226     typedef Element<A, AI1> lhs_t;
00227     typedef Element<A, AI2> rhs_t;
00228     typedef typename lhs_t::hstate_t l_hstate_t;
00229     typedef typename rhs_t::hstate_t r_hstate_t;
00230     typedef std::map<l_hstate_t, r_hstate_t>    map_t;
00231 
00232     
00233 
00234 
00235     map_t       map_h;
00236     l_hstate_t  new_state;
00237 
00238     
00239     for (typename rhs_t::state_iterator s = rhs.states().begin();
00240          s != rhs.states().end();
00241          ++s)
00242       if (!rhs.is_initial(*s))
00243       {
00244         new_state = lhs.add_state();
00245         map_h[*s] = new_state;
00246       }
00247 
00248     
00249     for (typename rhs_t::state_iterator i = rhs.states().begin();
00250          i != rhs.states().end();
00251          ++i)
00252       if (!rhs.is_initial(*i))
00253       {
00254         for (typename rhs_t::delta_iterator d(rhs.value(), *i);
00255              ! d.done();
00256              d.next())
00257           lhs.add_transition(map_h[*i],
00258                              map_h[rhs.dst_of(*d)],
00259                              rhs.label_of(*d));
00260       }
00261 
00262 
00263     r_hstate_t rhs_i = *rhs.initial().begin();
00264 
00265     concat_of_standard_here_common(lhs.structure(),
00266                                    lhs,
00267                                    rhs,
00268                                    rhs_i,
00269                                    lhs.final().begin(),
00270                                    lhs.final().end(),
00271                                    map_h);
00272 
00273     
00274     for_all_const_(map_t, nf, map_h)
00275       if (rhs.is_final(nf->first))
00276         lhs.set_final(nf->second, rhs.get_final(nf->first));
00277   }
00278 
00279   
00280   
00281   
00282   
00283   
00284   
00285   
00286   template<typename A, typename AI1, typename AI2, typename T1, typename T2>
00287   void
00288   concat_of_standard_here_common(const AutomataBase<A>&,
00289                                  Element<A, AI1>& lhs,
00290                                  const Element<A, AI2>& rhs,
00291                                  typename Element<A, AI2>::hstate_t& rhs_i,
00292                                  const T1& lhs_finals_b,
00293                                  const T1& lhs_finals_e,
00294                                  T2& accessor)
00295   {
00296     typedef Element<A, AI1>                     lhs_t;
00297     typedef Element<A, AI2>                     rhs_t;
00298     typedef T1                                  lhs_final_it_t;
00299     typedef typename rhs_t::delta_iterator      delta_iterator_t;
00300     typedef typename lhs_t::htransition_t       htransition_t;
00301     typedef std::list<htransition_t>            delta_ret_t;
00302 
00303     delta_ret_t dst;
00304 
00305     for (delta_iterator_t i(rhs.value(), rhs_i);
00306          ! i.done();
00307          i.next())
00308       dst.push_back(*i);
00309 
00310     
00311     for (lhs_final_it_t f = lhs_finals_b;
00312          f != lhs_finals_e;
00313          ++f)
00314     {
00315       typename lhs_t::series_set_elt_t weight = lhs.get_final(*f);
00316 
00317       for_all_const_(delta_ret_t, d, dst)
00318         lhs.add_series_transition(*f,
00319                                   accessor[rhs.dst_of(*d)],
00320                                   weight * rhs.label_of(*d));
00321     }
00322 
00323     
00324     
00325     typename lhs_t::series_set_elt_t rhs_iw = rhs.get_final(rhs_i);
00326 
00327     for (lhs_final_it_t next = lhs_finals_b;
00328          next != lhs_finals_e;)
00329     {
00330       lhs_final_it_t f = next;
00331       next++;
00332       lhs.set_final(*f, lhs.get_final(*f) * rhs_iw);
00333     }
00334   }
00335 
00336   template<typename A, typename AI1, typename AI2>
00337   void
00338   concat_of_standard_here(Element<A, AI1>& lhs, const Element<A, AI2>& rhs)
00339   {
00340     do_concat_of_standard_here(lhs.structure(), lhs, rhs);
00341   }
00342 
00343   template<typename A, typename AI1, typename AI2>
00344   Element<A, AI1>
00345   concat_of_standard(const Element<A, AI1>& lhs,
00346                      const Element<A, AI2>& rhs)
00347   {
00348     Element<A, AI1> ret(lhs);
00349     do_concat_of_standard_here(ret.structure(), ret, rhs);
00350     return ret;
00351   }
00352 
00353   
00354 
00355 
00356   template <typename A, typename AI>
00357   void
00358   do_star_of_standard_here(const AutomataBase<A>&, Element<A, AI>& a)
00359   {
00360     precondition(is_standard(a));
00361 
00362     BENCH_TASK_SCOPED("star_of_standard");
00363 
00364     assertion (a.initial().size() == 1);
00365     typename Element<A, AI>::hstate_t new_i = *a.initial().begin();
00366     star_of_standard_here_common(a.structure(), a, new_i);
00367   }
00368 
00369   
00370   template<typename A, typename AI>
00371   void
00372   star_of_standard_here_common(const AutomataBase<A>&,
00373                                Element<A, AI>& a,
00374                                typename Element<A, AI>::hstate_t& new_i)
00375   {
00376     typedef Element<A, AI>              automaton_t;
00377     AUTOMATON_TYPES(automaton_t);
00378     typedef std::list<htransition_t>    delta_ret_t;
00379 
00380     
00381     
00382     
00383     
00384     
00385 
00386     series_set_elt_t                    out_mult = a.get_final(new_i);
00387 
00388     out_mult.star();
00389 
00390     delta_ret_t dst;
00391 
00392     for (delta_iterator i(a.value(), new_i);
00393          ! i.done();
00394          i.next())
00395       dst.push_back(*i);
00396 
00397     for_all_final_states(f, a)
00398     {
00399       if (*f != new_i)
00400       {
00401         series_set_elt_t f_mult = a.get_final(*f) * out_mult;
00402         a.set_final(*f, f_mult);
00403 
00404         for_all_const_(delta_ret_t, d, dst)
00405           a.add_series_transition(*f, a.dst_of(*d), f_mult * a.label_of(*d));
00406       }
00407     }
00408     a.set_final(new_i, out_mult);
00409   }
00410 
00411   template<typename A, typename AI>
00412   void
00413   star_of_standard_here(Element<A, AI>& a)
00414   {
00415     do_star_of_standard_here(a.structure(), a);
00416   }
00417 
00418   template<typename A, typename AI>
00419   Element<A, AI>
00420   star_of_standard(const Element<A, AI>& a)
00421   {
00422     Element<A, AI> ret(a);
00423     do_star_of_standard_here(ret.structure(), ret);
00424     return ret;
00425   }
00426 
00427 } 
00428 
00429 #endif // ! VCSN_ALGORITHMS_STANDARD_HXX