28     template <
typename Aut, 
typename... Auts>
 
   33                     "product: requires letterized labels");
 
   43         = 
typename tuple_automaton_t::element_type::state_name_t;
 
   45         = 
typename tuple_automaton_t::element_type::state_t;
 
   46       template <
size_t... I>
 
   48         = 
typename tuple_automaton_t::element_type::template 
seq<I...>;
 
   52         static symbol res(
"product_automaton" 
   53                           + tuple_automaton_t::element_type::sname_());
 
   59         o << 
"product_automaton";
 
   60         return aut_->print_set_(o, fmt);
 
   68       using label_t = 
typename labelset_t::value_t;
 
   69       using weight_t = 
typename weightset_t::value_t;
 
   91         -> decltype(
aut_->origins())
 
   93         return aut_->origins();
 
  104       void complete_(
state_t s)
 const 
  106         const auto& orig = origins();
 
  115         -> decltype(
aut_->all_out(s))
 
  119         return aut_->all_out(s);
 
  123       template <
typename Pred>
 
  125         -> decltype(
aut_->all_out(s, pred))
 
  129         return aut_->all_out(s, pred);
 
  160         return all_out(s, not_to_post_p{*
this});
 
  168         return all_out(s, label_equal_p{*
this, l});
 
  177           while (!
aut_->todo_.empty())
 
  179               const auto& p = 
aut_->todo_.front();
 
  181               aut_->todo_.pop_front();
 
  190         while (!
aut_->todo_.empty())
 
  192             const auto& p = 
aut_->todo_.front();
 
  193             add_shuffle_transitions<false>(std::get<1>(p), std::get<0>(p));
 
  194             aut_->todo_.pop_front();
 
  219                 "infiltration: variadic product does not work");
 
  226         while (!
aut_->todo_.empty())
 
  228             const auto& p = 
aut_->todo_.front();
 
  235             add_shuffle_transitions<true>(std::get<1>(p), std::get<0>(p));
 
  237             aut_->todo_.pop_front();
 
  259       template <
typename... Args>
 
  262         return aut_->state(std::forward<Args>(args)...);
 
  267       template <
typename A>
 
  271       std::tuple<typename transition_map_t<Auts>::map_t&...>
 
  277       template <
size_t... I>
 
  278       std::tuple<typename transition_map_t<Auts>::map_t&...>
 
  296           if (!
aut_->labelset()->is_one(t.first))
 
  311       template <std::size_t... I>
 
  316         using swallow = 
int[];
 
  319           (maybe_add_one_transitions_<I>(*(std::get<I>(
aut_->auts_)->
labelset()),
 
  325       template <std::
size_t I, 
typename L>
 
  332       template <std::
size_t I, 
typename L>
 
  342             if (ls.is_one(tmap.begin()->first))
 
  343               for (
auto t : tmap.begin()->second)
 
  346                   std::get<I>(pdst) = t.dst;
 
  347                   this->new_transition(src, 
state(pdst), ls.one(), t.weight());
 
  354       template <std::size_t... I>
 
  359                                              std::get<I>(psrc))... };
 
  360         for (; i < 
sizeof...(Auts); ++i)
 
  368       template <std::size_t... I>
 
  372         bool has_ones[] = { has_only_ones_out<I>(psrc)... };
 
  373         for (
size_t j = 0; j < i; ++j)
 
  381       template <
typename Aut_>
 
  385         return aut->labelset()->is_one(aut->label_of(tr));
 
  390       template <
typename Aut_>
 
  400       template <
typename Aut_>
 
  412       template <
typename Aut_>
 
  416         auto rin = rhs->all_in(rst);
 
  417         auto rtr = rin.begin();
 
  418         return rtr != rin.end() && 
is_one(rhs, *rtr);
 
  428         auto s = tmap.size();
 
  434           return std::get<I>(
aut_->auts_)->
labelset()->is_one(tmap.begin()->first);
 
  441       template <
bool Infiltration = false>
 
  446           = add_shuffle_transitions_<Infiltration>(src, psrc, 
aut_->indices);
 
  447         aut_->set_final(src, 
final);
 
  454       template <
bool Infiltration, 
size_t... I>
 
  460         using swallow = 
int[];
 
  464                          add_shuffle_transitions_<Infiltration, I>(src, psrc)),
 
  480       template <
