20 #define DEFINE(Type) \
21 template <Automaton Aut> \
22 struct Type ## _of_impl \
24 using type = typename Aut::element_type::Type; \
27 template <Automaton Aut> \
28 struct Type ## _of_impl<insplit_automaton<Aut>> \
29 : Type ## _of_impl<Aut> \
32 template <Automaton Aut> \
34 = typename Type ## _of_impl<Aut>::type
43 template <Automaton Lhs, Automaton Rhs>
74 template <
bool Lazy, Automaton Lhs, Automaton Rhs>
79 typename composed_type<Lhs, Rhs>::out_t,
83 "compose: lhs labelset must be a tupleset");
85 "compose: rhs labelset must be a tupleset");
89 "compose: common tape must be of same type");
92 template <std::size_t... I>
134 static symbol res(std::string{
"compose_automaton<"}
135 + (Lazy ?
"true" :
"false") +
", "
143 o <<
"compose_automaton<";
158 while (!
aut_->todo_.empty())
160 const auto& p =
aut_->todo_.front();
162 aut_->todo_.pop_front();
179 template <Automaton A>
186 template <Automaton A>
189 return aut->aut_out();
194 template <Automaton A>
207 template <std::size_t... I1, std::size_t... I2>
214 std::get<I2>(rl.sets())...};
222 join(*lhs->weightset(), *rhs->weightset())};
235 return std::tuple_cat(ll, rl);
238 template <Automaton Aut>
239 std::enable_if_t<labelset_t_of<Aut>::has_one(),
243 return aut->hidden_one();
246 template <Automaton Aut>
247 std::enable_if_t<labelset_t_of<Aut>::has_one(),
254 template <Automaton Aut>
256 std::enable_if_t<!labelset_t_of<Aut>::has_one(),
260 raise(
"should not get here");
271 const auto& lhs = std::get<0>(
aut_->auts_);
272 const auto& rhs = std::get<1>(
aut_->auts_);
278 add_one_transitions_<0>(src, psrc);
279 add_one_transitions_<1>(src, psrc);
284 using polynomialset_t
286 using polynomial_t =
typename polynomialset_t::value_t;
287 const auto ps = polynomialset_t(
aut_->context());
288 auto poly_maps = std::map<state_t, polynomial_t>();
290 for (
const auto& t:
zip_maps(ltm, rtm))
293 if (!lhs->labelset()->is_one(t.first))
302 ps.add_here(poly_maps[this->
state(lts.
dst, rts.
dst)],
303 join_label(lhs->hidden_label_of(lts.transition),
304 real_aut(rhs)->hidden_label_of(rts.transition)),
311 for (
const auto& elt: poly_maps)
312 for (
const auto& m: elt.second)
317 template <std::
size_t I>
329 if (!tmap.empty() && ls.is_one(tmap.begin()->first))
330 for (
const auto& t: tmap.begin()->second)
336 return std::make_tuple(dst, std::get<1>(psrc));
339 return std::make_tuple(std::get<0>(psrc), dst);
344 ([
this, t=t.transition](
const auto& lhs,
const auto& rhs)
349 [
this, t=t.transition](
const auto& lhs,
const auto& rhs)
354 (std::get<0>(
aut_->auts_), std::get<1>(
aut_->auts_));
360 template <Automaton Aut>
361 std::enable_if_t<labelset_t_of<Aut>::has_one(),
bool>
364 return aut->labelset()->is_one(aut->label_of(tr));
367 template <Automaton Aut>
369 std::enable_if_t<!labelset_t_of<Aut>::has_one(),
bool>
377 template <std::size_t... I>
380 return all(is_proper_in<I>(psrc)...);
400 -> std::enable_if_t<labelset_t_of<input_automaton_t<I>>::has_one(),
406 const auto& aut = std::get<I>(
aut_->auts_);
407 auto s = std::get<I>(sn);
408 auto rin =
all_in(aut, s);
409 auto rtr = rin.begin();
412 return rtr == rin.end() || !
is_one(aut, *rtr);
417 template <std::size_t... I>
420 return all(has_proper_out<I>(psrc)...);
433 auto s = tmap.size();
439 return !std::get<I>(
aut_->auts_)->
labelset()->is_one(tmap.begin()->first);
445 template <
bool Lazy, Automaton Lhs, Automaton Rhs>
447 = std::shared_ptr<detail::compose_automaton_impl<Lazy, Lhs, Rhs>>;
449 template <
bool Lazy, std::size_t OutTape, std::size_t InTape,
454 auto l = focus<OutTape>(lhs);
455 auto r =
insplit(focus<InTape>(rhs), Lazy);
459 return make_shared_ptr<res_t>(l,
r);
468 std::size_t OutTape = 1, std::size_t InTape = 0>
472 auto res = make_compose_automaton<false, OutTape, InTape>(lhs, rhs);
478 template <
typename Lhs,
typename Rhs,
479 std::size_t OutTape = 1, std::size_t InTape = 0>
483 auto res = make_compose_automaton<true, OutTape, InTape>(lhs, rhs);
493 template <Automaton Lhs, Automaton Rhs,
typename Bool>
497 auto& l = lhs->
as<Lhs>();
498 auto&
r = rhs->
as<Rhs>();
mutable_automaton< context_t > out_t
std::shared_ptr< detail::compose_automaton_impl< Lazy, Lhs, Rhs >> compose_automaton
A compose automaton as a shared pointer.
void initialize_compose()
Fill the worklist with the initial source-state pairs, as needed for the composition algorithm...
static labelset_t make_labelset_(const hidden_l_labelset_t &ll, seq< I1... >, const hidden_r_labelset_t &rl, seq< I2... >)
auto labelset(Args &&...args) const -> decltype(aut_-> labelset(std::forward< Args >(args)...))
typename labelset_t::value_t label_t
std::tuple< Lhs, Rhs > automata_t
The type of input automata.
std::string type(const automaton &a)
The implementation type of a.
void add_transitions(const state_t src, const state_name_t &psrc)
Callback for complete_ when lazy.
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
typename hidden_l_labelset_t::value_t hidden_l_label_t
typename labelset_t::value_t res_label_t
std::enable_if_t< labelset_t_of< Aut >::has_one(), bool > is_one(const Aut &aut, transition_t_of< Aut > tr) const
Build the (accessible part of the) composition.
std::tuple< transition_map_t< Auts >... > transition_maps_
Transition caches.
ATTRIBUTE_NORETURN std::enable_if_t<!labelset_t_of< Aut >::has_one(), res_label_t_of< Aut > > get_hidden_one(const Aut &) const
typename type_helper_t::labelset_t labelset_t
The type of context of the result.
std::shared_ptr< detail::mutable_automaton_impl< Context >> mutable_automaton
std::enable_if_t< labelset_t_of< Aut >::has_one(), res_label_t_of< Aut > > get_hidden_one(const Aut &aut) const
auto all_in(Args &&...args) const -> decltype(aut_-> all_in(std::forward< Args >(args)...))
base_t< tuple_element_t< I, automata_t >> input_automaton_t
The type of the Ith input automaton, unqualified.
typename detail::transition_t_of_impl< base_t< ValueSet >>::type transition_t_of
static auto real_aut(const A &aut)
Get the focus automaton, possibly from a non insplit automaton.
res_label_t join_label(const hidden_l_label_t &ll, const hidden_r_label_t &rl) const
typename type_helper_t::weightset_t weightset_t
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
auto is_proper_in(const state_name_t &sn) const -> std::enable_if_t< labelset_t_of< input_automaton_t< I >>::has_one(), bool >
Whether the state has only proper incoming transitions.
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
typename tuple_automaton_impl::state_name_t state_name_t
typename res_label_t_of_impl< Aut >::type res_label_t_of
auto join(const ValueSet &vs) -> ValueSet
The join of a single valueset.
auto compose_lazy(const Lhs &lhs, const Rhs &rhs)
Build the (accessible part of the) laze composition.
typename res_labelset_t_of_impl< Aut >::type res_labelset_t_of
Outgoing signature: weight, destination.
Build the (accessible part of the) composition.
typename full_context_t_of_impl< Aut >::type full_context_t_of
decltype(join(std::declval< ValueSets >()...)) join_t
The type of the join of the ValueSets.
bool has_proper_out(const state_name_t &psrc)
Whether the Ith state of psrc in the Ith input automaton has proper outgoing transitions (but possibl...
static labelset_t make_labelset_(const hidden_l_labelset_t &ll, const hidden_r_labelset_t &rl)
std::ostream & print_set(std::ostream &o, format fmt={}) const
typename type_helper_t::context_t context_t
typename hidden_r_labelset_t::value_t hidden_r_label_t
auto make_compose_automaton(const Lhs &lhs, const Rhs &rhs)
bool are_proper_in(const state_name_t &psrc, seq< I... >) const
Whether no tapes in the sequence have spontaneous incoming transitions.
typename tuple_automaton_impl::state_t state_t
transition_map< A, weightset_t, false, true, true > transition_map_t
The type of our transition maps: convert the weight to weightset_t, non deterministic, and including transitions to post().
typename type_helper_t::res_label_t res_label_t
bool have_proper_out(const state_name_t &psrc, seq< I... >)
Whether all the tapes in the sequence have proper outgoing transitions (but possibly spontaneous too)...
typename type_helper_t::hidden_l_labelset_t hidden_l_labelset_t
auto insplit(Aut aut, bool lazy=false) -> std::enable_if_t< labelset_t_of< Aut >::has_one(), decltype(make_insplit_automaton(aut))>
Insplit an automaton with possible spontaneous transitions.
An input/output format for valuesets.
typename concat_tupleset< hidden_l_labelset_t, hidden_r_labelset_t >::type labelset_t
The type of context of the result.
static auto real_aut(const insplit_automaton< A > &aut)
Get the focus automaton from an insplit automaton.
typename weightset_t::value_t weight_t
std::shared_ptr< detail::focus_automaton_impl< Tape, Aut >> focus_automaton
A focus automaton as a shared pointer.
static context_t make_context_(const Lhs &lhs, const Rhs &rhs)
std::remove_cv_t< std::remove_reference_t< T >> base_t
T without reference or const/volatile qualifiers.
bool all(Bool &&...values)
Whether all the values evaluate as true.
constexpr std::enable_if_t<!labelset_t_of< Aut >::has_one(), bool > is_one(const Aut &, transition_t_of< Aut >) const
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...
Cache the outgoing transitions of an automaton as efficient maps label -> vector<(weight, dst)>.
res_labelset_t_of< clhs_t > hidden_l_labelset_t
typename super_t::state_name_t state_name_t
Tuple of states of input automata.
::vcsn::context< labelset_t, weightset_t > context_t
state_t state(Args &&...args)
Conversion from state name to state number.
typename super_t::state_t state_t
Result state type.
void cross_tuple(Fun f, const std::tuple< Ts... > &ts)
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
automaton_t aut_
The wrapped automaton, possibly const.
auto & as()
Extract wrapped typed automaton.
typename type_helper_t::hidden_r_labelset_t hidden_r_labelset_t
Decorator implementing the laziness for an algorithm.
zipped_maps< Dereference, Maps... > zip_maps(Maps &&...maps)
typename type_helper_t::hidden_l_label_t hidden_l_label_t
Provide a variadic mul on top of a binary mul(), and one().
std::shared_ptr< insplit_automaton_impl< Aut >> insplit_automaton
An insplit automaton as a shared pointer.
compose_automaton_impl(const Lhs &lhs, const Rhs &rhs)
constexpr auto is_proper_in(const state_name_t &) const -> std::enable_if_t<!labelset_t_of< input_automaton_t< I >>::has_one(), bool >
Whether the state has only proper incoming transitions.
join_t< weightset_t_of< context_t_of< Lhs >>, weightset_t_of< context_t_of< Rhs >>> weightset_t
std::enable_if_t< labelset_t_of< Aut >::has_one(), res_label_t_of< Aut > > get_hidden_one(const insplit_automaton< Aut > &aut) const
void add_one_transitions_(const state_t src, const state_name_t &psrc)
typename type_helper_t::out_t out_t
automaton compose(const automaton &lhs, const automaton &rhs, bool lazy)
Bridge.
void compose()
The (accessible part of the) composition of lhs_ and rhs_.
res_labelset_t_of< crhs_t > hidden_r_labelset_t
mutable_automaton< Context > make_mutable_automaton(const Context &ctx)
auto new_transition(Args &&...args) -> decltype(aut_-> new_transition(std::forward< Args >(args)...))
typename type_helper_t::hidden_r_label_t hidden_r_label_t
weightset_mixin< detail::r_impl > r
auto weightset(Args &&...args) const -> decltype(aut_-> weightset(std::forward< Args >(args)...))