Vcsn  2.2
Be Rational
is-eps-acyclic.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <unordered_map>
4 
5 #include <vcsn/ctx/traits.hh>
7 #include <vcsn/misc/builtins.hh>
8 #include <vcsn/dyn/automaton.hh>
9 #include <vcsn/core/fwd.hh>
10 
11 namespace vcsn
12 {
13  namespace detail
14  {
15 
16  template <Automaton Aut,
17  bool has_one = context_t_of<Aut>::has_one()>
19 
23  template <Automaton Aut>
24  struct epsilon_acyclic<Aut, true>
25  {
26  using automaton_t = std::remove_cv_t<Aut>;
29 
31  : aut_(aut)
32  {}
33 
35  {
36  for (auto s : aut_->states())
37  if (has_spontaneous_circuit(s))
38  return false;
39  return true;
40  }
41 
42  // Return true if an epsilon-circuit is accessible from s by
43  // epsilon-transitions.
45  {
46  auto it = tag.find(s);
47  if (it == tag.end())
48  {
49  tag[s] = unknown;
50  for (auto t : out(aut_, s, one))
51  if (has_spontaneous_circuit(aut_->dst_of(t)))
52  {
53  tag[s] = circuit;
54  return true;
55  }
56  tag[s] = ok;
57  return false;
58  }
59 
60  // Switch with respect to tag[s].
61  switch (it->second)
62  {
63  case unknown:
64  // s is reached while we are exploring successors of s:
65  // there is a circuit.
66  tag[s] = circuit;
67  return true;
68  case ok:
69  // Otherwise the graph reachable from s has already been explored.
70  return false;
71  case circuit:
72  return true;
73  }
75  }
76 
77  enum status
78  {
82  ok,
85  };
86 
87  // States not in the map have not been reached yet.
88  std::unordered_map<state_t, status> tag;
89 
91  label_t one = aut_->labelset()->one();
92  };
93 
94  template <Automaton Aut>
95  struct epsilon_acyclic<Aut, false>
96  {
97  using automaton_t = std::remove_cv_t<Aut>;
98 
99  constexpr epsilon_acyclic(const automaton_t&)
100  {}
101 
102  static constexpr bool is_eps_acyclic()
103  {
104  return true;
105  }
106  };
107  }
108 
109  template <Automaton Aut>
110  ATTRIBUTE_CONST
111  bool is_eps_acyclic(const Aut& aut)
112  {
114  return t.is_eps_acyclic();
115  }
116 
117  namespace dyn
118  {
119  namespace detail
120  {
122  template <Automaton Aut>
123  bool is_eps_acyclic(const automaton& aut)
124  {
125  return is_eps_acyclic(aut->as<Aut>());
126  }
127  }
128  }
129 } // namespace vcsn
std::unordered_map< state_t, status > tag
Definition: a-star.hh:8
bool is_eps_acyclic(const automaton &aut)
Bridge.
There is no eps-circuit accessible from s.
The graph reachable from s is under exploration.
ATTRIBUTE_CONST bool is_eps_acyclic(const Aut &aut)
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:56
#define BUILTIN_UNREACHABLE()
Definition: builtins.hh:13
auto out(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions leaving state s.
Definition: automaton.hh:56
There is an eps-circuit accessible from s.
constexpr epsilon_acyclic(const automaton_t &)
std::shared_ptr< detail::automaton_base > automaton
Definition: automaton.hh:69
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
Definition: traits.hh:54
#define Automaton
Definition: automaton.hh:24