Vcsn  2.0
Be Rational
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
accessible.hh
Go to the documentation of this file.
1 #ifndef VCSN_ALGOS_ACCESSIBLE_HH
2 # define VCSN_ALGOS_ACCESSIBLE_HH
3 
4 # include <deque>
5 # include <queue>
6 # include <map>
7 
8 # include <vcsn/algos/filter.hh>
9 # include <vcsn/algos/transpose.hh>
10 # include <vcsn/dyn/fwd.hh>
11 # include <vcsn/misc/attributes.hh>
13 
14 namespace vcsn
15 {
16 
17  /*--------------------------------------------------.
18  | Sets of accessible, coaccessible, useful states. |
19  `--------------------------------------------------*/
20 
21  template <typename Aut>
22  using states_t = std::unordered_set<state_t_of<Aut>>;
23 
24  // The set of accessible states, including pre(), and possibly post().
25  template <typename Aut>
27  accessible_states(const Aut& aptr)
28  {
29  using automaton_t = Aut;
30  using state_t = state_t_of<automaton_t>;
31 
32  // Reachable states.
33  const auto& a = *aptr;
34  states_t<Aut> res{a.pre()};
35 
36  // States work list.
37  using worklist_t = std::queue<state_t>;
38  worklist_t todo;
39  todo.emplace(a.pre());
40 
41  while (!todo.empty())
42  {
43  const state_t src = todo.front();
44  todo.pop();
45 
46  for (auto tr : a.all_out(src))
47  {
48  state_t dst = a.dst_of(tr);
49  // If we have not seen it already, explore its successors.
50  if (res.emplace(dst).second)
51  todo.emplace(dst);
52  }
53  }
54 
55  return res;
56  }
57 
58  // The set of coaccessible states, including post(), and possibly pre().
59  template <typename Aut>
60  states_t<Aut>
61  coaccessible_states(const Aut& a)
62  {
63  return accessible_states(transpose(a));
64  }
65 
66  // The set of coaccessible states, including post(), and possibly pre().
67  template <typename Aut>
68  states_t<Aut>
69  useful_states(const Aut& a)
70  {
71  auto accessible = accessible_states(a);
74  }
75 
76 
77  /*----------------------------------------------------.
78  | Number of accessible, coaccessible, useful states. |
79  `----------------------------------------------------*/
80 
82  template <typename Aut>
83  size_t
84  num_accessible_states(const Aut& a)
85  {
86  auto set = accessible_states(a);
87  size_t res = set.size();
88  // Don't count pre().
89  res -= 1;
90  // Don't count post().
91  if (has(set, a->post()))
92  res -= 1;
93  return res;
94  }
95 
97  template <typename Aut>
98  size_t
100  {
101  return num_accessible_states(transpose(a));
102  }
103 
105  template <typename Aut>
106  size_t
107  num_useful_states(const Aut& a)
108  {
109  auto set = useful_states(a);
110  size_t res = set.size();
111  // Don't count pre().
112  if (has(set, a->pre()))
113  res -= 1;
114  // Don't count post().
115  if (has(set, a->post()))
116  res -= 1;
117  return res;
118  }
119 
120 
121  /*-----------------------------------------------.
122  | accessible, coaccessible, useful subautomata. |
123  `-----------------------------------------------*/
124 
125  template <typename Aut>
126  filter_automaton<Aut>
127  accessible(const Aut& a)
128  {
129  return vcsn::filter(a, accessible_states(a));
130  }
131 
132  template <typename Aut>
133  filter_automaton<Aut>
134  coaccessible(const Aut& a)
135  {
136  return vcsn::filter(a, coaccessible_states(a));
137  }
138 
139  template <typename Aut>
140  filter_automaton<Aut>
141  trim(const Aut& a)
142  {
143  return vcsn::filter(a, useful_states(a));
144  }
145 
146  /*----------------------------------------------------------------.
147  | is_trim, is_accessible, is_coaccessible, is_empty, is_useless. |
148  `----------------------------------------------------------------*/
149 
150  template <typename Aut>
151  bool is_trim(const Aut& a)
152  {
153  return num_useful_states(a) == a->num_states();
154  }
155 
156  template <typename Aut>
157  bool is_useless(const Aut& a)
158  {
159  return num_useful_states(a) == 0;
160  }
161 
162  template <typename Aut>
163  bool is_accessible(const Aut& a)
164  {
165  return num_accessible_states(a) == a->num_states();
166  }
167 
168  template <typename Aut>
169  bool is_coaccessible(const Aut& a)
170  {
171  return num_coaccessible_states(a) == a->num_states();
172  }
173 
174  template <typename Aut>
175  bool is_empty(const Aut& a) ATTRIBUTE_PURE;
176 
177  template <typename Aut>
178  bool is_empty(const Aut& a)
179  {
180  // FIXME: Beware of the case where there is a transition from
181  // pre() to post().
182  return a->num_states() == 0;
183  }
184 
185  namespace dyn
186  {
187  namespace detail
188  {
189 
190  /*------------------.
191  | dyn::accessible. |
192  `------------------*/
193 
194  template <typename Aut>
195  automaton
196  accessible(const automaton& aut)
197  {
198  const auto& a = aut->as<Aut>();
199  return make_automaton(::vcsn::accessible(a));
200  }
201 
203  (const automaton&) -> automaton);
204 
205  /*--------------------.
206  | dyn::coaccessible. |
207  `--------------------*/
208 
209  template <typename Aut>
210  automaton
212  {
213  const auto& a = aut->as<Aut>();
214  return make_automaton(::vcsn::coaccessible(a));
215  }
216 
218  (const automaton&) -> automaton);
219 
220  /*------------.
221  | dyn::trim. |
222  `------------*/
223 
224  template <typename Aut>
225  automaton
226  trim(const automaton& aut)
227  {
228  const auto& a = aut->as<Aut>();
229  return make_automaton(::vcsn::trim(a));
230  }
231 
233  (const automaton&) -> automaton);
234 
235  /*---------------------.
236  | dyn::is_accessible. |
237  `---------------------*/
238 
239  template <typename Aut>
240  bool
242  {
243  const auto& a = aut->as<Aut>();
244  return is_accessible(a);
245  }
246 
248  (const automaton&) -> bool);
249 
250  /*-----------------------.
251  | dyn::is_coaccessible. |
252  `-----------------------*/
253 
254  template <typename Aut>
255  bool
257  {
258  const auto& a = aut->as<Aut>();
259  return is_coaccessible(a);
260  }
261 
263  (const automaton&) -> bool);
264 
265  /*---------------.
266  | dyn::is_trim. |
267  `---------------*/
268 
269  template <typename Aut>
270  bool
271  is_trim(const automaton& aut)
272  {
273  const auto& a = aut->as<Aut>();
274  return is_trim(a);
275  }
276 
278  (const automaton&) -> bool);
279 
280  /*------------------.
281  | dyn::is_useless. |
282  `------------------*/
283 
284  template <typename Aut>
285  bool
286  is_useless(const automaton& aut)
287  {
288  const auto& a = aut->as<Aut>();
289  return is_useless(a);
290  }
291 
293  (const automaton&) -> bool);
294 
295  /*----------------.
296  | dyn::is_empty. |
297  `----------------*/
298 
299  template <typename Aut>
300  bool
301  is_empty(const automaton& aut)
302  {
303  const auto& a = aut->as<Aut>();
304  return is_empty(a);
305  }
306 
308  (const automaton&) -> bool);
309  }
310  }
311 }
312 
313 #endif // !VCSN_ALGOS_ACCESSIBLE_HH
filter_automaton< Aut > coaccessible(const Aut &a)
Definition: accessible.hh:134
REGISTER_DECLARE(accessible,(const automaton &) -> automaton)
std::shared_ptr< detail::automaton_base > automaton
Definition: automaton.hh:71
size_t num_accessible_states(const Aut &a)
Number of accessible states, not counting pre() and post().
Definition: accessible.hh:84
states_t< Aut > useful_states(const Aut &a)
Definition: accessible.hh:69
automaton accessible(const automaton &aut)
Definition: accessible.hh:196
bool is_trim(const Aut &a)
Definition: accessible.hh:151
bool is_useless(const Aut &a)
Definition: accessible.hh:157
std::unordered_set< state_t_of< Aut >> states_t
Definition: accessible.hh:22
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
Definition: automaton.hh:77
bool is_empty(const automaton &aut)
Definition: accessible.hh:301
bool is_useless(const automaton &aut)
Definition: accessible.hh:286
filter_automaton< Aut > trim(const Aut &a)
Definition: accessible.hh:141
bool is_trim(const automaton &aut)
Definition: accessible.hh:271
states_t< Aut > accessible_states(const Aut &aptr)
Definition: accessible.hh:27
bool is_empty(const Aut &a) ATTRIBUTE_PURE
Definition: accessible.hh:178
size_t num_useful_states(const Aut &a)
Number of accessible states, not counting pre() and post().
Definition: accessible.hh:107
automaton coaccessible(const automaton &aut)
Definition: accessible.hh:211
std::set< T, Compare, Alloc > intersection(const std::set< T, Compare, Alloc > &set1, const std::set< T, Compare, Alloc > &set2)
The intersection of two sets.
Aut transpose(const transpose_automaton< Aut > &aut)
Definition: transpose.hh:230
bool is_accessible(const automaton &aut)
Definition: accessible.hh:241
bool is_coaccessible(const automaton &aut)
Definition: accessible.hh:256
bool is_accessible(const Aut &a)
Definition: accessible.hh:163
size_t num_coaccessible_states(const Aut &a)
Number of accessible states, not counting pre() and post().
Definition: accessible.hh:99
states_t< Aut > coaccessible_states(const Aut &a)
Definition: accessible.hh:61
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:35
bool is_coaccessible(const Aut &a)
Definition: accessible.hh:169
filter_automaton< Aut > accessible(const Aut &a)
Definition: accessible.hh:127
automaton trim(const automaton &aut)
Definition: accessible.hh:226
bool has(const std::map< Key, Value, Compare, Alloc > &s, const Key &e)
Definition: map.hh:35
filter_automaton< Aut > filter(const Aut &aut, const std::unordered_set< state_t_of< Aut >> &ss)
Get an automaton who is a part state set ss of aut.
Definition: filter.hh:259