00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
00031
00032
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
00063 lhs->accept(*this);
00064
00065 std::pair<hstate_t, hstate_t> left_ini_fin = ini_fin_;
00066
00067 rhs->accept(*this);
00068
00069
00070 auto_.add_spontaneous(left_ini_fin.second, ini_fin_.first);
00071
00072
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
00197
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
00218 ThompsonVisitor<auto_t, Letter, Weight> visitor(output);
00219
00220
00221
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 }
00246
00247 #endif // ! VCSN_ALGORITHMS_THOMPSON_HXX