17 #ifndef AWALI_PRODUCT_HH
18 # define AWALI_PRODUCT_HH
37 template <
typename... Auts>
46 template <
typename... Auts>
56 template<
typename WS,
typename W1,
typename W2>
58 ->
typename WS::value_t
63 template<
typename WS,
typename W1,
typename... W>
65 ->
typename WS::value_t
75 template <
typename Aut,
typename... Auts>
79 "requires free labels");
82 using automaton_t = Aut;
86 template <std::size_t... I>
98 using label_t =
typename labelset_t::value_t;
99 using weight_t =
typename weightset_t::value_t;
103 template <
typename A>
116 : transition_maps_{{auts, *aut->weightset()}...}
120 pmap_[pre_()] = aut_->pre();
121 pmap_[post_()] = aut_->post();
127 return pre_(indices);
130 template <
size_t... I>
135 return tuple_t{(std::get<I>(auts_)->pre())...};
141 return post_(indices);
144 template <
size_t... I>
149 return tuple_t{(std::get<I>(auts_)->post())...};
160 auto lb = pmap_.lower_bound(state);
161 if (lb == pmap_.end() || pmap_.key_comp()(state, lb->first))
163 lb = pmap_.emplace_hint(lb, state, aut_->add_state());
164 todo_.emplace_back(state);
172 initialize_product();
174 while (!todo_.empty())
180 add_product_transitions(src, psrc);
187 initialize_shuffle();
189 while (!todo_.empty())
195 add_shuffle_transitions(src, psrc);
205 initialize_shuffle();
207 while (!todo_.empty())
218 add_product_transitions(src, psrc);
219 add_shuffle_transitions(src, psrc);
224 auto history = std::make_shared<tuple_history<automata_t>>(auts_);
225 aut_->set_history(history);
226 for (
const auto& p: pmap_)
227 if(p.second != aut_->pre() && p.second != aut_->post())
228 history->add_state(p.second, p.first);
234 void initialize_product()
236 todo_.emplace_back(pre_());
241 void initialize_shuffle()
245 add_product_transitions(aut_->pre(), pre_());
249 std::tuple<typename transition_map_t<Auts>::map_t&...>
250 out_(
const tuple_t& ss)
252 return out_(ss, indices);
255 template <
size_t... I>
256 std::tuple<typename transition_map_t<Auts>::map_t&...>
257 out_(
const tuple_t& ss, seq<I...>)
259 return std::tie(std::get<I>(transition_maps_)[std::get<I>(ss)]...);
266 void add_product_transitions(
const state_t src,
275 ([&] (
const typename transition_map_t<Auts>::transition&... ts)
277 aut_->new_transition(src, state(std::make_tuple(ts.dst...)),
278 t.first,
variadic_mul(*(aut_->weightset()), ts.wgt...));
287 void add_shuffle_transitions(
const state_t src,
290 weight_t final = add_shuffle_transitions_(src, psrc, indices);
291 aut_->set_final(src,
final);
298 template <
size_t... I>
303 weight_t res = aut_->weightset()->one();
304 using swallow =
int[];
308 add_shuffle_transitions_<I>(src, psrc)),
321 add_shuffle_transitions_(
const state_t src,
325 weight_t res = aut_->weightset()->zero();
327 auto& ts = std::get<I>(transition_maps_)[std::get<I>(psrc)];
329 if (std::get<I>(auts_)->labelset()->is_special(t.first))
330 res = t.second.front().wgt;
332 for (
auto d: t.second) {
334 std::get<I>(pdst) = d.dst;
335 aut_->add_transition(src, state(pdst), t.first, d.wgt);
341 std::tuple<transition_map_t<Auts>...> transition_maps_;
343 using out_tuple_t = std::pair<size_t, state_t>;
344 using out_map_t = std::map<out_tuple_t, bool>;
352 using map = std::map<tuple_t, state_t>;
356 std::deque<tuple_t> todo_;
365 template <
typename... Auts>
378 template <
typename... Auts>
391 template <
typename Lhs,
typename Rhs>
394 product(
const Lhs& lhs,
const Rhs& rhs,
bool keep_history=
true)
401 if(lhs->get_name().empty() || rhs->get_name().empty()) {
402 res->set_name(
"product");
403 res->set_desc(
"Automaton obtained by a product");
406 res->set_name(
"prod-"+lhs->get_name()+
"-"+rhs->get_name());
407 res->set_desc(
"Product of "+lhs->get_name()+
" and "+rhs->get_name());
417 template <
typename... Auts>
430 template <
typename... Auts>
442 template <
typename Lhs,
typename Rhs>
445 shuffle(
const Lhs& lhs,
const Rhs& rhs,
bool keep_history=
true)
452 if(lhs->get_name().empty() || rhs->get_name().empty()) {
453 res->set_name(
"shuffle");
454 res->set_desc(
"Automaton obtained by a shuffle product");
457 res->set_name(
"shuffle-"+lhs->get_name()+
"-"+rhs->get_name());
458 res->set_desc(
"Shuffle of "+lhs->get_name()+
" and "+rhs->get_name());
468 template <
typename Lhs,
typename Rhs>
479 if(lhs->get_name().empty() || rhs->get_name().empty()) {
480 res->set_name(
"infiltration");
481 res->set_desc(
"Automaton obtained by an infiltration product");
484 res->set_name(
"infilt-"+lhs->get_name()+
"-"+rhs->get_name());
485 res->set_desc(
"Infiltration of "+lhs->get_name()+
" and "+rhs->get_name());
494 template <
typename Aut>
497 ->
typename Aut::element_type::automaton_nocv_t
502 auto s = res->add_state();
505 for (
auto l: res->context().labelset()->genset())
506 res->new_transition(s, s, l);
512 static bool iterative = getenv(
"AWALI_ITERATIVE");
514 for (
size_t i = 0; i <
n; ++i)
515 res =
product(res, aut,
false);
Build the (accessible part of the) product.
Definition: product.hh:77
tuple_t post_() const
The name of the post of the output automaton.
Definition: product.hh:139
labelset_t_of< context_t > labelset_t
Definition: product.hh:95
void set_history()
Definition: product.hh:223
void infiltration()
Compute the (accessible part of the) infiltration product.
Definition: product.hh:200
static constexpr indices_t indices
Definition: product.hh:91
std::tuple< Auts... > automata_t
The type of input automata.
Definition: product.hh:108
product_algo_impl(Aut aut, const Auts &... auts)
Definition: product.hh:115
typename weightset_t::value_t weight_t
Definition: product.hh:99
void product()
Compute the (accessible part of the) product.
Definition: product.hh:170
typename std::cst_tuple< state_t, std::tuple_size< std::tuple< Auts... > >::value >::type tuple_t
Definition: product.hh:85
weightset_t_of< context_t > weightset_t
Definition: product.hh:96
state_t state(tuple_t state)
The state in the product corresponding to a tuple of states of operands.
Definition: product.hh:158
typename labelset_t::value_t label_t
Definition: product.hh:98
base_t< typename std::tuple_element< I, automata_t >::type > input_automaton_t
The type of the Ith input automaton, unqualified.
Definition: product.hh:113
tuple_t pre_() const
The name of the pre of the output automaton.
Definition: product.hh:125
tuple_t post_(seq< I... >) const
Definition: product.hh:145
context_t_of< Aut > context_t
The context of the result.
Definition: product.hh:94
void shuffle()
Compute the (accessible part of the) shuffle product.
Definition: product.hh:185
tuple_t pre_(seq< I... >) const
Definition: product.hh:131
The semiring of Natural numbers.
Definition: n.hh:34
weightset_description weightset(const std::string &k)
any_t weight_t
Type for (transition) weights; it is an alias to any_t since the its precise type depends on the weig...
Definition: typedefs.hh:61
auto map(const std::tuple< Ts... > &ts, Fun f) -> decltype(map_tuple_(f, ts, make_index_sequence< sizeof...(Ts)>()))
Map a function on a tuple, return tuple of the results.
Definition: tuple.hh:134
static constexpr TOP< void > value
Definition: priority.hh:93
cross_sequences< Sequences... > cross_tuple(const std::tuple< Sequences... > &seqs)
Definition: cross.hh:264
typename std::remove_cv< typename std::remove_reference< T >::type >::type base_t
T without reference or const/volatile qualifiers.
Definition: traits.hh:30
auto variadic_mul(const WS &weightset, const W1 &w1, const W2 &w2) -> typename WS::value_t
Definition: product.hh:57
zipped_maps< Dereference, Maps... > zip_map_tuple(const std::tuple< Maps... > &maps)
Definition: zip_maps.hh:281
auto product(const Lhs &lhs, const Rhs &rhs, bool keep_history=true) -> decltype(join_automata(lhs, rhs))
Definition: product.hh:394
auto power(const Aut &aut, unsigned n) -> typename Aut::element_type::automaton_nocv_t
Definition: product.hh:496
auto join(const ratexpset< Ctx1 > &a, const ratexpset< Ctx2 > &b) -> ratexpset< join_t< Ctx1, Ctx2 >>
The union of two ratexpsets.
Definition: ratexpset.hh:445
auto k_shuffle_no_history(const Auts &... as) -> decltype(join_automata(as...))
Build the (accessible part of the) product.
Definition: product.hh:420
auto infiltration(const Lhs &lhs, const Rhs &rhs, bool keep_history=true) -> decltype(join_automata(lhs, rhs))
Build the (accessible part of the) infiltration.
Definition: product.hh:471
typename internal::context_t_of_impl< internal::base_t< ValueSet > >::type context_t_of
Helper to retrieve the type of the context of a value set.
Definition: traits.hh:66
auto k_product_with_history(const Auts &... as) -> decltype(join_automata(as...))
Build the (accessible part of the) product.
Definition: product.hh:381
auto meet(const ratexpset< Ctx1 > &a, const ratexpset< Ctx2 > &b) -> ratexpset< meet_t< Ctx1, Ctx2 >>
The meet of two ratexpsets.
Definition: ratexpset.hh:434
typename internal::labelset_t_of_impl< internal::base_t< ValueSet > >::type labelset_t_of
Helper to retrieve the type of the labelset of a value set.
Definition: traits.hh:76
auto meet_automata(Auts &&... auts) -> decltype(make_mutable_automaton(meet(auts->context()...)))
Meet between automata.
Definition: product.hh:48
auto k_shuffle_with_history(const Auts &... as) -> decltype(join_automata(as...))
Build the (accessible part of the) product.
Definition: product.hh:433
auto join_automata(Auts &&... auts) -> decltype(make_mutable_automaton(join(auts->context()...)))
Join between automata.
Definition: product.hh:39
mutable_automaton< Context > make_mutable_automaton(const Context &ctx)
Definition: mutable_automaton.hh:915
auto k_product_no_history(const Auts &... as) -> decltype(join_automata(as...))
Build the (accessible part of the) product.
Definition: product.hh:368
typename internal::weightset_t_of_impl< internal::base_t< ValueSet > >::type weightset_t_of
Helper to retrieve the type of the weightset of a value set.
Definition: traits.hh:86
Main namespace of Awali.
Definition: ato.hh:22
unsigned state_t
Definition: types.hh:21
constexpr bool all_()
Definition: tuple.hh:318
Cache the outgoing transitions of an automaton as efficient maps label -> vector<(weight,...
Definition: transition_map.hh:46