- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

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