Vaucanson 1.4
|
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, 2008, 2009, 2010, 2011 00006 // The Vaucanson Group. 00007 // 00008 // This program is free software; you can redistribute it and/or 00009 // modify it under the terms of the GNU General Public License 00010 // as published by the Free Software Foundation; either version 2 00011 // of the License, or (at your option) any later version. 00012 // 00013 // The complete GNU General Public Licence Notice can be found as the 00014 // `COPYING' file in the root directory. 00015 // 00016 // The Vaucanson Group consists of people listed in the `AUTHORS' file. 00017 // 00018 #ifndef VCSN_ALGORITHMS_STANDARD_OF_HXX 00019 # define VCSN_ALGORITHMS_STANDARD_OF_HXX 00020 00021 # include <vaucanson/algorithms/standard_of.hh> 00022 00023 # include <vaucanson/algebra/implementation/series/krat_exp_pattern.hh> 00024 # include <vaucanson/algorithms/standard.hh> 00025 00026 # include <vaucanson/misc/usual_macros.hh> 00027 00028 namespace vcsn { 00029 00030 namespace algebra { 00031 00032 /*-------------------. 00033 | Standard_OfVisitor | 00034 `-------------------*/ 00035 template <class Exp_, 00036 class Auto_, 00037 class Dispatch_> 00038 class Standard_OfVisitor : 00039 public algebra::KRatExpMatcher< 00040 Standard_OfVisitor<Exp_, Auto_, Dispatch_>, 00041 Exp_, 00042 Auto_*, 00043 Dispatch_ 00044 > 00045 { 00046 public : 00047 typedef Auto_* automaton_ptr_t; 00048 typedef Auto_ automaton_t; 00049 typedef typename automaton_t::set_t automata_set_t; 00050 00051 typedef typename automaton_t::series_set_t series_set_t; 00052 typedef typename automaton_t::monoid_t monoid_t; 00053 typedef typename automaton_t::semiring_t semiring_t; 00054 00055 typedef typename automaton_t::series_set_elt_t series_set_elt_t; 00056 typedef typename automaton_t::monoid_elt_t monoid_elt_t; 00057 typedef typename automaton_t::semiring_elt_t semiring_elt_t; 00058 00059 typedef typename automaton_t::hstate_t hstate_t; 00060 typedef typename automaton_t::htransition_t htransition_t; 00061 00062 typedef typename Exp_::monoid_elt_value_t monoid_elt_value_t; 00063 typedef typename Exp_::semiring_elt_value_t semiring_elt_value_t; 00064 00065 typedef Standard_OfVisitor<Exp_, Auto_, Dispatch_> this_class; 00066 typedef algebra::KRatExpMatcher<this_class, Exp_, Auto_*, Dispatch_> 00067 parent_class; 00068 typedef typename parent_class::return_type return_type; 00069 00070 public : 00071 00072 Standard_OfVisitor(automaton_t& a) : 00073 automata_set_(a.series()), 00074 auto_(&a) 00075 { 00076 } 00077 00078 INHERIT_CONSTRUCTORS(this_class, Exp_, Auto_*, Dispatch_); 00079 00080 // Could not use standard.hh functions because of the storing system. 00081 // No map needed here. 00082 MATCH__(Product, lhs, rhs) 00083 { 00084 AUTOMATON_TYPES(automaton_t); 00085 this->match(lhs); 00086 00087 hstate_t lhs_i = initial_; 00088 00089 // Store final states and final values and clear it. 00090 typedef typename std::list<std::pair<hstate_t, series_set_elt_t> > 00091 list_fin_st_t; 00092 00093 list_fin_st_t lhs_tmp; 00094 00095 for_all_final_states(f, *auto_) 00096 lhs_tmp.push_back (std::pair<hstate_t, series_set_elt_t> 00097 (*f, auto_->get_final(*f))); 00098 auto_->clear_final(); 00099 00100 this->match(rhs); 00101 00102 // Restore the previously saved data. 00103 typedef std::list<hstate_t> list_st_t; 00104 00105 list_st_t lhs_finals; 00106 00107 for (typename list_fin_st_t::iterator i = lhs_tmp.begin(); 00108 i != lhs_tmp.end(); 00109 ++i) 00110 { 00111 auto_->set_final(i->first, i->second); 00112 lhs_finals.push_back (i->first); 00113 } 00114 00115 concat_of_standard_inside(auto_->structure(), 00116 *auto_, lhs_finals, initial_); 00117 00118 initial_ = lhs_i; 00119 return auto_; 00120 } 00121 END 00122 00123 MATCH__(Sum, lhs, rhs) 00124 { 00125 AUTOMATON_TYPES(automaton_t); 00126 typedef typename std::list<std::pair<hstate_t, series_set_elt_t> > 00127 list_fin_st_t; 00128 00129 this->match(lhs); 00130 00131 // Store lhs initial state. 00132 hstate_t left_i = initial_; 00133 00134 // Store final states and final values and clear it. 00135 list_fin_st_t lhs_tmp; 00136 00137 for_all_const_final_states(f, *auto_) 00138 lhs_tmp.push_back (std::pair<hstate_t, series_set_elt_t> 00139 (*f, auto_->get_final(*f))); 00140 00141 auto_->clear_final(); 00142 00143 this->match(rhs); 00144 00145 // Restore the previously saved data. 00146 for (typename list_fin_st_t::iterator i = lhs_tmp.begin(); 00147 i != lhs_tmp.end(); 00148 ++i) 00149 auto_->set_final(i->first, i->second); 00150 00151 sum_of_standard_inside(auto_->structure(), 00152 *auto_, left_i, initial_); 00153 00154 initial_ = left_i; 00155 return auto_; 00156 } 00157 END 00158 00159 MATCH_(Star, node) 00160 { 00161 AUTOMATON_TYPES(automaton_t); 00162 this->match(node); 00163 00164 precondition(auto_->get_final(initial_).starable()); 00165 00166 typedef typename std::list<hstate_t> list_fin_st_t; 00167 00168 // Store final states and final values and clear it. 00169 list_fin_st_t tmp; 00170 00171 for_all_final_states(f, *auto_) 00172 if (*f != initial_) 00173 tmp.push_back(*f); 00174 00175 star_of_standard_inside(auto_->structure(), 00176 *auto_, initial_, tmp); 00177 return auto_; 00178 } 00179 END 00180 00181 MATCH__(LeftWeight, w, node) 00182 { 00183 const semiring_t& semiring = automata_set_.series().semiring(); 00184 const semiring_elt_t weight (semiring, w); 00185 const series_set_elt_t ws(auto_->series(), weight); 00186 this->match(node); 00187 00188 left_ext_mult_of_standard_inside(auto_->structure(), 00189 *auto_, initial_, ws); 00190 return auto_; 00191 } 00192 END 00193 00194 MATCH__(RightWeight, node, w) 00195 { 00196 const semiring_t& semiring = automata_set_.series().semiring(); 00197 const semiring_elt_t weight (semiring, w); 00198 this->match(node); 00199 00200 for (typename automaton_t::final_iterator 00201 f, next = auto_->final().begin(); 00202 next != auto_->final().end();) 00203 { 00204 // We need to store the next iterator before using the 00205 // current one to avoid an invalid iterator after having 00206 // called set_final. Indeed, set_final() can delete the 00207 // iterator if its second parameter is the zero of the 00208 // series. 00209 f = next; 00210 next++; 00211 auto_->set_final(*f, auto_->get_final(*f) * weight); 00212 } 00213 00214 return auto_; 00215 } 00216 END 00217 00218 MATCH_(Constant, m) 00219 { 00220 initial_ = auto_->add_state(); 00221 hstate_t last = initial_; 00222 hstate_t new_f = initial_; 00223 00224 for (typename monoid_elt_value_t::const_iterator i = m.begin(); 00225 i != m.end(); ++i) 00226 { 00227 new_f = auto_->add_state(); 00228 auto_->add_letter_transition(last, new_f, *i); 00229 last = new_f; 00230 } 00231 auto_->set_initial(initial_); 00232 auto_->set_final(new_f); 00233 00234 return auto_; 00235 } 00236 END 00237 00238 MATCH(Zero) 00239 { 00240 initial_ = auto_->add_state(); 00241 auto_->set_initial(initial_); 00242 return auto_; 00243 } 00244 END 00245 00246 MATCH(One) 00247 { 00248 initial_ = auto_->add_state(); 00249 auto_->set_initial(initial_); 00250 auto_->set_final(initial_); 00251 return auto_; 00252 } 00253 END 00254 00255 private: 00256 automata_set_t automata_set_; 00257 // The automata used for construction 00258 hstate_t initial_; 00259 automaton_ptr_t auto_; 00260 00261 typedef 00262 class 00263 { 00264 public: 00265 inline hstate_t operator[] (hstate_t a) 00266 { 00267 return a; 00268 } 00269 } ident_t; 00270 00271 ident_t identity_; 00272 }; 00273 00274 } 00275 00276 template <typename A, 00277 typename Output, 00278 typename Exp> 00279 void 00280 do_standard_of(const AutomataBase<A>&, 00281 Output& output, 00282 const Exp& kexp) 00283 { 00284 algebra::Standard_OfVisitor<Exp, Output, algebra::DispatchFunction<Exp> > 00285 m(output); 00286 00287 m.match(kexp); 00288 } 00289 00290 template<typename A, 00291 typename T, 00292 typename Exp> 00293 void 00294 standard_of(Element<A, T>& out, 00295 const Exp& kexp) 00296 { 00297 do_standard_of(out.structure(), out, kexp); 00298 } 00299 00300 } // vcsn 00301 00302 #endif // ! VCSN_ALGORITHMS_STANDARD_OF_HXX