00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef VCSN_ALGORITHMS_KRAT_EXP_PARTIAL_DERIVATION_HXX
00018 # define VCSN_ALGORITHMS_KRAT_EXP_PARTIAL_DERIVATION_HXX
00019
00020 # include <vaucanson/algorithms/krat_exp_partial_derivation.hh>
00021
00022 # include <vaucanson/algebra/implementation/series/krat_exp_pattern.hh>
00023 # include <vaucanson/algorithms/krat_exp_constant_term.hh>
00024
00025 namespace vcsn {
00026
00027 namespace algebra {
00028
00029
00030
00031
00032
00033
00034 template <typename T, typename U>
00035 std::set<T> operator^ (std::set<T> set, U other)
00036 {
00037 typedef typename std::set<T>::iterator iterator;
00038 std::set<T> result;
00039 for (iterator i = set.begin(); i != set.end(); ++i)
00040 result.insert(*i * other);
00041 return result;
00042 }
00043
00044 template <typename T, typename U>
00045 std::set<T> operator^ (U other, std::set<T> set)
00046 {
00047 typedef typename std::set<T>::iterator iterator;
00048 std::set<T> result;
00049 for (iterator i = set.begin(); i != set.end(); ++i)
00050 result.insert(other * *i);
00051 return result;
00052 }
00053
00054
00055 template <typename T>
00056 std::set<T> operator+ (std::set<T> s1, std::set<T> s2)
00057 {
00058 std::set<T> result;
00059 merge(s1.begin(), s1.end(),
00060 s2.begin(), s2.end(),
00061 inserter(result, result.begin()));
00062 return result;
00063 }
00064
00065
00066
00067 template <class Series, class T, class Dispatch>
00068 struct KRatExpPartialDerivation : algebra::KRatExpMatcher<
00069 KRatExpPartialDerivation<Series, T, Dispatch>,
00070 T,
00071 std::set<Element<Series, T> >,
00072 Dispatch
00073 >
00074 {
00075 typedef KRatExpPartialDerivation<Series, T, Dispatch> self_t;
00076 typedef Element<Series, T> exp_t;
00077 typedef std::set<exp_t> set_t;
00078 typedef set_t return_type;
00079 typedef typename set_t::iterator iterator;
00080 typedef typename Element<Series, T>::semiring_elt_t semiring_elt_t;
00081 typedef typename semiring_elt_t::value_t semiring_elt_value_t;
00082 typedef typename Element<Series, T>::monoid_elt_t monoid_elt_t;
00083 typedef typename monoid_elt_t::value_t monoid_elt_value_t;
00084 typedef typename monoid_elt_t::set_t monoid_t;
00085 typedef typename monoid_t::alphabet_t alphabet_t;
00086 typedef typename alphabet_t::letter_t letter_t;
00087 INHERIT_CONSTRUCTORS(self_t, T, semiring_elt_t, Dispatch);
00088
00089 KRatExpPartialDerivation(const Element<Series, T>& exp,
00090 letter_t a) :
00091 undefined(false),
00092 exp_(exp),
00093 a_(a)
00094 {}
00095
00096 Element<Series, T> series(const T& e)
00097 {
00098 return Element<Series, T>(exp_.structure(), e);
00099 }
00100
00101 MATCH__(Product, lhs, rhs)
00102 {
00103 std::pair<semiring_elt_t, bool> ret = constant_term(series(lhs));
00104 if (ret.second == false)
00105 {
00106 undefined = true;
00107 return return_type();
00108 }
00109 if (ret.first !=
00110 exp_.structure().semiring().zero(SELECT(semiring_elt_value_t)))
00111 return (match(lhs) ^ rhs) + (ret.first ^ match(rhs));
00112 else
00113 return (match(lhs) ^ rhs);
00114 }
00115 END
00116
00117 MATCH__(Sum, lhs, rhs)
00118 {
00119 return match(lhs) + match(rhs);
00120 }
00121 END
00122
00123 MATCH_(Star, e)
00124 {
00125 std::pair<semiring_elt_t, bool> ret = constant_term(series(e));
00126 if ((ret.second == false) || (ret.first.starable() == false))
00127 {
00128 undefined = true;
00129 return return_type();
00130 }
00131 return ret.first.star() ^ (match(e) ^ e.clone().star());
00132 }
00133 END
00134
00135 MATCH__(LeftWeight, w, e)
00136 {
00137 return semiring_elt_t(w) ^ match(e);
00138 }
00139 END
00140
00141 MATCH__(RightWeight, e, w)
00142 {
00143 return match(e) ^ semiring_elt_t(w);
00144 }
00145 END
00146
00147 MATCH_(Constant, m)
00148 {
00149 return_type res;
00150 if (m[0] == a_)
00151 {
00152 if (m.length() == 1)
00153 res.insert(algebra::identity_as<T>::of(exp_.structure()));
00154 else
00155 res.insert(Element<Series, T> (exp_.structure(), m.substr(1)));
00156 }
00157 return res;
00158 }
00159 END
00160
00161 MATCH(Zero)
00162 {
00163 return return_type();
00164 }
00165 END
00166
00167 MATCH(One)
00168 {
00169 return return_type();
00170 }
00171 END
00172
00173 bool undefined;
00174
00175 private:
00176 Element<Series, T> exp_;
00177 letter_t a_;
00178 };
00179
00180 }
00181
00182 template <class Series, class T, class Letter>
00183 std::pair<std::set<Element<Series, T> >, bool>
00184 partial_derivate(const Element<Series, T>& exp,
00185 Letter a)
00186 {
00187 algebra::KRatExpPartialDerivation<Series, T, algebra::DispatchFunction<T> >
00188 matcher(exp, a);
00189 std::set<Element<Series, T> > ret = matcher.match(exp.value());
00190 if (matcher.undefined)
00191 return std::make_pair(ret, false);
00192 return std::make_pair(ret, true);
00193 }
00194
00195 }
00196
00197 #endif // ! VCSN_ALGORITHMS_KRAT_EXP_PARTIAL_DERIVATION_HXX