Vcsn  2.1
Be Rational
mutable-automaton.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <algorithm>
4 #include <cassert>
5 #include <vector>
6 
7 #include <boost/range/algorithm/find.hpp>
8 #include <boost/range/algorithm/find_if.hpp>
9 #include <boost/range/irange.hpp>
10 
11 #include <vcsn/misc/crange.hh>
12 #include <vcsn/core/fwd.hh>
13 #include <vcsn/core/transition.hh>
14 #include <vcsn/ctx/context.hh>
15 #include <vcsn/ctx/traits.hh>
16 #include <vcsn/misc/format.hh>
17 #include <vcsn/misc/memory.hh>
18 #include <vcsn/misc/symbol.hh>
19 
20 namespace vcsn
21 {
22  namespace detail
23  {
24  template <typename Context>
25  class mutable_automaton_impl
26  {
27  public:
28  using context_t = Context;
31  template <typename Ctx = Context>
35  using kind_t = typename context_t::kind_t;
36 
37  using labelset_ptr = typename context_t::labelset_ptr;
38  using weightset_ptr = typename context_t::weightset_ptr;
39 
41  using state_t = unsigned;
43  using transition_t = unsigned;
45  using label_t = typename labelset_t::value_t;
47  using weight_t = typename weightset_t::value_t;
48 
49  protected:
52 
55 
57  using tr_store_t = std::vector<stored_transition_t>;
59  using tr_cont_t = std::vector<transition_t>;
60 
63  {
68  };
69 
71  using st_store_t = std::vector<stored_state_t>;
72 
74  using free_store_t = std::vector<unsigned>;
75 
84 
85  public:
86  mutable_automaton_impl() = delete;
89  : ctx_{ctx}
90  , states_{2}
91  , prepost_label_(ctx.labelset()->special())
92  {}
93 
95  : ctx_(that.ctx_)
96  , prepost_label_(that.prepost_label_)
97  {
98  *this = std::move(that);
99  }
100 
102  {
103  if (this != &that)
104  {
105  ctx_ = std::move(that.ctx_);
106  prepost_label_ = std::move(that.prepost_label_);
107  std::swap(states_, that.states_);
108  std::swap(states_fs_, that.states_fs_);
109  std::swap(transitions_, that.transitions_);
110  std::swap(transitions_fs_, that.transitions_fs_);
111  }
112  return *this;
113  }
114 
115 
116  /*----------------.
117  | Related sets. |
118  `----------------*/
119 
120  static symbol sname()
121  {
122  static symbol res("mutable_automaton<" + context_t::sname() + '>');
123  return res;
124  }
125 
126  std::ostream& print_set(std::ostream& o, format fmt = {}) const
127  {
128  o << "mutable_automaton<";
129  context().print_set(o, fmt);
130  return o << '>';
131  }
132 
133  const context_t& context() const { return ctx_; }
134  const weightset_ptr& weightset() const { return ctx_.weightset(); }
135  const labelset_ptr& labelset() const { return ctx_.labelset(); }
136 
137 
138  /*----------------------------------.
139  | Special states and transitions. |
140  `----------------------------------*/
141 
142  // pseudo-initial and final states.
143  // The code below assumes that pre() and post() are the first
144  // two states of the automaton. In other words, all other states
145  // have greater numbers. We also assume that pre()<post().
146  static constexpr state_t pre() { return 0U; }
147  static constexpr state_t post() { return 1U; }
149  static constexpr state_t null_state() { return -1U; }
151  static constexpr transition_t null_transition() { return -1U; }
152 
154  label_t prepost_label() const
155  {
156  return prepost_label_;
157  }
158 
159 
160  /*--------------.
161  | Statistics. |
162  `--------------*/
163 
164  size_t num_all_states() const { return states_.size() - states_fs_.size(); }
165  size_t num_states() const { return num_all_states() - 2; }
166  size_t num_initials() const { return states_[pre()].succ.size(); }
167  size_t num_finals() const { return states_[post()].pred.size(); }
168  size_t num_transitions() const
169  {
170  return (transitions_.size()
171  - transitions_fs_.size() - num_initials() - num_finals());
172  }
173 
174 
175  /*---------------------.
176  | Queries on states. |
177  `---------------------*/
178 
180  bool
181  has_state(state_t s) const
182  {
183  // Any number outside our container is not a state.
184  // (This includes "null_state()".)
185  if (states_.size() <= s)
186  return false;
187  else
188  {
189  const stored_state_t& ss = states_[s];
190  // Erased states have 'invalid' as their first successor.
191  return ss.succ.empty() || ss.succ.front() != null_transition();
192  }
193  }
194 
196  bool
197  state_is_strict(state_t s) const
198  {
199  assert(has_state(s)); (void) s;
200  return true;
201  }
202 
204  bool
205  is_initial(state_t s) const
206  {
207  return has_transition(pre(), s, prepost_label_);
208  }
209 
211  bool
212  is_final(state_t s) const
213  {
214  return has_transition(s, post(), prepost_label_);
215  }
216 
218  ATTRIBUTE_PURE
219  weight_t
220  get_initial_weight(state_t s) const
221  {
222  transition_t t = get_transition(pre(), s, prepost_label_);
223  if (t == null_transition())
224  return weightset()->zero();
225  else
226  return weight_of(t);
227  }
228 
230  ATTRIBUTE_PURE
231  weight_t
232  get_final_weight(state_t s) const
233  {
234  transition_t t = get_transition(s, post(), prepost_label_);
235  if (t == null_transition())
236  return weightset()->zero();
237  else
238  return weight_of(t);
239  }
240 
241 
242  /*--------------------------.
243  | Queries on transitions. |
244  `--------------------------*/
245 
246  transition_t
247  get_transition(state_t src, state_t dst, label_t l) const
248  {
249  assert(has_state(src));
250  assert(has_state(dst));
251  const tr_cont_t& succ = states_[src].succ;
252  const tr_cont_t& pred = states_[dst].pred;
253  const auto& ls = *this->labelset();
254  if (succ.size() <= pred.size())
255  {
256  auto i =
257  boost::find_if(succ,
258  [this,l,ls,dst] (transition_t t)
259  {
260  return (dst_of(t) == dst
261  && ls.equal(label_of(t), l));
262  });
263  if (i != end(succ))
264  return *i;
265  }
266  else
267  {
268  auto i =
269  boost::find_if(pred,
270  [this,l,ls,src] (transition_t t)
271  {
272  return (src_of(t) == src
273  && ls.equal(label_of(t), l));
274  });
275  if (i != end(pred))
276  return *i;
277  }
278  return null_transition();
279  }
280 
281  bool
282  has_transition(state_t src, state_t dst, label_t l) const
283  {
284  return get_transition(src, dst, l) != null_transition();
285  }
286 
287  bool
288  has_transition(transition_t t) const
289  {
290  // Any number outside our container is not a transition.
291  // (This includes "null_transition()".)
292  if (t >= transitions_.size())
293  return false;
294 
295  // Erased transition have invalid source state.
296  return transitions_[t].src != null_state();
297  }
298 
299  state_t src_of(transition_t t) const { return transitions_[t].src; }
300  state_t dst_of(transition_t t) const { return transitions_[t].dst; }
301  label_t label_of(transition_t t) const
302  {
303  return transitions_[t].get_label();
304  }
305 
306  weight_t weight_of(transition_t t) const
307  {
308  return transitions_[t].get_weight();
309  }
310 
311 
312  /*---------------------.
313  | Edition of states. |
314  `---------------------*/
315 
316  protected:
318  void
319  del_transition_from_src(transition_t t)
320  {
321  stored_transition_t& st = transitions_[t];
322  auto& succ = states_[st.src].succ;
323  auto tsucc = boost::range::find(succ, t);
324  assert(tsucc != succ.end());
325  *tsucc = std::move(succ.back());
326  succ.pop_back();
327  }
328 
330  void
331  del_transition_from_dst(transition_t t)
332  {
333  stored_transition_t& st = transitions_[t];
334  auto& pred = states_[st.dst].pred;
335  auto tpred = boost::range::find(pred, t);
336  assert(tpred != pred.end());
337  *tpred = std::move(pred.back());
338  pred.pop_back();
339  }
340 
341  void
342  del_transition_container(tr_cont_t& tc, bool from_succ)
343  {
344  for (auto t: tc)
345  {
346  if (from_succ)
347  del_transition_from_dst(t);
348  else
349  del_transition_from_src(t);
350  transitions_[t].src = null_state();
351  }
352  transitions_fs_.insert(transitions_fs_.end(), tc.begin(), tc.end());
353  tc.clear();
354  }
355 
356  public:
358  state_t
359  new_state()
360  {
361  state_t res;
362  if (states_fs_.empty())
363  {
364  res = states_.size();
365  states_.emplace_back();
366  }
367  else
368  {
369  res = states_fs_.back();
370  states_fs_.pop_back();
371  stored_state_t& ss = states_[res];
372  // De-invalidate this state: remove the invalid transition.
373  ss.succ.clear();
374  }
375  return res;
376  }
377 
378  std::ostream&
379  print_state(state_t s, std::ostream& o) const
380  {
381  if (s == pre())
382  o << "pre";
383  else if (s == post())
384  o << "post";
385  else
386  o << s - 2;
387  return o;
388  }
389 
390  std::ostream&
391  print_state_name(state_t s, std::ostream& o,
392  format = {},
393  bool = false) const
394  {
395  return print_state(s, o);
396  }
397 
398  static constexpr bool
399  state_has_name(state_t)
400  {
401  return false;
402  }
403 
404  void
405  del_state(state_t s)
406  {
407  assert(has_state(s));
408  assert(s > post()); // Cannot erase pre() and post().
409  stored_state_t& ss = states_[s];
410  del_transition_container(ss.pred, false);
411  del_transition_container(ss.succ, true);
412  ss.succ.emplace_back(null_transition()); // So has_state() can work.
413  states_fs_.emplace_back(s);
414  }
415 
416  void
417  set_initial(state_t s, weight_t w)
418  {
419  set_transition(pre(), s, prepost_label_, w);
420  }
421 
422  void
423  set_initial(state_t s)
424  {
425  set_initial(s, weightset()->one());
426  }
427 
428  transition_t
429  add_initial(state_t s, weight_t w)
430  {
431  return add_transition(pre(), s, prepost_label_, w);
432  }
433 
434  void
435  unset_initial(state_t s)
436  {
437  set_initial(s, weightset()->zero());
438  }
439 
440  void
441  set_final(state_t s, weight_t w)
442  {
443  set_transition(s, post(), prepost_label_, w);
444  }
445 
446  void
447  set_final(state_t s)
448  {
449  set_final(s, weightset()->one());
450  }
451 
452  transition_t
453  add_final(state_t s, weight_t w)
454  {
455  return add_transition(s, post(), prepost_label_, w);
456  }
457 
458  void
459  unset_final(state_t s)
460  {
461  set_final(s, weightset()->zero());
462  }
463 
464 
465  /*--------------------------.
466  | Edition of transitions. |
467  `--------------------------*/
468 
469  void
470  del_transition(transition_t t)
471  {
472  assert(has_transition(t));
473  // Remove transition from source and destination.
474  del_transition_from_src(t);
475  del_transition_from_dst(t);
476  // Actually erase the transition.
477  transitions_[t].src = null_state();
478  transitions_fs_.emplace_back(t);
479  }
480 
482  void
483  del_transition(state_t src, state_t dst, label_t l)
484  {
485  transition_t t = get_transition(src, dst, l);
486  if (t != null_transition())
487  del_transition(t);
488  }
489 
491  void
492  del_transition(state_t s, state_t d)
493  {
494  // Make a copy of the transition indexes, as the iterators are
495  // invalidated by del_transition(t).
496  auto ts = outin(s, d);
497  for (auto t: tr_cont_t{std::begin(ts), std::end(ts)})
498  del_transition(t);
499  }
500 
511  transition_t
512  new_transition(state_t src, state_t dst, label_t l, weight_t w)
513  {
514  assert(!has_transition(src, dst, l));
515  if (weightset()->is_zero(w))
516  return null_transition();
517  else
518  {
519  // FIXME: When src == pre() || dst == post(), label must be empty.
520  transition_t t;
521  if (transitions_fs_.empty())
522  {
523  t = transitions_.size();
524  transitions_.emplace_back(src, dst, l, w);
525  }
526  else
527  {
528  t = transitions_fs_.back();
529  transitions_fs_.pop_back();
530  stored_transition_t& st = transitions_[t];
531  st.src = src;
532  st.dst = dst;
533  st.set_label(l);
534  st.set_weight(w);
535  }
536  states_[src].succ.emplace_back(t);
537  states_[dst].pred.emplace_back(t);
538  return t;
539  }
540  }
541 
554  template <typename A>
555  transition_t
556  new_transition_copy(state_t src, state_t dst,
557  const A& aut, typename A::element_type::transition_t t,
558  bool transpose = false)
559  {
560  auto l = aut->label_of(t);
561  auto w = aut->weight_of(t);
562  if (transpose)
563  {
564  l = aut->labelset()->transpose(l);
565  w = aut->weightset()->transpose(w);
566  }
567  return new_transition(src, dst,
568  labelset()->conv(*aut->labelset(), l),
569  weightset()->conv(*aut->weightset(), w));
570  }
571 
573  transition_t
574  new_transition(state_t src, state_t dst, label_t l)
575  {
576  return new_transition(src, dst, l, weightset()->one());
577  }
578 
589  transition_t
590  set_transition(state_t src, state_t dst, label_t l, weight_t w)
591  {
592  // It's illegal to connect pre() to post().
593  // FIXME: reenable except for labels_are_one.
594  // assert(src != pre() || dst != post());
595  // It's illegal to leave post().
596  assert(src != post());
597  // It's illegal to go to pre().
598  assert(dst != pre());
599 
600  transition_t t = get_transition(src, dst, l);
601  if (t == null_transition())
602  t = new_transition(src, dst, l, w);
603  else if (weightset()->is_zero(w))
604  {
605  del_transition(t);
606  t = null_transition();
607  }
608  else
609  {
610  stored_transition_t& st = transitions_[t];
611  st.set_label(l);
612  st.set_weight(w);
613  }
614  return t;
615  }
616 
620  {
621  return set_transition(src, dst, l, weightset()->one());
622  }
623 
636  {
637  transition_t t = get_transition(src, dst, l);
638  if (t == null_transition())
639  t = new_transition(src, dst, l, w);
640  else
641  {
642  w = weightset()->add(weight_of(t), w);
643  t = set_weight(t, w);
644  }
645  return t;
646  }
647 
651  {
652  return add_transition(src, dst, l, weightset()->one());
653  }
654 
663  template <typename A>
666  const A& aut, typename A::element_type::transition_t t,
667  bool transpose = false)
668  {
669  auto l = aut->label_of(t);
670  auto w = aut->weight_of(t);
671  if (transpose)
672  {
673  l = aut->labelset()->transpose(l);
674  w = aut->weightset()->transpose(w);
675  }
676  return add_transition(src, dst,
677  labelset()->conv(*aut->labelset(), l),
678  weightset()->conv(*aut->weightset(), w));
679  }
680 
681  std::string
683  {
684  constexpr char langle = '<';
685  constexpr char rangle = '>';
686 
687  std::ostringstream o;
688  o << src_of(t)
689  << " -- "
690  << langle;
691  weightset()->print(weight_of(t), o)
692  << rangle;
693  labelset()->print(label_of(t), o)
694  << " --> "
695  << dst_of(t);
696  return o.str();
697  }
698 
701  {
702  if (weightset()->is_zero(w))
703  {
704  del_transition(t);
705  return null_transition();
706  }
707  else
708  transitions_[t].set_weight(w);
709  return t;
710  }
711 
712  weight_t
714  {
715  return weight_of(set_weight(t, weightset()->add(weight_of(t), w)));
716  }
717 
718  weight_t
720  {
721  return weight_of(set_weight(t, weightset()->mul(w, weight_of(t))));
722  }
723 
724  weight_t
726  {
727  return weight_of(set_weight(t, weightset()->mul(weight_of(t), w)));
728  }
729 
730 
731  /*---------------------------------------.
732  | Iteration on states and transitions. |
733  `---------------------------------------*/
734 
735  template <typename Pred>
736  using states_output_t
738 
739  protected:
740  // FIXME: Exists only to work around Clang++ 3.5 dying on debug
741  // symbols for functions with deduced return type.
742  template <typename Pred>
744  {
745  auto operator()(state_t s) -> bool
746  {
747  const stored_state_t& ss = aut_.states_[s];
748  return ((ss.succ.empty()
749  || ss.succ.front() != aut_.null_transition())
750  && pred_(s));
751  }
753  Pred pred_;
754  };
755 
758  template <typename Pred>
760  state_range(state_t b, state_t e, Pred pred) const
761  {
762  return
763  {boost::irange<state_t>(b, e), valid_state_p<Pred>{*this, pred}};
764  }
765 
766  // FIXME: clang workaround.
774  {
775  bool operator()(state_t) const { return true; };
776  };
777 
779  auto state_range(state_t b, state_t e) const
780  -> decltype(this->state_range(b, e, all_states_p{}))
781  {
782  return state_range(b, e, all_states_p{});
783  }
784 
785  public:
788  auto all_states() const
789  -> decltype(this->state_range(0U, states_.size()))
790  {
791  return state_range(0U, states_.size());
792  }
793 
796  template <typename Pred>
797  auto all_states(Pred pred) const
798  -> decltype(this->state_range(0U, states_.size(), pred))
799  {
800  return state_range(0U, states_.size(), pred);
801  }
802 
805  auto states() const
806  -> decltype(this->state_range(post() + 1, states_.size()))
807  {
808  return state_range(post() + 1, states_.size());
809  }
810 
811  template <typename Pred>
814 
815  // FIXME: clang workaround.
816  template <typename Pred>
817  struct has_state_p
818  {
819  bool operator()(transition_t t) const
820  {
821  return (aut_.src_of(t) != aut_.null_state()
822  && pred_(t));
823  };
825  Pred pred_;
826  };
827 
830  template <typename Pred>
832  all_transitions(Pred pred) const
833  {
834  return
835  {
836  boost::irange<transition_t>(0U, transitions_.size()),
837  has_state_p<Pred>{*this, pred}
838  };
839  }
840 
841  // FIXME: clang workaround.
843  {
844  bool operator()(transition_t) const { return true; };
845  };
846 
848  auto all_transitions() const
849  -> decltype(this->all_transitions(all_transitions_p{}))
850  {
851  return all_transitions(all_transitions_p{});
852  }
853 
854  // FIXME: clang workaround.
856  {
857  bool operator()(transition_t t) const
858  {
859  return aut_.src_of(t) != aut_.pre();
860  }
862  };
863 
864  // FIXME: clang workaround.
866  {
867  bool operator()(transition_t t) const
868  {
869  return aut_.dst_of(t) != aut_.post();
870  }
872  };
873 
874  // FIXME: clang workaround.
876  {
877  bool operator()(transition_t t) const
878  {
879  return (aut_.src_of(t) != aut_.pre()
880  && aut_.dst_of(t) != aut_.post());
881  }
883  };
884 
886  auto transitions() const
887  -> decltype(this->all_transitions(not_with_pre_post_p{*this}))
888  {
889  return all_transitions(not_with_pre_post_p{*this});
890  }
891 
894  container_range<const tr_cont_t&>
895  all_out(state_t s) const
896  {
897  assert(has_state(s));
898  return states_[s].succ;
899  }
900 
905  template <typename Pred>
907  all_out(state_t s, Pred pred) const
908  {
909  assert(has_state(s));
910  return {states_[s].succ, pred};
911  }
912 
915  auto out(state_t s) const
916  -> decltype(this->all_out(s, not_to_post_p{*this}))
917  {
918  return all_out(s, not_to_post_p{*this});
919  }
920 
921  // FIXME: clang workaround.
923  {
924  bool operator()(transition_t t) const
925  {
926  return aut_.labelset()->equal(aut_.label_of(t), label_);
927  }
929  // Capture by copy: in the case of the transpose_automaton, the
930  // labels are transposed, so they are temporaries.
932  };
933 
936  auto out(state_t s, label_t l) const
937  -> decltype(this->all_out(s, label_equal_p{*this, l}))
938  {
939  return all_out(s, label_equal_p{*this, l});
940  }
941 
944  container_range<const tr_cont_t&>
945  all_in(state_t s) const
946  {
947  assert(has_state(s));
948  return states_[s].pred;
949  }
950 
955  template <typename Pred>
957  all_in(state_t s, Pred pred) const
958  {
959  assert(has_state(s));
960  return {states_[s].pred, pred};
961  }
962 
965  auto in(state_t s) const
966  -> decltype(this->all_in(s, not_from_pre_p{*this}))
967  {
968  return all_in(s, not_from_pre_p{*this});
969  }
970 
973  auto in(state_t s, label_t l) const
974  -> decltype(this->all_in(s, label_equal_p{*this, l}))
975  {
976  return all_in(s, label_equal_p{*this, l});
977  }
978 
979  // FIXME: clang workaround.
980  struct dst_p
981  {
982  bool operator()(transition_t t) const
983  {
984  return aut_.dst_of(t) == dst;
985  }
988  };
989 
992  auto outin(state_t s, state_t d) const
993  -> decltype(this->all_out(s, dst_p{*this, d}))
994  {
995  return all_out(s, dst_p{*this, d});
996  }
997 
1002  auto initial_transitions() const
1003  -> decltype(this->all_out(pre()))
1004  {
1005  return all_out(pre());
1006  }
1007 
1012  auto final_transitions() const
1013  -> decltype(this->all_in(post()))
1014  {
1015  return all_in(post());
1016  }
1017  };
1018  }
1019 
1020  template <typename Context>
1021  mutable_automaton<Context>
1022  make_mutable_automaton(const Context& ctx)
1023  {
1024  return make_shared_ptr<mutable_automaton<Context>>(ctx);
1025  }
1026 }
unsigned transition_t
Lightweight transition handle (or index).
free_store_t states_fs_
Free indexes in states_.
transition_t set_weight(transition_t t, weight_t w)
auto in(state_t s) const -> decltype(this->all_in(s, not_from_pre_p
Indexes of visible transitions arriving to state s.
auto all_states(Pred pred) const -> decltype(this->state_range(0U, states_.size(), pred))
All states including pre()/post() that validate pred.
typename weightset_t::value_t weight_t
Transition weight.
auto out(state_t s) const -> decltype(this->all_out(s, not_to_post_p
Indexes of visible transitions leaving state s.
typename context_t::kind_t kind_t
transitions_output_t< has_state_p< Pred > > all_transitions(Pred pred) const
All the transition indexes between all states (including pre and post), that validate pred...
typename context_t::weightset_ptr weightset_ptr
labelset_t_of< context_t > labelset_t
state_t dst_of(transition_t t) const
static constexpr state_t null_state()
Invalid state.
auto final_transitions() const -> decltype(this->all_in(post()))
Indexes of transitions from visible final states.
transition_t get_transition(state_t src, state_t dst, label_t l) const
states_output_t< valid_state_p< Pred > > state_range(state_t b, state_t e, Pred pred) const
The range of state numbers in [b .
weightset_mixin< detail::b_impl > b
Definition: fwd.hh:48
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
Definition: traits.hh:51
unsigned state_t
Lightweight state handle (or index).
static constexpr transition_t null_transition()
Invalid transition.
container_filter_range< boost::integer_range< transition_t >, Pred > transitions_output_t
container_range< const tr_cont_t & > all_out(state_t s) const
Indexes of all transitions leaving state s.
auto outin(state_t s, state_t d) const -> decltype(this->all_out(s, dst_p
Indexes of visible transitions from state s to state d.
weight_t lmul_weight(transition_t t, weight_t w)
std::string format_transition(transition_t t) const
typename labelset_t::value_t label_t
Transition label.
mutable_automaton_impl(const context_t &ctx)
Aut transpose(const transpose_automaton< Aut > &aut)
Definition: transpose.hh:235
std::ostream & print_set(std::ostream &o, format fmt={}) const
std::vector< stored_transition_t > tr_store_t
All the automaton's transitions.
bool has_state(state_t s) const
Whether state s belongs to the automaton.
transition_tuple< state_t, label_t, weight_t > stored_transition_t
Data stored per transition.
static dyn::context ctx(const driver &d)
Get the context of the driver.
Definition: parse.cc:80
label_t label_of(transition_t t) const
mutable_automaton< Context > make_mutable_automaton(const Context &ctx)
std::vector< unsigned > free_store_t
A list of unused indexes in the states/transitions tables.
An input/output format.
Definition: format.hh:11
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
const weightset_ptr & weightset() const
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
transition_t set_transition(state_t src, state_t dst, label_t l)
Same as above, with unit weight.
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:47
typename context_t::labelset_ptr labelset_ptr
context_t ctx_
The algebraic type of this automaton.
auto out(state_t s, label_t l) const -> decltype(this->all_out(s, label_equal_p
Indexes of all transitions leaving state s on label l.
std::vector< transition_t > tr_cont_t
All the incoming/outgoing transition handles of a state.
transition_t add_transition(state_t src, state_t dst, label_t l, weight_t w)
Add a transition between two states.
transition_t add_transition(state_t src, state_t dst, label_t l)
Same as above, with weight one.
weight_t add_weight(transition_t t, weight_t w)
auto state_range(state_t b, state_t e) const -> decltype(this->state_range(b, e, all_states_p
The range of state numbers in [b .. e].
auto all_states() const -> decltype(this->state_range(0U, states_.size()))
All states including pre()/post().
auto all_transitions() const -> decltype(this->all_transitions(all_transitions_p
All the transition indexes between all states (including pre and post).
symbol sname()
Definition: name.hh:67
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
Definition: symbol.hh:23
Transition with label and non Boolean weight.
Definition: transition.hh:56
state_t src_of(transition_t t) const
auto initial_transitions() const -> decltype(this->all_out(pre()))
Indexes of transitions to visible initial states.
mutable_automaton< Ctx > fresh_automaton_t
The (shared pointer) type to use if we have to create an automaton of the same (underlying) type...
std::vector< stored_state_t > st_store_t
All the automaton's states.
auto states() const -> decltype(this->state_range(post()+1, states_.size()))
All states excluding pre()/post().
container_range< const tr_cont_t & > all_in(state_t s) const
Indexes of all transitions arriving to state s.
label_t prepost_label_
Label for initial and final transitions.
mutable_automaton_impl & operator=(mutable_automaton_impl &&that)
weightset_t_of< context_t > weightset_t
auto conv(const ValueSet &vs, const std::string &str, Args &&...args) -> decltype(vs.conv(std::declval< std::istream & >(), std::forward< Args >(args)...))
Parse str via vs.conv.
Definition: stream.hh:28
transition_t add_transition_copy(state_t src, state_t dst, const A &aut, typename A::element_type::transition_t t, bool transpose=false)
Add a transition between two states, copying the label from the given transition. ...
auto transitions() const -> decltype(this->all_transitions(not_with_pre_post_p
All the transition indexes between visible states.
mutable_automaton_impl(mutable_automaton_impl &&that)
container_filter_range< boost::integer_range< state_t >, Pred > states_output_t
container_filter_range< const tr_cont_t &, Pred > all_out(state_t s, Pred pred) const
Indexes of transitions leaving state s that validate the predicate.
weight_t weight_of(transition_t t) const
weight_t rmul_weight(transition_t t, weight_t w)
free_store_t transitions_fs_
Free indexes in transitions_.
transition_t new_transition(state_t src, state_t dst, label_t l, weight_t w)
Create a transition between two states.
auto in(state_t s, label_t l) const -> decltype(this->all_in(s, label_equal_p
Indexes of visible transitions arriving to state s on label l.
const labelset_ptr & labelset() const
container_filter_range< const tr_cont_t &, Pred > all_in(state_t s, Pred pred) const
Indexes of transitions entering state s that validate the predicate.
std::shared_ptr< detail::mutable_automaton_impl< Context >> mutable_automaton
Definition: fwd.hh:24
const context_t & context() const
transition_t set_transition(state_t src, state_t dst, label_t l, weight_t w)
Set a transition between two states.