Vaucanson  1.4.1
eval.hxx
1 // eval.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 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_EVAL_HXX
18 # define VCSN_ALGORITHMS_EVAL_HXX
19 
21 # include <vaucanson/automata/concept/automata_base.hh>
23 # include <vaucanson/misc/usual_macros.hh>
24 # include <algorithm>
25 # include <vector>
26 
27 namespace vcsn {
28 
29  /*-----.
30  | Eval |
31  `-----*/
32 
33  // precondition : the automaton is realtime
34  template <typename auto_t, typename input_t, typename Selt>
35  struct eval_functor
36  {
37  AUTOMATON_TYPES(auto_t);
38 
39  typedef std::vector<semiring_elt_t> weights;
40 
41  const auto_t& a;
42  int max_hstate;
43 
44  weights v1, v2;
45 
46  typename weights::const_iterator w;
47  typename input_t::const_iterator l;
48 
49  template <typename A>
50  eval_functor(const AutomataBase<A>&, const auto_t& aut)
51  : a(aut), max_hstate(a.states().back() + 1),
52  v1(max_hstate, a.series().semiring().wzero_), v2(max_hstate)
53  {}
54 
55  void execute(const input_t& word, Selt& result)
56  {
57  const monoid_elt_t empty = algebra::identity_as<monoid_elt_value_t>::of(a.series().monoid());
58 
59  // Initialize
60  for_all_const_initial_states(i, a)
61  v1[*i] = a.get_initial(*i).get(empty);
62 
63  const semiring_elt_t zero = a.series().semiring().wzero_;
64 
65  // Computation
66  l = word.begin();
67  for (typename input_t::const_iterator w_end = word.end();
68  l != w_end; ++l)
69  {
70  std::fill(v2.begin(), v2.end(), zero);
71  int i = 0;
72  w = v1.begin();
73  for (typename weights::const_iterator v1_end = v1.end();
74  w != v1_end; ++w)
75  {
76  if (*w != zero)
77  {
78  for (delta_iterator t(a.value(), a.get_state(i)); ! t.done(); t.next())
79  {
80  monoid_elt_t l_w(a.series_of(*t).structure().monoid(), *l);
81  if (a.series_of(*t).get(l_w) != a.series().semiring().wzero_)
82  {
83  v2[a.dst_of(*t)] += *w *
84  a.series_of(*t).get(monoid_elt_t(a.structure().series().monoid(), *l));
85  }
86  }
87  }
88  ++i;
89  }
90  std::swap(v1, v2);
91  }
92 
93  // Result
94  result = zero;
95  int i = 0;
96  for_all_const_ (weights, w, v1)
97  {
98  if (*w != zero)
99  result += *w * a.get_final(i).get(empty);
100  ++i;
101  }
102  }
103  };
104 
105  /*----------.
106  | Wrapper. |
107  `----------*/
108 
109  template<typename A, typename AI, typename W>
110  typename Element<A, AI>::semiring_elt_t
111  eval(const Element<A, AI>& a, const W& word)
112  {
113  BENCH_TASK_SCOPED("eval");
114  typedef Element<A, AI> automaton_t;
115  AUTOMATON_TYPES(automaton_t);
116  semiring_elt_t ret(a.structure().series().semiring());
117 
118  // Check if the automaton is empty.
119  if (!is_empty(a))
120  {
121  eval_functor<automaton_t, W, semiring_elt_t> evalf(a.structure(), a);
122  evalf.execute(word, ret);
123  }
124 
125  return ret;
126  }
127 
128 } // ! vcsn
129 
130 #endif // ! VCSN_ALGORITHMS_EVAL_HXX