Vcsn  2.2
Be Rational
to-expression.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <boost/heap/fibonacci_heap.hpp>
4 
5 #include <vcsn/algos/copy.hh>
6 #include <vcsn/algos/lift.hh>
8 #include <vcsn/core/rat/info.hh>
9 #include <vcsn/core/rat/size.hh>
10 #include <vcsn/dyn/label.hh>
11 #include <vcsn/misc/builtins.hh>
12 #include <vcsn/misc/getargs.hh>
13 #include <vcsn/misc/vector.hh>
14 
15 namespace vcsn
16 {
17  namespace detail
18  {
19  /*----------------.
20  | Naive profiler. |
21  `----------------*/
22 
25  template <Automaton Aut>
27  {
28  using automaton_t = Aut;
31 
33  : aut_(aut)
34  {}
35 
40  {
42  : state_(state)
43  {}
44 
45  bool operator<(const state_profile& rhs) const
46  {
47  return std::make_tuple(rhs.size_, rhs.has_loop_, rhs.state_)
48  < std::make_tuple(size_, has_loop_, state_);
49  }
50 
51  friend std::ostream& operator<<(std::ostream& o, const state_profile& p)
52  {
53  return o << p.state_
54  << 's' << p.size_
55  << 'l' << p.has_loop_;
56  }
57 
60  size_t size_;
61  bool has_loop_ = false;
63  };
64 
67  {
68  auto p = state_profile{state};
69  update(p);
70  return p;
71  }
72 
74  {}
75 
77  {
78  size_t out = 0;
79  for (auto t: all_out(aut_, p.state_))
80  if (aut_->dst_of(t) == p.state_)
81  p.has_loop_ = true;
82  else
83  ++out;
84  size_t in = all_in(aut_, p.state_).size();
85  p.size_ = in * out;
86  }
87 
89  };
90 
91  /*-------------------.
92  | Delgado profiler. |
93  `-------------------*/
94 
97  template <Automaton Aut>
99  {
100  using automaton_t = Aut;
103 
109  delgado_profiler(const automaton_t& aut, bool count_labels = false)
110  : aut_{aut}
111  , count_labels_{count_labels}
113  {}
114 
116  {
118  : state_(state)
119  {}
120 
121  bool operator<(const state_profile& rhs) const
122  {
123  return std::make_tuple(rhs.size_, rhs.state_)
124  < std::make_tuple(size_, state_);
125  }
126 
127  friend std::ostream& operator<<(std::ostream& o, const state_profile& p)
128  {
129  return o << p.state_
130  << 's' << p.size_;
131  }
132 
133  size_t size_;
135  };
136 
139  {
140  auto p = state_profile{state};
141  update(p);
142  return p;
143  }
144 
149  {
150  auto& res = transition_cache_[t];
151  if (res == 0)
152  {
153  using expset_t = weightset_t_of<automaton_t>;
154  if (count_labels_)
155  res = rat::make_info<expset_t>(aut_->weight_of(t)).atom;
156  else
157  res = rat::size<expset_t>(aut_->weight_of(t));
158  }
159  return res;
160  }
161 
167  {
168  if (transition_cache_.size() <= t)
169  transition_cache_.resize(t + 1, 0);
170  transition_cache_[t] = 0;
171  }
172 
178  {
179  // The cumulated size of the incoming transitions excluding loops.
180  size_t size_in = 0;
181  // The number of incoming transitions excluding loops.
182  size_t ins = 0;
183  // The size of the loop, if there is one.
184  size_t size_loop = 0;
185  for (auto t: all_in(aut_, p.state_))
186  if (aut_->src_of(t) == p.state_)
187  size_loop += size_of_transition(t);
188  else
189  {
190  ++ins;
191  size_in += size_of_transition(t);
192  }
193 
194  // The cumulated size of the outgoing transitions excluding loops.
195  size_t size_out = 0;
196  // The number of outgoing transitions excluding loops.
197  size_t outs = 0;
198  for (auto t: all_out(aut_, p.state_))
199  if (aut_->dst_of(t) != p.state_)
200  {
201  ++outs;
202  size_out += size_of_transition(t);
203  }
204 
205  p.size_ = (size_in * (outs - 1)
206  + size_out * (ins - 1)
207  + size_loop * (ins * outs - 1));
208  }
209 
212  std::vector<size_t> transition_cache_;
213  };
214  }
215 
216  /*------------------.
217  | eliminate_state. |
218  `------------------*/
219 
220  namespace detail
221  {
225  template <Automaton Aut, typename Profiler>
227  {
228  using profiler_t = Profiler;
229  using profile_t = typename profiler_t::state_profile;
230  using automaton_t = std::remove_cv_t<Aut>;
232 
238  : aut_(aut)
239  , profiler_(profiler)
240  , handles_(aut_->all_states().back() + 1)
241  {
242  for (auto s: aut_->states())
243  handles_[s] = todo_.emplace(profiler_.make_state_profile(s));
244  }
245 
248  {
249  if (s == aut_->null_state())
250  {
251  require(!todo_.empty(), "no state left to remove");
252  auto p = todo_.top();
253  todo_.pop();
254  s = p.state_;
255  }
256  else
257  require(aut_->has_state(s), "not a valid state: ", s);
258  eliminate_state_(s);
259  }
260 
262  void operator()()
263  {
264  while (!todo_.empty())
265  {
266  auto p = todo_.top();
267  todo_.pop();
268 
269 #ifdef DEBUG_LOOP
270  std::cerr << "Remove: " << p << std::endl;
271 #endif
272  eliminate_state_(p.state_);
273  }
274  }
275 
276  private:
278  {
279 #ifdef DEBUG_UPDATE
280  std::cerr << "update heap: (";
281  show_heap_();
282 #endif
283  for (auto s: neighbors_)
284  if (s != aut_->pre() && s != aut_->post())
285  {
286  auto& h = handles_[s];
287  profiler_.update(*h);
288  todo_.update(h);
289  }
290 #ifdef DEBUG_UPDATE
291  std::cerr << ") => ";
292  show_heap_();
293  std::cerr << std::endl;
294 #endif
295  }
296 
298  void show_heap_() const
299  {
300  const char* sep = "";
301  for (auto i = todo_.ordered_begin(), end = todo_.ordered_end();
302  i != end; ++i)
303  {
304  std::cerr << sep << *i;
305  sep = " > ";
306  }
307  }
308 
310  template <typename Kind = typename context_t_of<automaton_t>::kind_t>
312  -> std::enable_if_t<std::is_same<Kind, labels_are_one>::value,
313  void>
314  {
315  neighbors_.clear();
316 
317  // Shorthand to the labelset.
318  const auto& ls = *aut_->labelset();
319 
320  // Shorthand to the weightset.
321  const auto& ws = *aut_->weightset();
322 
323  // The loop's weight.
324  auto loop = ws.zero();
325  assert(outin(aut_, s, s).size() <= 1);
326  // There is a single possible loop labeled by \e, but it's
327  // easier and symmetrical with LAR to use a for-loop.
328  for (auto t: make_vector(outin(aut_, s, s)))
329  {
330  loop = ws.add(loop, aut_->weight_of(t));
331  aut_->del_transition(t);
332  }
333  loop = ws.star(loop);
334 
335  // Get all the predecessors, and successors, except itself.
336  auto outs = all_out(aut_, s);
337  for (auto in: all_in(aut_, s))
338  for (auto out: outs)
339  {
340  auto src = aut_->src_of(in);
341  auto dst = aut_->dst_of(out);
342  auto t = aut_->add_transition
343  (src, dst,
344  // Of course, most of the time \e\e => \e. But there
345  // is also $ to take into account when eliminating an
346  // initial/final state.
347  ls.mul(aut_->label_of(in), aut_->label_of(out)),
348  ws.mul(aut_->weight_of(in), loop, aut_->weight_of(out)));
349  profiler_.invalidate_cache(t);
350  neighbors_.emplace(src);
351  neighbors_.emplace(dst);
352  }
353 
354  aut_->del_state(s);
355  update_heap_();
356  }
357 
359  //
360  // FIXME: expressionset<lal_char(a-c), z>, q for instance cannot
361  // work, because we need to move the q weights inside the
362  // lal_char(a-c), z expressions, which obviously not possible.
363  // So we need to require that there is a subtype relationship
364  // between the weightset and the weightset of the expression.
365  //
366  // Yet as of 2014-07, there is no means to check that subtype
367  // relationship in Vcsn.
368  template <typename Kind>
370  -> std::enable_if_t<std::is_same<Kind, labels_are_expressions>::value,
371  void>
372  {
373  neighbors_.clear();
374 
375  // Shorthand to the labelset, which is an expressionset.
376  const auto& rs = *aut_->labelset();
377 
378  // The loops' expression.
379  auto loop = rs.zero();
380  for (auto t: make_vector(outin(aut_, s, s)))
381  {
382  loop = rs.add(loop,
383  rs.lmul(aut_->weight_of(t), aut_->label_of(t)));
384  aut_->del_transition(t);
385  }
386  loop = rs.star(loop);
387 
388  // Get all the predecessors, and successors, except itself.
389  auto outs = all_out(aut_, s);
390  for (auto in: all_in(aut_, s))
391  for (auto out: outs)
392  {
393  auto src = aut_->src_of(in);
394  auto dst = aut_->dst_of(out);
395  auto t = aut_->add_transition
396  (src, dst,
397  rs.mul(rs.lmul(aut_->weight_of(in), aut_->label_of(in)),
398  loop,
399  rs.lmul(aut_->weight_of(out), aut_->label_of(out))));
400  profiler_.invalidate_cache(t);
401  neighbors_.emplace(src);
402  neighbors_.emplace(dst);
403  }
404 
405  aut_->del_state(s);
406  update_heap_();
407  }
408 
413 
415  using heap_t = boost::heap::fibonacci_heap<profile_t>;
418  std::vector<typename heap_t::handle_type> handles_;
419 
420  std::unordered_set<state_t> neighbors_;
421  };
422 
423  template <Automaton Aut, typename Profiler>
425  make_state_eliminator(Aut& a, Profiler& profiler)
426  {
427  return state_eliminator<Aut, Profiler>(a, profiler);
428  }
429  }
430 
431 
433  template <Automaton Aut>
434  Aut&
436  state_t_of<Aut> s = Aut::element_type::null_state())
437  {
438  // Delgado profiler not fit for lao with non expression weightset.
439  auto profiler = detail::naive_profiler<Aut>(res);
440  auto eliminate_state = detail::make_state_eliminator(res, profiler);
441  eliminate_state(s);
442  return res;
443  }
444 
446  template <Automaton Aut>
447  auto
448  eliminate_state(const Aut& aut,
449  state_t_of<Aut> s = Aut::element_type::null_state())
451  {
452  // Get a copy, but be sure to keep the correspondance bw original
453  // state numbers and the new ones.
454  auto res = make_fresh_automaton<Aut>(aut);
455  auto copy = make_copier(aut, res);
456  copy();
457  if (s != aut->null_state())
458  {
459  require(aut->has_state(s), "not a valid state: ", s);
460  s = copy.state_map().at(s);
461  }
462  return eliminate_state_here(res, s);
463  }
464 
465 
466  /*-----------------------.
467  | dyn::eliminate_state. |
468  `-----------------------*/
469 
470  namespace dyn
471  {
472  namespace detail
473  {
475  template <Automaton Aut, typename Int>
476  automaton
477  eliminate_state(const automaton& aut, int state)
478  {
479  const auto& a = aut->as<Aut>();
480  using state_t = state_t_of<Aut>;
481  auto s = 0 <= state ? state_t(state + 2) : a->null_state();
483  }
484  }
485  }
486 
487 
488  /*----------------------------.
489  | to_expression(automaton). |
490  `----------------------------*/
491 
492  template <Automaton Aut,
493  typename Profiler,
494  typename ExpSet = expressionset<context_t_of<Aut>>>
495  typename ExpSet::value_t
496  to_expression(Aut& a, Profiler& profiler)
497  {
498  auto eliminate_states = detail::make_state_eliminator(a, profiler);
499  eliminate_states();
500  return a->get_initial_weight(a->post());
501  }
502 
504  {
505  best,
506  delgado,
508  naive,
509  };
510 
511  template <Automaton Aut,
512  typename ExpSet = expressionset<context_t_of<Aut>>>
513  typename ExpSet::value_t
516  {
517  // State elimination is performed on the lifted automaton.
518  auto a = lift(aut, ids);
519  using delgado_t = detail::delgado_profiler<decltype(a)>;
520  using naive_t = detail::naive_profiler<decltype(a)>;
521  switch (algo)
522  {
524  raise("next_state: invalid algorithm: best");
525 
527  {
528  auto profiler = delgado_t(a);
529  return to_expression<decltype(a), delgado_t, ExpSet>(a, profiler);
530  }
531 
533  {
534  auto profiler = delgado_t(a, true);
535  return to_expression<decltype(a), delgado_t, ExpSet>(a, profiler);
536  }
537 
539  {
540  auto profiler = naive_t(a);
541  return to_expression<decltype(a), naive_t, ExpSet>(a, profiler);
542  }
543  }
545  }
546 
547  template <Automaton Aut,
548  typename ExpSet = expressionset<context_t_of<Aut>>>
549  typename ExpSet::value_t
552  {
554  {
555  typename ExpSet::value_t best;
556  auto best_size = std::numeric_limits<size_t>::max();
560  {
561  auto r = to_expression_heuristic<Aut, ExpSet>(aut, ids, a);
562  auto s = rat::size<ExpSet>(r);
563  if (s < best_size)
564  {
565  best = r;
566  best_size = s;
567  }
568  }
569  return best;
570  }
571  else
572  {
573  return to_expression_heuristic<Aut, ExpSet>(aut, ids, algo);
574  }
575  }
576 
577  template <Automaton Aut,
578  typename ExpSet = expressionset<context_t_of<Aut>>>
579  typename ExpSet::value_t
581  const std::string& algo)
582  {
583  static const auto map = getarg<to_expression_heuristic_t>
584  {
585  "heuristics",
586  {
587  {"auto", "best"},
590  {"delgado_label", to_expression_heuristic_t::delgado_label},
592  }
593  };
594  return to_expression<Aut, ExpSet>(a, ids, map[algo]);
595  }
596 
597  /*----------------------------.
598  | to_expression(automaton). |
599  `----------------------------*/
600 
601  namespace dyn
602  {
603  namespace detail
604  {
606  template <Automaton Aut, typename Identities, typename String>
607  expression
609  const std::string& algo)
610  {
611  const auto& a = aut->as<Aut>();
612  using context_t = context_t_of<Aut>;
613  using expressionset_t = vcsn::expressionset<context_t>;
614  auto rs = expressionset_t{a->context(), ids};
615  auto res = ::vcsn::to_expression(a, ids, algo);
616  return make_expression(rs, res);
617  }
618  }
619  }
620 
621  /*------------------------.
622  | to_expression(label). |
623  `------------------------*/
624 
625  namespace dyn
626  {
627  namespace detail
628  {
630  template <typename Context, typename Identities, typename Label>
631  expression
633  const label& lbl)
634  {
635  const auto& c = ctx->as<Context>();
636  const auto& l = lbl->as<Label>();
637  auto rs = vcsn::make_expressionset(c, ids);
638  return make_expression(rs, rs.atom(l.label()));
639  }
640  }
641  }
642 
643 
644  /*-------------------------------.
645  | to_expression(letter_class). |
646  `-------------------------------*/
647 
648  namespace detail
649  {
650  template <typename ExpSet>
651  auto letter_class_impl(const ExpSet&,
652  const letter_class_t&, bool,
653  std::false_type, std::true_type)
654  -> typename ExpSet::value_t
655  {
656  raise("letter_class: not implemented (is_expressionset)");
657  }
658 
659  template <typename ExpSet>
660  auto letter_class_impl(const ExpSet& rs,
661  const letter_class_t& chars, bool accept,
662  std::false_type, std::false_type)
663  -> typename ExpSet::value_t
664  {
665  auto ls = *rs.labelset();
666 
667  using labelset_t = decltype(ls);
668  using letter_t = typename labelset_t::letter_t;
669 
670  auto ccs = std::set<std::pair<letter_t, letter_t>>{};
671  for (const auto& cc: chars)
672  {
673  std::istringstream i1{cc.first};
674  std::istringstream i2{cc.second};
675  letter_t l1 = ls.get_letter(i1, false);
676  letter_t l2 = ls.get_letter(i2, false);
677  ccs.emplace(l1, l2);
678  }
679  return rs.letter_class(ccs, accept);
680  }
681 
682  template <typename ExpSet>
683  auto letter_class_impl(const ExpSet& rs,
684  const letter_class_t&, bool,
685  std::true_type, std::false_type)
686  -> typename ExpSet::value_t
687  {
688  return rs.one();
689  }
690  }
691 
701  template <typename ExpressionSet>
702  typename ExpressionSet::value_t
703  to_expression(const ExpressionSet& rs, const letter_class_t& letters,
704  bool accept = true)
705  {
706  using labelset_t = labelset_t_of<ExpressionSet>;
707  using is_one_t = std::is_same<labelset_t, vcsn::oneset>;
709  return detail::letter_class_impl(rs, letters, accept,
710  is_one_t{}, is_expset_t{});
711  }
712 
713  namespace dyn
714  {
715  namespace detail
716  {
718  template <typename Context, typename Identities,
719  typename Letters, typename Bool>
720  expression
722  const letter_class_t& letters, bool accept)
723  {
724  const auto& c = ctx->as<Context>();
725  auto rs = vcsn::make_expressionset(c, ids);
726  return make_expression(rs, to_expression(rs, letters, accept));
727  }
728  }
729  }
730 } // vcsn::
std::vector< typename heap_t::handle_type > handles_
Map: state -> heap-handle.
std::integral_constant< bool, B > bool_constant
Definition: type_traits.hh:12
auto all_out(const Aut &aut, state_t_of< Aut > s)
Indexes of transitions leaving state s.
Definition: automaton.hh:37
size_t size_of_transition(transition_t t)
The "weight" of a transition.
Container::value_type back(const Container &container)
The last member of this Container.
Definition: algorithm.hh:27
transition_t_of< automaton_t > transition_t
automaton eliminate_state(const automaton &aut, int state)
Bridge.
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
Definition: automaton.hh:75
ExpSet::value_t to_expression_heuristic(const Aut &aut, vcsn::rat::identities ids, to_expression_heuristic_t algo)
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
Definition: traits.hh:59
auto eliminate_state_(state_t s) -> std::enable_if_t< std::is_same< Kind, labels_are_one >::value, void >
Eliminate state s in the case of labels are one.
An expressionset can implement several different sets of identities on expressions.
Definition: identities.hh:21
state_eliminator< Aut, Profiler > make_state_eliminator(Aut &a, Profiler &profiler)
Definition: a-star.hh:8
Aut & eliminate_state_here(Aut &res, state_t_of< Aut > s=Aut::element_type::null_state())
In place removal of state s from automaton res.
void require(Bool b, Args &&...args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:78
bool operator<(const state_profile &rhs) const
auto all_in(const Aut &aut, state_t_of< Aut > s)
Indexes of transitions entering state s.
Definition: automaton.hh:86
std::set< std::pair< std::string, std::string >> letter_class_t
A set of letter ranges.
Definition: fwd.hh:111
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:55
boost::heap::fibonacci_heap< profile_t > heap_t
Max-heap to decide the order of state-elimination.
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
void operator()()
Eliminate all the states, in the order specified by next_state.
state_profile make_state_profile(state_t state)
to_expression_heuristic_t
expression to_expression(const automaton &aut, vcsn::rat::identities ids, const std::string &algo)
Bridge.
void invalidate_cache(transition_t)
state_t_of< automaton_t > state_t
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:56
#define BUILTIN_UNREACHABLE()
Definition: builtins.hh:13
std::shared_ptr< const detail::label_base > label
Definition: fwd.hh:61
void show_heap_() const
Show the heap, for debugging.
auto out(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions leaving state s.
Definition: automaton.hh:56
A mapping from strings to Values.
Definition: getargs.hh:33
state_profile make_state_profile(state_t state)
friend std::ostream & operator<<(std::ostream &o, const state_profile &p)
naive_profiler(const automaton_t &aut)
std::vector< size_t > transition_cache_
auto letter_class_impl(const ExpSet &, const letter_class_t &, bool, std::false_type, std::true_type) -> typename ExpSet::value_t
ExpSet::value_t to_expression(Aut &a, Profiler &profiler)
std::shared_ptr< const detail::context_base > context
A dyn::context.
Definition: fwd.hh:43
std::vector< typename Cont::value_type > make_vector(const Cont &cont)
The content of cont as a vector.
Definition: vector.hh:20
std::unordered_set< state_t > neighbors_
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
auto rs
Definition: lift.hh:151
automaton_t aut_
The automaton we work on.
typename detail::transition_t_of_impl< base_t< ValueSet >>::type transition_t_of
Definition: traits.hh:57
ExpressionSet::value_t to_expression(const ExpressionSet &rs, const letter_class_t &letters, bool accept=true)
An expression matching one letter in a letter class.
void invalidate_cache(transition_t t)
Updating transitions' size in the cache during the profiler's construction would be clearer but appea...
bool operator<(const state_profile &rhs) const
Compute a state profile for state-elimination based on the Delgado-Morais heuristic.
auto eliminate_state_impl_(state_t s) -> std::enable_if_t< std::is_same< Kind, labels_are_expressions >::value, void >
Eliminate state s in the case of labels are expressions.
expression to_expression_class(const context &ctx, rat::identities ids, const letter_class_t &letters, bool accept)
Bridge (to_expression).
void update(state_profile &p)
The "weight" of a state, as defined by Delgado-Morais.
expressionset< Context > make_expressionset(const Context &ctx, rat::identities identities={})
Shorthand to expressionset constructor.
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:53
The state profile is the product of the number of (strictly) incoming transitions with the number of ...
state_t_of< automaton_t > state_t
Eliminate states in an automaton.
expression to_expression_label(const context &ctx, rat::identities ids, const label &lbl)
Bridge (to_expression).
static dyn::context ctx(const driver &d)
Get the context of the driver.
Definition: parse.cc:82
delgado_profiler(const automaton_t &aut, bool count_labels=false)
Build a generator of Delgado-Morais state profiles.
void update(state_profile &p)
state_t_of< automaton_t > state_t
auto outin(const Aut &aut, state_t_of< Aut > s, state_t_of< Aut > d)
Indexes of visible transitions from state s to state d.
Definition: automaton.hh:159
state_eliminator(automaton_t &aut, profiler_t &profiler)
Prepare for state-elimination.
detail::copier< AutIn, AutOut > make_copier(const AutIn &in, AutOut &out, bool safe=true)
Build an automaton copier.
Definition: copy.hh:249
typename profiler_t::state_profile profile_t
profiler_t & profiler_
The profiler we work with. Corresponding to a specific heuristic.
std::shared_ptr< detail::expression_base > expression
Definition: expression.hh:92
auto eliminate_state(const Aut &aut, state_t_of< Aut > s=Aut::element_type::null_state()) -> fresh_automaton_t_of< Aut >
A copy of automaton res without the state s.
Compute a state profile for state-elimination based on connectivity.
static identities ids(const driver &d)
Get the identities of the driver.
Definition: parse.cc:89
size_t size_
Number of strictly incoming transitions, times the number of strictly outgoing transitions.
auto all_transitions(const Aut &aut)
All the transition indexes between all states (including pre and post).
Definition: automaton.hh:184
#define Automaton
Definition: automaton.hh:24
void operator()(state_t s)
Eliminate state s.
friend std::ostream & operator<<(std::ostream &o, const state_profile &p)
std::remove_cv_t< Aut > automaton_t
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
detail::lifted_automaton_t< Aut, Tapes... > lift(const Aut &a, vcsn::rat::identities ids={})
Lift some tapes of the transducer.
Definition: lift.hh:215
auto in(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions arriving to state s.
Definition: automaton.hh:105
expression make_expression(const ExpSet &rs, const typename ExpSet::value_t &r)
Definition: expression.hh:97
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
transition_t_of< automaton_t > transition_t