Vcsn  2.3
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  // The algorithm makes no sense (and doesn't compile) if the transducer
23  // has only one tape.
24  static_assert(labelset_t_of<Aut>::size() >= 2,
25  "has_bounded_lag: transducer labelset must have at least 2 tapes");
26 
27  using automaton_t = Aut;
30  using label_t = typename labelset_t::value_t;
32 
33  static constexpr size_t number_of_tapes = labelset_t_of<Aut>::size();
34 
35  enum visit_state {
39  };
40 
41  // Keep track of what states we have visited or are visiting
42  using visited_t = std::vector<visit_state>;
43 
44  // Keep track of how we arrived in a state
45  using parent_state_t = std::vector<transition_t>;
46 
48  template <std::size_t... I>
50 
51  using delay_index_t = detail::make_index_sequence<number_of_tapes - 1>;
52 
54  using delay_t = std::array<int, number_of_tapes - 1>;
55 
56  public:
57  // The vectors are indexed by the state number.
59  : aut_(aut)
61  , p_(states_size(aut_), -1)
62  {}
63 
64  // Get the size (number of letters) of a label on a specific tape.
65  template <std::size_t I>
67  {
68  using tape_labelset_t = typename labelset_t::template valueset_t<I>;
69  return tape_labelset_t::size(std::get<I>(l));
70  }
71 
72  // Add the delay from the transition's label to the given delay
73  template <std::size_t... I>
75  {
76  label_t l = aut_->label_of(tr);
77  int i0 = get_size_tape<0>(l);
78  d = {(d[I] + i0 - get_size_tape<I + 1>(l))...};
79  }
80 
82  {
83  add_delay(d, tr, delay_index_t{});
84  }
85 
86  // Depth-first search.
88  {
89  v_[src] = VISITING;
90  for (auto tr : all_out(aut_, src))
91  {
92  state_t dst = aut_->dst_of(tr);
93  auto visited = v_[dst];
94  if (visited == NOT_VISITED)
95  {
96  p_[dst] = tr;
97  if (!has_bounded_lag(dst))
98  return false;
99  }
100  else if (visited == VISITING)
101  {
102  // Cycle, compute the cycle's delay.
103  delay_t d = {0};
104  add_delay(d, tr);
105  if (src != dst)
106  {
107  transition_t t = p_[src];
108  // Go back through the transitions we followed
109  // until we loop.
110  while (aut_->src_of(t) != dst)
111  {
112  add_delay(d, t);
113  t = p_[aut_->src_of(t)];
114  }
115  add_delay(d, t);
116  }
117  if (d != delay_t{0})
118  return false;
119  }
120  }
121  v_[src] = VISITED;
122  return true;
123  }
124 
126  {
127  return has_bounded_lag(aut_->pre());
128  }
129 
130  private:
134  };
135  }
136 
137 
138  /*------------------.
139  | has_bounded_lag. |
140  `------------------*/
141 
146  template <Automaton Aut>
147  bool has_bounded_lag(const Aut& aut)
148  {
150  return blc.has_bounded_lag();
151  }
152 
153  namespace dyn
154  {
155  namespace detail
156  {
158  template <Automaton Aut>
159  bool has_bounded_lag(const automaton& aut)
160  {
161  return has_bounded_lag(aut->as<Aut>());
162  }
163  }
164  }
165 
166 }
labelset_t_of< automaton_t > labelset_t
bool has_bounded_lag(const Aut &aut)
Whether a transducer has a bounded lag.
typename detail::transition_t_of_impl< base_t< ValueSet >>::type transition_t_of
Definition: traits.hh:65
state_t_of< automaton_t > state_t
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:19
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:61
typename labelset_t::value_t label_t
std::array< int, number_of_tapes-1 > delay_t
The delay associated with each state.
std::vector< transition_t > parent_state_t
void add_delay(delay_t &d, transition_t tr, seq< I... >)
transition_t_of< automaton_t > transition_t
bool has_bounded_lag(const automaton &aut)
Bridge.
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:64
bounded_lag_checker(const automaton_t &aut)
Definition: a-star.hh:8
std::vector< visit_state > visited_t
A dyn automaton.
Definition: automaton.hh:17
static constexpr size_t number_of_tapes
auto & as()
Extract wrapped typed automaton.
Definition: automaton.hh:37
auto all_out(const Aut &aut, state_t_of< Aut > s)
Indexes of transitions leaving state s.
Definition: automaton.hh:45
void add_delay(delay_t &d, transition_t tr)