Vcsn  2.3
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>
7 #include <vcsn/dyn/automaton.hh>
8 #include <vcsn/dyn/context.hh>
9 #include <vcsn/misc/raise.hh>
10 #include <vcsn/misc/vector.hh>
11 
12 namespace vcsn
13 {
14  template <typename Context>
15  mutable_automaton<Context>
16  double_ring(const Context& ctx, unsigned n,
17  const std::vector<unsigned>& finals)
18  {
19  using context_t = Context;
20  const auto& ls = *ctx.labelset();
21  auto letters = detail::make_vector(ls.generators());
22  require(2 <= letters.size(),
23  "double_ring: the alphabet needs at least 2 letters");
24  auto a = ls.value(letters[0]);
25  auto b = ls.value(letters[1]);
26 
27  using automaton_t = mutable_automaton<context_t>;
28  using state_t = state_t_of<automaton_t>;
29  automaton_t res = make_shared_ptr<automaton_t>(ctx);
30  if (n == 0)
31  return res;
32 
33  // Set initial.
34  auto p = res->new_state();
35  res->set_initial(p);
36  // Have states start on base 0. No need for pre and post states
37  // here.
38  //
39  // FIXME: this map is ridiculous, should be a vector. Maybe we
40  // should turn finals into a set and not store this map/vector at
41  // all: perform the set_final in the main loop.
42  std::map<unsigned, state_t> states;
43  // We want first state to be 0 and not 2.
44  states.emplace(0, p);
45  // Set transitions.
46  state_t x = p;
47  for (unsigned i = 1; i < n; ++i)
48  {
49  state_t y = res->new_state();
50  res->new_transition(x, y, a);
51  res->new_transition(y, x, b);
52  x = y;
53  states.emplace(i, y);
54  }
55  res->new_transition(x, p, a);
56  res->new_transition(p, x, b);
57 
58  // Add finals.
59  for (auto f: finals)
60  {
61  require(f < n, "double_ring: invalid list of finals");
62  res->set_final(states[f]);
63  }
64 
65  return res;
66  }
67 
68  namespace dyn
69  {
70  namespace detail
71  {
73  template <typename Ctx, typename, typename>
74  automaton
75  double_ring(const context& ctx, unsigned n,
76  const std::vector<unsigned>& finals)
77  {
78  const auto& c = ctx->as<Ctx>();
79  return ::vcsn::double_ring(c, n, finals);
80  }
81  }
82  }
83 }
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::mutable_automaton_impl< Context >> mutable_automaton
Definition: fwd.hh:25
void require(Bool b, Args &&...args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:91
auto & as()
Downcast to the exact type.
Definition: context.hh:36
return res
Definition: multiply.hh:398
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:64
Template-less root for contexts.
Definition: context.hh:16
Definition: a-star.hh:8
mutable_automaton< Context > double_ring(const Context &ctx, unsigned n, const std::vector< unsigned > &finals)
Definition: double-ring.hh:16
automaton double_ring(const context &ctx, unsigned n, const std::vector< unsigned > &finals)
Bridge.
Definition: double-ring.hh:75
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46