3 #include <unordered_map> 32 template <Automaton Aut1, Automaton Aut2>
37 "multiply_here: requires free labelset");
46 template <Automaton Aut1, Automaton Aut2>
50 const auto& ls = *res->labelset();
51 const auto& ws = *res->weightset();
52 const auto& bws = *b->weightset();
66 const auto& map =
copy.state_map();
69 for (
auto t1: final_ts)
71 auto s1 = res->src_of(t1);
72 auto w1 = res->weight_of(t1);
73 res->del_transition(t1);
74 for (
auto t2: init_ts)
75 res->new_transition(s1,
76 map.at(b->dst_of(t2)),
79 ws.conv(bws, b->weight_of(t2))));
87 template <Automaton Aut1, Automaton Aut2>
91 const auto& ls = *res->labelset();
92 const auto& bls = *b->labelset();
93 const auto& ws = *res->weightset();
94 const auto& bws = *b->weightset();
109 return !b->is_initial(s) || !
in(b, s).empty();
114 const auto& map =
copy.state_map();
118 for (
auto t1: final_ts)
130 auto s1 = res->src_of(t1);
131 auto w1 = res->weight_of(t1);
132 res->del_transition(t1);
133 for (
auto t2: init_ts)
135 auto w2 = b->weight_of(t2);
136 for (
auto t3:
all_out(b, b->dst_of(t2)))
137 res->set_transition(s1,
138 map.at(b->dst_of(t3)),
139 ls.conv(bls, b->label_of(t3)),
142 ws.conv(bws, b->weight_of(t3))));
149 template <Automaton Aut1, Automaton Aut2,
typename Tag = general_tag>
151 multiply(
const Aut1& lhs,
const Aut2& rhs, Tag tag = {})
152 -> decltype(lhs->null_state(),
167 template <Automaton Lhs, Automaton Rhs,
typename String>
170 const std::string& algo)
172 const auto& l = lhs->
as<Lhs>();
173 const auto&
r = rhs->
as<Rhs>();
175 (algo ==
"auto" ?
"standard" : algo,
205 template <Automaton Aut,
typename Tag = general_tag>
208 -> decltype(aut->null_state(),
214 res =
star(aut, tag);
223 auto s = res->new_state();
232 for (
int n = 1; n < exp.
min; ++n)
240 auto s = sum->new_state();
244 for (
int n = 1; n <= exp.
max - exp.
min; ++n)
257 template <Automaton Aut,
typename Int1,
typename Int2,
typename String>
260 const std::string& algo)
262 const auto& aut = a->
as<Aut>();
264 [aut, min, max](
auto tag)
279 template <
typename ValueSet>
280 typename ValueSet::value_t
282 const typename ValueSet::value_t& lhs,
283 const typename ValueSet::value_t& rhs)
285 return vs.mul(lhs, rhs);
293 template <
typename ExpSetLhs,
typename ExpSetRhs>
297 auto join_elts = join<ExpSetLhs, ExpSetRhs>(lhs, rhs);
298 return {std::get<0>(join_elts),
300 std::get<1>(join_elts),
301 std::get<2>(join_elts))};
311 template <
typename ExpSetLhs,
typename ExpSetRhs>
315 auto join_elts = join<ExpSetLhs, ExpSetRhs>(lhs, rhs);
316 auto res = std::get<0>(join_elts).concat(std::get<1>(join_elts),
317 std::get<2>(join_elts));
318 return {std::get<0>(join_elts), res};
329 template <
typename ValueSet>
331 = decltype(std::declval<ValueSet>()
332 .
add(std::declval<typename ValueSet::value_t>(),
333 std::declval<typename ValueSet::value_t>()));
336 template <
typename ValueSet>
344 template <
typename ValueSet>
346 multiply(
const ValueSet& vs,
const typename ValueSet::value_t&
v,
348 -> std::enable_if_t<!has_add_mem_fn<ValueSet>{},
349 typename ValueSet::value_t>
352 vs,
": invalid range exponent: ", exp);
353 return detail::static_if<detail::has_power_mem_fn<ValueSet>{}>
354 ([](
const auto& vs,
const auto&
v,
auto n){
return vs.power(v, n); },
355 [](
const auto& vs,
const auto&
v,
auto n)
360 res = vs.mul(res, v);
374 template <
typename ValueSet>
376 multiply(
const ValueSet& vs,
const typename ValueSet::value_t& v,
378 -> std::enable_if_t<has_add_mem_fn<ValueSet>{},
379 typename ValueSet::value_t>
381 auto res =
typename ValueSet::value_t{};
386 res = vs.mul(vs.power(v, exp.
min),
res);
390 res = vs.power(v, exp.
min);
394 for (
int n = 1; n <= exp.
max - exp.
min; ++n)
395 sum = vs.add(sum, vs.power(v, n));
396 res = vs.mul(res, sum);
407 template <
typename ExpSet,
typename Int1,
typename Int2>
411 const auto&
r = re->as<ExpSet>();
412 return {
r.valueset(),
428 template <
typename LabelSetLhs,
typename LabelSetRhs>
432 const auto& l = lhs->
as<LabelSetLhs>();
433 const auto&
r = rhs->
as<LabelSetRhs>();
434 auto rs =
join(l.valueset(), r.valueset());
435 auto lr = rs.conv(l.valueset(), l.value());
436 auto rr = rs.conv(r.valueset(), r.value());
441 template <
typename LabelSet,
typename Int>
445 const auto&
r = re->
as<LabelSet>();
446 return {
r.valueset(),
462 template <
typename PolynomialSetLhs,
typename PolynomialSetRhs>
466 auto join_elts = join<PolynomialSetLhs, PolynomialSetRhs>(lhs, rhs);
467 return {std::get<0>(join_elts),
multiply(std::get<0>(join_elts),
468 std::get<1>(join_elts),
469 std::get<2>(join_elts))};
483 template <
typename WeightSetLhs,
typename WeightSetRhs>
487 const auto& l = lhs->
as<WeightSetLhs>();
488 const auto&
r = rhs->
as<WeightSetRhs>();
489 auto ws =
join(l.valueset(), r.valueset());
490 auto lw = ws.conv(l.valueset(), l.value());
491 auto rw = ws.conv(r.valueset(), r.value());
496 template <
typename WeightSet,
typename Int1,
typename Int2>
501 return {w.valueset(),
automaton multiply_repeated(const automaton &a, int min, int max, const std::string &algo)
Bridge (multiply).
auto initial_transitions(const Aut &aut) -> decltype(aut->all_out(aut->pre()))
Indexes of transitions to (visible) initial states.
weightset_mixin< detail::r_impl > r
void copy_into(const AutIn &in, AutOut &out, KeepState keep_state, KeepTrans keep_trans)
Copy selected states and transitions of an automaton.
Aut1 & multiply_here(Aut1 &res, const Aut2 &b, deterministic_tag)
Append automaton b to res.
auto multiply(const ValueSet &vs, const typename ValueSet::value_t &v, const to &exp) -> std::enable_if_t<!has_add_mem_fn< ValueSet >
Repeated multiplication of values that cannot be added.
typename detail::transition_t_of_impl< base_t< ValueSet > >::type transition_t_of
typename detail::state_t_of_impl< base_t< ValueSet > >::type state_t_of
auto multiply(const Aut1 &lhs, const Aut2 &rhs, Tag tag={}) -> decltype(lhs->null_state(), rhs->null_state(), detail::make_join_automaton(tag, lhs, rhs))
Concatenate two automata, general case.
polynomial multiply_polynomial(const polynomial &lhs, const polynomial &rhs)
Bridge (multiply).
Tag for operations on deterministic automata.
auto & as()
Extract wrapped typed value.
std::vector< typename Cont::value_type > make_vector(const Cont &cont)
The content of cont as a vector.
context join(const context &c1, const context &c2)
Bridge.
Tag for operations on standard automata.
auto final_transitions(const Aut &aut) -> decltype(aut->all_in(aut->post()))
Indexes of transitions from (visible) final states.
weight multiply_weight(const weight &lhs, const weight &rhs)
Bridge (multiply).
label multiply_label(const label &lhs, const label &rhs)
Bridge (multiply).
label multiply_label_repeated(const label &re, int exp)
Bridge (multiply).
ExpansionSet::value_t determinize(const ExpansionSet &xs, const typename ExpansionSet::value_t &x)
Determinize an expansion.
weight multiply_weight_repeated(const weight &wgt, int min, int max)
Bridge (multiply).
auto all_out(const Aut &aut, state_t_of< Aut > s)
Indexes of transitions leaving state s.
automaton multiply(const automaton &lhs, const automaton &rhs, const std::string &algo)
Bridge.
decltype(std::declval< ValueSet >() .add(std::declval< typename ValueSet::value_t >(), std::declval< typename ValueSet::value_t >())) add_mem_fn_t
The type of the add member function in valuesets.
Provide a variadic mul on top of a binary mul(), and one().
auto copy(const AutIn &input, KeepState keep_state, KeepTrans keep_trans) -> decltype(keep_state(input->null_state()), keep_trans(input->null_transition()), make_fresh_automaton< AutIn, AutOut >(input))
A copy of input keeping only its states that are accepted by keep_state, and transitions accepted by ...
typename detail::labelset_t_of_impl< base_t< ValueSet > >::type labelset_t_of
expression multiply_expression_repeated(const expression &re, int min, int max)
Bridge (multiply).
auto in(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions arriving to state s.
Tag for operations on all automata.
detail::copier< AutIn, AutOut > make_copier(const AutIn &in, AutOut &out, bool safe=true)
Build an automaton copier.
auto & as()
Extract wrapped typed automaton.
expression concatenate_expression(const expression &lhs, const expression &rhs)
Bridge (concatenate).
auto dispatch_tags(std::string algo, Operation op, Aut &&... auts)
Dispatch an operation between automata depending on their nature.
value_impl< detail::expression_tag > expression
automaton star(const automaton &a, const std::string &algo)
Bridge.
An exponent, or range of exponents.
bool single() const
Whether features a single exponent.
expression multiply_expression(const expression &lhs, const expression &rhs)
Bridge (multiply).
automaton strip(const automaton &aut)
Bridge.
automaton add(const automaton &lhs, const automaton &rhs, const std::string &algo)
Bridge.
#define VCSN_REQUIRE(Cond,...)
A macro similar to require.
auto make_join_automaton(deterministic_tag, Auts &&... auts) -> decltype(join_automata(std::forward< Auts >(auts)...))
Make an empty automaton which is a supertype of others.
weightset_mixin< detail::b_impl > b
bool finite() const
Whether the max exponent is finte.