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>
34 # pragma clang diagnostic push
35 # pragma clang diagnostic ignored "-Wunused-value"
37 template <
typename LabelSet>
38 auto label_is_zero(
const LabelSet& ls,
const typename LabelSet::value_t* l)
39 -> decltype(ls.is_zero(l), bool())
41 return ls.is_zero(*l);
45 # pragma clang diagnostic pop
48 template <
typename LabelSet>
52 template <typename LabelSet>
60 template <
typename WeightSet>
70 template <
typename Context, wet_kind_t Kind>
77 template <
typename Context, wet_kind_t Kind>
89 using label_t =
typename labelset_t::value_t;
113 const self_t&
self()
const {
return static_cast<const self_t&
>(*this); }
129 return weightset_t::has_lightening_weights();
219 template <wet_kind_t WetType,
typename WS>
225 for (
const auto& m:
r)
231 template <wet_kind_t WetType,
typename WS>
235 && std::is_same<WS, b>::value),
243 template <wet_kind_t WetType,
typename WS>
247 && std::is_same<WS, f2>::value),
257 return add_here_impl<value_t::kind, weightset_t>(l,
r);
282 raise(
sname(),
": sub_here: invalid arguments: ",
304 for (
const auto& rm: r)
324 template <wet_kind_t WetType>
331 for (
const auto& lm: l)
332 for (
const auto& rm:
r)
341 template <wet_kind_t WetType>
347 return l.set() &
r.set();
355 return mul_impl<value_t::kind>(l,
r);
364 for (
const auto& m: p)
378 template <
typename Ctx>
379 std::enable_if_t<Ctx::is_lar, value_t>
383 for (
const auto& lm: l)
384 for (
const auto& rm: r)
393 template <
typename Ctx>
394 std::enable_if_t<!Ctx::is_lar, value_t>
398 for (
const auto& p: zip_maps<vcsn::as_tuple>(l, r))
409 return conjunction_impl<context_t>(l,
r);
418 for (
const auto& lm: l)
419 for (
const auto& rm: r)
428 template <wet_kind_t WetType = value_t::kind>
435 for (
const auto& p: zip_maps<vcsn::as_tuple>(l,
r))
444 template <wet_kind_t WetType = value_t::kind,
typename WS = weightset_t>
448 && std::is_same<WS, b>::value),
451 return l.set().intersects(
r.set());
456 template <wet_kind_t WetType = value_t::kind,
typename WS = weightset_t>
460 && std::is_same<WS, f2>::value),
463 return (l.set() &
r.set()).count() % 2;
479 return {{i->first,
weightset()->star(i->second)}};
492 for (
const auto& m: v)
502 for (
const auto& m: v)
514 for (
const auto& m: v)
534 for (
const auto& m: v)
544 for (
const auto& lhs: v)
556 for (
const auto& lhs: l)
566 raise(
sname(),
": rdiv: not implemented (",
582 for (
const auto& m: r)
592 raise(
sname(),
": ldiv: division by zero");
597 std::cerr <<
"ldiv(";
598 print(l, std::cerr) <<
", ";
599 print(r, std::cerr) <<
"\n";
605 std::cerr <<
"factor = ";
print(
factor, std::cerr) <<
"\n";
609 std::cerr <<
"res = ";
print(res, std::cerr) <<
"\n";
614 std::cerr <<
"rem = ";
print(remainder, std::cerr) <<
"\n";
618 std::cerr <<
"ldiv(";
619 print(l, std::cerr) <<
", ";
620 print(r, std::cerr) <<
") = ";
621 print(res, std::cerr) <<
" rem: ";
622 print(remainder, std::cerr) <<
"\n";
625 raise(
sname(),
": ldiv: not implemented (",
663 auto i = begin(lhs), i_end = end(lhs);
664 auto j = begin(rhs), j_end = end(rhs);
666 i != i_end && j != j_end
667 &&
labelset()->equal(i->first, j->first);
672 if (i != i_end || j != j_end)
682 template <
typename WeightSet,
typename Dummy =
void>
693 template <
typename Dummy>
700 for (
const auto& m: v)
709 template <
typename Ctx, wet_kind_t Knd,
typename Dummy>
717 for (
const auto& p: v)
766 template <
typename... Polys>
771 auto res = value_t{};
776 this->weightset()->mul(ms.second...));
778 std::forward<Polys>(vs)...);
783 template <
size_t Tape>
787 auto res =
typename decltype(ps)::
value_t{};
788 for (
const auto& m: v)
804 for (
const auto& m: v)
840 template <wet_kind_t WetType>
850 template <wet_kind_t WetType>
857 return l.set() ==
r.set();
864 return equal_impl<value_t::kind>(l,
r);
889 return weightset_t::is_one(i->second);
908 return weightset_t::star_status();
921 template <
typename WS>
923 conv(
const WS& ws,
const typename WS::value_t&
v)
const
929 template <
typename C, wet_kind_t K>
934 const typename C::labelset_t& sls = *sps.labelset();
935 const typename C::weightset_t& sws = *sps.weightset();
939 for (
const auto& m: v)
960 template <wet_kind_t WetType>
967 return boost::range::lexicographical_compare(l,
r,
monomial_less);
970 template <wet_kind_t WetType>
977 return l.set() <
r.set();
984 return less_impl<value_t::kind>(l,
r);
992 for (
const auto& i: v)
1010 template <wet_kind_t WetType>
1018 for (
const auto& m: p)
1023 template <wet_kind_t WetType>
1036 return hash_impl<value_t::kind>(
v);
1044 eat(is,
"polynomialset<");
1045 auto ctx = Context::make(is);
1056 o <<
"\\mathsf{Poly}[";
1061 o <<
"polynomialset<";
1068 context().print_set(o, fmt);
1083 boost::optional<label_t>
1084 conv_label(std::istream& i, bool weighted, const char sep = '+
') const
1086 int peek = i.peek();
1087 assert(peek != '[
');
1091 if (i.peek() == 'z')
1100 // The label is not \z.
1101 // Check if there is a label that comes. Or rather, check if
1102 // there is something else than EOF or the separator, in which
1103 // case it must be a label.
1105 if (peek == EOF || peek == sep || isspace(peek))
1107 // There is no label. This counts as '$
', the special
1110 // Indeed, that's how we represent the initial and
final
1119 sname(),
": conv: invalid monomial: ",
1121 " (did you mean \\e or \\z?)");
1126 auto pos = i.tellg();
1137 require(i.peek() == EOF || pos < i.tellg(),
1138 "invalid implicit empty word before: ", i);
1167 boost::optional<monomial_t>
1170 #define SKIP_SPACES() \
1171 while (isspace(i.peek())) \
1176 if (i.peek() == EOF)
1180 bool weighted = i.peek() ==
langle;
1186 require(l,
"\\z is invalid for monomials");
1200 conv(std::istream& i,
const char sep =
'+')
const
1203 #define SKIP_SPACES() \
1204 while (isspace(i.peek())) \
1211 bool weighted = i.peek() ==
langle;
1217 if (i.peek() ==
'[')
1222 else if (
auto l =
conv_label(i, weighted, sep))
1224 require(l,
"\\z is invalid for monomials");
1230 if (i.peek() == sep)
1246 static bool parens = getenv(
"VCSN_PARENS");
1265 const std::string& sep =
" + ")
const
1290 static bool parens = getenv(
"VCSN_PARENS");
1296 weightset()->print(w, out, fmt.for_weights());
1308 const std::string& sep)
const
1311 for (
const auto& m: v)
1325 const std::string& sep)
const
1332 using labels_t = std::vector<label_t>;
1338 for (
const auto& m: v)
1344 std::pair<weight_t, labels_t>,
1346 for (
const auto& p: per_weight)
1348 if (p.second.size() < 3)
1349 for (
auto l: p.second)
1350 per_label[l] = std::make_pair(p.first, labels_t{l});
1364 for (
const auto& p: per_label)
1373 if (1 < p.second.second.size())
1386 template <
typename Ctx = context_t>
1391 const std::string& sep =
" + ")
const
1398 template <
typename Ctx = context_t>
1403 const std::string& sep =
" + ")
const
1406 if (sep ==
" + " || v.size() <= 2)
1422 template <
typename Context,
1423 wet_kind_t Kind = detail::wet_kind<labelset_t_of<Context>,
1441 return {
vcsn::join(ps1.context(), ps2.context())};
1454 return {*ps1.labelset(),
vcsn::join(*ps1.weightset(), ws2)};
value_t infiltration(const value_t &l, const value_t &r) const
The infiltration of polynomials l and r.
auto join(const ValueSet &vs) -> ValueSet
The join of a single valueset.
static constexpr bool has_lightening_weights()
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.
Linear combination of labels: map labels to weights.
#define VCSN_REQUIRE(Cond,...)
A macro similar to require.
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.
value_t rdiv(const value_t &l, const value_t &r) const
value_t sub(const value_t &l, const value_t &r) const
The subtraction of polynomials l and r.
static type join(const polynomialset< Ctx1, Kind1 > &ps1, const polynomialset< Ctx2, Kind2 > &ps2)
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 normalize(value_t res) const
Normalized v.
value_t conv(std::istream &i, const char sep= '+') const
Read a polynomial from a stream.
const context_t & context() const
decltype(join(std::declval< ValueSets >()...)) join_t
The type of the join of the ValueSets.
typename value_t::value_type monomial_t
A pair
Print as rich UTF-8 text, escaped.
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 constexpr bool is_commutative()
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 tuple(Polys &&...vs) const -> value_t
Build a tuple of polynomials: (e.E+f.F)|(g.G+h.H) => eg.
weightset_t_of< context_t > weightset_t
void weight_set(welement< Label, Weight > &m, const Weight &w)
Set the weight of a welement.
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
auto hash_value(const T &v) -> decltype(std::hash< T >
Following the naming convention of Boost.
value_t complement(const value_t &v) const
Complement this polynomial.
static constexpr bool show_one()
bool is_zero(const value_t &v) const
value_t & sub_here(value_t &v, const monomial_t &m) const
v -= m.
polynomialset_impl(const context_t &ctx)
void require(Bool b, Args &&...args)
If b is not verified, raise an error with args as message.
const value_t & zero() const
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. ...
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.
std::string to_string(direction d)
Conversion to string.
static symbol sname()
The static name.
value_t & rdiv_here(value_t &v, const weight_t w) const
Right exterior division.
std::ostream & str_escape(std::ostream &os, const std::string &str, const char *special=nullptr)
Output a string, escaping special characters.
polynomialset_impl()=delete
static ATTRIBUTE_PURE bool monomial_less(const monomial_t &lhs, const monomial_t &rhs)
value_t lmul_label(const label_t &lhs, const value_t &v) const
Left product by a label.
typename context_t::labelset_ptr labelset_ptr
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.
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
boost::optional< monomial_t > conv_monomial(std::istream &i, const char sep= '+') const
Read a monomial from a stream.
value_t lmul(const weight_t w, const value_t &v) const
Left exterior product.
weightset_mixin< detail::r_impl > r
An input/output format for valuesets.
value_t & ldiv_here(const weight_t w, value_t &v) const
Left exterior division.
auto factor(const Aut &aut) -> decltype(::vcsn::copy(aut))
char eat(std::istream &is, char c)
Check lookahead character and advance.
Provide a variadic mul on top of a binary mul(), and one().
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.
value_t & add_here(value_t &l, const value_t &r) const
format for_labels() const
A copy of this format, but to print labels.
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 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.
static ATTRIBUTE_PURE size_t hash(const monomial_t &m, size_t res=0)
auto weight_of(const welement< Label, Weight > &m) -> decltype(m.weight())
The weight of a welement.
typename detail::weight_t_of_impl< base_t< ValueSet >>::type weight_t_of
static ATTRIBUTE_PURE bool monomial_equal(const monomial_t &lhs, const monomial_t &rhs)
value_t ldiv(const value_t &l, const value_t &r) const
void cross(Fun f)
Variadic Cartesian product of containers.
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.
wet_of< context_t, Kind > value_t
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, format fmt={}) const
Print a monomial.
static constexpr char langle
Left marker for weight in concrete syntax.
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 k.
static const value_t & one()
The unit polynomial.
static ATTRIBUTE_PURE size_t hash(const value_t &v)
constant< type_t::one, Context > one
value_t add(const value_t &l, const value_t &r) const
The sum of polynomials l and r.
value_t ldiv(const monomial_t &l, const value_t &r) const
Left division by a monomial.
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 out(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions leaving state s.
void hash_combine(std::size_t &seed, const T &v)
A structure that implements the computation of join(V1, V2).
static ATTRIBUTE_PURE auto equal_impl(const value_t &l, const value_t &r) -> std::enable_if_t< WetType!=wet_kind_t::bitset, bool >
static self_t make(std::istream &is)
Build from the description in is.
value_t & add_here(value_t &v, const label_t &l, const weight_t k) const
v += l.
static ATTRIBUTE_PURE auto hash_impl(const value_t &p) -> std::enable_if_t< WetType!=wet_kind_t::bitset, size_t >
monomial_t determinize(value_t v) const
"Determinize" this polynomial: turn into a monomial.
weight_t_of< context_t > weight_t
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
value_t transpose(const value_t &v) const
static type join(const polynomialset< Ctx1, Kind1 > &ps1, const WS2 &ws2)
value_t mul(const monomial_t &lhs, const value_t &v) const
Left product by a monomial.
std::string bracketed(std::istream &i, char lbracket, char rbracket)
Extract the string which is here between lbracket and rbracket.
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.
In the general case, normalize by the first (non null) weight.
const weightset_ptr & weightset() const
z::value_t operator()(const value_t &v) const
ps_t::value_t operator()(const value_t &v) const
std::ostream & print_weight_(const weight_t w, std::ostream &out, format fmt) const
Print a weight.
value_t rmul_label(const value_t &v, const label_t &rhs) const
Right product.
value_t mul(const value_t &l, const monomial_t &rhs) const
Right product by a monomial.
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.
wet_kind_t
Different implementations of wets.
static ATTRIBUTE_PURE bool equal(const value_t &l, const value_t &r)
std::istringstream is
The input stream: the specification to translate.
value_t & add_here(value_t &v, const monomial_t &m) const
v += m.
weight_t normalize_here(value_t &v) const
Normalize v in place: compute the LGCD of the weights, ldiv the monomials with that factor...
static bool is_one(const value_t &v) ATTRIBUTE_PURE
Whether is the unit polynomial.
auto label_of(const welement< Label, Weight > &m) -> decltype(m.label())
The label of a welement.
Print as a parsable type string.
static dyn::context ctx(const driver &d)
Get the context of the driver.
labelset_t_of< context_t > labelset_t
static ATTRIBUTE_PURE bool less(const value_t &l, const value_t &r)
std::ostream & print(const value_t &v, std::ostream &out, format fmt={}, const std::string &sep=" + ") const
Print a value (a polynomial).
const weight_t get_weight(const value_t &v, const label_t &l) const ATTRIBUTE_PURE
auto mul(const value_t &l, const value_t &r) const -> value_t
The product of polynomials l and r.
Container::value_type front(const Container &container)
The first member of this Container.
static value_t conv(self_t, const value_t &v)
Conversion from (this and) other weightsets.
monomial_t mul(const monomial_t &l, const monomial_t &r) const
The product of monomials l and r.
Request the bitset implementation (bool weights).
typename context_t::weightset_ptr weightset_ptr
label_t to_label(const value_t &v) const
Convert into a label.
value_t star(const value_t &v) const
The star of polynomial v.
value_t lgcd(const value_t &lhs, const value_t &rhs) const
LGCD between two polynomials.
std::enable_if_t<!is_letterized_t< labelset_t_of< Aut > >{}, bool > is_letterized(const Aut &aut)
typename labelset_t::value_t label_t
Polynomials over labels.
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.
static constexpr star_status_t star_status()
value_t conv(const polynomialset< C, K > &sps, const typename polynomialset< C, K >::value_t &v) const
Convert from another polynomialset to type_t.
static ATTRIBUTE_PURE auto hash_impl(const value_t &p) -> std::enable_if_t< WetType==wet_kind_t::bitset, size_t >
value_t rmul(const value_t &v, const weight_t w) const
Right exterior product.
auto project(const value_t &v) const
Extract a single tape.
std::ostream & print_set(std::ostream &o, format fmt={}) const
boost::optional< label_t > conv_label(std::istream &i, bool weighted, const char sep= '+') const
Read a label, if there is one.
auto mul(const value_t &p, const label_t &l, const weight_t w) const -> value_t
The product of polynomials l and r.
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.
value_t & del_weight(value_t &v, const label_t &l) const
Remove the monomial of l in v.
static ATTRIBUTE_PURE auto less_impl(const value_t &l, const value_t &r) -> std::enable_if_t< WetType!=wet_kind_t::bitset, bool >
polynomialset< Context, Kind > make_polynomialset(const Context &context)
static const monomial_t & monomial_one()
The unit monomial.
auto label_is_zero(const LabelSet &ls, const typename LabelSet::value_t *l) -> decltype(ls.is_zero(l), bool())
WeightSet::value_t operator()(const value_t &v) const
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.
static ATTRIBUTE_PURE auto less_impl(const value_t &l, const value_t &r) -> std::enable_if_t< WetType==wet_kind_t::bitset, bool >
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.
weight_t conv_weight(std::istream &i) const
Read a weight, if there is one, bracketed.
const labelset_ptr & labelset() const
monomial_t ldiv(const monomial_t &l, const monomial_t &r) const
value_t conjunction(const value_t &l, const value_t &r) const
void clear(value_t &v)
Set to zero.
Functor to compare Values of ValueSets.
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.
Request the map implementation.
static constexpr char rangle
Right marker for weight in concrete syntax.