Vcsn  2.1
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 <typename Aut,
17  bool has_one = context_t_of<Aut>::has_one()>
19 
23  template <typename Aut>
24  struct epsilon_acyclic<Aut, true>
25  {
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 : aut_->out(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 <typename Aut>
95  struct epsilon_acyclic<Aut, false>
96  {
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 <typename 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 <typename Aut>
123  bool is_eps_acyclic(const automaton& aut)
124  {
125  return is_eps_acyclic(aut->as<Aut>());
126  }
127  }
128  }
129 } // namespace vcsn
ATTRIBUTE_CONST bool is_eps_acyclic(const Aut &aut)
constexpr epsilon_acyclic(const automaton_t &)
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
Definition: traits.hh:46
std::string type(const automaton &a)
The implementation type of a.
Definition: others.cc:197
typename std::remove_cv< Aut >::type automaton_t
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:48
bool is_eps_acyclic(const automaton &aut)
Bridge.
std::shared_ptr< detail::automaton_base > automaton
Definition: automaton.hh:69
There is an eps-circuit accessible from s.
There is no eps-circuit accessible from s.
The graph reachable from s is under exploration.
std::unordered_map< state_t, status > tag
typename std::remove_cv< Aut >::type automaton_t
#define BUILTIN_UNREACHABLE()
Definition: builtins.hh:13