Vaucanson 1.4
|
00001 // partial_rat_exp_derivation.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 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_INTERNAL_PARTIAL_RAT_EXP_DERIVATION_HXX 00018 # define VCSN_ALGORITHMS_INTERNAL_PARTIAL_RAT_EXP_DERIVATION_HXX 00019 00020 # include <vaucanson/algebra/implementation/series/krat_exp_pattern.hh> 00021 # include <vaucanson/algorithms/krat_exp_constant_term.hh> 00022 # include <vaucanson/algebra/implementation/series/krat.hh> 00023 # include <vaucanson/misc/contract.hh> 00024 00025 namespace vcsn { 00026 00027 template <typename T> 00028 void list_fusion_here(std::list<T>& dst, std::list<T>& src) 00029 { 00030 typedef typename std::list<T>::iterator iterator; 00031 typedef typename T::series_set_t series_set_t; 00032 typedef typename T::series_set_elt_value_t series_set_elt_value_t; 00033 typedef typename T::semiring_elt_t::value_t semiring_elt_value_t; 00034 00035 src.sort(unweighted_inf<series_set_t, series_set_elt_value_t>); 00036 dst.sort(unweighted_inf<series_set_t, series_set_elt_value_t>); 00037 dst.merge(src, unweighted_inf<series_set_t, series_set_elt_value_t>); 00038 iterator i = dst.begin(); 00039 while (i != dst.end()) 00040 { 00041 iterator next = i; 00042 if (++next != dst.end() and unweighted_eq(*next, *i)) 00043 { 00044 i->begin().semiring_elt() += next->begin().semiring_elt(); 00045 dst.erase(next); 00046 if (i->begin().semiring_elt() == 00047 i->begin().semiring_elt().structure().zero( 00048 SELECT(semiring_elt_value_t))) 00049 { 00050 next = i++; 00051 dst.erase(next); 00052 continue ; 00053 } 00054 } 00055 ++i; 00056 } 00057 } 00058 00059 template <typename S, typename T> 00060 void list_multiply_here_left(std::list<PartialExp<S, T> >& l, 00061 const typename PartialExp<S, T>::semiring_elt_t& w) 00062 { 00063 typedef std::list<PartialExp<S, T> > list_t; 00064 for (typename list_t::iterator i = l.begin(); i != l.end(); ++i) 00065 *i >>= w; 00066 } 00067 00068 template <typename S, typename T> 00069 void list_multiply_here_right(std::list<PartialExp<S, T> >& l, 00070 const typename PartialExp<S, T>::semiring_elt_t& w) 00071 { 00072 typedef std::list<PartialExp<S, T> > list_t; 00073 for (typename list_t::iterator i = l.begin(); i != l.end(); ++i) 00074 *i <<= w; 00075 } 00076 00077 template <typename S, typename T> 00078 void list_insert_here(std::list<PartialExp<S, T> >& l, 00079 const typename PartialExp<S,T>::node_t* elm) 00080 { 00081 typedef std::list<PartialExp<S, T> > list_t; 00082 for (typename list_t::iterator i = l.begin(); i != l.end(); ++i) 00083 i->insert(elm); 00084 } 00085 00092 template <typename Series, typename T> 00093 class PRatExpDerivationVisitor : 00094 public rat::ConstNodeVisitor<typename T::monoid_elt_value_t, 00095 typename T::semiring_elt_value_t> 00096 { 00097 public: 00098 typedef Element<Series, T> exp_t; 00099 typedef T series_set_elt_value_t; 00100 typedef typename T::node_t node_t; 00101 typedef typename std::list<PartialExp<Series, T> > return_type; 00102 typedef typename Element<Series, T>::semiring_elt_t semiring_elt_t; 00103 typedef typename semiring_elt_t::value_t semiring_elt_value_t; 00104 typedef typename Element<Series, T>::monoid_elt_t monoid_elt_t; 00105 typedef typename monoid_elt_t::value_t monoid_elt_value_t; 00106 typedef typename monoid_elt_t::set_t monoid_t; 00107 typedef typename monoid_t::alphabet_t alphabet_t; 00108 typedef typename alphabet_t::letter_t letter_t; 00109 00110 public: 00111 PRatExpDerivationVisitor(const exp_t& exp, 00112 const letter_t& a) : 00113 undefined(false), 00114 exp_(exp), 00115 a_(a), 00116 father_(NULL) 00117 {} 00118 00119 virtual 00120 ~PRatExpDerivationVisitor() 00121 {} 00122 00123 void match(const node_t* node) 00124 { 00125 father_ = node; 00126 node->accept(*this); 00127 } 00128 00129 private: 00130 Element<Series, T> series(const T& e) 00131 { 00132 return Element<Series, T>(exp_.structure(), e); 00133 } 00134 00135 public: 00136 virtual void 00137 product(const node_t* lhs, const node_t* rhs) 00138 { 00139 std::pair<semiring_elt_t, bool> ret = 00140 constant_term(series(series_set_elt_value_t(lhs))); 00141 if (ret.second == false) 00142 { 00143 undefined = true; 00144 return ; 00145 } 00146 00147 return_type tmp; 00148 if ( ret.first != 00149 exp_.structure().semiring().zero(SELECT(semiring_elt_value_t))) 00150 { 00151 match(rhs); 00152 list_multiply_here_left(result, ret.first); 00153 tmp = result; 00154 } 00155 00156 match(lhs); 00157 list_insert_here(result, rhs); 00158 list_fusion_here(result, tmp); 00159 } 00160 00161 virtual void 00162 sum(const node_t* lhs, const node_t* rhs) 00163 { 00164 match(rhs); 00165 return_type tmp = result; 00166 match(lhs); 00167 list_fusion_here(result, tmp); 00168 } 00169 00170 virtual void 00171 star(const node_t* node) 00172 { 00173 assertion(father_ != NULL); 00174 const typename T::node_t* father = father_; 00175 00176 std::pair<semiring_elt_t, bool> ret = 00177 constant_term(series(series_set_elt_value_t(node))); 00178 if ((ret.second == false) || (ret.first.starable() == false)) 00179 { 00180 undefined = true; 00181 return; 00182 } 00183 00184 match(node); 00185 list_insert_here(result, father); 00186 list_multiply_here_left(result, ret.first.star()); 00187 } 00188 00189 virtual void 00190 left_weight(const semiring_elt_value_t& w, const node_t* node) 00191 { 00192 match(node); 00193 list_multiply_here_left(result, semiring_elt_t(w)); 00194 } 00195 00196 virtual void 00197 right_weight(const semiring_elt_value_t& w, const node_t* node) 00198 { 00199 match(node); 00200 list_multiply_here_right(result, semiring_elt_t(w)); 00201 } 00202 00203 virtual void 00204 constant(const monoid_elt_value_t& m) 00205 { 00206 result = return_type(); 00207 if (m.length() != 1) 00208 { 00209 WARNING("PartialExp base is not realtime."); 00210 undefined = true; 00211 return; 00212 } 00213 if (m[0] == a_) 00214 result.push_back(PartialExp<Series, T>(exp_)); 00215 } 00216 00217 virtual void 00218 zero() 00219 { 00220 result = return_type(); 00221 } 00222 00223 virtual void 00224 one() 00225 { 00226 result = return_type(); 00227 } 00228 00229 public: 00230 bool undefined; 00231 return_type result; 00232 00233 private: 00234 const exp_t& exp_; 00235 const letter_t& a_; 00236 const typename T::node_t* father_; 00237 }; 00238 00239 00240 /*****************************************************************************/ 00241 /***************************** User's functions ******************************/ 00242 /*****************************************************************************/ 00243 00244 template <class Series, class T, class Letter> 00245 std::pair<std::list<PartialExp<Series, T> >, bool> 00246 prat_exp_derivate(const Element<Series, T>& exp, 00247 Letter a) 00248 { 00249 PRatExpDerivationVisitor<Series, T> visitor(exp, a); 00250 visitor.match(exp.value().base()); 00251 return std::make_pair(visitor.result, !visitor.undefined); 00252 } 00253 00254 template <class Series, class T, class Letter> 00255 std::pair<std::list<PartialExp<Series, T> >, bool> 00256 prat_exp_derivate(const PartialExp<Series, T>& exp, 00257 Letter a) 00258 { 00259 typedef PartialExp<Series, T> exp_t; 00260 typedef std::list<PartialExp<Series, T> > exp_list_t; 00261 typedef std::pair<exp_list_t, bool> return_type; 00262 typedef typename exp_t::const_iterator const_iterator; 00263 typedef typename Element<Series, T>::semiring_elt_t semiring_elt_t; 00264 typedef typename semiring_elt_t::value_t semiring_elt_value_t; 00265 typedef T series_set_elt_value_t; 00266 00267 // Save the first weight, and go to the first expression 00268 const_iterator i = exp.begin(); 00269 semiring_elt_t w = i.semiring_elt(); 00270 i++; 00271 00272 // Check if the exp is not empty 00273 if (i == exp.end()) 00274 return std::make_pair(exp_list_t(), true); 00275 00276 // Visit the first element of the exp 00277 PRatExpDerivationVisitor<Series, T> visitor(exp.exp(), a); 00278 const typename exp_t::node_t* n = i.node(); 00279 visitor.match(n); 00280 00281 // Insert other pointers and values into the result 00282 for (i++; i != exp.end(); ++i) 00283 if (i.on_node()) 00284 list_insert_here(visitor.result, i.node()); 00285 else 00286 list_multiply_here_right(visitor.result, i.semiring_elt()); 00287 00288 // Calculate the constant term 00289 std::pair<semiring_elt_t, bool> cterm = 00290 constant_term(Element<Series, T>(exp.exp_structure(), series_set_elt_value_t(n))); 00291 if (cterm.second == false) 00292 return std::make_pair(exp_list_t(), false); 00293 00294 // -------- If cterm != 0, look at the rest of the list --------------- 00295 if (cterm.first != 00296 exp.exp_structure().semiring().zero(SELECT(semiring_elt_value_t)) ) 00297 { 00298 // Build an exp from the orignal, without the head 00299 exp_t new_exp(exp); 00300 new_exp.nodes().pop_front(); 00301 new_exp.weights().pop_front(); 00302 00303 // Recall prat_exp_derivate on it 00304 return_type ret = prat_exp_derivate(new_exp, a); 00305 00306 // Multiply by constant term 00307 list_multiply_here_left(ret.first, cterm.first); 00308 00309 // Fusion results 00310 visitor.undefined = visitor.undefined || !ret.second; 00311 list_fusion_here(visitor.result, ret.first); 00312 } 00313 //------------------------------------------------------------------------ 00314 00315 // Multiply by the weight of exp 00316 list_multiply_here_left(visitor.result, w); 00317 00318 // Return the final result 00319 return std::make_pair(visitor.result, !visitor.undefined); 00320 } 00321 00322 } // vcsn 00323 00324 #endif // ! VCSN_ALGORITHMS_INTERNAL_PARTIAL_RAT_EXP_DERIVATION_HXX