1 #ifndef VCSN_ALGOS_COMPOSE_HH
2 # define VCSN_ALGOS_COMPOSE_HH
29 template <
typename Lhs,
typename Rhs>
32 static_assert(Lhs::element_type::full_context_t::is_lat,
33 "compose: lhs labelset must be a tupleset");
34 static_assert(Rhs::element_type::full_context_t::is_lat,
35 "compose: rhs labelset must be a tupleset");
38 template <std::size_t... I>
53 "compose: common tape must be of same type");
77 using state_name_t =
typename automaton_t::element_type::state_name_t;
83 {rhs, *
res_->weightset()}}
89 return make_labelset_(ll, make_index_sequence<hidden_l_labelset_t::size()>{},
90 rl, make_index_sequence<hidden_r_labelset_t::size()>{});
93 template <std::size_t... I1, std::size_t... I2>
100 std::get<I2>(rl.sets())...};
107 join(*lhs->weightset(), *rhs->weightset())};
115 while (!
res_->todo_.empty())
118 res_->todo_.pop_front();
123 return std::move(
res_);
132 template <
typename A>
139 res_->todo_.emplace_back(
res_->pre_());
144 return std::tuple_cat(ll, rl);
147 template<
typename Aut>
148 typename std::enable_if<labelset_t_of<Aut>::has_one(),
149 typename Aut::element_type::res_label_t>::type
152 return aut->hidden_one();
155 template<
typename Aut>
156 typename std::enable_if<!labelset_t_of<Aut>::has_one(),
157 typename Aut::element_type::res_label_t>::type
160 raise(
"should not get here");
170 auto& lhs = std::get<0>(
res_->auts_);
171 auto& rhs = std::get<1>(
res_->auts_);
177 bool has_eps_out =
false;
183 && lhs->labelset()->is_one(ltm.begin()->first))
186 for (
auto t: ltm.begin()->second)
187 res_->new_transition(src,
188 res_->state(t.dst, std::get<1>(psrc)),
189 join_label(lhs->hidden_label_of(t.transition),
198 const bool lhs_has_non_sp_trans =
199 !lhs->labelset()->is_one(ltm.begin()->first)
202 if (!has_eps_out || lhs_has_non_sp_trans)
205 && rhs->labelset()->is_one(rtm.begin()->first))
207 for (
auto t: rtm.begin()->second)
208 res_->new_transition(src,
209 res_->state(std::get<0>(psrc), t.dst),
211 rhs->hidden_label_of(t.transition)),
219 if (!lhs->labelset()->is_one(t.first))
231 join_label(lhs->hidden_label_of(lts.transition),
232 rhs->hidden_label_of(rts.transition)),
238 template <
typename A>
239 typename std::enable_if<labelset_t_of<A>::has_one(),
243 return aut->labelset()->is_one(aut->label_of(tr));
246 template <
typename A>
248 typename std::enable_if<!labelset_t_of<A>::has_one(),
256 template <
typename Aut>
258 typename std::enable_if<!labelset_t_of<Aut>::has_one(),
265 template <
typename Aut>
266 typename std::enable_if<labelset_t_of<Aut>::has_one(),
270 auto rin = rhs->all_in(rst);
271 auto rtr = rin.begin();
272 return rtr != rin.end() &&
is_one(rhs, *rtr) && !rhs->is_initial(rst);
287 template <
typename Lhs,
typename Rhs>
293 auto l = blind<1>(lhs);
305 template <
typename Lhs,
typename Rhs>
309 auto& l = lhs->as<Lhs>();
310 auto&
r = rhs->as<Rhs>();
322 #endif // !VCSN_ALGOS_COMPOSE_HH
std::size_t static I2 labelset_t make_labelset_(const hidden_l_labelset_t &ll, seq< I1...>, const hidden_r_labelset_t &rl, seq< I2...>)
mutable_automaton< Context > make_mutable_automaton(const Context &ctx)
std::shared_ptr< detail::automaton_base > automaton
Build the (accessible part of the) composition.
typename labelset_t::value_t res_label_t
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
std::enable_if< labelset_t_of< Aut >::has_one(), typename Aut::element_type::res_label_t >::type get_hidden_one(const Aut &aut)
automaton_t res_
The computed product.
weight_t wgt
The (converted) weight.
tuple_automaton< mutable_automaton< context_t >, Lhs, Rhs > automaton_t
The type of the resulting automaton.
res_label_t join_label(hidden_l_label_t ll, hidden_r_label_t rl)
state_t_of< automaton_t > state_t
Result state type.
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
std::shared_ptr< detail::blind_automaton_impl< Tape, Aut >> blind_automaton
A blind automaton as a shared pointer.
typename labelset_t::value_t label_t
typename crhs_t::element_type::res_labelset_t hidden_r_labelset_t
std::enable_if< labelset_t_of< A >::has_one(), bool >::type is_one(const A &aut, transition_t_of< A > tr) const
typename automaton_t::element_type::state_name_t state_name_t
Tuple of states of input automata.
typename hidden_r_labelset_t::value_t hidden_r_label_t
typename hidden_l_labelset_t::value_t hidden_l_label_t
std::enable_if< labelset_t_of< Aut >::has_one(), bool >::type has_only_ones_in(const Aut &rhs, state_t_of< Aut > rst) const
#define REGISTER_DECLARE(Name, Signature)
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)
typename concat_tupleset< hidden_l_labelset_t, hidden_r_labelset_t >::type labelset_t
The type of context of the result.
static context_t make_context_(const Lhs &lhs, const Rhs &rhs)
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
Outgoing signature: weight, destination.
void cross_tuple(Fun f, const std::tuple< Ts...> &ts)
std::tuple< transition_map_t< Lhs >, transition_map_t< Rhs > > transition_maps_
Transition caches.
std::enable_if< labelset_t_of< Aut >::has_one(), Aut >::type insplit(Aut &aut)
constexpr std::enable_if<!labelset_t_of< A >::has_one(), bool >::type is_one(const A &, transition_t_of< A >) const
typename detail::transition_t_of_impl< base_t< ValueSet >>::type transition_t_of
auto compose(Lhs &lhs, Rhs &rhs) -> typename detail::composer< blind_automaton< 1, Lhs >, blind_automaton< 0, Rhs >>::automaton_t
Build the (accessible part of the) composition.
typename weightset_t::value_t weight_t
automaton_t compose()
The (accessible part of the) product of lhs_ and rhs_.
Provide a variadic mul on top of a binary mul(), and one().
labelset_t_of< clhs_t > middle_labelset_t
typename clhs_t::element_type::res_labelset_t hidden_l_labelset_t
constexpr std::enable_if<!labelset_t_of< Aut >::has_one(), bool >::type has_only_ones_in(const Aut &, state_t_of< Aut >) const
zipped_maps< Dereference, Maps...> zip_maps(Maps &&...maps)
void initialize_compose()
Fill the worklist with the initial source-state pairs, as needed for the product algorithm.
join_t< weightset_t_of< context_t_of< Lhs >>, weightset_t_of< context_t_of< Rhs >>> weightset_t
auto join(const ValueSet &vs) -> ValueSet
The join of a single valueset.
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
SharedPtr make_shared_ptr(Args &&...args)
Same as std::make_shared, but parameterized by the shared_ptr type, not the (pointed to) element_type...
std::shared_ptr< detail::tuple_automaton_impl< Auts...>> tuple_automaton
A product automaton as a shared pointer.
std::enable_if<!labelset_t_of< Aut >::has_one(), typename Aut::element_type::res_label_t >::type get_hidden_one(const Aut &)
Cache the outgoing transitions of an automaton as efficient maps label -> vector<(weight, dst)>.