1 #ifndef VCSN_WEIGHTSET_POLYNOMIALSET_HH
2 # define VCSN_WEIGHTSET_POLYNOMIALSET_HH
7 # include <type_traits>
26 # if defined __clang__
27 # pragma clang diagnostic push
28 # pragma clang diagnostic ignored "-Wunused-value"
30 template <
typename LabelSet>
32 -> decltype(ls.is_zero(l), bool())
34 return ls.is_zero(*l);
37 # if defined __clang__
38 # pragma clang diagnostic pop
41 template <
typename LabelSet>
53 template <
class Context>
66 using label_t =
typename labelset_t::value_t;
69 using value_t = std::map<label_t, weight_t, vcsn::less<labelset_t>>;
86 std::string
vname(
bool full =
true)
const
88 return "polynomialset<" +
context().vname(full) +
">";
118 for (
const auto& m: p)
127 return add_here(v, p.first, p.second);
145 auto w2 =
weightset()->add(i->second, k);
182 labelset()->concat(i.first, j.first),
206 for (
auto i: zip_maps<vcsn::as_tuple>(l, r))
209 std::get<1>(i).second));
226 return {{i->first,
weightset()->star(i->second)}};
237 for (
const auto& m: v)
261 for (
const auto& m: v)
281 throw std::runtime_error(
"not implemented for polynomials");
295 m.second =
weightset()->ldiv(w, m.second);
304 m.second =
weightset()->rdiv(m.second, w);
310 typename std::enable_if<!std::is_same<WeightSet, z>::value,
int>::type = 0>
311 typename WeightSet::value_t
314 return begin(v)->second;
319 typename std::enable_if<std::is_same<WeightSet, z>::value,
int>::type = 0>
320 typename WeightSet::value_t
323 int sign = 0 < begin(v)->second ? 1 : -1;
324 auto res = abs(begin(v)->second);
325 for (
const auto& m: v)
335 auto res = norm_<weightset_t>(v);
344 return (labelset_t::equals(lhs.first, rhs.first)
345 && weightset_t::equals(lhs.second, rhs.second));
351 return l.size() ==
r.size()
352 && std::equal(l.begin(), l.end(),
r.begin(),
397 return weightset_t::star_status();
410 template <
typename WS>
412 conv(
const WS& ws,
const typename WS::value_t& v)
const
418 template <
typename C>
424 typename C::labelset_t sls = * sps.labelset();
425 typename C::weightset_t sws = * sps.weightset();
428 for (
const auto& m: v)
429 add_here(res, tls.conv(sls, m.first), tws.conv(sws, m.second));
449 return std::lexicographical_compare(lhs.begin(), lhs.end(),
450 rhs.begin(), rhs.end(),
458 for (
const auto& i: v)
467 std::hash_combine(res, labelset_t::hash(m.first));
468 std::hash_combine(res, weightset_t::hash(m.second));
476 for (
const auto& m: v)
478 std::hash_combine(res, labelset_t::hash(m.first));
479 std::hash_combine(res, weightset_t::hash(m.second));
488 eat(is,
"polynomialset<");
489 auto ctx = Context::make(is);
497 if (format ==
"latex")
499 o <<
"\\mathsf{Poly}[";
507 o <<
"polynomialset<";
525 conv(std::istream& i,
const char sep =
'+')
const
528 #define SKIP_SPACES() \
529 while (isspace(i.peek())) \
537 bool default_w =
true;
549 if (i.peek() ==
'\\')
575 if (peek == EOF || peek == sep || isspace(peek))
591 sname(),
": conv: invalid monomial: ",
593 " (did you mean \\e or \\z?)");
620 static bool parens = getenv(
"VCSN_PARENS");
623 out << (format ==
"latex" ?
"\\left(" :
"(");
624 labelset()->print(m.first, out, format);
626 out << (format ==
"latex" ?
"\\right)" :
")");
639 const std::string& sep =
" + ")
const
641 bool latex = format ==
"latex";
643 out << (latex ?
"\\emptyset" :
"\\z");
645 print_<context_t>(v, out, format,
646 latex && sep ==
" + " ?
" \\oplus " : sep);
656 static bool parens = getenv(
"VCSN_PARENS");
659 out << (format ==
"latex" ?
"\\left\\langle " : std::string{
langle});
661 out << (format ==
"latex" ?
"\\right\\rangle " : std::string{
rangle});
670 const std::string& sep =
" + ")
const
673 for (
const auto& m: v)
678 print(m, out, format);
687 const std::string& sep =
" + ")
const
689 if (sep ==
" + " || v.size() <= 2)
697 std::vector<label_t> letters;
699 for (
const auto& m: v)
705 letters.push_back(m.first);
711 print(*std::begin(v), out, format);
722 const auto& alphabet =
labelset()->genset();
723 for (
auto it = std::begin(letters), letters_end = std::end(letters);
724 it != letters_end; ++it)
726 auto end = std::mismatch(it, letters_end, alphabet.find(*it)).first;
727 labelset()->print(*it, out, format);
729 auto width = std::distance(it, end);
734 labelset()->print(*it, out, format);
743 template <
typename context>
748 const std::string& sep =
" + ")
const
754 template <
typename Ctx>
755 typename std::enable_if<Ctx::is_lal || Ctx::is_lan,
759 const std::string& sep =
" + ")
const
775 template <
typename Aut>
780 using automaton_t = Aut;
783 using polynomial_t =
typename polynomialset_t::value_t;
786 for (
auto t : aut->outin(s, d))
789 res[aut->label_of(t)] = aut->weight_of(t);
795 template <
typename Ctx1,
typename Ctx2>
802 return {
vcsn::join(ps1.context(), ps2.context())};
806 template <
typename WS1,
typename Ctx2>
814 return {*ps2.labelset(),
vcsn::join(ws1, *ps2.weightset())};
820 #endif // !VCSN_WEIGHTSET_POLYNOMIALSET_HH
bool is_zero(const value_t &v) const
weight_t scalar_product(const value_t &l, const value_t &r) const
The sum of the weights of the common labels.
static ATTRIBUTE_PURE size_t hash(const monomial_t &m)
value_t & add_here(value_t &v, const label_t &l, const weight_t k) const
v += (l, k).
typename labelset_t::value_t label_t
Polynomials over labels.
value_t & add_here(value_t &v, const value_t &p) const
v += p.
value_t & ldiv_here(const weight_t &w, value_t &v) const
Left exterior division.
static constexpr char langle
Left marker for weight in concrete syntax.
std::string bracketed(std::istream &i, const char lbracket, const char rbracket)
Extract the string which is here between lbracket and rbracket.
static constexpr bool show_one()
decltype(join(std::declval< ValueSets >()...)) join_t
The type of the join of the ValueSets.
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
const weightset_ptr & weightset() const
static bool equals(const value_t &l, const value_t &r) ATTRIBUTE_PURE
value_t rmul(const value_t &v, const label_t &rhs) const
Right product.
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.
static value_t rdiv(const value_t &, const value_t &)
weight_t_of< context_t > weight_t
static constexpr char rangle
Right marker for weight in concrete syntax.
static type join(const polynomialset< Ctx1 > &ps1, const polynomialset< Ctx2 > &ps2)
ATTRIBUTE_PURE unsigned int gcd(unsigned int a, unsigned int b)
static bool less_than(const value_t &lhs, const value_t &rhs)
boost::flyweight< std::string, boost::flyweights::no_tracking > symbol
An internalized string.
value_t rmul(const value_t &v, const weight_t &w) const
Right exterior product.
const value_t & zero() const
std::ostream & str_escape(std::ostream &os, const std::string &str)
Output a string, escaping special characters.
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.
value_t lmul(const weight_t &w, const value_t &v) const
Left exterior product.
labelset_t_of< context_t > labelset_t
value_t mul(const value_t &l, const value_t &r) const
The product of polynomials l and r.
std::ostream & print_set(std::ostream &o, symbol format=symbol{"text"}) const
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
bool is_one(const value_t &v) const ATTRIBUTE_PURE
static ATTRIBUTE_PURE size_t hash(const value_t &v)
value_t & add_here(value_t &v, const monomial_t &p) const
v += m.
typename value_t::value_type monomial_t
A pair
std::ostream & print_with_ranges_(const value_t &v, std::ostream &out, symbol format=symbol{"text"}, const std::string &sep=" + ") const
Print a polynomial value with ranges.
static constexpr star_status_t star_status()
const context_t & context() const
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
auto label_is_zero(const LabelSet &ls, const typename LabelSet::value_t *l) -> decltype(ls.is_zero(l), bool())
static type join(const WS1 &ws1, const polynomialset< Ctx2 > &ps2)
typename context_t::labelset_ptr labelset_ptr
std::enable_if< Ctx::is_lal||Ctx::is_lan, std::ostream & >::type print_(const value_t &v, std::ostream &out, symbol format=symbol{"text"}, const std::string &sep=" + ") const
Print a non-null value for LAL or LAN.
std::ostream & print(const monomial_t &m, std::ostream &out, symbol format=symbol{"text"}) const
Print a monomial.
std::istringstream is
The input stream: the specification to translate.
value_t add(const value_t &l, const value_t &r) const
The sum of polynomials l and r.
value_t star(const value_t &v) const
The star of polynomial v.
value_t conv(const polynomialset< C > &sps, const typename polynomialset< C >::value_t &v) const
Convert from another polynomialset to type_t.
value_t conv(std::istream &i, const char sep= '+') const
Construct from a string.
A structure that implements the computation of join(V1, V2).
std::shared_ptr< const detail::label_base > label
value_t lmul(const label_t &lhs, const value_t &v) const
Left product by a label.
std::string vname(bool full=true) const
The dynamic name.
static value_t conv(self_type, value_t v)
Conversion from (this and) other weightsets.
std::enable_if<!(context::is_lal||context::is_lan), std::ostream & >::type print_(const value_t &v, std::ostream &out, symbol format=symbol{"text"}, const std::string &sep=" + ") const
Print a non-null value for neither LAL nor LAN.
Provide a variadic mul on top of a binary mul(), and one().
polynomialset< context_t_of< Aut > >::value_t get_entry(const Aut &aut, state_t_of< Aut > s, state_t_of< Aut > d)
The entry between two states of an automaton.
value_t conjunction(const value_t &l, const value_t &r) const
The conjunction of polynomials l and r.
const labelset_ptr & labelset() const
WeightSet::value_t norm_(value_t &v) const
In the general case, normalize by the first (non null) weight.
static value_t ldiv(const value_t &l, const value_t &r)
weightset_t_of< context_t > weightset_t
std::map< label_t, weight_t, vcsn::less< labelset_t >> value_t
typename detail::weight_t_of_impl< base_t< ValueSet >>::type weight_t_of
std::ostream & print_weight_(const weight_t &w, std::ostream &out, symbol format=symbol{"text"}) const
Print a weight.
char eat(std::istream &is, char c)
Check lookahead character and advance.
std::ostream & print(const value_t &v, std::ostream &out, symbol format=symbol{"text"}, const std::string &sep=" + ") const
Print a value (a polynomial).
value_t & del_weight(value_t &v, const label_t &w) const
Remove the monomial of w in v.
const monomial_t & monomial_one() const
static self_type make(std::istream &is)
Build from the description in is.
typename context_t::weightset_ptr weightset_ptr
auto join(const ValueSet &vs) -> ValueSet
The join of a single valueset.
value_t transpose(const value_t &v) const
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
weight_t normalize_here(value_t &v) const
Normalize v in place, and return the factor which was divided.
static std::string sname()
The static name.
RatExpSet::value_t less_than(const RatExpSet &rs, const typename RatExpSet::value_t &v)
const value_t & one() const
static ATTRIBUTE_PURE bool monomial_equals(const monomial_t &lhs, const monomial_t &rhs)
std::ostream & print_without_ranges_(const value_t &v, std::ostream &out, symbol format=symbol{"text"}, const std::string &sep=" + ") const
Print a polynomial value without ranges.
const weight_t get_weight(const value_t &v, const label_t &w) const ATTRIBUTE_PURE
polynomialset(const context_t &ctx)
value_t & set_weight(value_t &v, const label_t &w, const weight_t k) const
Set the monomial of w in v to weight k.
value_t & rdiv_here(value_t &v, const weight_t &w) const
Right exterior division.
static ATTRIBUTE_PURE bool monomial_less_than(const monomial_t &lhs, const monomial_t &rhs)
void require(bool b, Args &&...args)
If b is not verified, raise an error with args as message.
std::string to_string(direction d)
Conversion to string.