Vcsn  2.5
Be Rational
tupleset.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <array>
4 #include <iosfwd>
5 #include <istream>
6 #include <set>
7 #include <tuple>
8 
9 #include <boost/range/join.hpp>
10 #include <boost/optional.hpp>
11 
12 #include <vcsn/config.hh> // VCSN_HAVE_CORRECT_LIST_INITIALIZER_ORDER
13 //#include <vcsn/core/rat/expressionset.hh> needed, but breaks everythying...
14 #include <vcsn/labelset/fwd.hh>
16 #include <vcsn/misc/cross.hh>
17 #include <vcsn/misc/escape.hh>
18 #include <vcsn/misc/filter.hh>
19 #include <vcsn/misc/raise.hh>
20 #include <vcsn/misc/static-if.hh>
21 #include <vcsn/misc/stream.hh>
22 #include <vcsn/misc/tuple.hh> // tuple_element_t
23 #include <vcsn/misc/zip.hh>
24 #include <vcsn/weightset/b.hh>
25 
26 namespace vcsn
27 {
28  namespace detail
29  {
30 
35  template <typename Enable = void, typename... ValueSets>
37  {
38  using genset_t = void;
39  using genset_ptr = void;
40  using letter_t = void;
41  using letters_t = void;
43  using word_t = std::tuple<typename ValueSets::value_t...>;
44  constexpr static bool is_labelset = false;
45  };
46 
48  template <typename... ValueSets>
49  struct labelset_types_impl<decltype(pass{std::declval<ValueSets>().genset()...},
50  void()),
51  ValueSets...>
52  {
53  using genset_t
54  = cross_sequences<decltype(std::declval<ValueSets>().generators())...>;
55  using genset_ptr = std::tuple<typename ValueSets::genset_ptr...>;
56  using letter_t = std::tuple<typename ValueSets::letter_t...>;
57  using letters_t = std::set<letter_t,
58  vcsn::less<tupleset<ValueSets...>, letter_t>>;
59  using word_t = std::tuple<typename ValueSets::word_t...>;
60  constexpr static bool is_labelset = true;
61  };
62 
63  template <typename... ValueSets>
64  using labelset_types = labelset_types_impl<void, ValueSets...>;
65 
70  template <typename... ValueSets>
71  class tupleset_impl
72  {
73  public:
74  using valuesets_t = std::tuple<ValueSets...>;
75  using indices_t = make_index_sequence<sizeof...(ValueSets)>;
76  static constexpr indices_t indices{};
77  template <std::size_t... I>
78  using seq = index_sequence<I...>;
79 
81  template <std::size_t I>
83 
84  public:
85  using self_t = tupleset<ValueSets...>;
86 
88  using value_t = std::tuple<typename ValueSets::value_t...>;
89 
91  using letter_t = typename labelset_types<ValueSets...>::letter_t;
93  using letters_t = typename labelset_types<ValueSets...>::letters_t;
95  // using genset_t = typename labelset_types<ValueSets...>::genset_t;
96  using genset_ptr = typename labelset_types<ValueSets...>::genset_ptr;
98  using word_t = typename labelset_types<ValueSets...>::word_t;
99 
101  constexpr static bool is_labelset
103 
106 
108 
110  : sets_(std::move(vs))
111  {}
112 
113  tupleset_impl(ValueSets... ls)
114  : sets_(ls...)
115  {}
116 
117  static symbol sname()
118  {
119  static auto res = symbol{sname_(indices)};
120  return res;
121  }
122 
124  static constexpr std::size_t size()
125  {
126  return sizeof...(ValueSets);
127  }
128 
130  template <typename Value>
131  static size_t size(const Value& v)
132  {
133  return size_(v, indices);
134  }
135 
136  static constexpr bool
138  {
139  return is_commutative_(indices);
140  }
141 
142  static constexpr bool
144  {
145  return is_idempotent_(indices);
146  }
147 
149  static self_t make(std::istream& is)
150  {
151  // name: lat<law_char(abc), law_char(xyz)>
152  kind_t::make(is);
153  eat(is, '<');
154  auto res = make_(is, indices);
155  eat(is, '>');
156  return res;
157  }
158 
160  const valuesets_t& sets() const
161  {
162  return sets_;
163  }
164 
166  template <size_t I>
167  const valueset_t<I>& set() const
168  {
169  return std::get<I>(sets());
170  }
171 
173  template <size_t I>
175 
179  template <size_t I>
180  const valueset_t<I>& project() const
181  {
182  return set<I>();
183  }
184 
186  template <size_t I>
187  auto project(const value_t& v) const
188  {
189  return std::get<I>(v);
190  }
191 
195  bool open(bool o) const
196  {
197  return this->open_(o, indices);
198  }
199 
201  template <typename... Args>
202  value_t value(const std::tuple<Args...>& args) const
203  {
204  return this->value_(args, indices);
205  }
206 
208  template <typename... Args>
209  value_t tuple(Args&&... args) const
210  {
211  return value_t{args...};
212  }
213 
214  genset_ptr
215  genset() const
216  {
217  return this->genset_(indices);
218  }
219 
221  auto
222  generators() const
223  {
224  return this->generators_(indices);
225  }
226 
227  static constexpr bool is_free()
228  {
229  return is_free_(indices);
230  }
231 
233  template <typename... Args>
234  auto
235  word(const std::tuple<Args...>& v) const
236  -> word_t
237  {
238  return this->word_(v, indices);
239  }
240 
242  static bool
243  equal(const value_t& l, const value_t& r)
244  {
245  return equal_(l, r, indices);
246  }
247 
249  template <typename LhsValue, typename RhsValue>
250  static auto
251  compare(const LhsValue& l, const RhsValue& r)
252  -> int
253  {
254  return less(r, l) - less(l, r);
255  }
256 
258  template <typename LhsValue, typename RhsValue>
259  static auto
260  less(const LhsValue& l, const RhsValue& r)
261  -> bool
262  {
263  auto sl = size(l);
264  auto sr = size(r);
265  if (sl < sr)
266  return true;
267  else if (sr < sl)
268  return false;
269  else
270  return less_(l, r, indices);
271  }
272 
273  static value_t
275  {
276  return special_(indices);
277  }
278 
279  static bool
280  is_special(const value_t& l)
281  {
282  return is_special_(l, indices);
283  }
284 
285  value_t
286  zero() const
287  {
288  return this->zero_(indices);
289  }
290 
291  bool
292  is_zero(const value_t& l) const
293  {
294  return is_zero_(l, indices);
295  }
296 
297  static constexpr bool
299  {
300  return has_lightening_weights_(indices);
301  }
302 
303  static constexpr bool
305  {
306  return has_one_(indices);
307  }
308 
309  static constexpr bool
311  {
312  return is_expressionset_(indices);
313  }
314 
315  static constexpr bool
317  {
318  return is_letterized_(indices);
319  }
320 
321  private:
322  template <std::size_t... I>
323  static auto one_(seq<I...>)
324  -> decltype(value_t{valueset_t<I>::one()...})
325  {
326  return value_t{valueset_t<I>::one()...};
327  }
328 
329  public:
334  template <typename Indices = indices_t>
335  static auto one() -> decltype(one_(Indices{}))
336  {
337  return one_(Indices{});
338  }
339 
340  static bool
341  is_one(const value_t& l)
342  {
343  return is_one_(l, indices);
344  }
345 
346  static bool
348  {
349  return show_one_(indices);
350  }
351 
352  bool
353  is_letter(const value_t&) const
354  {
355  // FIXME: why??? Is this for the printer of expressions?
356  return false;
357  }
358 
360  value_t
361  add(const value_t& l, const value_t& r) const
362  {
363  return map_(l, r,
364  [](const auto& vs, const auto& l, const auto& r)
365  {
366  return vs.add(l, r);
367  });
368  }
369 
374  template <typename LhsValue, typename RhsValue>
375  auto
376  mul(const LhsValue& l, const RhsValue& r) const
377  -> word_t
378  {
379  return this->mul_(l, r, indices);
380  }
381 
383  value_t
384  lgcd(const value_t& l, const value_t& r) const
385  {
386  return map_(l, r,
387  [](const auto& vs, const auto& l, const auto& r)
388  {
389  return vs.lgcd(l, r);
390  });
391  }
392 
394  value_t
395  rdivide(const value_t& l, const value_t& r) const
396  {
397  return map_(l, r,
398  [](const auto& vs, const auto& l, const auto& r)
399  {
400  return vs.rdivide(l, r);
401  });
402  }
403 
404  boost::optional<value_t>
405  maybe_rdivide(const value_t& l, const value_t& r) const
406  {
407  bool valid = true;
408  auto res = map_(l, r,
409  [&valid](const auto& vs, const auto& l, const auto& r)
410  {
411  if (auto res = vs.maybe_rdivide(l, r))
412  return *res;
413  else
414  {
415  valid = false;
416  return l;
417  }
418  });
419 
420  if (valid)
421  return res;
422  else
423  return boost::none;
424  }
425 
427  value_t
428  ldivide(const value_t& l, const value_t& r) const
429  {
430  return map_(l, r,
431  [](const auto& vs, const auto& l, const auto& r)
432  {
433  return vs.ldivide(l, r);
434  });
435  }
436 
437  boost::optional<value_t>
438  maybe_ldivide(const value_t& l, const value_t& r) const
439  {
440  bool valid = true;
441  auto res = map_(l, r,
442  [&valid](const auto& vs, const auto& l, const auto& r)
443  {
444  if (auto res = vs.maybe_ldivide(l, r))
445  return *res;
446  else
447  {
448  valid = false;
449  return l;
450  }
451  });
452 
453  if (valid)
454  return res;
455  else
456  return boost::none;
457  }
458 
463  typename valueset_t<0>::value_t
465  {
466  return this->lnormalize_here_(v, indices);
467  }
468 
470  value_t
471  star(const value_t& v) const
472  {
473  return map_(v,
474  [](const auto& vs, const auto& v)
475  {
476  return vs.star(v);
477  });
478  }
479 
485  template <typename Value>
486  Value
487  delimit(const Value& l) const
488  {
489  return this->delimit_(l, indices);
490  }
491 
493  template <typename Value>
494  Value
495  undelimit(const Value& l) const
496  {
497  return this->undelimit_(l, indices);
498  }
499 
500  // FIXME: this needs to be computed.
501  static constexpr star_status_t star_status()
502  {
504  }
505 
507  template <typename Value>
508  Value
509  transpose(const Value& l) const
510  {
511  return this->transpose_(l, indices);
512  }
513 
514  static size_t
515  hash(const value_t& v)
516  {
517  return hash_(v, indices);
518  }
519 
520  static value_t
522  {
523  return v;
524  }
525 
526  value_t
527  conv(b, b::value_t v) const
528  {
529  return v ? one() : zero();
530  }
531 
533  template <typename... VS>
534  value_t
536  const typename tupleset<VS...>::value_t& v) const
537  {
538  return this->conv_(vs, v, indices);
539  }
540 
542  template <typename... VS>
543  value_t
545  const typename nullableset<tupleset<VS...>>::value_t& v) const
546  {
547  return conv(*vs.labelset(), vs.get_value(v));
548  }
549 
551  value_t
552  conv(std::istream& i, bool quoted = true) const
553  {
554  constexpr auto has_label_one
556  return conv_(i, quoted, bool_constant<has_label_one>{});
557  }
558 
560  template <typename Fun>
561  void convs(std::istream& i, Fun&& fun) const
562  {
563  eat(i, '[');
564  conv_label_class_(*this, i,
565  [this,fun](const letter_t& l)
566  { fun(this->value(l)); });
567  eat(i, ']');
568  }
569 
570  std::ostream&
571  print_set(std::ostream& o, format fmt = {}) const
572  {
573  return this->print_set_(o, fmt, indices);
574  }
575 
576  std::ostream&
577  print(const value_t& l, std::ostream& o = std::cout,
578  format fmt = {}) const
579  {
580  return this->print_(l, o,
581  // 1, (2, 3) is different from 1, 2, 3:
582  // delimit components.
583  fmt.delimit(true),
584  fmt.delimit() ? "(" : "",
585  fmt.is_for_labels() ? "|" : ",",
586  fmt.delimit() ? ")" : "",
587  indices);
588  }
589 
590  private:
591  template <std::size_t... I>
592  static std::string sname_(seq<I...>)
593  {
594  std::string res = "lat<";
595  const char *sep = "";
596  for (auto n: {valueset_t<I>::sname()...})
597  {
598  res += sep;
599  res += n;
600  sep = ", ";
601  }
602  res.push_back('>');
603  return res;
604  }
605 
606  template <std::size_t... I>
607  static constexpr bool
609  {
610  return all_<valueset_t<I>::is_commutative()...>();
611  }
612 
613  template <std::size_t... I>
614  static constexpr bool
616  {
617  return all_<valueset_t<I>::is_idempotent()...>();
618  }
619 
620  template <std::size_t... I>
621  static self_t make_(std::istream& i, seq<I...>)
622  {
623 #if VCSN_HAVE_CORRECT_LIST_INITIALIZER_ORDER
624  return self_t{(eat_separator_<I>(i),
625  valueset_t<I>::make(i))...};
626 #else
627  return make_gcc_tuple
628  ((eat_separator_<sizeof...(ValueSets)-1 -I>(i),
629  valueset_t<sizeof...(ValueSets)-1 -I>::make(i))...);
630 #endif
631  }
632 
633  template <std::size_t... I>
634  bool open_(bool o, seq<I...>) const
635  {
636  using swallow = int[];
637  (void) swallow { set<I>().open(o)... };
638  std::swap(o, open__);
639  return o;
640  }
641 
644  template <typename Value, std::size_t I>
645  static auto size_(const Value& v, int)
646  -> decltype(valueset_t<I>::size(std::get<I>(v)))
647  {
648  return valueset_t<I>::size(std::get<I>(v));
649  }
650 
653  template <typename Value, std::size_t I>
654  static constexpr auto size_(const Value&, ...)
655  -> size_t
656  {
657  return 0;
658  }
659 
660  template <typename Value, std::size_t... I>
661  static size_t size_(const Value& v, seq<I...>)
662  {
663  return std::max({size_<Value, I>(v, 0)...});
664  }
665 
666  template <typename... Args, std::size_t... I>
667  value_t value_(const std::tuple<Args...>& args, seq<I...>) const
668  {
669  return value_t{set<I>().value(std::get<I>(args))...};
670  }
671 
672  template <std::size_t... I>
673  genset_ptr
675  {
676  return genset_ptr{set<I>().genset()...};
677  }
678 
679  template <std::size_t I>
680  decltype(auto) generators_() const
681  {
684  ([](const auto& ls)
685  {
686  using label_t = typename valueset_t<I>::value_t;
687  static const auto one = std::array<label_t, 1>{{ls.one()}};
688  return boost::range::join(one, ls.generators());
689  },
690  [](const auto& ls)
691  {
692  return ls.generators();
693  })(set<I>());
694  }
695 
696  template <std::size_t... I>
697  decltype(auto)
698  generators_(seq<I...>) const
699  {
700  // Need value(), since we might have to convert from letter_t to
701  // value_t.
702  auto p = [this](const auto& g)
703  { return !this->is_one(this->value(g)); };
704  return filter(vcsn::cross(generators_<I>()...),
705  // Need std::ref so that we can copy-assignment
706  // (filtered) iterators, which is needed with lat<lat<>>.
707  std::ref(p));
708  }
709 
710  template <std::size_t... I>
711  static constexpr bool
713  {
714  return all_<valueset_t<I>::is_free()...>();
715  }
716 
717  template <typename... Args, std::size_t... I>
718  word_t
719  word_(const std::tuple<Args...>& l, seq<I...>) const
720  {
721  return word_t{set<I>().word(std::get<I>(l))...};
722  }
723 
724  template <std::size_t... I>
725  static bool
726  equal_(const value_t& l, const value_t& r, seq<I...>)
727  {
728  for (auto n: {valueset_t<I>::equal(std::get<I>(l),
729  std::get<I>(r))...})
730  if (!n)
731  return false;
732  return true;
733  }
734 
735  template <typename LhsValue, typename RhsValue, std::size_t... I>
736  static auto
737  less_(const LhsValue& l, const RhsValue& r, seq<I...>)
738  -> bool
739  {
740  for (auto n: {std::make_pair(valueset_t<I>::less(std::get<I>(l),
741  std::get<I>(r)),
742  valueset_t<I>::less(std::get<I>(r),
743  std::get<I>(l)))...})
744  if (n.first)
745  return true;
746  else if (n.second)
747  return false;
748  return false;
749  }
750 
751  template <std::size_t... I>
752  static std::size_t
754  {
755  std::size_t res = 0;
756  for (auto h: {valueset_t<I>::hash(std::get<I>(v))...})
757  hash_combine(res, h);
758  return res;
759  }
760 
761  template <std::size_t... I>
762  static value_t
764  {
765  return std::make_tuple(valueset_t<I>::special()...);
766  }
767 
768  template <std::size_t... I>
769  static bool
771  {
772  for (auto n: {valueset_t<I>::is_special(std::get<I>(l))...})
773  if (!n)
774  return false;
775  return true;
776  }
777 
778  template <std::size_t... I>
779  value_t
781  {
782  return value_t{set<I>().zero()...};
783  }
784 
785  template <std::size_t... I>
786  bool
787  is_zero_(const value_t& l, seq<I...>) const
788  {
789  for (auto n: {set<I>().is_zero(std::get<I>(l))...})
790  if (!n)
791  return false;
792  return true;
793  }
794 
795  template <std::size_t... I>
796  static constexpr bool
798  {
799  return all_<valueset_t<I>::has_lightening_weights()...>();
800  }
801 
802  template <std::size_t... I>
803  static constexpr bool
805  {
806  return all_<valueset_t<I>::has_one()...>();
807  }
808 
809  template <std::size_t... I>
810  static constexpr bool
812  {
813  return all_<valueset_t<I>::is_expressionset()...>();
814  }
815 
816  template <std::size_t... I>
817  static constexpr bool
819  {
820  return all_<valueset_t<I>::is_letterized()...>();
821  }
822 
823  template <std::size_t... I>
824  static bool
826  {
827  for (auto n: {valueset_t<I>::is_one(std::get<I>(l))...})
828  if (!n)
829  return false;
830  return true;
831  }
832 
833  template <std::size_t... I>
834  static bool
836  {
837  for (auto n: {valueset_t<I>::show_one()...})
838  if (n)
839  return true;
840  return false;
841  }
842 
844  template <typename Fun>
845  value_t
846  map_(const value_t& v, Fun&& fun) const
847  {
848  return map_impl_(v, std::forward<Fun>(fun), indices);
849  }
850 
851  template <typename Fun, std::size_t... I>
852  value_t
853  map_impl_(const value_t& v, Fun&& fun, seq<I...>) const
854  {
855  return value_t{fun(set<I>(), std::get<I>(v))...};
856  }
857 
859  template <typename Fun>
860  value_t
861  map_(const value_t& l, const value_t& r, Fun&& fun) const
862  {
863  return map_impl_(l, r, std::forward<Fun>(fun), indices);
864  }
865 
866  template <typename Fun, std::size_t... I>
867  value_t
868  map_impl_(const value_t& l, const value_t& r, Fun&& fun, seq<I...>) const
869  {
870  return value_t{fun(set<I>(), std::get<I>(l), std::get<I>(r))...};
871  }
872 
873  template <typename LhsValue, typename RhsValue, std::size_t... I>
874  auto
875  mul_(const LhsValue& l, const RhsValue& r, seq<I...>) const
876  -> word_t
877  {
878  return word_t{set<I>().mul(std::get<I>(l), std::get<I>(r))...};
879  }
880 
881  template <std::size_t... I>
882  typename valueset_t<0>::value_t
884  {
885  typename valueset_t<0>::value_t res = std::get<0>(vs);
886  for (auto v: {std::get<I>(vs)...})
887  res = set<0>().lgcd(res, v);
888  using swallow = int[];
889  (void) swallow { (set<0>().ldivide_here(res, std::get<I>(vs)), 0)... };
890  return res;
891  }
892 
893  template <typename Value, std::size_t... I>
894  Value
895  delimit_(const Value& l, seq<I...>) const
896  {
897  return Value{set<I>().delimit(std::get<I>(l))...};
898  }
899 
900  template <typename Value, std::size_t... I>
901  Value
902  undelimit_(const Value& l, seq<I...>) const
903  {
904  return Value{set<I>().undelimit(std::get<I>(l))...};
905  }
906 
907  template <typename... VS, std::size_t... I>
908  value_t
910  const typename tupleset<VS...>::value_t& v,
911  seq<I...>) const
912  {
913  return value_t{set<I>().conv(vs.template set<I>(), std::get<I>(v))...};
914  }
915 
918  value_t
919  conv_(std::istream& i, bool quoted, std::true_type) const
920  {
921  if (i.peek() == EOF)
922  return one();
923  else
924  // This is not the empty string, bounce to the regular case.
925  return conv_(i, quoted, std::false_type{});
926  }
927 
929  value_t
930  conv_(std::istream& i, bool quoted, std::false_type) const
931  {
932  bool par = i.peek() == '(';
933  if (par)
934  eat(i, '(');
935  value_t res = conv_(i, quoted, indices);
936  if (par)
937  eat(i, ')');
938  return res;
939  }
940 
941  template <std::size_t... I>
942  value_t
943  conv_(std::istream& i, bool quoted, seq<I...>) const
944  {
945 #if VCSN_HAVE_CORRECT_LIST_INITIALIZER_ORDER
946  return value_t{(eat_separator_<I>(i),
947  set<I>().conv(i, quoted))...};
948 #else
949  constexpr auto S = sizeof...(ValueSets)-1;
950  return
951  detail::make_gcc_tuple((eat_separator_<S - I>(i),
952  set<S - I>().conv(i, quoted))...);
953 #endif
954  }
955 
960  template <std::size_t I>
961  static void
962  eat_separator_(std::istream& i)
963  {
964  if (I)
965  eat(i, i.peek() == ',' ? ',' : '|');
966  while (isspace(i.peek()))
967  i.ignore();
968  }
969 
970 
971  template <std::size_t... I>
972  std::ostream&
973  print_(const value_t& l, std::ostream& o,
974  format fmt,
975  const char* pre,
976  const char* sep,
977  const char* post,
978  seq<I...>) const
979  {
980  if (!is_special(l))
981  {
982  using swallow = int[];
983  (void) swallow
984  {
985  (o << (I == 0 ? pre : sep),
986  set<I>().print(std::get<I>(l), o, fmt),
987  0)...
988  };
989  o << post;
990  }
991  return o;
992  }
993 
994  template <std::size_t... I>
995  std::ostream&
996  print_set_(std::ostream& o, format fmt,
997  seq<I...>) const
998  {
999  const char *sep = "";
1000  const char *close = "";
1001  switch (fmt.kind())
1002  {
1003  case format::latex:
1004  sep = " \\times ";
1005  break;
1006  case format::sname:
1007  o << "lat<";
1008  sep = ", ";
1009  close = ">";
1010  break;
1011  case format::text:
1012  sep = " x ";
1013  break;
1014  case format::utf8:
1015  sep = " × ";
1016  break;
1017  case format::raw:
1018  assert(0);
1019  break;
1020  }
1021  using swallow = int[];
1022  (void) swallow
1023  {
1024  (o << (I == 0 ? "" : sep),
1025  set<I>().print_set(o, fmt),
1026  0)...
1027  };
1028  o << close;
1029  return o;
1030  }
1031 
1032  template <typename Value, std::size_t... I>
1033  Value
1034  transpose_(const Value& l, seq<I...>) const
1035  {
1036  return Value{set<I>().transpose(std::get<I>(l))...};
1037  }
1038 
1040  template <std::size_t... I>
1041  self_t
1042  meet_(const self_t& rhs, seq<I...>) const
1043  {
1044  return self_t{meet(set<I>(), rhs.template set<I>())...};
1045  }
1046 
1048  friend
1049  self_t
1050  meet(const self_t& lhs, const self_t& rhs)
1051  {
1052  return lhs.meet_(rhs, indices);
1053  }
1054 
1056  friend
1057  self_t
1058  meet(const self_t& lhs, const b&)
1059  {
1060  return lhs;
1061  }
1062 
1064  friend
1065  self_t
1066  meet(const b&, const self_t& rhs)
1067  {
1068  return rhs;
1069  }
1070 
1074  mutable bool open__ = false;
1075 
1076  private:
1078  template <std::size_t... I>
1079  auto
1080  get_letter_(std::istream& i, bool quoted, seq<I...>) const
1081  -> letter_t
1082  {
1083 #if VCSN_HAVE_CORRECT_LIST_INITIALIZER_ORDER
1084  return letter_t{(eat_separator_<I>(i),
1085  set<I>().get_letter(i, quoted))...};
1086 #else
1087  constexpr auto S = sizeof...(ValueSets)-1;
1088  return
1089  detail::make_gcc_tuple((eat_separator_<S - I>(i),
1090  set<S - I>().get_letter(i, quoted))...);
1091 #endif
1092  }
1093 
1095  template <typename Value, std::size_t... I>
1096  static auto
1097  letters_of_(const Value& v, seq<I...>)
1098  -> decltype(zip(valueset_t<I>::letters_of(std::get<I>(v))...))
1099  {
1100  return zip(valueset_t<I>::letters_of(std::get<I>(v))...);
1101  }
1102 
1104  template <typename Value, typename... Defaults, std::size_t... I>
1105  auto
1106  letters_of_padded_(const Value& v,
1107  const std::tuple<Defaults...>& def, seq<I...>) const
1108  -> decltype(zip_with_padding(def,
1109  this->set<I>().letters_of_padded(std::get<I>(v),
1110  std::get<I>(def))...))
1111  {
1112  return zip_with_padding(def,
1113  set<I>().letters_of_padded(std::get<I>(v),
1114  std::get<I>(def))...);
1115  }
1116 
1117  public:
1118  template <std::size_t... I>
1119  auto
1120  get_letter(std::istream& i, bool quoted = true) const
1121  -> decltype(this->get_letter_(i, quoted, indices))
1122  {
1123  bool par = i.peek() == '(';
1124  if (par)
1125  eat(i, '(');
1126  auto res = get_letter_(i, quoted, indices);
1127  if (par)
1128  eat(i, ')');
1129  return res;
1130  }
1131 
1137  template <typename Value>
1138  static auto
1139  letters_of(const Value& v)
1140  -> decltype(letters_of_(v, indices))
1141  {
1142  return letters_of_(v, indices);
1143  }
1144 
1150  template <typename Value, typename... Defaults>
1151  auto
1152  letters_of_padded(const Value& v, const std::tuple<Defaults...>& def) const
1153  -> decltype(this->letters_of_padded_(v, def, indices))
1154  {
1155  return letters_of_padded_(v, def, indices);
1156  }
1157  };
1158 
1159  template <typename... ValueSets>
1160  tupleset<ValueSets...>
1161  make_tupleset(const ValueSets&... vss)
1162  {
1163  return {vss...};
1164  }
1165 
1166 
1167  /*----------------.
1168  | is_multitape. |
1169  `----------------*/
1170 
1172  template <typename ValueSet>
1174  : std::false_type
1175  {};
1176 
1177  template <typename... ValueSet>
1178  struct is_multitape<tupleset<ValueSet...>>
1179  : std::true_type
1180  {};
1181 
1182  template <typename LabelSet, typename WeightSet>
1183  struct is_multitape<context<LabelSet, WeightSet>>
1184  : is_multitape<LabelSet>
1185  {};
1186 
1187  template <typename Context>
1188  struct is_multitape<expressionset<Context>>
1189  : is_multitape<Context>
1190  {};
1191 
1192 
1193 
1194  template <typename T1, typename T2>
1196 
1197  // Sure, we'd like to use tuple<> instead of
1198  // weightset_mixin<tupleset_impl<>>, however then we hit a Clang
1199  // 3.5.0 bug.
1200  //
1201  // https://llvm.org/bugs/show_bug.cgi?id=19372
1202  template <typename... T1, typename... T2>
1205  {
1206  using type = weightset_mixin<tupleset_impl<T1..., T2...>>;
1207  };
1208 
1210  template <typename... LabelSets>
1211  struct letterized_traits<tupleset<LabelSets...>>
1212  {
1213  using indices_t = make_index_sequence<sizeof...(LabelSets)>;
1214 
1215  template <std::size_t... I>
1216  using seq = index_sequence<I...>;
1217 
1218  template <size_t I>
1219  using letterized_traits_t =
1221  template <std::size_t... I>
1222  static constexpr bool is_letterized_(seq<I...>)
1223  {
1225  }
1226  static constexpr bool is_letterized = is_letterized_(indices_t{});
1227 
1228  using labelset_t =
1230 
1231  static labelset_t labelset(const tupleset<LabelSets...>& ls)
1232  {
1233  return labelset_(ls, indices_t{});
1234  }
1235 
1236  template <std::size_t... I>
1237  static labelset_t labelset_(const tupleset<LabelSets...>& ls,
1238  seq<I...>)
1239  {
1240  return {make_letterized(std::get<I>(ls.sets()))...};
1241  }
1242  };
1243 
1245  template <typename... LabelSets>
1246  struct nullableset_traits<tupleset<LabelSets...>,
1247  std::enable_if_t<tupleset<LabelSets...>::has_one()>>
1248  {
1249  using labelset_t = tupleset<LabelSets...>;
1250  using type = labelset_t;
1251  static type value(const labelset_t& ls)
1252  {
1253  return ls;
1254  }
1255  };
1256 
1258  template <typename... LabelSets>
1259  struct nullableset_traits<tupleset<LabelSets...>,
1260  std::enable_if_t<!tupleset<LabelSets...>::has_one()>>
1261  {
1262  using labelset_t = tupleset<LabelSets...>;
1264 
1265  static type value(const labelset_t& ls)
1266  {
1267  return ls;
1268  }
1269  };
1270 
1272  template <typename LabelSet>
1273  struct proper_traits<tupleset<LabelSet>>
1274  {
1276  static type value(const tupleset<LabelSet>& ls)
1277  {
1278  return {proper_traits<LabelSet>::value(ls.template set<0>())};
1279  }
1280  };
1281 
1283  template <typename... LabelSets>
1284  struct law_traits<tupleset<LabelSets...>>
1285  {
1286  using labelset_t = tupleset<LabelSets...>;
1288 
1289  template <std::size_t... I>
1291  {
1292  return {make_wordset(ls.template set<I>())...};
1293  }
1294 
1295  static type value(const labelset_t& ls)
1296  {
1297  return value(ls, make_index_sequence<sizeof...(LabelSets)>{});
1298  }
1299  };
1300 
1302  template <typename... VS1, typename... VS2>
1303  struct join_impl<tupleset<VS1...>, tupleset<VS2...>>
1304  {
1305  static_assert(sizeof...(VS1) == sizeof...(VS2),
1306  "join: tuplesets must have the same sizes");
1307  using vs1_t = tupleset<VS1...>;
1308  using vs2_t = tupleset<VS2...>;
1311 
1312  template <std::size_t... I>
1313  static type join(const vs1_t& lhs, const vs2_t& rhs,
1315  {
1316  return {::vcsn::join(lhs.template set<I>(), rhs.template set<I>())...};
1317  }
1318 
1320  static type join(const vs1_t& lhs, const vs2_t& rhs)
1321  {
1322  return join(lhs, rhs,
1323  make_index_sequence<sizeof...(VS1)>{});
1324  }
1325  };
1326 
1328  template <typename... VS1, typename VS2>
1329  struct join_impl<tupleset<VS1...>, VS2>
1330  {
1331  // Cannot just leave "false" as condition: the assertion is then
1332  // always checked, even if the template is not instantiated.
1333  static_assert(is_multitape<VS2>{},
1334  "join: cannot mix tuplesets and non tuplesets");
1335  };
1336 
1337 
1338  /*------------------.
1339  | project_labelset. |
1340  `------------------*/
1341 
1344  template <size_t Tape, typename LabelSet>
1346 
1349  template <size_t Tape, typename LabelSet>
1351 
1353  template <size_t Tape, typename... LabelSets>
1354  struct project_labelset_impl<Tape, tupleset<LabelSets...>>
1355  {
1356  using valueset_t = tupleset<LabelSets...>;
1357  using type = typename valueset_t::template project_t<Tape>;
1358  };
1359 
1361  template <size_t Tape, typename Context>
1362  struct project_labelset_impl<Tape, expressionset<Context>>
1363  {
1365  using type = typename valueset_t::template project_t<Tape>;
1366  };
1367 
1368 
1369  /*------------------.
1370  | project_context. |
1371  `------------------*/
1372 
1374  template <size_t Tape, typename Context>
1375  using project_context
1378 
1379  }// detail::
1380 
1381 
1382  /*----------------.
1383  | random_label. |
1384  `----------------*/
1385 
1387  template <typename... LabelSet,
1388  typename RandomGenerator = std::default_random_engine>
1389  typename tupleset<LabelSet...>::value_t
1391  RandomGenerator& gen = RandomGenerator())
1392  {
1393  return random_label_(ls, gen, ls.indices);
1394  }
1395 
1396 
1398  template <typename... LabelSet,
1399  size_t... I,
1400  typename RandomGenerator = std::default_random_engine>
1401  typename tupleset<LabelSet...>::value_t
1403  RandomGenerator& gen,
1405  {
1406  // No need to check for the emptiness here: it will be checked in
1407  // each sub-labelset.
1408  return ls.tuple(random_label(ls.template set<I>(), gen)...);
1409  }
1410 
1411 
1412 }// vcsn::
From a labelset, its non-nullable labelset.
Definition: labelset.hh:183
std::tuple< typename ValueSets::value_t... > word_t
Same as value_t.
Definition: tupleset.hh:43
static constexpr bool is_letterized_(seq< I... >)
Definition: tupleset.hh:1222
static constexpr bool is_letterized()
Definition: tupleset.hh:316
Print as plain (ASCII) text, escaped.
Definition: format.hh:28
static auto letters_of(const Value &v) -> decltype(letters_of_(v, indices))
Iterate over the letters of v.
Definition: tupleset.hh:1139
static bool equal(const value_t &l, const value_t &r)
Whether l equals r.
Definition: tupleset.hh:243
Ignore its arguments.
Definition: raise.hh:18
value_t conv(const tupleset< VS... > &vs, const typename tupleset< VS... >::value_t &v) const
Convert a value from tupleset<...> to value_t.
Definition: tupleset.hh:535
static constexpr bool has_one()
Definition: tupleset.hh:304
Print as a parsable type string.
Definition: format.hh:26
static value_t conv(self_t, value_t v)
Definition: tupleset.hh:521
typename labelset_types< ValueSets... >::letters_t letters_t
A set of letters if meaningful, void otherwise.
Definition: tupleset.hh:93
Implementation of labels are nullables (letter or empty).
Definition: fwd.hh:14
static constexpr bool is_expressionset_(seq< I... >)
Definition: tupleset.hh:811
Provide a range that allows to iterate over the cross product of the provided ranges.
Definition: cross.hh:16
value_t zero() const
Definition: tupleset.hh:286
std::tuple< typename ValueSets::value_t... > value_t
A tuple of values.
Definition: tupleset.hh:88
value_t map_(const value_t &l, const value_t &r, Fun &&fun) const
Apply a binary function pointwise, and return the tuple of results.
Definition: tupleset.hh:861
static void eat_separator_(std::istream &i)
Read the separator from the input stream i if I is not 0.
Definition: tupleset.hh:962
static type join(const vs1_t &lhs, const vs2_t &rhs, index_sequence< I... >)
Definition: tupleset.hh:1313
void swap(config::config_value &first, config::config_value &second)
auto get_letter_(std::istream &i, bool quoted, seq< I... >) const -> letter_t
Must be declared before, as we use its result in decltype.
Definition: tupleset.hh:1080
genset_ptr genset() const
Definition: tupleset.hh:215
static auto compare(const LhsValue &l, const RhsValue &r) -> int
Three-way comparison between l and r.
Definition: tupleset.hh:251
static size_t size(const Value &v)
Get the max of the sizes of the tapes.
Definition: tupleset.hh:131
auto tuple(const Auts &... as)
Build the (accessible part of the) tuple.
static constexpr bool is_idempotent()
Definition: tupleset.hh:143
valueset_t< 0 >::value_t lnormalize_here_(value_t &vs, seq< I... >) const
Definition: tupleset.hh:883
value_t lgcd(const value_t &l, const value_t &r) const
Pointwise left GCD.
Definition: tupleset.hh:384
The smallest nullableset which includes LabelSet.
Definition: labelset.hh:139
Value delimit_(const Value &l, seq< I... >) const
Definition: tupleset.hh:895
Definition: a-star.hh:8
format_t kind() const
Definition: format.hh:98
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 constexpr bool is_expressionset()
Definition: tupleset.hh:310
static type value(const labelset_t &ls, index_sequence< I... >)
Definition: tupleset.hh:1290
void hash_combine(std::size_t &seed, const T &v)
Definition: functional.hh:63
valueset_t< I > project_t
The type of the I-th tape valueset.
Definition: tupleset.hh:174
static bool equal_(const value_t &l, const value_t &r, seq< I... >)
Definition: tupleset.hh:726
static constexpr auto size_(const Value &,...) -> size_t
The size of the Ith element, if its valueset does not feature a size() function.
Definition: tupleset.hh:654
zip_sequences< Sequences... > zip(Sequences &&... seqs)
Definition: zip.hh:439
letter_t value_type
To be iterable.
Definition: tupleset.hh:105
auto map_impl_(Fun f, const std::tuple< Ts... > &ts, index_sequence< I... >)
Definition: tuple.hh:185
const valuesets_t & sets() const
The componants valuesets, as a tuple.
Definition: tupleset.hh:160
static bool is_one(const value_t &l)
Definition: tupleset.hh:341
static constexpr std::size_t size()
Number of tapes.
Definition: tupleset.hh:124
static constexpr bool is_free_(seq< I... >)
Definition: tupleset.hh:712
static std::size_t hash_(const value_t &v, seq< I... >)
Definition: tupleset.hh:753
value_t zero_(seq< I... >) const
Definition: tupleset.hh:780
value_t conv_(std::istream &i, bool quoted, std::false_type) const
Read a tuple in the stream, possibly parenthesized.
Definition: tupleset.hh:930
typename project_labelset_impl< Tape, LabelSet >::type project_labelset
The type of the resulting apparent LabelSet when keeping only tape Tape.
Definition: tupleset.hh:1350
value_t tuple(Args &&... args) const
Construct a value.
Definition: tupleset.hh:209
zip_sequences_padded< zip_sequences< Sequences... > > zip_with_padding(const std::tuple< typename Sequences::value_type... > &pad, const Sequences &... seq)
Definition: zip.hh:453
static self_t make(std::istream &is)
Build from the description in is.
Definition: tupleset.hh:149
static auto one_(seq< I... >) -> decltype(value_t
Definition: tupleset.hh:323
tupleset< ValueSets... > make_tupleset(const ValueSets &... vss)
Definition: tupleset.hh:1161
static value_t special()
Definition: tupleset.hh:274
static type value(const labelset_t &ls)
Definition: tupleset.hh:1295
value_t map_(const value_t &v, Fun &&fun) const
Apply a unary function pointwise, and return the tuple of results.
Definition: tupleset.hh:846
auto letters_of_padded_(const Value &v, const std::tuple< Defaults... > &def, seq< I... >) const -> decltype(zip_with_padding(def, this->set< I >().letters_of_padded(std::get< I >(v), std::get< I >(def))...))
Must be declared before, as we use its result in decltype.
Definition: tupleset.hh:1106
The type of the resulting apparent LabelSet when keeping only tape Tape.
Definition: tupleset.hh:1345
self_t meet_(const self_t &rhs, seq< I... >) const
The intersection with another tupleset.
Definition: tupleset.hh:1042
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
Definition: symbol.hh:21
cross_sequences< Sequences... > cross(Sequences &&... seqs)
Definition: cross.hh:287
bool is_zero(const value_t &l) const
Definition: tupleset.hh:292
STL namespace.
std::ostream & print_set_(std::ostream &o, format fmt, seq< I... >) const
Definition: tupleset.hh:996
static constexpr star_status_t star_status()
Definition: tupleset.hh:501
context join(const context &c1, const context &c2)
Bridge.
std::tuple< ValueSets... > valuesets_t
Definition: tupleset.hh:74
typename std::tuple_element< I, T >::type tuple_element_t
C++14.
Definition: tuple.hh:14
auto letters_of_padded(const Value &v, const std::tuple< Defaults... > &def) const -> decltype(this->letters_of_padded_(v, def, indices))
Iterate over the letters of v.
Definition: tupleset.hh:1152
value_t value_(const std::tuple< Args... > &args, seq< I... >) const
Definition: tupleset.hh:667
static bool is_one_(const value_t &l, seq< I... >)
Definition: tupleset.hh:825
value_t conv_(const tupleset< VS... > &vs, const typename tupleset< VS... >::value_t &v, seq< I... >) const
Definition: tupleset.hh:909
genset_ptr genset_(seq< I... >) const
Definition: tupleset.hh:674
value_t star(const value_t &v) const
Pointwise star.
Definition: tupleset.hh:471
weightset_mixin< detail::r_impl > r
Definition: fwd.hh:54
star_status_t
Definition: star-status.hh:5
auto meet(const expressionset< Ctx1 > &a, const expressionset< Ctx2 > &b) -> expressionset< meet_t< Ctx1, Ctx2 >>
The meet of two expressionsets.
value_t map_impl_(const value_t &l, const value_t &r, Fun &&fun, seq< I... >) const
Definition: tupleset.hh:868
auto mul(const LhsValue &l, const RhsValue &r) const -> word_t
The product (possibly concatenation) of l and r.
Definition: tupleset.hh:376
Print as rich UTF-8 text, escaped.
Definition: format.hh:30
value_t conv_(std::istream &i, bool quoted, std::true_type) const
When the valuesets are labelsets and support one, accept the empty string to denote one...
Definition: tupleset.hh:919
auto get_letter(std::istream &i, bool quoted=true) const -> decltype(this->get_letter_(i, quoted, indices))
Definition: tupleset.hh:1120
auto generators() const
The generators. Meaningful for labelsets only.
Definition: tupleset.hh:222
tupleset< LabelSet... >::value_t random_label_(const tupleset< LabelSet... > &ls, RandomGenerator &gen, detail::index_sequence< I... >)
Implementation detail for random label from tupleset.
Definition: tupleset.hh:1402
static constexpr bool is_free()
Definition: tupleset.hh:227
static std::string sname_(seq< I... >)
Definition: tupleset.hh:592
tupleset_impl(ValueSets... ls)
Definition: tupleset.hh:113
auto word(const std::tuple< Args... > &v) const -> word_t
Convert to a word.
Definition: tupleset.hh:235
friend self_t meet(const b &, const self_t &rhs)
The meet with the B weightset.
Definition: tupleset.hh:1066
valueset_t< 0 >::value_t lnormalize_here(value_t &v) const
Eliminate the LGCD between all the tapes.
Definition: tupleset.hh:464
static auto less_(const LhsValue &l, const RhsValue &r, seq< I... >) -> bool
Definition: tupleset.hh:737
value_t value(const std::tuple< Args... > &args) const
Construct a value.
Definition: tupleset.hh:202
typename valueset_t::template project_t< Tape > type
Definition: tupleset.hh:1357
typename detail::weightset_t_of_impl< base_t< ValueSet > >::type weightset_t_of
Definition: traits.hh:67
Value undelimit(const Value &l) const
Remove first and last characters, that must be "special".
Definition: tupleset.hh:495
auto join(const ValueSet &vs) -> ValueSet
The join of a single valueset.
Definition: join.hh:44
static constexpr bool is_commutative_(seq< I... >)
Definition: tupleset.hh:608
A traits so that tupleset may define types that may exist.
Definition: tupleset.hh:36
filter_automaton< Aut, Trans > filter(const Aut &aut, boost::optional< dynamic_bitset > ss={}, boost::optional< dynamic_bitset > ts={})
Get an automaton who is a part state set ss of aut.
Definition: filter.hh:301
boost::optional< value_t > maybe_rdivide(const value_t &l, const value_t &r) const
Definition: tupleset.hh:405
Print for LaTeX.
Definition: format.hh:22
bool is_letter(const value_t &) const
Definition: tupleset.hh:353
const valueset_t< I > & project() const
The Ith component valueset.
Definition: tupleset.hh:180
auto conv(const ValueSet &vs, const std::string &str, Args &&... args) -> decltype(vs.conv(std::declval< std::istream &>(), std::forward< Args >(args)...))
Parse str via vs.conv.
Definition: stream.hh:29
std::enable_if_t<!is_letterized_t< labelset_t_of< Aut > >{}, bool > is_letterized(const Aut &aut)
Definition: letterize.hh:161
value_t conv(b, b::value_t v) const
Definition: tupleset.hh:527
static auto letters_of_(const Value &v, seq< I... >) -> decltype(zip(valueset_t< I >::letters_of(std::get< I >(v))...))
Must be declared before, as we use its result in decltype.
Definition: tupleset.hh:1097
static constexpr bool is_idempotent_(seq< I... >)
Definition: tupleset.hh:615
value_t conv(std::istream &i, bool quoted=true) const
Read one label from i, return the corresponding value.
Definition: tupleset.hh:552
auto make_gcc_tuple(Ts &&... ts) -> decltype(reverse_tuple(std::make_tuple(std::forward< Ts >(ts)...)))
Same as make_tuple, unless the evaluation of arguments if right-to-left, in which case reverse the re...
Definition: tuple.hh:342
static labelset_t labelset_(const tupleset< LabelSets... > &ls, seq< I... >)
Definition: tupleset.hh:1237
static auto less(const LhsValue &l, const RhsValue &r) -> bool
Whether l < r.
Definition: tupleset.hh:260
word_t word_(const std::tuple< Args... > &l, seq< I... >) const
Definition: tupleset.hh:719
void print_(std::ostream &o, const T &arg, long)
Serialize arg into o.
Definition: raise.hh:26
static bool is_special_(const value_t &l, seq< I... >)
Definition: tupleset.hh:770
value_t conv_(std::istream &i, bool quoted, seq< I... >) const
Definition: tupleset.hh:943
static value_t special_(seq< I... >)
Definition: tupleset.hh:763
An input/output format for valuesets.
Definition: format.hh:13
static bool is_special(const value_t &l)
Definition: tupleset.hh:280
value_t conv(const nullableset< tupleset< VS... >> &vs, const typename nullableset< tupleset< VS... >>::value_t &v) const
Convert a value from nullableset<tupleset<...>> to value_t.
Definition: tupleset.hh:544
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
static size_t hash(const value_t &v)
Definition: tupleset.hh:515
Aut transpose(const transpose_automaton< Aut > &aut)
The transpose of a transpose automaton is the original automaton.
Definition: transpose.hh:253
std::integral_constant< bool, B > bool_constant
Definition: type_traits.hh:12
Print as is. For instance, don&#39;t try to escape labels.
Definition: format.hh:24
value_t rdivide(const value_t &l, const value_t &r) const
Pointwise right division (l / r).
Definition: tupleset.hh:395
constant< type_t::one, Context > one
Definition: fwd.hh:117
A structure that implements the computation of join(V1, V2).
Definition: join.hh:18
typename labelset_types< ValueSets... >::letter_t letter_t
A tuple of base letters if meaningful, void otherwise.
Definition: tupleset.hh:91
value_t ldivide(const value_t &l, const value_t &r) const
Pointwise left division (l \ r).
Definition: tupleset.hh:428
friend self_t meet(const self_t &lhs, const self_t &rhs)
The meet with another tupleset.
Definition: tupleset.hh:1050
tuple_element_t< I, valuesets_t > valueset_t
The Ith valueset type.
Definition: tupleset.hh:82
bool is_zero_(const value_t &l, seq< I... >) const
Definition: tupleset.hh:787
ValueSet::value_t lgcd(const ValueSet &vs, const typename ValueSet::value_t &lhs, const typename ValueSet::value_t &rhs)
Left-division of values.
Definition: divide.hh:91
static type value(const tupleset< LabelSet > &ls)
Definition: tupleset.hh:1276
typename labelset_types< ValueSets... >::genset_ptr genset_ptr
A tuple of generators if meaningful, void otherwise.
Definition: tupleset.hh:96
auto project(const value_t &v) const
The I-th component of the value.
Definition: tupleset.hh:187
boost::optional< value_t > maybe_ldivide(const value_t &l, const value_t &r) const
Definition: tupleset.hh:438
The LAW from a LAL.
Definition: labelset.hh:250
auto mul_(const LhsValue &l, const RhsValue &r, seq< I... >) const -> word_t
Definition: tupleset.hh:875
static auto size_(const Value &v, int) -> decltype(valueset_t< I >::size(std::get< I >(v)))
The size of the Ith element, if its valueset features a size() function.
Definition: tupleset.hh:645
expressionset< Context >::value_t random_label(const expressionset< Context > &rs, RandomGenerator &gen=RandomGenerator())
Random label from expressionset: limited to a single label.
Value transpose(const Value &l) const
Transpose a word_t or a value_t.
Definition: tupleset.hh:509
static self_t make_(std::istream &i, seq< I... >)
Definition: tupleset.hh:621
static size_t size_(const Value &v, seq< I... >)
Definition: tupleset.hh:661
static constexpr bool has_lightening_weights_(seq< I... >)
Definition: tupleset.hh:797
valuesets_t sets_
The tupled valuesets.
Definition: tupleset.hh:1072
Whether a ValueSet, or a context, is multitape.
Definition: tupleset.hh:1173
tupleset_impl(valuesets_t vs)
Definition: tupleset.hh:109
std::ostream & print_(const value_t &l, std::ostream &o, format fmt, const char *pre, const char *sep, const char *post, seq< I... >) const
Definition: tupleset.hh:973
char eat(std::istream &is, char c)
Check lookahead character and advance.
Definition: stream.cc:130
void convs(std::istream &i, Fun &&fun) const
Fun: (label_t) -> void.
Definition: tupleset.hh:561
LabelSet::letters_t conv_label_class_(const LabelSet &ls, std::istream &i)
Read a set of letters (hence, guaranteed in order, and unique).
Definition: labelset.hh:442
typename valueset_t::template project_t< Tape > type
Definition: tupleset.hh:1365
value_t add(const value_t &l, const value_t &r) const
Pointwise addition.
Definition: tupleset.hh:361
static constexpr bool has_lightening_weights()
Definition: tupleset.hh:298
static symbol sname()
Definition: tupleset.hh:117
static type value(const LabelSet &ls)
Definition: labelset.hh:186
Functor to compare Values of ValueSets.
Definition: functional.hh:91
bool open(bool o) const
Whether unknown letters should be added, or rejected.
Definition: tupleset.hh:195
static constexpr bool is_commutative()
Definition: tupleset.hh:137
Request the set implementation (bool weights).
static auto one() -> decltype(one_(Indices
A tuple of ones.
Definition: tupleset.hh:335
A traits to compute the letterized context.
Definition: labelset.hh:80
static type join(const vs1_t &lhs, const vs2_t &rhs)
The resulting valueset.
Definition: tupleset.hh:1320
friend self_t meet(const self_t &lhs, const b &)
The meet with the B weightset.
Definition: tupleset.hh:1058
static constexpr bool is_labelset
Definition: tupleset.hh:44
static constexpr bool has_one_(seq< I... >)
Definition: tupleset.hh:804
A ValueSet which is a Cartesian product of ValueSets.
Definition: fwd.hh:23
static bool show_one_(seq< I... >)
Definition: tupleset.hh:835
std::ostream & print(const value_t &l, std::ostream &o=std::cout, format fmt={}) const
Definition: tupleset.hh:577
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
letterized_t< LabelSet > make_letterized(const LabelSet &ls)
Definition: labelset.hh:101
always valid.
Definition: star-status.hh:17
Value undelimit_(const Value &l, seq< I... >) const
Definition: tupleset.hh:902
Value delimit(const Value &l) const
Add the special character first and last.
Definition: tupleset.hh:487
value_t map_impl_(const value_t &v, Fun &&fun, seq< I... >) const
Definition: tupleset.hh:853
symbol sname()
Definition: name.hh:65
typename labelset_types< ValueSets... >::word_t word_t
A tuple of words if meaningful, void otherwise.
Definition: tupleset.hh:98
static labelset_t labelset(const tupleset< LabelSets... > &ls)
Definition: tupleset.hh:1231
static constexpr bool is_letterized_(seq< I... >)
Definition: tupleset.hh:818
law_t< LabelSet > make_wordset(const LabelSet &ls)
The wordset of a labelset.
Definition: labelset.hh:260
bool open_(bool o, seq< I... >) const
Definition: tupleset.hh:634
Value transpose_(const Value &l, seq< I... >) const
Definition: tupleset.hh:1034
std::ostream & print_set(std::ostream &o, format fmt={}) const
Definition: tupleset.hh:571