Vaucanson 1.4
|
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