Awali
Another Weighted Automata library
divkbaseb.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_DIVKBASEB_HH
18 # define AWALI_ALGOS_DIVKBASEB_HH
19 
20 #include <awali/sttc/ctx/traits.hh>
24 #include <awali/sttc/misc/raise.hh>
25 
26 namespace awali { namespace sttc {
27 
28 
46  template <typename Context>
47  mutable_automaton<Context>
48  divkbaseb(const Context& ctx, unsigned divisor, unsigned base)
49  {
50  using context_t = Context;
51  using automaton_t = mutable_automaton<context_t>;
52  const auto& gens = ctx.labelset()->genset();
53  std::vector<typename context_t::labelset_t::letter_t> letters
54  {std::begin(gens), std::end(gens)};
55 
56  require(divisor,
57  "divkbaseb: divisor cannot be 0");
58  require(2 <= base,
59  "divkbaseb: base (" + std::to_string(base)
60  + ") must be at least 2");
61  require(base <= letters.size(),
62  "divkbaseb: base (" + std::to_string(base)
63  + ") must be less than or equal to the alphabet size ("
64  + std::to_string(letters.size()) + ")");
65 
66  automaton_t res = make_shared_ptr<automaton_t>(ctx);
67 
68  // Add one state for each possible remainder. The last state encountered
69  // during the evaluation will be n % k. If the last state is the state 0,
70  // it means that the residue is 0, ie the word will be accepted, ie the
71  // number is a multiple of k.
72  std::vector<state_t> states;
73  for (unsigned i = 0; i < divisor; ++i)
74  states.emplace_back(res->add_state());
75 
76  res->set_initial(states[0]);
77  res->set_final(states[0]);
78 
79  for (unsigned i = 0; i < divisor; ++i)
80  {
81  int e = i * base;
82  for (unsigned l = 0; l < base; ++l)
83  {
84  int d = (e + l) % divisor;
85  res->new_transition(states[i], states[d], letters[l]);
86  }
87  }
88  res->set_name("div-"+std::to_string(divisor)+"-base-"+std::to_string(base));
89  return res;
90  }
91 
92 }}//end of ns awali::stc
93 
94 #endif // !AWALI_ALGOS_DIVKBASEB_HH
std::vector< state_t > states(abstract_automaton_t const *aut, bool all)
std::string to_string(identities i)
std::shared_ptr< internal::mutable_automaton_impl< Context > > mutable_automaton
Definition: mutable_automaton.hh:45
void require(bool b, Args &&... args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:55
mutable_automaton< Context > divkbaseb(const Context &ctx, unsigned divisor, unsigned base)
Returns an automaton which recognizes numbers in the given base which are multiple of divisor.
Definition: divkbaseb.hh:48
Main namespace of Awali.
Definition: ato.hh:22