Vcsn  2.8
Be Rational
tupleset.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <iosfwd>
4 #include <istream>
5 #include <set>
6 #include <tuple>
7 
8 #include <boost/optional.hpp>
9 #include <boost/range/join.hpp>
10 
11 #include <vcsn/config.hh> // VCSN_HAVE_CORRECT_LIST_INITIALIZER_ORDER
12 #include <vcsn/ctx/traits.hh>
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_(std::move(ls)...)
115  {}
116 
118  {}
119 
120  static symbol sname()
121  {
122  static auto res = symbol{sname_(indices)};
123  return res;
124  }
125 
127  static constexpr std::size_t size()
128  {
129  return sizeof...(ValueSets);
130  }
131 
133  template <typename Value>
134  static size_t size(const Value& v)
135  {
136  return size_(v, indices);
137  }
138 
139  static constexpr bool
141  {
142  return is_commutative_(indices);
143  }
144 
145  static constexpr bool
147  {
148  return is_idempotent_(indices);
149  }
150 
152  static self_t make(std::istream& is)
153  {
154  // name: lat<law_char(abc), law_char(xyz)>
155  kind_t::make(is);
156  eat(is, '<');
157  auto res = make_(is, indices);
158  eat(is, '>');
159  return res;
160  }
161 
163  const valuesets_t& sets() const
164  {
165  return sets_;
166  }
167 
169  template <size_t I>
170  const valueset_t<I>& set() const
171  {
172  return std::get<I>(sets());
173  }
174 
176  template <size_t I>
178 
182  template <size_t I>
183  const valueset_t<I>& project() const
184  {
185  return set<I>();
186  }
187 
189  template <size_t I>
190  auto project(const value_t& v) const
191  {
192  return std::get<I>(v);
193  }
194 
198  bool open(bool o) const
199  {
200  return this->open_(o, indices);
201  }
202 
204  template <typename... Args>
205  value_t value(const std::tuple<Args...>& args) const
206  {
207  return this->value_(args, indices);
208  }
209 
211  template <typename... Args>
212  value_t tuple(Args&&... args) const
213  {
214  return value_t{args...};
215  }
216 
219  template <typename... LS1, typename... LS2>
220  auto compose(const tupleset<LS1...>& ls1,
221  const typename tupleset<LS1...>::value_t& l1,
222  const tupleset<LS2...>& ls2,
223  const typename tupleset<LS2...>::value_t& l2) const
224  -> std::enable_if_t<are_labelsets_composable<tupleset<LS1...>,
225  tupleset<LS2...>>{},
226  value_t>
227  {
228  // Tape of the lhs on which we compose.
229  constexpr auto out = tupleset<LS1...>::size() - 1;
230  // Tape of the rhs on which we compose.
231  constexpr auto in = 0;
234  return compose_(ls1, l1, ls2, l2,
235  indices1_t{}, indices2_t{});
236  }
237 
238  genset_ptr
239  genset() const
240  {
241  return this->genset_(indices);
242  }
243 
245  auto
247  {
248  return this->pregenerators_(indices);
249  }
250 
252  auto
253  generators() const
254  {
255  if (has_one())
256  return pregenerators().skip_first();
257  else
258  return pregenerators();
259  }
260 
261  static constexpr bool is_free()
262  {
263  return is_free_(indices);
264  }
265 
267  template <typename... Args>
268  auto
269  word(const std::tuple<Args...>& v) const
270  -> word_t
271  {
272  return this->word_(v, indices);
273  }
274 
276  template <typename Fun>
277  auto
278  map(Fun&& fun) const
279  {
280  return map_impl_(std::forward<Fun>(fun), indices);
281  }
282 
284  static bool
285  equal(const value_t& l, const value_t& r)
286  {
287  return equal_(l, r, indices);
288  }
289 
291  template <typename LhsValue, typename RhsValue>
292  static auto
293  compare(const LhsValue& l, const RhsValue& r)
294  -> int
295  {
296  return less(r, l) - less(l, r);
297  }
298 
300  template <typename LhsValue, typename RhsValue>
301  static auto
302  less(const LhsValue& l, const RhsValue& r)
303  -> bool
304  {
305  auto sl = size(l);
306  auto sr = size(r);
307  if (sl < sr)
308  return true;
309  else if (sr < sl)
310  return false;
311  else
312  return less_(l, r, indices);
313  }
314 
315  static value_t
317  {
318  return special_(indices);
319  }
320 
321  static bool
322  is_special(const value_t& l)
323  {
324  return is_special_(l, indices);
325  }
326 
327  bool
328  is_zero(const value_t& l) const
329  {
330  return is_zero_(l, indices);
331  }
332 
333  static constexpr bool
335  {
336  return has_lightening_weights_(indices);
337  }
338 
339  static constexpr bool
341  {
342  return has_one_(indices);
343  }
344 
345  static constexpr bool
347  {
348  return is_expressionset_(indices);
349  }
350 
351  static constexpr bool
353  {
354  return is_letterized_(indices);
355  }
356 
357  private:
358  template <std::size_t... I>
359  static auto one_(seq<I...>)
360  -> decltype(value_t{valueset_t<I>::one()...})
361  {
362  return value_t{valueset_t<I>::one()...};
363  }
364 
365  public:
370  template <typename Indices = indices_t>
371  static auto one() -> decltype(one_(Indices{}))
372  {
373  return one_(Indices{});
374  }
375 
376  static bool
377  is_one(const value_t& l)
378  {
379  return is_one_(l, indices);
380  }
381 
382  static bool
384  {
385  return show_one_(indices);
386  }
387 
388  bool
389  is_letter(const value_t&) const
390  {
391  // FIXME: why??? Is this for the printer of expressions?
392  return false;
393  }
394 
395  bool
396  is_valid(const value_t& l) const
397  {
398  return is_valid_(l, indices);
399  }
400 
402  value_t
403  add(const value_t& l, const value_t& r) const
404  {
405  return map_(l, r,
406  [](const auto& vs, const auto& l, const auto& r)
407  {
408  return vs.add(l, r);
409  });
410  }
411 
416  template <typename LhsValue, typename RhsValue>
417  auto
418  mul(const LhsValue& l, const RhsValue& r) const
419  -> word_t
420  {
421  return this->mul_(l, r, indices);
422  }
423 
425  value_t
426  lgcd(const value_t& l, const value_t& r) const
427  {
428  return map_(l, r,
429  [](const auto& vs, const auto& l, const auto& r)
430  {
431  return vs.lgcd(l, r);
432  });
433  }
434 
436  value_t
437  rdivide(const value_t& l, const value_t& r) const
438  {
439  return map_(l, r,
440  [](const auto& vs, const auto& l, const auto& r)
441  {
442  return vs.rdivide(l, r);
443  });
444  }
445 
446  boost::optional<value_t>
447  maybe_rdivide(const value_t& l, const value_t& r) const
448  {
449  bool valid = true;
450  auto res = map_(l, r,
451  [&valid](const auto& vs, const auto& l, const auto& r)
452  {
453  if (auto res = vs.maybe_rdivide(l, r))
454  return *res;
455  else
456  {
457  valid = false;
458  return l;
459  }
460  });
461 
462  if (valid)
463  return res;
464  else
465  return boost::none;
466  }
467 
469  value_t
470  ldivide(const value_t& l, const value_t& r) const
471  {
472  return map_(l, r,
473  [](const auto& vs, const auto& l, const auto& r)
474  {
475  return vs.ldivide(l, r);
476  });
477  }
478 
479  boost::optional<value_t>
480  maybe_ldivide(const value_t& l, const value_t& r) const
481  {
482  bool valid = true;
483  auto res = map_(l, r,
484  [&valid](const auto& vs, const auto& l, const auto& r)
485  {
486  if (auto res = vs.maybe_ldivide(l, r))
487  return *res;
488  else
489  {
490  valid = false;
491  return l;
492  }
493  });
494 
495  if (valid)
496  return res;
497  else
498  return boost::none;
499  }
500 
505  typename valueset_t<0>::value_t
507  {
508  return this->lnormalize_here_(v, indices);
509  }
510 
512  value_t
513  star(const value_t& v) const
514  {
515  return map_(v,
516  [](const auto& vs, const auto& v)
517  {
518  return vs.star(v);
519  });
520  }
521 
527  template <typename Value>
528  Value
529  delimit(const Value& l) const
530  {
531  return this->delimit_(l, indices);
532  }
533 
535  template <typename Value>
536  Value
537  undelimit(const Value& l) const
538  {
539  return this->undelimit_(l, indices);
540  }
541 
542  // FIXME: this needs to be computed.
543  static constexpr star_status_t star_status()
544  {
546  }
547 
549  template <typename Value>
550  Value
551  transpose(const Value& l) const
552  {
553  return this->transpose_(l, indices);
554  }
555 
556  static size_t
557  hash(const value_t& v)
558  {
559  return hash_(v, indices);
560  }
561 
562  static value_t
564  {
565  return v;
566  }
567 
568  value_t
569  conv(b, b::value_t v) const
570  {
571  return v ? one() : zero();
572  }
573 
575  template <typename... VS>
576  value_t
578  const typename tupleset<VS...>::value_t& v) const
579  {
580  return this->conv_(vs, v, indices);
581  }
582 
584  template <typename... VS>
585  value_t
587  const typename nullableset<tupleset<VS...>>::value_t& v) const
588  {
589  return conv(*vs.labelset(), vs.get_value(v));
590  }
591 
593  template <typename VS>
594  value_t
595  conv(const VS& vs, const typename VS::value_t& v) const
596  {
597  return this->partial_identity_(vs, v, indices);
598  }
599 
601  value_t
602  conv(std::istream& i, bool quoted = true) const
603  {
604  constexpr auto has_label_one
606  return conv_(i, quoted, bool_constant<has_label_one>{});
607  }
608 
610  template <typename Fun>
611  void convs(std::istream& i, Fun&& fun) const
612  {
613  eat(i, '[');
614  conv_label_class_(*this, i,
615  [this,fun](const letter_t& l)
616  {
617  fun(this->value(l));
618  });
619  eat(i, ']');
620  }
621 
622  std::ostream&
623  print_set(std::ostream& o, format fmt = {}) const
624  {
625  return this->print_set_(o, fmt, indices);
626  }
627 
628  std::ostream&
629  print(const value_t& l, std::ostream& o = std::cout,
630  format fmt = {}) const
631  {
632  return this->print_(l, o,
633  // 1, (2, 3) is different from 1, 2, 3:
634  // delimit components.
635  fmt.delimit(true),
636  fmt.delimit() ? "(" : "",
637  fmt.is_for_labels() ? "|" : ",",
638  fmt.delimit() ? ")" : "",
639  indices);
640  }
641 
642  private:
643  template <std::size_t... I>
644  static std::string sname_(seq<I...>)
645  {
646  std::string res = "lat<";
647  const char *sep = "";
648  for (auto n: {valueset_t<I>::sname()...})
649  {
650  res += sep;
651  res += n;
652  sep = ", ";
653  }
654  res.push_back('>');
655  return res;
656  }
657 
658  template <std::size_t... I>
659  static constexpr bool
661  {
662  return all_<valueset_t<I>::is_commutative()...>();
663  }
664 
665  template <std::size_t... I>
666  static constexpr bool
668  {
669  return all_<valueset_t<I>::is_idempotent()...>();
670  }
671 
672  template <std::size_t... I>
673  static self_t make_(std::istream& i, seq<I...>)
674  {
675 #if VCSN_HAVE_CORRECT_LIST_INITIALIZER_ORDER
676  return self_t{(eat_separator_<I>(i),
677  valueset_t<I>::make(i))...};
678 #else
679  return make_gcc_tuple
680  ((eat_separator_<sizeof...(ValueSets)-1 -I>(i),
681  valueset_t<sizeof...(ValueSets)-1 -I>::make(i))...);
682 #endif
683  }
684 
685  template <std::size_t... I>
686  bool open_(bool o, seq<I...>) const
687  {
688  using swallow = int[];
689  (void) swallow { set<I>().open(o)... };
690  std::swap(o, open__);
691  return o;
692  }
693 
696  template <typename Value, std::size_t I>
697  static auto size_(const Value& v, int)
698  -> decltype(valueset_t<I>::size(std::get<I>(v)))
699  {
700  return valueset_t<I>::size(std::get<I>(v));
701  }
702 
705  template <typename Value, std::size_t I>
706  static constexpr auto size_(const Value&, ...)
707  -> size_t
708  {
709  return 0;
710  }
711 
712  template <typename Value, std::size_t... I>
713  static size_t size_(const Value& v, seq<I...>)
714  {
715  return std::max({size_<Value, I>(v, 0)...});
716  }
717 
718  template <typename... Args, std::size_t... I>
719  value_t value_(const std::tuple<Args...>& args, seq<I...>) const
720  {
721  return value_t{set<I>().value(std::get<I>(args))...};
722  }
723 
724  template <typename... LS1, typename... LS2,
725  std::size_t... I1, std::size_t... I2>
727  const typename tupleset<LS1...>::value_t& l1,
728  const tupleset<LS2...>&,
729  const typename tupleset<LS2...>::value_t& l2,
730  seq<I1...>, seq<I2...>) const
731  {
732  return value_t{std::get<I1>(l1)..., std::get<I2>(l2)...};
733  }
734 
735  template <std::size_t... I>
736  genset_ptr
738  {
739  return genset_ptr{set<I>().genset()...};
740  }
741 
742  template <std::size_t... I>
743  auto
745  {
746  return vcsn::cross(set<I>().pregenerators()...);
747  }
748 
749  template <std::size_t... I>
750  static constexpr bool
752  {
753  return all_<valueset_t<I>::is_free()...>();
754  }
755 
756  template <typename... Args, std::size_t... I>
757  word_t
758  word_(const std::tuple<Args...>& l, seq<I...>) const
759  {
760  return word_t{set<I>().word(std::get<I>(l))...};
761  }
762 
763  template <std::size_t... I>
764  static bool
765  equal_(const value_t& l, const value_t& r, seq<I...>)
766  {
767  for (auto n: {valueset_t<I>::equal(std::get<I>(l),
768  std::get<I>(r))...})
769  if (!n)
770  return false;
771  return true;
772  }
773 
774  template <typename LhsValue, typename RhsValue, std::size_t... I>
775  static auto
776  less_(const LhsValue& l, const RhsValue& r, seq<I...>)
777  -> bool
778  {
779  for (auto n: {std::make_pair(valueset_t<I>::less(std::get<I>(l),
780  std::get<I>(r)),
781  valueset_t<I>::less(std::get<I>(r),
782  std::get<I>(l)))...})
783  if (n.first)
784  return true;
785  else if (n.second)
786  return false;
787  return false;
788  }
789 
790  template <std::size_t... I>
791  static std::size_t
793  {
794  std::size_t res = 0;
795  for (auto h: {valueset_t<I>::hash(std::get<I>(v))...})
796  hash_combine(res, h);
797  return res;
798  }
799 
800  template <std::size_t... I>
801  static value_t
803  {
804  return std::make_tuple(valueset_t<I>::special()...);
805  }
806 
807  template <std::size_t... I>
808  static bool
810  {
811  for (auto n: {valueset_t<I>::is_special(std::get<I>(l))...})
812  if (!n)
813  return false;
814  return true;
815  }
816 
817  template <std::size_t... I>
818  static auto zero_(seq<I...>)
819  -> decltype(value_t{valueset_t<I>::zero()...})
820  {
821  return value_t{valueset_t<I>::zero()...};
822  }
823 
824  public:
829  template <typename Indices = indices_t>
830  static auto zero() -> decltype(zero_(Indices{}))
831  {
832  return zero_(Indices{});
833  }
834 
835  private:
836  template <std::size_t... I>
837  bool
838  is_zero_(const value_t& l, seq<I...>) const
839  {
840  for (auto n: {set<I>().is_zero(std::get<I>(l))...})
841  if (!n)
842  return false;
843  return true;
844  }
845 
846  template <std::size_t... I>
847  static constexpr bool
849  {
850  return all_<valueset_t<I>::has_lightening_weights()...>();
851  }
852 
853  template <std::size_t... I>
854  static constexpr bool
856  {
857  return all_<valueset_t<I>::has_one()...>();
858  }
859 
860  template <std::size_t... I>
861  static constexpr bool
863  {
864  return all_<valueset_t<I>::is_expressionset()...>();
865  }
866 
867  template <std::size_t... I>
868  static constexpr bool
870  {
871  return all_<valueset_t<I>::is_letterized()...>();
872  }
873 
874  template <std::size_t... I>
875  static bool
877  {
878  for (auto n: {valueset_t<I>::is_one(std::get<I>(l))...})
879  if (!n)
880  return false;
881  return true;
882  }
883 
884  template <std::size_t... I>
885  static bool
887  {
888  for (auto n: {valueset_t<I>::show_one()...})
889  if (n)
890  return true;
891  return false;
892  }
893 
894  template <std::size_t... I>
895  bool
896  is_valid_(const value_t& l, seq<I...>) const
897  {
898  for (auto n: {set<I>().is_valid(std::get<I>(l))...})
899  if (!n)
900  return false;
901  return true;
902  }
903 
905  template <typename Fun, std::size_t... I>
906  auto
907  map_impl_(Fun&& fun, seq<I...>) const
908  {
909  return std::make_tuple(fun(set<I>())...);
910  }
911 
913  template <typename Fun>
914  value_t
915  map_(const value_t& v, Fun&& fun) const
916  {
917  return map_impl_(v, std::forward<Fun>(fun), indices);
918  }
919 
920  template <typename Fun, std::size_t... I>
921  value_t
922  map_impl_(const value_t& v, Fun&& fun, seq<I...>) const
923  {
924  return value_t{fun(set<I>(), std::get<I>(v))...};
925  }
926 
928  template <typename Fun>
929  value_t
930  map_(const value_t& l, const value_t& r, Fun&& fun) const
931  {
932  return map_impl_(l, r, std::forward<Fun>(fun), indices);
933  }
934 
935  template <typename Fun, std::size_t... I>
936  value_t
937  map_impl_(const value_t& l, const value_t& r, Fun&& fun, seq<I...>) const
938  {
939  return value_t{fun(set<I>(), std::get<I>(l), std::get<I>(r))...};
940  }
941 
942  template <typename LhsValue, typename RhsValue, std::size_t... I>
943  auto
944  mul_(const LhsValue& l, const RhsValue& r, seq<I...>) const
945  -> word_t
946  {
947  return word_t{set<I>().mul(std::get<I>(l), std::get<I>(r))...};
948  }
949 
950  template <std::size_t... I>
951  typename valueset_t<0>::value_t
953  {
954  typename valueset_t<0>::value_t res = std::get<0>(vs);
955  for (auto v: {std::get<I>(vs)...})
956  res = set<0>().lgcd(res, v);
957  using swallow = int[];
958  (void) swallow { (set<0>().ldivide_here(res, std::get<I>(vs)), 0)... };
959  return res;
960  }
961 
962  template <typename Value, std::size_t... I>
963  Value
964  delimit_(const Value& l, seq<I...>) const
965  {
966  return Value{set<I>().delimit(std::get<I>(l))...};
967  }
968 
969  template <typename Value, std::size_t... I>
970  Value
971  undelimit_(const Value& l, seq<I...>) const
972  {
973  return Value{set<I>().undelimit(std::get<I>(l))...};
974  }
975 
976  template <typename... VS, std::size_t... I>
977  value_t
979  const typename tupleset<VS...>::value_t& v,
980  seq<I...>) const
981  {
982  return value_t{set<I>().conv(vs.template set<I>(), std::get<I>(v))...};
983  }
984 
985  template <typename VS, std::size_t... I>
986  value_t
987  partial_identity_(const VS& vs, const typename VS::value_t& v,
988  seq<I...>) const
989  {
990  return value_t{set<I>().conv(vs, v)...};
991  }
992 
995  value_t
996  conv_(std::istream& i, bool quoted, std::true_type) const
997  {
998  if (i.peek() == EOF)
999  return one();
1000  else
1001  // This is not the empty string, bounce to the regular case.
1002  return conv_(i, quoted, std::false_type{});
1003  }
1004 
1006  value_t
1007  conv_(std::istream& i, bool quoted, std::false_type) const
1008  {
1009  bool par = i.peek() == '(';
1010  if (par)
1011  eat(i, '(');
1012  value_t res = conv_(i, quoted, indices);
1013  if (par)
1014  eat(i, ')');
1015  return res;
1016  }
1017 
1018  template <std::size_t... I>
1019  value_t
1020  conv_(std::istream& i, bool quoted, seq<I...>) const
1021  {
1022 #if VCSN_HAVE_CORRECT_LIST_INITIALIZER_ORDER
1023  return value_t{(eat_separator_<I>(i),
1024  set<I>().conv(i, quoted))...};
1025 #else
1026  constexpr auto S = sizeof...(ValueSets)-1;
1027  return
1028  detail::make_gcc_tuple((eat_separator_<S - I>(i),
1029  set<S - I>().conv(i, quoted))...);
1030 #endif
1031  }
1032 
1037  template <std::size_t I>
1038  static void
1039  eat_separator_(std::istream& i)
1040  {
1041  if (I)
1042  eat(i, i.peek() == ',' ? ',' : '|');
1043  while (isspace(i.peek()))
1044  i.ignore();
1045  }
1046 
1047 
1048  template <std::size_t... I>
1049  std::ostream&
1050  print_(const value_t& l, std::ostream& o,
1051  format fmt,
1052  const char* pre,
1053  const char* sep,
1054  const char* post,
1055  seq<I...>) const
1056  {
1057  if (!is_special(l))
1058  {
1059  using swallow = int[];
1060  (void) swallow
1061  {
1062  (o << (I == 0 ? pre : sep),
1063  set<I>().print(std::get<I>(l), o, fmt),
1064  0)...
1065  };
1066  o << post;
1067  }
1068  return o;
1069  }
1070 
1071  template <std::size_t... I>
1072  std::ostream&
1073  print_set_(std::ostream& o, format fmt,
1074  seq<I...>) const
1075  {
1076  const char *sep = "";
1077  const char *close = "";
1078  switch (fmt.kind())
1079  {
1080  case format::latex:
1081  sep = " \\times ";
1082  break;
1083  case format::sname:
1084  o << "lat<";
1085  sep = ", ";
1086  close = ">";
1087  break;
1088  case format::text:
1089  sep = " x ";
1090  break;
1091  case format::utf8:
1092  sep = " × ";
1093  break;
1094  case format::raw:
1095  assert(0);
1096  break;
1097  }
1098  using swallow = int[];
1099  (void) swallow
1100  {
1101  (o << (I == 0 ? "" : sep),
1102  set<I>().print_set(o, fmt),
1103  0)...
1104  };
1105  o << close;
1106  return o;
1107  }
1108 
1109  template <typename Value, std::size_t... I>
1110  Value
1111  transpose_(const Value& l, seq<I...>) const
1112  {
1113  return Value{set<I>().transpose(std::get<I>(l))...};
1114  }
1115 
1117  template <std::size_t... I>
1118  self_t
1119  meet_(const self_t& rhs, seq<I...>) const
1120  {
1121  return self_t{meet(set<I>(), rhs.template set<I>())...};
1122  }
1123 
1125  friend
1126  self_t
1127  meet(const self_t& lhs, const self_t& rhs)
1128  {
1129  return lhs.meet_(rhs, indices);
1130  }
1131 
1133  friend
1134  self_t
1135  meet(const self_t& lhs, const b&)
1136  {
1137  return lhs;
1138  }
1139 
1141  friend
1142  self_t
1143  meet(const b&, const self_t& rhs)
1144  {
1145  return rhs;
1146  }
1147 
1151  mutable bool open__ = false;
1152 
1153  private:
1155  template <std::size_t... I>
1156  auto
1157  get_letter_(std::istream& i, bool quoted, seq<I...>) const
1158  -> letter_t
1159  {
1160 #if VCSN_HAVE_CORRECT_LIST_INITIALIZER_ORDER
1161  return letter_t{(eat_separator_<I>(i),
1162  set<I>().get_letter(i, quoted))...};
1163 #else
1164  constexpr auto S = sizeof...(ValueSets)-1;
1165  return
1166  detail::make_gcc_tuple((eat_separator_<S - I>(i),
1167  set<S - I>().get_letter(i, quoted))...);
1168 #endif
1169  }
1170 
1172  template <typename Value, std::size_t... I>
1173  static auto
1174  letters_of_(const Value& v, seq<I...>)
1175  -> decltype(zip(valueset_t<I>::letters_of(std::get<I>(v))...))
1176  {
1177  return zip(valueset_t<I>::letters_of(std::get<I>(v))...);
1178  }
1179 
1181  template <typename Value, typename... Defaults, std::size_t... I>
1182  auto
1183  letters_of_padded_(const Value& v,
1184  const std::tuple<Defaults...>& def, seq<I...>) const
1185  -> decltype(zip_with_padding(def,
1186  this->set<I>().letters_of_padded(std::get<I>(v),
1187  std::get<I>(def))...))
1188  {
1189  return zip_with_padding(def,
1190  set<I>().letters_of_padded(std::get<I>(v),
1191  std::get<I>(def))...);
1192  }
1193 
1194  public:
1195  template <std::size_t... I>
1196  auto
1197  get_letter(std::istream& i, bool quoted = true) const
1198  -> decltype(this->get_letter_(i, quoted, indices))
1199  {
1200  bool par = i.peek() == '(';
1201  if (par)
1202  eat(i, '(');
1203  auto res = get_letter_(i, quoted, indices);
1204  if (par)
1205  eat(i, ')');
1206  return res;
1207  }
1208 
1214  template <typename Value>
1215  static auto
1216  letters_of(const Value& v)
1217  -> decltype(letters_of_(v, indices))
1218  {
1219  return letters_of_(v, indices);
1220  }
1221 
1227  template <typename Value, typename... Defaults>
1228  auto
1229  letters_of_padded(const Value& v, const std::tuple<Defaults...>& def) const
1230  -> decltype(this->letters_of_padded_(v, def, indices))
1231  {
1232  return letters_of_padded_(v, def, indices);
1233  }
1234  };
1235 
1236  template <typename... ValueSets>
1237  tupleset<ValueSets...>
1238  make_tupleset(const ValueSets&... vss)
1239  {
1240  return {vss...};
1241  }
1242 
1243 
1244  /*----------------.
1245  | is_multitape. |
1246  `----------------*/
1247 
1248  template <typename T1, typename T2>
1250 
1251  // Sure, we'd like to use tuple<> instead of
1252  // weightset_mixin<tupleset_impl<>>, however then we hit a Clang
1253  // 3.5.0 bug.
1254  //
1255  // https://llvm.org/bugs/show_bug.cgi?id=19372
1256  template <typename... T1, typename... T2>
1259  {
1260  using type = weightset_mixin<tupleset_impl<T1..., T2...>>;
1261  };
1262 
1264  template <typename... LabelSets>
1265  struct letterized_traits<tupleset<LabelSets...>>
1266  {
1267  using indices_t = make_index_sequence<sizeof...(LabelSets)>;
1268 
1269  template <std::size_t... I>
1270  using seq = index_sequence<I...>;
1271 
1272  template <size_t I>
1273  using letterized_traits_t =
1275  template <std::size_t... I>
1276  static constexpr bool is_letterized_(seq<I...>)
1277  {
1279  }
1280  static constexpr bool is_letterized = is_letterized_(indices_t{});
1281 
1282  using labelset_t =
1284 
1285  static labelset_t labelset(const tupleset<LabelSets...>& ls)
1286  {
1287  return labelset_(ls, indices_t{});
1288  }
1289 
1290  template <std::size_t... I>
1291  static labelset_t labelset_(const tupleset<LabelSets...>& ls,
1292  seq<I...>)
1293  {
1294  return {make_letterized(std::get<I>(ls.sets()))...};
1295  }
1296  };
1297 
1299  template <typename... LabelSets>
1300  struct nullableset_traits<tupleset<LabelSets...>,
1301  std::enable_if_t<tupleset<LabelSets...>::has_one()>>
1302  {
1303  using labelset_t = tupleset<LabelSets...>;
1304  using type = labelset_t;
1305  static type value(const labelset_t& ls)
1306  {
1307  return ls;
1308  }
1309  };
1310 
1312  template <typename... LabelSets>
1313  struct nullableset_traits<tupleset<LabelSets...>,
1314  std::enable_if_t<!tupleset<LabelSets...>::has_one()>>
1315  {
1316  using labelset_t = tupleset<LabelSets...>;
1318 
1319  static type value(const labelset_t& ls)
1320  {
1321  return ls;
1322  }
1323  };
1324 
1326  template <typename LabelSet>
1327  struct proper_traits<tupleset<LabelSet>>
1328  {
1330  static type value(const tupleset<LabelSet>& ls)
1331  {
1332  return {proper_traits<LabelSet>::value(ls.template set<0>())};
1333  }
1334  };
1335 
1337  template <typename... LabelSets>
1338  struct law_traits<tupleset<LabelSets...>>
1339  {
1340  using labelset_t = tupleset<LabelSets...>;
1342 
1343  template <std::size_t... I>
1345  {
1346  return {make_wordset(ls.template set<I>())...};
1347  }
1348 
1349  static type value(const labelset_t& ls)
1350  {
1351  return value(ls, make_index_sequence<sizeof...(LabelSets)>{});
1352  }
1353  };
1354 
1356  template <typename... VS1, typename... VS2>
1357  struct join_impl<tupleset<VS1...>, tupleset<VS2...>>
1358  {
1359  static_assert(sizeof...(VS1) == sizeof...(VS2),
1360  "join: tuplesets must have the same sizes");
1361  using vs1_t = tupleset<VS1...>;
1362  using vs2_t = tupleset<VS2...>;
1365 
1366  template <std::size_t... I>
1367  static type join(const vs1_t& lhs, const vs2_t& rhs,
1369  {
1370  return {::vcsn::join(lhs.template set<I>(), rhs.template set<I>())...};
1371  }
1372 
1374  static type join(const vs1_t& lhs, const vs2_t& rhs)
1375  {
1376  return join(lhs, rhs,
1377  make_index_sequence<sizeof...(VS1)>{});
1378  }
1379  };
1380 
1382  template <typename... VS1, typename VS2>
1383  struct join_impl<tupleset<VS1...>, VS2>
1384  {
1385  using vs1_t = tupleset<VS1...>;
1386  using vs2_t = VS2;
1389 
1390  template <std::size_t... I>
1391  static type join(const vs1_t& lhs, const vs2_t& rhs,
1393  {
1394  return {::vcsn::join(lhs.template set<I>(), rhs)...};
1395  }
1396 
1398  static type join(const vs1_t& lhs, const vs2_t& rhs)
1399  {
1400  return join(lhs, rhs,
1401  make_index_sequence<sizeof...(VS1)>{});
1402  }
1403  };
1404 
1405 
1406  /*------------------.
1407  | project_labelset. |
1408  `------------------*/
1409 
1412  template <size_t Tape, typename LabelSet>
1414 
1417  template <size_t Tape, typename LabelSet>
1419 
1421  template <size_t Tape, typename... LabelSets>
1422  struct project_labelset_impl<Tape, tupleset<LabelSets...>>
1423  {
1424  using valueset_t = tupleset<LabelSets...>;
1425  using type = typename valueset_t::template project_t<Tape>;
1426  };
1427 
1429  template <size_t Tape, typename Context>
1430  struct project_labelset_impl<Tape, expressionset<Context>>
1431  {
1433  using type = typename valueset_t::template project_t<Tape>;
1434  };
1435 
1436 
1437  /*------------------.
1438  | project_context. |
1439  `------------------*/
1440 
1442  template <size_t Tape, typename Context>
1443  using project_context
1446 
1447  }// detail::
1448 
1449  template <typename... ValueSet>
1450  struct is_multitape<tupleset<ValueSet...>>
1451  : std::true_type
1452  {};
1453 
1454  template <typename... ValueSets>
1455  struct number_of_tapes<tupleset<ValueSets...>>
1456  {
1457  constexpr static auto value = sizeof...(ValueSets);
1458  };
1459 
1460 
1461  /*----------------.
1462  | random_label. |
1463  `----------------*/
1464 
1466  template <typename... LabelSet,
1467  typename RandomGenerator = std::default_random_engine>
1468  typename tupleset<LabelSet...>::value_t
1470  RandomGenerator& gen = RandomGenerator())
1471  {
1472  return random_label_(ls, gen, ls.indices);
1473  }
1474 
1475 
1477  template <typename... LabelSet,
1478  size_t... I,
1479  typename RandomGenerator = std::default_random_engine>
1480  typename tupleset<LabelSet...>::value_t
1482  RandomGenerator& gen,
1484  {
1485  // No need to check for the emptiness here: it will be checked in
1486  // each sub-labelset.
1487  return ls.tuple(random_label(ls.template set<I>(), gen)...);
1488  }
1489 }// vcsn::
static bool equal_(const value_t &l, const value_t &r, seq< I... >)
Definition: tupleset.hh:765
bool is_letter(const value_t &) const
Definition: tupleset.hh:389
Aut transpose(const transpose_automaton< Aut > &aut)
The transpose of a transpose automaton is the original automaton.
Definition: transpose.hh:253
Print as a parsable type string.
Definition: format.hh:26
static constexpr bool has_one_(seq< I... >)
Definition: tupleset.hh:855
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:706
tupleset< ValueSets... > make_tupleset(const ValueSets &... vss)
Definition: tupleset.hh:1238
static std::string sname_(seq< I... >)
Definition: tupleset.hh:644
std::ostream & print_set(std::ostream &o, format fmt={}) const
Definition: tupleset.hh:623
weightset_mixin< detail::r_impl > r
Definition: fwd.hh:54
genset_ptr genset() const
Definition: tupleset.hh:239
const valuesets_t & sets() const
The componants valuesets, as a tuple.
Definition: tupleset.hh:163
auto map_impl_(Fun f, const std::tuple< Ts... > &ts, index_sequence< I... >)
Definition: tuple.hh:231
auto meet(const expressionset< Ctx1 > &a, const expressionset< Ctx2 > &b) -> expressionset< meet_t< Ctx1, Ctx2 >>
The meet of two expressionsets.
typename detail::weightset_t_of_impl< base_t< ValueSet > >::type weightset_t_of
Definition: traits.hh:67
auto map(Fun &&fun) const
Run a function per set, and return the tuple of results.
Definition: tupleset.hh:278
auto compose(const tupleset< LS1... > &ls1, const typename tupleset< LS1... >::value_t &l1, const tupleset< LS2... > &ls2, const typename tupleset< LS2... >::value_t &l2) const -> std::enable_if_t< are_labelsets_composable< tupleset< LS1... >, tupleset< LS2... >>
Compose, aka join in the world of databases.
Definition: tupleset.hh:220
friend self_t meet(const self_t &lhs, const b &)
The meet with the B weightset.
Definition: tupleset.hh:1135
value_t value_(const std::tuple< Args... > &args, seq< I... >) const
Definition: tupleset.hh:719
static type join(const vs1_t &lhs, const vs2_t &rhs, index_sequence< I... >)
Definition: tupleset.hh:1367
tupleset_impl(ValueSets... ls)
Definition: tupleset.hh:113
bool is_valid(const Aut &aut)
Definition: is-valid.hh:139
Value transpose(const Value &l) const
Transpose a word_t or a value_t.
Definition: tupleset.hh:551
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:1481
static constexpr bool is_commutative()
Definition: tupleset.hh:140
boost::optional< value_t > maybe_rdivide(const value_t &l, const value_t &r) const
Definition: tupleset.hh:447
value_t map_(const value_t &v, Fun &&fun) const
Apply a unary function pointwise, and return the tuple of results.
Definition: tupleset.hh:915
static std::size_t hash_(const value_t &v, seq< I... >)
Definition: tupleset.hh:792
typename valueset_t::template project_t< Tape > type
Definition: tupleset.hh:1425
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
static bool equal(const value_t &l, const value_t &r)
Whether l equals r.
Definition: tupleset.hh:285
A traits so that tupleset may define types that may exist.
Definition: tupleset.hh:36
auto mul_(const LhsValue &l, const RhsValue &r, seq< I... >) const -> word_t
Definition: tupleset.hh:944
valuesets_t sets_
The tupled valuesets.
Definition: tupleset.hh:1149
auto project(const value_t &v) const
The I-th component of the value.
Definition: tupleset.hh:190
auto map_impl_(Fun &&fun, seq< I... >) const
Run a nullary function pointwise, and return the tuple of results.
Definition: tupleset.hh:907
static symbol sname()
Definition: tupleset.hh:120
typename labelset_types< ValueSets... >::word_t word_t
A tuple of words if meaningful, void otherwise.
Definition: tupleset.hh:98
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:586
format_t kind() const
Definition: format.hh:98
static constexpr bool is_free()
Definition: tupleset.hh:261
value_t conv_(std::istream &i, bool quoted, seq< I... >) const
Definition: tupleset.hh:1020
static auto letters_of(const Value &v) -> decltype(letters_of_(v, indices))
Iterate over the letters of v.
Definition: tupleset.hh:1216
char eat(std::istream &is, char c)
Check lookahead character and advance.
Definition: stream.cc:147
tupleset_impl(valuesets_t vs)
Definition: tupleset.hh:109
const valueset_t< I > & project() const
The Ith component valueset.
Definition: tupleset.hh:183
The LAW from a LAL.
Definition: labelset.hh:249
static constexpr bool is_labelset
Definition: tupleset.hh:44
A traits to compute the letterized context.
Definition: labelset.hh:79
Request the set implementation (bool weights).
typename valueset_t::template project_t< Tape > type
Definition: tupleset.hh:1433
letterized_t< LabelSet > make_letterized(const LabelSet &ls)
Definition: labelset.hh:100
static value_t conv(self_t, value_t v)
Definition: tupleset.hh:563
value_t partial_identity_(const VS &vs, const typename VS::value_t &v, seq< I... >) const
Definition: tupleset.hh:987
bool is_special(const Aut &aut, transition_t_of< Aut > t)
Whether this transition is from pre or to post.
Definition: automaton.hh:229
static constexpr bool is_letterized()
Definition: tupleset.hh:352
context join(const context &c1, const context &c2)
Bridge.
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 constexpr bool has_lightening_weights()
Definition: tupleset.hh:334
static self_t make(std::istream &is)
Build from the description in is.
Definition: tupleset.hh:152
always valid.
Definition: star-status.hh:17
constant< type_t::one, Context > one
Definition: fwd.hh:121
static bool is_special_(const value_t &l, seq< I... >)
Definition: tupleset.hh:809
auto mul(const LhsValue &l, const RhsValue &r) const -> word_t
The product (possibly concatenation) of l and r.
Definition: tupleset.hh:418
static type value(const labelset_t &ls)
Definition: tupleset.hh:1349
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
Definition: symbol.hh:21
value_t map_impl_(const value_t &l, const value_t &r, Fun &&fun, seq< I... >) const
Definition: tupleset.hh:937
static type join(const vs1_t &lhs, const vs2_t &rhs)
The resulting valueset.
Definition: tupleset.hh:1374
auto word(const std::tuple< Args... > &v) const -> word_t
Convert to a word.
Definition: tupleset.hh:269
static type value(const LabelSet &ls)
Definition: labelset.hh:185
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
static bool show_one_(seq< I... >)
Definition: tupleset.hh:886
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:1050
auto tuple(const Auts &... as)
Build the (accessible part of the) tuple.
static size_t size(const Value &v)
Get the max of the sizes of the tapes.
Definition: tupleset.hh:134
static bool is_one_(const value_t &l, seq< I... >)
Definition: tupleset.hh:876
value_t add(const value_t &l, const value_t &r) const
Pointwise addition.
Definition: tupleset.hh:403
A ValueSet which is a Cartesian product of ValueSets.
Definition: fwd.hh:23
static auto zero_(seq< I... >) -> decltype(value_t
Definition: tupleset.hh:818
static type value(const tupleset< LabelSet > &ls)
Definition: tupleset.hh:1330
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:1183
constant< type_t::zero, Context > zero
Definition: fwd.hh:118
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:697
Print as rich UTF-8 text, escaped.
Definition: format.hh:30
An input/output format for valuesets.
Definition: format.hh:13
std::tuple< typename ValueSets::value_t... > word_t
Same as value_t.
Definition: tupleset.hh:43
typename std::tuple_element< I, T >::type tuple_element_t
C++14.
Definition: tuple.hh:14
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
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:577
std::ostream & print_set_(std::ostream &o, format fmt, seq< I... >) const
Definition: tupleset.hh:1073
tuple_element_t< I, valuesets_t > valueset_t
The Ith valueset type.
Definition: tupleset.hh:82
bool open(bool o) const
Whether unknown letters should be added, or rejected.
Definition: tupleset.hh:198
value_t star(const value_t &v) const
Pointwise star.
Definition: tupleset.hh:513
static constexpr bool has_one()
Definition: tupleset.hh:340
static type join(const vs1_t &lhs, const vs2_t &rhs, index_sequence< I... >)
Definition: tupleset.hh:1391
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:444
friend self_t meet(const self_t &lhs, const self_t &rhs)
The meet with another tupleset.
Definition: tupleset.hh:1127
auto generators() const
The generators. Meaningful for labelsets only.
Definition: tupleset.hh:253
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:388
static constexpr bool is_letterized_(seq< I... >)
Definition: tupleset.hh:1276
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 special()
Definition: tupleset.hh:316
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 value_t special_(seq< I... >)
Definition: tupleset.hh:802
value_t rdivide(const value_t &l, const value_t &r) const
Pointwise right division (l / r).
Definition: tupleset.hh:437
std::tuple< typename ValueSets::value_t... > value_t
A tuple of values.
Definition: tupleset.hh:88
From a labelset, its non-nullable labelset.
Definition: labelset.hh:182
static bool is_special(const value_t &l)
Definition: tupleset.hh:322
A structure that implements the computation of join(V1, V2).
Definition: join.hh:18
Ignore its arguments.
Definition: raise.hh:18
punched_sequence< tupleset< LS2... >::size(), in > indices2_t
Definition: tupleset.hh:233
typename labelset_types< ValueSets... >::letter_t letter_t
A tuple of base letters if meaningful, void otherwise.
Definition: tupleset.hh:91
Build the static sequence of size_t [0, N[.
Definition: tuple.hh:56
static constexpr bool is_idempotent()
Definition: tupleset.hh:146
auto get_letter(std::istream &i, bool quoted=true) const -> decltype(this->get_letter_(i, quoted, indices))
Definition: tupleset.hh:1197
Provide a range that allows to iterate over the cross product of the provided ranges.
Definition: cross.hh:16
Implementation of labels are nullables (letter or empty).
Definition: fwd.hh:14
static auto less(const LhsValue &l, const RhsValue &r) -> bool
Whether l < r.
Definition: tupleset.hh:302
typename labelset_types< ValueSets... >::genset_ptr genset_ptr
A tuple of generators if meaningful, void otherwise.
Definition: tupleset.hh:96
Definition: a-star.hh:8
auto pregenerators() const
The pregenerators. Meaningful for labelsets only.
Definition: tupleset.hh:246
cross_sequences< Sequences... > cross(Sequences &&... seqs)
Definition: cross.hh:303
auto in(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions arriving to state s.
Definition: automaton.hh:135
static type value(const labelset_t &ls, index_sequence< I... >)
Definition: tupleset.hh:1344
punched_sequence< tupleset< LS1... >::size(), out > indices1_t
Definition: tupleset.hh:232
valueset_t< I > project_t
The type of the I-th tape valueset.
Definition: tupleset.hh:177
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:1157
value_t lgcd(const value_t &l, const value_t &r) const
Pointwise left GCD.
Definition: tupleset.hh:426
static constexpr bool is_commutative_(seq< I... >)
Definition: tupleset.hh:660
static constexpr bool is_expressionset()
Definition: tupleset.hh:346
genset_ptr genset_(seq< I... >) const
Definition: tupleset.hh:737
static labelset_t labelset(const tupleset< LabelSets... > &ls)
Definition: tupleset.hh:1285
star_status_t
Definition: star-status.hh:5
static constexpr bool has_lightening_weights_(seq< I... >)
Definition: tupleset.hh:848
bool is_zero(const value_t &l) const
Definition: tupleset.hh:328
static bool is_one(const value_t &l)
Definition: tupleset.hh:377
static labelset_t labelset_(const tupleset< LabelSets... > &ls, seq< I... >)
Definition: tupleset.hh:1291
static constexpr std::size_t size()
Number of tapes.
Definition: tupleset.hh:127
letter_t value_type
To be iterable.
Definition: tupleset.hh:105
The smallest nullableset which includes LabelSet.
Definition: labelset.hh:138
word_t word_(const std::tuple< Args... > &l, seq< I... >) const
Definition: tupleset.hh:758
static void eat_separator_(std::istream &i)
Read the separator from the input stream i if I is not 0.
Definition: tupleset.hh:1039
bool is_valid_(const value_t &l, seq< I... >) const
Definition: tupleset.hh:896
Print as plain (ASCII) text, escaped.
Definition: format.hh:28
static constexpr bool is_letterized_(seq< I... >)
Definition: tupleset.hh:869
static auto less_(const LhsValue &l, const RhsValue &r, seq< I... >) -> bool
Definition: tupleset.hh:776
friend self_t meet(const b &, const self_t &rhs)
The meet with the B weightset.
Definition: tupleset.hh:1143
bool is_zero_(const value_t &l, seq< I... >) const
Definition: tupleset.hh:838
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:1174
A static list of size_t.
Definition: tuple.hh:32
static auto compare(const LhsValue &l, const RhsValue &r) -> int
Three-way comparison between l and r.
Definition: tupleset.hh:293
static auto one() -> decltype(one_(Indices
A tuple of ones.
Definition: tupleset.hh:371
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:930
auto pregenerators_(seq< I... >) const
Definition: tupleset.hh:744
The type of the resulting apparent LabelSet when keeping only tape Tape.
Definition: tupleset.hh:1413
void swap(config::value &first, config::value &second)
static constexpr star_status_t star_status()
Definition: tupleset.hh:543
Value undelimit(const Value &l) const
Remove first and last characters, that must be "special".
Definition: tupleset.hh:537
typename project_labelset_impl< Tape, LabelSet >::type project_labelset
The type of the resulting apparent LabelSet when keeping only tape Tape.
Definition: tupleset.hh:1418
self_t meet_(const self_t &rhs, seq< I... >) const
The intersection with another tupleset.
Definition: tupleset.hh:1119
bool open_(bool o, seq< I... >) const
Definition: tupleset.hh:686
value_t conv_(const tupleset< VS... > &vs, const typename tupleset< VS... >::value_t &v, seq< I... >) const
Definition: tupleset.hh:978
Value undelimit_(const Value &l, seq< I... >) const
Definition: tupleset.hh:971
symbol sname()
Definition: name.hh:65
Print as is. For instance, don&#39;t try to escape labels.
Definition: format.hh:24
static self_t make_(std::istream &i, seq< I... >)
Definition: tupleset.hh:673
typename labelset_types< ValueSets... >::letters_t letters_t
A set of letters if meaningful, void otherwise.
Definition: tupleset.hh:93
Print for LaTeX.
Definition: format.hh:22
Value delimit(const Value &l) const
Add the special character first and last.
Definition: tupleset.hh:529
value_t compose_(const tupleset< LS1... > &, const typename tupleset< LS1... >::value_t &l1, const tupleset< LS2... > &, const typename tupleset< LS2... >::value_t &l2, seq< I1... >, seq< I2... >) const
Definition: tupleset.hh:726
void convs(std::istream &i, Fun &&fun) const
Fun: (label_t) -> void.
Definition: tupleset.hh:611
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:1229
void hash_combine(std::size_t &seed, const T &v)
Definition: functional.hh:63
Functor to compare Values of ValueSets.
Definition: functional.hh:91
valueset_t< 0 >::value_t lnormalize_here(value_t &v) const
Eliminate the LGCD between all the tapes.
Definition: tupleset.hh:506
law_t< LabelSet > make_wordset(const LabelSet &ls)
The wordset of a labelset.
Definition: labelset.hh:259
zip_sequences< Sequences... > zip(Sequences &&... seqs)
Definition: zip.hh:439
static type join(const vs1_t &lhs, const vs2_t &rhs)
The resulting valueset.
Definition: tupleset.hh:1398
Value delimit_(const Value &l, seq< I... >) const
Definition: tupleset.hh:964
static auto zero() -> decltype(zero_(Indices
A tuple of zeros.
Definition: tupleset.hh:830
std::ostream & print(const value_t &l, std::ostream &o=std::cout, format fmt={}) const
Definition: tupleset.hh:629
value_t conv_(std::istream &i, bool quoted, std::false_type) const
Read a tuple in the stream, possibly parenthesized.
Definition: tupleset.hh:1007
static constexpr bool is_expressionset_(seq< I... >)
Definition: tupleset.hh:862
static constexpr bool is_free_(seq< I... >)
Definition: tupleset.hh:751
Whether a ValueSet, or a context, is multitape.
Definition: traits.hh:117
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:996
void print_(std::ostream &o, const T &arg, long)
Serialize arg into o.
Definition: raise.hh:26
static size_t size_(const Value &v, seq< I... >)
Definition: tupleset.hh:713
std::tuple< ValueSets... > valuesets_t
Definition: tupleset.hh:74
std::enable_if_t<!is_letterized_t< labelset_t_of< Aut > >{}, bool > is_letterized(const Aut &aut)
Definition: letterize.hh:161
bool is_valid(const value_t &l) const
Definition: tupleset.hh:396
value_t value(const std::tuple< Args... > &args) const
Construct a value.
Definition: tupleset.hh:205
STL namespace.
Whether two labelsets are composable.
Definition: traits.hh:94
boost::optional< value_t > maybe_ldivide(const value_t &l, const value_t &r) const
Definition: tupleset.hh:480
value_t map_impl_(const value_t &v, Fun &&fun, seq< I... >) const
Definition: tupleset.hh:922
static auto one_(seq< I... >) -> decltype(value_t
Definition: tupleset.hh:359
Value transpose_(const Value &l, seq< I... >) const
Definition: tupleset.hh:1111
value_t conv(std::istream &i, bool quoted=true) const
Read one label from i, return the corresponding value.
Definition: tupleset.hh:602
return res
Definition: multiply.hh:399
value_t conv(b, b::value_t v) const
Definition: tupleset.hh:569
valueset_t< 0 >::value_t lnormalize_here_(value_t &vs, seq< I... >) const
Definition: tupleset.hh:952
value_t tuple(Args &&... args) const
Construct a value.
Definition: tupleset.hh:212
static constexpr bool is_idempotent_(seq< I... >)
Definition: tupleset.hh:667
expressionset< Context >::value_t random_label(const expressionset< Context > &rs, RandomGenerator &gen=RandomGenerator())
Random label from expressionset: limited to a single label.
value_t conv(const VS &vs, const typename VS::value_t &v) const
Convert a single tape expression to multitape.
Definition: tupleset.hh:595
static size_t hash(const value_t &v)
Definition: tupleset.hh:557
auto out(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions leaving state s.
Definition: automaton.hh:86
value_t ldivide(const value_t &l, const value_t &r) const
Pointwise left division (l \ r).
Definition: tupleset.hh:470