Vcsn  2.0
Be Rational
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
enumerate.hh
Go to the documentation of this file.
1 #ifndef VCSN_ALGOS_ENUMERATE_HH
2 # define VCSN_ALGOS_ENUMERATE_HH
3 
4 # include <algorithm>
5 # include <map>
6 # include <queue>
7 
8 # include <vcsn/ctx/context.hh>
9 # include <vcsn/dyn/automaton.hh>
10 # include <vcsn/dyn/fwd.hh>
11 # include <vcsn/dyn/polynomial.hh>
12 # include <vcsn/labelset/labelset.hh>
14 
15 namespace vcsn
16 {
17 
18 
19  /*-----------------------.
20  | enumerate(automaton). |
21  `-----------------------*/
22 
23  namespace detail
24  {
25  template <typename Aut>
26  class enumerater
27  {
28  public:
29  using automaton_t = Aut;
31  static_assert(context_t::labelset_t::is_free(),
32  "enumerate: requires free labelset");
33 
42  using word_t = typename labelset_t::word_t;
43 
45  using monomial_t = std::pair<word_t, weight_t>;
46  using queue_t = std::queue<std::pair<state_t, monomial_t>>;
47 
48  enumerater(const automaton_t& aut)
49  : aut_(aut)
50  {
51  past_[aut_->pre()] = ps_.one();
52  }
53 
55  polynomial_t enumerate(unsigned max)
56  {
57  queue_t queue;
58  queue.emplace(aut_->pre(), ps_.monomial_one());
59 
60  // We match words that include the initial and final special
61  // characters.
62  max += 2;
63  for (size_t i = 0; i < max && !queue.empty(); ++i)
64  propagate_(queue);
65 
66  // Return the past of post(), but remove the initial and final
67  // special characters for the words.
68  polynomial_t res;
69  for (const auto& m: past_[aut_->post()])
70  ps_.add_here(res, ls_.undelimit(m.first), m.second);
71  return res;
72  }
73 
75  // FIXME: code duplication.
76  polynomial_t shortest(unsigned num)
77  {
78  queue_t queue;
79  queue.emplace(aut_->pre(), ps_.monomial_one());
80 
81  while (past_[aut_->post()].size() < num && !queue.empty())
82  propagate_(queue);
83 
84  // Return the past of post(), but remove the initial and final
85  // special characters for the words.
86  polynomial_t res;
87  for (const auto& m: past_[aut_->post()])
88  {
89  ps_.add_here(res, ls_.undelimit(m.first), m.second);
90  if (--num == 0)
91  break;
92  }
93  return res;
94  }
95 
96  private:
99  void propagate_(queue_t& q1)
100  {
101  queue_t q2;
102  while (!q1.empty())
103  {
104  state_t s;
105  monomial_t m;
106  tie(s, m) = std::move(q1.front());
107  q1.pop();
108  for (const auto t: aut_->all_out(s))
109  {
110  // FIXME: monomial mul.
111  monomial_t n(ls_.concat(m.first, aut_->label_of(t)),
112  ws_.mul(m.second, aut_->weight_of(t)));
113  ps_.add_here(past_[aut_->dst_of(t)], n);
114  q2.emplace(aut_->dst_of(t), n);
115  }
116  }
117  q1.swap(q2);
118  }
119 
121  const weightset_t& ws_ = *aut_->weightset();
125  std::map<state_t, polynomial_t> past_;
126  };
127  }
128 
129  template <typename Automaton>
130  inline
132  enumerate(const Automaton& aut, unsigned max)
133  {
134  detail::enumerater<Automaton> enumerater(aut);
135  return enumerater.enumerate(max);
136  }
137 
138  template <typename Automaton>
139  inline
140  typename detail::enumerater<Automaton>::polynomial_t
141  shortest(const Automaton& aut, unsigned num)
142  {
143  detail::enumerater<Automaton> enumerater(aut);
144  return enumerater.shortest(num);
145  }
146 
147 
148  namespace dyn
149  {
150  namespace detail
151  {
152 
153  /*-----------------.
154  | dyn::enumerate. |
155  `-----------------*/
156 
157  template <typename Aut, typename Unsigned>
158  polynomial
159  enumerate(const automaton& aut, unsigned max)
160  {
161  const auto& a = aut->as<Aut>();
162  auto ps = vcsn::detail::make_word_polynomialset(a->context());
163  return make_polynomial(ps, enumerate(a, max));
164  }
165 
167  (enumerate,
168  (const automaton& aut, unsigned max) -> polynomial);
169 
170 
171  /*----------------.
172  | dyn::shortest. |
173  `----------------*/
174 
175  template <typename Aut, typename Unsigned>
176  polynomial
177  shortest(const automaton& aut, unsigned num)
178  {
179  const auto& a = aut->as<Aut>();
180  auto ps = vcsn::detail::make_word_polynomialset(a->context());
181  return make_polynomial(ps, shortest(a, num));
182  }
183 
185  (const automaton& aut, unsigned num) -> polynomial);
186  }
187  }
188 }
189 
190 #endif // !VCSN_ALGOS_ENUMERATE_HH
Linear combination of labels: map labels to weights.
Definition: fwd.hh:32
polynomial enumerate(const automaton &aut, unsigned max)
Definition: enumerate.hh:159
value_t & add_here(value_t &v, const value_t &p) const
v += p.
std::pair< word_t, weight_t > monomial_t
Same as polynomial_t::value_type.
Definition: enumerate.hh:45
const polynomialset_t ps_
Definition: enumerate.hh:122
REGISTER_DECLARE(accessible,(const automaton &) -> automaton)
std::shared_ptr< detail::automaton_base > automaton
Definition: automaton.hh:71
polynomial make_polynomial(const PolynomialSet &ps, const typename PolynomialSet::value_t &polynomial)
Definition: polynomial.hh:91
detail::enumerater< Automaton >::polynomial_t shortest(const Automaton &aut, unsigned num)
Definition: enumerate.hh:141
state_t_of< automaton_t > state_t
Definition: enumerate.hh:41
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:34
const labelset_t_of< polynomialset_t > & ls_
Definition: enumerate.hh:123
polynomial_t enumerate(unsigned max)
The weighted accepted word with length at most max.
Definition: enumerate.hh:55
detail::enumerater< Automaton >::polynomial_t enumerate(const Automaton &aut, unsigned max)
Definition: enumerate.hh:132
typename labelset_t::word_t word_t
Definition: enumerate.hh:42
context_t_of< Aut > context_t
Definition: enumerate.hh:30
const weightset_t & ws_
Definition: enumerate.hh:121
label_t_of< automaton_t > label_t
Definition: enumerate.hh:39
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:32
std::queue< std::pair< state_t, monomial_t >> queue_t
Definition: enumerate.hh:46
std::map< state_t, polynomial_t > past_
For each state, the first orders of its past.
Definition: enumerate.hh:125
auto make_word_polynomialset(const Ctx &ctx) -> word_polynomialset_t< Ctx >
The polynomialset of words of a labelset (not necessarily on words itself).
Definition: labelset.hh:104
polynomial shortest(const automaton &aut, unsigned num)
Definition: enumerate.hh:177
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
Definition: traits.hh:33
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
Definition: traits.hh:38
typename polynomialset_t::value_t polynomial_t
Definition: enumerate.hh:38
const labelset_ptr & labelset() const
std::map< label_t, weight_t, vcsn::less< labelset_t >> value_t
typename detail::weight_t_of_impl< base_t< ValueSet >>::type weight_t_of
Definition: traits.hh:37
void propagate_(queue_t &q1)
Process once all the states of q1.
Definition: enumerate.hh:99
const automaton_t & aut_
Definition: enumerate.hh:120
polynomial_t shortest(unsigned num)
The shortest accepted weighted words, or throw an exception.
Definition: enumerate.hh:76
const monomial_t & monomial_one() const
weight_t_of< automaton_t > weight_t
Definition: enumerate.hh:40
labelset_t_of< automaton_t > labelset_t
Definition: enumerate.hh:34
enumerater(const automaton_t &aut)
Definition: enumerate.hh:48
weightset_t_of< automaton_t > weightset_t
Definition: enumerate.hh:35
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:35
const value_t & one() const
std::shared_ptr< const detail::polynomial_base > polynomial
Definition: fwd.hh:55