bool Infiltration, 
size_t I>
 
  490           if (std::get<I>(
aut_->auts_)->labelset()->is_special(t.first))
 
  491             res = t.second.front().weight();
 
  503             for (
auto d: t.second)
 
  506                 std::get<I>(pdst) = d.dst;
 
  508                     || std::get<I>(psrc) == d.dst)
 
  530   template <
typename Aut, 
typename... Auts>
 
  534   template <
typename Aut, 
typename... Auts>
 
  541     return make_shared_ptr<res_t>(aut, auts...);
 
  550   template <
typename... Auts>
 
  564   template <
typename... Auts>
 
  573     res->conjunction(
true);
 
  581       template <std::
size_t I, 
typename Aut>
 
  588       template <std::
size_t I, 
typename Aut>
 
  596       template <
typename Auts, 
size_t... I>
 
  613       template <
typename Auts, 
typename Bool>
 
  620         return conjunction_<Auts>(as, lazy, indices);
 
  631   template <
typename... Auts>
 
  648       template <
typename Auts, 
size_t... I>
 
  658       template <
typename Auts>
 
  664         return shuffle_<Auts>(as, indices);
 
  675   template <
typename ValueSet>
 
  677   typename ValueSet::value_t
 
  679           const typename ValueSet::value_t& lhs,
 
  680           const typename ValueSet::value_t& rhs)
 
  682     return vs.shuffle(lhs, rhs);
 
  690       template <
typename ExpSetLhs, 
typename ExpSetRhs>
 
  694         const auto& l = lhs->as<ExpSetLhs>();
 
  695         const auto& 
r = rhs->as<ExpSetRhs>();
 
  696         auto rs = 
join(l.expressionset(), r.expressionset());
 
  697         auto lr = rs.conv(l.expressionset(), l.expression());
 
  698         auto rr = rs.conv(r.expressionset(), r.expression());
 
  710   template <
typename A1, 
typename A2>
 
  723   template <
typename A1, 
typename A2, 
typename A3, 
typename... Auts>
 
  726   infiltration(
const A1& a1, 
const A2& a2, 
const A3& a3, 
const Auts&... as)
 
  737       template <
typename Auts, 
size_t... I>
 
  748       template <
typename Auts>
 
  754         return infiltration_<Auts>(as, indices);
 
  764   template <
typename ValueSet>
 
  766   typename ValueSet::value_t
 
  768                const typename ValueSet::value_t& lhs,
 
  769                const typename ValueSet::value_t& rhs)
 
  771     return vs.infiltration(lhs, rhs);
 
  779       template <
typename ExpSetLhs, 
typename ExpSetRhs>
 
  783         const auto& l = lhs->as<ExpSetLhs>();
 
  784         const auto& 
r = rhs->as<ExpSetRhs>();
 
  785         auto rs = 
join(l.expressionset(), r.expressionset());
 
  786         auto lr = rs.conv(l.expressionset(), l.expression());
 
  787         auto rr = rs.conv(r.expressionset(), r.expression());
 
  798   template <
typename Aut>
 
  806       auto s = res->new_state();
 
  809       for (
auto l: res->context().labelset()->genset())
 
  810         res->new_transition(s, s, l);
 
  816         static bool iterative = getenv(
"VCSN_ITERATIVE");
 
  818           for (
size_t i = 0; i < n; ++i)
 
  822             auto power = 
strip(aut);
 
  844       template <
typename Aut, 
typename Un
signed>
 
  848         const auto& a = aut->as<Aut>();
 
  860   template <
typename ExpSet>
 
  862   typename ExpSet::value_t
 
  864               const typename ExpSet::value_t& lhs,
 
  865               const typename ExpSet::value_t& rhs)
 
  867     return rs.conjunction(lhs, rhs);
 
  875       template <
typename ExpSetLhs, 
typename ExpSetRhs>
 
  879         const auto& l = lhs->as<ExpSetLhs>();
 
  880         const auto& 
r = rhs->as<ExpSetRhs>();
 
  881         auto rs = 
join(l.expressionset(), r.expressionset());
 
  882         auto lr = rs.conv(l.expressionset(), l.expression());
 
  883         auto rr = rs.conv(r.expressionset(), r.expression());
 
