00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
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
00043
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
00071 private:
00072
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
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
00106
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
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
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
00148
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
00167 public:
00168
00169 exp_t get()
00170 {
00171 return_type l = this->match(exp_.value());
00172 return convert(l);
00173 }
00174
00175
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 }
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 }
00279
00280 #endif // ! VCSN_ALGORITHMS_KRAT_EXP_EXPAND_HXX