Awali
Another Weighted Automata library
is_acyclic.hh
Go to the documentation of this file.
1 // This file is part of Awali.
2 // Copyright 2016-2022 Sylvain Lombardy, Victor Marsault, Jacques Sakarovitch
3 //
4 // Awali is a free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 
17 #ifndef AWALI_ALGOS_IS_ACYCLIC_HH
18 # define AWALI_ALGOS_IS_ACYCLIC_HH
19 
20 # include <unordered_map>
21 
22 #include <awali/sttc/ctx/traits.hh>
24 
25 namespace awali {
26  namespace sttc {
31  template <typename Aut>
32  struct test_acyclic
33  {
34  using automaton_t = typename std::remove_cv<Aut>::type;
36  std::unordered_map<state_t, char> tag;
37  /*
38  tag gives the status of the state s;
39  if s is not in the map, the state has not been reached yet;
40  if tag[s]='u', the status is unknown, the graph reachable from s is
41  under exploration
42  if tag[s]='o', the status is "ok": there is no eps-circuit accessible
43  from s
44  if tag[s]='c', there is an eps-circuit accessible from s
45  */
46 
47  const automaton_t& aut_;
48 
49  // Return true if a circuit is accessible from s
51  {
52  auto it = tag.find(s);
53  if (it == tag.end())
54  {
55  tag[s] = 'u';
56  for (auto t : aut_->out(s))
57  if (has_circuit(aut_->dst_of(t)))
58  {
59  tag[s] = 'c';
60  return true;
61  }
62  tag[s] = 'o';
63  return false;
64  }
65 
66  // Switch with respect to tag[s].
67  switch (it->second)
68  {
69  case 'u':
70  // s is reached while we are exploring successors of s:
71  // there is a circuit.
72  tag[s] = 'c';
73  return true;
74  // Otherwise the graph reachable from s has already been explored.
75  case 'o':
76  return false;
77  default: //'c'
78  return true;
79  }
80  }
81 
83  : aut_(aut)
84  {}
85 
86  bool is_acyclic()
87  {
88  for (auto s : aut_->states())
89  if (has_circuit(s))
90  return false;
91  return true;
92  }
93  };
94 
95 
96  template <typename Aut>
97  ATTRIBUTE_CONST
98  bool is_acyclic(const Aut& aut)
99  {
100  test_acyclic<Aut> t{aut};
101  return t.is_acyclic();
102  }
103  }
104 }//end of ns awali::stc
105 
106 #endif // !AWALI_ALGOS_IS_ACYCLIC_HH
typename internal::label_t_of_impl< internal::base_t< ValueSet > >::type label_t_of
Helper to retrieve the type of the labels of a value set.
Definition: traits.hh:71
ATTRIBUTE_CONST bool is_acyclic(const Aut &aut)
Definition: is_acyclic.hh:98
Main namespace of Awali.
Definition: ato.hh:22
unsigned state_t
Definition: types.hh:21
Definition: is_acyclic.hh:33
bool is_acyclic()
Definition: is_acyclic.hh:86
std::unordered_map< state_t, char > tag
Definition: is_acyclic.hh:36
bool has_circuit(state_t s)
Definition: is_acyclic.hh:50
label_t_of< automaton_t > label_t
Definition: is_acyclic.hh:35
typename std::remove_cv< Aut >::type automaton_t
Definition: is_acyclic.hh:34
const automaton_t & aut_
Definition: is_acyclic.hh:47
test_acyclic(const automaton_t &aut)
Definition: is_acyclic.hh:82