Vcsn  2.0
Be Rational
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
product.hh
Go to the documentation of this file.
1 #ifndef VCSN_ALGOS_PRODUCT_HH
2 # define VCSN_ALGOS_PRODUCT_HH
3 
4 # include <iostream>
5 # include <map>
6 # include <utility>
7 
8 # include <vcsn/algos/insplit.hh>
9 # include <vcsn/algos/strip.hh>
12 # include <vcsn/ctx/context.hh>
13 # include <vcsn/ctx/traits.hh>
14 # include <vcsn/dyn/automaton.hh> // dyn::make_automaton
15 # include <vcsn/dyn/ratexp.hh> // dyn::make_ratexp
16 # include <vcsn/misc/vector.hh> // cross_tuple
17 # include <vcsn/misc/zip-maps.hh>
18 
19 namespace vcsn
20 {
22  template <typename... Auts>
23  auto
24  join_automata(Auts&&... auts)
25  -> decltype(make_mutable_automaton(join(auts->context()...)))
26  {
27  return make_mutable_automaton(join(auts->context()...));
28  }
29 
31  template <typename... Auts>
32  auto
33  meet_automata(Auts&&... auts)
34  -> decltype(make_mutable_automaton(meet(auts->context()...)))
35  {
36  return make_mutable_automaton(meet(auts->context()...));
37  }
38 
39  namespace detail
40  {
41  /*---------------------------------.
42  | product_automaton_impl<Aut...>. |
43  `---------------------------------*/
44 
46  template <typename Aut, typename... Auts>
48  : public tuple_automaton_impl<Aut, Auts...>
49  {
50  static_assert(all_<labelset_t_of<Auts>::is_letterized()...>(),
51  "product: requires letterized labels");
52 
54  using automaton_t = Aut;
56 
57  public:
58  using typename super_t::state_name_t;
59  using typename super_t::state_t;
60  template <size_t... I>
61  using seq = typename super_t::template seq<I...>;
62 
63  using super_t::auts_;
64  using super_t::indices;
65  using super_t::pmap_;
66  using super_t::post_;
67  using super_t::pre_;
68  using super_t::todo_;
69 
70  using super_t::state;
71 
72  static std::string sname()
73  {
74  return "product_automaton" + super_t::sname_();
75  }
76 
77  std::string vname(bool full = true) const
78  {
79  return "product_automaton" + super_t::vname_(full);
80  }
81 
86 
87  using label_t = typename labelset_t::value_t;
88  using weight_t = typename weightset_t::value_t;
89 
90  public:
92  using automata_t = std::tuple<Auts...>;
93 
95  template <size_t I>
96  using input_automaton_t
98 
99  using super_t::aut_;
100 
101  product_automaton_impl(Aut aut, const Auts&... auts)
102  : super_t(aut, auts...)
103  , transition_maps_{{auts, *aut_->weightset()}...}
104  {}
105 
107  void product()
108  {
109  initialize_product();
110 
111  while (!todo_.empty())
112  {
113  state_name_t psrc = todo_.front();
114  todo_.pop_front();
115  state_t src = pmap_[psrc];
116 
117  add_product_transitions(src, psrc);
118  }
119  }
120 
122  void shuffle()
123  {
124  initialize_shuffle();
125 
126  while (!todo_.empty())
127  {
128  state_name_t psrc = todo_.front();
129  todo_.pop_front();
130  state_t src = pmap_[psrc];
131 
132  add_shuffle_transitions(src, psrc);
133  }
134  }
135 
137  void infiltration()
138  {
139  // Infiltrate is a mix of product and shuffle operations, and
140  // the initial states for shuffle are a superset of the
141  // initial states for product:
142  initialize_shuffle();
143 
144  while (!todo_.empty())
145  {
146  state_name_t psrc = todo_.front();
147  todo_.pop_front();
148  state_t src = pmap_[psrc];
149 
150  // Infiltrate is a mix of product and shuffle operations.
151  //
152  // Product transitions must be added before shuffle ones:
153  // this way "product" can use "new_transition" only, which
154  // is faster than "add_transition".
155  add_product_transitions(src, psrc);
156  add_shuffle_transitions(src, psrc);
157  }
158  }
159 
160  private:
163  void initialize_product()
164  {
165  todo_.emplace_back(pre_());
166  }
167 
170  void initialize_shuffle()
171  {
172  // Make the result automaton initial states: same as the
173  // (synchronized) product of pre: synchronized transitions on $.
174  add_product_transitions(aut_->pre(), pre_());
175  }
176 
179  template <typename A>
180  using transition_map_t = transition_map<A, weightset_t, false, true>;
181 
183  std::tuple<typename transition_map_t<Auts>::map_t&...>
184  out_(const state_name_t& ss)
185  {
186  return out_(ss, indices);
187  }
188 
189  template <size_t... I>
190  std::tuple<typename transition_map_t<Auts>::map_t&...>
192  {
193  return std::tie(std::get<I>(transition_maps_)[std::get<I>(ss)]...);
194  }
195 
201  const state_name_t& psrc)
202  {
203  for (auto t: zip_map_tuple(out_(psrc)))
204  // These are always new transitions: first because the
205  // source state is visited for the first time, and second
206  // because the couple (left destination, label) is unique,
207  // and so is (right destination, label).
208  if (!aut_->labelset()->is_one(t.first))
210  ([&] (const typename transition_map_t<Auts>::transition&... ts)
211  {
212  aut_->new_transition(src, state(ts.dst...),
213  t.first, aut_->weightset()->mul(ts.wgt...));
214  },
215  t.second);
216  add_one_transitions_(src, psrc, indices);
217  }
218 
221  template <std::size_t... I>
222  void
223  add_one_transitions_(const state_t src, const state_name_t& psrc,
224  seq<I...>)
225  {
226  using swallow = int[];
227  (void) swallow
228  {
229  (maybe_add_one_transitions_<I>(*(std::get<I>(auts_)->labelset()),
230  src, psrc), 0)...
231  };
232  }
233 
235  template <std::size_t I, typename L>
236  typename std::enable_if<!L::has_one(), void>::type
238  {}
239 
242  template <std::size_t I, typename L>
243  typename std::enable_if<L::has_one(), void>::type
244  maybe_add_one_transitions_(const L& ls, const state_t src,
245  const state_name_t& psrc)
246  {
247  if (!has_one_in(psrc, I + 1, indices)
248  && !has_only_one_out(psrc, I, indices))
249  {
250  // one is guaranteed to be first.
251  const auto& tmap = std::get<I>(transition_maps_)[std::get<I>(psrc)];
252  if (ls.is_one(tmap.begin()->first))
253  for (auto t : tmap.begin()->second)
254  {
255  auto pdst = psrc;
256  std::get<I>(pdst) = t.dst;
257  aut_->new_transition(src, state(pdst), ls.one(), t.wgt);
258  }
259  }
260  }
261 
264  template <std::size_t... I>
265  bool has_one_in(const state_name_t& psrc, std::size_t i,
266  seq<I...>) const
267  {
268  bool has_ones[] = { has_only_ones_in(std::get<I>(auts_),
269  std::get<I>(psrc))... };
270  for (; i < sizeof...(Auts); ++i)
271  if (has_ones[i])
272  return true;
273  return false;
274  }
275 
278  template <std::size_t... I>
279  bool has_only_one_out(const state_name_t& psrc, std::size_t i,
280  seq<I...>)
281  {
282  bool has_ones[] = { has_only_ones_out<I>(psrc)... };
283  for (size_t j = 0; j < i; ++j)
284  if (has_ones[j])
285  return true;
286  return false;
287  }
288 
291  template <typename Aut_>
292  typename std::enable_if<labelset_t_of<Aut_>::has_one(),
293  bool>::type
294  is_one(const Aut_& aut, transition_t_of<Aut_> tr) const
295  {
296  return aut->labelset()->is_one(aut->label_of(tr));
297  }
298 
301  template <typename Aut_>
302  constexpr typename std::enable_if<!labelset_t_of<Aut_>::has_one(),
303  bool>::type
304  is_one(const Aut_&, transition_t_of<Aut_>) const
305  {
306  return false;
307  }
308 
312  template <typename Aut_>
313  constexpr typename std::enable_if<!labelset_t_of<Aut_>::has_one(),
314  bool>::type
315  has_only_ones_in(const Aut_&,
316  state_t_of<Aut_>) const
317  {
318  return false;
319  }
320 
322  template <typename Aut_>
323  typename std::enable_if<labelset_t_of<Aut_>::has_one(),
324  bool>::type
325  has_only_ones_in(const Aut_& rhs, state_t_of<Aut_> rst) const
326  {
327  auto rin = rhs->all_in(rst);
328  auto rtr = rin.begin();
329  return rtr != rin.end() && is_one(rhs, *rtr) && !rhs->is_initial(rst);
330  }
331 
334  template <size_t I>
335  bool
337  {
338  const auto& tmap = std::get<I>(transition_maps_)[std::get<I>(psrc)];
339  auto s = tmap.size();
340  if (s == 0)
341  return true;
342  else if (2 <= s)
343  return false;
344  else
345  return std::get<I>(auts_)->labelset()->is_one(tmap.begin()->first);
346  }
347 
353  const state_name_t& psrc)
354  {
355  weight_t final = add_shuffle_transitions_(src, psrc, indices);
356  aut_->set_final(src, final);
357  }
358 
363  template <size_t... I>
365  const state_name_t& psrc,
366  seq<I...>)
367  {
368  weight_t res = aut_->weightset()->one();
369  using swallow = int[];
370  (void) swallow
371  {
372  (res = aut_->weightset()->mul(res,
373  add_shuffle_transitions_<I>(src, psrc)),
374  0)...
375  };
376  return res;
377  }
378 
384  template <size_t I>
385  weight_t
387  const state_name_t& psrc)
388  {
389  // Whether is a final state.
390  weight_t res = aut_->weightset()->zero();
391 
392  auto& ts = std::get<I>(transition_maps_)[std::get<I>(psrc)];
393  for (auto t: ts)
394  if (std::get<I>(auts_)->labelset()->is_special(t.first))
395  res = t.second.front().wgt;
396  else
397  // The src state is visited for the first time, so all
398  // these transitions are new. *Except* in the case where
399  // we have a loop on some tapes.
400  //
401  // If add_product_transitions was called before (in the
402  // case of infiltration), there may even exist such a
403  // transition in the first loop.
404  for (auto d: t.second)
405  if (std::get<I>(psrc) == d.dst)
406  aut_->add_transition(src, src, t.first, d.wgt);
407  else
408  {
409  auto pdst = psrc;
410  std::get<I>(pdst) = d.dst;
411  aut_->new_transition(src, state(pdst), t.first, d.wgt);
412  }
413  return res;
414  }
415 
417  std::tuple<transition_map_t<Auts>...> transition_maps_;
418  };
419  }
420 
422  template <typename Aut, typename... Auts>
423  using product_automaton
424  = std::shared_ptr<detail::product_automaton_impl<Aut, Auts...>>;
425 
426  template <typename Aut, typename... Auts>
427  inline
428  auto
429  make_product_automaton(Aut aut, const Auts&... auts)
430  -> product_automaton<Aut, Auts...>
431  {
432  using res_t = product_automaton<Aut, Auts...>;
433  return make_shared_ptr<res_t>(aut, auts...);
434  }
435 
436 
437  /*------------------------.
438  | product(automaton...). |
439  `------------------------*/
440 
442  template <typename... Auts>
443  inline
444  auto
445  product(const Auts&... as)
446  -> product_automaton<decltype(meet_automata(as...)),
447  Auts...>
448  {
449  auto res = make_product_automaton(meet_automata(as...),
450  as...);
451  res->product();
452  return res;
453  }
454 
455  namespace dyn
456  {
457  namespace detail
458  {
459 
460  template <std::size_t I, typename Aut>
461  typename std::enable_if<labelset_t_of<Aut>::has_one()
462  && I != 0, Aut>::type
463  do_insplit(Aut& aut)
464  {
465  return insplit(aut);
466  }
467 
468  template <std::size_t I, typename Aut>
469  typename std::enable_if<!labelset_t_of<Aut>::has_one()
470  || I == 0, Aut&>::type
471  do_insplit(Aut& aut)
472  {
473  return aut;
474  }
475 
476  template <typename... Auts, size_t... I>
477  automaton
478  product_(const std::vector<automaton>& as,
480  {
481  return make_automaton(vcsn::product(do_insplit<I, Auts>(as[I]->as<Auts>())...));
482  }
483 
485  template <typename Lhs, typename Rhs>
486  automaton
487  product(const automaton& lhs, const automaton& rhs)
488  {
489  const auto& l = lhs->as<Lhs>();
490  const auto& r = rhs->as<Rhs>();
491  return make_automaton(::vcsn::product(l, r));
492  }
493 
495  (const automaton&, const automaton&) -> automaton);
496 
498  template <typename... Auts>
499  automaton
500  product_vector(const std::vector<automaton>& as)
501  {
502  auto indices = vcsn::detail::make_index_sequence<sizeof...(Auts)>{};
503  return product_<Auts...>(as, indices);
504  }
505 
507  (const std::vector<automaton>&) -> automaton);
508  }
509  }
510 
511 
512  /*------------------------.
513  | shuffle(automaton...). |
514  `------------------------*/
515 
517  template <typename... Auts>
518  inline
519  auto
520  shuffle(const Auts&... as)
521  -> product_automaton<decltype(join_automata(as...)),
522  Auts...>
523  {
524  auto res = make_product_automaton(join_automata(as...), as...);
525  res->shuffle();
526  return res;
527  }
528 
529  namespace dyn
530  {
531  namespace detail
532  {
534  template <typename Lhs, typename Rhs>
535  automaton
536  shuffle(const automaton& lhs, const automaton& rhs)
537  {
538  const auto& l = lhs->as<Lhs>();
539  const auto& r = rhs->as<Rhs>();
540  return make_automaton(::vcsn::shuffle(l, r));
541  }
542 
543  REGISTER_DECLARE(shuffle,
544  (const automaton&, const automaton&) -> automaton);
545 
547  template <typename... Auts, size_t... I>
548  automaton
549  shuffle_(const std::vector<automaton>& as,
551  {
552  auto res = vcsn::shuffle(as[I]->as<Auts>()...);
553  return make_automaton(res);
554  }
555 
557  template <typename... Auts>
558  automaton
559  shuffle_vector(const std::vector<automaton>& as)
560  {
561  auto indices = vcsn::detail::make_index_sequence<sizeof...(Auts)>{};
562  return shuffle_<Auts...>(as, indices);
563  }
564 
566  (const std::vector<automaton>&) -> automaton);
567  }
568  }
569 
570 
571  /*--------------------------.
572  | shuffle(ratexp, ratexp). |
573  `--------------------------*/
574 
576  template <typename ValueSet>
577  inline
578  typename ValueSet::value_t
579  shuffle(const ValueSet& vs,
580  const typename ValueSet::value_t& lhs,
581  const typename ValueSet::value_t& rhs)
582  {
583  return vs.shuffle(lhs, rhs);
584  }
585 
586  namespace dyn
587  {
588  namespace detail
589  {
591  template <typename RatExpSetLhs, typename RatExpSetRhs>
592  ratexp
593  shuffle_ratexp(const ratexp& lhs, const ratexp& rhs)
594  {
595  const auto& l = lhs->as<RatExpSetLhs>();
596  const auto& r = rhs->as<RatExpSetRhs>();
597  auto rs = join(l.ratexpset(), r.ratexpset());
598  auto lr = rs.conv(l.ratexpset(), l.ratexp());
599  auto rr = rs.conv(r.ratexpset(), r.ratexp());
600  return make_ratexp(rs, ::vcsn::shuffle(rs, lr, rr));
601  }
602 
604  (const ratexp&, const ratexp&) -> ratexp);
605  }
606  }
607 
608 
609  /*-----------------------------.
610  | infiltration(automaton...). |
611  `-----------------------------*/
612 
614  template <typename... Auts>
615  inline
616  auto
617  infiltration(const Auts&... as)
618  -> product_automaton<decltype(join_automata(as...)),
619  Auts...>
620  {
621  auto res = make_product_automaton(join_automata(as...), as...);
622  res->infiltration();
623  return res;
624  }
625 
626  namespace dyn
627  {
628  namespace detail
629  {
630 
632  template <typename Lhs, typename Rhs>
633  automaton
634  infiltration(const automaton& lhs, const automaton& rhs)
635  {
636  const auto& l = lhs->as<Lhs>();
637  const auto& r = rhs->as<Rhs>();
638  return make_automaton(::vcsn::infiltration(l, r));
639  }
640 
642  (const automaton&, const automaton&) -> automaton);
643 
645  template <typename... Auts, size_t... I>
646  automaton
647  infiltration_(const std::vector<automaton>& as,
649  {
650  auto res = vcsn::infiltration(as[I]->as<Auts>()...);
651  return make_automaton(res);
652  }
653 
655  template <typename... Auts>
656  automaton
657  infiltration_vector(const std::vector<automaton>& as)
658  {
659  auto indices = vcsn::detail::make_index_sequence<sizeof...(Auts)>{};
660  return infiltration_<Auts...>(as, indices);
661  }
662 
664  (const std::vector<automaton>&) -> automaton);
665  }
666  }
667 
668  /*----------------------.
669  | power(automaton, n). |
670  `----------------------*/
671 
672  template <typename Aut>
673  auto
674  power(const Aut& aut, unsigned n)
675  -> typename Aut::element_type::automaton_nocv_t
676  {
677  using res_t = typename Aut::element_type::automaton_nocv_t;
678  auto res = make_shared_ptr<res_t>(aut->context());
679  {
680  // automatonset::one().
681  auto s = res->new_state();
682  res->set_initial(s);
683  res->set_final(s);
684  for (auto l: res->context().labelset()->genset())
685  res->new_transition(s, s, l);
686  }
687 
688  if (n)
689  {
690  // FIXME: for 1, we should return the accessible part only.
691  static bool iterative = getenv("VCSN_ITERATIVE");
692  if (iterative)
693  for (size_t i = 0; i < n; ++i)
694  res = strip(product(res, aut));
695  else
696  {
697  auto power = strip(aut);
698  while (true)
699  {
700  if (n % 2)
701  res = strip(product(res, power));
702  n /= 2;
703  if (!n)
704  break;
706  }
707  }
708  }
709 
710  return res;
711  }
712 
713 
714  namespace dyn
715  {
716  namespace detail
717  {
719  template <typename Aut, typename Unsigned>
720  automaton
721  power(const automaton& aut, unsigned n)
722  {
723  const auto& a = aut->as<Aut>();
724  return make_automaton(::vcsn::power(a, n));
725  }
726 
728  (const automaton&, unsigned) -> automaton);
729  }
730  }
731 
732 
733  /*------------------------------.
734  | conjunction(ratexp, ratexp). |
735  `------------------------------*/
736 
738  template <typename RatExpSet>
739  inline
740  typename RatExpSet::value_t
741  conjunction(const RatExpSet& rs,
742  const typename RatExpSet::value_t& lhs,
743  const typename RatExpSet::value_t& rhs)
744  {
745  return rs.conjunction(lhs, rhs);
746  }
747 
748  namespace dyn
749  {
750  namespace detail
751  {
753  template <typename RatExpSetLhs, typename RatExpSetRhs>
754  ratexp
755  conjunction_ratexp(const ratexp& lhs, const ratexp& rhs)
756  {
757  const auto& l = lhs->as<RatExpSetLhs>();
758  const auto& r = rhs->as<RatExpSetRhs>();
759  auto rs = join(l.ratexpset(), r.ratexpset());
760  auto lr = rs.conv(l.ratexpset(), l.ratexp());
761  auto rr = rs.conv(r.ratexpset(), r.ratexp());
762  return make_ratexp(rs, ::vcsn::conjunction(rs, lr, rr));
763  }
764 
766  (const ratexp&, const ratexp&) -> ratexp);
767  }
768  }
769 }
770 
771 #endif // !VCSN_ALGOS_PRODUCT_HH
Aut automaton_t
The type of the resulting automaton.
Definition: product.hh:54
ratexp make_ratexp(const RatExpSet &rs, const typename RatExpSet::value_t &ratexp)
Definition: ratexp.hh:85
std::enable_if< labelset_t_of< Aut_ >::has_one(), bool >::type is_one(const Aut_ &aut, transition_t_of< Aut_ > tr) const
Check if the transition is spontaneous (in the case of a labelset with one).
Definition: product.hh:294
automaton product_vector(const std::vector< automaton > &as)
Variadic bridge.
Definition: product.hh:500
mutable_automaton< Context > make_mutable_automaton(const Context &ctx)
std::shared_ptr< detail::automaton_base > automaton
Definition: automaton.hh:71
std::tuple< Auts...> automata_t
The type of input automata.
Definition: product.hh:92
state_t_of< automaton_t > state_t
Result state type.
auto power(const Aut &aut, unsigned n) -> typename Aut::element_type::automaton_nocv_t
Definition: product.hh:674
auto labelset(Args &&...args) const -> decltype(aut_-> labelset(std::forward< Args >(args)...))
auto product(const Auts &...as) -> product_automaton< decltype(meet_automata(as...)), Auts...>
Build the (accessible part of the) product.
Definition: product.hh:445
std::tuple< state_t_of< Auts >...> state_name_t
State names: Tuple of states of input automata.
product_automaton_impl(Aut aut, const Auts &...auts)
Definition: product.hh:101
automaton shuffle_vector(const std::vector< automaton > &as)
Variadic bridge.
Definition: product.hh:559
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:34
state_name_t post_() const
The name of the post of the output automaton.
state_t state(state_name_t state)
The state in the product corresponding to a pair of states of operands.
context_t_of< Aut > context_t
The context of the result.
Definition: product.hh:83
bool has_only_ones_out(const state_name_t &psrc)
Whether the Ith state of psrc in the Ith input automaton has no non-spontaneous outgoing transitions...
Definition: product.hh:336
RatExpSet::value_t conjunction(const RatExpSet &rs, const typename RatExpSet::value_t &lhs, const typename RatExpSet::value_t &rhs)
Intersection/Hadamard product of ratexps.
Definition: product.hh:741
std::enable_if<!labelset_t_of< Aut >::has_one()||I==0, Aut & >::type do_insplit(Aut &aut)
Definition: product.hh:471
static std::string sname()
Definition: product.hh:72
std::tuple< state_t_of< Auts >...> state_name_t
State names: Tuple of states of input automata.
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
Definition: automaton.hh:77
automaton shuffle_(const std::vector< automaton > &as, vcsn::detail::index_sequence< I...>)
Variadic bridge helper.
Definition: product.hh:549
void add_shuffle_transitions(const state_t src, const state_name_t &psrc)
Add transitions to the given result automaton, starting from the given result input state...
Definition: product.hh:352
std::shared_ptr< detail::ratexp_base > ratexp
Definition: fwd.hh:64
auto join_automata(Auts &&...auts) -> decltype(make_mutable_automaton(join(auts->context()...)))
Join between automata.
Definition: product.hh:24
std::shared_ptr< const node< Context >> ratexp
Definition: fwd.hh:156
state_t_of< automaton_t > state_t
Result state type.
weight_t add_shuffle_transitions_(const state_t src, const state_name_t &psrc, seq< I...>)
Let all automata advance one after the other, and add the corresponding transitions in the output...
Definition: product.hh:364
weight_t add_shuffle_transitions_(const state_t src, const state_name_t &psrc)
Let Ith automaton advance, and add the corresponding transitions in the output.
Definition: product.hh:386
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:32
automaton infiltration_vector(const std::vector< automaton > &as)
Variadic bridge.
Definition: product.hh:657
std::deque< state_name_t > todo_
Worklist of state tuples.
An automaton whose states are tuples of states of automata.
std::string vname(bool full=true) const
Definition: product.hh:77
labelset_t_of< context_t > labelset_t
Definition: product.hh:84
#define REGISTER_DECLARE(Name, Signature)
Definition: fwd.hh:104
static std::string sname_()
The sname of the sub automata.
std::enable_if< L::has_one(), void >::type maybe_add_one_transitions_(const L &ls, const state_t src, const state_name_t &psrc)
If the labelset has one, add the relevant spontaneous-transitions leaving the state.
Definition: product.hh:244
zipped_maps< Dereference, Maps...> zip_map_tuple(const std::tuple< Maps...> &maps)
Definition: zip-maps.hh:264
std::tuple< typename transition_map_t< Auts >::map_t &...> out_(const state_name_t &ss)
The outgoing tuple of transitions from state tuple ss.
Definition: product.hh:184
Build the (accessible part of the) product.
Definition: product.hh:47
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
Definition: traits.hh:38
ratexp shuffle_ratexp(const ratexp &lhs, const ratexp &rhs)
Bridge.
Definition: product.hh:593
state_name_t pre_() const
The name of the pre of the output automaton.
void cross_tuple(Fun f, const std::tuple< Ts...> &ts)
Definition: vector.hh:38
constexpr std::enable_if<!labelset_t_of< Aut_ >::has_one(), bool >::type is_one(const Aut_ &, transition_t_of< Aut_ >) const
Same as above, but for labelsets without one, so it's always false.
Definition: product.hh:304
auto meet(const ratexpset< Ctx1 > &a, const ratexpset< Ctx2 > &b) -> ratexpset< meet_t< Ctx1, Ctx2 >>
The meet of two ratexpsets.
Definition: ratexpset.hh:480
auto make_product_automaton(Aut aut, const Auts &...auts) -> product_automaton< Aut, Auts...>
Definition: product.hh:429
std::enable_if< labelset_t_of< Aut >::has_one(), Aut >::type insplit(Aut &aut)
Definition: insplit.hh:103
typename detail::transition_t_of_impl< base_t< ValueSet >>::type transition_t_of
Definition: traits.hh:36
auto shuffle(const Auts &...as) -> product_automaton< decltype(join_automata(as...)), Auts...>
The (accessible part of the) shuffle product.
Definition: product.hh:520
typename super_t::template seq< I...> seq
Definition: product.hh:61
std::tuple< typename transition_map_t< Auts >::map_t &...> out_(const state_name_t &ss, seq< I...>)
Definition: product.hh:191
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:36
constexpr std::enable_if<!labelset_t_of< Aut_ >::has_one(), bool >::type has_only_ones_in(const Aut_ &, state_t_of< Aut_ >) const
Check if the state has only incoming spontaneous transitions.
Definition: product.hh:315
bool has_only_one_out(const state_name_t &psrc, std::size_t i, seq< I...>)
Check if all the tapes before the Ith have only outgoing spontaneous transitions. ...
Definition: product.hh:279
static constexpr indices_t indices
ratexp conjunction_ratexp(const ratexp &lhs, const ratexp &rhs)
Bridge.
Definition: product.hh:755
variadic< type_t::shuffle, Context > shuffle
Definition: fwd.hh:135
weightset_t_of< context_t > weightset_t
Definition: product.hh:85
std::string vname_(bool full=true) const
The vname of the sub automata.
automaton infiltration_(const std::vector< automaton > &as, vcsn::detail::index_sequence< I...>)
Variadic bridge helper.
Definition: product.hh:647
auto join(const ValueSet &vs) -> ValueSet
The join of a single valueset.
Definition: join.hh:44
std::tuple< transition_map_t< Auts >...> transition_maps_
Transition caches.
Definition: product.hh:417
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:35
auto infiltration(const Auts &...as) -> product_automaton< decltype(join_automata(as...)), Auts...>
The (accessible part of the) infiltration product.
Definition: product.hh:617
typename weightset_t::value_t weight_t
Definition: product.hh:88
typename std::remove_cv< typename std::remove_reference< T >::type >::type base_t
T without reference or const/volatile qualifiers.
Definition: traits.hh:12
auto meet_automata(Auts &&...auts) -> decltype(make_mutable_automaton(meet(auts->context()...)))
Meet between automata.
Definition: product.hh:33
void add_product_transitions(const state_t src, const state_name_t &psrc)
Add transitions to the given result automaton, starting from the given result input state...
Definition: product.hh:200
automaton product_(const std::vector< automaton > &as, vcsn::detail::index_sequence< I...>)
Definition: product.hh:478
constexpr bool all_()
Definition: tuple.hh:298
void add_one_transitions_(const state_t src, const state_name_t &psrc, seq< I...>)
Add the spontaneous transitions leaving state src, if it is relevant (i.e.
Definition: product.hh:223
bool has_one_in(const state_name_t &psrc, std::size_t i, seq< I...>) const
Check if all the tapes after the Ith have only incoming spontaneous transitions.
Definition: product.hh:265
automata_t auts_
Input automata, supplied at construction time.
typename labelset_t::value_t label_t
Definition: product.hh:87
std::enable_if<!L::has_one(), void >::type maybe_add_one_transitions_(const L &, const state_t, const state_name_t &)
In the case where the labelset doesn't have one, do nothing.
Definition: product.hh:237
std::enable_if< labelset_t_of< Aut_ >::has_one(), bool >::type has_only_ones_in(const Aut_ &rhs, state_t_of< Aut_ > rst) const
Whether the state has only incoming spontaneous transitions.
Definition: product.hh:325
automaton_t aut_
The wrapped automaton, possibly const.
base_t< typename std::tuple_element< I, automata_t >::type > input_automaton_t
The type of the Ith input automaton, unqualified.
Definition: product.hh:97
std::shared_ptr< detail::product_automaton_impl< Aut, Auts...>> product_automaton
A product automaton as a shared pointer.
Definition: product.hh:424