Vcsn  2.4
Be Rational
has-bounded-lag.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <array>
4 #include <vector>
5 
6 #include <vcsn/core/automaton.hh> // states_size
7 #include <vcsn/ctx/context.hh>
8 #include <vcsn/dyn/automaton.hh> // dyn::make_automaton
10 #include <vcsn/misc/tuple.hh> // make_index_sequence
11 
12 namespace vcsn
13 {
14 
15  namespace detail
16  {
17  template <Automaton Aut>
19  {
20  static_assert(context_t_of<Aut>::is_lat,
21  "has_bounded_lag: automaton labelset must be a tupleset");
22  static constexpr size_t number_of_tapes = labelset_t_of<Aut>::size();
23  // The algorithm makes no sense (and doesn't compile) if the transducer
24  // has only one tape.
25  static_assert(2 <= number_of_tapes,
26  "has_bounded_lag: transducer labelset must have"
27  " at least 2 tapes");
28 
29  using automaton_t = Aut;
32  using label_t = typename labelset_t::value_t;
34 
35  enum visit_state {
39  };
40 
42  using visited_t = std::vector<visit_state>;
43 
45  template <std::size_t... I>
47 
48  using delay_index_t = detail::make_index_sequence<number_of_tapes - 1>;
49 
51  using delay_t = std::array<int, number_of_tapes - 1>;
52 
53  public:
56  : aut_(aut)
58  , p_(states_size(aut_), -1)
59  {}
60 
62  template <std::size_t I>
63  static int get_size_tape(label_t l)
64  {
65  using tape_labelset_t = typename labelset_t::template valueset_t<I>;
66  return tape_labelset_t::size(std::get<I>(l));
67  }
68 
70  template <std::size_t... I>
72  {
73  label_t l = aut_->label_of(tr);
74  int i0 = get_size_tape<0>(l);
75  d = {(d[I] + i0 - get_size_tape<I + 1>(l))...};
76  }
77 
79  {
80  add_delay(d, tr, delay_index_t{});
81  }
82 
85  {
86  v_[src] = visiting;
87  for (auto tr : all_out(aut_, src))
88  {
89  state_t dst = aut_->dst_of(tr);
90  switch (v_[dst])
91  {
92  case visited:
93  break;
94  case not_visited:
95  {
96  p_[dst] = tr;
97  if (!has_bounded_lag(dst))
98  return false;
99  }
100  break;
101  case visiting:
102  {
103  // Cycle, compute the cycle's delay.
104  auto d = delay_t{0};
105  add_delay(d, tr);
106  if (src != dst)
107  {
108  transition_t t = p_[src];
109  // Go back through the transitions we followed
110  // until we loop.
111  while (aut_->src_of(t) != dst)
112  {
113  add_delay(d, t);
114  t = p_[aut_->src_of(t)];
115  }
116  add_delay(d, t);
117  }
118  if (d != delay_t{0})
119  return false;
120  }
121  break;
122  }
123  }
124  v_[src] = visited;
125  return true;
126  }
127 
129  {
130  return has_bounded_lag(aut_->pre());
131  }
132 
133  private:
137  };
138  }
139 
140 
141  /*------------------.
142  | has_bounded_lag. |
143  `------------------*/
144 
149  template <Automaton Aut>
150  bool has_bounded_lag(const Aut& aut)
151  {
152  auto blc = detail::bounded_lag_checker<Aut>{aut};
153  return blc.has_bounded_lag();
154  }
155 
156  namespace dyn
157  {
158  namespace detail
159  {
161  template <Automaton Aut>
162  bool has_bounded_lag(const automaton& aut)
163  {
164  return has_bounded_lag(aut->as<Aut>());
165  }
166  }
167  }
168 }
labelset_t_of< automaton_t > labelset_t
bool has_bounded_lag(state_t src)
Depth-first search.
state_t_of< automaton_t > state_t
typename labelset_t::value_t label_t
std::array< int, number_of_tapes-1 > delay_t
The delay associated with each state.
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:63
size_t states_size(const Aut &aut)
The largest state number, plus one.
Definition: automaton.hh:40
void add_delay(delay_t &d, transition_t tr, seq< I... >)
Add the delay from the transition's label to the given delay.
transition_t_of< automaton_t > transition_t
Definition: a-star.hh:8
predecessors_t_of< automaton_t > p_
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
auto all_out(const Aut &aut, state_t_of< Aut > s)
Indexes of transitions leaving state s.
Definition: automaton.hh:66
bool has_bounded_lag(const Aut &aut)
Whether a transducer has a bounded lag.
bounded_lag_checker(const automaton_t &aut)
The vectors are indexed by the state number.
std::vector< visit_state > visited_t
Keep track of what states we have visited or are visiting.
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:64
A dyn automaton.
Definition: automaton.hh:17
static int get_size_tape(label_t l)
Get the size (number of letters) of a label on a specific tape.
typename detail::transition_t_of_impl< base_t< ValueSet >>::type transition_t_of
Definition: traits.hh:65
static constexpr size_t number_of_tapes
std::vector< transition_t_of< Aut >> predecessors_t_of
A state-indexed vector of predecessor transitions from the path path.
Definition: automaton.hh:18
auto & as()
Extract wrapped typed automaton.
Definition: automaton.hh:37
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:61
bool has_bounded_lag(const automaton &aut)
Bridge.
void add_delay(delay_t &d, transition_t tr)