Vaucanson 1.4
standard_of.hxx
00001 // standard_of.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, 2005, 2006, 2008, 2009, 2010, 2011
00006 // The Vaucanson Group.
00007 //
00008 // This program is free software; you can redistribute it and/or
00009 // modify it under the terms of the GNU General Public License
00010 // as published by the Free Software Foundation; either version 2
00011 // of the License, or (at your option) any later version.
00012 //
00013 // The complete GNU General Public Licence Notice can be found as the
00014 // `COPYING' file in the root directory.
00015 //
00016 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
00017 //
00018 #ifndef VCSN_ALGORITHMS_STANDARD_OF_HXX
00019 # define VCSN_ALGORITHMS_STANDARD_OF_HXX
00020 
00021 # include <vaucanson/algorithms/standard_of.hh>
00022 
00023 # include <vaucanson/algebra/implementation/series/krat_exp_pattern.hh>
00024 # include <vaucanson/algorithms/standard.hh>
00025 
00026 # include <vaucanson/misc/usual_macros.hh>
00027 
00028 namespace vcsn {
00029 
00030   namespace algebra {
00031 
00032     /*-------------------.
00033     | Standard_OfVisitor |
00034     `-------------------*/
00035     template <class Exp_,
00036               class Auto_,
00037               class Dispatch_>
00038     class Standard_OfVisitor :
00039         public algebra::KRatExpMatcher<
00040       Standard_OfVisitor<Exp_, Auto_, Dispatch_>,
00041       Exp_,
00042       Auto_*,
00043       Dispatch_
00044       >
00045     {
00046       public :
00047         typedef Auto_*                                  automaton_ptr_t;
00048         typedef Auto_                                   automaton_t;
00049         typedef typename automaton_t::set_t             automata_set_t;
00050 
00051         typedef typename automaton_t::series_set_t      series_set_t;
00052         typedef typename automaton_t::monoid_t          monoid_t;
00053         typedef typename automaton_t::semiring_t        semiring_t;
00054 
00055         typedef typename automaton_t::series_set_elt_t  series_set_elt_t;
00056         typedef typename automaton_t::monoid_elt_t      monoid_elt_t;
00057         typedef typename automaton_t::semiring_elt_t    semiring_elt_t;
00058 
00059         typedef typename automaton_t::hstate_t          hstate_t;
00060         typedef typename automaton_t::htransition_t     htransition_t;
00061 
00062         typedef typename Exp_::monoid_elt_value_t       monoid_elt_value_t;
00063         typedef typename Exp_::semiring_elt_value_t     semiring_elt_value_t;
00064 
00065         typedef Standard_OfVisitor<Exp_, Auto_, Dispatch_>      this_class;
00066         typedef algebra::KRatExpMatcher<this_class, Exp_, Auto_*, Dispatch_>
00067         parent_class;
00068         typedef typename parent_class::return_type      return_type;
00069 
00070       public :
00071 
00072         Standard_OfVisitor(automaton_t& a) :
00073           automata_set_(a.series()),
00074           auto_(&a)
00075         {
00076         }
00077 
00078         INHERIT_CONSTRUCTORS(this_class, Exp_, Auto_*, Dispatch_);
00079 
00080         // Could not use standard.hh functions because of the storing system.
00081         // No map needed here.
00082         MATCH__(Product, lhs, rhs)
00083         {
00084           AUTOMATON_TYPES(automaton_t);
00085           this->match(lhs);
00086 
00087           hstate_t lhs_i = initial_;
00088 
00089           // Store final states and final values and clear it.
00090           typedef typename std::list<std::pair<hstate_t, series_set_elt_t> >
00091             list_fin_st_t;
00092 
00093           list_fin_st_t lhs_tmp;
00094 
00095           for_all_final_states(f, *auto_)
00096             lhs_tmp.push_back (std::pair<hstate_t, series_set_elt_t>
00097                                   (*f, auto_->get_final(*f)));
00098           auto_->clear_final();
00099 
00100           this->match(rhs);
00101 
00102           // Restore the previously saved data.
00103           typedef std::list<hstate_t> list_st_t;
00104 
00105           list_st_t lhs_finals;
00106 
00107           for (typename list_fin_st_t::iterator i = lhs_tmp.begin();
00108                i != lhs_tmp.end();
00109                ++i)
00110           {
00111             auto_->set_final(i->first, i->second);
00112             lhs_finals.push_back (i->first);
00113           }
00114 
00115           concat_of_standard_inside(auto_->structure(),
00116                                     *auto_, lhs_finals, initial_);
00117 
00118           initial_ = lhs_i;
00119           return auto_;
00120         }
00121         END
00122 
00123         MATCH__(Sum, lhs, rhs)
00124         {
00125           AUTOMATON_TYPES(automaton_t);
00126           typedef typename std::list<std::pair<hstate_t, series_set_elt_t> >
00127             list_fin_st_t;
00128 
00129           this->match(lhs);
00130 
00131           // Store lhs initial state.
00132           hstate_t left_i = initial_;
00133 
00134           // Store final states and final values and clear it.
00135           list_fin_st_t lhs_tmp;
00136 
00137           for_all_const_final_states(f, *auto_)
00138             lhs_tmp.push_back (std::pair<hstate_t, series_set_elt_t>
00139                                (*f, auto_->get_final(*f)));
00140 
00141           auto_->clear_final();
00142 
00143           this->match(rhs);
00144 
00145           // Restore the previously saved data.
00146           for (typename list_fin_st_t::iterator i = lhs_tmp.begin();
00147                i != lhs_tmp.end();
00148                ++i)
00149             auto_->set_final(i->first, i->second);
00150 
00151           sum_of_standard_inside(auto_->structure(),
00152                                  *auto_, left_i, initial_);
00153 
00154           initial_ = left_i;
00155           return auto_;
00156         }
00157         END
00158 
00159         MATCH_(Star, node)
00160         {
00161           AUTOMATON_TYPES(automaton_t);
00162           this->match(node);
00163 
00164           precondition(auto_->get_final(initial_).starable());
00165 
00166           typedef typename std::list<hstate_t> list_fin_st_t;
00167 
00168           // Store final states and final values and clear it.
00169           list_fin_st_t tmp;
00170 
00171           for_all_final_states(f, *auto_)
00172             if (*f != initial_)
00173               tmp.push_back(*f);
00174 
00175           star_of_standard_inside(auto_->structure(),
00176                                   *auto_, initial_, tmp);
00177           return auto_;
00178         }
00179         END
00180 
00181         MATCH__(LeftWeight, w, node)
00182         {
00183           const semiring_t&     semiring = automata_set_.series().semiring();
00184           const semiring_elt_t  weight (semiring, w);
00185           const series_set_elt_t ws(auto_->series(), weight);
00186           this->match(node);
00187 
00188           left_ext_mult_of_standard_inside(auto_->structure(),
00189                                            *auto_, initial_, ws);
00190           return auto_;
00191         }
00192         END
00193 
00194         MATCH__(RightWeight, node, w)
00195         {
00196           const semiring_t&     semiring = automata_set_.series().semiring();
00197           const semiring_elt_t  weight (semiring, w);
00198           this->match(node);
00199 
00200           for (typename automaton_t::final_iterator
00201                  f, next = auto_->final().begin();
00202                next != auto_->final().end();)
00203           {
00204             // We need to store the next iterator before using the
00205             // current one to avoid an invalid iterator after having
00206             // called set_final.  Indeed, set_final() can delete the
00207             // iterator if its second parameter is the zero of the
00208             // series.
00209             f = next;
00210             next++;
00211             auto_->set_final(*f, auto_->get_final(*f) * weight);
00212           }
00213 
00214           return auto_;
00215         }
00216         END
00217 
00218         MATCH_(Constant, m)
00219         {
00220           initial_ = auto_->add_state();
00221           hstate_t last = initial_;
00222           hstate_t new_f = initial_;
00223 
00224           for (typename monoid_elt_value_t::const_iterator i = m.begin();
00225                i != m.end(); ++i)
00226           {
00227             new_f = auto_->add_state();
00228             auto_->add_letter_transition(last, new_f, *i);
00229             last = new_f;
00230           }
00231           auto_->set_initial(initial_);
00232           auto_->set_final(new_f);
00233 
00234           return auto_;
00235         }
00236         END
00237 
00238         MATCH(Zero)
00239         {
00240           initial_ = auto_->add_state();
00241           auto_->set_initial(initial_);
00242           return auto_;
00243         }
00244         END
00245 
00246         MATCH(One)
00247         {
00248           initial_ = auto_->add_state();
00249           auto_->set_initial(initial_);
00250           auto_->set_final(initial_);
00251           return auto_;
00252         }
00253         END
00254 
00255       private:
00256         automata_set_t automata_set_;
00257         // The automata used for construction
00258         hstate_t initial_;
00259         automaton_ptr_t auto_;
00260 
00261         typedef
00262         class
00263         {
00264           public:
00265             inline hstate_t operator[] (hstate_t a)
00266             {
00267               return a;
00268             }
00269         } ident_t;
00270 
00271         ident_t identity_;
00272     };
00273 
00274   }
00275 
00276   template <typename A,
00277             typename Output,
00278             typename Exp>
00279   void
00280   do_standard_of(const AutomataBase<A>&,
00281                  Output& output,
00282                  const Exp& kexp)
00283   {
00284     algebra::Standard_OfVisitor<Exp, Output, algebra::DispatchFunction<Exp> >
00285       m(output);
00286 
00287     m.match(kexp);
00288   }
00289 
00290   template<typename A,
00291            typename T,
00292            typename Exp>
00293   void
00294   standard_of(Element<A, T>& out,
00295               const Exp& kexp)
00296   {
00297     do_standard_of(out.structure(), out, kexp);
00298   }
00299 
00300 } // vcsn
00301 
00302 #endif // ! VCSN_ALGORITHMS_STANDARD_OF_HXX