void shuffle()
Compute the (accessible part of the) shuffle product. 
auto state_is_strict(Args &&...args) const -> decltype(aut_-> state_is_strict(std::forward< Args >(args)...))
auto new_transition(Args &&...args) -> decltype(aut_-> new_transition(std::forward< Args >(args)...))
remove_cv_t< remove_reference_t< T >> base_t
T without reference or const/volatile qualifiers. 
product_automaton_impl self_t
std::tuple< transition_map_t< Auts >...> transition_maps_
Transition caches. 
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
std::shared_ptr< detail::product_automaton_impl< Aut, Auts...>> product_automaton
A product automaton as a shared pointer. 
bool operator()(transition_t_of< self_t > t) const 
automaton conjunction_(const std::vector< automaton > &as, bool lazy, vcsn::detail::index_sequence< I...>)
Bridge helper. 
auto all_out(Args &&...args) const -> decltype(aut_-> all_out(std::forward< Args >(args)...))
Outgoing signature: weight, destination. 
context_t_of< Aut > context_t
The context of the result. 
state_t state(Args &&...args)
Conversion from state name to state number. 
const weightset_t & ws_
The resulting weightset. 
Aut automaton_t
The type of the resulting automaton. 
auto out(state_t s, label_t_of< self_t > l) -> decltype(this->all_out(s, label_equal_p
Indexes of all transitions leaving state s on label l. 
static constexpr auto post(Args &&...args) -> decltype(element_type::post(std::forward< Args >(args)...))
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. ...
AutOut make_fresh_automaton(const AutIn &model)
Create an empty, mutable, automaton, based on another one. 
automaton infiltration_(const std::vector< automaton > &as, vcsn::detail::index_sequence< I...>)
Variadic bridge helper. 
vcsn::enable_if_t< labelset_t_of< Aut_ >::has_one(), bool > is_spontaneous_in(const Aut_ &rhs, state_t_of< Aut_ > rst) const 
Whether the state has only incoming spontaneous transitions. 
auto join(const ValueSet &vs) -> ValueSet
The join of a single valueset. 
void initialize_conjunction()
Fill the worklist with the initial source-state pairs, as needed for the conjunction algorithm...
auto label_of(Args &&...args) const -> decltype(aut_-> label_of(std::forward< Args >(args)...))
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
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...
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
auto conjunction_lazy(const Auts &...as) -> product_automaton< decltype(meet_automata(as...)), Auts...>
Build the (accessible part of the) conjunction. 
auto labelset(Args &&...args) const -> decltype(aut_-> labelset(std::forward< Args >(args)...))
automaton shuffle_(const std::vector< automaton > &as, vcsn::detail::index_sequence< I...>)
Variadic bridge helper. 
typename std::enable_if< Cond, T >::type enable_if_t
auto make_product_automaton(Aut aut, const Auts &...auts) -> product_automaton< Aut, Auts...>
std::tuple< Auts...> automata_t
The type of input automata. 
void infiltration()
Compute the (accessible part of the) infiltration product. 
auto meet_automata(Auts &&...auts) -> decltype(make_mutable_automaton(meet(auts->context()...)))
An automaton whose type is the meet between those of auts. 
Aggregate an automaton, and forward calls to it. 
std::tuple< typename transition_map_t< Auts >::map_t &...> out_(const state_name_t &ss, seq< I...>)
auto all_out(state_t s) const -> decltype(aut_->all_out(s))
void conjunction(bool lazy=false)
Compute the (accessible part of the) conjunction. 
void cross_tuple(Fun f, const std::tuple< Ts...> &ts)
auto infiltration(const A1 &a1, const A2 &a2) -> tuple_automaton< decltype(join_automata(a1, a2)), A1, A2 >
The (accessible part of the) infiltration product. 
ValueSet::value_t tuple(const ValueSet &vs, const typename ValueSets::value_t &...v)
typename tuple_automaton_t::element_type::state_t state_t
typename tuple_automaton_t::element_type::state_name_t state_name_t
void add_conjunction_transitions(const state_t src, const state_name_t &psrc)
Add transitions to the result automaton, starting from the given result input state, which must correspond to the given pair of input state automata. 
automaton make_automaton(const Aut &aut)
Build a dyn::automaton. 
std::shared_ptr< const node< Context >> expression
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...
expression infiltration_expression(const expression &lhs, const expression &rhs)
Bridge (infiltration). 
auto shuffle(const Auts &...as) -> tuple_automaton< decltype(join_automata(as...)), Auts...>
The (accessible part of the) shuffle product. 
std::tuple< typename transition_map_t< Auts >::map_t &...> out_(const state_name_t &ss)
The outgoing tuple of transitions from state tuple ss. 
tuple_automaton< automaton_t, Auts...> tuple_automaton_t
auto out(state_t s) -> decltype(this->all_out(s, not_to_post_p
Indexes of visible transitions leaving state s. 
bool operator()(transition_t_of< self_t > t) const 
vcsn::enable_if_t< labelset_t_of< Aut >::has_one(), Aut > insplit(Aut &aut)
Provide a variadic mul on top of a binary mul(), and one(). 
automaton conjunction_repeated(const automaton &aut, unsigned n)
Bridge (conjunction). 
std::shared_ptr< detail::tuple_automaton_impl< Auts...>> tuple_automaton
A tuple automaton as a shared pointer. 
std::shared_ptr< detail::automaton_base > automaton
auto conjunction(const Auts &...as) -> tuple_automaton< decltype(meet_automata(as...)), Auts...>
Build the (accessible part of the) conjunction. 
typename tuple_automaton_t::element_type::template seq< I...> seq
vcsn::enable_if_t< labelset_t_of< Aut_ >::has_one(), bool > 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). 
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
typename std::tuple_element< I, T >::type tuple_element_t
C++14. 
void require(bool b, Args &&...args)
If b is not verified, raise an error with args as message. 
auto add_transition(Args &&...args) -> decltype(aut_-> add_transition(std::forward< Args >(args)...))
std::ostream & print_set(std::ostream &o, format fmt={}) const 
vcsn::enable_if_t<!L::has_one(), void > 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. 
typename detail::transition_t_of_impl< base_t< ValueSet >>::type transition_t_of
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. 
auto make_tuple_automaton(const Auts &...auts) -> tuple_automaton< Auts...>
expression conjunction_expression(const expression &lhs, const expression &rhs)
Bridge (conjunction). 
Build the (accessible part of the) product. 
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string. 
vcsn::enable_if_t<!labelset_t_of< Aut >::has_one()||I==0, Aut & > do_insplit(Aut &aut)
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. 
expression make_expression(const ExpSet &rs, const typename ExpSet::value_t &r)
typename weightset_t::value_t weight_t
auto join_automata(Auts &&...auts) -> decltype(make_mutable_automaton(join(auts->context()...)))
An automaton whose type is the join between those of auts. 
Cache the outgoing transitions of an automaton as efficient maps label -> vector<(weight, dst)>. 
vcsn::enable_if_t< L::has_one(), void > 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. 
ATTRIBUTE_PURE bool has(const std::deque< T, Allocator > &s, const T &e)
Whether e is member of s. 
weightset_t_of< context_t > weightset_t
base_t< tuple_element_t< I, automata_t >> input_automaton_t
The type of the Ith input automaton, unqualified. 
std::shared_ptr< detail::expression_base > expression
constexpr vcsn::enable_if_t<!labelset_t_of< Aut_ >::has_one(), bool > is_one(const Aut_ &, transition_t_of< Aut_ >) const 
Same as above, but for labelsets without one, so it's always false. 
expression shuffle_expression(const expression &lhs, const expression &rhs)
Bridge (shuffle). 
auto dst_of(Args &&...args) const -> decltype(aut_-> dst_of(std::forward< Args >(args)...))
void initialize_shuffle()
Fill the worklist with the initial source-state pairs, as needed for the shuffle algorithm. 
constexpr vcsn::enable_if_t<!labelset_t_of< Aut_ >::has_one(), bool > is_spontaneous_in(const Aut_ &, state_t_of< Aut_ >) const 
Check if the state has only incoming spontaneous transitions. 
zipped_maps< Dereference, Maps...> zip_map_tuple(const std::tuple< Maps...> &maps)
label_t_of< self_t > label_
automaton_t aut_
The wrapped automaton, possibly const. 
typename labelset_t::value_t label_t
product_automaton_impl(Aut aut, const Auts &...auts)
Build a product automaton. 
std::set< state_t > done_
When performing the lazy construction, list of states that have been completed (i.e., their outgoing transitions have been computed). 
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. 
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...
auto all_out(state_t s, Pred pred) const -> decltype(aut_->all_out(s, pred))
All the outgoing transitions satisfying the predicate. 
labelset_t_of< context_t > labelset_t