23 template <
typename Lhs,
typename Rhs>
26 static_assert(Lhs::element_type::full_context_t::is_lat,
27 "compose: lhs labelset must be a tupleset");
28 static_assert(Rhs::element_type::full_context_t::is_lat,
29 "compose: rhs labelset must be a tupleset");
32 template <std::size_t... I>
47 "compose: common tape must be of same type");
71 using state_name_t =
typename automaton_t::element_type::state_name_t;
77 {rhs, *
res_->weightset()}}
85 while (!
res_->todo_.empty())
87 const auto& p =
res_->todo_.front();
89 res_->todo_.pop_front();
91 return std::move(
res_);
95 using label_t =
typename labelset_t::value_t;
96 using weight_t =
typename weightset_t::value_t;
100 template <
typename A>
111 template <std::size_t... I1, std::size_t... I2>
118 std::get<I2>(rl.sets())...};
125 join(*lhs->weightset(), *rhs->weightset())};
138 return std::tuple_cat(ll, rl);
141 template<
typename Aut>
143 typename Aut::element_type::res_label_t>
146 return aut->hidden_one();
149 template<
typename Aut>
151 typename Aut::element_type::res_label_t>
154 raise(
"should not get here");
164 auto& lhs = std::get<0>(
res_->auts_);
165 auto& rhs = std::get<1>(
res_->auts_);
171 bool has_eps_out =
false;
176 && lhs->labelset()->is_one(ltm.begin()->first))
179 for (
auto t: ltm.begin()->second)
180 res_->new_transition(src,
181 res_->state(t.dst, std::get<1>(psrc)),
182 join_label(lhs->hidden_label_of(t.transition),
190 const bool lhs_has_proper_trans =
192 && (!lhs->labelset()->is_one(ltm.begin()->first)
195 if ((!has_eps_out || lhs_has_proper_trans)
197 && rhs->labelset()->is_one(rtm.begin()->first))
198 for (
auto t: rtm.begin()->second)
199 res_->new_transition(src,
200 res_->state(std::get<0>(psrc), t.dst),
202 rhs->hidden_label_of(t.transition)),
208 if (!lhs->labelset()->is_one(t.first))
220 join_label(lhs->hidden_label_of(lts.transition),
221 rhs->hidden_label_of(rts.transition)),
227 template <
typename A>
231 return aut->labelset()->is_one(aut->label_of(tr));
234 template <
typename A>
246 template <
typename Aut>
258 template <
typename Aut>
262 auto rin = rhs->all_in(rst);
263 auto rtr = rin.begin();
264 return rtr != rin.end() &&
is_one(rhs, *rtr);
273 template <
typename Lhs,
typename Rhs>
287 template <
typename Lhs,
typename Rhs,
288 unsigned OutTape = 1,
unsigned InTape = 0>
294 auto l = focus<OutTape>(lhs);
295 auto r =
insplit(focus<InTape>(rhs));
305 template <
typename Lhs,
typename Rhs>
309 auto& l = lhs->as<Lhs>();
310 auto&
r = rhs->as<Rhs>();
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.
join_t< weightset_t_of< context_t_of< Lhs >>, weightset_t_of< context_t_of< Rhs >>> weightset_t
void add_compose_transitions(const state_t src, const state_name_t &psrc)
Add transitions to the given result automaton, starting from the given result input state...
composer(const Lhs &lhs, const Rhs &rhs)
static context_t make_context_(const Lhs &lhs, const Rhs &rhs)
Outgoing signature: weight, destination.
res_label_t join_label(const hidden_l_label_t &ll, const hidden_r_label_t &rl)
typename labelset_t::value_t res_label_t
std::string type(const automaton &a)
The implementation type of a.
constexpr vcsn::enable_if_t<!labelset_t_of< A >::has_one(), bool > is_one(const A &, transition_t_of< A >) const
auto join(const ValueSet &vs) -> ValueSet
The join of a single valueset.
static labelset_t make_labelset_(const hidden_l_labelset_t &ll, const hidden_r_labelset_t &rl)
vcsn::enable_if_t< labelset_t_of< Aut >::has_one(), typename Aut::element_type::res_label_t > get_hidden_one(const Aut &aut)
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
typename std::enable_if< Cond, T >::type enable_if_t
typename crhs_t::element_type::res_labelset_t hidden_r_labelset_t
auto make_composer(Lhs &lhs, Rhs &rhs) -> typename detail::composer< Lhs, Rhs >
void cross_tuple(Fun f, const std::tuple< Ts...> &ts)
typename clhs_t::element_type::res_labelset_t hidden_l_labelset_t
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.
typename weightset_t::value_t weight_t
SharedPtr make_shared_ptr(Args &&...args)
Same as std::make_shared, but parameterized by the shared_ptr type, not the (pointed to) element_type...
zipped_maps< Dereference, Maps...> zip_maps(Maps &&...maps)
std::tuple< transition_map_t< Lhs >, transition_map_t< Rhs > > transition_maps_
Transition caches.
vcsn::enable_if_t< labelset_t_of< A >::has_one(), bool > is_one(const A &aut, transition_t_of< A > tr) const
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
mutable_automaton< Context > make_mutable_automaton(const Context &ctx)
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().
std::shared_ptr< detail::tuple_automaton_impl< Auts...>> tuple_automaton
A tuple automaton as a shared pointer.
typename automaton_t::element_type::state_name_t state_name_t
Tuple of states of input automata.
std::shared_ptr< detail::automaton_base > automaton
Build the (accessible part of the) composition.
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
decltype(join(std::declval< ValueSets >()...)) join_t
The type of the join of the ValueSets.
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
labelset_t_of< clhs_t > middle_labelset_t
typename detail::transition_t_of_impl< base_t< ValueSet >>::type transition_t_of
typename concat_tupleset< hidden_l_labelset_t, hidden_r_labelset_t >::type labelset_t
The type of context of the result.
automaton_t res_
The computed product.
Cache the outgoing transitions of an automaton as efficient maps label -> vector<(weight, dst)>.
tuple_automaton< mutable_automaton< context_t >, Lhs, Rhs > automaton_t
The type of the resulting automaton.
std::shared_ptr< detail::focus_automaton_impl< Tape, Aut >> focus_automaton
A focus automaton as a shared pointer.
void initialize_compose()
Fill the worklist with the initial source-state pairs, as needed for the product algorithm.
typename hidden_r_labelset_t::value_t hidden_r_label_t
typename hidden_l_labelset_t::value_t hidden_l_label_t
state_t_of< automaton_t > state_t
Result state type.
static labelset_t make_labelset_(const hidden_l_labelset_t &ll, seq< I1...>, const hidden_r_labelset_t &rl, seq< I2...>)
vcsn::enable_if_t<!labelset_t_of< Aut >::has_one(), typename Aut::element_type::res_label_t > get_hidden_one(const Aut &)
auto compose(Lhs &lhs, Rhs &rhs) -> typename detail::composer< focus_automaton< OutTape, Lhs >, focus_automaton< InTape, Rhs >>::automaton_t
Build the (accessible part of the) composition.