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

- File List
- File Members

# 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, 2008, 2009 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 <utility>
    00021
    00022 # include <vaucanson/algorithms/thompson.hh>
    00023
    00024 # include <vaucanson/automata/concept/automata_base.hh>
    00025 # include <vaucanson/misc/usual_macros.hh>
    00026
    00027 namespace vcsn {
    00028
    00029   /*----------------.
    00030   | ThompsonVisitor |
    00031   `----------------*/
    00032   // FIXME : from now, it is only working over LetterAutomaton
    00033
    00034   template <class Auto_, class Monoid_, class Semiring_>
    00035   class ThompsonVisitor :
    00036       public rat::ConstNodeVisitor<Monoid_, Semiring_>
    00037   {
    00038     public :
    00039       typedef Auto_                                     automaton_t;
    00040       typedef typename automaton_t::hstate_t            hstate_t;
    00041       typedef typename automaton_t::set_t               automata_set_t;
    00042       typedef typename automaton_t::series_set_t        series_set_t;
    00043       typedef typename automaton_t::series_set_elt_t    series_set_elt_t;
    00044       typedef typename series_set_elt_t::semiring_elt_t semiring_elt_t;
    00045       typedef Monoid_                                   monoid_elt_value_t;
    00046       typedef Semiring_                                 semiring_elt_value_t;
    00047       typedef rat::Node<monoid_elt_value_t, semiring_elt_value_t> node_t;
    00048
    00049     public :
    00050
    00051       ThompsonVisitor(automaton_t &a)
    00052         : auto_ (a)
    00053       {}
    00054
    00055       virtual
    00056       ~ThompsonVisitor()
    00057       {}
    00058
    00059       virtual void
    00060       product(const node_t* lhs, const node_t* rhs)
    00061       {
    00062         // Visit left tree
    00063         lhs->accept(*this);
    00064         // Store results
    00065         std::pair<hstate_t, hstate_t>     left_ini_fin = ini_fin_;
    00066         // Visit right tree
    00067         rhs->accept(*this);
    00068         // Create spontaneous link between
    00069         // final of left automaton and initial of right automaton.
    00070         auto_.add_spontaneous(left_ini_fin.second, ini_fin_.first);
    00071
    00072         // Save new initial state.
    00073         ini_fin_.first = left_ini_fin.first;
    00074       }
    00075
    00076       virtual void
    00077       sum(const node_t* lhs, const node_t* rhs)
    00078       {
    00079         lhs->accept(*this);
    00080
    00081         std::pair<hstate_t, hstate_t>     left_ini_fin = ini_fin_;
    00082         hstate_t new_i = auto_.add_state();
    00083         hstate_t new_f = auto_.add_state();
    00084
    00085         auto_.add_spontaneous(new_i, left_ini_fin.first);
    00086         auto_.add_spontaneous(left_ini_fin.second, new_f);
    00087
    00088         rhs->accept(*this);
    00089
    00090         auto_.add_spontaneous(new_i, ini_fin_.first);
    00091         auto_.add_spontaneous(ini_fin_.second, new_f);
    00092
    00093         ini_fin_.first = new_i;
    00094         ini_fin_.second = new_f;
    00095       }
    00096
    00097       virtual void
    00098       star(const node_t* node)
    00099       {
    00100         node->accept(*this);
    00101         auto_.add_spontaneous(ini_fin_.second, ini_fin_.first);
    00102
    00103         hstate_t new_i = auto_.add_state();
    00104         hstate_t new_f = auto_.add_state();
    00105
    00106         auto_.add_spontaneous(new_i, new_f);
    00107         auto_.add_spontaneous(new_i, ini_fin_.first);
    00108         auto_.add_spontaneous(ini_fin_.second, new_f);
    00109
    00110         ini_fin_.first = new_i;
    00111         ini_fin_.second = new_f;
    00112       }
    00113
    00114       virtual void
    00115       left_weight(const semiring_elt_value_t& w, const node_t* node)
    00116       {
    00117         node->accept(*this);
    00118
    00119         hstate_t new_i = auto_.add_state();
    00120         hstate_t new_f = auto_.add_state();
    00121
    00122         series_set_elt_t t = auto_.series().zero_;
    00123         t.assoc(auto_.series().monoid().identity(SELECT(monoid_elt_value_t)), w);
    00124         auto_.add_series_transition(new_i, ini_fin_.first, t);
    00125
    00126         auto_.add_spontaneous(ini_fin_.second, new_f);
    00127
    00128         ini_fin_.first = new_i;
    00129         ini_fin_.second = new_f;
    00130       }
    00131
    00132       virtual void
    00133       right_weight(const semiring_elt_value_t& w, const node_t* node)
    00134       {
    00135         node->accept(*this);
    00136
    00137         hstate_t new_i = auto_.add_state();
    00138         hstate_t new_f = auto_.add_state();
    00139
    00140         auto_.add_spontaneous(new_i, ini_fin_.first);
    00141
    00142         series_set_elt_t t = auto_.series().zero_;
    00143         t.assoc(auto_.series().monoid().identity(SELECT(monoid_elt_value_t)), w);
    00144         auto_.add_series_transition(ini_fin_.second, new_f, t);
    00145
    00146         ini_fin_.first = new_i;
    00147         ini_fin_.second = new_f;
    00148       }
    00149
    00150       virtual void
    00151       constant(const monoid_elt_value_t& m)
    00152       {
    00153         ini_fin_.first = auto_.add_state();
    00154         hstate_t link_state;
    00155
    00156         typename monoid_elt_value_t::const_iterator i = m.begin();
    00157
    00158         ini_fin_.second = auto_.add_state();
    00159         auto_.add_letter_transition(ini_fin_.first, ini_fin_.second, *i);
    00160         ++i;
    00161
    00162         while (i != m.end())
    00163         {
    00164           link_state = auto_.add_state();
    00165           auto_.add_spontaneous(ini_fin_.second, link_state);
    00166           ini_fin_.second = auto_.add_state();
    00167           auto_.add_letter_transition(link_state, ini_fin_.second, *i);
    00168           ++i;
    00169         }
    00170       }
    00171
    00172       virtual void
    00173       zero()
    00174       {
    00175         ini_fin_.first = auto_.add_state();
    00176         ini_fin_.second = auto_.add_state();
    00177       }
    00178
    00179       virtual void
    00180       one()
    00181       {
    00182         ini_fin_.first = auto_.add_state();
    00183         ini_fin_.second = auto_.add_state();
    00184         auto_.add_spontaneous(ini_fin_.first, ini_fin_.second);
    00185       }
    00186
    00187       const automaton_t         &get_auto() const
    00188       {
    00189         auto_.clear_initial();
    00190         auto_.clear_final();
    00191         auto_.set_initial(ini_fin_.first);
    00192         auto_.set_final(ini_fin_.second);
    00193         return auto_;
    00194       }
    00195
    00196       // finalize is used to only set initial and final states of auto_
    00197       // only once (to spare the multiple set and unset required elsewise).
    00198       void
    00199       finalize() const
    00200       {
    00201         auto_.set_initial(ini_fin_.first);
    00202         auto_.set_final(ini_fin_.second);
    00203       }
    00204
    00205     private :
    00206       automaton_t                       &auto_;
    00207       std::pair<hstate_t, hstate_t>     ini_fin_;
    00208   };
    00209
    00210   template <typename A, typename auto_t,
    00211             typename Letter, typename Weight>
    00212   void
    00213   do_thompson_of(const AutomataBase<A>&,
    00214                  auto_t& output,
    00215                  const rat::exp<Letter, Weight>& kexp)
    00216   {
    00217     // You should provide an empty automaton as output.
    00218     ThompsonVisitor<auto_t, Letter, Weight> visitor(output);
    00219     // FIXME :
    00220     // Static assert : Letter = monoid_elt_value_t,
    00221     //                 Weight = semiring_elt_value_t
    00222     kexp.accept(visitor);
    00223     visitor.finalize();
    00224   }
    00225
    00226   template<typename A,      typename T,
    00227            typename Letter, typename Weight>
    00228   void
    00229   thompson_of(Element<A, T>& out,
    00230               const rat::exp<Letter, Weight>& kexp)
    00231   {
    00232     do_thompson_of(out.structure(), out, kexp);
    00233   }
    00234
    00235   template <typename AutoType, typename S, typename K, typename T>
    00236   Element<Automata<S, K>, AutoType>
    00237   thompson_of(const Element<S, T>& exp)
    00238   {
    00239     Automata<S, K>                      automata_set(exp.structure());
    00240     Element<Automata<S, K>, AutoType>   automata(automata_set);
    00241
    00242     thompson_of(automata, exp.value());
    00243     return automata;
    00244   }
    00245 } // vcsn
    00246
    00247 #endif // ! VCSN_ALGORITHMS_THOMPSON_HXX