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 typedef typename exp_list_t::const_iterator const_iterator;
00131
00132 typename T::n_const_t* left_node =
00133 dynamic_cast<typename T::n_const_t*>(left.back().value().base());
00134 typename T::n_const_t* right_node =
00135 dynamic_cast<typename T::n_const_t*>(right.front().value().base());
00136
00137 std::list<exp_t> result(left);
00138
00139 if (left_node and right_node)
00140 {
00141 result.back() = exp_t(exp_.structure(),
00142 left_node->value_ + right_node->value_);
00143 for (const_iterator i = ++right.begin(); i != right.end(); ++i)
00144 result.push_back(*i);
00145 }
00146 else
00147 for (const_iterator i = right.begin(); i != right.end(); ++i)
00148 result.push_back(*i);
00149 return result;
00150 }
00151
00152
00153 public:
00154
00155 exp_t get()
00156 {
00157 return_type l = match(exp_.value());
00158 return convert(l);
00159 }
00160
00161
00162 MATCH__(Product, lhs, rhs)
00163 {
00164 typedef typename return_type::iterator iterator;
00165
00166 return_type llist = match(lhs);
00167 return_type rlist = match(rhs);
00168 return_type result;
00169
00170 for (iterator i = llist.begin(); i != llist.end(); ++i)
00171 for (iterator j = rlist.begin(); j != rlist.end(); ++j)
00172 result[list_concat(i->first, j->first)] = i->second * j->second;
00173 return result;
00174 }
00175 END
00176
00177 MATCH__(Sum, lhs, rhs)
00178 {
00179 return list_union(match(lhs), match(rhs));
00180 }
00181 END
00182
00183 MATCH_(Star, e)
00184 {
00185 return_type l = match(e);
00186 return convert(convert(l).star());
00187 }
00188 END
00189
00190 MATCH__(LeftWeight, w, e)
00191 {
00192 typedef typename return_type::iterator iterator;
00193
00194 return_type l = match(e);
00195 return_type result;
00196
00197 for (iterator i = l.begin(); i != l.end(); ++i)
00198 result[i->first] = semiring_elt_t(w) * i->second;
00199 return result;
00200 }
00201 END
00202
00203 MATCH__(RightWeight, e, w)
00204 {
00205 typedef typename return_type::iterator iterator;
00206
00207 return_type l = match(e);
00208 return_type result;
00209
00210 for (iterator i = l.begin(); i != l.end(); ++i)
00211 result[i->first] = i->second * semiring_elt_t(w);
00212 return result;
00213 }
00214 END
00215
00216 MATCH_(Constant, m)
00217 {
00218 return convert(exp_t(exp_.structure(), m));
00219 }
00220 END
00221
00222 MATCH(Zero)
00223 {
00224 return convert(exp_.structure().zero(SELECT(T)));
00225 }
00226 END
00227
00228 MATCH(One)
00229 {
00230 return convert(exp_.structure().identity(SELECT(T)));
00231 }
00232 END
00233
00234 private:
00235 Element<Series, T> exp_;
00236 };
00237
00238 }
00239
00240 template <class S, class E>
00241 E do_expand(const algebra::SeriesBase<S>&, const E& exp)
00242 {
00243 typedef typename E::value_t T;
00244
00245 algebra::KRatExpExpander< S, T, algebra::DispatchFunction<T> > matcher(exp);
00246 return matcher.get();
00247 }
00248
00249 template <class Series, class T>
00250 Element<Series, T>
00251 expand(const Element<Series, T>& exp)
00252 {
00253 return do_expand(exp.structure(), exp);
00254 }
00255
00256 }
00257
00258 #endif // ! VCSN_ALGORITHMS_KRAT_EXP_EXPAND_HXX