Vaucanson  1.4.1
aci_canonical.hxx
1 // aci_canonical.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, 2006, 2008, 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_ACI_CANONICAL_HXX
18 # define VCSN_ALGORITHMS_ACI_CANONICAL_HXX
19 
21 
22 # include <vaucanson/algebra/concept/series_base.hh>
23 # include <vaucanson/algebra/implementation/series/krat_exp_pattern.hh>
24 
25 # include <set>
26 
27 namespace vcsn
28 {
29 
38  template <class Series, class T, class Dispatch>
39  struct KRatExpAciCanonical : algebra::KRatExpMatcher<
40  KRatExpAciCanonical<Series, T, Dispatch>,
41  T,
42  std::set< Element<Series, T> >,
43  Dispatch
44  >
45  {
46  typedef Element<Series, T> exp_t;
47  typedef std::set<exp_t> set_t;
48  typedef std::set<exp_t> return_type;
49  typedef typename set_t::iterator iterator_t;
51  typedef typename Element<Series, T>::semiring_elt_t semiring_elt_t;
52  typedef typename semiring_elt_t::value_t semiring_elt_value_t;
53  typedef typename Element<Series, T>::monoid_elt_t monoid_elt_t;
54  typedef typename monoid_elt_t::set_t monoid_t;
55  typedef typename monoid_t::alphabet_t alphabet_t;
56  typedef typename alphabet_t::letter_t letter_t;
57  INHERIT_CONSTRUCTORS(self_t, T, semiring_elt_t, Dispatch);
58 
60  exp_(exp)
61  {}
62 
63  // Useful functions:
64  private:
65  set_t apply_sum(set_t expset)
66  {
67  if (expset.size() != 1)
68  {
69  iterator_t i = expset.begin();
70  exp_t res = *i;
71  for (i++; i != expset.end(); ++i)
72  {
73  res += *i;
74  }
75  expset.clear();
76  expset.insert(res);
77  }
78  return expset;
79  }
80 
81  set_t& put_in(set_t& s, exp_t e)
82  {
83  s.clear();
84  s.insert(e);
85  return s;
86  }
87 
88  public:
89  exp_t set2exp(set_t expset)
90  {
91  expset = apply_sum(expset);
92  return *expset.begin();
93  }
94 
95  // Matches:
96  MATCH__(Product, lhs, rhs)
97  {
98  set_t lset = apply_sum(this->match(lhs));
99  set_t rset = apply_sum(this->match(rhs));
100  put_in(lset, *lset.begin() * *rset.begin());
101  return lset;
102  }
103  END
104 
105  MATCH__(Sum, lhs, rhs)
106  {
107  set_t lset = this->match(lhs);
108  set_t rset = this->match(rhs);
109  set_t res;
110  merge(lset.begin(), lset.end(),
111  rset.begin(), rset.end(),
112  inserter(res, res.begin()));
113  return res;
114  }
115  END
116 
117  MATCH_(Star, e)
118  {
119  set_t cset = apply_sum(this->match(e));
120  exp_t exp = *cset.begin();
121  put_in(cset, exp.star());
122  return cset;
123  }
124  END
125 
126  MATCH__(LeftWeight, w, e)
127  {
128  set_t cset = apply_sum(this->match(e));
129  put_in(cset, semiring_elt_t(w) * *cset.begin());
130  return cset;
131  }
132  END
133 
134  MATCH__(RightWeight, e, w)
135  {
136  set_t cset = apply_sum(this->match(e));
137  put_in(cset, *cset.begin() * semiring_elt_t(w));
138  return cset;
139  }
140  END
141 
142  MATCH_(Constant, m)
143  {
144  set_t res;
145  Element<Series, T> s (exp_.structure(), m);
146  res.insert(s);
147  return res;
148  }
149  END
150 
151  MATCH(Zero)
152  {
153  set_t res;
154  res.insert(exp_.structure().zero(SELECT(T)));
155  return res;
156  }
157  END
158 
159  MATCH(One)
160  {
161  set_t res;
162  res.insert(exp_.structure().identity(SELECT(T)));
163  return res;
164  }
165  END
166 
167  private:
168  Element<Series, T> exp_;
169  };
170 
171  template <typename S, typename SI>
173  do_canonical(const algebra::SeriesBase<S>&, const Element<S, SI>& exp)
174  {
176  return matcher.set2exp(matcher.match(exp.value()));
177  }
178 
179  template <typename S, typename SI>
180  Element<S, SI>
182  {
183  BENCH_TASK_SCOPED("canonical");
184  return do_canonical(exp.structure(), exp);
185  }
186 
187 }
188 
189 #endif // ! VCSN_ALGORITHMS_ACI_CANONICAL_HXX