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())};
typename detail::context_t_of_impl< base_t< ValueSet > >::type context_t_of
value_t ldivide(value_t lhs, value_t rhs) const
weightset_mixin< detail::r_impl > r
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.
auto compose(const compose_t &, long) -> void
auto tuple(Expansions &&... es) const -> value_t
The tuplization of single-tape expansions into a multitape expansion.
VCSN_RAT_VISIT(compose, e)
VCSN_RAT_VISIT(lweight, e)
typename expansionset_t::value_t expansion_t
value_t rweight(const value_t &lhs, const weight_t &w) const
Right-multiplication of lhs by w.
weightset_t ws_
Manipulate the weights.
value_impl< detail::expression_tag > expression
VCSN_RAT_VISIT(conjunction, e)
d(E&F) = d(E) & d(F).
An inner node with multiple children.
expansion_t operator()(const expression_t &v)
From an expression, build its expansion.
bool transposed_
Whether to work transposed.
std::ostream & print_(const expansion_t &v, std::ostream &o=std::cerr) const
Print an expansion.
void swap(config::config_value &first, config::config_value &second)
auto label_of(const welement< Label, Weight > &m) -> decltype(m.label())
The label of a welement.
Functor to compute the expansion of an expression.
value_t one() const
The one.
std::ostream & iendl(std::ostream &o)
Print an end of line, then set the indentation.
rat::expansionset< ExpSet >::value_t to_expansion(const ExpSet &rs, const typename ExpSet::value_t &e)
First order expansion.
expression_t me(expression_t res) const
Find if an expression is named.
typename detail::labelset_t_of_impl< base_t< ValueSet > >::type labelset_t_of
typename expansionset_t::polys_t polys_t
value_t complement(const value_t &v) const
The complement of v.
std::ostream & incendl(std::ostream &o)
Increment the indentation, print an end of line, and set the indentation.
An inner node to name the subexpression.
This is useful to make hashes with labels or weights as keys without using non-default constructors; ...
Provide a variadic mul on top of a binary mul(), and one().
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 &de, const expression_t &e, const value_t &df, const expression_t &f) const
The shuffle product of de and df.
typename weightset_t::value_t weight_t
expansion_t to_expansion(const expression_t &e)
Facilitate recursion.
value_t & rmul_label_here(value_t &res, const expression_t &rhs) const
In place right multiplication by an expression.
static constexpr const char * me()
std::map< label_t, polynomial_t, vcsn::less< labelset_t > > polys_t
expansion_t res_
The result.
value_t & denormalize(value_t &res) const
Move the constant to the polynomial associated to one.
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
VCSN_RAT_VISIT(name, e)
When we find that an expression is named, record named -> naming, so that when we need named...
VCSN_RAT_VISIT(star, e)
If E is normal, d(E*) = <c(E)*> + <c(E)*> dp(E) E*.
context_t_of< expressionset_t > context_t
value_impl< detail::expansion_tag > expansion
VCSN_RAT_VISIT(complement, e)
weightset_t_of< expressionset_t > weightset_t
This is useful to make hashes with labels or weights as keys without using non-default constructors; ...
auto weight_of(const welement< Label, Weight > &m) -> decltype(m.weight())
The weight of a welement.
typename detail::weightset_t_of_impl< base_t< ValueSet > >::type weightset_t_of
typename expressionset_t::const_visitor super_t
value_t atom(const label_t &l) const
A single label.
labelset_t_of< context_t > labelset_t
bool is_normal(const value_t &x) const
Whether an expansion is normal.
VCSN_RAT_VISIT(transposition, e)
d(Eᵗ) = dᵗ(E)
expressionset_t expressionset_t
typename expressionset_t::value_t expression_t
polynomialset_t ps_
Manipulate the polynomials of expressions.
void require(Bool b, Args &&... args)
If b is not verified, raise an error with args as message.
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.
expression_polynomialset_t< ExpSet > make_expression_polynomialset(const ExpSet &rs)
From a ExpSet to its polynomialset.
VCSN_RAT_VISIT(ldivide, e)
typename super_t::tuple_t tuple_t
labelset_t ls_
Manipulate the labels.
std::map< expression_t, expression_t > names_
A table from the expression to the naming expression.
VCSN_RAT_VISIT(rweight, e)
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.
expansion_t work_(const tuple_t &v, detail::index_sequence< I... >)
value_t & lweight_here(const weight_t &w, value_t &res) const
Inplace left-multiplication by w of res.
void add_here(value_t &lhs, const value_t &rhs) const
In place addition.
expressionset_t rs_
Manipulate the expressions.
VCSN_RAT_VISIT(shuffle, e)
d(E:F) = d(E):F + E:d(F) dᵗ(E:F) = dᵗ(E):Fᵗ + Eᵗ:dᵗ(F)
to_expansion_visitor(const expressionset_t &rs)
void visit(const tuple_t &v, std::true_type) override
typename polynomialset_t::value_t polynomial_t
expansion_t operator()(const tuple_t &v)
#define BUILTIN_UNREACHABLE()
Indentation relative functions.
std::ostream & print(const value_t &v, std::ostream &o=std::cout, format fmt={}) const
Print this expansion.
expansion_t operator()(const tuple_t &)
std::ostream & decendl(std::ostream &o)
Decrement the indentation, print an end of line, and set the indentation.
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.
expansionset_t xs_
Manipulate the expansions.
value_t zero() const
The zero.
An inner node implementing a weight.
Request the unordered_map implementation.