Vcsn  2.1
Be Rational
eval.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <vector>
4 
5 #include <vcsn/ctx/traits.hh>
6 #include <vcsn/dyn/fwd.hh>
7 #include <vcsn/dyn/automaton.hh>
8 #include <vcsn/dyn/label.hh>
9 #include <vcsn/dyn/weight.hh>
10 #include <vcsn/misc/algorithm.hh>
11 
12 namespace vcsn
13 {
14  namespace detail
15  {
16  template <typename Aut>
17  class evaluator
18  {
19  static_assert(labelset_t_of<Aut>::is_free(),
20  "evaluate: requires free labelset");
21 
22  using automaton_t = Aut;
26  using weight_t = typename weightset_t::value_t;
27 
28  // state -> weight.
29  using weights_t = std::vector<weight_t>;
30 
31  public:
33  : aut_(a)
34  {}
35 
36  weight_t operator()(const word_t& word) const
37  {
38  // Initialization.
39  const weight_t zero = ws_.zero();
40 
41  // An array indexed by state numbers.
42  //
43  // Do not use braces (v1{size, zero}): the type of zero might
44  // result in the compiler believing we are building a vector
45  // with two values: size and zero.
46  //
47  // We start with just two states numbered 0 and 1: pre() and
48  // post().
49  weights_t v1(2, zero);
50  v1.reserve(detail::back(aut_->all_states()) + 1);
51  v1[aut_->pre()] = ws_.one();
52  weights_t v2{v1};
53  v2.reserve(detail::back(aut_->all_states()) + 1);
54 
55  // Computation.
56  auto ls = *aut_->labelset();
57  for (auto l : ls.letters_of(ls.delimit(word)))
58  {
59  v2.assign(v2.size(), zero);
60  for (size_t s = 0; s < v1.size(); ++s)
61  if (!ws_.is_zero(v1[s])) // delete if bench >
62  for (auto t : aut_->out(s, l))
63  {
64  // Make sure the vectors are large enough for dst.
65  // Exponential growth on the capacity, but keep
66  // the actual size as small as possible.
67  auto dst = aut_->dst_of(t);
68  if (v2.size() <= dst)
69  {
70  auto capacity = v2.capacity();
71  while (capacity <= dst)
72  capacity *= 2;
73  v1.reserve(capacity);
74  v2.reserve(capacity);
75  v1.resize(dst + 1, zero);
76  v2.resize(dst + 1, zero);
77  }
78  // Introducing a reference to v2[aut_->dst_of(tr)] is
79  // tempting, but won't work for std::vector<bool>.
80  // FIXME: Specialize for Boolean?
81  v2[dst] =
82  ws_.add(v2[dst],
83  ws_.mul(v1[s], aut_->weight_of(t)));
84  }
85  std::swap(v1, v2);
86  }
87  return v1[aut_->post()];
88  }
89  private:
91  const weightset_t& ws_ = *aut_->weightset();
92  };
93 
94  } // namespace detail
95 
96  template <typename Aut>
97  inline
98  auto
99  eval(const Aut& a, const word_t_of<Aut>& w)
101  {
103  return e(w);
104  }
105 
106  namespace dyn
107  {
108  namespace detail
109  {
111  template <typename Aut, typename LabelSet>
112  weight
113  eval(const automaton& aut, const label& lbl)
114  {
115  const auto& a = aut->as<Aut>();
116  const auto& l = lbl->as<LabelSet>().label();
117  auto res = ::vcsn::eval(a, l);
118  const auto& ctx = a->context();
119  return make_weight(*ctx.weightset(), res);
120  }
121  }
122  }
123 } // namespace vcsn
std::shared_ptr< const detail::label_base > label
Definition: fwd.hh:59
evaluator(const automaton_t &a)
Definition: eval.hh:32
std::vector< weight_t > weights_t
Definition: eval.hh:29
typename weightset_t::value_t weight_t
Definition: eval.hh:26
Container::value_type back(const Container &container)
The last member of this Container.
Definition: algorithm.hh:26
auto eval(const Aut &a, const word_t_of< Aut > &w) -> weight_t_of< Aut >
Definition: eval.hh:99
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:48
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
Definition: traits.hh:51
weightset_t_of< automaton_t > weightset_t
Definition: eval.hh:25
state_t_of< automaton_t > state_t
Definition: eval.hh:23
typename labelset_t_of< base_t< ValueSet >>::word_t word_t_of
Definition: traits.hh:65
weight eval(const automaton &aut, const label &lbl)
Bridge.
Definition: eval.hh:113
static dyn::context ctx(const driver &d)
Get the context of the driver.
Definition: parse.cc:80
std::shared_ptr< const detail::weight_base > weight
Definition: fwd.hh:86
automaton_t aut_
Definition: eval.hh:90
weight make_weight(const WeightSet &ws, const typename WeightSet::value_t &w)
Definition: weight.hh:79
std::shared_ptr< detail::automaton_base > automaton
Definition: automaton.hh:69
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:47
weight_t operator()(const word_t &word) const
Definition: eval.hh:36
word_t_of< automaton_t > word_t
Definition: eval.hh:24
const weightset_t & ws_
Definition: eval.hh:91
typename detail::weight_t_of_impl< base_t< ValueSet >>::type weight_t_of
Definition: traits.hh:50