Vcsn  2.0
Be Rational
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
divkbaseb.hh
Go to the documentation of this file.
1 #ifndef VCSN_ALGOS_DIVKBASEB_HH
2 # define VCSN_ALGOS_DIVKBASEB_HH
3 
4 # include <vcsn/ctx/traits.hh>
5 # include <vcsn/alphabets/char.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& gens = ctx.labelset()->genset();
24  std::vector<typename context_t::labelset_t::letter_t> letters
25  {std::begin(gens), std::end(gens)};
26 
27  require(divisor,
28  "divkbaseb: divisor cannot be 0");
29  require(2 <= base,
30  "divkbaseb: base (" + std::to_string(base)
31  + ") must be at least 2");
32  require(base <= letters.size(),
33  "divkbaseb: base (" + std::to_string(base)
34  + ") must be less than or equal to the alphabet size ("
35  + std::to_string(letters.size()) + ")");
36 
37  automaton_t res = make_shared_ptr<automaton_t>(ctx);
38 
39  // Add one state for each possible remainder. The last state encountered
40  // during the evaluation will be n % k. If the last state is the state 0,
41  // it means that the residue is 0, ie the word will be accepted, ie the
42  // number is a multiple of k.
43  std::vector<state_t> states;
44  for (unsigned i = 0; i < divisor; ++i)
45  states.emplace_back(res->new_state());
46 
47  res->set_initial(states[0]);
48  res->set_final(states[0]);
49 
50  for (unsigned i = 0; i < divisor; ++i)
51  {
52  int e = i * base;
53  for (unsigned l = 0; l < base; ++l)
54  {
55  int d = (e + l) % divisor;
56  res->new_transition(states[i], states[d], letters[l]);
57  }
58  }
59  return res;
60  }
61 
62 
63  namespace dyn
64  {
65  namespace detail
66  {
68  template <typename Ctx, typename Unsigned1, typename Unsigned2>
69  automaton
70  divkbaseb(const context& ctx, unsigned divisor, unsigned base)
71  {
72  const auto& c = ctx->as<Ctx>();
73  return make_automaton(::vcsn::divkbaseb(c, divisor, base));
74  }
75 
77  (divkbaseb,
78  (const context& ctx, unsigned k, unsigned b) -> automaton);
79  }
80  }
81 
82 }
83 
84 #endif // !VCSN_ALGOS_DIVKBASEB_HH
REGISTER_DECLARE(accessible,(const automaton &) -> automaton)
std::shared_ptr< detail::automaton_base > automaton
Definition: automaton.hh:71
std::string to_string(identities i)
Definition: identities.cc:13
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
Definition: automaton.hh:77
std::shared_ptr< detail::mutable_automaton_impl< Context >> mutable_automaton
Definition: fwd.hh:25
automaton divkbaseb(const context &ctx, unsigned divisor, unsigned base)
Bridge.
Definition: divkbaseb.hh:70
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:36
std::shared_ptr< const detail::context_base > context
Definition: context.hh:71
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
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:35
void require(bool b, Args &&...args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:39