Awali
Another Weighted Automata library
eval.hh
Go to the documentation of this file.
1 // This file is part of Awali.
2 // Copyright 2016-2022 Sylvain Lombardy, Victor Marsault, Jacques Sakarovitch
3 //
4 // Awali is a free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 
17 #ifndef AWALI_ALGOS_EVAL_HH
18 # define AWALI_ALGOS_EVAL_HH
19 
20 # include <algorithm>
21 # include <vector>
22 
23 #include <awali/sttc/ctx/traits.hh>
25 
26 namespace awali { namespace sttc {
27 
28  namespace internal
29  {
30  template <typename Aut>
31  class evaluator
32  {
33  static_assert(labelset_t_of<Aut>::is_free(),
34  "requires free labelset");
35 
36  using automaton_t = Aut;
38  using weightset_t = weightset_t_of<automaton_t>;
39  using weight_t = typename weightset_t::value_t;
40  using labelset_t = labelset_t_of<automaton_t>;
41 
42  // state -> weight.
43  using weights_t = std::vector<weight_t>;
44 
45  public:
46  evaluator(const automaton_t& a)
47  : a_(a)
48  , ws_(*a_->weightset())
49  , ls_(*a_->labelset())
50  {}
51 
52  void check(const word_t& word) const {
53  for(auto l : word)
54  if(!ls_.genset().has(l))
55  throw std::invalid_argument("The word contains some unexpected letters");
56  }
57 
58  weight_t operator()(const word_t& word) const
59  {
60  // Initialization.
61  const weight_t zero = ws_.zero();
62  // FIXME: a perfect job for a sparse array: most of the states
63  // will be not visited, nevertheless, because we iterate on
64  // all the states, they are costly at each iteration.
65 
67  const auto& states = a_->states();
68  unsigned last_state = *std::max_element(std::begin(states),
69  std::end(states));
70  // Do not use braces (v1{size, zero}): the type of zero might
71  // result in the compiler believing we are building a vector
72  // with two values: a_->num_all_states() and zero.
73  weights_t v1(last_state + 1, zero);
74  v1[a_->pre()] = ws_.one();
75  weights_t v2{v1};
76 
77  // Computation.
78 // Failed attempt to refuse words written with letters absent from the labelset (VM)
79 // for (auto l : ls.letters_of(ls.delimit(word))) {
80 // if (!ls.has(l)) {
81 // throw std::runtime_error("Given word is not written with the correct labelset.");
82 // }
83 // }
84  auto lsw = get_wordset(ls_);
85  for (auto l : lsw.delimit(word))
86  {
87  v2.assign(v2.size(), zero);
88  for (unsigned s = 0; s < v1.size(); ++s)
89  if (!ws_.is_zero(v1[s])) // delete if bench >
90  for (auto t : a_->out(s, l))
91  // Introducing a reference to v2[a_->dst_of(tr)] is
92  // tempting, but won't work for std::vector<bool>.
93  // FIXME: Specialize for Boolean?
94  v2[a_->dst_of(t)] =
95  ws_.add(v2[a_->dst_of(t)],
96  ws_.mul(v1[s], a_->weight_of(t)));
97  std::swap(v1, v2);
98  }
99  return v1[a_->post()];
100  }
101  private:
102  const automaton_t& a_;
103  const weightset_t& ws_;
104  const labelset_t& ls_;
105  };
106 
107  } // namespace internal
108 
109  template <typename Aut>
110  inline
111  auto
112  eval(const Aut& a, const typename labelset_trait<labelset_t_of<Aut>>::wordset_t::word_t& w, bool check_alphabet=true)
114  {
116  if(check_alphabet)
117  e.check(w);
118  return e(w);
119  }
120 
121 }}//end of ns awali::stc
122 
123 #endif // !AWALI_ALGOS_EVAL_HH
Definition: eval.hh:32
evaluator(const automaton_t &a)
Definition: eval.hh:46
void check(const word_t &word) const
Definition: eval.hh:52
weight_t operator()(const word_t &word) const
Definition: eval.hh:58
weightset_description weightset(const std::string &k)
std::vector< state_t > states(abstract_automaton_t const *aut, bool all)
any_t word_t
Type for words; it is an alias to any_t since the precise type depends on the context (most of the ti...
Definition: typedefs.hh:67
auto eval(const Aut &a, const typename labelset_trait< labelset_t_of< Aut >>::wordset_t::word_t &w, bool check_alphabet=true) -> weight_t_of< Aut >
Definition: eval.hh:112
typename internal::weight_t_of_impl< internal::base_t< ValueSet > >::type weight_t_of
Helper to retrieve the type of the weights of a value set.
Definition: traits.hh:81
typename internal::labelset_t_of_impl< internal::base_t< ValueSet > >::type labelset_t_of
Helper to retrieve the type of the labelset of a value set.
Definition: traits.hh:76
auto get_wordset(const L &labelset) -> typename labelset_trait< L >::wordset_t
Definition: traits.hh:232
typename internal::weightset_t_of_impl< internal::base_t< ValueSet > >::type weightset_t_of
Helper to retrieve the type of the weightset of a value set.
Definition: traits.hh:86
Main namespace of Awali.
Definition: ato.hh:22
trait that computes the related types of a labelset
Definition: traits.hh:34