Vaucanson  1.4.1
krat_exp_partial_derivation.hxx
1 // krat_exp_partial_derivation.hxx: this file is part of the Vaucanson project.
2 //
3 // Vaucanson, a generic library for finite state machines.
4 //
5 // Copyright (C) 2001, 2002, 2003, 2004, 2005 The Vaucanson Group.
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
11 //
12 // The complete GNU General Public Licence Notice can be found as the
13 // `COPYING' file in the root directory.
14 //
15 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
16 //
17 #ifndef VCSN_ALGORITHMS_KRAT_EXP_PARTIAL_DERIVATION_HXX
18 # define VCSN_ALGORITHMS_KRAT_EXP_PARTIAL_DERIVATION_HXX
19 
21 
22 # include <vaucanson/algebra/implementation/series/krat_exp_pattern.hh>
24 
25 namespace vcsn {
26 
27  namespace algebra {
28 
29  // Some operators are defined in order to make algorithm clearer
30  // and efficient
31 
32  // operator^ apply * between each element of the set and the other
33  // argument
34  template <typename T, typename U>
35  std::set<T> operator^ (std::set<T> set, U other)
36  {
37  typedef typename std::set<T>::iterator iterator;
38  std::set<T> result;
39  for (iterator i = set.begin(); i != set.end(); ++i)
40  result.insert(*i * other);
41  return result;
42  }
43 
44  template <typename T, typename U>
45  std::set<T> operator^ (U other, std::set<T> set)
46  {
47  typedef typename std::set<T>::iterator iterator;
48  std::set<T> result;
49  for (iterator i = set.begin(); i != set.end(); ++i)
50  result.insert(other * *i);
51  return result;
52  }
53 
54  // operator+ make the union of two set
55  template <typename T>
56  std::set<T> operator+ (std::set<T> s1, std::set<T> s2)
57  {
58  std::set<T> result;
59  merge(s1.begin(), s1.end(),
60  s2.begin(), s2.end(),
61  inserter(result, result.begin()));
62  return result;
63  }
64 
65  // It is a first implementation of partial derivate.
66  // It simply apply the definition of partial derivates.
67  template <class Series, class T, class Dispatch>
68  struct KRatExpPartialDerivation : algebra::KRatExpMatcher<
69  KRatExpPartialDerivation<Series, T, Dispatch>,
70  T,
71  std::set<Element<Series, T> >,
72  Dispatch
73  >
74  {
75  typedef KRatExpPartialDerivation<Series, T, Dispatch> self_t;
76  typedef Element<Series, T> exp_t;
77  typedef std::set<exp_t> set_t;
78  typedef set_t return_type;
79  typedef typename set_t::iterator iterator;
80  typedef typename Element<Series, T>::semiring_elt_t semiring_elt_t;
81  typedef typename semiring_elt_t::value_t semiring_elt_value_t;
82  typedef typename Element<Series, T>::monoid_elt_t monoid_elt_t;
83  typedef typename monoid_elt_t::value_t monoid_elt_value_t;
84  typedef typename monoid_elt_t::set_t monoid_t;
85  typedef typename monoid_t::alphabet_t alphabet_t;
86  typedef typename alphabet_t::letter_t letter_t;
87  INHERIT_CONSTRUCTORS(self_t, T, semiring_elt_t, Dispatch);
88 
89  KRatExpPartialDerivation(const Element<Series, T>& exp,
90  letter_t a) :
91  undefined(false),
92  exp_(exp),
93  a_(a)
94  {}
95 
96  Element<Series, T> series(const T& e)
97  {
98  return Element<Series, T>(exp_.structure(), e);
99  }
100 
101  MATCH__(Product, lhs, rhs)
102  {
103  std::pair<semiring_elt_t, bool> ret = constant_term(series(lhs));
104  if (ret.second == false)
105  {
106  undefined = true;
107  return return_type();
108  }
109  if (ret.first !=
110  exp_.structure().semiring().zero(SELECT(semiring_elt_value_t)))
111  return (match(lhs) ^ rhs) + (ret.first ^ match(rhs));
112  else
113  return (match(lhs) ^ rhs);
114  }
115  END
116 
117  MATCH__(Sum, lhs, rhs)
118  {
119  return match(lhs) + match(rhs);
120  }
121  END
122 
123  MATCH_(Star, e)
124  {
125  std::pair<semiring_elt_t, bool> ret = constant_term(series(e));
126  if ((ret.second == false) || (ret.first.starable() == false))
127  {
128  undefined = true;
129  return return_type();
130  }
131  return ret.first.star() ^ (match(e) ^ e.clone().star());
132  }
133  END
134 
135  MATCH__(LeftWeight, w, e)
136  {
137  return semiring_elt_t(w) ^ match(e);
138  }
139  END
140 
141  MATCH__(RightWeight, e, w)
142  {
143  return match(e) ^ semiring_elt_t(w);
144  }
145  END
146 
147  MATCH_(Constant, m)
148  {
149  return_type res;
150  if (m[0] == a_)
151  {
152  if (m.length() == 1)
153  res.insert(algebra::identity_as<T>::of(exp_.structure()));
154  else
155  res.insert(Element<Series, T> (exp_.structure(), m.substr(1)));
156  }
157  return res;
158  }
159  END
160 
161  MATCH(Zero)
162  {
163  return return_type();
164  }
165  END
166 
167  MATCH(One)
168  {
169  return return_type();
170  }
171  END
172 
173  bool undefined;
174 
175  private:
176  Element<Series, T> exp_;
177  letter_t a_;
178  };
179 
180  } // algebra
181 
182  template <class Series, class T, class Letter>
183  std::pair<std::set<Element<Series, T> >, bool>
185  Letter a)
186  {
187  algebra::KRatExpPartialDerivation<Series, T, algebra::DispatchFunction<T> >
188  matcher(exp, a);
189  std::set<Element<Series, T> > ret = matcher.match(exp.value());
190  if (matcher.undefined)
191  return std::make_pair(ret, false);
192  return std::make_pair(ret, true);
193  }
194 
195 } // vcsn
196 
197 #endif // ! VCSN_ALGORITHMS_KRAT_EXP_PARTIAL_DERIVATION_HXX