Awali
Another Weighted Automata library
polynomialset.hh
Go to the documentation of this file.
1 // This file is part of Awali.
2 // Copyright 2016-2023 Sylvain Lombardy, Victor Marsault, Jacques Sakarovitch
3 //
4 // Awali is a free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 
17 #ifndef AWALI_WEIGHTSET_POLYNOMIALSET_HH
18 # define AWALI_WEIGHTSET_POLYNOMIALSET_HH
19 
20 # include <algorithm>
21 # include <iostream>
22 # include <sstream>
23 # include <type_traits>
24 # include <vector>
25 
26 #include <awali/sttc/ctx/context.hh> // We need context to define join.
28 
29 #include <awali/sttc/ctx/traits.hh>
31 #include <awali/utils/hash.hh>
32 #include <awali/sttc/misc/map.hh>
33 #include <awali/sttc/misc/raise.hh>
34 #include <awali/common/enums.hh>
36 #include <awali/common/types.hh>
37 
38 namespace awali { namespace sttc {
39  // http://llvm.org/bugs/show_bug.cgi?id=18571
40 # if defined __clang__
41 # pragma clang diagnostic push
42 # pragma clang diagnostic ignored "-Wunused-value"
43 # endif
44  template <typename LabelSet>
45  auto label_is_zero(const LabelSet& ls, const typename LabelSet::value_t* l)
46  -> decltype(ls.is_zero(l), bool())
47  {
48  return ls.is_zero(*l);
49  }
50 
51 # if defined __clang__
52 # pragma clang diagnostic pop
53 # endif
54 
55  template <typename LabelSet>
56  bool label_is_zero(const LabelSet&, ...)
57  ATTRIBUTE_CONST;
58 
59  template <typename LabelSet>
60  bool label_is_zero(const LabelSet&, ...)
61  {
62  return false;
63  }
64 
67  template <class Context>
69  {
70  public:
72  using context_t = Context;
76 
77  using labelset_ptr = typename context_t::labelset_ptr;
78  using weightset_ptr = typename context_t::weightset_ptr;
80  using label_t = typename labelset_t::value_t;
82 
83  using value_t = std::map<label_t, weight_t, internal::less<labelset_t>>;
85  using monomial_t = typename value_t::value_type;
86 
87  polynomialset() = delete;
88  polynomialset(const polynomialset&) = default;
90  : ctx_{ctx}
91  {}
92 
94  static std::string sname()
95  {
96  return "polynomialset<" + context_t::sname() + ">";
97  }
98 
100  std::string vname(bool full = true) const
101  {
102  return "polynomialset<" + context().vname(full) + ">";
103  }
104 
105  const context_t& context() const { return ctx_; }
106  const labelset_ptr& labelset() const { return ctx_.labelset(); }
107  const weightset_ptr& weightset() const { return ctx_.weightset(); }
108 
110  value_t&
111  del_weight(value_t& v, const label_t& w) const
112  {
113  v.erase(w);
114  return v;
115  }
116 
118  value_t&
119  set_weight(value_t& v, const label_t& w, const weight_t k) const
120  {
121  if (weightset()->is_zero(k))
122  del_weight(v, w);
123  else
124  v[w] = k;
125  return v;
126  }
127 
129  value_t&
130  add_here(value_t& v, const value_t& p) const
131  {
132  for (const auto& m: p)
133  add_here(v, m);
134  return v;
135  }
136 
138  value_t&
139  add_here(value_t& v, const monomial_t& p) const
140  {
141  return add_here(v, p.first, p.second);
142  }
143 
144  // FIXME: rename at least this version.
146  value_t&
147  add_here(value_t& v, const label_t& l, const weight_t k) const
148  {
149  if (!label_is_zero(*labelset(), &l))
150  {
151  auto i = v.find(l);
152  if (i == v.end())
153  {
154  set_weight(v, l, k);
155  }
156  else
157  {
158  // Do not use set_weight() because it would lookup w
159  // again and we already have the right iterator.
160  auto w2 = weightset()->add(i->second, k);
161  if (weightset()->is_zero(w2))
162  v.erase(i);
163  else
164  i->second = w2;
165  }
166  }
167  return v;
168  }
169 
170  const weight_t
171  get_weight(const value_t& v, const label_t& w) const ATTRIBUTE_PURE
172  {
173  auto i = v.find(w);
174  if (i == v.end())
175  return weightset()->zero();
176  else
177  return i->second;
178  }
179 
181  value_t
182  add(const value_t& l, const value_t& r) const
183  {
184  value_t res = l;
185  for (auto& i : r)
186  add_here(res, i.first, i.second);
187  return res;
188  }
189 
191  value_t
192  mul(const value_t& l, const value_t& r) const
193  {
194  value_t res;
195  for (auto i: l)
196  for (auto j: r)
197  add_here(res,
198  labelset()->concat(i.first, j.first),
199  weightset()->mul(i.second, j.second));
200  return res;
201  }
202 
205  value_t
206  conjunction(const value_t& l, const value_t& r) const
207  {
208  value_t res;
209  for (auto i: l)
210  for (auto j: r)
211  add_here(res,
212  labelset()->conjunction(i.first, j.first),
213  weightset()->mul(i.second, j.second));
214  return res;
215  }
216 
218  value_t
219  star(const value_t& v) const
220  {
221  // The only starrable polynomialsets are scalars (if they are
222  // starrable too).
223  auto s = v.size();
224  if (s == 0)
225  return one();
226  else if (s == 1)
227  {
228  auto i = v.find(labelset()->one());
229  if (i != v.end())
230  {
231  value_t res;
232  add_here(res, i->first, weightset()->star(i->second));
233  return res;
234  }
235  }
236  raise(sname(), ": star: invalid value: ", format(*this, v));
237  }
238 
240  value_t
241  plus(const value_t& v) const
242  {
243  // The only starrable polynomialsets are scalars (if they are
244  // starrable too).
245  auto s = v.size();
246  if (s == 0)
247  return zero();
248  else if (s == 1)
249  {
250  auto i = v.find(labelset()->one());
251  if (i != v.end())
252  {
253  value_t res;
254  add_here(res, i->first, weightset()->plus(i->second));
255  return res;
256  }
257  }
258  raise(sname(), ": star: invalid value: ", format(*this, v));
259  }
260 
262  value_t
263  lmul(const weight_t& w, const value_t& v) const
264  {
265  value_t res;
266  if (!weightset()->is_zero(w))
267  // FIXME: What if there are divisors of 0?
268  for (const auto& m: v)
269  add_here(res, m.first, weightset()->mul(w, m.second));
270  return res;
271  }
272 
274  value_t
275  lmul_letter(const label_t& lhs, const value_t& v) const
276  {
277  value_t res;
278  for (auto i: v)
279  add_here(res,
280  // FIXME: This is wrong, it should be mul, not concat.
281  labelset()->concat(lhs, i.first),
282  i.second);
283  return res;
284  }
285 
287  value_t
288  rmul(const value_t& v, const weight_t& w) const
289  {
290  value_t res;
291  if (!weightset()->is_zero(w))
292  for (const auto& m: v)
293  add_here(res, m.first, weightset()->mul(m.second, w));
294  return res;
295  }
296 
298  value_t
299  rmul_letter(const value_t& v, const label_t& rhs) const
300  {
301  value_t res;
302  for (auto i: v)
303  add_here(res,
304  labelset()->concat(i.first, rhs),
305  i.second);
306  return res;
307  }
308 
309  static value_t
310  rdiv(const value_t&, const value_t&)
311  {
312  throw std::runtime_error("not implemented for polynomials");
313  }
314 
315  static value_t
316  ldiv(const value_t& l, const value_t& r)
317  {
318  return rdiv(r, l);
319  }
320 
322  value_t&
323  ldiv_here(const weight_t& w, value_t& v) const
324  {
325  for (auto& m: v)
326  m.second = weightset()->ldiv(w, m.second);
327  return v;
328  }
329 
331  value_t&
332  rdiv_here(value_t& v, const weight_t& w) const
333  {
334  for (auto& m: v)
335  m.second = weightset()->rdiv(m.second, w);
336  return v;
337  }
338 
339  static bool
340  equals(const value_t& l, const value_t& r) ATTRIBUTE_PURE
341  {
342  return l.size() == r.size()
343  // FIXME: this is wrong, it uses operator== instead of equals().
344  && std::equal(l.begin(), l.end(),
345  r.begin());
346  }
347 
348  const value_t&
349  one() const
350  {
351  static value_t one_{monomial_one()};
352  return one_;
353  }
354 
355  const monomial_t&
356  monomial_one() const
357  {
358  // Singleton.
359  static monomial_t res{labelset()->one(), weightset()->one()};
360  return res;
361  }
362 
363  bool
364  is_one(const value_t& v) const ATTRIBUTE_PURE
365  {
366  if (v.size() != 1)
367  return false;
368  auto i = v.find(labelset()->one());
369  if (i == v.end())
370  return false;
371  return weightset()->is_one(i->second);
372  }
373 
374  const value_t&
375  zero() const
376  {
377  static value_t zero_;
378  return zero_;
379  }
380 
381  bool
382  is_zero(const value_t& v) const
383  {
384  return v.empty();
385  }
386 
387  static constexpr bool show_one() { return true; }
388  static constexpr star_status_t star_status()
389  {
390  return weightset_t::star_status();
391  }
392 
394  static value_t
396  {
397  return v;
398  }
399 
400  private:
401  value_t
402  conv_from_this_weightset(const typename weightset_t::value_t& v) const
403  {
404  monomial_t m{labelset()->one(),
405  weightset()->mul(v, weightset()->one())};
406  return value_t{m};
407  }
408 
409  public:
413  template <typename WS>
414  value_t
415  conv(const WS& ws, const typename WS::value_t& v) const
416  {
417  return conv_from_this_weightset(weightset()->conv(ws, v));
418  }
419 
421  template <typename C>
422  value_t
423  conv(const polynomialset<C>& sps,
424  const typename polynomialset<C>::value_t& v) const
425  {
426  value_t res;
427  typename C::labelset_t sls = * sps.labelset();
428  typename C::weightset_t sws = * sps.weightset();
429  labelset_t tls = * labelset();
430  weightset_t tws = * weightset();
431  for (const auto& m: v)
432  // FIXME: rename this version of add_here.
433  add_here(res, tls.conv(sls, m.first), tws.conv(sws, m.second));
434  return res;
435  }
436 
437 
438  ATTRIBUTE_PURE
439  static bool monomial_less_than(const monomial_t& lhs,
440  const monomial_t& rhs)
441  {
442  if (labelset_t::less_than(lhs.first, rhs.first))
443  return true;
444  else if (labelset_t::less_than(rhs.first, lhs.first))
445  return false;
446  else
447  return weightset_t::less_than(lhs.second, rhs.second);
448  }
449 
450  static bool less_than(const value_t& lhs,
451  const value_t& rhs)
452  {
453  return std::lexicographical_compare(lhs.begin(), lhs.end(),
454  rhs.begin(), rhs.end(),
456  }
457 
458  value_t
459  transpose(const value_t& v) const
460  {
461  value_t res;
462  for (const auto& i: v)
463  res[labelset()->transpose(i.first)] = weightset()->transpose(i.second);
464  return res;
465  }
466 
467  static size_t hash(const monomial_t& m)
468  {
469  size_t res = 0;
470  std::hash_combine(res, labelset_t::hash(m.first));
471  std::hash_combine(res, weightset_t::hash(m.second));
472  return res;
473  }
474 
475  static size_t hash(const value_t& v)
476  {
477  size_t res = 0;
478  for (const auto& m: v)
479  {
480  std::hash_combine(res, labelset_t::hash(m.first));
481  std::hash_combine(res, weightset_t::hash(m.second));
482  }
483  return res;
484  }
485 
487  static self_type make(std::istream& is)
488  {
489  // name is, for instance, "polynomialset<lal_char(abcd)_z>".
490  eat(is, "polynomialset<");
491  auto ctx = Context::make(is);
492  eat(is, '>');
493  return {ctx};
494  }
495 
496  std::ostream&
497  print_set(std::ostream& o, const std::string& format = "text") const
498  {
499  if (format == "latex")
500  {
501  o << "\\mathsf{Poly}[";
502  labelset()->print_set(o, format);
503  o << " \\to ";
504  weightset()->print_set(o, format);
505  o << "]";
506  }
507  else
508  {
509  o << "polynomialset<";
510  labelset()->print_set(o, format);
511  o << "_";
512  weightset()->print_set(o, format);
513  o << ">";
514  }
515  return o;
516  }
517 
526  value_t
527  conv(std::istream& i, const char sep = '+') const
528  {
529  value_t res;
530 #define SKIP_SPACES() \
531  while (isspace(i.peek())) \
532  i.ignore()
533 
534  do
535  {
536  // Possibly a weight in braces.
537  SKIP_SPACES();
538  weight_t w = weightset()->one();
539  bool default_w = true;
540  if (i.peek() == langle)
541  {
542  // FIXME: convert to use conv(std::istream).
543  w = conv(*weightset(), bracketed(i, langle, rangle));
544  default_w = false;
545  }
546 
547  // Possibly, a label.
548  SKIP_SPACES();
549  // Whether the label is \z.
550  bool is_zero = false;
551  if (i.peek() == '\\')
552  {
553  i.ignore();
554  if (i.peek() == 'z')
555  {
556  is_zero = true;
557  i.ignore();
558  }
559  else
560  i.unget();
561  }
562 
563  if (!is_zero)
564  {
565  // The label is not \z.
566 
567  // Handle ranges
568  if (i.peek() == '[')
569  for (auto c : labelset()->convs(i))
570  add_here(res, c, w);
571  else
572  {
573 
574  // Register the current position in the stream, so that
575  // we reject inputs such as "a++a" in LAW (where the
576  // labelset::conv would accept the empty string between
577  // the two "+").
578  std::streampos p = i.tellg();
579  label_t label = labelset()->special();
580  // Accept an implicit label (which can be an error,
581  // e.g., for LAL) if there is an explicit weight.
582  try
583  {
584  label = labelset()->conv(i);
585  }
586  catch (const std::domain_error&)
587  {}
588  // We must have at least a weight or a label.
589  if (default_w && p == i.tellg())
590  raise(sname(), ": conv: invalid value: ",
591  str_escape(i.peek()),
592  " contains an empty label"
593  " (did you mean \\e or \\z?)");
594  add_here(res, label, w);
595  }
596  }
597 
598  // sep (e.g., '+'), or stop parsing.
599  SKIP_SPACES();
600  if (i.peek() == sep)
601  i.ignore();
602  else
603  break;
604  }
605  while (true);
606 #undef SKIP_SPACES
607 
608  return res;
609  }
610 
612  std::ostream&
613  print(const monomial_t& m, std::ostream& out,
614  const std::string& format = "text") const
615  {
616  static bool parens = getenv("AWALI_PARENS");
617  print_weight_(m.second, out, format);
618  if (parens)
619  out << (format == "latex" ? "\\left(" : "(");
620  labelset()->print(m.first, out, format);
621  if (parens)
622  out << (format == "latex" ? "\\right)" : ")");
623  return out;
624  }
625 
627  std::ostream&
628  print(const value_t& v, std::ostream& out,
629  const std::string& format = "text",
630  const std::string& sep = " + ") const
631  {
632  bool latex = format == "latex";
633  if (v.empty())
634  out << (latex ? "\\emptyset" : "\\z");
635  else
636  print_<context_t>(v, out, format,
637  latex && sep == " + " ? " \\oplus " : sep);
638  return out;
639  }
640 
641  std::string
642  format(const value_t& v, const std::string& sep = " + ",
643  const std::string& fmt = "text") const
644  {
645  std::ostringstream o;
646  print(v, o, fmt, sep);
647  return o.str();
648  }
649 
651  std::string
652  format(const monomial_t& m) const
653  {
654  std::ostringstream o;
655  print(m, o, "text");
656  return o.str();
657  }
658 
659  private:
661  std::ostream&
662  print_weight_(const weight_t& w, std::ostream& out,
663  const std::string& format = "text") const
664  {
665  static bool parens = getenv("AWALI_PARENS");
666  if (parens || weightset()->show_one() || !weightset()->is_one(w))
667  {
668  out << (format == "latex" ? "\\langle " : std::string{langle});
669  weightset()->print(w, out, format);
670  out << (format == "latex" ? "\\rangle " : std::string{rangle});
671  }
672  return out;
673  }
674 
676  std::ostream&
677  print_without_ranges_(const value_t& v, std::ostream& out,
678  const std::string& format = "text",
679  const std::string& sep = " + ") const
680  {
681  bool first = true;
682  for (const auto& m: v)
683  {
684  if (!first)
685  out << sep;
686  first = false;
687  print(m, out, format);
688  }
689  return out;
690  }
691 
693  std::ostream&
694  print_with_ranges_(const value_t& v, std::ostream& out,
695  const std::string& format = "text",
696  const std::string& sep = " + ") const
697  {
698  if (sep == " + " || v.size() <= 3)
699  return print_without_ranges_(v, out, format, sep);
700 
701  // No ranges if the weights aren't all the same.
702  std::vector<label_t> letters;
703 // weight_t first_w = weightset()->zero();
704 // commented out by VM on 2022-02-14
705  for (const auto& m: v)
706  {
707  if(labelset()->is_one(m.first))
708  continue;
709  /*
710  if (weightset()->is_zero(first_w))
711  first_w = m.second;
712  else if (!weightset()->equals(m.second, first_w))
713  return print_without_ranges_(v, out, format, sep);
714  */
715  letters.push_back(m.first);
716  }
717 
718  // Print with ranges. First, the constant-term.
719  if (labelset()->is_one(std::begin(v)->first))
720  {
721  print(*std::begin(v), out, format);
722  if (1 < v.size())
723  out << sep;
724  }
725 
726  label_t left,last;
727  bool start=true;
728  for(const auto &l : letters)
729  if(start) {
730  start=false;
731  left=l;
732  last=l;
733  }
734  else {
735  if(l == last+1 &&
736  weightset()->equals(get_weight(v,left),get_weight(v,l))) {
737  last=l;
738  }
739  else {
740  if(last-left>1) {
741  print_weight_(get_weight(v, left), out, format);
742  out << '[';
743  labelset()->print(left, out, format);
744  out << '-';
745  labelset()->print(last, out, format);
746  out << ']' << sep;
747  }
748  else
749  for(auto le = left; le<=last; ++le) {
750  print_weight_(get_weight(v, le), out, format);
751  labelset()->print(le, out, format);
752  out << sep;
753  }
754  left = last = l;
755  }
756  }
757  if(!start) {
758  if (last-left>2) {
759  print_weight_(get_weight(v, left), out, format);
760  out << '[';
761  labelset()->print(left, out, format);
762  out << '-';
763  labelset()->print(last, out, format);
764  out << ']';
765  }
766  else
767  for(auto le = left; le<=last; ++le) {
768  print_weight_(get_weight(v, le), out, format);
769  labelset()->print(le, out, format);
770  if(le!=last)
771  out << sep;
772  }
773  }
774  return out;
775  }
776 
778  template <typename context>
779  typename std::enable_if<!(context::is_lal || context::is_lan),
780  std::ostream&>::type
781  print_(const value_t& v, std::ostream& out,
782  const std::string& format = "text",
783  const std::string& sep = " + ") const
784  {
785  return print_without_ranges_(v, out, format, sep);
786  }
787 
789  template <typename Ctx>
790  typename std::enable_if<Ctx::is_lal || Ctx::is_lan,
791  std::ostream&>::type
792  print_(const value_t& v, std::ostream& out,
793  const std::string& format = "text",
794  const std::string& sep = " + ") const
795  {
796  return print_with_ranges_(v, out, format, sep);
797  }
798 
799 
800  private:
801  context_t ctx_;
802 
804  constexpr static char langle = '<';
806  constexpr static char rangle = '>';
807  };
808 
810  template <typename Aut>
811  typename polynomialset<context_t_of<Aut>>::value_t
812  get_entry(const Aut& aut,
813  state_t s, state_t d)
814  {
815  using automaton_t = Aut;
816  using context_t = context_t_of<automaton_t>;
817  using polynomialset_t = polynomialset<context_t>;
818  using polynomial_t = typename polynomialset_t::value_t;
819 
820  polynomial_t res;
821  for (auto t : aut->outin(s, d))
822  // Bypass set_weight(), because we know that the weight is
823  // nonzero, and that there is only one weight per letter.
824  res[aut->label_of(t)] = aut->weight_of(t);
825  return res;
826  }
827 
828  // FIXME: this works perfectly well, but I'd like a two-parameter version.
829  template <typename PLS1, typename PWS1,
830  typename PLS2, typename PWS2>
831  inline
832  auto
837  {
838  return {join(p1.context(), p2.context())};
839  }
840 
841  template <typename WS1,
842  typename PLS2, typename PWS2>
843  inline
844  auto
845  join(const WS1& w1,
848  {
849  using ctx_t = context<PLS2, join_t<WS1, PWS2>>;
850  return ctx_t{* p2.labelset(), join(w1, * p2.weightset())};
851  }
852 
853  template <typename PLS1, typename PWS1,
854  typename WS2>
855  inline
856  auto
858  const WS2& w2)
860  {
861  return join(w2, p1);
862  }
863 
864 }}//end of ns awali::stc
865 
866 #endif // !AWALI_WEIGHTSET_POLYNOMIALSET_HH
The semiring of complex numbers.
Definition: c.hh:44
carries the algebraic settings of automata
Definition: context.hh:40
@ is_lal
Definition: context.hh:50
@ is_lan
Definition: context.hh:51
const labelset_ptr & labelset() const
Definition: context.hh:152
Linear combination of labels: map labels to weights.
Definition: polynomialset.hh:69
typename context_t::labelset_ptr labelset_ptr
Definition: polynomialset.hh:77
value_t & add_here(value_t &v, const label_t &l, const weight_t k) const
v += (l, k).
Definition: polynomialset.hh:147
polynomialset(const polynomialset &)=default
static size_t hash(const value_t &v)
Definition: polynomialset.hh:475
static std::string sname()
The static name.
Definition: polynomialset.hh:94
value_t lmul_letter(const label_t &lhs, const value_t &v) const
Left product by a label.
Definition: polynomialset.hh:275
value_t mul(const value_t &l, const value_t &r) const
The product of polynomials l and r.
Definition: polynomialset.hh:192
const monomial_t & monomial_one() const
Definition: polynomialset.hh:356
const value_t & one() const
Definition: polynomialset.hh:349
typename value_t::value_type monomial_t
A pair <label, weight>.
Definition: polynomialset.hh:85
value_t conjunction(const value_t &l, const value_t &r) const
The conjunction of polynomials l and r.
Definition: polynomialset.hh:206
const weightset_ptr & weightset() const
Definition: polynomialset.hh:107
std::map< label_t, weight_t, internal::less< labelset_t > > value_t
Definition: polynomialset.hh:83
Context context_t
Definition: polynomialset.hh:72
labelset_t_of< context_t > labelset_t
Definition: polynomialset.hh:73
static constexpr star_status_t star_status()
Definition: polynomialset.hh:388
bool is_one(const value_t &v) const ATTRIBUTE_PURE
Definition: polynomialset.hh:364
typename labelset_t::value_t label_t
Polynomials over labels.
Definition: polynomialset.hh:80
static value_t rdiv(const value_t &, const value_t &)
Definition: polynomialset.hh:310
value_t & add_here(value_t &v, const monomial_t &p) const
v += m.
Definition: polynomialset.hh:139
static size_t hash(const monomial_t &m)
Definition: polynomialset.hh:467
std::string format(const value_t &v, const std::string &sep=" + ", const std::string &fmt="text") const
Definition: polynomialset.hh:642
value_t & add_here(value_t &v, const value_t &p) const
v += p.
Definition: polynomialset.hh:130
value_t conv(const polynomialset< C > &sps, const typename polynomialset< C >::value_t &v) const
Convert from another polynomialset to type_t.
Definition: polynomialset.hh:423
bool is_zero(const value_t &v) const
Definition: polynomialset.hh:382
value_t & del_weight(value_t &v, const label_t &w) const
Remove the monomial of w in v.
Definition: polynomialset.hh:111
weightset_t_of< context_t > weightset_t
Definition: polynomialset.hh:74
const context_t & context() const
Definition: polynomialset.hh:105
static ATTRIBUTE_PURE bool monomial_less_than(const monomial_t &lhs, const monomial_t &rhs)
Definition: polynomialset.hh:439
value_t plus(const value_t &v) const
The star of polynomial v.
Definition: polynomialset.hh:241
value_t add(const value_t &l, const value_t &r) const
The sum of polynomials l and r.
Definition: polynomialset.hh:182
static bool less_than(const value_t &lhs, const value_t &rhs)
Definition: polynomialset.hh:450
polynomialset(const context_t &ctx)
Definition: polynomialset.hh:89
value_t star(const value_t &v) const
The star of polynomial v.
Definition: polynomialset.hh:219
weight_t_of< context_t > weight_t
Definition: polynomialset.hh:81
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.
Definition: polynomialset.hh:119
static value_t conv(self_type, value_t v)
Conversion from (this and) other weightsets.
Definition: polynomialset.hh:395
std::ostream & print(const value_t &v, std::ostream &out, const std::string &format="text", const std::string &sep=" + ") const
Print a value (a polynomial).
Definition: polynomialset.hh:628
value_t conv(std::istream &i, const char sep='+') const
Construct from a string.
Definition: polynomialset.hh:527
std::ostream & print(const monomial_t &m, std::ostream &out, const std::string &format="text") const
Print a monomial.
Definition: polynomialset.hh:613
typename context_t::weightset_ptr weightset_ptr
Definition: polynomialset.hh:78
value_t transpose(const value_t &v) const
Definition: polynomialset.hh:459
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.
Definition: polynomialset.hh:415
static constexpr bool show_one()
Definition: polynomialset.hh:387
static value_t ldiv(const value_t &l, const value_t &r)
Definition: polynomialset.hh:316
std::string format(const monomial_t &m) const
Format a monomial.
Definition: polynomialset.hh:652
const labelset_ptr & labelset() const
Definition: polynomialset.hh:106
std::ostream & print_set(std::ostream &o, const std::string &format="text") const
Definition: polynomialset.hh:497
static bool equals(const value_t &l, const value_t &r) ATTRIBUTE_PURE
Definition: polynomialset.hh:340
const weight_t get_weight(const value_t &v, const label_t &w) const ATTRIBUTE_PURE
Definition: polynomialset.hh:171
value_t & ldiv_here(const weight_t &w, value_t &v) const
Left exterior division.
Definition: polynomialset.hh:323
const value_t & zero() const
Definition: polynomialset.hh:375
static self_type make(std::istream &is)
Build from the description in is.
Definition: polynomialset.hh:487
value_t & rdiv_here(value_t &v, const weight_t &w) const
Right exterior division.
Definition: polynomialset.hh:332
value_t rmul(const value_t &v, const weight_t &w) const
Right exterior product.
Definition: polynomialset.hh:288
value_t lmul(const weight_t &w, const value_t &v) const
Left exterior product.
Definition: polynomialset.hh:263
value_t rmul_letter(const value_t &v, const label_t &rhs) const
Right product.
Definition: polynomialset.hh:299
std::string vname(bool full=true) const
The dynamic name.
Definition: polynomialset.hh:100
The semiring of floating Numbers.
Definition: r.hh:35
star_status_t
The different behaviours a weightset may have with respect to the star.
Definition: enums.hh:163
bool equal(node_t const *left, node_t const *right, path_t *path=nullptr)
void eat(std::istream &is, char c)
Check lookahead character and advance.
Definition: stream.hh:62
RatExpSet::ratexp_t less_than(const RatExpSet &rs, const typename RatExpSet::ratexp_t &v)
Definition: less_than.hh:168
typename internal::weight_t_of_impl< internal::base_t< ValueSet > >::type weight_t_of
Helper to retrieve the type of the weights of a value set.
Definition: traits.hh:81
auto label_is_zero(const LabelSet &ls, const typename LabelSet::value_t *l) -> decltype(ls.is_zero(l), bool())
Definition: polynomialset.hh:45
decltype(join(std::declval< ValueSets >()...)) join_t
Computation of the join of some value sets.
Definition: context.hh:210
auto join(const ratexpset< Ctx1 > &a, const ratexpset< Ctx2 > &b) -> ratexpset< join_t< Ctx1, Ctx2 >>
The union of two ratexpsets.
Definition: ratexpset.hh:449
polynomialset< context_t_of< Aut > >::value_t get_entry(const Aut &aut, state_t s, state_t d)
The entry between two states of an automaton.
Definition: polynomialset.hh:812
std::ostream & str_escape(std::ostream &os, const int c)
Definition: escape.hh:30
typename internal::context_t_of_impl< internal::base_t< ValueSet > >::type context_t_of
Helper to retrieve the type of the context of a value set.
Definition: traits.hh:66
typename internal::labelset_t_of_impl< internal::base_t< ValueSet > >::type labelset_t_of
Helper to retrieve the type of the labelset of a value set.
Definition: traits.hh:76
std::string bracketed(std::istream &i, const char lbracket, const char rbracket)
An narrow-char stream that discards the output.
typename internal::weightset_t_of_impl< internal::base_t< ValueSet > >::type weightset_t_of
Helper to retrieve the type of the weightset of a value set.
Definition: traits.hh:86
static const std::string full
Completely version of Awali as a std::string.
Definition: version.hh:42
Main namespace of Awali.
Definition: ato.hh:22
unsigned state_t
Definition: types.hh:21
#define SKIP_SPACES()