Awali
Another Weighted Automata library
polynomialset.hh
Go to the documentation of this file.
1 // This file is part of Awali.
2 // Copyright 2016-2021 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  lmul(const weight_t& w, const value_t& v) const
242  {
243  value_t res;
244  if (!weightset()->is_zero(w))
245  // FIXME: What if there are divisors of 0?
246  for (const auto& m: v)
247  add_here(res, m.first, weightset()->mul(w, m.second));
248  return res;
249  }
250 
252  value_t
253  lmul_letter(const label_t& lhs, const value_t& v) const
254  {
255  value_t res;
256  for (auto i: v)
257  add_here(res,
258  // FIXME: This is wrong, it should be mul, not concat.
259  labelset()->concat(lhs, i.first),
260  i.second);
261  return res;
262  }
263 
265  value_t
266  rmul(const value_t& v, const weight_t& w) const
267  {
268  value_t res;
269  if (!weightset()->is_zero(w))
270  for (const auto& m: v)
271  add_here(res, m.first, weightset()->mul(m.second, w));
272  return res;
273  }
274 
276  value_t
277  rmul_letter(const value_t& v, const label_t& rhs) const
278  {
279  value_t res;
280  for (auto i: v)
281  add_here(res,
282  labelset()->concat(i.first, rhs),
283  i.second);
284  return res;
285  }
286 
287  static value_t
288  rdiv(const value_t&, const value_t&)
289  {
290  throw std::runtime_error("not implemented for polynomials");
291  }
292 
293  static value_t
294  ldiv(const value_t& l, const value_t& r)
295  {
296  return rdiv(r, l);
297  }
298 
300  value_t&
301  ldiv_here(const weight_t& w, value_t& v) const
302  {
303  for (auto& m: v)
304  m.second = weightset()->ldiv(w, m.second);
305  return v;
306  }
307 
309  value_t&
310  rdiv_here(value_t& v, const weight_t& w) const
311  {
312  for (auto& m: v)
313  m.second = weightset()->rdiv(m.second, w);
314  return v;
315  }
316 
317  static bool
318  equals(const value_t& l, const value_t& r) ATTRIBUTE_PURE
319  {
320  return l.size() == r.size()
321  // FIXME: this is wrong, it uses operator== instead of equals().
322  && std::equal(l.begin(), l.end(),
323  r.begin());
324  }
325 
326  const value_t&
327  one() const
328  {
329  static value_t one_{monomial_one()};
330  return one_;
331  }
332 
333  const monomial_t&
334  monomial_one() const
335  {
336  // Singleton.
337  static monomial_t res{labelset()->one(), weightset()->one()};
338  return res;
339  }
340 
341  bool
342  is_one(const value_t& v) const ATTRIBUTE_PURE
343  {
344  if (v.size() != 1)
345  return false;
346  auto i = v.find(labelset()->one());
347  if (i == v.end())
348  return false;
349  return weightset()->is_one(i->second);
350  }
351 
352  const value_t&
353  zero() const
354  {
355  static value_t zero_;
356  return zero_;
357  }
358 
359  bool
360  is_zero(const value_t& v) const
361  {
362  return v.empty();
363  }
364 
365  static constexpr bool show_one() { return true; }
366  static constexpr star_status_t star_status()
367  {
368  return weightset_t::star_status();
369  }
370 
372  static value_t
374  {
375  return v;
376  }
377 
378  private:
379  value_t
380  conv_from_this_weightset(const typename weightset_t::value_t& v) const
381  {
382  monomial_t m{labelset()->one(),
383  weightset()->mul(v, weightset()->one())};
384  return value_t{m};
385  }
386 
387  public:
391  template <typename WS>
392  value_t
393  conv(const WS& ws, const typename WS::value_t& v) const
394  {
395  return conv_from_this_weightset(weightset()->conv(ws, v));
396  }
397 
399  template <typename C>
400  value_t
401  conv(const polynomialset<C>& sps,
402  const typename polynomialset<C>::value_t& v) const
403  {
404  value_t res;
405  typename C::labelset_t sls = * sps.labelset();
406  typename C::weightset_t sws = * sps.weightset();
407  labelset_t tls = * labelset();
408  weightset_t tws = * weightset();
409  for (const auto& m: v)
410  // FIXME: rename this version of add_here.
411  add_here(res, tls.conv(sls, m.first), tws.conv(sws, m.second));
412  return res;
413  }
414 
415 
416  ATTRIBUTE_PURE
417  static bool monomial_less_than(const monomial_t& lhs,
418  const monomial_t& rhs)
419  {
420  if (labelset_t::less_than(lhs.first, rhs.first))
421  return true;
422  else if (labelset_t::less_than(rhs.first, lhs.first))
423  return false;
424  else
425  return weightset_t::less_than(lhs.second, rhs.second);
426  }
427 
428  static bool less_than(const value_t& lhs,
429  const value_t& rhs)
430  {
431  return std::lexicographical_compare(lhs.begin(), lhs.end(),
432  rhs.begin(), rhs.end(),
434  }
435 
436  value_t
437  transpose(const value_t& v) const
438  {
439  value_t res;
440  for (const auto& i: v)
441  res[labelset()->transpose(i.first)] = weightset()->transpose(i.second);
442  return res;
443  }
444 
445  static size_t hash(const monomial_t& m)
446  {
447  size_t res = 0;
448  std::hash_combine(res, labelset_t::hash(m.first));
449  std::hash_combine(res, weightset_t::hash(m.second));
450  return res;
451  }
452 
453  static size_t hash(const value_t& v)
454  {
455  size_t res = 0;
456  for (const auto& m: v)
457  {
458  std::hash_combine(res, labelset_t::hash(m.first));
459  std::hash_combine(res, weightset_t::hash(m.second));
460  }
461  return res;
462  }
463 
465  static self_type make(std::istream& is)
466  {
467  // name is, for instance, "polynomialset<lal_char(abcd)_z>".
468  eat(is, "polynomialset<");
469  auto ctx = Context::make(is);
470  eat(is, '>');
471  return {ctx};
472  }
473 
474  std::ostream&
475  print_set(std::ostream& o, const std::string& format = "text") const
476  {
477  if (format == "latex")
478  {
479  o << "\\mathsf{Poly}[";
480  labelset()->print_set(o, format);
481  o << " \\to ";
482  weightset()->print_set(o, format);
483  o << "]";
484  }
485  else
486  {
487  o << "polynomialset<";
488  labelset()->print_set(o, format);
489  o << "_";
490  weightset()->print_set(o, format);
491  o << ">";
492  }
493  return o;
494  }
495 
504  value_t
505  conv(std::istream& i, const char sep = '+') const
506  {
507  value_t res;
508 #define SKIP_SPACES() \
509  while (isspace(i.peek())) \
510  i.ignore()
511 
512  do
513  {
514  // Possibly a weight in braces.
515  SKIP_SPACES();
516  weight_t w = weightset()->one();
517  bool default_w = true;
518  if (i.peek() == langle)
519  {
520  // FIXME: convert to use conv(std::istream).
521  w = conv(*weightset(), bracketed(i, langle, rangle));
522  default_w = false;
523  }
524 
525  // Possibly, a label.
526  SKIP_SPACES();
527  // Whether the label is \z.
528  bool is_zero = false;
529  if (i.peek() == '\\')
530  {
531  i.ignore();
532  if (i.peek() == 'z')
533  {
534  is_zero = true;
535  i.ignore();
536  }
537  else
538  i.unget();
539  }
540 
541  if (!is_zero)
542  {
543  // The label is not \z.
544 
545  // Handle ranges
546  if (i.peek() == '[')
547  for (auto c : labelset()->convs(i))
548  add_here(res, c, w);
549  else
550  {
551 
552  // Register the current position in the stream, so that
553  // we reject inputs such as "a++a" in LAW (where the
554  // labelset::conv would accept the empty string between
555  // the two "+").
556  std::streampos p = i.tellg();
557  label_t label = labelset()->special();
558  // Accept an implicit label (which can be an error,
559  // e.g., for LAL) if there is an explicit weight.
560  try
561  {
562  label = labelset()->conv(i);
563  }
564  catch (const std::domain_error&)
565  {}
566  // We must have at least a weight or a label.
567  if (default_w && p == i.tellg())
568  raise(sname(), ": conv: invalid value: ",
569  str_escape(i.peek()),
570  " contains an empty label"
571  " (did you mean \\e or \\z?)");
572  add_here(res, label, w);
573  }
574  }
575 
576  // sep (e.g., '+'), or stop parsing.
577  SKIP_SPACES();
578  if (i.peek() == sep)
579  i.ignore();
580  else
581  break;
582  }
583  while (true);
584 #undef SKIP_SPACES
585 
586  return res;
587  }
588 
590  std::ostream&
591  print(const monomial_t& m, std::ostream& out,
592  const std::string& format = "text") const
593  {
594  static bool parens = getenv("AWALI_PARENS");
595  print_weight_(m.second, out, format);
596  if (parens)
597  out << (format == "latex" ? "\\left(" : "(");
598  labelset()->print(m.first, out, format);
599  if (parens)
600  out << (format == "latex" ? "\\right)" : ")");
601  return out;
602  }
603 
605  std::ostream&
606  print(const value_t& v, std::ostream& out,
607  const std::string& format = "text",
608  const std::string& sep = " + ") const
609  {
610  bool latex = format == "latex";
611  if (v.empty())
612  out << (latex ? "\\emptyset" : "\\z");
613  else
614  print_<context_t>(v, out, format,
615  latex && sep == " + " ? " \\oplus " : sep);
616  return out;
617  }
618 
619  std::string
620  format(const value_t& v, const std::string& sep = " + ",
621  const std::string& fmt = "text") const
622  {
623  std::ostringstream o;
624  print(v, o, fmt, sep);
625  return o.str();
626  }
627 
629  std::string
630  format(const monomial_t& m) const
631  {
632  std::ostringstream o;
633  print(m, o, "text");
634  return o.str();
635  }
636 
637  private:
639  std::ostream&
640  print_weight_(const weight_t& w, std::ostream& out,
641  const std::string& format = "text") const
642  {
643  static bool parens = getenv("AWALI_PARENS");
644  if (parens || weightset()->show_one() || !weightset()->is_one(w))
645  {
646  out << (format == "latex" ? "\\langle " : std::string{langle});
647  weightset()->print(w, out, format);
648  out << (format == "latex" ? "\\rangle " : std::string{rangle});
649  }
650  return out;
651  }
652 
654  std::ostream&
655  print_without_ranges_(const value_t& v, std::ostream& out,
656  const std::string& format = "text",
657  const std::string& sep = " + ") const
658  {
659  bool first = true;
660  for (const auto& m: v)
661  {
662  if (!first)
663  out << sep;
664  first = false;
665  print(m, out, format);
666  }
667  return out;
668  }
669 
671  std::ostream&
672  print_with_ranges_(const value_t& v, std::ostream& out,
673  const std::string& format = "text",
674  const std::string& sep = " + ") const
675  {
676  if (sep == " + " || v.size() <= 3)
677  return print_without_ranges_(v, out, format, sep);
678 
679  // No ranges if the weights aren't all the same.
680  std::vector<label_t> letters;
681  weight_t first_w = weightset()->zero();
682  for (const auto& m: v)
683  {
684  if(labelset()->is_one(m.first))
685  continue;
686  /*
687  if (weightset()->is_zero(first_w))
688  first_w = m.second;
689  else if (!weightset()->equals(m.second, first_w))
690  return print_without_ranges_(v, out, format, sep);
691  */
692  letters.push_back(m.first);
693  }
694 
695  // Print with ranges. First, the constant-term.
696  if (labelset()->is_one(std::begin(v)->first))
697  {
698  print(*std::begin(v), out, format);
699  if (1 < v.size())
700  out << sep;
701  }
702 
703  label_t left,last;
704  bool start=true;
705  for(const auto &l : letters)
706  if(start) {
707  start=false;
708  left=l;
709  last=l;
710  }
711  else {
712  if(l == last+1 &&
713  weightset()->equals(get_weight(v,left),get_weight(v,l))) {
714  last=l;
715  }
716  else {
717  if(last-left>1) {
718  print_weight_(get_weight(v, left), out, format);
719  out << '[';
720  labelset()->print(left, out, format);
721  out << '-';
722  labelset()->print(last, out, format);
723  out << ']' << sep;
724  }
725  else
726  for(auto le = left; le<=last; ++le) {
727  print_weight_(get_weight(v, le), out, format);
728  labelset()->print(le, out, format);
729  out << sep;
730  }
731  left = last = l;
732  }
733  }
734  if(last-left>2) {
735  print_weight_(get_weight(v, left), out, format);
736  out << '[';
737  labelset()->print(left, out, format);
738  out << '-';
739  labelset()->print(last, out, format);
740  out << ']';
741  }
742  else
743  for(auto le = left; le<=last; ++le) {
744  print_weight_(get_weight(v, le), out, format);
745  labelset()->print(le, out, format);
746  if(le!=last)
747  out << sep;
748  }
749  return out;
750  }
751 
753  template <typename context>
754  typename std::enable_if<!(context::is_lal || context::is_lan),
755  std::ostream&>::type
756  print_(const value_t& v, std::ostream& out,
757  const std::string& format = "text",
758  const std::string& sep = " + ") const
759  {
760  return print_without_ranges_(v, out, format, sep);
761  }
762 
764  template <typename Ctx>
765  typename std::enable_if<Ctx::is_lal || Ctx::is_lan,
766  std::ostream&>::type
767  print_(const value_t& v, std::ostream& out,
768  const std::string& format = "text",
769  const std::string& sep = " + ") const
770  {
771  return print_with_ranges_(v, out, format, sep);
772  }
773 
774 
775  private:
776  context_t ctx_;
777 
779  constexpr static char langle = '<';
781  constexpr static char rangle = '>';
782  };
783 
785  template <typename Aut>
786  typename polynomialset<context_t_of<Aut>>::value_t
787  get_entry(const Aut& aut,
788  state_t s, state_t d)
789  {
790  using automaton_t = Aut;
791  using context_t = context_t_of<automaton_t>;
792  using polynomialset_t = polynomialset<context_t>;
793  using polynomial_t = typename polynomialset_t::value_t;
794 
795  polynomial_t res;
796  for (auto t : aut->outin(s, d))
797  // Bypass set_weight(), because we know that the weight is
798  // nonzero, and that there is only one weight per letter.
799  res[aut->label_of(t)] = aut->weight_of(t);
800  return res;
801  }
802 
803  // FIXME: this works perfectly well, but I'd like a two-parameter version.
804  template <typename PLS1, typename PWS1,
805  typename PLS2, typename PWS2>
806  inline
807  auto
812  {
813  return {join(p1.context(), p2.context())};
814  }
815 
816  template <typename WS1,
817  typename PLS2, typename PWS2>
818  inline
819  auto
820  join(const WS1& w1,
823  {
824  using ctx_t = context<PLS2, join_t<WS1, PWS2>>;
825  return ctx_t{* p2.labelset(), join(w1, * p2.weightset())};
826  }
827 
828  template <typename PLS1, typename PWS1,
829  typename WS2>
830  inline
831  auto
833  const WS2& w2)
835  {
836  return join(w2, p1);
837  }
838 
839 }}//end of ns awali::stc
840 
841 #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:149
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:453
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:253
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:334
const value_t & one() const
Definition: polynomialset.hh:327
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:366
bool is_one(const value_t &v) const ATTRIBUTE_PURE
Definition: polynomialset.hh:342
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:288
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:445
std::string format(const value_t &v, const std::string &sep=" + ", const std::string &fmt="text") const
Definition: polynomialset.hh:620
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:401
bool is_zero(const value_t &v) const
Definition: polynomialset.hh:360
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:417
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:428
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:373
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:606
value_t conv(std::istream &i, const char sep='+') const
Construct from a string.
Definition: polynomialset.hh:505
std::ostream & print(const monomial_t &m, std::ostream &out, const std::string &format="text") const
Print a monomial.
Definition: polynomialset.hh:591
typename context_t::weightset_ptr weightset_ptr
Definition: polynomialset.hh:78
value_t transpose(const value_t &v) const
Definition: polynomialset.hh:437
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:393
static constexpr bool show_one()
Definition: polynomialset.hh:365
static value_t ldiv(const value_t &l, const value_t &r)
Definition: polynomialset.hh:294
std::string format(const monomial_t &m) const
Format a monomial.
Definition: polynomialset.hh:630
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:475
static bool equals(const value_t &l, const value_t &r) ATTRIBUTE_PURE
Definition: polynomialset.hh:318
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:301
const value_t & zero() const
Definition: polynomialset.hh:353
static self_type make(std::istream &is)
Build from the description in is.
Definition: polynomialset.hh:465
value_t & rdiv_here(value_t &v, const weight_t &w) const
Right exterior division.
Definition: polynomialset.hh:310
value_t rmul(const value_t &v, const weight_t &w) const
Right exterior product.
Definition: polynomialset.hh:266
value_t lmul(const weight_t &w, const value_t &v) const
Left exterior product.
Definition: polynomialset.hh:241
value_t rmul_letter(const value_t &v, const label_t &rhs) const
Right product.
Definition: polynomialset.hh:277
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:161
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:166
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:206
auto join(const ratexpset< Ctx1 > &a, const ratexpset< Ctx2 > &b) -> ratexpset< join_t< Ctx1, Ctx2 >>
The union of two ratexpsets.
Definition: ratexpset.hh:448
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:787
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:40
Main namespace of Awali.
Definition: ato.hh:22
unsigned state_t
Definition: types.hh:21
#define SKIP_SPACES()