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

Generated on Sat Jul 29 17:13:11 2006 for Vaucanson by  doxygen 1.4.6