Vcsn  2.2
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 
7 namespace vcsn
8 {
9 
10  namespace rat
11  {
12 
13  /*---------------.
14  | expansionset. |
15  `---------------*/
16 
17  template <typename ExpSet>
18  struct expansionset
19  {
20  public:
21  using expressionset_t = ExpSet;
26  using expression_t = typename expressionset_t::value_t;
28  using weight_t = typename weightset_t::value_t;
29 
32  using monomial_t = typename polynomialset_t::monomial_t;
33 
34  constexpr static const char* me() { return "expansion"; }
35 
36  // Keep it sorted to ensure determinism, and better looking
37  // results. Anyway, rough benches show no difference between
38  // map and unordered_map here.
39  using polys_t = std::map<label_t, polynomial_t, vcsn::less<labelset_t>>;
40 
42  struct value_t
43  {
46  };
47 
49  : rs_(rs)
50  {}
51 
53  static symbol sname()
54  {
55  static auto res
56  = symbol{"expansionset<" + expressionset_t::sname() + '>'};
57  return res;
58  }
59 
62  {
63  return rs_;
64  }
65 
68  {
69  return ps_;
70  }
71 
73  const context_t& context() const
74  {
75  return rs_.context();
76  }
77 
79  std::ostream& print_set(std::ostream& o, format fmt = {}) const
80  {
81  switch (fmt.kind())
82  {
83  case format::latex:
84  o << "\\mathsf{Expansion}[";
85  rs_.print_set(o, fmt);
86  o << ']';
87  break;
88  case format::sname:
89  o << "expansionset<";
90  rs_.print_set(o, fmt);
91  o << ">";
92  break;
93  case format::text:
94  case format::utf8:
95  o << "Expansion[";
96  rs_.print_set(o, fmt);
97  o << ']';
98  break;
99  case format::raw:
100  assert(0);
101  break;
102  }
103  return o;
104  }
105 
107  std::ostream& print(const value_t& v, std::ostream& o,
108  format fmt = {}) const
109  {
110  bool first = true;
111  if (!ws_.is_zero(v.constant) || v.polynomials.empty())
112  {
113  o << (fmt == format::latex ? "\\left\\langle "
114  : fmt == format::utf8 ? "⟨"
115  : "<");
116  ws_.print(v.constant, o, fmt.for_weights());
117  o << (fmt == format::latex ? "\\right\\rangle "
118  : fmt == format::utf8 ? "⟩"
119  : ">");
120  first = false;
121  }
122  for (const auto& p: v.polynomials)
123  {
124  if (!first)
125  o << (fmt == format::latex ? " \\oplus "
126  : fmt == format::utf8 ? " ⊕ "
127  : " + ");
128  first = false;
129  ls_.print(p.first, o, fmt.for_labels());
130  o << (fmt == format::latex ? " \\odot \\left["
131  : fmt == format::utf8 ? "⊙["
132  : ".[");
133  ps_.print(p.second, o, fmt);
134  o << (fmt == format::latex ? "\\right]"
135  : fmt == format::utf8 ? "]"
136  : "]");
137  }
138  return o;
139  }
140 
143  {
145  return normalize_(res, has_one);
146  }
147 
151  value_t& normalize_(value_t& res, std::true_type) const
152  {
153  auto one = ls_.one();
154  auto i = res.polynomials.find(one);
155  if (i != std::end(res.polynomials))
156  {
157  auto j = i->second.find(rs_.one());
158  if (j != std::end(i->second))
159  {
160  res.constant = ws_.add(res.constant, weight_of(*j));
161  i->second.erase(j);
162  if (i->second.empty())
163  res.polynomials.erase(i);
164  }
165  }
166  return res;
167  }
168 
170  value_t& normalize_(value_t& res, std::false_type) const
171  {
172  return res;
173  }
174 
177  {
179  return denormalize_(res, has_one);
180  }
181 
184  value_t& denormalize_(value_t& res, std::true_type) const
185  {
186  if (!ws_.is_zero(res.constant))
187  {
188  auto one = ls_.one();
189  ps_.add_here(res.polynomials[one],
190  polynomial_t{{rs_.one(), res.constant}});
191  res.constant = ws_.zero();
192  }
193  return res;
194  }
195 
197  value_t& denormalize_(value_t& res, std::false_type) const
198  {
199  return res;
200  }
201 
202  /*--------.
203  | Conv. |
204  `--------*/
205 
207  static value_t
208  conv(self_t, const value_t& v)
209  {
210  return v;
211  }
212 
214  template <typename OtherExpSet>
215  value_t
217  const typename expansionset<OtherExpSet>::value_t& v) const
218  {
219  const auto& other_ws = other.expressionset().weightset();
220  const auto& other_ps = other.polynomialset();
221  return {ws_.conv(other_ws, v.constant),
222  ps_.conv(other_ps, v.polynomials)};
223  }
224 
226  value_t zero() const
227  {
228  return {ws_.zero(), polys_t{}};
229  }
230 
232  value_t one() const
233  {
234  return {ws_.one(), polys_t{}};
235  }
236 
238  value_t atom(const label_t& l) const
239  {
240  return {ws_.zero(), {{l, ps_.one()}}};
241  }
242 
244  void add_here(value_t& lhs, const value_t& rhs) const
245  {
246  lhs.constant = ws_.add(lhs.constant, rhs.constant);
247  for (const auto& p: rhs.polynomials)
248  ps_.add_here(lhs.polynomials[p.first], p.second);
249  }
250 
252  value_t add(const value_t& lhs, const value_t& rhs) const
253  {
254  value_t res = lhs;
255  add_here(res, rhs);
256  return res;
257  }
258 
260  value_t lmul(const weight_t& w, const value_t& rhs) const
261  {
262  value_t res = rhs;
263  lmul_here(w, res);
264  return res;
265  }
266 
268  value_t& lmul_here(const weight_t& w, value_t& res) const
269  {
270  res.constant = ws_.mul(w, res.constant);
271  for (auto& p: res.polynomials)
272  p.second = ps_.lmul(w, p.second);
273  return res;
274  }
275 
277  value_t rmul(const value_t& lhs, const weight_t& w) const
278  {
279  value_t res = {ws_.mul(lhs.constant, w), polys_t{}};
280  for (auto& p: lhs.polynomials)
281  for (const auto& m: p.second)
282  ps_.add_here(res.polynomials[p.first],
283  rs_.rmul(label_of(m), w), weight_of(m));
284  return res;
285  }
286 
288  value_t& rmul_here(value_t& res, const expression_t& rhs) const
289  {
290  for (auto& p: res.polynomials)
291  p.second = ps_.rmul_label(p.second, rhs);
292  return res;
293  }
294 
296  value_t& ldiv_here(const weight_t& w, value_t& res) const
297  {
298  res.constant = ws_.ldiv(w, res.constant);
299  for (auto& p: res.polynomials)
300  for (auto&& m: p.second)
301  weight_set(m, ws_.ldiv(w, weight_of(m)));
302  return normalize(res);
303  }
304 
305  private:
306  template <typename Conjunction>
307  void
309  const value_t&, const value_t&,
310  std::false_type,
311  Conjunction) const
312  {}
313 
314  template <typename Conjunction>
315  void
317  const value_t& l, const value_t& r,
318  std::true_type,
319  Conjunction conjunction) const
320  {
321  // Spontaneous transitions from the lhs.
322  auto one = ls_.one();
323  {
324  auto i = l.polynomials.find(one);
325  if (i != std::end(l.polynomials))
326  for (const auto& rhs: r.polynomials)
327  if (!ls_.is_one(rhs.first))
328  ps_.add_here(res.polynomials[one],
329  conjunction(i->second,
330  ps_.lmul_label(rs_.atom(rhs.first),
331  rhs.second)));
332  }
333  // Spontaneous transitions from the rhs.
334  {
335  auto i = r.polynomials.find(one);
336  if (i != std::end(r.polynomials))
337  for (const auto& lhs: l.polynomials)
338  if (!ls_.is_one(lhs.first))
339  ps_.add_here(res.polynomials[one],
340  conjunction(ps_.lmul_label(rs_.atom(lhs.first),
341  lhs.second),
342  i->second));
343  }
344  }
345 
349  template <typename LabelSet = labelset_t, typename Conjunction>
350  auto conjunction_(value_t l, value_t r,
351  Conjunction conjunction) const
352  -> std::enable_if_t<detail::is_letterized_t<LabelSet>{},
353  value_t>
354  {
355  value_t res = zero();
356  denormalize(l);
357  denormalize(r);
358  res.constant = ws_.mul(l.constant, r.constant);
359  for (const auto& p: zip_maps(l.polynomials, r.polynomials))
360  res.polynomials[p.first]
361  = conjunction(std::get<0>(p.second), std::get<1>(p.second));
362 
364  conjunctions_with_one_(res, l, r, has_one, conjunction);
365  normalize(res);
366  return res;
367  }
368 
372  template <typename LabelSet = labelset_t, typename Conjunction>
373  auto conjunction_(value_t lhs, value_t rhs,
374  Conjunction conjunction) const
375  -> std::enable_if_t<!detail::is_letterized_t<LabelSet>{},
376  value_t>
377  {
378  value_t res = zero();
379  res.constant = ws_.mul(lhs.constant, rhs.constant);
380  for (const auto& l: lhs.polynomials)
381  for (const auto& r: rhs.polynomials)
382  {
383  // The longest common prefix.
384  auto lcp = ls_.lgcd(l.first, r.first);
385  if (!ls_.is_one(lcp))
386  {
387  auto left = rs_.atom(ls_.ldiv(lcp, l.first));
388  auto right = rs_.atom(ls_.ldiv(lcp, r.first));
389  ps_.add_here(res.polynomials[lcp],
390  conjunction(ps_.lmul_label(left, l.second),
391  ps_.lmul_label(right, r.second)));
392  }
393  }
394  return res;
395  }
396 
398  template <typename Shuffle>
399  value_t& shuffle_(value_t& res,
400  const value_t& lhs_xpn, const expression_t& lhs_xpr,
401  const value_t& rhs_xpn, const expression_t& rhs_xpr,
402  Shuffle shuffle) const
403  {
404  // (i) lhs_xpn:rhs_xpr.
405  for (const auto& p: lhs_xpn.polynomials)
406  for (const auto& m: p.second)
407  ps_.add_here(res.polynomials[p.first],
408  shuffle(label_of(m), rhs_xpr), weight_of(m));
409  // (ii) lhs_xpr:rhs_xpn
410  for (const auto& p: rhs_xpn.polynomials)
411  for (const auto& m: p.second)
412  ps_.add_here(res.polynomials[p.first],
413  shuffle(lhs_xpr, label_of(m)), weight_of(m));
414 
415  return res;
416  }
417 
418  public:
420  value_t conjunction(value_t l, value_t r) const
421  {
422  return conjunction_(l, r,
423  [this](const polynomial_t& l,
424  const polynomial_t& r)
425  {
426  return ps_.conjunction(l, r);
427  });
428  }
429 
431  value_t shuffle(const value_t& lhs_xpn, const expression_t& lhs_xpr,
432  const value_t& rhs_xpn, const expression_t& rhs_xpr) const
433  {
434  value_t res;
435  res.constant = ws_.mul(lhs_xpn.constant, rhs_xpn.constant);
436  return shuffle_(res,
437  lhs_xpn, lhs_xpr, rhs_xpn, rhs_xpr,
438  [this](const expression_t& l, const expression_t& r)
439  {
440  return rs_.shuffle(l, r);
441  });
442  }
443 
445  value_t infiltration(const value_t& lhs_xpn, const expression_t& lhs_xpr,
446  const value_t& rhs_xpn, const expression_t& rhs_xpr) const
447  {
448  // Conjunction part: lhs_xpn&:rhs_xpn.
449  value_t res =
450  conjunction_(lhs_xpn, rhs_xpn,
451  [this](const polynomial_t& l, const polynomial_t& r)
452  {
453  return ps_.infiltration(l, r);
454  });
455 
456  // Shuffle part: lhs_xpn&:rhs_xpr + lhs_xpr&:rhs_xpn.
457  shuffle_(res,
458  lhs_xpn, lhs_xpr, rhs_xpn, rhs_xpr,
459  [this](const expression_t& l, const expression_t& r)
460  {
461  return rs_.infiltration(l, r);
462  });
463  return res;
464  }
465 
466  /*--------------.
467  | complement. |
468  `--------------*/
469 
471  value_t complement(const value_t& v) const
472  {
473  // Complement requires a free labelset.
474  return complement_<labelset_t::is_free()>(v);
475  }
476 
477  private:
479  template <bool IsFree>
480  std::enable_if_t<!IsFree, value_t>
481  complement_(const value_t&) const
482  {
483  raise(me(), ": cannot handle complement without generators");
484  }
485 
487  template <bool IsFree>
488  std::enable_if_t<IsFree, value_t>
489  complement_(const value_t& v) const
490  {
491  value_t res;
492  res.constant = ws_.is_zero(v.constant) ? ws_.one() : ws_.zero();
493 
494  // Turn the polynomials into expressions, and complement them.
495  for (auto l: ls_.generators())
496  {
497  auto i = v.polynomials.find(l);
498  res.polynomials[l] =
499  ps_.complement(i == end(v.polynomials) ? ps_.zero() : i->second);
500  }
501  return res;
502  }
503 
504  public:
506  value_t
507  determinize(const value_t& v) const
508  {
509  value_t res;
510  res.constant = v.constant;
511  for (const auto& lp: v.polynomials)
512  res.polynomials[lp.first] = {ps_.determinize(lp.second)};
513  return res;
514  }
515 
516  /*---------------.
517  | tuple(v...). |
518  `---------------*/
519 
521  template <unsigned Tape>
522  using project_t
524 
526  template <unsigned Tape>
527  auto project() const
528  -> project_t<Tape>
529  {
530  return {detail::project<Tape>(rs_)};
531  }
532 
534  template <typename... Expansions>
535  struct tuple_impl
536  {
539  template <size_t Tape>
540  auto denormalize_tape(const typename project_t<Tape>::value_t& e) const
541  -> typename project_t<Tape>::polys_t
542  {
543  auto es = eset_.template project<Tape>();
544  auto res = e;
545  es.denormalize(res);
546  VCSN_REQUIRE(es.expressionset().weightset()->is_zero(res.constant),
547  es, ": to-expansion: cannot denormalize ",
548  to_string(es, res),
549  ", need support for label one (the empty label)");
550  return res.polynomials;
551  }
552 
554  template <size_t... Tape>
555  auto denormalize(std::tuple<const Expansions&...>& es,
557  -> std::tuple<typename project_t<Tape>::polys_t...>
558  {
559  using res_t = std::tuple<typename project_t<Tape>::polys_t...>;
560  return res_t{denormalize_tape<Tape>(std::get<Tape>(es))...};
561  }
562 
564  auto denormalize(const Expansions&... es) const
565  {
566  auto t = std::tuple<const Expansions&...>{es...};
567  constexpr auto indices
568  = detail::make_index_sequence<sizeof...(Expansions)>{};
569  return denormalize(t, indices);
570  }
571 
572  auto
573  tuple(Expansions&&... es) const
574  -> value_t
575  {
576  auto res = eset_.zero();
577  auto polys = denormalize(std::forward<Expansions>(es)...);
579  ([&res, this](const auto&... ps)
580  {
581  auto l = label_t{ps.first...};
582  eset_.ps_.add_here(res.polynomials[l],
583  eset_.ps_.tuple(ps.second...));
584  },
585  polys);
586  eset_.normalize(res);
587  return res;
588  }
589 
591  };
592 
647  template <typename... Expansions>
648  auto
649  tuple(Expansions&&... es) const
650  -> value_t
651  {
652  auto t = tuple_impl<Expansions...>{*this};
653  return t.tuple(std::forward<Expansions>(es)...);
654  }
655 
656  private:
660  const labelset_t& ls_ = *rs_.labelset();
662  const weightset_t& ws_ = *rs_.weightset();
665  };
666  }
667 
668  template <typename ExpSet>
670  make_expansionset(const ExpSet& expset)
671  {
672  return {expset};
673  }
674 
675  namespace detail
676  {
678  template <typename Ctx1, typename Ctx2>
681  {
683 
685  const expansionset<expressionset<Ctx2>>& rhs)
686  {
687  return type(vcsn::join(lhs.expressionset(), rhs.expressionset()));
688  }
689  };
690  }
691 }
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.
std::integral_constant< bool, B > bool_constant
Definition: type_traits.hh:12
auto join(const ValueSet &vs) -> ValueSet
The join of a single valueset.
Definition: join.hh:44
static value_t conv(self_t, const value_t &v)
Conversion from (this and) other weightsets.
value_t conjunction(value_t l, value_t r) const
The conjunction of l and r.
std::enable_if_t< IsFree, value_t > complement_(const value_t &v) const
Complement on a free labelset.
#define VCSN_REQUIRE(Cond,...)
A macro similar to require.
Definition: raise.hh:89
value_t complement(const value_t &v) const
The complement of v.
const labelset_t & ls_
Shorthand to the labelset.
auto tuple(Expansions &&...es) const -> value_t
value_t lmul(const weight_t &w, const value_t &rhs) const
Left-multiplication by w of rhs.
value_t conv(const expansionset< OtherExpSet > &other, const typename expansionset< OtherExpSet >::value_t &v) const
Convert from another expansionset to self.
void add_here(value_t &lhs, const value_t &rhs) const
In place addition.
Print as rich UTF-8 text, escaped.
Definition: format.hh:28
void weight_set(welement< Label, Weight > &m, const Weight &w)
Set the weight of a welement.
Definition: wet.hh:162
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
Definition: traits.hh:59
value_t & rmul_here(value_t &res, const expression_t &rhs) const
In place right multiplication by an expression.
auto denormalize(const Expansions &...es) const
Entry point: Denormalize all these expansions.
auto conjunction_(value_t lhs, value_t rhs, Conjunction conjunction) const -> std::enable_if_t<!detail::is_letterized_t< LabelSet >
The conjunction of l and r.
value_t rmul(const value_t &lhs, const weight_t &w) const
Right-multiplication of lhs by w.
Definition: a-star.hh:8
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...
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.
STL namespace.
value_t zero() const
The zero.
variadic< type_t::conjunction, Context > conjunction
Definition: fwd.hh:140
Print for LaTeX.
Definition: format.hh:20
typename weightset_t::value_t weight_t
Definition: expansionset.hh:28
value_t infiltration(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 is. For instance, don't try to escape labels.
Definition: format.hh:22
std::ostream & print_set(std::ostream &o, format fmt={}) const
Print this valueset.
Definition: expansionset.hh:79
Denormalize a pack of one-tape expansions.
value_t one() const
The one.
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:55
std::string type(const automaton &a)
The implementation type of a.
Definition: others.cc:206
static symbol sname()
The static name.
Definition: expansionset.hh:53
An input/output format for valuesets.
Definition: format.hh:11
value_t determinize(const value_t &v) const
Turn the polynomials into (normalized) monomials.
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
An inner node with multiple children.
Definition: expression.hh:118
expressionset_t rs_
The expressionset used for the expressions.
auto weight_of(const welement< Label, Weight > &m) -> decltype(m.weight())
The weight of a welement.
Definition: wet.hh:154
context_t_of< expressionset_t > context_t
Definition: expansionset.hh:23
value_t add(const value_t &lhs, const value_t &rhs) const
Addition.
A structure that implements the computation of join(V1, V2).
Definition: join.hh:18
std::enable_if_t<!IsFree, value_t > complement_(const value_t &) const
Cannot complement on a non-free labelset.
expansionset< ExpSet > make_expansionset(const ExpSet &expset)
void conjunctions_with_one_(value_t &, const value_t &, const value_t &, std::false_type, Conjunction) const
value_t & normalize(value_t &res) const
Normalize: move the constant term to the label one.
std::ostream & print(const value_t &v, std::ostream &o, format fmt={}) const
Print this expansion.
expansionset(const expressionset_t &rs)
Definition: expansionset.hh:48
void cross_tuple(Fun f, const std::tuple< Ts... > &ts)
Definition: tuple.hh:235
auto normalize(const Aut &a) -> decltype(copy(a))
Normalize a automaton.
Definition: normalize.hh:20
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
Definition: symbol.hh:23
Print as plain (ASCII) text, escaped.
Definition: format.hh:26
const context_t & context() const
The context.
Definition: expansionset.hh:73
static constexpr const char * me()
Definition: expansionset.hh:34
auto rs
Definition: lift.hh:151
const weightset_t & ws_
Shorthand to the weightset.
constant< type_t::zero, Context > zero
Definition: fwd.hh:108
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.
polynomialset_t ps_
The polynomialset for the polynomials.
static type join(const expansionset< expressionset< Ctx1 >> &lhs, const expansionset< expressionset< Ctx2 >> &rhs)
symbol sname()
Definition: name.hh:67
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:53
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
typename polynomialset_t::monomial_t monomial_t
Definition: expansionset.hh:32
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
Definition: traits.hh:54
Print as a parsable type string.
Definition: format.hh:24
automaton conjunction_(const std::vector< automaton > &as, bool lazy, vcsn::detail::index_sequence< I... >)
Bridge helper.
Definition: conjunction.hh:494
value_t & normalize_(value_t &res, std::false_type) const
Normalize when there is no label one: identity.
value_t & denormalize(value_t &res) const
Move the constant to the polynomial associated to one.
std::string to_string(identities i)
Wrapper around operator<<.
Definition: identities.cc:17
typename polynomialset_t::value_t polynomial_t
Definition: expansionset.hh:31
automaton shuffle_(const std::vector< automaton > &as, vcsn::detail::index_sequence< I... >)
Variadic bridge helper.
Definition: conjunction.hh:543
value_t & denormalize_(value_t &res, std::false_type) const
Denormalize when there is no label one: identity.
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.
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 l and r.
expression_polynomialset_t< ExpSet > make_expression_polynomialset(const ExpSet &rs)
From a ExpSet to its polynomialset.
Definition: split.hh:33
value_t & lmul_here(const weight_t &w, value_t &res) const
Inplace left-multiplication by w of res.
value_t atom(const label_t &l) const
A single label.
const polynomialset_t & polynomialset() const
The polynomialset.
Definition: expansionset.hh:67
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:26
Implementation of nodes of tuple of rational expressions.
Definition: expression.hh:182
weightset_t_of< expressionset_t > weightset_t
Definition: expansionset.hh:27
auto project() const -> project_t< Tape >
The expansionsset for tape Tape.
value_t & ldiv_here(const weight_t &w, value_t &res) const
Inplace left-division by w of res.
zipped_maps< Dereference, Maps... > zip_maps(Maps &&...maps)
Definition: zip-maps.hh:250
labelset_t_of< context_t > labelset_t
Definition: expansionset.hh:24
std::map< label_t, polynomial_t, vcsn::less< labelset_t >> polys_t
Definition: expansionset.hh:39
const expressionset_t & expressionset() const
The expressionset.
Definition: expansionset.hh:61