18 # define DEBUG_IFELSE(Then, Else) Then
20 # define DEBUG_IFELSE(Then, Else) Else
23 #define DEBUG_IF(Then) DEBUG_IFELSE(Then,)
38 template <
typename ExpSet>
40 :
public ExpSet::const_visitor
44 using super_t =
typename expressionset_t::const_visitor;
51 using weight_t =
typename weightset_t::value_t;
57 constexpr
static const char*
me() {
return "to_expansion"; }
75 catch (
const std::runtime_error& e)
77 raise(e,
" while computing expansion of: ",
to_string(
rs_, v));
93 auto insert = cache_.emplace(e,
xs_.
zero());
94 auto&
res = insert.first->second;
102 rs_.print(e, std::cerr) <<
" => ";
109 rs_.print(e, std::cerr) <<
" -> ";
120 rs_.print(e, std::cerr) <<
" -> ";
128 std::ostream&
print_(
const expansion_t&
v, std::ostream& o)
const
132 o <<
" (transposed)";
150 ?
ls_.transpose(e.value())
157 for (
const auto&
v: e)
164 for (
size_t i = 0,
size = e.size(); i <
size; ++i)
169 r =
rs_.transposition(
r);
190 ?
rs_.transposition(
prod_(e.begin(),
191 std::next(e.begin(), size-(i+1))))
192 :
prod_(std::next(e.begin(), i + 1), std::end(e));
195 for (
const auto& p: rhs.polynomials)
196 ps_.add_here(
res_.polynomials[p.first],
197 ps_.lweight(
res_.constant, p.second));
198 res_.constant =
ws_.mul(
res_.constant, rhs.constant);
200 if (
ws_.is_zero(
res_.constant))
210 prod_(
typename mul_t::iterator begin,
211 typename mul_t::iterator end)
const
213 using expressions_t =
typename mul_t::values_t;
216 else if (std::next(begin, 1) == end)
219 return std::make_shared<mul_t>(expressions_t{begin, end});
224 assert(e.size() == 2);
239 for (
const auto&
r: e.tail())
249 auto prev = e.head();
251 for (
const auto&
r: e.tail())
257 prev =
rs_.shuffle(prev,
r);
268 auto prev = e.head();
270 for (
const auto&
r: e.tail())
277 prev =
rs_.infiltrate(prev,
r);
290 e.sub()->accept(*
this);
297 res_.constant =
ws_.star(res.constant);
298 auto f = e.shared_from_this();
302 f =
rs_.transposition(f);
305 for (
const auto& p: res.polynomials)
333 template <
bool = context_t::is_lat,
334 typename Dummy =
void>
337 template <
size_t... I>
344 std::get<I>(v.sub()))...);
354 template <
typename Dummy>
366 res_ = visit_tuple<>{*
this}(
v);
375 template <
typename Exp = expansion_t>
377 -> decltype(std::declval<expansionset_t>()
378 .
compose(std::declval<Exp>(), std::declval<Exp>()),
382 for (
const auto&
r: e.tail())
389 require(
false,
"compose: context is not composable");
412 template <
typename ExpSet>
425 template <
typename ExpSet>
429 const auto& e = exp->
as<ExpSet>();
430 const auto&
rs = e.valueset();
432 return {es, to_expansion<ExpSet>(
rs, e.value())};
rat::expansionset< ExpSet >::value_t to_expansion(const ExpSet &rs, const typename ExpSet::value_t &e)
First order expansion.
value_impl< detail::expansion_tag > expansion
value_t conjunction(const value_t &l, const value_t &r) const
The conjunction of l and r.
auto tuple(Expansions &&...es) const -> value_t
The tuplization of single-tape expansions into a multitape expansion.
expansion_t to_expansion(const expression_t &e)
Facilitate recursion.
weightset_t ws_
Manipulate the weights.
expressionset_t expressionset_t
typename polynomialset_t::value_t polynomial_t
value_t rweight(const value_t &lhs, const weight_t &w) const
Right-multiplication of lhs by w.
expression_polynomialset_t< ExpSet > make_expression_polynomialset(const ExpSet &rs)
From a ExpSet to its polynomialset.
value_t ldivide(value_t lhs, value_t rhs) const
labelset_t_of< context_t > labelset_t
std::ostream & print(const value_t &v, std::ostream &o, format fmt={}) const
Print this expansion.
typename expansionset_t::value_t expansion_t
typename expressionset_t::value_t expression_t
This is useful to make hashes with labels or weights as keys without using non-default constructors; ...
expansion_t operator()(const tuple_t &)
weightset_t_of< expressionset_t > weightset_t
std::ostream & decendl(std::ostream &o)
Decrement the indentation, print an end of line, and set the indentation.
An inner node implementing a weight.
typename expansionset_t::polys_t polys_t
auto compose(value_t l, value_t r) const -> std::enable_if_t< are_composable< Ctx, Ctx >
The composition of l and r.
This is useful to make hashes with labels or weights as keys without using non-default constructors; ...
expansion_t operator()(const tuple_t &v)
VCSN_RAT_VISIT(conjunction, e)
d(E&F) = d(E) & d(F).
value_t atom(const label_t &l) const
A single label.
auto weight_of(const welement< Label, Weight > &m) -> decltype(m.weight())
The weight of a welement.
VCSN_RAT_VISIT(lweight, e)
expression_t prod_(typename mul_t::iterator begin, typename mul_t::iterator end) const
Build a product for these expressions.
value_t infiltrate(const value_t &de, const expression_t &e, const value_t &df, const expression_t &f) const
The infiltration product of l and r.
auto compose(const compose_t &e, int) -> decltype(std::declval< expansionset_t >() .compose(std::declval< Exp >(), std::declval< Exp >()), void())
weightset_mixin< detail::r_impl > r
void require(Bool b, Args &&...args)
If b is not verified, raise an error with args as message.
expansionset_t xs_
Manipulate the expansions.
Provide a variadic mul on top of a binary mul(), and one().
VCSN_RAT_VISIT(rweight, e)
std::map< label_t, polynomial_t, vcsn::less< labelset_t >> polys_t
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
value_t & lweight_here(const weight_t &w, value_t &res) const
Inplace left-multiplication by w of res.
static constexpr const char * me()
value_t complement(const value_t &v) const
The complement of v.
polynomialset_t ps_
Manipulate the polynomials of expressions.
VCSN_RAT_VISIT(compose, e)
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
to_expansion_visitor(const expressionset_t &rs)
VCSN_RAT_VISIT(transposition, e)
d(Eᵗ) = dᵗ(E)
VCSN_RAT_VISIT(complement, e)
VCSN_RAT_VISIT(ldivide, e)
context_t_of< expressionset_t > context_t
std::ostream & iendl(std::ostream &o)
Print an end of line, then set the indentation.
value_t zero() const
The zero.
#define BUILTIN_UNREACHABLE()
expansion_t work_(const tuple_t &v, detail::index_sequence< I... >)
value_t transpose(const value_t &v) const
Transpose an expansion. The firsts must be reduced to one.
bool transposed_
Whether to work transposed.
An inner node with multiple children.
value_t & rweight_here(value_t &res, const expression_t &rhs) const
In place right multiplication by an expression.
std::ostream & incendl(std::ostream &o)
Increment the indentation, print an end of line, and set the indentation.
auto & as()
Extract wrapped typed value.
Indentation relative functions.
void add_here(value_t &lhs, const value_t &rhs) const
In place addition.
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
std::ostream & print_(const expansion_t &v, std::ostream &o) const
Print an expansion.
auto compose(const compose_t &, long) -> void
value_t shuffle(const value_t &de, const expression_t &e, const value_t &df, const expression_t &f) const
The shuffle product of de and df.
VCSN_RAT_VISIT(infiltrate, e)
d(E&:F) = d(E)&:F + d(E)&:d(F) + E&:d(F) dᵗ(E&:F) = dᵗ(E)&:Fᵗ + dᵗ(E)&:dᵗ(F) + Eᵗ&:dᵗ(F) ...
value_impl< detail::expression_tag > expression
void visit(const tuple_t &v, std::true_type) override
expressionset_t rs_
Manipulate the expressions.
typename weightset_t::value_t weight_t
typename super_t::tuple_t tuple_t
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Request the unordered_map implementation.
auto label_of(const welement< Label, Weight > &m) -> decltype(m.label())
The label of a welement.
expansion_t res_
The result.
value_t one() const
The one.
std::string to_string(identities i)
Wrapper around operator<<.
labelset_t ls_
Manipulate the labels.
VCSN_RAT_VISIT(shuffle, e)
d(E:F) = d(E):F + E:d(F) dᵗ(E:F) = dᵗ(E):Fᵗ + Eᵗ:dᵗ(F)
Functor to compute the expansion of an expression.
expansion_t operator()(const expression_t &v)
From an expression, build its expansion.
expansion to_expansion(const expression &exp)
Bridge.
typename expressionset_t::const_visitor super_t