19 # define DEBUG_IFELSE(Then, Else) Then
21 # define DEBUG_IFELSE(Then, Else) Else
24 #define DEBUG_IF(Then) DEBUG_IFELSE(Then,)
39 template <
typename ExpSet>
41 :
public ExpSet::const_visitor
45 using super_t =
typename expressionset_t::const_visitor;
52 using weight_t =
typename weightset_t::value_t;
58 constexpr
static const char*
me() {
return "to_expansion"; }
87 auto insert = cache_.emplace(e,
es_.
zero());
88 auto& res = insert.first->second;
96 rs_.print(e, std::cerr) <<
" => ";
103 rs_.print(e, std::cerr) <<
" -> ";
110 std::swap(res,
res_);
112 std::swap(res,
res_);
114 rs_.print(e, std::cerr) <<
" -> ";
122 std::ostream&
print_(
const expansion_t&
v, std::ostream& o)
const
126 o <<
" (transposed)";
144 ?
ls_.transpose(e.value())
151 for (
const auto&
v: e)
158 for (
size_t i = 0,
size = e.size(); i <
size; ++i)
163 r =
rs_.transposition(
r);
184 ?
rs_.transposition(
prod_(e.begin(),
185 std::next(e.begin(), size-(i+1))))
186 :
prod_(std::next(e.begin(), i + 1), std::end(e));
189 for (
const auto& p: rhs.polynomials)
190 ps_.add_here(
res_.polynomials[p.first],
191 ps_.lmul(
res_.constant, p.second));
192 res_.constant =
ws_.mul(
res_.constant, rhs.constant);
194 if (
ws_.is_zero(
res_.constant))
204 prod_(
typename prod_t::iterator begin,
205 typename prod_t::iterator end)
const
207 using expressions_t =
typename prod_t::values_t;
210 else if (std::next(begin, 1) == end)
213 return std::make_shared<prod_t>(expressions_t{begin, end});
218 assert(e.size() == 2);
220 std::cerr <<
"Start: ";
221 rs_.print(e.shared_from_this(), std::cerr) <<
" =>\n";
230 std::cerr <<
"Lhs: ";
print_(lhs, std::cerr) <<
'\n';
231 std::cerr <<
"Rhs: ";
print_(rhs, std::cerr) <<
'\n';
235 if (!
ws_.is_zero(lhs.constant))
247 for (
const auto& p:
zip_maps(lhs.polynomials, rhs.polynomials))
248 for (
const auto& lm: std::get<0>(p.second))
249 for (
const auto& rm: std::get<1>(p.second))
253 ps_.add_here(res_.polynomials[
one],
259 ps_.add_here(res_.polynomials[
one],
269 for (
const auto&
r: e.tail())
278 auto prev = e.head();
280 for (
const auto&
r: e.tail())
284 prev =
rs_.shuffle(prev,
r);
294 auto prev = e.head();
296 for (
const auto&
r: e.tail())
300 prev =
rs_.infiltration(prev,
r);
313 e.sub()->accept(*
this);
320 res_.constant =
ws_.star(res.constant);
321 auto f = e.shared_from_this();
325 f =
rs_.transposition(f);
328 for (
const auto& p: res.polynomials)
356 template <
bool = context_t::is_lat,
357 typename Dummy =
void>
360 template <
size_t... I>
367 std::get<I>(v.sub()))...);
377 template <
typename Dummy>
389 res_ = visit_tuple<>{*
this}(
v);
411 template <
typename ExpSet>
424 template <
typename ExpSet>
428 const auto& e = exp->as<ExpSet>();
429 const auto&
rs = e.expressionset();
432 to_expansion<ExpSet>(rs, e.expression()));
VCSN_RAT_VISIT(conjunction, e)
void visit(const tuple_t &v, std::true_type) override
value_t conjunction(value_t l, value_t r) const
The conjunction of l and r.
std::ostream & incendl(std::ostream &o)
Increment the indentation, print an end of line, and set the indentation.
VCSN_RAT_VISIT(lweight, e)
value_t complement(const value_t &v) const
The complement of v.
typename super_t::tuple_t tuple_t
expansion_t operator()(const tuple_t &v)
VCSN_RAT_VISIT(infiltration, e)
void add_here(value_t &lhs, const value_t &rhs) const
In place addition.
VCSN_RAT_VISIT(rweight, e)
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
labelset_t ls_
Manipulate the labels.
typename expressionset_t::const_visitor super_t
value_t & rmul_here(value_t &res, const expression_t &rhs) const
In place right multiplication by an expression.
value_t rmul(const value_t &lhs, const weight_t &w) const
Right-multiplication of lhs by w.
expansionset_t es_
Manipulate the expansions.
value_t zero() const
The zero.
expansion_t to_expansion(const expression_t &e)
Facilitate recursion.
std::ostream & decendl(std::ostream &o)
Decrement the indentation, print an end of line, and set the indentation.
polynomialset_t ps_
Manipulate the polynomials of expressions.
std::shared_ptr< const detail::expansion_base > expansion
weightset_t ws_
Manipulate the weights.
value_t infiltration(const value_t &lhs_xpn, const expression_t &lhs_xpr, const value_t &rhs_xpn, const expression_t &rhs_xpr) const
The infiltration product of l and r.
value_t one() const
The one.
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
typename expansionset_t::value_t expansion_t
VCSN_RAT_VISIT(complement, e)
Indentation relative functions.
expression_t prod_(typename prod_t::iterator begin, typename prod_t::iterator end) const
Build a product for these expressions.
Provide a variadic mul on top of a binary mul(), and one().
An inner node with multiple children.
auto weight_of(const welement< Label, Weight > &m) -> decltype(m.weight())
The weight of a welement.
std::ostream & iendl(std::ostream &o)
Print an end of line, then set the indentation.
typename expansionset_t::polys_t polys_t
context_t_of< expressionset_t > context_t
#define BUILTIN_UNREACHABLE()
bool transposed_
Whether to work transposed.
value_t & normalize(value_t &res) const
Normalize: move the constant term to the label one.
std::ostream & print(const value_t &v, std::ostream &o, format fmt={}) const
Print this expansion.
Request the unordered_map implementation.
auto label_one() -> std::enable_if_t< LabelSet::has_one(), typename LabelSet::value_t >
This LabelSet's one(), if supported.
static constexpr const char * me()
expressionset_t rs_
Manipulate the expressions.
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
typename weightset_t::value_t weight_t
auto tuple(Expansions &&...es) const -> value_t
The tuplization of single-tape expansions into a multitape expansion.
auto label_of(const welement< Label, Weight > &m) -> decltype(m.label())
The label of a welement.
to_expansion_visitor(const expressionset_t &rs)
VCSN_RAT_VISIT(transposition, e)
An inner node implementing a weight.
expansion_t res_
The result.
VCSN_RAT_VISIT(shuffle, e)
Functor to compute the expansion of an expression.
expansion_t operator()(const expression_t &v)
From an expression, build its expansion.
This is useful to make hashes with labels or weights as keys without using non-default constructors; ...
std::shared_ptr< detail::expression_base > expression
expansion make_expansion(const ExpansionSet &ps, const typename ExpansionSet::value_t &expansion)
value_t shuffle(const value_t &lhs_xpn, const expression_t &lhs_xpr, const value_t &rhs_xpn, const expression_t &rhs_xpr) const
The shuffle product of l and r.
expansion_t operator()(const tuple_t &)
expression_polynomialset_t< ExpSet > make_expression_polynomialset(const ExpSet &rs)
From a ExpSet to its polynomialset.
expansion to_expansion(const expression &exp)
Bridge.
value_t & lmul_here(const weight_t &w, value_t &res) const
Inplace left-multiplication by w of res.
value_t atom(const label_t &l) const
A single label.
rat::expansionset< ExpSet >::value_t to_expansion(const ExpSet &rs, const typename ExpSet::value_t &e)
First order expansion.
expressionset_t expressionset_t
typename polynomialset_t::value_t polynomial_t
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
labelset_t_of< context_t > labelset_t
This is useful to make hashes with labels or weights as keys without using non-default constructors; ...
typename expressionset_t::value_t expression_t
value_t & ldiv_here(const weight_t &w, value_t &res) const
Inplace left-division by w of res.
zipped_maps< Dereference, Maps... > zip_maps(Maps &&...maps)
std::map< label_t, polynomial_t, vcsn::less< labelset_t >> polys_t
std::ostream & print_(const expansion_t &v, std::ostream &o) const
Print an expansion.
weightset_t_of< expressionset_t > weightset_t
expansion_t work_(const tuple_t &v, detail::index_sequence< I... >)