Vcsn  2.0
Be Rational
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
double-ring.hh
Go to the documentation of this file.
1 #ifndef VCSN_ALGOS_DOUBLE_RING_HH
2 # define VCSN_ALGOS_DOUBLE_RING_HH
3 
4 # include <map>
5 
6 # include <vcsn/ctx/traits.hh>
7 # include <vcsn/alphabets/char.hh>
10 # include <vcsn/dyn/context.hh>
11 # include <vcsn/misc/raise.hh>
12 
13 namespace vcsn
14 {
15  template <class Context>
16  mutable_automaton<Context>
17  double_ring(const Context& ctx, unsigned n,
18  const std::vector<unsigned>& finals)
19  {
20  using context_t = Context;
21  const auto& gens = ctx.labelset()->genset();
22  std::vector<typename context_t::labelset_t::letter_t> letters
23  {std::begin(gens), std::end(gens)};
24  require(2 <= letters.size(),
25  "double_ring: the alphabet needs at least 2 letters");
26  auto a = letters[0];
27  auto b = letters[1];
28 
29  using automaton_t = mutable_automaton<context_t>;
30  using state_t = state_t_of<automaton_t>;
31  automaton_t res = make_shared_ptr<automaton_t>(ctx);
32  if (n == 0)
33  return res;
34 
35  // Set initial.
36  auto p = res->new_state();
37  res->set_initial(p);
38  // Have states start on base 0. No need for pre and post states here.
39  std::map<unsigned, state_t> states;
40  // We want first state to be 0 and not 2.
41  states.emplace(0, p);
42  // Set transitions.
43  state_t x = p;
44  for (unsigned i = 1; i < n; ++i)
45  {
46  state_t y = res->new_state();
47  res->new_transition(x, y, a);
48  res->new_transition(y, x, b);
49  x = y;
50  states.emplace(i, y);
51  }
52  res->new_transition(x, p, a);
53  res->new_transition(p, x, b);
54 
55  // Add finals.
56  for (auto f: finals)
57  {
58  require(f < n, "double_ring: invalid list of finals");
59  res->set_final(states[f]);
60  }
61 
62  return res;
63  }
64 
65  /*-------------------.
66  | dyn::double_ring. |
67  `-------------------*/
68 
69  namespace dyn
70  {
71  namespace detail
72  {
74  template <typename Ctx, typename, typename>
75  automaton
76  double_ring(const dyn::context& ctx, unsigned n,
77  const std::vector<unsigned>& f)
78  {
79  const auto& c = ctx->as<Ctx>();
80  return make_automaton(::vcsn::double_ring(c, n, f));
81  }
82 
84  (const context& ctx, unsigned n,
85  const std::vector<unsigned>& f) -> automaton);
86  }
87  }
88 }
89 
90 #endif // !VCSN_ALGOS_DOUBLE_RING_HH
REGISTER_DECLARE(accessible,(const automaton &) -> automaton)
std::shared_ptr< detail::automaton_base > automaton
Definition: automaton.hh:71
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
mutable_automaton< Context > double_ring(const Context &ctx, unsigned n, const std::vector< unsigned > &finals)
Definition: double-ring.hh:17
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
automaton double_ring(const dyn::context &ctx, unsigned n, const std::vector< unsigned > &f)
Bridge.
Definition: double-ring.hh:76
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