thompson.hxx

00001 // thompson.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, 2007 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_THOMPSON_HXX
00018 # define VCSN_ALGORITHMS_THOMPSON_HXX
00019 
00020 # include <vaucanson/algorithms/thompson.hh>
00021 
00022 # include <vaucanson/automata/concept/automata_base.hh>
00023 # include <vaucanson/algorithms/normalized.hh>
00024 
00025 namespace vcsn {
00026 
00027   /*----------------.
00028   | ThompsonVisitor |
00029   `----------------*/
00030   // FIXME : Non optimal version.
00031   //         There are too much construction of automaton.
00032 
00033   // FIXME : from now, it is only working over LetterAutomaton
00034 
00035   template <class Auto_, class Monoid_, class Semiring_>
00036   class ThompsonVisitor :
00037       public rat::ConstNodeVisitor<Monoid_, Semiring_>
00038   {
00039     public :
00040       typedef Auto_                                     automaton_t;
00041       typedef typename automaton_t::hstate_t            hstate_t;
00042       typedef typename automaton_t::set_t               automata_set_t;
00043       typedef typename automaton_t::series_set_t        series_set_t;
00044       typedef typename automaton_t::series_set_elt_t    series_set_elt_t;
00045       typedef typename series_set_elt_t::semiring_elt_t semiring_elt_t;
00046       typedef Monoid_                                   monoid_elt_value_t;
00047       typedef Semiring_                                 semiring_elt_value_t;
00048       typedef rat::Node<monoid_elt_value_t, semiring_elt_value_t> node_t;
00049 
00050     public :
00051 
00052       ThompsonVisitor(const series_set_t& s) : series_(s)
00053       {}
00054 
00055       virtual
00056       ~ThompsonVisitor()
00057       {}
00058 
00059       virtual void
00060       product(const node_t* lhs, const node_t* rhs)
00061       {
00062         automaton_t     *tmp_;
00063         rhs->accept(*this);
00064         tmp_ = auto_;
00065         lhs->accept(*this);
00066         concatenate_of_normalized_here(*auto_, *tmp_);
00067         delete(tmp_);
00068       }
00069 
00070       virtual void
00071       sum(const node_t* lhs, const node_t* rhs)
00072       {
00073         automaton_t     *tmp_;
00074         lhs->accept(*this);
00075         tmp_ = auto_;
00076         rhs->accept(*this);
00077         union_of_normalized_here(*auto_, *tmp_);
00078       }
00079 
00080       virtual void
00081       star(const node_t* node)
00082       {
00083         node->accept(*this);
00084         star_of_normalized_here(*auto_);
00085       }
00086 
00087       virtual void
00088       left_weight(const semiring_elt_value_t& w, const node_t* node)
00089       {
00090         node->accept(*this);
00091 
00092         typedef typename automaton_t::hstate_t  hstate_t;
00093         typedef typename automaton_t::initial_iterator initial_iterator;
00094         typedef typename automaton_t::final_iterator final_iterator;
00095 
00096         hstate_t new_i = auto_->add_state();
00097         hstate_t new_f = auto_->add_state();
00098 
00099         for_all_const_initial_states(i, *auto_)
00100         {
00101           series_set_elt_t t = auto_->series().zero_;
00102           t.assoc(auto_->series().monoid().identity(SELECT(monoid_elt_value_t)), w);
00103           auto_->add_series_transition(new_i, *i, t);
00104         }
00105         for_all_const_final_states(f, *auto_)
00106           auto_->add_spontaneous(*f, new_f);
00107 
00108         auto_->clear_initial();
00109         auto_->clear_final();
00110 
00111         auto_->set_initial(new_i);
00112         auto_->set_final(new_f);
00113       }
00114 
00115       virtual void
00116       right_weight(const semiring_elt_value_t& w, const node_t* node)
00117       {
00118         node->accept(*this);
00119 
00120         typedef typename automaton_t::hstate_t  hstate_t;
00121         typedef typename automaton_t::initial_iterator initial_iterator;
00122         typedef typename automaton_t::final_iterator final_iterator;
00123 
00124         hstate_t new_i = auto_->add_state();
00125         hstate_t new_f = auto_->add_state();
00126 
00127         for_all_const_initial_states(i, *auto_)
00128           auto_->add_spontaneous(new_i, *i);
00129         for_all_const_final_states(f, *auto_)
00130         {
00131           series_set_elt_t t = auto_->series().zero_;
00132           t.assoc(auto_->series().monoid().identity(SELECT(monoid_elt_value_t)), w);
00133           auto_->add_series_transition(*f, new_f, t);
00134         }
00135 
00136         auto_->clear_initial();
00137         auto_->clear_final();
00138 
00139         auto_->set_initial(new_i);
00140         auto_->set_final(new_f);
00141       }
00142 
00143       virtual void
00144       constant(const monoid_elt_value_t& m)
00145       {
00146         auto_ = new automaton_t(automata_set_t(series_));
00147         hstate_t new_i = auto_->add_state();
00148         hstate_t last = new_i;
00149         hstate_t new_f;
00150         for (typename monoid_elt_value_t::const_iterator i = m.begin();
00151              i != m.end(); ++i)
00152         {
00153           new_f = auto_->add_state();
00154           auto_->add_letter_transition(last, new_f, *i);
00155           last = new_f;
00156         }
00157         auto_->set_initial(new_i);
00158         auto_->set_final(new_f);
00159       }
00160 
00161       virtual void
00162       zero()
00163       {
00164         auto_ = new automaton_t(automata_set_t(series_));
00165         auto_->set_initial(auto_->add_state());
00166         auto_->set_final(auto_->add_state());
00167       }
00168 
00169       virtual void
00170       one()
00171       {
00172         auto_ = new automaton_t(automata_set_t(series_));
00173         hstate_t new_i = auto_->add_state();
00174         hstate_t new_f = auto_->add_state();
00175         auto_->set_initial(new_i);
00176         auto_->set_final(new_f);
00177         auto_->add_spontaneous(new_i, new_f);
00178       }
00179 
00180       const automaton_t         &get_auto() const
00181       {
00182         return *auto_;
00183       }
00184 
00185     private :
00186       automaton_t               *auto_;
00187       const series_set_t        &series_;
00188   };
00189 
00190   template <typename A, typename auto_t,
00191             typename Letter, typename Weight>
00192   void
00193   do_thompson_of(const AutomataBase<A>&,
00194                  auto_t& output,
00195                  const rat::exp<Letter, Weight>& kexp)
00196   {
00197     ThompsonVisitor<auto_t, Letter, Weight> visitor(output.structure().series());
00198 
00199     // FIXME :
00200     // Static assert : Letter = monoid_elt_value_t,
00201     //                 Weight = semiring_elt_value_t
00202     kexp.accept(visitor);
00203     output = visitor.get_auto();
00204   }
00205 
00206   template<typename A,      typename T,
00207            typename Letter, typename Weight>
00208   void
00209   thompson_of(Element<A, T>& out,
00210               const rat::exp<Letter, Weight>& kexp)
00211   {
00212     do_thompson_of(out.structure(), out, kexp);
00213   }
00214 
00215   template <class AutoType, class S, class T>
00216   Element<Automata<S>, AutoType>
00217   thompson_of(const Element<S, T>& exp)
00218   {
00219     Automata<S>                         automata_set(exp.structure());
00220     Element<Automata<S>, AutoType>      automata(automata_set);
00221 
00222     thompson_of(automata, exp.value());
00223     return automata;
00224   }
00225 } // vcsn
00226 
00227 #endif // ! VCSN_ALGORITHMS_THOMPSON_HXX

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