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,
es_.
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);
226 std::cerr <<
"Start: ";
227 rs_.print(e.shared_from_this(), std::cerr) <<
" =>\n";
238 std::cerr <<
"Lhs: ";
print_(lhs, std::cerr) <<
'\n';
239 std::cerr <<
"Rhs: ";
print_(rhs, std::cerr) <<
'\n';
243 for (
const auto& p:
zip_maps(lhs.polynomials, rhs.polynomials))
244 for (
const auto& lm: std::get<0>(p.second))
245 for (
const auto& rm: std::get<1>(p.second))
249 ps_.add_here(res_.polynomials[
one],
255 ps_.add_here(res_.polynomials[
one],
258 if (
has(lhs.polynomials,
one))
259 for (
const auto& rhsp: rhs.polynomials)
260 if (rhsp.first !=
one)
261 for (
const auto& lm: lhs.polynomials[
one])
262 for (
const auto& rm: rhsp.second)
265 ps_.add_here(res_.polynomials[one],
268 rs_.mul(
rs_.atom(rhsp.first),
272 ps_.add_here(res_.polynomials[one],
277 if (
has(rhs.polynomials, one))
278 for (
const auto& lhsp: lhs.polynomials)
279 if (lhsp.first != one)
280 for (
const auto& lm: lhsp.second)
281 for (
const auto& rm: rhs.polynomials[one])
284 ps_.add_here(res_.polynomials[one],
290 ps_.add_here(res_.polynomials[one],
302 for (
const auto&
r: e.tail())
312 auto prev = e.head();
314 for (
const auto&
r: e.tail())
320 prev =
rs_.shuffle(prev,
r);
331 auto prev = e.head();
333 for (
const auto&
r: e.tail())
340 prev =
rs_.infiltrate(prev,
r);
353 e.sub()->accept(*
this);
360 res_.constant =
ws_.star(res.constant);
361 auto f = e.shared_from_this();
365 f =
rs_.transposition(f);
368 for (
const auto& p: res.polynomials)
396 template <
bool = context_t::is_lat,
397 typename Dummy =
void>
400 template <
size_t... I>
407 std::get<I>(v.sub()))...);
417 template <
typename Dummy>
429 res_ = visit_tuple<>{*
this}(
v);
438 template <
typename Exp = expansion_t>
440 -> decltype(std::declval<expansionset_t>()
441 .
compose(std::declval<Exp>(), std::declval<Exp>()),
445 for (
const auto&
r: e.tail())
452 require(
false,
"compose: context is not composable");
475 template <
typename ExpSet>
488 template <
typename ExpSet>
492 const auto& e = exp->
as<ExpSet>();
493 const auto&
rs = e.valueset();
495 return {es, to_expansion<ExpSet>(
rs, e.value())};
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_t & normalize(value_t &res) const
Normalize: move the constant term to the label one.
expressionset_t rs_
Manipulate the expressions.
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)
std::ostream & print_(const expansion_t &v, std::ostream &o) const
Print an expansion.
#define BUILTIN_UNREACHABLE()
weightset_t ws_
Manipulate the weights.
value_t & denormalize(value_t &res) const
Move the constant to the polynomial associated to one.
std::ostream & incendl(std::ostream &o)
Increment the indentation, print an end of line, and set the indentation.
auto compose(const compose_t &, long) -> void
VCSN_RAT_VISIT(complement, e)
typename super_t::tuple_t tuple_t
auto label_one(const LabelSet &ls) -> typename LabelSet::value_t
Enjoy type inference.
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
typename expansionset_t::polys_t polys_t
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
auto compose(value_t l, value_t r) const -> std::enable_if_t< are_composable< Ctx, Ctx >
The composition of l and r.
VCSN_RAT_VISIT(rweight, e)
typename expressionset_t::value_t expression_t
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
std::ostream & iendl(std::ostream &o)
Print an end of line, then set the indentation.
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.
expressionset_t expressionset_t
std::ostream & decendl(std::ostream &o)
Decrement the indentation, print an end of line, and set the indentation.
value_t infiltrate(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.
VCSN_RAT_VISIT(transposition, e)
d(Eᵗ) = dᵗ(E)
An inner node implementing a weight.
void require(Bool b, Args &&...args)
If b is not verified, raise an error with args as message.
value_t & lweight_here(const weight_t &w, value_t &res) const
Inplace left-multiplication by w of res.
VCSN_RAT_VISIT(ldivide, e)
Request the unordered_map implementation.
weightset_t_of< expressionset_t > weightset_t
static constexpr const char * me()
auto compose(const compose_t &e, int) -> decltype(std::declval< expansionset_t >() .compose(std::declval< Exp >(), std::declval< Exp >()), void())
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 lhs_xpn and rhs_xpn.
VCSN_RAT_VISIT(compose, e)
value_t atom(const label_t &l) const
A single label.
ATTRIBUTE_PURE bool has(const boost::container::flat_set< Key, Compare, Allocator > &s, const Key &e)
Whether e is member of s.
rat::expansionset< ExpSet >::value_t to_expansion(const ExpSet &rs, const typename ExpSet::value_t &e)
First order expansion.
value_t complement(const value_t &v) const
The complement of v.
value_t & rweight_here(value_t &res, const expression_t &rhs) const
In place right multiplication by an expression.
typename expansionset_t::value_t expansion_t
std::map< label_t, polynomial_t, vcsn::less< labelset_t >> polys_t
expansion_t work_(const tuple_t &v, detail::index_sequence< I... >)
This is useful to make hashes with labels or weights as keys without using non-default constructors; ...
bool transposed_
Whether to work transposed.
void visit(const tuple_t &v, std::true_type) override
typename weightset_t::value_t weight_t
Indentation relative functions.
expansion_t to_expansion(const expression_t &e)
Facilitate recursion.
value_t zero() const
The zero.
expansion_t operator()(const tuple_t &)
polynomialset_t ps_
Manipulate the polynomials of expressions.
value_impl< detail::expansion_tag > expansion
Functor to compute the expansion of an expression.
void add_here(value_t &lhs, const value_t &rhs) const
In place addition.
std::string to_string(identities i)
Wrapper around operator<<.
value_t one() const
The one.
expression_t prod_(typename mul_t::iterator begin, typename mul_t::iterator end) const
Build a product for these expressions.
to_expansion_visitor(const expressionset_t &rs)
labelset_t_of< context_t > labelset_t
auto weight_of(const welement< Label, Weight > &m) -> decltype(m.weight())
The weight of a welement.
expansionset_t es_
Manipulate the expansions.
expansion_t operator()(const tuple_t &v)
expansion_t operator()(const expression_t &v)
From an expression, build its expansion.
auto & as()
Extract wrapped typed value.
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
typename expressionset_t::const_visitor super_t
expansion to_expansion(const expression &exp)
Bridge.
expression_polynomialset_t< ExpSet > make_expression_polynomialset(const ExpSet &rs)
From a ExpSet to its polynomialset.
value_t rweight(const value_t &lhs, const weight_t &w) const
Right-multiplication of lhs by w.
An inner node with multiple children.
expansion_t res_
The result.
std::ostream & print(const value_t &v, std::ostream &o, format fmt={}) const
Print this expansion.
VCSN_RAT_VISIT(conjunction, e)
d(E&F) = d(E) & d(F).
zipped_maps< Dereference, Maps... > zip_maps(Maps &&...maps)
Provide a variadic mul on top of a binary mul(), and one().
typename polynomialset_t::value_t polynomial_t
value_impl< detail::expression_tag > expression
This is useful to make hashes with labels or weights as keys without using non-default constructors; ...
value_t conjunction(const value_t &l, const value_t &r) const
The conjunction of l and r.
context_t_of< expressionset_t > context_t
VCSN_RAT_VISIT(lweight, e)
weightset_mixin< detail::r_impl > r