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();
107 [b](state_t_of<Aut2> s)
109 return !b->is_initial(s) || !
in(b, s).empty();
113 [
b] (transition_t_of<Aut2> t) {
return b->src_of(t) != b->pre(); });
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,
204 template <Automaton Aut,
typename Tag = general_tag>
207 -> decltype(aut->null_state(),
213 res =
star(aut, tag);
222 auto s = res->new_state();
231 for (
int n = 1; n < exp.
min; ++n)
239 auto s = sum->new_state();
243 for (
int n = 1; n <= exp.
max - exp.
min; ++n)
256 template <Automaton Aut,
typename Int1,
typename Int2,
typename String>
259 const std::string& algo)
261 const auto& aut = a->
as<Aut>();
263 [aut, min, max](
auto tag)
278 template <
typename ValueSet>
279 typename ValueSet::value_t
281 const typename ValueSet::value_t& lhs,
282 const typename ValueSet::value_t& rhs)
284 return vs.mul(lhs, rhs);
292 template <
typename ExpSetLhs,
typename ExpSetRhs>
296 auto join_elts = join<ExpSetLhs, ExpSetRhs>(lhs, rhs);
297 return {std::get<0>(join_elts),
299 std::get<1>(join_elts),
300 std::get<2>(join_elts))};
310 template <
typename ExpSetLhs,
typename ExpSetRhs>
314 auto join_elts = join<ExpSetLhs, ExpSetRhs>(lhs, rhs);
315 auto res = std::get<0>(join_elts).concat(std::get<1>(join_elts),
316 std::get<2>(join_elts));
317 return {std::get<0>(join_elts), res};
328 template <
typename ValueSet>
330 = decltype(std::declval<ValueSet>()
331 .
add(std::declval<typename ValueSet::value_t>(),
332 std::declval<typename ValueSet::value_t>()));
335 template <
typename ValueSet>
343 template <
typename ValueSet>
345 multiply(
const ValueSet& vs,
const typename ValueSet::value_t&
v,
347 -> std::enable_if_t<!has_add_mem_fn<ValueSet>{},
348 typename ValueSet::value_t>
351 vs,
": invalid range exponent: ", exp);
352 return detail::static_if<detail::has_power_mem_fn<ValueSet>{}>
353 ([](
const auto& vs,
const auto&
v,
auto n){
return vs.power(v, n); },
354 [](
const auto& vs,
const auto&
v,
auto n)
359 res = vs.mul(res, v);
373 template <
typename ValueSet>
375 multiply(
const ValueSet& vs,
const typename ValueSet::value_t& v,
377 -> std::enable_if_t<has_add_mem_fn<ValueSet>{},
378 typename ValueSet::value_t>
380 auto res =
typename ValueSet::value_t{};
385 res = vs.mul(vs.power(v, exp.
min),
res);
389 res = vs.power(v, exp.
min);
393 for (
int n = 1; n <= exp.
max - exp.
min; ++n)
394 sum = vs.add(sum, vs.power(v, n));
395 res = vs.mul(res, sum);
406 template <
typename ExpSet,
typename Int1,
typename Int2>
410 const auto&
r = re->as<ExpSet>();
411 return {
r.valueset(),
427 template <
typename LabelSetLhs,
typename LabelSetRhs>
431 const auto& l = lhs->
as<LabelSetLhs>();
432 const auto&
r = rhs->
as<LabelSetRhs>();
433 auto rs =
join(l.valueset(), r.valueset());
434 auto lr = rs.conv(l.valueset(), l.value());
435 auto rr = rs.conv(r.valueset(), r.value());
440 template <
typename LabelSet,
typename Int>
444 const auto&
r = re->
as<LabelSet>();
445 return {
r.valueset(),
461 template <
typename PolynomialSetLhs,
typename PolynomialSetRhs>
465 auto join_elts = join<PolynomialSetLhs, PolynomialSetRhs>(lhs, rhs);
466 return {std::get<0>(join_elts),
multiply(std::get<0>(join_elts),
467 std::get<1>(join_elts),
468 std::get<2>(join_elts))};
482 template <
typename WeightSetLhs,
typename WeightSetRhs>
486 const auto& l = lhs->
as<WeightSetLhs>();
487 const auto&
r = rhs->
as<WeightSetRhs>();
488 auto ws =
join(l.valueset(), r.valueset());
489 auto lw = ws.conv(l.valueset(), l.value());
490 auto rw = ws.conv(r.valueset(), r.value());
495 template <
typename WeightSet,
typename Int1,
typename Int2>
500 return {w.valueset(),
Tag for operations on all automata.
value_impl< detail::weight_tag > weight
expression concatenate_expression(const expression &lhs, const expression &rhs)
Bridge (concatenate).
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.
std::vector< typename Cont::value_type > make_vector(const Cont &cont)
The content of cont as a vector.
typename detail::transition_t_of_impl< base_t< ValueSet >>::type transition_t_of
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
bool finite() const
Whether the max exponent is finte.
auto in(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions arriving to state s.
Tag for operations on standard automata.
Aut1 & multiply_here(Aut1 &res, const Aut2 &b, deterministic_tag)
Append automaton b to res.
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.
automaton multiply(const automaton &lhs, const automaton &rhs, const std::string &algo="auto")
Multiply (concatenate) two automata.
weight multiply_weight(const weight &lhs, const weight &rhs)
Bridge (multiply).
automaton add(const automaton &lhs, const automaton &rhs, const std::string &algo="auto")
Sum of two automata.
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
value_impl< detail::label_tag > label
label multiply_label(const label &lhs, const label &rhs)
Bridge (multiply).
expression multiply_expression_repeated(const expression &re, int min, int max)
Bridge (multiply).
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 ...
auto add(const Aut1 &lhs, const Aut2 &rhs, deterministic_tag)
automaton multiply(const automaton &lhs, const automaton &rhs, const std::string &algo)
Bridge.
#define VCSN_REQUIRE(Cond,...)
A macro similar to require.
void copy_into(const AutIn &in, AutOut &out, KeepState keep_state, KeepTrans keep_trans)
Copy selected states and transitions of an automaton.
value_impl< detail::polynomial_tag > polynomial
auto determinize(const Aut &a, Tag={}, bool_constant< Lazy >={})
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.
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.
label multiply_label_repeated(const label &re, int exp)
Bridge (multiply).
detail::copier< AutIn, AutOut > make_copier(const AutIn &in, AutOut &out, bool safe=true)
Build an automaton copier.
auto initial_transitions(const Aut &aut) -> decltype(aut->all_out(aut->pre()))
Indexes of transitions to (visible) initial states.
auto & as()
Extract wrapped typed value.
automaton multiply_repeated(const automaton &a, int min, int max, const std::string &algo)
Bridge (multiply).
context join(const context &lhs, const context &rhs)
The join between two contexts, i.e., their lowest common supertype.
weightset_mixin< detail::b_impl > b
auto dispatch_tags(std::string algo, Operation op, Aut &&...auts)
Dispatch an operation between automata depending on their nature.
auto & as()
Extract wrapped typed automaton.
auto strip(const Aut &aut)
Remove (all) the decorations from a decorated automaton.
Tag for operations on deterministic automata.
polynomial multiply_polynomial(const polynomial &lhs, const polynomial &rhs)
Bridge (multiply).
An exponent, or range of exponents.
Provide a variadic mul on top of a binary mul(), and one().
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.
auto all_out(const Aut &aut, state_t_of< Aut > s)
Indexes of transitions leaving state s.
weight multiply_weight_repeated(const weight &wgt, int min, int max)
Bridge (multiply).
value_impl< detail::expression_tag > expression
auto final_transitions(const Aut &aut) -> decltype(aut->all_in(aut->post()))
Indexes of transitions from (visible) final states.
expression multiply_expression(const expression &lhs, const expression &rhs)
Bridge (multiply).
bool single() const
Whether features a single exponent.
auto star(const Aut &aut, Tag tag={}) -> decltype(detail::make_join_automaton(tag, aut))
Star of an automaton.
weightset_mixin< detail::r_impl > r