Vcsn  2.2a
Be Rational
divkbaseb.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <vcsn/ctx/traits.hh>
4 #include <vcsn/alphabets/char.hh>
7 #include <vcsn/dyn/automaton.hh>
8 #include <vcsn/dyn/context.hh>
9 #include <vcsn/misc/raise.hh>
10 
11 namespace vcsn
12 {
13 
16  template <typename Context>
17  mutable_automaton<Context>
18  divkbaseb(const Context& ctx, unsigned divisor, unsigned base)
19  {
20  using context_t = Context;
21  using automaton_t = mutable_automaton<context_t>;
22  using state_t = state_t_of<automaton_t>;
23  const auto& ls = *ctx.labelset();
24  const auto& gens = ls.generators();
25  std::vector<label_t_of<context_t>> letters;
26  for (auto l: gens)
27  letters.emplace_back(ls.value(l));
28 
29  require(divisor,
30  "divkbaseb: divisor cannot be 0");
31  require(2 <= base,
32  "divkbaseb: base (", base, ") must be at least 2");
33  VCSN_REQUIRE(base <= letters.size(),
34  "divkbaseb: base (", base,
35  ") must be less than or equal to the alphabet size (",
36  letters.size(), ')');
37 
38  automaton_t res = make_shared_ptr<automaton_t>(ctx);
39 
40  // Add one state for each possible remainder. The last state encountered
41  // during the evaluation will be n % k. If the last state is the state 0,
42  // it means that the residue is 0, ie the word will be accepted, ie the
43  // number is a multiple of k.
44  std::vector<state_t> states;
45  for (unsigned i = 0; i < divisor; ++i)
46  states.emplace_back(res->new_state());
47 
48  res->set_initial(states[0]);
49  res->set_final(states[0]);
50 
51  for (unsigned i = 0; i < divisor; ++i)
52  {
53  int e = i * base;
54  for (unsigned l = 0; l < base; ++l)
55  {
56  int d = (e + l) % divisor;
57  res->new_transition(states[i], states[d], letters[l]);
58  }
59  }
60  return res;
61  }
62 
63 
64  namespace dyn
65  {
66  namespace detail
67  {
69  template <typename Ctx, typename Unsigned1, typename Unsigned2>
70  automaton
71  divkbaseb(const context& ctx, unsigned divisor, unsigned base)
72  {
73  const auto& c = ctx->as<Ctx>();
74  return make_automaton(::vcsn::divkbaseb(c, divisor, base));
75  }
76  }
77  }
78 }
detail::automaton automaton
Definition: automaton.hh:108
std::shared_ptr< const detail::context_base > context
A dyn::context.
Definition: fwd.hh:26
#define VCSN_REQUIRE(Cond,...)
A macro similar to require.
Definition: raise.hh:89
mutable_automaton< Context > divkbaseb(const Context &ctx, unsigned divisor, unsigned base)
Build the Boolean automaton which accepts a word n representing a number in base "base" if and only i...
Definition: divkbaseb.hh:18
void require(Bool b, Args &&...args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:78
automaton divkbaseb(const context &ctx, unsigned divisor, unsigned base)
Bridge.
Definition: divkbaseb.hh:71
std::shared_ptr< detail::mutable_automaton_impl< Context >> mutable_automaton
Definition: fwd.hh:25
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
Definition: automaton.hh:113
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:56
static dyn::context ctx(const driver &d)
Get the context of the driver.
Definition: parse.cc:82
auto & as()
Extract wrapped typed automaton.
Definition: automaton.hh:39
Definition: a-star.hh:8