Vaucanson  1.4.1
krat_exp_derivation.hxx
1 // krat_exp_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, 2011 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_DERIVATION_HXX
18 # define VCSN_ALGORITHMS_KRAT_EXP_DERIVATION_HXX
19 
21 
22 # include <vaucanson/algebra/implementation/series/krat_exp_pattern.hh>
24 
25 namespace vcsn {
26 
27  template <class Series, class T, class Dispatch>
28  struct KRatExpDerivation : algebra::KRatExpMatcher<
29  KRatExpDerivation<Series, T, Dispatch>,
30  T,
31  Element<Series, T>,
32  Dispatch
33  >
34  {
35  typedef KRatExpDerivation<Series, T, Dispatch> self_t;
36  typedef Element<Series, T> return_type;
37  typedef typename Element<Series, T>::semiring_elt_t semiring_elt_t;
38  typedef typename semiring_elt_t::value_t semiring_elt_value_t;
39  typedef typename Element<Series, T>::monoid_elt_t monoid_elt_t;
40  typedef typename monoid_elt_t::value_t monoid_elt_value_t;
41  typedef typename monoid_elt_t::set_t monoid_t;
42  typedef typename monoid_t::alphabet_t alphabet_t;
43  typedef typename alphabet_t::letter_t letter_t;
44  INHERIT_CONSTRUCTORS(self_t, T, semiring_elt_t, Dispatch);
45 
46  KRatExpDerivation(const Element<Series, T>& exp,
47  letter_t a) :
48  undefined(false),
49  exp_(exp),
50  a_(a)
51  {}
52 
53  Element<Series, T> series(const T& e)
54  {
55  return Element<Series, T>(exp_.structure(), e);
56  }
57 
58  MATCH__(Product, lhs, rhs)
59  {
60  std::pair<semiring_elt_t, bool> ret = constant_term(series(lhs));
61  if (ret.second == false)
62  {
63  undefined = true;
64  return return_type(exp_.structure());
65  }
66  return (this->match(lhs) * rhs) + ret.first * this->match(rhs);
67  }
68  END
69 
70  MATCH__(Sum, lhs, rhs)
71  {
72  return this->match(lhs) + this->match(rhs);
73  }
74  END
75 
76  MATCH_(Star, e)
77  {
78  std::pair<semiring_elt_t, bool> ret = constant_term(series(e));
79  if ((ret.second == false) || (ret.first.starable() == false))
80  {
81  undefined = true;
82  return return_type(exp_.structure());
83  }
84  return ret.first.star() * this->match(e) * e.clone().star();
85  }
86  END
87 
88  MATCH__(LeftWeight, w, e)
89  {
90  return semiring_elt_t(w) * this->match(e);
91  }
92  END
93 
94  MATCH__(RightWeight, e, w)
95  {
96  return this->match(e) * semiring_elt_t(w);
97  }
98  END
99 
100  MATCH_(Constant, m)
101  {
102  if (m[0] == a_)
103  {
104  if (m.length() == 1)
105  return algebra::identity_as<T>::of(exp_.structure());
106  else
107  return Element<Series, T> (exp_.structure(), m.substr(1));
108  }
109  else
110  return algebra::zero_as<T>::of(exp_.structure());
111  }
112  END
113 
114  MATCH(Zero)
115  {
116  return algebra::zero_as<T>::of(exp_.structure());
117  }
118  END
119 
120  MATCH(One)
121  {
122  return algebra::zero_as<T>::of(exp_.structure());
123  }
124  END
125 
126  bool undefined;
127 
128  private:
129  Element<Series, T> exp_;
130  letter_t a_;
131  };
132 
133  template <class Series, class T, class Letter>
134  std::pair<Element<Series, T>, bool>
136  Letter a)
137  {
138  KRatExpDerivation<Series, T, algebra::DispatchFunction<T> >
139  matcher(exp, a);
140  Element<Series, T> ret = matcher.match(exp.value());
141  if (matcher.undefined)
142  return std::make_pair(ret, false);
143  return std::make_pair(ret, true);
144  }
145 
146  template <class Series, class T, class Word>
147  std::pair<Element<Series, T>, bool>
149  Word w)
150  {
151  Element<Series, T> ret(exp);
152  for (typename Word::reverse_iterator a = w.rbegin();
153  a != w.rend(); ++a)
154  {
155  KRatExpDerivation<Series, T, algebra::DispatchFunction<T> >
156  matcher(exp, *a);
157  ret = matcher.match(ret.value());
158  if (matcher.undefined)
159  return std::make_pair(ret, false);
160  }
161  return std::make_pair(ret, true);
162  }
163 
164 } // vcsn
165 
166 #endif // ! VCSN_ALGORITHMS_KRAT_EXP_DERIVATION_HXX