Vcsn  2.2
Be Rational
proper.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <stdexcept>
4 #include <type_traits>
5 #include <utility>
6 
7 #include <vcsn/algos/copy.hh>
12 #include <vcsn/algos/fwd.hh>
13 #include <vcsn/algos/is-proper.hh>
14 #include <vcsn/algos/is-valid.hh>
15 #include <vcsn/core/kind.hh>
16 #include <vcsn/misc/builtins.hh>
17 #include <vcsn/misc/direction.hh>
18 #include <vcsn/misc/getargs.hh>
19 #include <vcsn/misc/star-status.hh>
20 
21 namespace vcsn
22 {
23  namespace detail
24  {
28  template <Automaton Aut>
29  class properer
30  {
31  using automaton_t = std::remove_cv_t<Aut>;
32  using self_t = properer;
38 
39  public:
54  properer(automaton_t aut,
55  bool prune = true,
56  const std::string& algo = "auto")
57  : aut_(aut)
58  , prune_(prune)
59  , algo_(algo)
60  {}
61 
64  {
65  return proper_star_<weightset_t::star_status()>();
66  }
67 
69  void here()
70  {
71  proper_star_here_<weightset_t::star_status()>();
72  }
73 
74  private:
75 
76  /*-----------------.
77  | Separate proper. |
78  `-----------------*/
79 
81  {
82  static const auto map
84  {
85  "proper algorithm",
86  {
87  {"auto", "inplace"},
88  {"default", "inplace"},
89  {"distance", [](const self_t& s) {
90  auto r =
92  s.prune_};
93  return r();
94  }},
95  {"inplace", [](const self_t& s) {
96  auto a = copy(s.aut_); // in place
98  return r();
99  }},
100  {"separate", [](const self_t& s) {
101  auto r =
103  s.prune_};
104  return r();
105  }},
106  },
107  };
108  return map[algo_](*this);
109  }
110 
111  template <star_status_t Status>
112  std::enable_if_t<Status == star_status_t::ABSVAL, aut_proper_t>
113  proper_star_() const
114  {
115  require(is_valid(aut_), "proper: invalid automaton");
116  return remover_();
117  }
118 
119  template <star_status_t Status>
120  std::enable_if_t<Status == star_status_t::NON_STARRABLE, aut_proper_t>
121  proper_star_() const
122  {
123  require(is_valid(aut_), "proper: invalid automaton");
124  return remover_();
125  }
126 
127  template <star_status_t Status>
128  std::enable_if_t<Status == star_status_t::STARRABLE, aut_proper_t>
129  proper_star_() const
130  {
131  return remover_();
132  }
133 
134  template <star_status_t Status>
135  std::enable_if_t<Status == star_status_t::TOPS, aut_proper_t>
136  proper_star_() const
137  {
138  try
139  {
140  return remover_();
141  }
142  catch (const std::runtime_error&)
143  {
144  raise("proper: invalid automaton");
145  }
146  }
147 
148 
149  /*-----------------.
150  | In place proper. |
151  `-----------------*/
152 
154  {
155  if (algo_ == "auto" || algo_ == "default" || algo_ == "inplace")
156  {
158  r.in_situ_remover();
159  }
160  else if (algo_ == "separate" || algo_ == "distance")
161  raise("proper: algorithm ", algo_, " cannot be used in place");
162  else
163  raise("proper: invalid algorithm: ", algo_);
164  }
165 
166  template <star_status_t Status>
167  std::enable_if_t<Status == star_status_t::ABSVAL>
169  {
170  require(is_valid(aut_), "proper: invalid automaton");
171  remover_here_();
172  }
173 
174  template <star_status_t Status>
175  std::enable_if_t<Status == star_status_t::NON_STARRABLE>
177  {
178  require(is_valid(aut_), "proper: invalid automaton");
179  remover_here_();
180  }
181 
182  template <star_status_t Status>
183  std::enable_if_t<Status == star_status_t::STARRABLE>
185  {
186  remover_here_();
187  }
188 
189  template <star_status_t Status>
190  std::enable_if_t<Status == star_status_t::TOPS>
192  {
193  try
194  {
195  remover_here_();
196  }
197  catch (const std::runtime_error&)
198  {
199  raise("proper: invalid automaton");
200  }
201  }
202 
203  automaton_t aut_;
204  bool prune_;
205  const std::string& algo_;
206  };
207 
208  template <Automaton Aut>
209  auto make_properer(Aut aut,
210  bool prune = true,
211  const std::string& algo = "auto")
212  {
213  return properer<Aut>(aut, prune, algo);
214  }
215  }
216 
217  /*---------.
218  | proper. |
219  `---------*/
220 
234  template <Automaton Aut>
235  auto
236  proper(const Aut& aut, direction dir = direction::backward,
237  bool prune = true, const std::string& algo = "auto")
239  {
240  switch (dir)
241  {
242  case direction::backward:
243  return detail::make_properer(aut, prune, algo)();
244  case direction::forward:
245  return transpose(proper(transpose(aut),
246  direction::backward, prune, algo));
247  }
249  }
250 
251  template <Automaton Aut>
252  auto
254  bool prune = true)
256  {
258  "backward direction for lazy proper is not implemented");
259  return make_shared_ptr<lazy_proper_automaton<Aut>>(aut, prune);
260  }
261 
268  template <Automaton Aut>
269  inline
271  bool prune = true, const std::string& algo = "auto")
272  {
273  switch (dir)
274  {
275  case direction::backward:
276  detail::make_properer(aut, prune, algo).here();
277  return;
278  case direction::forward:
279  auto tr_aut = transpose(aut);
280  detail::make_properer(tr_aut, prune, algo).here();
281  return;
282  }
283  }
284 
285  namespace dyn
286  {
287  namespace detail
288  {
290  template <Automaton Aut, typename Dir, typename Bool, typename String>
291  automaton proper(const automaton& aut, direction dir, bool prune,
292  const std::string& algo)
293  {
294  const auto& a = aut->as<Aut>();
295  if (algo == "lazy")
296  return make_automaton(proper_lazy(a, dir, prune));
297  else
298  return make_automaton(::vcsn::proper(a, dir, prune, algo));
299  }
300  }
301  }
302 } // namespace vcsn
auto proper_lazy(const Aut &aut, direction dir=direction::backward, bool prune=true) -> lazy_proper_automaton< Aut >
Definition: proper.hh:253
auto map(const std::tuple< Ts... > &ts, Fun f) -> decltype(map_tuple_(f, ts, make_index_sequence< sizeof...(Ts)>()))
Map a function on a tuple, return tuple of the results.
Definition: tuple.hh:160
This class contains the core of the proper algorithm.
labelset_t_of< automaton_t > labelset_t
Definition: proper.hh:34
This class contains the core of the proper algorithm.
automaton proper(const automaton &aut, direction dir, bool prune, const std::string &algo)
Bridge.
Definition: proper.hh:291
Looking upstream.
std::enable_if_t< Status==star_status_t::TOPS, aut_proper_t > proper_star_() const
Definition: proper.hh:136
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
Definition: automaton.hh:75
direction
Orientation.
Definition: direction.hh:9
std::enable_if_t< Status==star_status_t::STARRABLE, aut_proper_t > proper_star_() const
Definition: proper.hh:129
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
Definition: traits.hh:59
std::enable_if_t< Status==star_status_t::STARRABLE > proper_star_here_()
Definition: proper.hh:184
std::enable_if_t< Status==star_status_t::NON_STARRABLE > proper_star_here_()
Definition: proper.hh:176
Definition: a-star.hh:8
weightset_t_of< automaton_t > weightset_t
Definition: proper.hh:33
void require(Bool b, Args &&...args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:78
std::enable_if_t< Status==star_status_t::NON_STARRABLE, aut_proper_t > proper_star_() const
Definition: proper.hh:121
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:55
void here()
In-place spontaneous transition removal.
Definition: proper.hh:69
weightset_mixin< detail::r_impl > r
Definition: fwd.hh:54
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
aut_proper_t remover_() const
Definition: proper.hh:80
Aut transpose(const transpose_automaton< Aut > &aut)
Definition: transpose.hh:227
#define BUILTIN_UNREACHABLE()
Definition: builtins.hh:13
A mapping from strings to Values.
Definition: getargs.hh:33
bool prune_
Whether to prune states that become inaccessible.
aut_proper_t operator()() const
Proper automata with proper context.
Definition: proper.hh:63
This class contains the core of the proper algorithm.
auto make_properer(Aut aut, bool prune=true, const std::string &algo="auto")
Definition: proper.hh:209
std::enable_if_t< Status==star_status_t::ABSVAL > proper_star_here_()
Definition: proper.hh:168
typename Aut::element_type::template fresh_automaton_t< Context > fresh_automaton_t_of
Given an automaton type, the type of its copies.
Definition: traits.hh:74
std::shared_ptr< detail::automaton_base > automaton
Definition: automaton.hh:69
properer(automaton_t aut, bool prune=true, const std::string &algo="auto")
Remove the epsilon-transitions of the input.
Definition: proper.hh:54
bool prune_
Whether to prune states that become inaccessible.
void proper_here(Aut &aut, direction dir=direction::backward, bool prune=true, const std::string &algo="auto")
Eliminate spontaneous transitions in place.
Definition: proper.hh:270
const std::string & algo_
Definition: proper.hh:205
fresh_automaton_t_of< automaton_t, detail::proper_context< context_t_of< automaton_t >>> aut_proper_t
The result type.
Definition: proper.hh:37
std::enable_if_t< Status==star_status_t::TOPS > proper_star_here_()
Definition: proper.hh:191
std::remove_cv_t< Aut > automaton_t
Definition: proper.hh:31
Spontaneous transition elimination.
Definition: proper.hh:29
std::shared_ptr< detail::lazy_proper_automaton_impl< Aut >> lazy_proper_automaton
bool is_valid(const Aut &aut)
Definition: is-valid.hh:141
Looking downstream.
automaton_t aut_
Definition: proper.hh:203
auto proper(const Aut &aut, direction dir=direction::backward, bool prune=true, const std::string &algo="auto") -> fresh_automaton_t_of< Aut, detail::proper_context< context_t_of< Aut >>>
Eliminate spontaneous transitions.
Definition: proper.hh:236
bool prune_
Whether to prune states that become inaccessible.
auto copy(const AutIn &input, KeepState keep_state, KeepTrans keep_trans) -> decltype(keep_state(input->null_state()), keep_trans(input->null_transition()), make_fresh_automaton< AutIn, AutOut >(input))
A copy of input keeping only its states that are accepted by keep_state, and transitions accepted by ...
Definition: copy.hh:308
std::enable_if_t< Status==star_status_t::ABSVAL, aut_proper_t > proper_star_() const
Definition: proper.hh:113