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) <<
" -> ";
129 print_(
const expansion_t&
v, std::ostream& o = std::cerr)
const 133 o <<
" (transposed)";
138 expression_t
me(expression_t
res)
const 142 auto i =
names_.find(res);
158 auto i =
names_.emplace(e.sub(), e.shared_from_this()).first;
176 ?
ls_.transpose(e.value())
183 for (
const auto&
v: e)
189 if (getenv(
"VCSN_NAIVE_MUL"))
195 prod_(std::next(e.begin()), std::end(e)));
200 for (
size_t i = 0,
size = e.size(); i <
size; ++i)
205 r =
rs_.transposition(
r);
230 ?
rs_.transposition(
prod_(e.begin(),
231 std::next(e.begin(), size-(i+1))))
232 :
prod_(std::next(e.begin(), i + 1), std::end(e));
235 auto w = std::move(rhs.constant);
236 rhs.constant =
ws_.zero();
238 rhs.constant = std::move(w);
241 for (
const auto& p: rhs.polynomials)
242 ps_.add_here(
res_.polynomials[p.first],
243 ps_.lweight(
res_.constant, p.second));
244 res_.constant =
ws_.mul(
res_.constant, rhs.constant);
246 if (
ws_.is_zero(
res_.constant))
257 prod_(
typename mul_t::iterator begin,
258 typename mul_t::iterator end)
const 260 using expressions_t =
typename mul_t::values_t;
261 assert(begin != end);
262 if (std::next(begin, 1) == end)
265 return std::make_shared<mul_t>(expressions_t{begin, end});
270 assert(e.size() == 2);
285 for (
const auto&
r: e.tail())
295 auto prev = e.head();
297 for (
const auto&
r: e.tail())
303 prev =
rs_.shuffle(prev,
r);
314 auto prev = e.head();
316 for (
const auto&
r: e.tail())
323 prev =
rs_.infiltrate(prev,
r);
336 e.sub()->accept(*
this);
345 auto f =
me(e.shared_from_this());
349 res_.constant =
ws_.star(x.constant);
360 f =
rs_.transposition(f);
363 for (
const auto& p: x.polynomials)
367 if (getenv(
"VCSN_DENORMALIZE_STAR"))
393 template <
bool = context_t::is_lat,
394 typename Dummy =
void>
397 template <
size_t... I>
404 std::get<I>(v.sub()))...);
414 template <
typename Dummy>
426 res_ = visit_tuple<>{*
this}(
v);
435 template <
typename Exp = expansion_t>
437 -> decltype(std::declval<expansionset_t>()
438 .
compose(std::declval<Exp>(), std::declval<Exp>()),
442 for (
const auto&
r: e.tail())
449 require(
false,
"compose: context is not composable");
469 std::map<expression_t, expression_t>
names_;
474 template <
typename ExpSet>
487 template <
typename ExpSet>
491 const auto& e = exp->as<ExpSet>();
492 const auto& rs = e.valueset();
494 return {es, to_expansion<ExpSet>(rs, e.value())};
std::ostream & iendl(std::ostream &o)
Print an end of line, then set the indentation.
value_impl< detail::expansion_tag > expansion
value_t & denormalize(value_t &res) const
Move the constant to the polynomial associated to one.
VCSN_RAT_VISIT(transposition, e)
d(Eᵗ) = dᵗ(E)
typename expressionset_t::value_t expression_t
weightset_mixin< detail::r_impl > r
typename detail::weightset_t_of_impl< base_t< ValueSet > >::type weightset_t_of
typename expansionset_t::polys_t polys_t
auto compose(const compose_t &e, int) -> decltype(std::declval< expansionset_t >() .compose(std::declval< Exp >(), std::declval< Exp >()), void())
value_t complement(const value_t &v) const
The complement of v.
std::map< expression_t, expression_t > names_
A table from the expression to the naming expression.
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
VCSN_RAT_VISIT(rweight, e)
typename expressionset_t::const_visitor super_t
auto tuple(Expansions &&... es) const -> value_t
The tuplization of single-tape expansions into a multitape expansion.
An inner node with multiple children.
value_t & rmul_label_here(value_t &res, const expression_t &rhs) const
In place right multiplication by an expression.
std::map< label_t, polynomial_t, vcsn::less< labelset_t > > polys_t
VCSN_RAT_VISIT(shuffle, e)
d(E:F) = d(E):F + E:d(F) dᵗ(E:F) = dᵗ(E):Fᵗ + Eᵗ:dᵗ(F)
VCSN_RAT_VISIT(ldivide, e)
VCSN_RAT_VISIT(complement, e)
static constexpr const char * me()
bool transposed_
Whether to work transposed.
VCSN_RAT_VISIT(lweight, e)
typename expansionset_t::value_t expansion_t
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 conjunction(const value_t &l, const value_t &r) const
The conjunction of l and r.
VCSN_RAT_VISIT(name, e)
When we find that an expression is named, record named -> naming, so that when we need named...
value_t rweight(const value_t &lhs, const weight_t &w) const
Right-multiplication of lhs by w.
labelset_t_of< context_t > labelset_t
auto compose(const compose_t &, long) -> void
An inner node to name the subexpression.
This is useful to make hashes with labels or weights as keys without using non-default constructors; ...
typename detail::context_t_of_impl< base_t< ValueSet > >::type context_t_of
Provide a variadic mul on top of a binary mul(), and one().
typename detail::labelset_t_of_impl< base_t< ValueSet > >::type labelset_t_of
expression_t me(expression_t res) const
Find if an expression is named.
value_t & lweight_here(const weight_t &w, value_t &res) const
Inplace left-multiplication by w of res.
value_t one() const
The one.
std::ostream & incendl(std::ostream &o)
Increment the indentation, print an end of line, and set the indentation.
std::ostream & print(const value_t &v, std::ostream &o=std::cout, format fmt={}) const
Print this expansion.
to_expansion_visitor(const expressionset_t &rs)
std::ostream & decendl(std::ostream &o)
Decrement the indentation, print an end of line, and set the indentation.
VCSN_RAT_VISIT(star, e)
If E is normal, d(E*) = <c(E)*> + <c(E)*> dp(E) E*.
typename weightset_t::value_t weight_t
expansion_t res_
The result.
std::string to_string(identities i)
Wrapper around operator<<.
expression_t prod_(typename mul_t::iterator begin, typename mul_t::iterator end) const
Build a product for these expressions.
An inner node implementing a weight.
This is useful to make hashes with labels or weights as keys without using non-default constructors; ...
weightset_t ws_
Manipulate the weights.
value_t zero() const
The zero.
void visit(const tuple_t &v, std::true_type) override
VCSN_RAT_VISIT(conjunction, e)
d(E&F) = d(E) & d(F).
void swap(config::value &first, config::value &second)
expansion_t operator()(const tuple_t &v)
typename polynomialset_t::value_t polynomial_t
weightset_t_of< expressionset_t > weightset_t
expansion_t to_expansion(const expression_t &e)
Facilitate recursion.
auto weight_of(const welement< Label, Weight > &m) -> decltype(m.weight())
The weight of a welement.
auto label_of(const welement< Label, Weight > &m) -> decltype(m.label())
The label of a welement.
value_t ldivide(value_t lhs, value_t rhs) const
polynomialset_t ps_
Manipulate the polynomials of expressions.
rat::expansionset< ExpSet >::value_t to_expansion(const ExpSet &rs, const typename ExpSet::value_t &e)
First order expansion.
expansionset_t xs_
Manipulate the expansions.
value_impl< detail::expression_tag > expression
Functor to compute the expansion of an expression.
VCSN_RAT_VISIT(compose, e)
expression_polynomialset_t< ExpSet > make_expression_polynomialset(const ExpSet &rs)
From a ExpSet to its polynomialset.
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.
expressionset_t expressionset_t
void require(Bool b, Args &&... args)
If b is not verified, raise an error with args as message.
Request the unordered_map implementation.
value_t transpose(const value_t &v) const
Transpose an expansion. The firsts must be reduced to one.
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.
expansion_t operator()(const tuple_t &)
context_t_of< expressionset_t > context_t
auto compose(value_t l, value_t r) const -> std::enable_if_t< are_composable< Ctx, Ctx >() &&number_of_tapes< Ctx >::value==2, value_t >
The composition of l and r.
typename super_t::tuple_t tuple_t
expansion_t operator()(const expression_t &v)
From an expression, build its expansion.
labelset_t ls_
Manipulate the labels.
bool is_normal(const value_t &x) const
Whether an expansion is normal.
std::ostream & print_(const expansion_t &v, std::ostream &o=std::cerr) const
Print an expansion.
Indentation relative functions.
#define BUILTIN_UNREACHABLE()
expansion_t work_(const tuple_t &v, detail::index_sequence< I... >)
value_t atom(const label_t &l) const
A single label.
void add_here(value_t &lhs, const value_t &rhs) const
In place addition.
expressionset_t rs_
Manipulate the expressions.