1 #ifndef VCSN_ALGOS_TO_EXPANSION_HH
2 # define VCSN_ALGOS_TO_EXPANSION_HH
22 # define DEBUG_IFELSE(Then, Else) Then
24 # define DEBUG_IFELSE(Then, Else) Else
27 # define DEBUG_IF(Then) DEBUG_IFELSE(Then,)
39 template <
typename RatExpSet>
41 :
public RatExpSet::const_visitor
48 using ratexp_t =
typename ratexpset_t::value_t;
50 using weight_t =
typename weightset_t::value_t;
56 using super_t =
typename ratexpset_t::const_visitor;
58 constexpr
static const char*
me() {
return "to_expansion"; }
83 auto insert = cache_.emplace(e,
es_.
zero());
84 auto& res = insert.first->second;
92 rs_.print(e, std::cerr) <<
" => ";
99 rs_.print(e, std::cerr) <<
" -> ";
106 std::swap(res,
res_);
108 std::swap(res,
res_);
110 rs_.print(e, std::cerr) <<
" -> ";
128 o <<
" (transposed)";
146 ?
ls_.transpose(e.value())
153 for (
const auto& v: e)
160 for (
size_t i = 0,
size = e.size(); i <
size; ++i)
161 if (
ws_.is_zero(
res_.constant))
171 ?
rs_.transposition(
prod_(e.begin(),
172 std::next(e.begin(), size-i)))
173 :
prod_(std::next(e.begin(), i), std::end(e));
182 r =
rs_.transposition(
r);
186 for (
const auto& p: rhs.polynomials)
189 res_.constant =
ws_.mul(
res_.constant, rhs.constant);
196 prod_(
typename prod_t::iterator begin,
197 typename prod_t::iterator end)
const
199 using ratexps_t =
typename prod_t::values_t;
202 else if (std::next(begin, 1) == end)
205 return std::make_shared<prod_t>(ratexps_t{begin, end});
210 return rs_.labelset()->one();
215 raise(
me(),
": quotient requires a labelset with a neutral");
225 if (
auto c = std::dynamic_pointer_cast<const transposition_t>(r))
227 if (
auto s = std::dynamic_pointer_cast<const star_t>(c->sub()))
228 return rs_.transposition(s->sub());
230 else if (
auto s = std::dynamic_pointer_cast<const star_t>(r))
237 assert(e.size() == 2);
239 std::cerr <<
"Start: ";
240 rs_.print(e.shared_from_this, std::cerr()) <<
" =>\n";
249 std::cerr <<
"Lhs: ";
print_(lhs, std::cerr) <<
'\n';
250 std::cerr <<
"Rhs: ";
print_(rhs, std::cerr) <<
'\n';
254 if (!
ws_.is_zero(lhs.constant))
265 auto one =
one_(std::integral_constant<
bool, context_t::has_one()>());
266 for (
const auto& p:
zip_maps(lhs.polynomials, rhs.polynomials))
267 for (
const auto& lm: std::get<0>(p.second))
268 for (
const auto& rm: std::get<1>(p.second))
273 rs_.transposition(
rs_.ldiv(lm.first, rm.first)),
274 ws_.transpose(
ws_.ldiv(lm.second, rm.second)));
277 rs_.ldiv(lm.first, rm.first),
278 ws_.ldiv(lm.second, rm.second));
285 for (
const auto&
r: e.tail())
296 for (
const auto& rhs: e)
303 res.constant =
ws_.mul(lhs.constant, r.constant);
307 for (
const auto& p: lhs.polynomials)
308 for (
const auto& m: p.second)
309 res.polynomials[p.first].emplace(
rs_.shuffle(m.first, rhs),
312 for (
const auto& p: r.polynomials)
313 for (
const auto& m: p.second)
315 rs_.shuffle(prev, m.first), m.second);
317 prev =
rs_.shuffle(prev, rhs);
325 visit_complement<context_t::labelset_t::is_free()>(e);
329 template <
bool IsFree>
330 typename std::enable_if<!IsFree, void>::type
333 raise(
me(),
": cannot handle complement without generators");
337 template <
bool IsFree>
338 typename std::enable_if<IsFree, void>::type
342 res_.constant =
ws_.is_zero(res.constant) ?
ws_.one() :
ws_.zero();
345 for (
auto l:
rs_.labelset()->genset())
347 (
res_.polynomials[l],
348 polynomial_t{{rs_.complement(es_.as_ratexp(res.polynomials[l])),
355 transposed_ = !transposed_;
356 e.sub()->accept(*
this);
357 transposed_ = !transposed_;
363 res_.constant = ws_.star(res.constant);
364 auto f = e.shared_from_this();
367 res_.constant = ws_.transpose(res_.constant);
368 f = rs_.transposition(f);
371 for (
const auto& p: res.polynomials)
372 res_.polynomials[p.first]
373 = ps_.lmul(res_.constant,
374 ps_.rmul(p.second, f));
383 ? es_.rmul(
r, ws_.transpose(l))
384 : es_.lmul_here(l,
r);
393 ? es_.lmul_here(ws_.transpose(r), l)
409 bool transposed_ =
false;
417 template <
typename RatExpSet>
420 to_expansion(
const RatExpSet& rs,
const typename RatExpSet::value_t& e)
431 template <
typename RatExpSet>
435 const auto& e = exp->as<RatExpSet>();
436 const auto& rs = e.ratexpset();
439 to_expansion<RatExpSet>(rs, e.ratexp()));
448 #endif // !VCSN_ALGOS_TO_EXPANSION_HH
Linear combination of labels: map labels to weights.
value_t & add_here(value_t &v, const value_t &p) const
v += p.
An inner node with multiple children.
std::ostream & iendl(std::ostream &o)
Print an end of line, then set the indentation.
expansion make_expansion(const ExpansionSet &ps, const typename ExpansionSet::value_t &expansion)
typename ratexpset_t::value_t ratexp_t
context_t_of< ratexpset_t > context_t
expansion_t operator()(const ratexp_t &v)
value_t & rmul_here(value_t &res, const ratexp_t &rhs) const
In place right multiplication by a ratexp.
ratexp_polynomialset_t< RatExpSet > make_ratexp_polynomialset(const RatExpSet &rs)
From a RatExpSet to its polynomialset.
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Indentation relative functions.
VCSN_RAT_VISIT(shuffle, e)
VCSN_RAT_VISIT(lweight, e)
VCSN_RAT_VISIT(rweight, e)
VCSN_RAT_VISIT(conjunction, e)
ratexpset_t rs_
Manipulate the ratexps.
label_t one_(std::false_type)
ratexp_t prod_(typename prod_t::iterator begin, typename prod_t::iterator end) const
Build a product for these expressions.
std::ostream & incendl(std::ostream &o)
Increment the indentation, print an end of line, and set the indentation.
rat::expansionset< RatExpSet >::value_t to_expansion(const RatExpSet &rs, const typename RatExpSet::value_t &e)
First order expansion.
typename expansionset_t::polys_t polys_t
value_t conjunction(value_t l, value_t r) const
The conjunction of l and r.
VCSN_RAT_VISIT(complement, e)
weightset_t_of< ratexpset_t > weightset_t
std::shared_ptr< detail::ratexp_base > ratexp
value_t lmul(const weight_t &w, const value_t &v) const
Left exterior product.
value_t & normalize(value_t &res) const
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
static constexpr const char * me()
void add_here(value_t &lhs, const value_t &rhs) const
In place addition.
#define REGISTER_DECLARE(Name, Signature)
VCSN_RAT_VISIT(transposition, e)
to_expansion_visitor(const ratexpset_t &rs)
value_t & ldiv_here(const weight_t &w, value_t &res) const
Inplace left-division by w of res.
std::shared_ptr< const detail::expansion_base > expansion
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
polynomialset_t ps_
Manipulate the polynomials of ratexps.
std::ostream & decendl(std::ostream &o)
Decrement the indentation, print an end of line, and set the indentation.
std::enable_if< IsFree, void >::type visit_complement(const complement_t &e)
Complement on a free labelset.
polynomial_t to_expansion_as_polynomial(const ratexp_t &e)
std::map< label_t, polynomial_t, vcsn::less< labelset_t >> polys_t
labelset_t ls_
Manipulate the labels.
std::ostream & print_(const expansion_t &v, std::ostream &o) const
Print an expansion.
typename ratexpset_t::const_visitor super_t
typename expansionset_t::value_t expansion_t
value_t atom(const label_t &l) const
A single label.
labelset_t_of< context_t > labelset_t
expansion to_expansion(const ratexp &exp)
Bridge.
Provide a variadic mul on top of a binary mul(), and one().
polynomial_t as_polynomial(const value_t &v) const
Convert an expansion to a polynomial.
An inner node implementing a weight.
std::map< label_t, weight_t, vcsn::less< labelset_t >> value_t
std::enable_if<!IsFree, void >::type visit_complement(const complement_t &)
Cannot complement on a non-free labelset.
bool transposed_
Whether to work transposed.
expansionset_t es_
Manipulate the expansions.
typename weightset_t::value_t weight_t
value_t zero() const
The zero.
zipped_maps< Dereference, Maps...> zip_maps(Maps &&...maps)
ratexp_t star_child(const ratexp_t r)
If r is e*, return e.
label_t_of< context_t > label_t
value_t one() const
The one.
std::ostream & print(const value_t &v, std::ostream &o, symbol format=symbol{"text"}) const
Print a first order development.
This is useful to make hashes with labels or weights as keys without using non-default constructors; ...
typename polynomialset_t::value_t polynomial_t
expansion_t to_expansion(const ratexp_t &e)
label_t one_(std::true_type)
expansion_t res_
The result.
weightset_t ws_
Manipulate the weights.
This is useful to make hashes with labels or weights as keys without using non-default constructors; ...