Awali
Another Weighted Automata library
enumerate.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_ENUMERATE_HH
18 # define AWALI_ALGOS_ENUMERATE_HH
19 
20 # include <algorithm>
21 # include <iostream>
22 # include <list>
23 # include <map>
24 # include <queue>
25 # include <vector>
26 
28 //#include <awali/sttc/labelset/labelset.hh>
32 
33 namespace awali { namespace sttc {
34 
35 
36 
37  /*-----------------------.
38  | enumerate(automaton). |
39  `-----------------------*/
40 
41  namespace internal
42  {
43  template <typename Aut>
44  class enumerater
45  {
46  public:
47  using automaton_t = Aut;
49  static_assert(context_t::labelset_t::is_free(),
50  "requires free labelset");
51 
61  using word_t = typename labelset_t::word_t;
62 
64  using monomial_t = std::pair<word_t, weight_t>;
65  using queue_t = std::list<std::pair<state_t, monomial_t>>;
66 
67  enumerater(const automaton_t& aut)
68  : aut_(aut) {}
69 
72  {
73  if(is_empty(trim(aut_)))
74  return ps_.zero();
75  queue_t queue;
76  queue.emplace_back(aut_->pre(), ps_.monomial_one());
77 
78  // We match words that include the initial and final special
79  // characters.
80  max += 2;
81  for (unsigned i = 0; i < max && !queue.empty(); ++i)
82  propagate_(queue);
83 
84  polynomial_t res;
85  // Return the past of post(), but remove the initial and final
86  // special characters for the words.
87  for (const auto& m: achieved_)
88  ps_.add_here(res, ls_.undelimit(m.first), m.second);
89  return res;
90  }
91 
93  // FIXME: code duplication.
94  polynomial_t shortest(unsigned num)
95  {
96  if(is_empty(trim(aut_)))
97  return ps_.zero();
98  queue_t queue;
99  queue.emplace_back(aut_->pre(), ps_.monomial_one());
100 
101  polynomial_t res;
102  while (achieved_.size() < num && !queue.empty())
103  propagate_(queue);
104 
105  // Return the past of post(), but remove the initial and final
106  // special characters for the words.
107  for (const auto& m: achieved_)
108  {
109  ps_.add_here(res, ls_.undelimit(m.first), m.second);
110  if (--num == 0)
111  break;
112  }
113  return res;
114  }
115 
116  private:
119  void propagate_(queue_t& q1)
120  {
121  queue_t q2;
122  while (!q1.empty())
123  {
124  state_t s;
125  monomial_t m;
126  tie(s, m) = std::move(q1.front());
127  q1.pop_front();
128  for (const auto t: aut_->all_out(s))
129  {
130  // FIXME: monomial mul.
131  monomial_t n(ls_.concat(m.first, aut_->label_of(t)),
132  ws_.mul(m.second, aut_->weight_of(t)));
133  if(aut_->dst_of(t) == aut_->post())
134  ps_.add_here(achieved_, n);
135  q2.emplace_back(aut_->dst_of(t), n);
136  }
137  }
138  q1.swap(q2);
139  }
140 
141  const automaton_t& aut_;
142  const weightset_t& ws_ = *aut_->weightset();
143  const polynomialset_t ps_{get_wordset_context(aut_->context())};
144  const labelset_t_of<polynomialset_t>& ls_ = *ps_.labelset();
146  polynomial_t achieved_;
147  };
148  }
149 
158  template <typename Automaton>
159  inline
161  enumerate(const Automaton& aut, unsigned max_length)
162  {
163  internal::enumerater<Automaton> enumerater(aut);
164  return enumerater.enumerate(max_length);
165  }
166 
179  template <typename Automaton>
180  inline
182  shortest(const Automaton& aut, unsigned num)
183  {
184  internal::enumerater<Automaton> enumerater(aut);
185  return enumerater.shortest(num);
186  }
187 
188 }}//end of ns awali::stc
189 
190 #endif // !AWALI_ALGOS_ENUMERATE_HH
carries the algebraic settings of automata
Definition: context.hh:40
Definition: enumerate.hh:45
Aut automaton_t
Definition: enumerate.hh:47
label_t_of< automaton_t > label_t
Definition: enumerate.hh:58
enumerater(const automaton_t &aut)
Definition: enumerate.hh:67
weightset_t_of< automaton_t > weightset_t
Definition: enumerate.hh:53
weight_t_of< automaton_t > weight_t
Definition: enumerate.hh:59
std::pair< word_t, weight_t > monomial_t
Same as polynomial_t::value_type.
Definition: enumerate.hh:64
typename polynomialset_t::value_t polynomial_t
Definition: enumerate.hh:57
std::list< std::pair< state_t, monomial_t > > queue_t
Definition: enumerate.hh:65
polynomial_t shortest(unsigned num)
The shortest accepted weighted words, or throw an exception.
Definition: enumerate.hh:94
context_t_of< Aut > context_t
Definition: enumerate.hh:48
polynomial_t enumerate(unsigned max)
The weighted accepted word with length at most max.
Definition: enumerate.hh:71
typename labelset_t_of< automaton_t >::genset_t genset_t
Definition: enumerate.hh:60
typename labelset_trait< labelset_t >::wordset_t wordset_t
Definition: enumerate.hh:54
labelset_t_of< automaton_t > labelset_t
Definition: enumerate.hh:52
typename labelset_t::word_t word_t
Definition: enumerate.hh:61
polynomialset< wordset_context_t > polynomialset_t
Definition: enumerate.hh:56
The semiring of Natural numbers.
Definition: n.hh:34
Linear combination of labels: map labels to weights.
Definition: polynomialset.hh:69
const monomial_t & monomial_one() const
Definition: polynomialset.hh:334
std::map< label_t, weight_t, internal::less< labelset_t > > value_t
Definition: polynomialset.hh:83
value_t & add_here(value_t &v, const value_t &p) const
v += p.
Definition: polynomialset.hh:130
const value_t & zero() const
Definition: polynomialset.hh:353
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
bool is_empty(const Aut &aut) ATTRIBUTE_PURE
Test whether the automaton has no state.
Definition: accessible.hh:365
typename internal::label_t_of_impl< internal::base_t< ValueSet > >::type label_t_of
Helper to retrieve the type of the labels of a value set.
Definition: traits.hh:71
auto get_wordset_context(const context< LS, WS > &ctx) -> context< typename labelset_trait< LS >::wordset_t, WS >
Definition: traits.hh:267
internal::enumerater< Automaton >::polynomial_t shortest(const Automaton &aut, unsigned num)
Computes the weight of the num smallest words accepted by the automaton.
Definition: enumerate.hh:182
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::context_t_of_impl< internal::base_t< ValueSet > >::type context_t_of
Helper to retrieve the type of the context of a value set.
Definition: traits.hh:66
Aut::element_type::automaton_nocv_t trim(const Aut &aut, bool keep_history=true)
Trim subautomaton.
Definition: accessible.hh:278
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
internal::enumerater< Automaton >::polynomial_t enumerate(const Automaton &aut, unsigned max_length)
Gives the weight associated with each word shorter than max_length by aut.
Definition: enumerate.hh:161
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
ATTRIBUTE_CONST int max(int a, int b)
Definition: arith.hh:54
Main namespace of Awali.
Definition: ato.hh:22
unsigned state_t
Definition: types.hh:21
L wordset_t
Definition: traits.hh:38