Vaucanson 1.4
|
00001 // krat_exp_expand.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, 2008, 2011 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_KRAT_EXP_EXPAND_HXX 00018 # define VCSN_ALGORITHMS_KRAT_EXP_EXPAND_HXX 00019 00020 # include <list> 00021 # include <map> 00022 00023 # include <vaucanson/algorithms/krat_exp_expand.hh> 00024 00025 # include <vaucanson/algebra/implementation/series/krat_exp_pattern.hh> 00026 00027 namespace vcsn 00028 { 00029 00030 namespace algebra { 00031 00032 // This is a trait to get more easily used types. 00033 template <typename S, typename T> 00034 struct pseudo_exp_list 00035 { 00036 typedef Element<S, T> exp_t; 00037 typedef std::list<exp_t> exp_list_t; 00038 typedef typename exp_t::semiring_elt_t semiring_elt_t; 00039 typedef std::map<exp_list_t, semiring_elt_t> ret_t; 00040 }; 00041 00042 // The Expander class. It breaks up the expression to build a map 00043 // and then rebuild it. 00044 template <class Series, class T, class Dispatch> 00045 struct KRatExpExpander : algebra::KRatExpMatcher< 00046 KRatExpExpander<Series, T, Dispatch>, 00047 T, 00048 typename pseudo_exp_list<Series, T>::ret_t, 00049 Dispatch 00050 > 00051 { 00052 public: 00053 typedef pseudo_exp_list<Series, T> trait; 00054 typedef typename trait::exp_t exp_t; 00055 typedef typename trait::ret_t return_type; 00056 typedef typename trait::exp_list_t exp_list_t; 00057 typedef KRatExpExpander<Series, T, Dispatch> self_t; 00058 typedef typename Element<Series, T>::semiring_elt_t semiring_elt_t; 00059 typedef typename semiring_elt_t::value_t semiring_elt_value_t; 00060 typedef typename Element<Series, T>::monoid_elt_t monoid_elt_t; 00061 typedef typename monoid_elt_t::set_t monoid_t; 00062 typedef typename monoid_t::alphabet_t alphabet_t; 00063 typedef typename alphabet_t::letter_t letter_t; 00064 INHERIT_CONSTRUCTORS(self_t, T, semiring_elt_t, Dispatch); 00065 00066 KRatExpExpander(const exp_t& exp) : 00067 exp_(exp) 00068 {} 00069 00070 // Some useful internal functions. 00071 private: 00072 // Convert the return_type into a rational expression. 00073 exp_t convert(const return_type& l) 00074 { 00075 typedef typename return_type::const_iterator iterator; 00076 typedef typename exp_list_t::const_iterator sub_iterator; 00077 00078 exp_t result = exp_.structure().zero(SELECT(T)); 00079 00080 for (iterator i = l.begin(); i != l.end(); ++i) 00081 { 00082 exp_list_t l = i->first; 00083 exp_t e = l.front(); 00084 for (sub_iterator j = ++l.begin(); j != l.end(); ++j) 00085 e *= *j; 00086 result += i->second * e; 00087 } 00088 00089 return result; 00090 } 00091 00092 // Convert a standard expression into the corresponding breaked one. 00093 return_type convert(const exp_t& e) 00094 { 00095 exp_list_t exp_list; 00096 exp_list.push_front(e); 00097 00098 return_type result; 00099 result[exp_list] = 00100 exp_.structure().semiring().identity(SELECT(semiring_elt_value_t)); 00101 00102 return result; 00103 } 00104 00105 // The union of two lists implemented by a map. If an element is in the 00106 // two lists then the weights are added. 00107 return_type list_union(const return_type& left, 00108 const return_type& right) 00109 { 00110 typedef typename return_type::const_iterator const_iterator; 00111 typedef typename return_type::iterator iterator; 00112 00113 return_type result(left); 00114 for (const_iterator i = right.begin(); i != right.end(); ++i) 00115 { 00116 iterator j = result.find(i->first); 00117 00118 if (j != result.end()) 00119 j->second += i->second; 00120 else 00121 result.insert(*i); 00122 } 00123 00124 return result; 00125 } 00126 00127 // Compute the concatenation of two lists 00128 exp_list_t list_concat(const exp_list_t& left, const exp_list_t& right) 00129 { 00130 00131 typename T::node_t* lnode = left.back().value().base(); 00132 typename T::node_t* rnode = right.front().value().base(); 00133 00134 // Handle concatenations when one operand is a constant (ONE or ZERO) 00135 if (dynamic_cast<typename T::n_one_t*>(lnode)) 00136 return right; 00137 if (dynamic_cast<typename T::n_one_t*>(rnode)) 00138 return left; 00139 if (dynamic_cast<typename T::n_zero_t*>(lnode)) 00140 return left; 00141 if (dynamic_cast<typename T::n_zero_t*>(rnode)) 00142 return right; 00143 00144 typedef typename exp_list_t::const_iterator const_iterator; 00145 std::list<exp_t> result(left); 00146 00147 // If the last exp from left and the first exp from right 00148 // are words, concatenate them. 00149 typename T::n_const_t* left_node = 00150 dynamic_cast<typename T::n_const_t*>(lnode); 00151 typename T::n_const_t* right_node = 00152 dynamic_cast<typename T::n_const_t*>(rnode); 00153 if (left_node and right_node) 00154 { 00155 result.back() = exp_t(exp_.structure(), 00156 left_node->value_ + right_node->value_); 00157 for (const_iterator i = ++right.begin(); i != right.end(); ++i) 00158 result.push_back(*i); 00159 } 00160 else 00161 for (const_iterator i = right.begin(); i != right.end(); ++i) 00162 result.push_back(*i); 00163 return result; 00164 } 00165 00166 // Public functions. 00167 public: 00168 // This function convert the result the original form. 00169 exp_t get() 00170 { 00171 return_type l = this->match(exp_.value()); 00172 return convert(l); 00173 } 00174 00175 // Match functions. 00176 MATCH__(Product, lhs, rhs) 00177 { 00178 typedef typename return_type::iterator iterator; 00179 00180 return_type llist = this->match(lhs); 00181 return_type rlist = this->match(rhs); 00182 return_type result; 00183 00184 for (iterator i = llist.begin(); i != llist.end(); ++i) 00185 for (iterator j = rlist.begin(); j != rlist.end(); ++j) 00186 { 00187 exp_list_t p = list_concat(i->first, j->first); 00188 00189 iterator pi = result.find(p); 00190 if (pi != result.end()) 00191 pi->second += i->second * j->second; 00192 else 00193 result[p] = i->second * j->second; 00194 } 00195 return result; 00196 } 00197 END 00198 00199 MATCH__(Sum, lhs, rhs) 00200 { 00201 return list_union(this->match(lhs), this->match(rhs)); 00202 } 00203 END 00204 00205 MATCH_(Star, e) 00206 { 00207 return_type l = this->match(e); 00208 return convert(convert(l).star()); 00209 } 00210 END 00211 00212 MATCH__(LeftWeight, w, e) 00213 { 00214 typedef typename return_type::iterator iterator; 00215 00216 return_type l = this->match(e); 00217 return_type result; 00218 00219 for (iterator i = l.begin(); i != l.end(); ++i) 00220 result[i->first] = semiring_elt_t(w) * i->second; 00221 return result; 00222 } 00223 END 00224 00225 MATCH__(RightWeight, e, w) 00226 { 00227 typedef typename return_type::iterator iterator; 00228 00229 return_type l = this->match(e); 00230 return_type result; 00231 00232 for (iterator i = l.begin(); i != l.end(); ++i) 00233 result[i->first] = i->second * semiring_elt_t(w); 00234 return result; 00235 } 00236 END 00237 00238 MATCH_(Constant, m) 00239 { 00240 return convert(exp_t(exp_.structure(), m)); 00241 } 00242 END 00243 00244 MATCH(Zero) 00245 { 00246 return convert(exp_.structure().zero(SELECT(T))); 00247 } 00248 END 00249 00250 MATCH(One) 00251 { 00252 return convert(exp_.structure().identity(SELECT(T))); 00253 } 00254 END 00255 00256 private: 00257 Element<Series, T> exp_; 00258 }; 00259 00260 } // ! algebra 00261 00262 template <class S, class E> 00263 E do_expand(const algebra::SeriesBase<S>&, const E& exp) 00264 { 00265 typedef typename E::value_t T; 00266 00267 algebra::KRatExpExpander< S, T, algebra::DispatchFunction<T> > matcher(exp); 00268 return matcher.get(); 00269 } 00270 00271 template <class Series, class T> 00272 Element<Series, T> 00273 expand(const Element<Series, T>& exp) 00274 { 00275 return do_expand(exp.structure(), exp); 00276 } 00277 00278 } // ! vcsn 00279 00280 #endif // ! VCSN_ALGORITHMS_KRAT_EXP_EXPAND_HXX