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 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_OF_HXX
00018 # define VCSN_ALGORITHMS_STANDARD_OF_HXX
00019 
00020 # include <vaucanson/algorithms/standard_of.hh>
00021 
00022 # include <vaucanson/algebra/implementation/series/krat_exp_pattern.hh>
00023 # include <vaucanson/algorithms/standard.hh>
00024 
00025 # include <vaucanson/misc/usual_macros.hh>
00026 
00027 namespace vcsn {
00028 
00029   namespace algebra {
00030 
00031     /*-------------------.
00032     | Standard_OfVisitor |
00033     `-------------------*/
00034     template <class Exp_,
00035               class Auto_,
00036               class Dispatch_>
00037     class Standard_OfVisitor :
00038         public algebra::KRatExpMatcher<
00039       Standard_OfVisitor<Exp_, Auto_, Dispatch_>,
00040       Exp_,
00041       Auto_*,
00042       Dispatch_
00043       >
00044     {
00045       public :
00046         typedef Auto_*                                  automaton_ptr_t;
00047         typedef Auto_                                   automaton_t;
00048         typedef typename automaton_t::set_t             automata_set_t;
00049 
00050         typedef typename automaton_t::series_set_t      series_set_t;
00051         typedef typename automaton_t::monoid_t          monoid_t;
00052         typedef typename automaton_t::semiring_t        semiring_t;
00053 
00054         typedef typename automaton_t::series_set_elt_t  series_set_elt_t;
00055         typedef typename automaton_t::monoid_elt_t      monoid_elt_t;
00056         typedef typename automaton_t::semiring_elt_t    semiring_elt_t;
00057 
00058         typedef typename automaton_t::hstate_t          hstate_t;
00059         typedef typename automaton_t::htransition_t     htransition_t;
00060 
00061         typedef typename Exp_::monoid_elt_value_t       monoid_elt_value_t;
00062         typedef typename Exp_::semiring_elt_value_t     semiring_elt_value_t;
00063 
00064         typedef Standard_OfVisitor<Exp_, Auto_, Dispatch_>      this_class;
00065         typedef algebra::KRatExpMatcher<this_class, Exp_, Auto_*, Dispatch_>
00066         parent_class;
00067         typedef typename parent_class::return_type      return_type;
00068 
00069       public :
00070 
00071         Standard_OfVisitor(const series_set_t& series) :
00072           automata_set_(series)
00073         {}
00074 
00075         INHERIT_CONSTRUCTORS(this_class, Exp_, Auto_*, Dispatch_);
00076 
00077         MATCH__(Product, lhs, rhs)
00078         {
00079           automaton_ptr_t tmp_  = match(rhs);
00080           automaton_ptr_t auto_ = match(lhs);
00081           concat_of_standard_here(*auto_, *tmp_);
00082           delete (tmp_);
00083           return auto_;
00084         }
00085         END
00086 
00087         MATCH__(Sum, lhs, rhs)
00088         {
00089           automaton_ptr_t tmp_  = match(rhs);
00090           automaton_ptr_t auto_ = match(lhs);
00091           union_of_standard_here(*auto_, *tmp_);
00092           delete (tmp_);
00093           return auto_;
00094         }
00095         END
00096 
00097         MATCH_(Star, node)
00098         {
00099           automaton_ptr_t stared = match(node);
00100           star_of_standard_here(*stared);
00101           return stared;
00102         }
00103         END
00104 
00105         MATCH__(LeftWeight, w, node)
00106         {
00107           const semiring_t&     semiring = automata_set_.series().semiring();
00108           const semiring_elt_t  weight (semiring, w);
00109           automaton_ptr_t       auto_ = match(node);
00110 
00111           for (typename automaton_t::initial_iterator i = auto_->initial().begin();
00112                i != auto_->initial().end();
00113                ++i)
00114           {
00115             std::list<htransition_t>    e;
00116             auto_->deltac(e, *i, delta_kind::transitions());
00117             for (typename std::list<htransition_t>::const_iterator j = e.begin();
00118                  j != e.end();
00119                  ++j)
00120             {
00121               // FIXME: The following code is only correct when labels are
00122               // FIXME: series. We should add meta code to make the code
00123               // FIXME: fail at runtime when this function is called
00124               // FIXME: with label as letters. However, we cannot afford
00125               // FIXME: doing an error at compile time, because the rest
00126               // FIXME: of this matcher is valid on Boolean automata with
00127               // FIXME: label as letter.
00128               typedef typename automaton_t::label_t     label_t;
00129               typedef Element<series_set_t, label_t>    label_elt_t;
00130 
00131               label_elt_t label (automata_set_.series(), auto_->label_of(*j));
00132               label  = weight * label;
00133 
00134               hstate_t dst = auto_->dst_of(*j);
00135               auto_->del_transition(*j);
00136 
00137               if (label != zero_as<label_t>::of(automata_set_.series()))
00138                 auto_->add_transition(*i, dst, label.value());
00139             }
00140             auto_->set_final(*i, weight * auto_->get_final(*i));
00141           }
00142           return auto_;
00143         }
00144         END
00145 
00146         MATCH__(RightWeight, node, w)
00147         {
00148           const semiring_t&     semiring = automata_set_.series().semiring();
00149           const semiring_elt_t  weight (semiring, w);
00150           automaton_ptr_t       auto_ = match(node);
00151 
00152           for (typename automaton_t::final_iterator f, next = auto_->final().begin();
00153                next != auto_->final().end();)
00154           {
00155             //We need to store the next iterator before using the current one
00156             //to avoid an invalid iterator after having called set_final.
00157             //Indeed, set_final can delete the iterator if its second parameter
00158             //is the zero of the serie.
00159             f = next;
00160             next++;
00161             auto_->set_final(*f, auto_->get_final(*f) * weight);
00162           }
00163           return auto_;
00164         }
00165         END
00166 
00167         MATCH_(Constant, m)
00168         {
00169           automaton_ptr_t auto_ = new automaton_t(automata_set_);
00170           hstate_t new_i = auto_->add_state();
00171           hstate_t last = new_i;
00172           hstate_t new_f = new_i;
00173           for (typename monoid_elt_value_t::const_iterator i = m.begin();
00174                i != m.end(); ++i)
00175           {
00176             new_f = auto_->add_state();
00177             auto_->add_letter_transition(last, new_f, *i);
00178             last = new_f;
00179           }
00180           auto_->set_initial(new_i);
00181           auto_->set_final(new_f);
00182           return auto_;
00183         }
00184         END
00185 
00186         MATCH(Zero)
00187         {
00188           automaton_ptr_t auto_ = new automaton_t(automata_set_);
00189           hstate_t s = auto_->add_state();
00190           auto_->set_initial(s);
00191           return auto_;
00192         }
00193         END
00194 
00195         MATCH(One)
00196         {
00197           automaton_ptr_t auto_ = new automaton_t(automata_set_);
00198           hstate_t new_i = auto_->add_state();
00199           auto_->set_initial(new_i);
00200           auto_->set_final(new_i);
00201           return auto_;
00202         }
00203       END
00204 
00205       private:
00206         automata_set_t automata_set_;
00207     };
00208 
00209   }
00210 
00211   template <typename A,
00212             typename Output,
00213             typename Exp>
00214   void
00215   do_standard_of(const AutomataBase<A>&,
00216                  Output& output,
00217                  const Exp& kexp)
00218   {
00219     algebra::Standard_OfVisitor<Exp, Output, algebra::DispatchFunction<Exp> >
00220       m(output.structure().series());
00221     Output* res = m.match(kexp);
00222     output = *res;
00223     delete res;
00224   }
00225 
00226   template<typename A,
00227            typename T,
00228            typename Exp>
00229   void
00230   standard_of(Element<A, T>& out,
00231               const Exp& kexp)
00232   {
00233     do_standard_of(out.structure(), out, kexp);
00234   }
00235 
00236 } // vcsn
00237 
00238 #endif // ! VCSN_ALGORITHMS_STANDARD_OF_HXX

Generated on Thu Oct 9 20:22:41 2008 for Vaucanson by  doxygen 1.5.1