Vcsn  2.8
Be Rational
accessible.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <limits>
4 #include <queue>
5 
6 #include <vcsn/algos/filter.hh>
8 #include <vcsn/dyn/fwd.hh>
11 
12 namespace vcsn
13 {
14 
15  /*--------------------------------------------------.
16  | Sets of accessible, coaccessible, useful states. |
17  `--------------------------------------------------*/
18 
19  template <Automaton Aut>
20  using states_t = std::unordered_set<state_t_of<Aut>>;
21 
26  template <Automaton Aut>
28  accessible_states(const Aut& aut, bool strict = true)
29  {
30  using automaton_t = Aut;
31  using state_t = state_t_of<automaton_t>;
32 
33  // Reachable states.
34  auto res = states_t<Aut>{aut->pre()};
35 
36  // States work list.
37  auto todo = std::queue<state_t>{};
38  todo.emplace(aut->pre());
39 
40  auto credit
41  = getenv("VCSN_CREDIT")
42  ? std::stoul(getenv("VCSN_CREDIT"))
43  : std::numeric_limits<unsigned>::max();
44  while (!todo.empty())
45  {
46  const state_t src = todo.front();
47  todo.pop();
48 
49  if (strict || !aut->is_lazy(src))
50  for (auto tr : all_out(aut, src))
51  {
52  state_t dst = aut->dst_of(tr);
53  // If we have not seen it already, explore its successors.
54  if (res.emplace(dst).second && credit--)
55  todo.emplace(dst);
56  }
57  }
58 
59  return res;
60  }
61 
66  template <Automaton Aut>
68  coaccessible_states(const Aut& a, bool strict = true)
69  {
70  return accessible_states(transpose(a), strict);
71  }
72 
77  template <Automaton Aut>
79  useful_states(const Aut& a, bool strict = true)
80  {
81  auto accessible = accessible_states(a, strict);
82  auto coaccessible = coaccessible_states(a, strict);
84  }
85 
86 
87  /*----------------------------------------------------.
88  | Number of accessible, coaccessible, useful states. |
89  `----------------------------------------------------*/
90 
92  template <Automaton Aut>
93  size_t
94  num_accessible_states(const Aut& a)
95  {
96  auto set = accessible_states(a);
97  size_t res = set.size();
98  // Don't count pre().
99  res -= 1;
100  // Don't count post().
101  if (has(set, a->post()))
102  res -= 1;
103  return res;
104  }
105 
107  template <Automaton Aut>
108  size_t
110  {
111  return num_accessible_states(transpose(a));
112  }
113 
115  template <Automaton Aut>
116  size_t
117  num_useful_states(const Aut& a)
118  {
119  auto set = useful_states(a);
120  size_t res = set.size();
121  // Don't count pre().
122  if (has(set, a->pre()))
123  res -= 1;
124  // Don't count post().
125  if (has(set, a->post()))
126  res -= 1;
127  return res;
128  }
129 
130 
131  /*-----------------------------------------------.
132  | accessible, coaccessible, useful subautomata. |
133  `-----------------------------------------------*/
134 
136  template <Automaton Aut>
138  accessible(const Aut& a)
139  {
140  return vcsn::filter(a, accessible_states(a));
141  }
142 
144  template <Automaton Aut>
146  coaccessible(const Aut& a)
147  {
148  return vcsn::filter(a, coaccessible_states(a));
149  }
150 
152  template <Automaton Aut>
154  trim(const Aut& a)
155  {
156  return vcsn::filter(a, useful_states(a));
157  }
158 
159  /*----------------------------------------------------------------.
160  | is_trim, is_accessible, is_coaccessible, is_empty, is_useless. |
161  `----------------------------------------------------------------*/
162 
164  template <Automaton Aut>
165  bool is_trim(const Aut& a)
166  {
167  return num_useful_states(a) == a->num_states();
168  }
169 
171  template <Automaton Aut>
172  bool is_useless(const Aut& a)
173  {
174  return num_useful_states(a) == 0;
175  }
176 
178  template <Automaton Aut>
179  bool is_accessible(const Aut& a)
180  {
181  return num_accessible_states(a) == a->num_states();
182  }
183 
185  template <Automaton Aut>
186  bool is_coaccessible(const Aut& a)
187  {
188  return num_coaccessible_states(a) == a->num_states();
189  }
190 
191  template <Automaton Aut>
192  bool is_empty(const Aut& a) ATTRIBUTE_PURE;
193 
195  template <Automaton Aut>
196  bool is_empty(const Aut& a)
197  {
198  // FIXME: Beware of the case where there is a transition from
199  // pre() to post().
200  return a->num_states() == 0;
201  }
202 
203  namespace dyn
204  {
205  namespace detail
206  {
208  template <Automaton Aut>
209  automaton
210  accessible(const automaton& aut)
211  {
212  const auto& a = aut->as<Aut>();
214  }
215 
217  template <Automaton Aut>
218  automaton
220  {
221  const auto& a = aut->as<Aut>();
223  }
224 
226  template <Automaton Aut>
227  automaton
228  trim(const automaton& aut)
229  {
230  const auto& a = aut->as<Aut>();
232  }
233 
235  template <Automaton Aut>
236  bool
238  {
239  const auto& a = aut->as<Aut>();
240  return is_accessible(a);
241  }
242 
244  template <Automaton Aut>
245  bool
247  {
248  const auto& a = aut->as<Aut>();
249  return is_coaccessible(a);
250  }
251 
253  template <Automaton Aut>
254  bool
255  is_trim(const automaton& aut)
256  {
257  const auto& a = aut->as<Aut>();
258  return is_trim(a);
259  }
260 
262  template <Automaton Aut>
263  bool
264  is_useless(const automaton& aut)
265  {
266  const auto& a = aut->as<Aut>();
267  return is_useless(a);
268  }
269 
271  template <Automaton Aut>
272  bool
273  is_empty(const automaton& aut)
274  {
275  const auto& a = aut->as<Aut>();
276  return is_empty(a);
277  }
278  }
279  }
280 }
A dyn automaton.
Definition: automaton.hh:17
Aut transpose(const transpose_automaton< Aut > &aut)
The transpose of a transpose automaton is the original automaton.
Definition: transpose.hh:253
bool is_empty(const automaton &aut)
Bridge.
Definition: accessible.hh:273
bool is_coaccessible(const Aut &a)
Whether all its states are coaccessible.
Definition: accessible.hh:186
ATTRIBUTE_PURE bool has(const boost::container::flat_set< Key, Compare, Allocator > &s, const Key &e)
Whether e is member of s.
Definition: setalpha.hh:26
states_t< Aut > useful_states(const Aut &a, bool strict=true)
The set of useful states, including possibly pre() and post().
Definition: accessible.hh:79
typename detail::state_t_of_impl< base_t< ValueSet > >::type state_t_of
Definition: traits.hh:64
bool is_useless(const automaton &aut)
Bridge.
Definition: accessible.hh:264
size_t num_useful_states(const Aut &a)
Number of accessible states, not counting pre() and post().
Definition: accessible.hh:117
automaton trim(const automaton &aut)
Bridge.
Definition: accessible.hh:228
bool is_coaccessible(const automaton &aut)
Bridge.
Definition: accessible.hh:246
auto all_out(const Aut &aut, state_t_of< Aut > s)
Indexes of transitions leaving state s.
Definition: automaton.hh:67
filter_automaton< Aut > trim(const Aut &a)
Useful part of an automaton.
Definition: accessible.hh:154
std::shared_ptr< detail::filter_automaton_impl< Aut, Trans > > filter_automaton
Definition: filter.hh:312
bool is_useless(const Aut &a)
Whether all no state is useful.
Definition: accessible.hh:172
automaton accessible(const automaton &aut)
Bridge.
Definition: accessible.hh:210
Definition: a-star.hh:8
bool is_empty(const Aut &a) ATTRIBUTE_PURE
Whether has no states.
Definition: accessible.hh:196
filter_automaton< Aut > accessible(const Aut &a)
Accessible part of an automaton.
Definition: accessible.hh:138
Container set_intersection(const Container &s1, const Container &s2)
The intersection of two sets.
Definition: algorithm.hh:238
filter_automaton< Aut > coaccessible(const Aut &a)
Coaccessible part of an automaton.
Definition: accessible.hh:146
std::unordered_set< state_t_of< Aut > > states_t
Definition: accessible.hh:20
states_t< Aut > accessible_states(const Aut &aut, bool strict=true)
The set of accessible states, including pre(), and possibly post().
Definition: accessible.hh:28
auto & as()
Extract wrapped typed automaton.
Definition: automaton.hh:37
bool is_accessible(const automaton &aut)
Bridge.
Definition: accessible.hh:237
size_t num_accessible_states(const Aut &a)
Number of accessible states, not counting pre() and post().
Definition: accessible.hh:94
size_t num_coaccessible_states(const Aut &a)
Number of accessible states, not counting pre() and post().
Definition: accessible.hh:109
bool is_trim(const automaton &aut)
Bridge.
Definition: accessible.hh:255
states_t< Aut > coaccessible_states(const Aut &a, bool strict=true)
The set of coaccessible states, including post(), and possibly pre().
Definition: accessible.hh:68
bool is_accessible(const Aut &a)
Whether all its states are accessible.
Definition: accessible.hh:179
bool is_trim(const Aut &a)
Whether all its states are useful.
Definition: accessible.hh:165
filter_automaton< Aut, Trans > filter(const Aut &aut, boost::optional< dynamic_bitset > ss={}, boost::optional< dynamic_bitset > ts={})
Build a filtered view of an automaton.
Definition: filter.hh:321
return res
Definition: multiply.hh:399
automaton coaccessible(const automaton &aut)
Bridge.
Definition: accessible.hh:219