Vaucanson  1.4.1
berry_sethi.hxx
1 // berry_sethi.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, 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_BERRY_SETHI_HXX
18 # define VCSN_ALGORITHMS_BERRY_SETHI_HXX
19 
20 # include <list>
21 
23 
24 # include <vaucanson/algorithms/internal/build_pattern.hh>
25 # include <vaucanson/automata/concept/automata_base.hh>
26 
30 # include <vaucanson/misc/usual_macros.hh>
31 
32 namespace vcsn {
33 
34  using namespace algorithm_patterns;
35 
47  template <typename S, typename T>
48  typename linearize_element<S, T>::alphabet_t
50  {
51  typedef typename linearize_element<S, T>::alphabet_t alphabet_t;
52  typedef typename linearize_element<S, T>::letter_t letter_t;
53 
54  alphabet_t result = linearize(exp).structure().monoid().alphabet();
55  result.insert(letter_t(0, 0));
56  return result;
57  }
58 
69  template <typename Exp, typename Letter>
70  Exp
71  linear_exp_continuation(const Exp& exp, const Letter& l)
72  {
73  typedef typename Exp::set_t::monoid_t::alphabet_t alphabet_t;
74  typedef typename alphabet_t::iterator iterator;
75  typedef typename Exp::value_t value_t;
76 
77  if (l == Letter(0,0))
78  return exp;
79 
80  alphabet_t alpha = exp.structure().monoid().alphabet();
81  Exp zero = exp.structure().zero(SELECT(value_t));
82  std::list<Exp> exp_list;
83 
84  exp_list.push_back(exp);
85 
86  while (!exp_list.empty())
87  {
88  Exp exp = exp_list.front();
89  exp_list.pop_front();
90  Exp deriv = derivate(exp, l).first;
91 
92  if (deriv != zero)
93  return deriv;
94  else
95  for (iterator i = alpha.begin(); i != alpha.end(); ++i)
96  if (*i != l)
97  {
98  Exp deriv = derivate(exp, *i).first;
99  if (deriv != zero && deriv != exp)
100  exp_list.push_back(deriv);
101  }
102  }
103  return zero;
104  }
105 
125  template <typename T_auto, typename S, typename T>
126  struct BerrySethiAlgo : public MathAutomataConstructor <
127  BerrySethiAlgo<T_auto, S, T>,
128  T_auto,
129  typename linearize_element<S, T>::letter_t >
130  {
131  public:
133  typedef
136 
139  typedef typename linearize_element<S, T>::letter_t etiq_t;
141  // Common types.
142  AUTOMATON_TYPES(T_auto);
143  AUTOMATON_FREEMONOID_TYPES(T_auto);
144 
157  BerrySethiAlgo(const series_set_t& series, const exp_t& exp):
158  MathAutomataConstructor <BerrySethiAlgo, T_auto, etiq_t>
159  (series, linearized_alphabet(exp)),
160  linear_exp(linearize(exp)),
161  linear_alpha(linear_exp.structure().monoid().alphabet())
162  {
163  linear_alpha.insert(etiq_t(0, 0));
164  }
165 
167 
168  bool is_initial(const etiq_t& e) const
169  {
170  return (e == etiq_t(0, 0));
171  }
172 
173  bool is_final(const etiq_t& e) const
174  {
175  return constant_term(linear_exp_continuation(linear_exp, e)).first
176  != linear_exp.structure().semiring().zero(SELECT(semiring_elt_value_t));
177  }
180 
181  std::set<etiq_t> delta(const etiq_t& e, const letter_t& l)
182  {
183  typedef typename linear_alphabet_t::iterator iterator;
184  std::set<etiq_t> result;
185  linear_exp_t continuation_e = linear_exp_continuation(linear_exp, e);
186 
187  for (iterator i = linear_alpha.begin(); i != linear_alpha.end(); ++i)
188  if (i->first == l
189  && (derivation(continuation_e, *i)
190  == linear_exp_continuation(linear_exp, *i)))
191  result.insert(*i);
192  return result;
193  }
194 
195  private:
197  linear_exp_t derivation(const linear_exp_t& exp, const etiq_t& e)
198  {
199  if (e == etiq_t(0, 0))
200  return exp;
201  else
202  return derivate(exp, e).first;
203  }
204 
206  linear_exp_t linear_exp;
208  linear_alphabet_t linear_alpha;
209  };
210 
211  template<typename T_auto, typename S, typename T>
212  T_auto*
213  do_berry_sethi(const T_auto& out, const Element<S, T>& kexp)
214  {
215  BerrySethiAlgo<T_auto, S, T> berrysethi_algo(out.series(), kexp);
216  berrysethi_algo.run();
217  return berrysethi_algo.get();
218  }
219 
220  template<typename A, typename T, typename Exp>
221  void
222  berry_sethi(Element<A, T>& out, const Exp& kexp)
223  {
224  BENCH_TASK_SCOPED("berry_sethi");
225  Element<A, T>* tmp = do_berry_sethi(out, kexp);
226  out = *tmp;
227  delete tmp;
228  }
229 
230 } // vcsn
231 
232 #endif // ! VCSN_ALGORITHMS_BERRY_SETHI_HXX