Vcsn  2.0
Be Rational
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
polynomialset.hh
Go to the documentation of this file.
1 #ifndef VCSN_WEIGHTSET_POLYNOMIALSET_HH
2 # define VCSN_WEIGHTSET_POLYNOMIALSET_HH
3 
4 # include <algorithm>
5 # include <iostream>
6 # include <sstream>
7 # include <type_traits>
8 # include <vector>
9 
10 # include <vcsn/ctx/context.hh> // We need context to define join.
11 # include <vcsn/weightset/fwd.hh>
12 
13 # include <vcsn/ctx/traits.hh>
14 # include <vcsn/misc/attributes.hh>
15 # include <vcsn/misc/hash.hh>
16 # include <vcsn/misc/map.hh>
17 # include <vcsn/misc/math.hh>
18 # include <vcsn/misc/raise.hh>
19 # include <vcsn/misc/star_status.hh>
20 # include <vcsn/misc/stream.hh>
21 # include <vcsn/misc/zip-maps.hh>
22 
23 namespace vcsn
24 {
25  // http://llvm.org/bugs/show_bug.cgi?id=18571
26 # if defined __clang__
27 # pragma clang diagnostic push
28 # pragma clang diagnostic ignored "-Wunused-value"
29 # endif
30  template <typename LabelSet>
31  auto label_is_zero(const LabelSet& ls, const typename LabelSet::value_t* l)
32  -> decltype(ls.is_zero(l), bool())
33  {
34  return ls.is_zero(*l);
35  }
36 
37 # if defined __clang__
38 # pragma clang diagnostic pop
39 # endif
40 
41  template <typename LabelSet>
42  bool label_is_zero(const LabelSet&, ...)
43  ATTRIBUTE_CONST;
44 
45  template <typename LabelSet>
46  bool label_is_zero(const LabelSet&, ...)
47  {
48  return false;
49  }
50 
53  template <class Context>
54  class polynomialset
55  {
56  public:
58  using context_t = Context;
62 
63  using labelset_ptr = typename context_t::labelset_ptr;
64  using weightset_ptr = typename context_t::weightset_ptr;
66  using label_t = typename labelset_t::value_t;
68 
69  using value_t = std::map<label_t, weight_t, vcsn::less<labelset_t>>;
71  using monomial_t = typename value_t::value_type;
72 
73  polynomialset() = delete;
74  polynomialset(const polynomialset&) = default;
76  : ctx_{ctx}
77  {}
78 
80  static std::string sname()
81  {
82  return "polynomialset<" + context_t::sname() + ">";
83  }
84 
86  std::string vname(bool full = true) const
87  {
88  return "polynomialset<" + context().vname(full) + ">";
89  }
90 
91  const context_t& context() const { return ctx_; }
92  const labelset_ptr& labelset() const { return ctx_.labelset(); }
93  const weightset_ptr& weightset() const { return ctx_.weightset(); }
94 
96  value_t&
97  del_weight(value_t& v, const label_t& w) const
98  {
99  v.erase(w);
100  return v;
101  }
102 
104  value_t&
105  set_weight(value_t& v, const label_t& w, const weight_t k) const
106  {
107  if (weightset()->is_zero(k))
108  del_weight(v, w);
109  else
110  v[w] = k;
111  return v;
112  }
113 
115  value_t&
116  add_here(value_t& v, const value_t& p) const
117  {
118  for (const auto& m: p)
119  add_here(v, m);
120  return v;
121  }
122 
124  value_t&
125  add_here(value_t& v, const monomial_t& p) const
126  {
127  return add_here(v, p.first, p.second);
128  }
129 
131  value_t&
132  add_here(value_t& v, const label_t& l, const weight_t k) const
133  {
134  if (!label_is_zero(*labelset(), &l))
135  {
136  auto i = v.find(l);
137  if (i == v.end())
138  {
139  set_weight(v, l, k);
140  }
141  else
142  {
143  // Do not use set_weight() because it would lookup w
144  // again and we already have the right iterator.
145  auto w2 = weightset()->add(i->second, k);
146  if (weightset()->is_zero(w2))
147  v.erase(i);
148  else
149  i->second = w2;
150  }
151  }
152  return v;
153  }
154 
155  const weight_t
156  get_weight(const value_t& v, const label_t& w) const ATTRIBUTE_PURE
157  {
158  auto i = v.find(w);
159  if (i == v.end())
160  return weightset()->zero();
161  else
162  return i->second;
163  }
164 
166  value_t
167  add(const value_t& l, const value_t& r) const
168  {
169  value_t res = l;
170  add_here(res, r);
171  return res;
172  }
173 
175  value_t
176  mul(const value_t& l, const value_t& r) const
177  {
178  value_t res;
179  for (auto i: l)
180  for (auto j: r)
181  add_here(res,
182  labelset()->concat(i.first, j.first),
183  weightset()->mul(i.second, j.second));
184  return res;
185  }
186 
189  value_t
190  conjunction(const value_t& l, const value_t& r) const
191  {
192  value_t res;
193  for (auto i: l)
194  for (auto j: r)
195  add_here(res,
196  labelset()->conjunction(i.first, j.first),
197  weightset()->mul(i.second, j.second));
198  return res;
199  }
200 
202  weight_t
203  scalar_product(const value_t& l, const value_t& r) const
204  {
205  weight_t res = weightset()->zero();
206  for (auto i: zip_maps<vcsn::as_tuple>(l, r))
207  res = weightset()->add(res,
208  weightset()->mul(std::get<0>(i).second,
209  std::get<1>(i).second));
210  return res;
211  }
212 
214  value_t
215  star(const value_t& v) const
216  {
217  // The only starrable polynomials are scalars (if they are
218  // starrable too).
219  auto s = v.size();
220  if (s == 0)
221  return one();
222  else if (s == 1)
223  {
224  auto i = v.find(labelset()->one());
225  if (i != v.end())
226  return {{i->first, weightset()->star(i->second)}};
227  }
228  raise(sname(), ": star: invalid value: ", to_string(*this, v));
229  }
230 
232  value_t
233  lmul(const weight_t& w, const value_t& v) const
234  {
235  value_t res;
236  if (!weightset()->is_zero(w))
237  for (const auto& m: v)
238  add_here(res, m.first, weightset()->mul(w, m.second));
239  return res;
240  }
241 
243  value_t
244  lmul(const label_t& lhs, const value_t& v) const
245  {
246  value_t res;
247  for (auto i: v)
248  add_here(res,
249  // FIXME: This is wrong, it should be mul, not concat.
250  labelset()->concat(lhs, i.first),
251  i.second);
252  return res;
253  }
254 
256  value_t
257  rmul(const value_t& v, const weight_t& w) const
258  {
259  value_t res;
260  if (!weightset()->is_zero(w))
261  for (const auto& m: v)
262  add_here(res, m.first, weightset()->mul(m.second, w));
263  return res;
264  }
265 
267  value_t
268  rmul(const value_t& v, const label_t& rhs) const
269  {
270  value_t res;
271  for (auto i: v)
272  add_here(res,
273  labelset()->concat(i.first, rhs),
274  i.second);
275  return res;
276  }
277 
278  static value_t
279  rdiv(const value_t&, const value_t&)
280  {
281  throw std::runtime_error("not implemented for polynomials");
282  }
283 
284  static value_t
285  ldiv(const value_t& l, const value_t& r)
286  {
287  return rdiv(r, l);
288  }
289 
291  value_t&
292  ldiv_here(const weight_t& w, value_t& v) const
293  {
294  for (auto& m: v)
295  m.second = weightset()->ldiv(w, m.second);
296  return v;
297  }
298 
300  value_t&
301  rdiv_here(value_t& v, const weight_t& w) const
302  {
303  for (auto& m: v)
304  m.second = weightset()->rdiv(m.second, w);
305  return v;
306  }
307 
309  template <typename WeightSet,
310  typename std::enable_if<!std::is_same<WeightSet, z>::value, int>::type = 0>
311  typename WeightSet::value_t
312  norm_(value_t& v) const
313  {
314  return begin(v)->second;
315  }
316 
318  template <typename WeightSet,
319  typename std::enable_if<std::is_same<WeightSet, z>::value, int>::type = 0>
320  typename WeightSet::value_t
321  norm_(value_t& v) const
322  {
323  int sign = 0 < begin(v)->second ? 1 : -1;
324  auto res = abs(begin(v)->second);
325  for (const auto& m: v)
326  res = detail::gcd(res, abs(m.second));
327  res *= sign;
328  return res;
329  }
330 
332  weight_t
334  {
335  auto res = norm_<weightset_t>(v);
336  ldiv_here(res, v);
337  return res;
338  }
339 
340  ATTRIBUTE_PURE
341  static bool monomial_equals(const monomial_t& lhs,
342  const monomial_t& rhs)
343  {
344  return (labelset_t::equals(lhs.first, rhs.first)
345  && weightset_t::equals(lhs.second, rhs.second));
346  }
347 
348  static bool
349  equals(const value_t& l, const value_t& r) ATTRIBUTE_PURE
350  {
351  return l.size() == r.size()
352  && std::equal(l.begin(), l.end(), r.begin(),
354  }
355 
356  const value_t&
357  one() const
358  {
359  static value_t res{monomial_one()};
360  return res;
361  }
362 
363  const monomial_t&
364  monomial_one() const
365  {
366  static monomial_t res{labelset()->one(), weightset()->one()};
367  return res;
368  }
369 
370  bool
371  is_one(const value_t& v) const ATTRIBUTE_PURE
372  {
373  if (v.size() != 1)
374  return false;
375  auto i = v.find(labelset()->one());
376  if (i == v.end())
377  return false;
378  return weightset()->is_one(i->second);
379  }
380 
381  const value_t&
382  zero() const
383  {
384  static value_t res;
385  return res;
386  }
387 
388  bool
389  is_zero(const value_t& v) const
390  {
391  return v.empty();
392  }
393 
394  static constexpr bool show_one() { return true; }
395  static constexpr star_status_t star_status()
396  {
397  return weightset_t::star_status();
398  }
399 
401  static value_t
403  {
404  return v;
405  }
406 
410  template <typename WS>
411  value_t
412  conv(const WS& ws, const typename WS::value_t& v) const
413  {
414  return {{labelset()->one(), weightset()->conv(ws, v)}};
415  }
416 
418  template <typename C>
419  value_t
420  conv(const polynomialset<C>& sps,
421  const typename polynomialset<C>::value_t& v) const
422  {
423  value_t res;
424  typename C::labelset_t sls = * sps.labelset();
425  typename C::weightset_t sws = * sps.weightset();
426  labelset_t tls = * labelset();
427  weightset_t tws = * weightset();
428  for (const auto& m: v)
429  add_here(res, tls.conv(sls, m.first), tws.conv(sws, m.second));
430  return res;
431  }
432 
433 
434  ATTRIBUTE_PURE
435  static bool monomial_less_than(const monomial_t& lhs,
436  const monomial_t& rhs)
437  {
438  if (labelset_t::less_than(lhs.first, rhs.first))
439  return true;
440  else if (labelset_t::less_than(rhs.first, lhs.first))
441  return false;
442  else
443  return weightset_t::less_than(lhs.second, rhs.second);
444  }
445 
446  static bool less_than(const value_t& lhs,
447  const value_t& rhs)
448  {
449  return std::lexicographical_compare(lhs.begin(), lhs.end(),
450  rhs.begin(), rhs.end(),
452  }
453 
454  value_t
455  transpose(const value_t& v) const
456  {
457  value_t res;
458  for (const auto& i: v)
459  res[labelset()->transpose(i.first)] = weightset()->transpose(i.second);
460  return res;
461  }
462 
463  ATTRIBUTE_PURE
464  static size_t hash(const monomial_t& m)
465  {
466  size_t res = 0;
467  std::hash_combine(res, labelset_t::hash(m.first));
468  std::hash_combine(res, weightset_t::hash(m.second));
469  return res;
470  }
471 
472  ATTRIBUTE_PURE
473  static size_t hash(const value_t& v)
474  {
475  size_t res = 0;
476  for (const auto& m: v)
477  {
478  std::hash_combine(res, labelset_t::hash(m.first));
479  std::hash_combine(res, weightset_t::hash(m.second));
480  }
481  return res;
482  }
483 
485  static self_type make(std::istream& is)
486  {
487  // name is, for instance, "polynomialset<lal_char(abcd), z>".
488  eat(is, "polynomialset<");
489  auto ctx = Context::make(is);
490  eat(is, '>');
491  return {ctx};
492  }
493 
494  std::ostream&
495  print_set(std::ostream& o, symbol format = symbol{"text"}) const
496  {
497  if (format == "latex")
498  {
499  o << "\\mathsf{Poly}[";
500  labelset()->print_set(o, format);
501  o << " \\to ";
502  weightset()->print_set(o, format);
503  o << "]";
504  }
505  else
506  {
507  o << "polynomialset<";
508  labelset()->print_set(o, format);
509  o << "_";
510  weightset()->print_set(o, format);
511  o << ">";
512  }
513  return o;
514  }
515 
524  value_t
525  conv(std::istream& i, const char sep = '+') const
526  {
527  value_t res;
528 #define SKIP_SPACES() \
529  while (isspace(i.peek())) \
530  i.ignore()
531 
532  do
533  {
534  // Possibly a weight in braces.
535  SKIP_SPACES();
536  weight_t w = weightset()->one();
537  bool default_w = true;
538  if (i.peek() == langle)
539  {
540  // FIXME: convert to use conv(std::istream).
542  default_w = false;
543  }
544 
545  // Possibly, a label.
546  SKIP_SPACES();
547  // Whether the label is \z.
548  bool is_zero = false;
549  if (i.peek() == '\\')
550  {
551  i.ignore();
552  if (i.peek() == 'z')
553  {
554  is_zero = true;
555  i.ignore();
556  }
557  else
558  i.unget();
559  }
560 
561  if (!is_zero)
562  {
563  // The label is not \z.
564  int peek = i.peek();
565  // Handle ranges
566  if (peek == '[')
567  for (auto c : labelset()->convs(i))
568  add_here(res, c, w);
569  else
570  {
571  // Check if there is a label that comes. Or rather,
572  // check if there is something else than EOF or the
573  // separator, in which case it must be a label.
574  label_t label;
575  if (peek == EOF || peek == sep || isspace(peek))
576  {
577  // There is no label. This counts as '$', the
578  // special label.
579  //
580  // Indeed, that how we represent the initial and
581  // final transitions: '$ -> 0 "<2>"'. Using the
582  // one label is tempting, but it does not exist
583  // for lal_char for instance. And it would be
584  // wrong to have '\e' when we can, and '$'
585  // otherwise...
586  //
587  // However, we must have at least a weight: a
588  // completely empty mononial ($ -> 0 "<2>,") is
589  // invalid.
590  require(!default_w,
591  sname(), ": conv: invalid monomial: ",
592  str_escape(peek),
593  " (did you mean \\e or \\z?)");
594  label = labelset()->special();
595  }
596  else
597  label = labelset()->conv(i);
598  add_here(res, label, w);
599  }
600  }
601 
602  // sep (e.g., '+'), or stop parsing.
603  SKIP_SPACES();
604  if (i.peek() == sep)
605  i.ignore();
606  else
607  break;
608  }
609  while (true);
610 #undef SKIP_SPACES
611 
612  return res;
613  }
614 
616  std::ostream&
617  print(const monomial_t& m, std::ostream& out,
618  symbol format = symbol{"text"}) const
619  {
620  static bool parens = getenv("VCSN_PARENS");
621  print_weight_(m.second, out, format);
622  if (parens)
623  out << (format == "latex" ? "\\left(" : "(");
624  labelset()->print(m.first, out, format);
625  if (parens)
626  out << (format == "latex" ? "\\right)" : ")");
627  return out;
628  }
629 
636  std::ostream&
637  print(const value_t& v, std::ostream& out,
638  symbol format = symbol{"text"},
639  const std::string& sep = " + ") const
640  {
641  bool latex = format == "latex";
642  if (v.empty())
643  out << (latex ? "\\emptyset" : "\\z");
644  else
645  print_<context_t>(v, out, format,
646  latex && sep == " + " ? " \\oplus " : sep);
647  return out;
648  }
649 
650  private:
652  std::ostream&
653  print_weight_(const weight_t& w, std::ostream& out,
654  symbol format = symbol{"text"}) const
655  {
656  static bool parens = getenv("VCSN_PARENS");
657  if (parens || weightset()->show_one() || !weightset()->is_one(w))
658  {
659  out << (format == "latex" ? "\\left\\langle " : std::string{langle});
660  weightset()->print(w, out, format);
661  out << (format == "latex" ? "\\right\\rangle " : std::string{rangle});
662  }
663  return out;
664  }
665 
667  std::ostream&
668  print_without_ranges_(const value_t& v, std::ostream& out,
669  symbol format = symbol{"text"},
670  const std::string& sep = " + ") const
671  {
672  bool first = true;
673  for (const auto& m: v)
674  {
675  if (!first)
676  out << sep;
677  first = false;
678  print(m, out, format);
679  }
680  return out;
681  }
682 
684  std::ostream&
685  print_with_ranges_(const value_t& v, std::ostream& out,
686  symbol format = symbol{"text"},
687  const std::string& sep = " + ") const
688  {
689  if (sep == " + " || v.size() <= 2)
690  return print_without_ranges_(v, out, format, sep);
691 
692  // No ranges if the weights aren't all the same.
693  //
694  // While at it, gather the letters. We can use a vector, as we
695  // know that the labels are already sorted, and random access
696  // iteration will be handy below.
697  std::vector<label_t> letters;
698  weight_t first_w = weightset()->zero();
699  for (const auto& m: v)
700  {
701  if (weightset()->is_zero(first_w))
702  first_w = m.second;
703  else if (!weightset()->equals(m.second, first_w))
704  return print_without_ranges_(v, out, format, sep);
705  letters.push_back(m.first);
706  }
707 
708  // Print with ranges. First, the constant-term.
709  if (labelset()->is_one(std::begin(v)->first))
710  {
711  print(*std::begin(v), out, format);
712  if (1 < v.size())
713  out << sep;
714  }
715 
716  // The weight.
717  print_weight_(first_w, out, format);
718 
719  // Print the character class. letters are sorted, since
720  // polynomials are shortlex-sorted on the labels.
721  out << '[';
722  const auto& alphabet = labelset()->genset();
723  for (auto it = std::begin(letters), letters_end = std::end(letters);
724  it != letters_end; ++it)
725  {
726  auto end = std::mismatch(it, letters_end, alphabet.find(*it)).first;
727  labelset()->print(*it, out, format);
728  // No ranges for two letters or less.
729  auto width = std::distance(it, end);
730  if (2 < width)
731  {
732  it += width - 1;
733  out << '-';
734  labelset()->print(*it, out, format);
735  }
736  }
737  out << ']';
738 
739  return out;
740  }
741 
743  template <typename context>
744  typename std::enable_if<!(context::is_lal || context::is_lan),
745  std::ostream&>::type
746  print_(const value_t& v, std::ostream& out,
747  symbol format = symbol{"text"},
748  const std::string& sep = " + ") const
749  {
750  return print_without_ranges_(v, out, format, sep);
751  }
752 
754  template <typename Ctx>
755  typename std::enable_if<Ctx::is_lal || Ctx::is_lan,
756  std::ostream&>::type
757  print_(const value_t& v, std::ostream& out,
758  symbol format = symbol{"text"},
759  const std::string& sep = " + ") const
760  {
761  return print_with_ranges_(v, out, format, sep);
762  }
763 
764 
765  private:
767 
769  constexpr static char langle = '<';
771  constexpr static char rangle = '>';
772  };
773 
775  template <typename Aut>
776  typename polynomialset<context_t_of<Aut>>::value_t
777  get_entry(const Aut& aut,
779  {
780  using automaton_t = Aut;
781  using context_t = context_t_of<automaton_t>;
782  using polynomialset_t = polynomialset<context_t>;
783  using polynomial_t = typename polynomialset_t::value_t;
784 
785  polynomial_t res;
786  for (auto t : aut->outin(s, d))
787  // Bypass set_weight(), because we know that the weight is
788  // nonzero, and that there is only one weight per letter.
789  res[aut->label_of(t)] = aut->weight_of(t);
790  return res;
791  }
792 
793  namespace detail
794  {
795  template <typename Ctx1, typename Ctx2>
796  struct join_impl<polynomialset<Ctx1>, polynomialset<Ctx2>>
797  {
799  static type join(const polynomialset<Ctx1>& ps1,
800  const polynomialset<Ctx2>& ps2)
801  {
802  return {vcsn::join(ps1.context(), ps2.context())};
803  }
804  };
805 
806  template <typename WS1, typename Ctx2>
807  struct join_impl<WS1, polynomialset<Ctx2>>
808  {
809  using type
810  = polynomialset<context<typename Ctx2::labelset_t,
812  static type join(const WS1& ws1, const polynomialset<Ctx2>& ps2)
813  {
814  return {*ps2.labelset(), vcsn::join(ws1, *ps2.weightset())};
815  }
816  };
817  }
818 }
819 
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.
#define SKIP_SPACES()
std::string bracketed(std::istream &i, const char lbracket, const char rbracket)
Extract the string which is here between lbracket and rbracket.
Definition: stream.cc:17
static constexpr bool show_one()
decltype(join(std::declval< ValueSets >()...)) join_t
The type of the join of the ValueSets.
Definition: join.hh:61
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:34
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)
Definition: math.hh:14
static bool less_than(const value_t &lhs, const value_t &rhs)
boost::flyweight< std::string, boost::flyweights::no_tracking > symbol
An internalized string.
Definition: symbol.hh:24
std::string sname()
Definition: name.hh:31
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.
Definition: escape.cc:43
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.
Definition: stream.hh:29
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
Definition: traits.hh:32
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
Definition: traits.hh:38
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.
Definition: translate.cc:329
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.
star_status_t
Definition: star_status.hh:6
A structure that implements the computation of join(V1, V2).
Definition: join.hh:19
std::shared_ptr< const detail::label_base > label
Definition: fwd.hh:46
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().
Definition: fwd.hh:36
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
Definition: traits.hh:37
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.
Definition: stream.cc:37
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.
Definition: join.hh:44
value_t transpose(const value_t &v) const
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:35
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)
Definition: less-than.hh:150
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.
Definition: raise.hh:39
std::string to_string(direction d)
Conversion to string.
Definition: direction.cc:7