9 #include <boost/optional.hpp> 10 #include <boost/range/algorithm/equal.hpp> 11 #include <boost/range/algorithm/find_if.hpp> 12 #include <boost/range/algorithm/lexicographical_compare.hpp> 40 template <
typename LabelSet>
42 = decltype(std::declval<LabelSet>().zero());
45 template <
typename LabelSet>
48 template <
typename LabelSet>
49 auto label_is_zero(
const LabelSet& ls,
const typename LabelSet::value_t& l)
51 return detail::static_if<has_zero_mem_fn<LabelSet>{}>
52 ([](
const auto& ls,
const auto& l){
return ls.is_zero(l);},
53 [](
const auto&,
const auto&) {
return false; })
61 template <
typename WeightSet>
71 template <
typename Context, wet_kind_t Kind>
78 template <
typename Context, wet_kind_t Kind>
90 using label_t =
typename labelset_t::value_t;
114 const self_t&
self()
const {
return static_cast<const self_t&
>(*this); }
130 return weightset_t::has_lightening_weights();
152 assert(!weightset()->is_zero(w));
161 if (weightset()->is_zero(w))
162 return del_weight(v, l);
164 return new_weight(v, l, w);
172 return weightset()->zero();
206 auto w2 = weightset()->add(
weight_of(*i), k);
207 if (weightset()->is_zero(w2))
224 template <wet_kind_t WetType,
typename WS>
230 for (
const auto& m:
r)
236 template <wet_kind_t WetType,
typename WS>
240 && std::is_same<WS, b>::value),
248 template <wet_kind_t WetType,
typename WS>
252 && std::is_same<WS, f2>::value),
262 return add_here_impl_<value_t::kind, weightset_t>(l,
r);
286 raise(*
this,
": sub_here: invalid arguments: ",
294 if (weightset()->is_zero(w2))
308 for (
const auto& rm: r)
328 template <wet_kind_t WetType>
335 for (
const auto& lm: l)
336 for (
const auto& rm:
r)
345 template <wet_kind_t WetType>
351 return l.set() &
r.set();
359 return mul_impl_<value_t::kind>(l,
r);
368 for (
const auto& m: p)
382 template <
typename Ctx>
383 std::enable_if_t<Ctx::is_lar, value_t>
387 for (
const auto& lm: l)
388 for (
const auto& rm: r)
397 template <
typename Ctx>
398 std::enable_if_t<!Ctx::is_lar, value_t>
402 for (
const auto& p: zip_maps<vcsn::as_tuple>(l, r))
405 weightset()->mul(
weight_of(std::get<0>(p)),
413 return conjunction_impl_<context_t>(l,
r);
422 for (
const auto& lm: l)
423 for (
const auto& rm: r)
432 template <wet_kind_t WetType = value_t::kind>
438 auto res = weightset()->zero();
439 for (
const auto& p: zip_maps<vcsn::as_tuple>(l,
r))
440 res = weightset()->add(
res,
441 weightset()->mul(
weight_of(std::get<0>(p)),
448 template <wet_kind_t WetType = value_t::kind,
typename WS = weightset_t>
452 && std::is_same<WS, b>::value),
455 return l.set().intersects(
r.set());
460 template <wet_kind_t WetType = value_t::kind,
typename WS = weightset_t>
464 && std::is_same<WS, f2>::value),
467 return (l.set() &
r.set()).count() % 2;
474 for (
const auto& m: v)
490 auto i = v.find(labelset()->one());
492 return {{i->first, weightset()->star(i->second)}};
502 if (weightset()->is_one(w))
504 else if (!weightset()->is_zero(w))
505 for (
const auto& m: v)
515 for (
const auto& m: v)
527 for (
const auto& m: v)
535 template <
typename Ctx>
542 template <
typename Ctx>
551 if (weightset()->is_one(w))
553 else if (!weightset()->is_zero(w))
554 for (
const auto& m:
v)
558 static_if<has_rweight_fn<context_t>{}>
559 ([
this, &
res] (
const auto& ls,
const auto& m,
const auto& w)
565 [
this, &
res] (
const auto&,
const auto& m,
const auto& w)
580 for (
const auto& lhs: v)
582 labelset()->mul(
label_of(lhs), rhs),
592 for (
const auto& lhs: l)
602 raise(*
this,
": rdivide: not implemented (",
619 for (
const auto& m: r)
626 template <
typename Ctx = context_t>
627 std::enable_if_t<Ctx::is_lar, value_t&>
630 for (
const auto& lm: l)
631 for (
const auto& rm: r)
647 template <
typename Ctx = context_t>
648 std::enable_if_t<!Ctx::is_lar, value_t&>
652 raise(*
this,
": ldivide: division by zero");
656 while (!is_zero(remainder))
660 remainder = sub(remainder, mul(l,
factor));
663 if (!is_zero(remainder))
664 raise(*
this,
": ldivide: not implemented (",
675 add_ldivide_here(
res, l, r);
683 if (!weightset()->is_one(w))
693 if (!weightset()->is_one(w))
711 auto i = begin(lhs), i_end = end(lhs);
712 auto j = begin(rhs), j_end = end(rhs);
714 i != i_end && j != j_end
715 && labelset()->equal(i->first, j->first);
717 res.set(i->first, weightset()->
lgcd(i->second, j->second));
720 if (i != i_end || j != j_end)
730 template <
typename WeightSet,
typename Dummy =
void>
741 template <
typename Dummy>
748 for (
const auto& m: v)
757 template <
typename Ctx, wet_kind_t Knd,
typename Dummy>
765 for (
const auto& p: v)
778 return weightset()->zero();
794 if (!weightset()->is_zero(
res))
795 ldivide_here(
res, v);
814 template <
typename... Polys>
823 this->labelset()->
tuple(ms.first...),
824 this->weightset()->mul(ms.second...));
826 std::forward<Polys>(vs)...);
831 template <
size_t Tape>
838 template <
size_t Tape>
841 auto ps = project<Tape>();
842 auto res = ps.zero();
843 for (
const auto& m: v)
845 labelset()->
template project<Tape>(
label_of(m)),
855 template <
typename Ctx>
863 template <
typename Ctx>
869 template <
typename Ctx1,
typename Ctx2>
875 -> std::enable_if_t<are_composable<Ctx1, Ctx2>{},
value_t>
877 const auto& ls = *labelset();
878 const auto& ls1 = *ps1.labelset();
879 const auto& ls2 = *ps2.labelset();
883 constexpr
auto in = 0;
885 const auto& midls = ls1.template set<out>();
887 for (
const auto& m1: p1)
888 for (
const auto& m2: p2)
889 if (midls.equal(std::get<out>(
label_of(m1)),
900 template <
typename Ctx = context_t>
903 -> std::enable_if_t<has_compose_fn<Ctx>{},
value_t>
906 for (
const auto& lm: l)
907 for (
const auto& rm:
r)
925 for (
const auto& m: v)
926 res = labelset()->add(res,
937 return {to_label(v), w};
945 return {{labelset()->complement(to_label(
normalize(v))),
946 weightset()->one()}};
961 template <wet_kind_t WetType>
968 return boost::equal(l, r, monomial_equal);
971 template <wet_kind_t WetType>
978 return l.set() == r.set();
986 return equal_impl_<value_t::kind>(l,
r);
1011 return weightset_t::is_one(i->second);
1030 return weightset_t::star_status();
1043 template <
typename WS>
1045 conv(
const WS& ws,
const typename WS::value_t&
v)
const 1047 return {{labelset()->one(), weightset()->conv(ws, v)}};
1051 template <
typename C, wet_kind_t K>
1056 const typename C::labelset_t& sls = *sps.labelset();
1057 const typename C::weightset_t& sws = *sps.weightset();
1061 for (
const auto& m: v)
1081 template <wet_kind_t WetType>
1091 template <wet_kind_t WetType>
1098 return l.set() - r.set();
1105 return compare_impl_<value_t::kind>(l,
r);
1124 template <wet_kind_t WetType>
1131 return boost::range::lexicographical_compare(l, r, monomial_less);
1134 template <wet_kind_t WetType>
1141 return l.set() < r.set();
1148 return less_impl_<value_t::kind>(l,
r);
1161 auto label_transpose
1162 = static_if<context_t::is_lar>
1163 ([](
const auto& ls,
const auto& l) {
return ls.transposition(l); },
1164 [](
const auto& ls,
const auto& l) {
return ls.transpose(l); });
1165 for (
const auto& i: v)
1166 res.set(label_transpose(*labelset(),
label_of(i)),
1183 template <wet_kind_t WetType>
1191 for (
const auto& m: p)
1196 template <wet_kind_t WetType>
1209 return hash_impl_<value_t::kind>(
v);
1217 eat(is,
"polynomialset<");
1218 auto ctx = Context::make(is);
1229 o <<
"\\mathsf{Poly}[";
1234 o <<
"polynomialset<";
1241 context().print_set(o, fmt); 1256 boost::optional<label_t> 1257 conv_label(std::istream& i, bool weighted, const char sep = '+
') const 1259 const auto peek = i.peek(); 1260 assert(peek != '[
'); 1264 if (i.peek() == 'z
') 1273 // The label is not \z. 1274 // Check if there is a label that comes. Or rather, check if 1275 // there is something else than EOF or the separator, in which 1276 // case it must be a label. 1278 if (peek == EOF || peek == sep || isspace(peek)) 1280 // There is no label. This counts as '$
', the special 1283 // Indeed, that's how we represent the initial and
final 1292 *
this,
": conv: invalid monomial: ",
1294 " (did you mean \\e or \\z?)");
1295 res = labelset()->special();
1299 const auto pos = i.tellg();
1300 res = labelset()->conv(i);
1310 require(i.peek() == EOF || pos < i.tellg(),
1311 *
this,
": invalid implicit empty word before: ", i);
1320 if (i.peek() == langle)
1331 return weightset()->one();
1340 boost::optional<monomial_t>
1343 #define SKIP_SPACES() \ 1344 while (isspace(i.peek())) \ 1349 if (i.peek() == EOF)
1353 bool weighted = i.peek() == langle;
1358 auto l = conv_label(i, weighted, sep);
1359 require(l, *
this,
": \\z is invalid for monomials");
1372 conv(std::istream& i,
const char sep =
'+')
const 1375 #define SKIP_SPACES() \ 1376 while (isspace(i.peek())) \ 1383 const bool weighted = i.peek() == langle;
1389 if (i.peek() ==
'[')
1390 labelset()->convs(i, [
this, &
res, &w](
const label_t& l)
1394 else if (
auto l = conv_label(i, weighted, sep))
1396 require(l, *
this,
": \\z is invalid for monomials");
1402 if (i.peek() == sep)
1418 static bool parens = getenv(
"VCSN_PARENS");
1422 labelset()->print(
label_of(m), out, fmt.for_labels());
1437 const std::string& sep =
" + ")
const 1462 static bool parens = getenv(
"VCSN_PARENS");
1463 if (parens || weightset()->show_one() || !weightset()->is_one(w))
1468 weightset()->print(w, out, fmt.for_weights());
1480 const std::string& sep)
const 1483 for (
const auto& m: v)
1497 const std::string& sep)
const 1504 using labels_t = std::vector<label_t>;
1510 for (
const auto& m: v)
1511 if (!labelset()->is_one(
label_of(m)))
1516 std::pair<weight_t, labels_t>,
1518 for (
const auto& p: per_weight)
1520 if (p.second.size() < 3)
1521 for (
auto l: p.second)
1522 per_label[l] = std::make_pair(p.first, labels_t{l});
1536 for (
const auto& p: per_label)
1543 print_weight_(p.second.first, out, fmt);
1545 if (1 < p.second.second.size())
1558 template <
typename Ctx = context_t>
1563 const std::string& sep =
" + ")
const 1565 return print_without_classes_(v, out, fmt, sep);
1570 template <
typename Ctx = context_t>
1575 const std::string& sep =
" + ")
const 1578 if (sep ==
" + " || v.size() <= 2)
1579 return print_without_classes_(v, out, fmt, sep);
1581 return print_with_classes_(v, out, fmt, sep);
1589 constexpr
static char langle =
'<';
1591 constexpr
static char rangle =
'>';
1594 template <
typename Context,
1595 wet_kind_t Kind = detail::wet_kind<labelset_t_of<Context>,
1613 return {
vcsn::join(ps1.context(), ps2.context())};
1626 return {*ps1.labelset(),
vcsn::join(*ps1.weightset(), ws2)};
static ATTRIBUTE_PURE auto less_impl_(const value_t &l, const value_t &r) -> std::enable_if_t< WetType==wet_kind_t::bitset, bool >
Aut transpose(const transpose_automaton< Aut > &aut)
The transpose of a transpose automaton is the original automaton.
std::enable_if_t<!Ctx::is_lar, value_t & > add_ldivide_here(value_t &res, const value_t &l, const value_t &r) const
The left-division of polynomials l and r: res += l \ r.
value_t conv(const WS &ws, const typename WS::value_t &v) const
FIXME: use enable_if to prevent this from being instantiated when WS is a polynomialset.
Print as a parsable type string.
weightset_mixin< detail::r_impl > r
value_t star(const value_t &v) const
The star of polynomial v.
decltype(join(std::declval< ValueSets >()...)) join_t
The type of the join of the ValueSets.
std::enable_if_t<!labelset_t_of< Ctx >::is_letterized(), std::ostream & > print_(const value_t &v, std::ostream &out, format fmt={}, const std::string &sep=" + ") const
Print a non-null value for a non letterized labelset.
typename detail::weightset_t_of_impl< base_t< ValueSet > >::type weightset_t_of
format for_labels() const
A copy of this format, but to print labels.
static type join(const polynomialset< Ctx1, Kind1 > &ps1, const WS2 &ws2)
value_t rmul_label(const value_t &v, const label_t &rhs) const
Right product.
int lexicographical_cmp(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Compare comp)
Lexicographical three-way comparison between two ranges.
static constexpr bool show_one()
Request the map implementation.
static ATTRIBUTE_PURE auto hash_impl_(const value_t &p) -> std::enable_if_t< WetType !=wet_kind_t::bitset, size_t >
In the general case, normalize by the first (non null) weight.
const labelset_ptr & labelset() const
value_t sub(const value_t &l, const value_t &r) const
The subtraction of polynomials l and r.
value_t conjunction(const value_t &l, const value_t &r) const
monomial_t determinize(value_t v) const
"Determinize" this polynomial: turn into a monomial.
void clear(value_t &v)
Set to zero.
char eat(std::istream &is, char c)
Check lookahead character and advance.
value_t rdivide(const value_t &l, const value_t &r) const
value_t lgcd(const value_t &lhs, const value_t &rhs) const
LGCD between two polynomials.
const weight_t get_weight(const value_t &v, const label_t &l) const ATTRIBUTE_PURE
value_t & new_weight(value_t &v, const label_t &l, const weight_t w) const
Set the monomial of l in v to weight w.
std::enable_if_t< labelset_t_of< Ctx >::is_letterized(), std::ostream & > print_(const value_t &v, std::ostream &out, format fmt={}, const std::string &sep=" + ") const
Print a non-null value for a letterized labelset (e.g., letterset or nullableset. ...
static ATTRIBUTE_PURE size_t hash(const value_t &v)
std::ostream & print(const value_t &v, std::ostream &out=std::cout, format fmt={}, const std::string &sep=" + ") const
Print a value (a polynomial).
ValueSet::value_t lgcd(const ValueSet &vs, const typename ValueSet::value_t &lhs, const typename ValueSet::value_t &rhs)
Left-division of values.
value_t conv(const polynomialset< C, K > &sps, const typename polynomialset< C, K >::value_t &v) const
Convert from another polynomialset to type_t.
std::ostream & print_set(std::ostream &o, format fmt={}) const
static const monomial_t & monomial_one()
The unit monomial.
constant< type_t::one, Context > one
polynomialset_impl(const context_t &ctx)
Aut1 & add_here(Aut1 &res, const Aut2 &b, standard_tag)
Merge transitions of b into those of res.
std::enable_if_t<!Ctx::is_lar, value_t > conjunction_impl_(const value_t &l, const value_t &r) const
The conjunction of polynomials l and r.
auto mul_impl_(const value_t &l, const value_t &r) const -> std::enable_if_t< WetType==wet_kind_t::bitset, value_t >
The product of polynomials l and r.
wet_kind_t
Different implementations of wets.
polynomialset< Context, Kind > make_polynomialset(const Context &context)
static ATTRIBUTE_PURE bool monomial_equal(const monomial_t &lhs, const monomial_t &rhs)
decltype(std::declval< labelset_t_of< Ctx > >() .rweight(std::declval< label_t_of< Ctx > >(), std::declval< weight_t_of< Ctx > >())) rweight_t
Detect whether the labelset features rweight.
std::ostream & str_escape(std::ostream &os, const std::string &str, const char *special=nullptr)
Output a string, escaping special characters.
static ATTRIBUTE_PURE bool less(const value_t &l, const value_t &r)
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
value_t complement(const value_t &v) const
Complement this polynomial.
value_t value(const label_t &l, const weight_t w) const
Create a polynomial with a single value.
value_t ldivide(const monomial_t &l, const value_t &r) const
Left division by a monomial: l \ r.
value_t mul(const value_t &l, const monomial_t &rhs) const
Right product by a monomial.
static constexpr bool has_lightening_weights()
static ATTRIBUTE_PURE auto equal_impl_(const value_t &l, const value_t &r) -> std::enable_if_t< WetType==wet_kind_t::bitset, bool >
auto rdivide(const Aut1 &a1, const Aut2 &a2)
Compute the right quotient.
value_t & sub_here(value_t &v, const monomial_t &m) const
v -= m.
auto conv(const ValueSet &vs, const std::string &str, Args &&... args) -> decltype(vs.conv(std::declval< std::istream &>(), std::forward< Args >(args)...))
Parse str via vs.conv.
std::enable_if_t< Ctx::is_lar, value_t & > add_ldivide_here(value_t &res, const value_t &l, const value_t &r) const
The left-division of polynomials l and r: res += l \ r.
value_t lweight(const weight_t w, const value_t &v) const
Left exterior product.
auto tuple(const Auts &... as)
Build the (accessible part of the) tuple.
static self_t make(std::istream &is)
Build from the description in is.
value_t ldivide(const value_t &l, const value_t &r) const
Left division of two polynomials: l \ r.
static bool is_one(const value_t &v) ATTRIBUTE_PURE
Whether is the unit polynomial.
static ATTRIBUTE_PURE auto equal_impl_(const value_t &l, const value_t &r) -> std::enable_if_t< WetType !=wet_kind_t::bitset, bool >
This is useful to make hashes with labels or weights as keys without using non-default constructors; ...
auto label_is_zero(const LabelSet &ls, const typename LabelSet::value_t &l)
value_t conv(std::istream &i, const char sep='+') const
Read a polynomial from a stream.
auto project() const
The polynomialset for tape Tape.
Print as rich UTF-8 text, escaped.
An input/output format for valuesets.
Provide a variadic mul on top of a binary mul(), and one().
const value_t & zero() const
decltype(std::declval< labelset_t_of< Ctx > >() .compose(std::declval< label_t_of< Ctx > >(), std::declval< label_t_of< Ctx > >())) compose_t
Detect whether the labelset features a binary compose.
bool is_zero(const value_t &v) const
ps_t::value_t operator()(const value_t &v) const
value_t & set_weight(value_t &v, const label_t &l, const weight_t w) const
Set the monomial of l in v to weight w.
static ATTRIBUTE_PURE auto compare_impl_(const value_t &l, const value_t &r) -> std::enable_if_t< WetType !=wet_kind_t::bitset, int >
auto rweight(const value_t &v, const weight_t w) const -> value_t
Right exterior product.
auto mul(const value_t &l, const value_t &r) const -> value_t
The product of polynomials l and r.
value_t & add_here(value_t &v, const label_t &l, const weight_t k) const
v += <k>l.
auto join(const ValueSet &vs) -> ValueSet
The join of a single valueset.
labelset_t_of< context_t > labelset_t
auto add_here_impl_(value_t &l, const value_t &r) const -> std::enable_if_t<(WetType==wet_kind_t::bitset &&std::is_same< WS, f2 >::value), value_t &>
v += p, F2 and bitsets.
A structure that implements the computation of join(V1, V2).
wet< label_t_of< Context >, weight_t_of< Context >, Kind, vcsn::less< labelset_t_of< Context > >, vcsn::hash< labelset_t_of< Context > >, vcsn::equal_to< labelset_t_of< Context > >> wet_of
The corresponding wet for a LabelSet -> WeightSet context.
auto hash_value(const T &v) -> decltype(std::hash< T >
Following the naming convention of Boost.
typename detail::labelset_t_of_impl< base_t< ValueSet > >::type labelset_t_of
typename value_t::value_type monomial_t
A pair <label, weight>.
value_t mul(const monomial_t &lhs, const value_t &v) const
Left product by a monomial.
auto in(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions arriving to state s.
typename context_t::weightset_ptr weightset_ptr
weightset_t_of< context_t > weightset_t
Request the bitset implementation (bool weights).
value_t add(value_t res, const value_t &r) const
The sum of polynomials l and r.
for(const auto &lm:l) for(const auto &rm return res
std::ostream & print(const std::tuple< Args... > &args, std::ostream &o)
value_t lmul_label(const label_t &lhs, const value_t &v) const
Left product by a label.
auto conjunction(const Aut &a, const Auts &... as)
Build the (accessible part of the) conjunction.
static type join(const polynomialset< Ctx1, Kind1 > &ps1, const polynomialset< Ctx2, Kind2 > &ps2)
typename detail::label_t_of_impl< base_t< ValueSet > >::type label_t_of
value_t infiltrate(const value_t &l, const value_t &r) const
The infiltration of polynomials l and r.
static ATTRIBUTE_PURE size_t hash(const monomial_t &m, size_t res=0)
auto norm(const value_t &v) const -> weight_t
The norm: the weight with which we should divide a polynomial to normalize it.
std::ostream & print(const monomial_t &m, std::ostream &out=std::cout, format fmt={}) const
Print a monomial.
auto mul_impl_(const value_t &l, const value_t &r) const -> std::enable_if_t< WetType !=wet_kind_t::bitset, value_t >
The product of polynomials l and r.
Container::value_type front(const Container &container)
The first member of this Container.
std::enable_if_t< Ctx::is_lar, value_t > conjunction_impl_(const value_t &l, const value_t &r) const
The conjunction of polynomials l and r.
value_t & del_weight(value_t &v, const label_t &l) const
Remove the monomial of l in v.
std::ostream & print_weight_(const weight_t w, std::ostream &out, format fmt) const
Print a weight.
static constexpr bool is_commutative()
void weight_set(welement< Label, Weight > &m, const Weight &w)
Set the weight of a welement.
static symbol sname()
The static name.
static ATTRIBUTE_PURE bool equal(const value_t &l, const value_t &r)
Whether l == r.
auto scalar_product(const value_t &l, const value_t &r) const -> std::enable_if_t<(WetType==wet_kind_t::bitset &&std::is_same< WS, f2 >::value), weight_t >
The sum of the weights of the common labels.
static ATTRIBUTE_PURE auto compare_impl_(const value_t &l, const value_t &r) -> std::enable_if_t< WetType==wet_kind_t::bitset, int >
typename labelset_t::value_t label_t
Polynomials over labels.
std::ostream & print_without_classes_(const value_t &v, std::ostream &out, format fmt, const std::string &sep) const
Print a polynomial value without classes.
auto add_here_impl_(value_t &l, const value_t &r) const -> std::enable_if_t<(WetType==wet_kind_t::bitset &&std::is_same< WS, b >::value), value_t &>
v += p, B and bitsets.
z::value_t operator()(const value_t &v) const
auto factor(const Aut &aut) -> decltype(::vcsn::copy(aut))
typename context_t::labelset_ptr labelset_ptr
Linear combination of labels: map labels to weights.
ATTRIBUTE_NORETURN void raise_not_starrable(const WeightSet &ws, const typename WeightSet::value_t &w)
This value is not starrable.
auto weight_of(const welement< Label, Weight > &m) -> decltype(m.weight())
The weight of a welement.
auto mul(const value_t &p, const label_t &l, const weight_t w) const -> value_t
The product of polynomials l and r.
static const value_t & one()
The unit polynomial.
auto scalar_product(const value_t &l, const value_t &r) const -> std::enable_if_t<(WetType==wet_kind_t::bitset &&std::is_same< WS, b >::value), weight_t >
The sum of the weights of the common labels.
static ATTRIBUTE_PURE int monomial_compare(const monomial_t &lhs, const monomial_t &rhs)
WeightSet::value_t operator()(const value_t &v) const
std::ostream & print_with_classes_(const value_t &v, std::ostream &out, format fmt, const std::string &sep) const
Print a polynomial value with classes.
auto project(const value_t &v) const
Extract a single tape.
value_t & ldivide_here(const weight_t w, value_t &v) const
Left exterior division.
auto add_here_impl_(value_t &l, const value_t &r) const -> std::enable_if_t< WetType !=wet_kind_t::bitset, value_t &>
v += p, default case.
auto tuple(Polys &&... vs) const -> value_t
Build a tuple of polynomials: (e.E+f.F)|(g.G+h.H) => eg.
auto label_of(const welement< Label, Weight > &m) -> decltype(m.label())
The label of a welement.
label_t to_label(const value_t &v) const
Convert into a label.
boost::optional< monomial_t > conv_monomial(std::istream &i, const char sep='+') const
Read a monomial from a stream.
auto compose(const value_t &l, const value_t &r) const -> std::enable_if_t< has_compose_fn< Ctx >
The composition of polynomials l and r when the context features compose.
std::ostream & print_set(std::ostream &o, format fmt={}) const
static ATTRIBUTE_PURE auto hash_impl_(const value_t &p) -> std::enable_if_t< WetType==wet_kind_t::bitset, size_t >
std::ostream & print_label_class(const LabelSet &ls, const std::vector< typename LabelSet::value_t > &letters, std::ostream &out, format fmt)
Print a set of labels (letterized) with classes.
std::string bracketed(std::istream &i, char lbracket, char rbracket)
Extract the string which is here between lbracket and rbracket.
void hash_combine(std::size_t &seed, const T &v)
Functor to compare Values of ValueSets.
value_t normalize(value_t res) const
Normalized v.
value_t & add_here(value_t &l, const value_t &r) const
value_t & rdivide_here(value_t &v, const weight_t w) const
Right exterior division.
static ATTRIBUTE_PURE int compare(const value_t &l, const value_t &r)
value_t transpose(const value_t &v) const
Transpose the labels and the weights.
void require(Bool b, Args &&... args)
If b is not verified, raise an error with args as message.
value_t abs(const value_t &v) const
Map all weights to their absolute value.
monomial_t ldivide(const monomial_t &l, const monomial_t &r) const
Left division between two mononials: l \ r.
const weightset_ptr & weightset() const
weight_t conv_weight(std::istream &i) const
Read a weight, if there is one, bracketed.
typename detail::weight_t_of_impl< base_t< ValueSet > >::type weight_t_of
std::string to_string(direction d)
Conversion to string.
monomial_t mul(const monomial_t &l, const monomial_t &r) const
The product of monomials l and r.
void print_(std::ostream &o, const T &arg, long)
Serialize arg into o.
std::enable_if_t<!is_letterized_t< labelset_t_of< Aut > >{}, bool > is_letterized(const Aut &aut)
value_t & add_here(value_t &v, const monomial_t &m) const
v += m.
auto compose(const polynomialset< Ctx1 > &ps1, const typename polynomialset< Ctx1 >::value_t &p1, const polynomialset< Ctx2 > &ps2, const typename polynomialset< Ctx2 >::value_t &p2) const -> std::enable_if_t< are_composable< Ctx1, Ctx2 >
The composition of polynomials l and r when the context is a composable tupleset. ...
static ATTRIBUTE_PURE auto less_impl_(const value_t &l, const value_t &r) -> std::enable_if_t< WetType !=wet_kind_t::bitset, bool >
decltype(std::declval< LabelSet >().zero()) zero_mem_fn_t
The type of the LabelSet::zero() member function.
ExpansionSet::value_t normalize(const ExpansionSet &xs, typename ExpansionSet::value_t x)
Normalize an expansion.
#define VCSN_REQUIRE(Cond,...)
A macro similar to require.
weight_t_of< context_t > weight_t
weight_t normalize_here(value_t &v) const
Normalize v in place: compute the LGCD of the weights, ldivide the monomials with that factor...
for(const auto &m1:p1) for(const auto &m2 return res
int compare(const Lhs &lhs, const Rhs &rhs)
Comparison between lhs and rhs.
void cross(Fun f)
Variadic Cartesian product of containers.
wet_of< context_t, Kind > value_t
static constexpr star_status_t star_status()
static ATTRIBUTE_PURE bool monomial_less(const monomial_t &lhs, const monomial_t &rhs)
auto scalar_product(const value_t &l, const value_t &r) const -> std::enable_if_t< WetType !=wet_kind_t::bitset, weight_t >
The sum of the weights of the common labels.
const context_t & context() const
static value_t conv(self_t, const value_t &v)
Conversion from (this and) other weightsets.
auto out(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions leaving state s.