standard.hxx

00001 // standard.hxx: this file is part of the Vaucanson project.
00002 //
00003 // Vaucanson, a generic library for finite state machines.
00004 //
00005 // Copyright (C) 2001, 2002, 2003, 2004 The Vaucanson Group.
00006 //
00007 // This program is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2
00010 // of the License, or (at your option) any later version.
00011 //
00012 // The complete GNU General Public Licence Notice can be found as the
00013 // `COPYING' file in the root directory.
00014 //
00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
00016 //
00017 #ifndef VCSN_ALGORITHMS_STANDARD_HXX
00018 # define VCSN_ALGORITHMS_STANDARD_HXX
00019 
00020 # include <vaucanson/algorithms/standard.hh>
00021 
00022 # include <vaucanson/algorithms/sum.hh>
00023 # include <vaucanson/algorithms/accessible.hh>
00024 # include <vaucanson/automata/concept/automata_base.hh>
00025 # include <vaucanson/tools/usual_macros.hh>
00026 
00027 # include <set>
00028 
00029 namespace vcsn {
00030 
00031   /*---------.
00032   | standard |
00033   `---------*/
00034   template <class A_, typename Auto_>
00035   void
00036   do_in_standardize(const AutomataBase<A_>& ,
00037                     Auto_&                  a)
00038   {
00039     AUTOMATON_TYPES(Auto_);
00040     hstate_t i = a.add_state();
00041     std::set<htransition_t> transition_oi;
00042     for_each_initial_state(oi, a)
00043     {
00044       series_set_elt_t s = a.get_initial(*oi);
00045       std::set<htransition_t> transition_oi;
00046       transition_oi.clear();
00047       a.deltac(transition_oi, *oi, delta_kind::transitions());
00048       for_all_const_(std::set<htransition_t>, oil, transition_oi)
00049       {
00050         series_set_elt_t t = s*a.series_of(*oil);
00051         a.add_series_transition(i,a.dst_of(*oil),t);
00052       }
00053     }
00054     a.clear_initial();
00055     a.set_initial(i);
00056     accessible_here(a);
00057   }
00058 
00059   template<typename A, typename T>
00060   void
00061   standardize(Element<A, T>& a)
00062   {
00063     do_in_standardize(a.structure(), a);
00064   }
00065 
00066   /*---------------.
00067   | standard_union |
00068   `---------------*/
00069 
00070   template <typename A, typename lhs_t, typename rhs_t>
00071   void do_union_of_standard_here(const AutomataBase<A>& ,
00072                                  lhs_t& lhs,
00073                                  const rhs_t& rhs)
00074   {
00075     typedef typename std::set<htransition_t>            edelta_ret_t;
00076     edelta_ret_t        aim;
00077     hstate_t            new_i, old_i;
00078 
00079     new_i = *lhs.initial().begin();
00080     sum_here(lhs, rhs);
00081     for (typename lhs_t::initial_iterator i = lhs.initial().begin();
00082          i != lhs.initial().end();
00083          ++i)
00084     {
00085       // FIXME : is there something like an iterator over the
00086       // support of initial ?
00087       if (*i != new_i)
00088       {
00089         old_i = *i;
00090         lhs.set_final(new_i,
00091                       lhs.get_final(new_i) +
00092                       lhs.get_final(old_i));
00093         aim.clear();
00094         lhs.deltac(aim, old_i, delta_kind::transitions());
00095         for (typename edelta_ret_t::const_iterator d = aim.begin();
00096              d != aim.end();
00097              ++d)
00098         {
00099           lhs.add_transition(new_i,
00100                              lhs.dst_of(*d),
00101                              lhs.label_of(*d));
00102           lhs.del_transition(*d);
00103         }
00104         aim.clear();
00105         lhs.rdeltac(aim, old_i, delta_kind::transitions());
00106         for (typename edelta_ret_t::const_iterator d = aim.begin();
00107              d != aim.end();
00108              ++d)
00109         {
00110           lhs.add_transition(lhs.src_of(*d),
00111                              new_i,
00112                              lhs.label_of(*d));
00113           lhs.del_transition(*d);
00114         }
00115         lhs.del_state(old_i);
00116       }
00117     }
00118   }
00119 
00120   template<typename A, typename T, typename U>
00121   void union_of_standard_here(Element<A, T>& lhs,
00122                               const Element<A, U>& rhs)
00123   {
00124     // assertion(lhs.structure() == rhs.structure())
00125     do_union_of_standard_here(lhs.structure(), lhs, rhs);
00126   }
00127 
00128   template<typename A, typename T, typename U>
00129   Element<A, T>
00130   union_of_standard(const Element<A, T>& lhs,
00131                     const Element<A, U>& rhs)
00132   {
00133     // assertion(lhs.structure() == rhs.structure())
00134     Element<A, T> ret(lhs);
00135     do_union_of_standard_here(ret.structure(), ret, rhs);
00136     return ret;
00137   }
00138 
00139   /*------------.
00140   | is_standard |
00141   `------------*/
00142   template <typename A, typename auto_t>
00143   bool
00144   do_is_standard(const AutomataBase<A>& ,
00145                  const auto_t& a)
00146   {
00147     typedef typename auto_t::series_set_elt_value_t     series_set_elt_value_t;
00148 
00149     // Check there is only one initial state.
00150     if (a.initial().size() != 1)
00151       return false;
00152 
00153     // Check there is no input transition on the initial state.
00154     hstate_t            s = *a.initial().begin();
00155     std::set<hstate_t>  delta_ret;
00156     a.rdeltac(delta_ret, s, vcsn::delta_kind::states());
00157     if (delta_ret.size() != 0)
00158       return false;
00159 
00160     // Check the multiplicity of the initial state.
00161     return
00162       a.get_initial(s) == a.series().identity(SELECT(series_set_elt_value_t));
00163   }
00164 
00165   template<typename A, typename T>
00166   bool
00167   is_standard(const Element<A, T>& a)
00168   {
00169     return do_is_standard(a.structure(), a);
00170   }
00171 
00172   /*----------------.
00173   | standard_concat |
00174   `----------------*/
00175   template <typename A, typename lhs_t, typename rhs_t>
00176   void do_concat_of_standard_here(const AutomataBase<A>& ,
00177                                   lhs_t& lhs,
00178                                   const rhs_t& rhs)
00179   {
00180     typedef std::map<hstate_t, hstate_t>        map_t;
00181     typedef std::set<htransition_t>                     delta_ret_t;
00182 
00183     /*-----------------.
00184     | Concat of states |
00185     `-----------------*/
00186     map_t       map_h;
00187     delta_ret_t aim;
00188     hstate_t    new_state;
00189 
00190     // Add states except the initial one
00191     for (typename rhs_t::state_iterator s = rhs.states().begin();
00192          s != rhs.states().end();
00193          ++s)
00194       if (!rhs.is_initial(*s))
00195       {
00196         new_state = lhs.add_state();
00197         map_h[*s] = new_state;
00198       }
00199 
00200     // Add transitions
00201     hstate_t rhs_i = *rhs.initial().begin();
00202     aim.clear();
00203     rhs.deltac(aim, rhs_i, delta_kind::transitions());
00204     for (typename lhs_t::final_iterator f = lhs.final().begin();
00205          f != lhs.final().end();
00206          ++f)
00207     {
00208       typename lhs_t::series_set_elt_t weight = lhs.get_final(*f);
00209       for (typename delta_ret_t::const_iterator d = aim.begin();
00210            d != aim.end();
00211            ++d)
00212         lhs.add_series_transition(*f,
00213                                   map_h[rhs.dst_of(*d)],
00214                                   weight * rhs.label_of(*d));
00215     }
00216 
00217     for (typename lhs_t::state_iterator s = lhs.states().begin();
00218          s != lhs.states().end();
00219          ++s)
00220       lhs.set_final(*s, lhs.get_final(*s) * rhs.get_final(rhs_i));
00221 
00222     for (typename map_t::const_iterator nf = map_h.begin();
00223          nf != map_h.end();
00224          ++nf)
00225       if (rhs.is_final(nf->first))
00226         lhs.set_final(nf->second);
00227 
00228     /*----------------------.
00229     | Concat of transitions |
00230     `----------------------*/
00231     for (typename rhs_t::state_iterator i = rhs.states().begin();
00232          i != rhs.states().end();
00233          ++i)
00234       if (!rhs.is_initial(*i))
00235       {
00236         aim.clear();
00237         rhs.deltac(aim, *i, delta_kind::transitions());
00238         for (typename delta_ret_t::const_iterator d = aim.begin();
00239              d != aim.end();
00240              ++d)
00241           lhs.add_transition(map_h[*i],
00242                              map_h[rhs.dst_of(*d)],
00243                              rhs.label_of(*d));
00244       }
00245   }
00246 
00247   template<typename A, typename T, typename U>
00248   void concat_of_standard_here(Element<A, T>& lhs,
00249                                const Element<A, U>& rhs)
00250   {
00251     // assertion(lhs.structure() == rhs.structure())
00252     do_concat_of_standard_here(lhs.structure(), lhs, rhs);
00253   }
00254 
00255   template<typename A, typename T, typename U>
00256   Element<A, T>
00257   concat_of_standard(const Element<A, T>& lhs,
00258                      const Element<A, U>& rhs)
00259   {
00260     // assertion(lhs.structure() == rhs.structure())
00261     Element<A, T> ret(lhs);
00262     do_concat_of_standard_here(ret.structure(), ret, rhs);
00263     return ret;
00264   }
00265 
00266   /*--------------.
00267   | standard_star |
00268   `--------------*/
00269   template <typename A, typename auto_t>
00270   void do_star_of_standard_here(const AutomataBase<A>& ,
00271                                 auto_t& a)
00272   {
00273     AUTOMATON_TYPES(auto_t);
00274 
00275     typedef std::set<htransition_t>             edelta_ret_t;
00276     edelta_ret_t                        aim;
00277 
00278     hstate_t                            new_i = *a.initial().begin();
00279     series_set_elt_t                    out_mult = a.get_final(new_i);
00280     out_mult.star();
00281 
00282     a.deltac(aim, new_i, delta_kind::transitions());
00283 
00284     for (typename auto_t::final_iterator f = a.final().begin();
00285          f != a.final().end();
00286          ++f)
00287     {
00288       if (*f != new_i)
00289         for (typename edelta_ret_t::iterator d = aim.begin();
00290              d != aim.end();
00291              ++d)
00292           // FIXME: it is wanted that we can create two similar transitions.
00293           // FIXME: is it a good thing ?
00294           a.add_transition(*f, a.dst_of(*d), a.label_of(*d));
00295 
00296     }
00297 
00298     for (typename edelta_ret_t::iterator d = aim.begin();
00299          d != aim.end();
00300          ++d)
00301     {
00302       series_set_elt_t st = out_mult * a.series_of(*d);
00303       hstate_t to = a.dst_of(*d);
00304       a.del_transition(*d);
00305       a.add_series_transition(new_i, to, st);
00306     }
00307 
00308     a.set_final(new_i, out_mult);
00309   }
00310 
00311   template<typename A, typename T>
00312   void star_of_standard_here(Element<A, T>& a)
00313   {
00314     do_star_of_standard_here(a.structure(), a);
00315   }
00316 
00317   template<typename A, typename T>
00318   Element<A, T>
00319   star_of_standard(const Element<A, T>& a)
00320   {
00321     // assertion(lhs.structure() == rhs.structure())
00322     Element<A, T> ret(a);
00323     do_star_of_standard_here(ret.structure(), ret);
00324     return ret;
00325   }
00326 
00327 } // vcsn
00328 
00329 #endif // ! VCSN_ALGORITHMS_STANDARD_HXX

Generated on Fri Jul 28 12:18:52 2006 for Vaucanson by  doxygen 1.4.6