Vcsn  2.5
Be Rational
nullableset.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <memory>
4 #include <sstream>
5 
6 #include <boost/optional.hpp>
7 
8 #include <vcsn/alphabets/setalpha.hh> // intersect
9 #include <vcsn/core/kind.hh>
10 #include <vcsn/labelset/fwd.hh>
13 #include <vcsn/labelset/oneset.hh>
14 #include <vcsn/misc/escape.hh>
15 #include <vcsn/misc/functional.hh>
16 #include <vcsn/misc/raise.hh>
17 
18 namespace vcsn
19 {
20  namespace detail
21  {
28  template <typename LabelSet>
30  {
31  using labelset_t = LabelSet;
32  using value_t = std::pair<typename labelset_t::value_t, bool>;
33 
34  ATTRIBUTE_PURE
35  static constexpr value_t
36  one()
37  {
38  return value_t{labelset_t::special(), true};
39  }
40 
41  ATTRIBUTE_PURE
42  static constexpr value_t
44  {
45  return value_t{labelset_t::special(), false};
46  }
47 
48  template <typename Ls>
49  ATTRIBUTE_PURE
50  static std::enable_if_t<Ls::has_one(), bool>
51  is_one_(const value_t& l)
52  {
53  return std::get<1>(l) || Ls::is_one(get_value(l));
54  }
55 
56  template <typename Ls>
57  ATTRIBUTE_PURE
58  static std::enable_if_t<!Ls::has_one(), bool>
59  is_one_(const value_t& l)
60  {
61  return std::get<1>(l);
62  }
63 
64  ATTRIBUTE_PURE
65  static bool
66  is_one(const value_t& l)
67  {
68  return is_one_<labelset_t>(l);
69  }
70 
71  template <typename Value>
72  static Value
73  transpose(const labelset_t& ls, Value l)
74  {
75  // This is not robust enough: Value is word_t, then it's not
76  // valid to call is_one on it. Since I'm unsure of the future
77  // of nullableset, let's not waste time on this now.
78  if (is_one(l))
79  return l;
80  else
81  return {ls.transpose(get_value(l)), false};
82  }
83 
84  template <typename... Args>
85  static value_t
86  value(const labelset_t& ls, Args&&... args)
87  {
88  return {ls.value(std::forward<Args>(args)...), false};
89  }
90 
91  ATTRIBUTE_PURE
92  static typename labelset_t::value_t
94  {
95  return std::get<0>(v);
96  }
97  };
98 
105  template <typename GenSet>
106  struct nullable_helper<letterset<GenSet>>
107  {
108  using genset_t = GenSet;
110  using value_t = typename labelset_t::value_t;
111 
112  ATTRIBUTE_PURE
113  static constexpr value_t
115  {
116  return genset_t::special();
117  }
118 
119  ATTRIBUTE_PURE
120  static constexpr value_t
121  one()
122  {
123  return genset_t::one_letter();
124  }
125 
126  ATTRIBUTE_PURE
127  static bool
129  {
130  return l == one();
131  }
132 
133  template <typename Value>
134  static Value
135  transpose(const labelset_t& ls, const Value& l)
136  {
137  return ls.transpose(l);
138  }
139 
140  template <typename... Args>
141  static value_t
142  value(const labelset_t& ls, Args&&... args)
143  {
144  return ls.value(std::forward<Args>(args)...);
145  }
146 
147  ATTRIBUTE_PURE
148  static value_t
150  {
151  return v;
152  }
153  };
154  }
155 
157  template <typename LabelSet>
158  class nullableset
159  {
160  public:
161  using labelset_t = LabelSet;
162  using labelset_ptr = std::shared_ptr<const labelset_t>;
166 
167  using value_t = typename helper_t::value_t;
168  using letter_t = typename labelset_t::letter_t;
169  using word_t = typename labelset_t::word_t;
170 
171  private:
175 
176  public:
177  using genset_ptr = decltype(ls_->genset());
178  using genset_t = decltype(ls_->generators());
179 
180  public:
182  : ls_{ls}
183  {}
184 
185  nullableset(const labelset_t& ls = {})
186  : nullableset{std::make_shared<const labelset_t>(ls)}
187  {}
188 
189  static symbol sname()
190  {
191  static auto res = symbol{"nullableset<" + labelset_t::sname() + '>'};
192  return res;
193  }
194 
196  static nullableset make(std::istream& is)
197  {
198  // name: nullableset<lal_char(abc)>.
199  // ^^^^^^^^^^^^
200  // labelset
201  eat(is, "nullableset<");
202  auto ls = labelset_t::make(is);
203  eat(is, '>');
204  return {ls};
205  }
206 
210  bool open(bool o) const
211  {
212  return this->ls_->open(o);
213  }
214 
215  static constexpr bool
217  {
218  return true;
219  }
220 
221  static constexpr bool
223  {
224  return false;
225  }
226 
227  static constexpr bool
229  {
230  return labelset_t::is_letterized();
231  }
232 
233  static constexpr bool is_free()
234  {
235  return false;
236  }
237 
238  ATTRIBUTE_PURE
239  static constexpr value_t
240  one()
241  {
242  return helper_t::one();
243  }
244 
245  ATTRIBUTE_PURE
246  static bool
248  {
249  return helper_t::is_one(l);
250  }
251 
252  bool
254  {
255  return is_one(v) || ls_->is_valid(get_value(v));
256  }
257 
258  genset_ptr
259  genset() const
260  {
261  return ls_->genset();
262  }
263 
265  decltype(auto)
266  generators() const
267  {
268  return ls_->generators();
269  }
270 
271  value_t
273  {
274  return v;
275  }
276 
277  value_t
278  conv(oneset, typename oneset::value_t) const
279  {
280  return one();
281  }
282 
286  template <typename LabelSet_>
287  value_t
288  conv(const LabelSet_& ls, typename LabelSet_::value_t v) const
289  {
290  return value(ls_->conv(ls, v));
291  }
292 
293  const labelset_ptr labelset() const
294  {
295  return ls_;
296  }
297 
298  template <typename... Args>
299  value_t
300  value(Args&&... args) const
301  {
302  return helper_t::value(*ls_, std::forward<Args>(args)...);
303  }
304 
305  word_t
306  word(const value_t& l) const
307  {
308  if (is_one(l))
309  return make_wordset(*labelset()).one();
310  else
311  return ls_->word(get_value(l));
312  }
313 
315  auto static
317  -> decltype(labelset_t::letters_of(v))
318  {
319  return labelset_t::letters_of(v);
320  }
321 
324  auto
326  -> decltype(ls_->letters_of_padded(v, l))
327  {
328  return ls_->letters_of_padded(v, l);
329  }
330 
331  auto
333  -> decltype(this->letters_of_padded(this->word(v), l))
334  {
335  return letters_of_padded(word(v), l);
336  }
337 
339  static int compare(const value_t& l, const value_t& r)
340  {
341  if (auto res = int(is_one(r)) - int(is_one(l)))
342  return res;
343  else
344  return labelset_t::compare(get_value(l), get_value(r));
345  }
346 
348  static bool equal(const value_t& l, const value_t& r)
349  {
350  if (is_one(l))
351  return is_one(r);
352  else
353  return !is_one(r) && labelset_t::equal(get_value(l), get_value(r));
354  }
355 
357  static bool less(const value_t& l, const value_t& r)
358  {
359  if (is_one(r))
360  return false;
361  else if (is_one(l))
362  return true;
363  else
364  return labelset_t::less(get_value(l), get_value(r));
365  }
366 
368  value_t mul(const value_t& l, const value_t& r) const
369  {
370  if (is_one(r))
371  return l;
372  else if (is_one(l))
373  return r;
374  else
375  raise(*this, ": mul: invalid arguments: ",
376  to_string(*this, l), ", ", to_string(*this, r));
377  }
378 
380  value_t lgcd(const value_t& l, const value_t& r) const
381  {
382  if (equal(l, r))
383  return l;
384  else if (is_one(l) || is_one(r))
385  return one();
386  else
387  return value(ls_->lgcd(get_value(l), get_value(r)));
388  }
389 
391  value_t ldivide(const value_t& l, const value_t& r) const
392  {
393  if (auto res = maybe_ldivide(l, r))
394  return *res;
395  else
396  raise(*this, ": ldivide: invalid arguments: ",
397  to_string(*this, l), ", ", to_string(*this, r));
398  }
399 
400  boost::optional<value_t>
401  maybe_ldivide(const value_t& l, const value_t& r) const
402  {
403  if (equal(l, r))
404  return one();
405  else if (is_one(l))
406  return r;
407  else if (is_one(r))
408  return boost::none;
409  else if (auto res = ls_->maybe_ldivide(get_value(l), get_value(r)))
410  return value(*res);
411  else
412  return boost::none;
413  }
414 
416  value_t rdivide(const value_t& l, const value_t& r) const
417  {
418  if (auto res = maybe_rdivide(l, r))
419  return *res;
420  else
421  raise(*this, ": rdivide: invalid arguments: ",
422  to_string(*this, l), ", ", to_string(*this, r));
423  }
424 
425  boost::optional<value_t>
426  maybe_rdivide(const value_t& l, const value_t& r) const
427  {
428  if (equal(l, r))
429  return one();
430  else if (is_one(l))
431  return boost::none;
432  else if (is_one(r))
433  return l;
434  else if (auto res = ls_->maybe_rdivide(get_value(l), get_value(r)))
435  return value(*res);
436  else
437  return boost::none;
438  }
439 
440  static value_t
442  {
443  return helper_t::special();
444  }
445 
446  static bool
448  {
449  return !is_one(v) && labelset_t::is_special(get_value(v));
450  }
451 
452  static size_t size(const value_t& v)
453  {
454  return is_one(v) ? 0 : labelset_t::size(get_value(v));
455  }
456 
457  // FIXME: specialize for both implementation.
458  static size_t hash(const value_t& v)
459  {
460  // Do not use get_value when is_one. Let's hash one() as 0.
461  return is_one(v) ? 0 : labelset_t::hash(get_value(v));
462  }
463 
464  letter_t
465  get_letter(std::istream& i, bool quoted = true) const
466  {
467  return ls_->get_letter(i, quoted);
468  }
469 
471  value_t
472  conv(std::istream& i, bool quoted = true) const
473  {
474  // Check for '\e', otherwise pass it to the inner labelset.
475  if (i.good() && i.peek() == '\\')
476  {
477  i.ignore();
478  int c = i.peek();
479  if (c == 'e')
480  {
481  i.ignore();
482  return {};
483  }
484  else
485  i.unget();
486  }
487  return value(ls_->conv(i, quoted));
488  }
489 
499  template <typename Fun>
500  void convs(std::istream& i, Fun&& fun) const
501  {
502  ls_->convs(i,
503  [this,fun](const typename labelset_t::value_t& l)
504  {
505  fun(value(l));
506  });
507  }
508 
509  value_t conjunction(const value_t& l, const value_t& r) const
510  {
511  if (is_one(l) && is_one(r))
512  return l;
513  else if (!is_one(l) && !is_one(r))
514  return ls_->conjunction(get_value(l), get_value(r));
515  else
516  raise(*this,
517  ": conjunction: invalid operation (lhs and rhs are not equal): ",
518  to_string(*this, l), ", ", to_string(*this, r));
519  }
520 
522  std::ostream&
523  print(const value_t& l, std::ostream& o = std::cout,
524  format fmt = {}) const
525  {
526  if (is_one(l))
527  o << (fmt == format::latex ? "\\varepsilon"
528  : fmt == format::utf8 ? "ε"
529  : "\\e");
530  else
531  ls_->print(get_value(l), o, fmt);
532  return o;
533  }
534 
535  value_t
536  zero() const
537  {
538  return value(ls_->zero());
539  }
540 
541  bool
542  is_zero(const value_t& v) const
543  {
544  return !is_one(v) && ls_->is_zero(get_value(v));
545  }
546 
547  bool
548  is_letter(const value_t& v) const
549  {
550  return !is_one(v) && ls_->is_letter(get_value(v));
551  }
552 
554  template <typename Value>
555  Value
556  transpose(const Value& l) const
557  {
558  return helper_t::transpose(*ls_, l);
559  }
560 
562  std::ostream&
563  print_set(std::ostream& o, format fmt = {}) const
564  {
565  switch (fmt.kind())
566  {
567  case format::latex:
568  o << "(";
569  ls_->print_set(o, fmt);
570  o << ")^?";
571  break;
572 
573  case format::sname:
574  o << "nullableset<";
575  ls_->print_set(o, fmt);
576  o << '>';
577  break;
578 
579  case format::text:
580  case format::utf8:
581  ls_->print_set(o, fmt);
582  o << '?';
583  break;
584 
585  case format::raw:
586  assert(0);
587  break;
588  }
589 
590  return o;
591  }
592 
594  static typename labelset_t::value_t
595  get_value(const value_t& v)
596  {
597  assert(!is_one(v));
598  return helper_t::get_value(v);
599  }
600  };
601 
602  namespace detail
603  {
605  template <typename LabelSet>
606  struct letterized_traits<nullableset<LabelSet>>
607  {
608  using traits = letterized_traits<LabelSet>;
609  static constexpr bool is_letterized = traits::is_letterized;
610 
611  using labelset_t = typename traits::labelset_t;
612 
613  static labelset_t labelset(const nullableset<LabelSet>& ls)
614  {
615  return make_letterized(*ls.labelset());
616  }
617  };
618 
620  template <typename LabelSet>
621  struct nullableset_traits<nullableset<LabelSet>>
622  {
623  using type = nullableset<LabelSet>;
624  static type value(const nullableset<LabelSet>& ls)
625  {
626  return ls;
627  }
628  };
629 
630  template <typename LabelSet>
631  struct proper_traits<nullableset<LabelSet>>
632  {
633  using type = LabelSet;
634  static type value(const nullableset<LabelSet>& ls)
635  {
636  return *ls.labelset();
637  }
638  };
639 
641  template <typename LabelSet>
642  struct law_traits<nullableset<LabelSet>>
643  {
644  using type = law_t<LabelSet>;
645  static type value(const nullableset<LabelSet>& ls)
646  {
647  return make_wordset(*ls.labelset());
648  }
649  };
650 
651  /*-------.
652  | Join. |
653  `-------*/
654 
656  template <typename LS>
657  struct join_impl<oneset, LS,
658  std::enable_if_t<!LS::has_one()>>
659  {
660  using type = nullableset<LS>;
661  static type join(const oneset&, const LS& ls)
662  {
663  return {ls};
664  }
665  };
666 
668  template <typename LS>
669  struct join_impl<oneset, LS,
670  std::enable_if_t<LS::has_one()>>
671  {
672  using type = LS;
673  static type join(const oneset&, const LS& ls)
674  {
675  return ls;
676  }
677  };
678 
680  template <typename LS1, typename LS2>
681  struct join_impl<nullableset<LS1>, LS2>
682  {
683  using type = nullableset<join_t<LS1, LS2>>;
684  static type join(const nullableset<LS1>& ls1, const LS2& ls2)
685  {
686  return {::vcsn::join(*ls1.labelset(), ls2)};
687  }
688  };
689 
694  template <typename LS1, typename LS2>
695  struct join_impl<nullableset<LS1>, nullableset<LS2>>
696  {
697  using type = nullableset<join_t<LS1, LS2>>;
698  static type join(const nullableset<LS1>& ls1,
699  const nullableset<LS2>& ls2)
700  {
701  return {::vcsn::join(*ls1.labelset(), *ls2.labelset())};
702  }
703  };
704  }
705 
706  /*-------.
707  | Meet. |
708  `-------*/
709 
710 #define DEFINE(Lhs, Rhs, Res) \
711  template <typename GenSet> \
712  Res \
713  meet(const Lhs& lhs, const Rhs& rhs) \
714  { \
715  return {set_intersection(*lhs.genset(), *rhs.genset())}; \
716  }
717 
719  DEFINE(nullableset<letterset<GenSet>>,
720  nullableset<letterset<GenSet>>, nullableset<letterset<GenSet>>);
721 
722  DEFINE(letterset<GenSet>,
723  nullableset<letterset<GenSet>>, nullableset<letterset<GenSet>>);
724 
725  DEFINE(nullableset<letterset<GenSet>>,
726  letterset<GenSet>, nullableset<letterset<GenSet>>);
727 
728  template <typename Lls, typename Rls>
729  nullableset<meet_t<Lls, Rls>>
730  meet(const nullableset<Lls>& lhs, const nullableset<Rls>& rhs)
731  {
732  return nullableset<meet_t<Lls, Rls>>{meet(*lhs.labelset(),
733  *rhs.labelset())};
734  }
735 
736 #undef DEFINE
737 
738 
739  /*----------------.
740  | random_label. |
741  `----------------*/
742 
744  template <typename LabelSet,
745  typename RandomGenerator = std::default_random_engine>
746  typename nullableset<LabelSet>::value_t
747  random_label(const nullableset<LabelSet>& ls,
748  RandomGenerator& gen = RandomGenerator())
749  {
750  // FIXME: the proportion should be controllable.
751  auto dis = std::bernoulli_distribution(0.5);
752  if (dis(gen) || ls.generators().empty())
753  return ls.one();
754  else
755  return ls.value(random_label(*ls.labelset(), gen));
756  }
757 }
typename helper_t::value_t value_t
Definition: nullableset.hh:167
value_t conv(oneset, typename oneset::value_t) const
Definition: nullableset.hh:278
word_t word(const value_t &l) const
Definition: nullableset.hh:306
typename labelset_t::letter_t letter_t
Definition: nullableset.hh:168
genset_ptr genset() const
Definition: nullableset.hh:259
Print as a parsable type string.
Definition: format.hh:26
Implementation of labels are nullables (letter or empty).
Definition: fwd.hh:14
static ATTRIBUTE_PURE value_t get_value(const value_t &v)
Definition: nullableset.hh:149
value_t conv(std::istream &i, bool quoted=true) const
Read a label from a stream.
Definition: nullableset.hh:472
static ATTRIBUTE_PURE constexpr value_t one()
Definition: nullableset.hh:240
static ATTRIBUTE_PURE std::enable_if_t<!Ls::has_one(), bool > is_one_(const value_t &l)
Definition: nullableset.hh:59
value_t conjunction(const value_t &l, const value_t &r) const
Definition: nullableset.hh:509
value_t value(Args &&... args) const
Value constructor.
Definition: letterset.hh:83
std::ostream & print_set(std::ostream &o, format fmt={}) const
Print labelset description.
Definition: nullableset.hh:563
boost::optional< value_t > maybe_rdivide(const value_t &l, const value_t &r) const
Definition: nullableset.hh:426
typename labelset_t::word_t word_t
Definition: nullableset.hh:169
static constexpr bool has_one()
Definition: nullableset.hh:216
Definition: a-star.hh:8
bool is_special(const Aut &aut, transition_t_of< Aut > t)
Whether this transition is from pre or to post.
Definition: automaton.hh:229
return res
Definition: multiply.hh:398
static ATTRIBUTE_PURE std::enable_if_t< Ls::has_one(), bool > is_one_(const value_t &l)
Definition: nullableset.hh:51
static size_t size(const value_t &v)
Definition: nullableset.hh:452
static ATTRIBUTE_PURE bool is_one(const value_t &l)
Definition: nullableset.hh:66
static ATTRIBUTE_PURE constexpr value_t special()
Definition: nullableset.hh:43
static ATTRIBUTE_PURE labelset_t::value_t get_value(const value_t &v)
Definition: nullableset.hh:93
letter_t get_letter(std::istream &i, bool quoted=true) const
Definition: nullableset.hh:465
std::shared_ptr< const labelset_t > labelset_ptr
Definition: nullableset.hh:162
Add support for an empty word to a LabelSet that does not provide such special label to this end...
Definition: nullableset.hh:29
decltype(ls_->genset()) genset_ptr
Definition: nullableset.hh:177
void convs(std::istream &i, Fun &&fun) const
Process a label class.
Definition: nullableset.hh:500
letter_t value_t
Definition: letterset.hh:33
static size_t hash(const value_t &v)
Definition: nullableset.hh:458
static value_t value(const labelset_t &ls, Args &&... args)
Definition: nullableset.hh:142
static bool equal(const value_t &l, const value_t &r)
Whether l == r.
Definition: nullableset.hh:348
std::ostream & print(const value_t &l, std::ostream &o=std::cout, format fmt={}) const
Print label to stream.
Definition: nullableset.hh:523
bool open(bool o) const
Whether unknown letters should be added, or rejected.
Definition: nullableset.hh:210
static ATTRIBUTE_PURE constexpr value_t one()
Definition: nullableset.hh:121
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
Definition: symbol.hh:21
boost::optional< value_t > maybe_ldivide(const value_t &l, const value_t &r) const
Definition: nullableset.hh:401
Value transpose(const Value &l) const
Mirror label.
Definition: nullableset.hh:556
value_t ldivide(const value_t &l, const value_t &r) const
Compute l \ r = l^{-1}r.
Definition: nullableset.hh:391
weightset_mixin< detail::r_impl > r
Definition: fwd.hh:54
Implementation of labels are ones: there is a single instance of label.
Definition: oneset.hh:19
value_t conv(self_t, value_t v) const
Definition: nullableset.hh:272
static bool less(const value_t &l, const value_t &r)
Whether l < r.
Definition: nullableset.hh:357
Print as rich UTF-8 text, escaped.
Definition: format.hh:30
labelset_ptr ls_
The wrapped LabelSet.
Definition: nullableset.hh:174
decltype(ls_->generators()) genset_t
Definition: nullableset.hh:178
nullableset(const labelset_t &ls={})
Definition: nullableset.hh:185
bool value_t
Definition: oneset.hh:23
Print for LaTeX.
Definition: format.hh:22
static Value transpose(const labelset_t &ls, Value l)
Definition: nullableset.hh:73
bool is_valid(value_t v) const
Definition: nullableset.hh:253
static Value transpose(const labelset_t &ls, const Value &l)
Definition: nullableset.hh:135
std::enable_if_t<!is_letterized_t< labelset_t_of< Aut > >{}, bool > is_letterized(const Aut &aut)
Definition: letterize.hh:161
bool is_letter(const value_t &v) const
Definition: nullableset.hh:548
nullableset(const labelset_ptr &ls)
Definition: nullableset.hh:181
value_t value(Args &&... args) const
Definition: nullableset.hh:300
An input/output format for valuesets.
Definition: format.hh:13
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
Aut transpose(const transpose_automaton< Aut > &aut)
The transpose of a transpose automaton is the original automaton.
Definition: transpose.hh:253
ATTRIBUTE_PURE auto transpose(Args &&... args) const -> decltype(this->genset() -> transpose(std::forward< Args >(args)...))
static ATTRIBUTE_PURE constexpr value_t one()
Definition: nullableset.hh:36
constant< type_t::one, Context > one
Definition: fwd.hh:117
static constexpr bool is_letterized()
Definition: nullableset.hh:228
auto letters_of_padded(const word_t &v, letter_t l) const -> decltype(ls_->letters_of_padded(v, l))
Prepare to iterate over the letters of v.
Definition: nullableset.hh:325
static symbol sname()
Definition: nullableset.hh:189
static ATTRIBUTE_PURE bool is_one(value_t l)
Definition: nullableset.hh:247
static constexpr bool is_free()
Definition: nullableset.hh:233
static ATTRIBUTE_PURE constexpr value_t special()
Definition: nullableset.hh:114
const labelset_ptr labelset() const
Definition: nullableset.hh:293
Implementation of labels are letters.
Definition: fwd.hh:10
char eat(std::istream &is, char c)
Check lookahead character and advance.
Definition: stream.cc:130
value_t mul(const value_t &l, const value_t &r) const
The concatenation.
Definition: nullableset.hh:368
static value_t value(const labelset_t &ls, Args &&... args)
Definition: nullableset.hh:86
static ATTRIBUTE_PURE bool is_one(value_t l)
Definition: nullableset.hh:128
value_t conv(const LabelSet_ &ls, typename LabelSet_::value_t v) const
Conversion from another type: first by the wrapped labelset, and then by our wrappers (in case the wr...
Definition: nullableset.hh:288
static auto letters_of(const word_t &v) -> decltype(labelset_t::letters_of(v))
Prepare to iterate over the letters of v.
Definition: nullableset.hh:316
value_t lgcd(const value_t &l, const value_t &r) const
The longest common prefix.
Definition: nullableset.hh:380
int compare(const Lhs &lhs, const Rhs &rhs)
Comparison between lhs and rhs.
value_t zero() const
Definition: nullableset.hh:536
std::pair< typename labelset_t::value_t, bool > value_t
Definition: nullableset.hh:32
auto letters_of_padded(value_t v, letter_t l) const -> decltype(this->letters_of_padded(this->word(v), l))
Definition: nullableset.hh:332
static int compare(const value_t &l, const value_t &r)
Three way comparison between l and r.
Definition: nullableset.hh:339
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
static value_t special()
Definition: nullableset.hh:441
std::string to_string(direction d)
Conversion to string.
Definition: direction.cc:7
bool is_zero(const value_t &v) const
Definition: nullableset.hh:542
static bool is_special(const value_t &v)
Definition: nullableset.hh:447
symbol sname()
Definition: name.hh:65
static nullableset make(std::istream &is)
Build from the description in is.
Definition: nullableset.hh:196
value_t rdivide(const value_t &l, const value_t &r) const
Compute l / r.
Definition: nullableset.hh:416
law_t< LabelSet > make_wordset(const LabelSet &ls)
The wordset of a labelset.
Definition: labelset.hh:260
static constexpr bool is_expressionset()
Definition: nullableset.hh:222