Vcsn  2.3
Be Rational
expansionset.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <vcsn/algos/project.hh> // project
4 #include <vcsn/algos/split.hh> // expression_polynomialset_t
5 #include <vcsn/misc/map.hh>
6 #include <vcsn/misc/static-if.hh>
7 
8 namespace vcsn
9 {
10 
11  namespace rat
12  {
13 
14  /*---------------.
15  | expansionset. |
16  `---------------*/
17 
18  template <typename ExpSet>
19  struct expansionset
20  {
21  public:
22  using expressionset_t = ExpSet;
27  using expression_t = typename expressionset_t::value_t;
29  using weight_t = typename weightset_t::value_t;
30 
33  using monomial_t = typename polynomialset_t::monomial_t;
34 
35  constexpr static const char* me() { return "expansion"; }
36 
37  // Keep it sorted to ensure determinism, and better looking
38  // results. Anyway, rough benches show no difference between
39  // map and unordered_map here.
40  using polys_t = std::map<label_t, polynomial_t, vcsn::less<labelset_t>>;
41 
43  struct value_t
44  {
47  };
48 
50  : rs_(rs)
51  {}
52 
54  static symbol sname()
55  {
56  static auto res
57  = symbol{"expansionset<" + expressionset_t::sname() + '>'};
58  return res;
59  }
60 
63  {
64  return rs_;
65  }
66 
69  {
70  return ps_;
71  }
72 
74  const context_t& context() const
75  {
76  return rs_.context();
77  }
78 
80  std::ostream& print_set(std::ostream& o, format fmt = {}) const
81  {
82  switch (fmt.kind())
83  {
84  case format::latex:
85  o << "\\mathsf{Expansion}[";
86  rs_.print_set(o, fmt);
87  o << ']';
88  break;
89  case format::sname:
90  o << "expansionset<";
91  rs_.print_set(o, fmt);
92  o << ">";
93  break;
94  case format::text:
95  case format::utf8:
96  o << "Expansion[";
97  rs_.print_set(o, fmt);
98  o << ']';
99  break;
100  case format::raw:
101  assert(0);
102  break;
103  }
104  return o;
105  }
106 
108  std::ostream& print(const value_t& v, std::ostream& o,
109  format fmt = {}) const
110  {
111  bool first = true;
112  if (!ws_.is_zero(v.constant) || v.polynomials.empty())
113  {
114  o << (fmt == format::latex ? "\\left\\langle "
115  : fmt == format::utf8 ? "⟨"
116  : "<");
117  ws_.print(v.constant, o, fmt.for_weights());
118  o << (fmt == format::latex ? "\\right\\rangle "
119  : fmt == format::utf8 ? "⟩"
120  : ">");
121  first = false;
122  }
123  for (const auto& p: v.polynomials)
124  {
125  if (!first)
126  o << (fmt == format::latex ? " \\oplus "
127  : fmt == format::utf8 ? " ⊕ "
128  : " + ");
129  first = false;
130  ls_.print(p.first, o, fmt.for_labels());
131  o << (fmt == format::latex ? " \\odot \\left["
132  : fmt == format::utf8 ? "⊙["
133  : ".[");
134  ps_.print(p.second, o, fmt);
135  o << (fmt == format::latex ? "\\right]"
136  : fmt == format::utf8 ? "]"
137  : "]");
138  }
139  return o;
140  }
141 
144  {
146  return normalize_(res, has_one);
147  }
148 
152  value_t& normalize_(value_t& res, std::true_type) const
153  {
154  auto one = ls_.one();
155  auto i = res.polynomials.find(one);
156  if (i != std::end(res.polynomials))
157  {
158  auto j = i->second.find(rs_.one());
159  if (j != std::end(i->second))
160  {
161  res.constant = ws_.add(res.constant, weight_of(*j));
162  i->second.erase(j);
163  if (i->second.empty())
164  res.polynomials.erase(i);
165  }
166  }
167  return res;
168  }
169 
171  value_t& normalize_(value_t& res, std::false_type) const
172  {
173  return res;
174  }
175 
178  {
180  return denormalize_(res, has_one);
181  }
182 
185  value_t& denormalize_(value_t& res, std::true_type) const
186  {
187  if (!ws_.is_zero(res.constant))
188  {
189  auto one = ls_.one();
190  ps_.add_here(res.polynomials[one],
191  polynomial_t{{rs_.one(), res.constant}});
192  res.constant = ws_.zero();
193  }
194  return res;
195  }
196 
198  value_t& denormalize_(value_t& res, std::false_type) const
199  {
200  return res;
201  }
202 
203  /*--------.
204  | Conv. |
205  `--------*/
206 
208  static value_t
209  conv(self_t, const value_t& v)
210  {
211  return v;
212  }
213 
215  template <typename OtherExpSet>
216  value_t
218  const typename expansionset<OtherExpSet>::value_t& v) const
219  {
220  const auto& other_ws = other.expressionset().weightset();
221  const auto& other_ps = other.polynomialset();
222  return {ws_.conv(other_ws, v.constant),
223  ps_.conv(other_ps, v.polynomials)};
224  }
225 
227  value_t zero() const
228  {
229  return {ws_.zero(), polys_t{}};
230  }
231 
233  value_t one() const
234  {
235  return {ws_.one(), polys_t{}};
236  }
237 
239  value_t atom(const label_t& l) const
240  {
241  return {ws_.zero(), {{l, ps_.one()}}};
242  }
243 
245  void add_here(value_t& lhs, const value_t& rhs) const
246  {
247  lhs.constant = ws_.add(lhs.constant, rhs.constant);
248  for (const auto& p: rhs.polynomials)
249  ps_.add_here(lhs.polynomials[p.first], p.second);
250  }
251 
253  value_t add(const value_t& lhs, const value_t& rhs) const
254  {
255  value_t res = lhs;
256  add_here(res, rhs);
257  return res;
258  }
259 
261  value_t lweight(const weight_t& w, const value_t& rhs) const
262  {
263  value_t res = rhs;
264  lweight_here(w, res);
265  return res;
266  }
267 
269  value_t& lweight_here(const weight_t& w, value_t& res) const
270  {
271  res.constant = ws_.mul(w, res.constant);
272  for (auto& p: res.polynomials)
273  p.second = ps_.lweight(w, p.second);
274  return res;
275  }
276 
278  value_t rweight(const value_t& lhs, const weight_t& w) const
279  {
280  value_t res = {ws_.mul(lhs.constant, w), polys_t{}};
281  for (auto& p: lhs.polynomials)
282  for (const auto& m: p.second)
283  ps_.add_here(res.polynomials[p.first],
284  rs_.rweight(label_of(m), w), weight_of(m));
285  return res;
286  }
287 
289  value_t& rweight_here(value_t& res, const expression_t& rhs) const
290  {
291  for (auto& p: res.polynomials)
292  p.second = ps_.rmul_label(p.second, rhs);
293  return res;
294  }
295 
297  value_t& ldivide_here(const weight_t& w, value_t& res) const
298  {
299  res.constant = ws_.ldivide(w, res.constant);
300  for (auto& p: res.polynomials)
301  for (auto&& m: p.second)
302  weight_set(m, ws_.ldivide(w, weight_of(m)));
303  return normalize(res);
304  }
305 
306  private:
307  template <typename Conjunction>
308  void
310  const value_t&, const value_t&,
311  std::false_type,
312  Conjunction) const
313  {}
314 
315  template <typename Conjunction>
316  void
318  const value_t& l, const value_t& r,
319  std::true_type,
320  Conjunction conjunction) const
321  {
322  // Spontaneous transitions from the lhs.
323  auto one = ls_.one();
324  {
325  auto i = l.polynomials.find(one);
326  if (i != std::end(l.polynomials))
327  for (const auto& rhs: r.polynomials)
328  if (!ls_.is_one(rhs.first))
329  ps_.add_here(res.polynomials[one],
330  conjunction(i->second,
331  ps_.lmul_label(rs_.atom(rhs.first),
332  rhs.second)));
333  }
334  // Spontaneous transitions from the rhs.
335  {
336  auto i = r.polynomials.find(one);
337  if (i != std::end(r.polynomials))
338  for (const auto& lhs: l.polynomials)
339  if (!ls_.is_one(lhs.first))
340  ps_.add_here(res.polynomials[one],
341  conjunction(ps_.lmul_label(rs_.atom(lhs.first),
342  lhs.second),
343  i->second));
344  }
345  }
346 
350  template <typename LabelSet = labelset_t, typename Conjunction>
351  auto conjunction_(value_t l, value_t r,
352  Conjunction conjunction) const
353  -> std::enable_if_t<detail::is_letterized_t<LabelSet>{},
354  value_t>
355  {
356  value_t res = zero();
357  denormalize(l);
358  denormalize(r);
359  res.constant = ws_.mul(l.constant, r.constant);
360  for (const auto& p: zip_maps(l.polynomials, r.polynomials))
361  res.polynomials[p.first]
362  = conjunction(std::get<0>(p.second), std::get<1>(p.second));
363 
365  conjunctions_with_one_(res, l, r, has_one, conjunction);
366  normalize(res);
367  return res;
368  }
369 
373  template <typename LabelSet = labelset_t, typename Conjunction>
374  auto conjunction_(const value_t& lhs, const value_t& rhs,
375  Conjunction conjunction) const
376  -> std::enable_if_t<!detail::is_letterized_t<LabelSet>{},
377  value_t>
378  {
379  value_t res = zero();
380  res.constant = ws_.mul(lhs.constant, rhs.constant);
381  for (const auto& l: lhs.polynomials)
382  for (const auto& r: rhs.polynomials)
383  {
384  // The longest common prefix.
385  auto lcp = ls_.lgcd(l.first, r.first);
386  if (!ls_.is_one(lcp))
387  {
388  auto left = rs_.atom(ls_.ldivide(lcp, l.first));
389  auto right = rs_.atom(ls_.ldivide(lcp, r.first));
390  ps_.add_here(res.polynomials[lcp],
391  conjunction(ps_.lmul_label(left, l.second),
392  ps_.lmul_label(right, r.second)));
393  }
394  }
395  return res;
396  }
397 
399  template <typename Shuffle>
400  value_t& shuffle_(value_t& res,
401  const value_t& lhs_xpn, const expression_t& lhs_xpr,
402  const value_t& rhs_xpn, const expression_t& rhs_xpr,
403  Shuffle shuffle) const
404  {
405  // (i) lhs_xpn:rhs_xpr.
406  for (const auto& p: lhs_xpn.polynomials)
407  for (const auto& m: p.second)
408  ps_.add_here(res.polynomials[p.first],
409  shuffle(label_of(m), rhs_xpr), weight_of(m));
410  // (ii) lhs_xpr:rhs_xpn
411  for (const auto& p: rhs_xpn.polynomials)
412  for (const auto& m: p.second)
413  ps_.add_here(res.polynomials[p.first],
414  shuffle(lhs_xpr, label_of(m)), weight_of(m));
415 
416  return res;
417  }
418 
419  public:
421  value_t conjunction(const value_t& l, const value_t& r) const
422  {
423  return conjunction_(l, r,
424  [this](const polynomial_t& l,
425  const polynomial_t& r)
426  {
427  return ps_.conjunction(l, r);
428  });
429  }
430 
434  value_t shuffle(const value_t& lhs_xpn, const expression_t& lhs_xpr,
435  const value_t& rhs_xpn, const expression_t& rhs_xpr) const
436  {
437  value_t res;
438  res.constant = ws_.mul(lhs_xpn.constant, rhs_xpn.constant);
439  return shuffle_(res,
440  lhs_xpn, lhs_xpr, rhs_xpn, rhs_xpr,
441  [this](const expression_t& l, const expression_t& r)
442  {
443  return rs_.shuffle(l, r);
444  });
445  }
446 
448  value_t infiltrate(const value_t& lhs_xpn, const expression_t& lhs_xpr,
449  const value_t& rhs_xpn, const expression_t& rhs_xpr) const
450  {
451  // Conjunction part: lhs_xpn&:rhs_xpn.
452  value_t res =
453  conjunction_(lhs_xpn, rhs_xpn,
454  [this](const polynomial_t& l, const polynomial_t& r)
455  {
456  return ps_.infiltrate(l, r);
457  });
458 
459  // Shuffle part: lhs_xpn&:rhs_xpr + lhs_xpr&:rhs_xpn.
460  shuffle_(res,
461  lhs_xpn, lhs_xpr, rhs_xpn, rhs_xpr,
462  [this](const expression_t& l, const expression_t& r)
463  {
464  return rs_.infiltrate(l, r);
465  });
466  return res;
467  }
468 
469  /*--------------.
470  | complement. |
471  `--------------*/
472 
474  value_t complement(const value_t& v) const
475  {
476  // We need an expansion whose firsts are letters. However,
477  // requiring a free labelset, i.e., rulling out lan, is too
478  // demanding, since, for instance, to compute {\} requires lan
479  // instead of lal.
480  //
481  // So require a letterized labelset.
482  return complement_<detail::is_letterized_t<labelset_t>{}>(v);
483  }
484 
485  private:
487  template <bool IsLetterized>
488  std::enable_if_t<!IsLetterized, value_t>
489  complement_(const value_t&) const
490  {
491  raise(me(),
492  ": complement: labelset must be letterized: ", ls_);
493  }
494 
496  template <bool IsLetterized>
497  std::enable_if_t<IsLetterized, value_t>
498  complement_(const value_t& v) const
499  {
500  value_t res;
501  res.constant = ws_.is_zero(v.constant) ? ws_.one() : ws_.zero();
502 
503  detail::static_if<labelset_t::has_one()>
504  ([this](const auto& v, const auto& ls)
505  {
506  require(!has(v.polynomials, ls.one()),
507  me(), ": complement: expansion must be normalized: ",
508  to_string(*this, v));
509  })(v, ls_);
510 
511  // Turn the polynomials into expressions, and complement them.
512  // The static-if is made of oneset.
513  detail::static_if<detail::has_generators_mem_fn<labelset_t>{}>
514  ([this, &res](const auto& v, const auto& ls)
515  {
516  for (auto l: ls.generators())
517  {
518  auto i = v.polynomials.find(l);
519  res.polynomials[l] =
520  ps_.complement(i == end(v.polynomials)
521  ? ps_.zero() : i->second);
522  }
523  })(v, ls_);
524  return res;
525  }
526 
527  public:
529  value_t
530  determinize(const value_t& v) const
531  {
532  value_t res;
533  res.constant = v.constant;
534  for (const auto& lp: v.polynomials)
535  res.polynomials[lp.first] = {ps_.determinize(lp.second)};
536  return res;
537  }
538 
539  /*---------------.
540  | tuple(v...). |
541  `---------------*/
542 
544  template <unsigned Tape>
545  using project_t
547 
549  template <unsigned Tape>
550  auto project() const
551  -> project_t<Tape>
552  {
553  return {rs_.template project<Tape>()};
554  }
555 
557  template <typename... Expansions>
558  struct tuple_impl
559  {
562  template <size_t Tape>
563  auto denormalize_tape(const typename project_t<Tape>::value_t& e) const
564  -> typename project_t<Tape>::polys_t
565  {
566  auto es = eset_.template project<Tape>();
567  auto res = e;
568  es.denormalize(res);
569  VCSN_REQUIRE(es.expressionset().weightset()->is_zero(res.constant),
570  es, ": to-expansion: cannot denormalize ",
571  to_string(es, res),
572  ", need support for label one (the empty label)");
573  return res.polynomials;
574  }
575 
577  template <size_t... Tape>
578  auto denormalize(std::tuple<const Expansions&...>& es,
580  -> std::tuple<typename project_t<Tape>::polys_t...>
581  {
582  using res_t = std::tuple<typename project_t<Tape>::polys_t...>;
583  return res_t{denormalize_tape<Tape>(std::get<Tape>(es))...};
584  }
585 
587  auto denormalize(const Expansions&... es) const
588  {
589  auto t = std::tuple<const Expansions&...>{es...};
590  constexpr auto indices
591  = detail::make_index_sequence<sizeof...(Expansions)>{};
592  return denormalize(t, indices);
593  }
594 
595  auto
596  tuple(Expansions&&... es) const
597  -> value_t
598  {
599  auto res = eset_.zero();
600  auto polys = denormalize(std::forward<Expansions>(es)...);
602  ([&res, this](const auto&... ps)
603  {
604  auto l = label_t{ps.first...};
605  eset_.ps_.add_here(res.polynomials[l],
606  eset_.ps_.tuple(ps.second...));
607  },
608  polys);
609  eset_.normalize(res);
610  return res;
611  }
612 
614  };
615 
670  template <typename... Expansions>
671  auto
672  tuple(Expansions&&... es) const
673  -> value_t
674  {
675  auto t = tuple_impl<Expansions...>{*this};
676  return t.tuple(std::forward<Expansions>(es)...);
677  }
678 
680  template <size_t Tape>
681  auto project(const value_t& v) const
682  {
683  auto xs = project<Tape>();
684  const auto& ps = xs.polynomialset();
685  using res_t = typename decltype(xs)::value_t;
686  auto res = res_t{};
687  res.constant = v.constant;
688  for (const auto& p: v.polynomials)
689  ps.add_here(res.polynomials[ls_.template project<Tape>(p.first)],
690  ps_.template project<Tape>(p.second));
691  // We might generate denormalized expansions, e.g., when
692  // projecting the expansion of `\e|a`, `\e` is a label.
693  xs.normalize(res);
694  return res;
695  }
696 
697  void
699  const value_t&, const value_t&,
700  std::false_type) const
701  {}
702 
703  void
704  compose_with_one_(value_t& res,
705  const value_t& l, const value_t& r,
706  std::true_type) const
707  {
708  // Handle lhs labels with one on the second tape.
709  {
710  for (const auto& lhs: l.polynomials)
711  if (ls_.template set<1>().is_one(std::get<1>(lhs.first)))
712  for (const auto& rhs: r.polynomials)
713  if (!ls_.template set<0>().is_one(std::get<0>(rhs.first)))
714  // a|\e . [P1] @ b|c . [P2] becomes a|\e . [P1 @ (b|c)P2]
715  ps_.add_here(res.polynomials[lhs.first],
716  ps_.compose(lhs.second,
717  ps_.lmul_label(rs_.atom(rhs.first),
718  rhs.second)));
719  }
720  // Handle rhs labels with one on the first tape.
721  {
722  for (const auto& rhs: r.polynomials)
723  if (ls_.template set<0>().is_one(std::get<0>(rhs.first)))
724  for (const auto& lhs: l.polynomials)
725  if (!ls_.template set<1>().is_one(std::get<1>(lhs.first)))
726  // a|b . [P1] @ \e|c . [P2] becomes \e|c . [(a|b)P1 @ P2]
727  ps_.add_here(res.polynomials[rhs.first],
728  ps_.compose(ps_.lmul_label(rs_.atom(lhs.first),
729  lhs.second),
730  rhs.second));
731  }
732  }
733 
735  template <typename Ctx = context_t>
736  auto compose(value_t l, value_t r) const
737  -> std::enable_if_t<are_composable<Ctx, Ctx>{}, value_t>
738  {
739  value_t res = zero();
740  denormalize(l);
741  denormalize(r);
742  res.constant = ws_.mul(l.constant, r.constant);
743  for (const auto& lm: l.polynomials)
744  for (const auto& rm: r.polynomials)
745  if (ls_.template set<0>().equal(std::get<1>(label_of(lm)),
746  std::get<0>(label_of(rm))))
747  {
748  auto l = ls_.tuple(std::get<0>(label_of(lm)),
749  std::get<1>(label_of(rm)));
750  ps_.add_here(res.polynomials[l],
751  ps_.compose(lm.second, rm.second));
752  }
753  auto has_one = bool_constant<context_t::has_one()>();
754  compose_with_one_(res, l, r, has_one);
755  normalize(res);
756  return res;
757  }
758 
759 
760  private:
764  const labelset_t& ls_ = *rs_.labelset();
766  const weightset_t& ws_ = *rs_.weightset();
769  };
770  }
771 
772  template <typename ExpSet>
774  make_expansionset(const ExpSet& expset)
775  {
776  return {expset};
777  }
778 
779  namespace detail
780  {
782  template <typename Ctx1, typename Ctx2>
785  {
787 
789  const expansionset<expressionset<Ctx2>>& rhs)
790  {
791  return type(vcsn::join(lhs.expressionset(), rhs.expressionset()));
792  }
793  };
794  }
795 }
return v
Definition: multiply.hh:361
void conjunctions_with_one_(value_t &res, const value_t &l, const value_t &r, std::true_type, Conjunction conjunction) const
value_t & denormalize_(value_t &res, std::true_type) const
Denormalize res move the constant to the polynomial associated to one.
value_t & ldivide_here(const weight_t &w, value_t &res) const
Inplace left-division by w of res.
polynomialset_t ps_
The polynomialset for the polynomials.
value_t & normalize(value_t &res) const
Normalize: move the constant term to the label one.
expansionset(const expressionset_t &rs)
Definition: expansionset.hh:49
std::string type(const automaton &a)
The implementation type of a.
Definition: others.cc:231
typename polynomialset_t::monomial_t monomial_t
Definition: expansionset.hh:33
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
Definition: symbol.hh:23
const context_t & context() const
The context.
Definition: expansionset.hh:74
STL namespace.
static constexpr const char * me()
Definition: expansionset.hh:35
value_t & denormalize(value_t &res) const
Move the constant to the polynomial associated to one.
Aut1 & add_here(Aut1 &res, const Aut2 &b, standard_tag)
Merge transitions of b into those of res.
Definition: add.hh:28
Denormalize a pack of one-tape expansions.
symbol sname()
Definition: name.hh:65
void compose_with_one_(value_t &res, const value_t &l, const value_t &r, std::true_type) const
value_t & denormalize_(value_t &res, std::false_type) const
Denormalize when there is no label one: identity.
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:63
auto compose(value_t l, value_t r) const -> std::enable_if_t< are_composable< Ctx, Ctx >
The composition of l and r.
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:61
auto tuple(Expansions &&...es) const -> value_t
The tuplization of single-tape expansions into a multitape expansion.
auto label_of(const welement< Label, Weight > &m) -> decltype(m.label())
The label of a welement.
Definition: wet.hh:146
auto join(const ValueSet &vs) -> ValueSet
The join of a single valueset.
Definition: join.hh:44
const polynomialset_t & polynomialset() const
The polynomialset.
Definition: expansionset.hh:68
A structure that implements the computation of join(V1, V2).
Definition: join.hh:18
value_t lweight(const weight_t &w, const value_t &rhs) const
Left-multiplication by w of rhs.
value_t & normalize_(value_t &res, std::false_type) const
Normalize when there is no label one: identity.
value_t infiltrate(const value_t &lhs_xpn, const expression_t &lhs_xpr, const value_t &rhs_xpn, const expression_t &rhs_xpr) const
The infiltration product of l and r.
Print as a parsable type string.
Definition: format.hh:26
typename polynomialset_t::value_t polynomial_t
Definition: expansionset.hh:32
auto project() const -> project_t< Tape >
The expansionset for tape Tape.
void require(Bool b, Args &&...args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:91
value_t & lweight_here(const weight_t &w, value_t &res) const
Inplace left-multiplication by w of res.
auto tuple(Expansions &&...es) const -> value_t
return res
Definition: multiply.hh:398
value_t shuffle(const value_t &lhs_xpn, const expression_t &lhs_xpr, const value_t &rhs_xpn, const expression_t &rhs_xpr) const
The shuffle product of lhs_xpn and rhs_xpn.
value_t atom(const label_t &l) const
A single label.
ATTRIBUTE_PURE bool has(const boost::container::flat_set< Key, Compare, Allocator > &s, const Key &e)
Whether e is member of s.
Definition: setalpha.hh:25
value_t complement(const value_t &v) const
The complement of v.
static type join(const expansionset< expressionset< Ctx1 >> &lhs, const expansionset< expressionset< Ctx2 >> &rhs)
const labelset_t & ls_
Shorthand to the labelset.
value_t & shuffle_(value_t &res, const value_t &lhs_xpn, const expression_t &lhs_xpr, const value_t &rhs_xpn, const expression_t &rhs_xpr, Shuffle shuffle) const
The shuffle product of l and r.
typename expressionset_t::value_t expression_t
Definition: expansionset.hh:27
value_t & rweight_here(value_t &res, const expression_t &rhs) const
In place right multiplication by an expression.
weightset_t_of< expressionset_t > weightset_t
Definition: expansionset.hh:28
auto rs
Definition: lift.hh:152
auto conjunction_(const value_t &lhs, const value_t &rhs, Conjunction conjunction) const -> std::enable_if_t<!detail::is_letterized_t< LabelSet >
The conjunction of l and r.
labelset_t_of< context_t > labelset_t
Definition: expansionset.hh:25
std::map< label_t, polynomial_t, vcsn::less< labelset_t >> polys_t
Definition: expansionset.hh:40
std::enable_if_t< IsLetterized, value_t > complement_(const value_t &v) const
Complement on a letterized labelset.
Definition: a-star.hh:8
auto project(const value_t &v) const
Project a multitape expansion.
auto normalize(const Aut &a) -> decltype(copy(a))
Normalize a automaton.
Definition: normalize.hh:20
const expressionset_t & expressionset() const
The expressionset.
Definition: expansionset.hh:62
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
Definition: traits.hh:62
#define VCSN_REQUIRE(Cond,...)
A macro similar to require.
Definition: raise.hh:111
automaton conjunction_(const std::vector< automaton > &as, bool lazy, vcsn::detail::index_sequence< I... >)
Bridge helper.
Definition: conjunction.hh:652
auto conjunction_(value_t l, value_t r, Conjunction conjunction) const -> std::enable_if_t< detail::is_letterized_t< LabelSet >
The conjunction of l and r.
automaton shuffle_(const std::vector< automaton > &as, vcsn::detail::index_sequence< I... >)
Variadic bridge helper.
Definition: conjunction.hh:798
std::enable_if_t<!IsLetterized, value_t > complement_(const value_t &) const
Complement on an invalid labelset.
An input/output format for valuesets.
Definition: format.hh:13
static value_t conv(self_t, const value_t &v)
Conversion from (this and) other weightsets.
value_t & normalize_(value_t &res, std::true_type) const
Normalize res: There must not remain a constant-term associated to one: put it with the constant term...
constant< type_t::zero, Context > zero
Definition: fwd.hh:110
value_t zero() const
The zero.
value_t conv(const expansionset< OtherExpSet > &other, const typename expansionset< OtherExpSet >::value_t &v) const
Convert from another expansionset to self.
typename weightset_t::value_t weight_t
Definition: expansionset.hh:29
void compose_with_one_(value_t &, const value_t &, const value_t &, std::false_type) const
Print as is. For instance, don't try to escape labels.
Definition: format.hh:24
void add_here(value_t &lhs, const value_t &rhs) const
In place addition.
void weight_set(welement< Label, Weight > &m, const Weight &w)
Set the weight of a welement.
Definition: wet.hh:162
std::string to_string(identities i)
Wrapper around operator<<.
Definition: identities.cc:41
value_t one() const
The one.
static symbol sname()
The static name.
Definition: expansionset.hh:54
variadic< type_t::conjunction, Context > conjunction
Definition: fwd.hh:142
auto denormalize(std::tuple< const Expansions &... > &es, detail::index_sequence< Tape... >) const -> std::tuple< typename project_t< Tape >::polys_t... >
Denormalize on all these tapes.
Print as rich UTF-8 text, escaped.
Definition: format.hh:30
expressionset_t rs_
The expressionset used for the expressions.
Implementation of nodes of tuple of rational expressions.
Definition: expression.hh:182
auto weight_of(const welement< Label, Weight > &m) -> decltype(m.weight())
The weight of a welement.
Definition: wet.hh:154
Aut & lweight_here(const weight_t_of< Aut > &w, Aut &res, Tag tag={})
In place left-multiplication of an automaton by a weight.
Definition: weight.hh:118
void cross_tuple(Fun f, const std::tuple< Ts... > &ts)
Definition: tuple.hh:301
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
Definition: traits.hh:67
expression_polynomialset_t< ExpSet > make_expression_polynomialset(const ExpSet &rs)
From a ExpSet to its polynomialset.
Definition: split.hh:31
value_t rweight(const value_t &lhs, const weight_t &w) const
Right-multiplication of lhs by w.
auto denormalize_tape(const typename project_t< Tape >::value_t &e) const -> typename project_t< Tape >::polys_t
Denormalize on this tape: from expansion to pure polynomial.
An inner node with multiple children.
Definition: expression.hh:118
void conjunctions_with_one_(value_t &, const value_t &, const value_t &, std::false_type, Conjunction) const
Print for LaTeX.
Definition: format.hh:22
auto denormalize(const Expansions &...es) const
Entry point: Denormalize all these expansions.
std::ostream & print(const value_t &v, std::ostream &o, format fmt={}) const
Print this expansion.
std::integral_constant< bool, B > bool_constant
Definition: type_traits.hh:12
std::ostream & print_set(std::ostream &o, format fmt={}) const
Print this valueset.
Definition: expansionset.hh:80
zipped_maps< Dereference, Maps... > zip_maps(Maps &&...maps)
Definition: zip-maps.hh:250
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
Print as plain (ASCII) text, escaped.
Definition: format.hh:28
value_t determinize(const value_t &v) const
Turn the polynomials into (normalized) monomials.
expansionset< ExpSet > make_expansionset(const ExpSet &expset)
context_t_of< expressionset_t > context_t
Definition: expansionset.hh:24
value_t add(const value_t &lhs, const value_t &rhs) const
Addition.
value_t conjunction(const value_t &l, const value_t &r) const
The conjunction of l and r.
const weightset_t & ws_
Shorthand to the weightset.