Vcsn  2.2
Be Rational
double-ring.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <map>
4 
5 #include <vcsn/ctx/traits.hh>
6 #include <vcsn/alphabets/char.hh>
9 #include <vcsn/dyn/automaton.hh>
10 #include <vcsn/dyn/context.hh>
11 #include <vcsn/misc/raise.hh>
12 #include <vcsn/misc/vector.hh>
13 
14 namespace vcsn
15 {
16  template <typename Context>
17  mutable_automaton<Context>
18  double_ring(const Context& ctx, unsigned n,
19  const std::vector<unsigned>& finals)
20  {
21  using context_t = Context;
22  const auto& ls = *ctx.labelset();
23  auto letters = detail::make_vector(ls.generators());
24  require(2 <= letters.size(),
25  "double_ring: the alphabet needs at least 2 letters");
26  auto a = ls.value(letters[0]);
27  auto b = ls.value(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
39  // here.
40  //
41  // FIXME: this map is ridiculous, should be a vector. Maybe we
42  // should turn finals into a set and not store this map/vector at
43  // all: perform the set_final in the main loop.
44  std::map<unsigned, state_t> states;
45  // We want first state to be 0 and not 2.
46  states.emplace(0, p);
47  // Set transitions.
48  state_t x = p;
49  for (unsigned i = 1; i < n; ++i)
50  {
51  state_t y = res->new_state();
52  res->new_transition(x, y, a);
53  res->new_transition(y, x, b);
54  x = y;
55  states.emplace(i, y);
56  }
57  res->new_transition(x, p, a);
58  res->new_transition(p, x, b);
59 
60  // Add finals.
61  for (auto f: finals)
62  {
63  require(f < n, "double_ring: invalid list of finals");
64  res->set_final(states[f]);
65  }
66 
67  return res;
68  }
69 
70  namespace dyn
71  {
72  namespace detail
73  {
75  template <typename Ctx, typename, typename>
76  automaton
77  double_ring(const context& ctx, unsigned n,
78  const std::vector<unsigned>& finals)
79  {
80  const auto& c = ctx->as<Ctx>();
81  return make_automaton(::vcsn::double_ring(c, n, finals));
82  }
83  }
84  }
85 }
mutable_automaton< Context > double_ring(const Context &ctx, unsigned n, const std::vector< unsigned > &finals)
Definition: double-ring.hh:18
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
Definition: automaton.hh:75
std::shared_ptr< detail::mutable_automaton_impl< Context >> mutable_automaton
Definition: fwd.hh:25
Definition: a-star.hh:8
void require(Bool b, Args &&...args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:78
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:56
std::shared_ptr< const detail::context_base > context
A dyn::context.
Definition: fwd.hh:43
std::vector< typename Cont::value_type > make_vector(const Cont &cont)
The content of cont as a vector.
Definition: vector.hh:20
std::shared_ptr< detail::automaton_base > automaton
Definition: automaton.hh:69
static dyn::context ctx(const driver &d)
Get the context of the driver.
Definition: parse.cc:82
automaton double_ring(const context &ctx, unsigned n, const std::vector< unsigned > &finals)
Bridge.
Definition: double-ring.hh:77