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>
78 template <
bool Lazy, Automaton Lhs, Automaton Rhs>
83 typename composed_type<Lhs, Rhs>::out_t,
87 "compose: lhs labelset must be a tupleset");
89 "compose: rhs labelset must be a tupleset");
93 "compose: common tape must be of same type");
96 template <std::size_t... I>
128 static symbol res(std::string{
"compose_automaton<"}
129 + (Lazy ?
"true" :
"false") +
", "
137 o <<
"compose_automaton<";
152 while (!
aut_->todo_.empty())
154 const auto& p =
aut_->todo_.front();
156 aut_->todo_.pop_front();
171 template <Automaton A>
177 template <Automaton A>
180 return aut->aut_out();
185 template <Automaton A>
196 template <std::size_t... I1, std::size_t... I2>
203 std::get<I2>(rl.sets())...};
211 join(*lhs->weightset(), *rhs->weightset())};
224 return std::tuple_cat(ll, rl);
227 template <Automaton Aut>
228 std::enable_if_t<labelset_t_of<Aut>::has_one(),
232 return aut->hidden_one();
235 template <Automaton Aut>
236 std::enable_if_t<labelset_t_of<Aut>::has_one(),
243 template <Automaton Aut>
245 std::enable_if_t<!labelset_t_of<Aut>::has_one(),
249 raise(
"should not get here");
260 const auto& lhs = std::get<0>(
aut_->auts_);
261 const auto& rhs = std::get<1>(
aut_->auts_);
267 bool has_eps_out =
false;
272 && lhs->labelset()->is_one(ltm.begin()->first))
276 for (
auto t: ltm.begin()->second)
278 this->
state(t.dst, std::get<1>(psrc)),
279 join_label(lhs->hidden_label_of(t.transition),
287 const bool lhs_has_proper_trans =
289 && (!lhs->labelset()->is_one(ltm.begin()->first)
292 if ((!has_eps_out || lhs_has_proper_trans)
294 && rhs->labelset()->is_one(rtm.begin()->first))
295 for (
auto t: rtm.begin()->second)
297 this->
state(std::get<0>(psrc), t.dst),
299 real_aut(rhs)->hidden_label_of(t.transition)),
307 using polynomial_t =
typename polynomialset_t::value_t;
308 const auto ps = polynomialset_t(
aut_->context());
309 auto poly_maps = std::map<state_t, polynomial_t>();
314 if (!lhs->labelset()->is_one(t.first))
323 ps.add_here(poly_maps[this->
state(lts.
dst, rts.
dst)],
324 join_label(lhs->hidden_label_of(lts.transition),
325 real_aut(rhs)->hidden_label_of(rts.transition)),
332 for (
auto elt: poly_maps)
333 for (
auto m: elt.second)
337 template <Automaton Aut>
338 std::enable_if_t<labelset_t_of<Aut>::has_one(),
bool>
341 return aut->labelset()->is_one(aut->label_of(tr));
344 template <Automaton Aut>
346 std::enable_if_t<!labelset_t_of<Aut>::has_one(),
bool>
355 template <Automaton Aut>
357 std::enable_if_t<!labelset_t_of<Aut>::has_one(),
bool>
367 template <Automaton Aut>
368 std::enable_if_t<labelset_t_of<Aut>::has_one(),
bool>
371 auto rin =
all_in(rhs, rst);
372 auto rtr = rin.begin();
373 return rtr != rin.end() &&
is_one(rhs, *rtr);
379 template <
bool Lazy, Automaton Lhs, Automaton Rhs>
381 = std::shared_ptr<detail::compose_automaton_impl<Lazy, Lhs, Rhs>>;
383 template <
bool Lazy, std::size_t OutTape, std::size_t InTape,
388 auto l = focus<OutTape>(lhs);
393 return make_shared_ptr<res_t>(l,
r);
402 std::size_t OutTape = 1, std::size_t InTape = 0>
406 auto res = make_compose_automaton<false, OutTape, InTape>(lhs, rhs);
412 template <
typename Lhs,
typename Rhs,
413 std::size_t OutTape = 1, std::size_t InTape = 0>
417 auto res = make_compose_automaton<true, OutTape, InTape>(lhs, rhs);
427 template <Automaton Lhs, Automaton Rhs,
typename Bool>
431 auto& l = lhs->as<Lhs>();
432 auto&
r = rhs->as<Rhs>();
auto weightset(Args &&...args) const -> decltype(aut_-> weightset(std::forward< Args >(args)...))
std::shared_ptr< detail::focus_automaton_impl< Tape, Aut >> focus_automaton
A focus automaton as a shared pointer.
auto join(const ValueSet &vs) -> ValueSet
The join of a single valueset.
compose_automaton_impl(const Lhs &lhs, const Rhs &rhs)
tuple_automaton< mutable_automaton< context_t >, Lhs, Rhs > automaton_t
The type of the resulting automaton.
std::shared_ptr< detail::insplit_automaton_impl< Aut, labelset_t_of< Aut >::has_one()>> insplit_automaton
A compose automaton as a shared pointer.
typename type_helper_t::hidden_r_label_t hidden_r_label_t
typename full_context_t_of_impl< Aut >::type full_context_t_of
Decorator implementing the laziness for an algorithm.
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
decltype(join(std::declval< ValueSets >()...)) join_t
The type of the join of the ValueSets.
auto compose(Lhs &lhs, Rhs &rhs)
Build the (accessible part of the) composition.
typename res_label_t_of_impl< Aut >::type res_label_t_of
typename super_t::state_name_t state_name_t
Tuple of states of input automata.
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
typename type_helper_t::context_t context_t
auto all_in(Args &&...args) const -> decltype(aut_-> all_in(std::forward< Args >(args)...))
std::shared_ptr< detail::mutable_automaton_impl< Context >> mutable_automaton
void initialize_compose()
Fill the worklist with the initial source-state pairs, as needed for the composition algorithm...
std::enable_if_t< labelset_t_of< Aut >::has_one(), bool > is_one(const Aut &aut, transition_t_of< Aut > tr) 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...
typename type_helper_t::hidden_l_labelset_t hidden_l_labelset_t
state_t state(Args &&...args)
Conversion from state name to state number.
auto make_compose_automaton(const Lhs &lhs, const Rhs &rhs)
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().
static auto real_aut(const insplit_automaton< A > &aut)
constexpr std::enable_if_t<!labelset_t_of< Aut >::has_one(), bool > is_one(const Aut &, transition_t_of< Aut >) const
std::enable_if_t< labelset_t_of< Aut >::has_one(), res_label_t_of< Aut > > get_hidden_one(const Aut &aut) const
res_labelset_t_of< clhs_t > hidden_l_labelset_t
typename labelset_t::value_t res_label_t
void add_transitions(const state_t src, const state_name_t &psrc)
automaton_t aut_
The wrapped automaton, possibly const.
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
typename hidden_l_labelset_t::value_t hidden_l_label_t
std::string type(const automaton &a)
The implementation type of a.
weightset_mixin< detail::r_impl > r
::vcsn::context< labelset_t, weightset_t > context_t
An input/output format for valuesets.
typename weightset_t::value_t weight_t
typename type_helper_t::hidden_l_label_t hidden_l_label_t
Provide a variadic mul on top of a binary mul(), and one().
Cache the outgoing transitions of an automaton as efficient maps label -> vector<(weight, dst)>.
typename labelset_t::value_t label_t
auto compose_lazy(Lhs &lhs, Rhs &rhs)
Build the (accessible part of the) laze composition.
auto insplit_lazy(const Aut &aut) -> decltype(make_insplit_automaton(aut))
std::enable_if_t< L, void > complete_(state_t s) const
Complete a state: find its outgoing transitions.
res_label_t join_label(const hidden_l_label_t &ll, const hidden_r_label_t &rl) const
static auto real_aut(const A &aut)
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
std::enable_if_t< labelset_t_of< Aut >::has_one(), res_label_t_of< Aut > > get_hidden_one(const insplit_automaton< Aut > &aut) const
constexpr std::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
std::shared_ptr< detail::tuple_automaton_impl< Auts... >> tuple_automaton
A tuple automaton as a shared pointer.
void cross_tuple(Fun f, const std::tuple< Ts... > &ts)
ATTRIBUTE_NORETURN std::enable_if_t<!labelset_t_of< Aut >::has_one(), res_label_t_of< Aut > > get_hidden_one(const Aut &) const
mutable_automaton< context_t > out_t
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
std::tuple< transition_map_t< Auts >... > transition_maps_
Transition caches.
std::shared_ptr< detail::automaton_base > automaton
typename detail::transition_t_of_impl< base_t< ValueSet >>::type transition_t_of
auto new_transition(Args &&...args) -> decltype(aut_-> new_transition(std::forward< Args >(args)...))
Build the (accessible part of the) composition.
void compose()
The (accessible part of the) composition of lhs_ and rhs_.
static labelset_t make_labelset_(const hidden_l_labelset_t &ll, const hidden_r_labelset_t &rl)
typename tuple_automaton_t::element_type::state_t state_t
typename concat_tupleset< hidden_l_labelset_t, hidden_r_labelset_t >::type labelset_t
The type of context of the result.
typename tuple_automaton_t::element_type::state_name_t state_name_t
typename super_t::state_t state_t
Result state type.
typename type_helper_t::res_label_t res_label_t
static context_t make_context_(const Lhs &lhs, const Rhs &rhs)
mutable_automaton< Context > make_mutable_automaton(const Context &ctx)
typename type_helper_t::hidden_r_labelset_t hidden_r_labelset_t
std::shared_ptr< detail::compose_automaton_impl< Lazy, Lhs, Rhs >> compose_automaton
A compose automaton as a shared pointer.
std::ostream & print_set(std::ostream &o, format fmt={}) const
typename res_labelset_t_of_impl< Aut >::type res_labelset_t_of
typename hidden_r_labelset_t::value_t hidden_r_label_t
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
typename type_helper_t::labelset_t labelset_t
The type of context of the result.
zipped_maps< Dereference, Maps... > zip_maps(Maps &&...maps)
typename type_helper_t::out_t out_t
res_labelset_t_of< crhs_t > hidden_r_labelset_t
std::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.
Build the (accessible part of the) composition.
static labelset_t make_labelset_(const hidden_l_labelset_t &ll, seq< I1... >, const hidden_r_labelset_t &rl, seq< I2... >)
Outgoing signature: weight, destination.
typename type_helper_t::weightset_t weightset_t