Vcsn  2.1
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 <vcsn/config.hh> // VCSN_HAVE_CORRECT_LIST_INITIALIZER_ORDER
9 #include <vcsn/labelset/fwd.hh>
11 #include <vcsn/misc/escape.hh>
12 #include <vcsn/misc/raise.hh>
13 #include <vcsn/misc/stream.hh>
14 #include <vcsn/misc/tuple.hh> // tuple_element_t
15 #include <vcsn/misc/cross.hh>
16 #include <vcsn/misc/raise.hh>
17 #include <vcsn/misc/zip.hh>
18 #include <vcsn/weightset/b.hh>
19 
20 namespace vcsn
21 {
22  namespace detail
23  {
24 
29  template <typename Enable = void, typename... ValueSets>
31  {
32  using genset_t = void;
33  using letter_t = void;
35  using word_t = std::tuple<typename ValueSets::value_t...>;
36  };
37 
39  template <typename... ValueSets>
40  struct labelset_types_impl<decltype(pass{std::declval<ValueSets>().genset()...}, void()),
41  ValueSets...>
42  {
43  using genset_t
44  = cross_sequences<decltype(std::declval<ValueSets>().genset())...>;
45  using letter_t = std::tuple<typename ValueSets::letter_t...>;
46  using word_t = std::tuple<typename ValueSets::word_t...>;
47  };
48 
49  template <typename... ValueSets>
50  using labelset_types = labelset_types_impl<void, ValueSets...>;
51 
56  template <typename... ValueSets>
57  class tupleset_impl
58  {
59  public:
60  using valuesets_t = std::tuple<ValueSets...>;
61  using indices_t = make_index_sequence<sizeof...(ValueSets)>;
62  static constexpr indices_t indices{};
63  template <std::size_t... I>
64  using seq = index_sequence<I...>;
65 
67  template <std::size_t I>
69 
70  public:
71  using self_t = tupleset<ValueSets...>;
72 
74  using value_t = std::tuple<typename ValueSets::value_t...>;
75 
77  using letter_t = typename labelset_types<ValueSets...>::letter_t;
79  using genset_t = typename labelset_types<ValueSets...>::genset_t;
81  using word_t = typename labelset_types<ValueSets...>::word_t;
82 
85 
87 
89  : sets_(std::move(vs))
90  {}
91 
92  tupleset_impl(ValueSets... ls)
93  : sets_(ls...)
94  {}
95 
96  static symbol sname()
97  {
98  static symbol res(sname_(indices));
99  return res;
100  }
101 
103  static constexpr std::size_t size()
104  {
105  return sizeof...(ValueSets);
106  }
107 
109  static size_t size(const value_t& v)
110  {
111  return size_(v, indices);
112  }
113 
114  static constexpr bool
116  {
117  return is_commutative_(indices);
118  }
119 
120  static constexpr bool
122  {
123  return is_idempotent_(indices);
124  }
125 
127  static self_t make(std::istream& is)
128  {
129  // name: lat<law_char(abc), law_char(xyz)>
130  kind_t::make(is);
131  eat(is, '<');
132  auto res = make_(is, indices);
133  eat(is, '>');
134  return res;
135  }
136 
138  const valuesets_t& sets() const
139  {
140  return sets_;
141  }
142 
144  template <size_t I>
145  const valueset_t<I>& set() const
146  {
147  return std::get<I>(sets());
148  }
149 
153  bool open(bool o) const
154  {
155  return this->open_(o, indices);
156  }
157 
159  template <typename... Args>
160  value_t value(const std::tuple<Args...>& args) const
161  {
162  return this->value_(args, indices);
163  }
164 
166  template <typename... Args>
167  value_t tuple(Args&&... args) const
168  {
169  return value_t{args...};
170  }
171 
173  genset_t
174  genset() const
175  {
176  return this->genset_(indices);
177  }
178 
179  static constexpr bool is_free()
180  {
181  return is_free_(indices);
182  }
183 
184  private:
185  template <typename LhsValue, typename RhsValue, std::size_t... I>
186  auto
187  mul_(const LhsValue& l, const RhsValue& r, seq<I...>) const
188  -> word_t
189  {
190  return word_t{set<I>().mul(std::get<I>(l), std::get<I>(r))...};
191  }
192 
193  public:
195  template <typename... Args>
196  auto
197  word(const std::tuple<Args...>& v) const
198  -> word_t
199  {
200  return this->word_(v, indices);
201  }
202 
204  static bool
205  equal(const value_t& l, const value_t& r)
206  {
207  return equal_(l, r, indices);
208  }
209 
211  static bool
212  less(const value_t& l, const value_t& r)
213  {
214  auto sl = size(l);
215  auto sr = size(r);
216  if (sl < sr)
217  return true;
218  else if (sr < sl)
219  return false;
220  else
221  return less_(l, r, indices);
222  }
223 
224  static value_t
226  {
227  return special_(indices);
228  }
229 
230  static bool
231  is_special(const value_t& l)
232  {
233  return is_special_(l, indices);
234  }
235 
236  value_t
237  zero() const
238  {
239  return this->zero_(indices);
240  }
241 
242  bool
243  is_zero(const value_t& l) const
244  {
245  return is_zero_(l, indices);
246  }
247 
248  static constexpr bool
250  {
251  return has_one_(indices);
252  }
253 
254  static constexpr bool
256  {
257  return is_expressionset_(indices);
258  }
259 
260  static constexpr bool
262  {
263  return is_letterized_(indices);
264  }
265 
266  private:
267  template <std::size_t... I>
268  static auto one_(seq<I...>)
269  -> decltype(value_t{valueset_t<I>::one()...})
270  {
271  return value_t{valueset_t<I>::one()...};
272  }
273 
274  public:
279  template <typename Indices = indices_t>
280  static auto one() -> decltype(one_(Indices{}))
281  {
282  return one_(Indices{});
283  }
284 
285  static bool
286  is_one(const value_t& l)
287  {
288  return is_one_(l, indices);
289  }
290 
291  static bool
293  {
294  return show_one_(indices);
295  }
296 
297  bool
298  is_letter(const value_t&) const
299  {
300  // FIXME: why??? Is this for the printer of expressions?
301  return false;
302  }
303 
305  value_t
306  add(const value_t& l, const value_t& r) const
307  {
308  return this->add_(l, r, indices);
309  }
310 
315  template <typename LhsValue, typename RhsValue>
316  auto
317  mul(const LhsValue& l, const RhsValue& r) const
318  -> word_t
319  {
320  return this->mul_(l, r, indices);
321  }
322 
324  value_t
325  lgcd(const value_t& l, const value_t& r) const
326  {
327  return this->lgcd_(l, r, indices);
328  }
329 
331  value_t
332  rdiv(const value_t& l, const value_t& r) const
333  {
334  return this->rdiv_(l, r, indices);
335  }
336 
338  value_t
339  ldiv(const value_t& l, const value_t& r) const
340  {
341  return this->ldiv_(l, r, indices);
342  }
343 
348  typename valueset_t<0>::value_t
350  {
351  return this->lnormalize_here_(v, indices);
352  }
353 
354  value_t
355  star(const value_t& l) const
356  {
357  return this->star_(l, indices);
358  }
359 
365  template <typename Value>
366  Value
367  delimit(const Value& l) const
368  {
369  return this->delimit_(l, indices);
370  }
371 
373  template <typename Value>
374  Value
375  undelimit(const Value& l) const
376  {
377  return this->undelimit_(l, indices);
378  }
379 
380  // FIXME: this needs to be computed.
381  static constexpr star_status_t star_status()
382  {
384  }
385 
387  template <typename Value>
388  Value
389  transpose(const Value& l) const
390  {
391  return this->transpose_(l, indices);
392  }
393 
394  static size_t
395  hash(const value_t& v)
396  {
397  return hash_(v, indices);
398  }
399 
400  static value_t
402  {
403  return v;
404  }
405 
406  value_t
407  conv(b, b::value_t v) const
408  {
409  return v ? one() : zero();
410  }
411 
413  template <typename... VS>
414  value_t
416  const typename tupleset<VS...>::value_t& v) const
417  {
418  return this->conv_(vs, v, indices);
419  }
420 
422  template <typename... VS>
423  value_t
425  const typename nullableset<tupleset<VS...>>::value_t& v) const
426  {
427  return conv(*vs.labelset(), vs.get_value(v));
428  }
429 
431  value_t
432  conv(std::istream& i, bool quoted = true) const
433  {
434  // To know whether we have a tupleset of labelsets, we check if
435  // genset_t is not void. See labelset_types_impl above.
436  constexpr auto has_label_one
437  = !std::is_same<genset_t, void>::value && has_one_mem_fn<self_t>{};
438  return conv_(i, quoted, bool_constant<has_label_one>{});
439  }
440 
441  template <typename Fun>
442  static void convs(std::istream&, Fun)
443  {
444  raise("tupleset: ranges not implemented");
445  }
446 
447  std::ostream&
448  print_set(std::ostream& o, format fmt = {}) const
449  {
450  return this->print_set_(o, fmt, indices);
451  }
452 
453  std::ostream&
454  print(const value_t& l, std::ostream& o,
455  format fmt = {}) const
456  {
457  if (fmt.is_for_labels())
458  this->print_(l, o, fmt, "", "|", "", indices);
459  else
460  this->print_(l, o, fmt, "(", ",", ")", indices);
461  return o;
462  }
463 
464  private:
465  template <std::size_t... I>
466  static std::string sname_(seq<I...>)
467  {
468  std::string res = "lat<";
469  const char *sep = "";
470  for (auto n: {valueset_t<I>::sname()...})
471  {
472  res += sep;
473  res += n;
474  sep = ", ";
475  }
476  res.push_back('>');
477  return res;
478  }
479 
480  template <std::size_t... I>
481  static constexpr bool
483  {
484  return all_<valueset_t<I>::is_commutative()...>();
485  }
486 
487  template <std::size_t... I>
488  static constexpr bool
490  {
491  return all_<valueset_t<I>::is_idempotent()...>();
492  }
493 
494  template <std::size_t... I>
495  static self_t make_(std::istream& i, seq<I...>)
496  {
497 #if VCSN_HAVE_CORRECT_LIST_INITIALIZER_ORDER
498  return self_t{(eat_separator_<I>(i),
499  valueset_t<I>::make(i))...};
500 #else
501  return make_gcc_tuple
502  ((eat_separator_<sizeof...(ValueSets)-1 -I>(i),
503  valueset_t<sizeof...(ValueSets)-1 -I>::make(i))...);
504 #endif
505  }
506 
507  template <std::size_t... I>
508  bool open_(bool o, seq<I...>) const
509  {
510  using swallow = int[];
511  (void) swallow { set<I>().open(o)... };
512  std::swap(o, open__);
513  return o;
514  }
515 
518  template <std::size_t I>
519  static auto size_(const value_t& v, int)
520  -> decltype(valueset_t<I>::size(std::get<I>(v)))
521  {
522  return valueset_t<I>::size(std::get<I>(v));
523  }
524 
527  template <std::size_t I>
528  static constexpr auto size_(const value_t&, ...)
529  -> size_t
530  {
531  return 0;
532  }
533 
534  template <std::size_t... I>
535  static size_t size_(const value_t& v, seq<I...>)
536  {
537  return std::max({size_<I>(v, 0)...});
538  }
539 
540  template <typename... Args, std::size_t... I>
541  value_t value_(const std::tuple<Args...>& args, seq<I...>) const
542  {
543  return value_t{set<I>().value(std::get<I>(args))...};
544  }
545 
546  template <std::size_t... I>
547  genset_t
549  {
550  return ::vcsn::cross(set<I>().genset()...);
551  }
552 
553  template <std::size_t... I>
554  static constexpr bool
556  {
557  return all_<valueset_t<I>::is_free()...>();
558  }
559 
560  template <typename... Args, std::size_t... I>
561  word_t
562  word_(const std::tuple<Args...>& l, seq<I...>) const
563  {
564  return word_t{set<I>().word(std::get<I>(l))...};
565  }
566 
567  template <std::size_t... I>
568  static bool
569  equal_(const value_t& l, const value_t& r, seq<I...>)
570  {
571  for (auto n: {valueset_t<I>::equal(std::get<I>(l),
572  std::get<I>(r))...})
573  if (!n)
574  return false;
575  return true;
576  }
577 
578  template <std::size_t... I>
579  static bool
580  less_(const value_t& l, const value_t& r, seq<I...>)
581  {
582  for (auto n: {std::make_pair(valueset_t<I>::less(std::get<I>(l),
583  std::get<I>(r)),
584  valueset_t<I>::less(std::get<I>(r),
585  std::get<I>(l)))...})
586  if (n.first)
587  return true;
588  else if (n.second)
589  return false;
590  return false;
591  }
592 
593  template <std::size_t... I>
594  static std::size_t
596  {
597  std::size_t res = 0;
598  for (auto h: {valueset_t<I>::hash(std::get<I>(v))...})
599  hash_combine(res, h);
600  return res;
601  }
602 
603  template <std::size_t... I>
604  static value_t
606  {
607  return std::make_tuple(valueset_t<I>::special()...);
608  }
609 
610  template <std::size_t... I>
611  static bool
613  {
614  for (auto n: {valueset_t<I>::is_special(std::get<I>(l))...})
615  if (!n)
616  return false;
617  return true;
618  }
619 
620  template <std::size_t... I>
621  value_t
623  {
624  return value_t{set<I>().zero()...};
625  }
626 
627  template <std::size_t... I>
628  bool
629  is_zero_(const value_t& l, seq<I...>) const
630  {
631  for (auto n: {set<I>().is_zero(std::get<I>(l))...})
632  if (!n)
633  return false;
634  return true;
635  }
636 
637  template <std::size_t... I>
638  static constexpr bool
640  {
641  return all_<valueset_t<I>::has_one()...>();
642  }
643 
644  template <std::size_t... I>
645  static constexpr bool
647  {
648  return all_<valueset_t<I>::is_expressionset()...>();
649  }
650 
651  template <std::size_t... I>
652  static constexpr bool
654  {
655  return all_<valueset_t<I>::is_letterized()...>();
656  }
657 
658  template <std::size_t... I>
659  static bool
661  {
662  for (auto n: {valueset_t<I>::is_one(std::get<I>(l))...})
663  if (!n)
664  return false;
665  return true;
666  }
667 
668  template <std::size_t... I>
669  static bool
671  {
672  for (auto n: {valueset_t<I>::show_one()...})
673  if (n)
674  return true;
675  return false;
676  }
677 
678  template <std::size_t... I>
679  value_t
680  add_(const value_t& l, const value_t& r, seq<I...>) const
681  {
682  return value_t{set<I>().add(std::get<I>(l), std::get<I>(r))...};
683  }
684 
685  template <std::size_t... I>
686  value_t
687  lgcd_(const value_t& l, const value_t& r, seq<I...>) const
688  {
689  return value_t{set<I>().lgcd(std::get<I>(l), std::get<I>(r))...};
690  }
691 
692  template <std::size_t... I>
693  value_t
694  rdiv_(const value_t& l, const value_t& r, seq<I...>) const
695  {
696  return value_t{set<I>().rdiv(std::get<I>(l), std::get<I>(r))...};
697  }
698 
699  template <std::size_t... I>
700  value_t
701  ldiv_(const value_t& l, const value_t& r, seq<I...>) const
702  {
703  return value_t{set<I>().ldiv(std::get<I>(l), std::get<I>(r))...};
704  }
705 
706  template <std::size_t... I>
707  typename valueset_t<0>::value_t
709  {
710  typename valueset_t<0>::value_t res = std::get<0>(vs);
711  for (auto v: {std::get<I>(vs)...})
712  res = set<0>().lgcd(res, v);
713  using swallow = int[];
714  (void) swallow { (set<0>().ldiv_here(res, std::get<I>(vs)), 0)... };
715  return res;
716  }
717 
718  template <std::size_t... I>
719  value_t
720  star_(const value_t& l, seq<I...>) const
721  {
722  return value_t{set<I>().star(std::get<I>(l))...};
723  }
724 
725  template <typename Value, std::size_t... I>
726  Value
727  delimit_(const Value& l, seq<I...>) const
728  {
729  return Value{set<I>().delimit(std::get<I>(l))...};
730  }
731 
732  template <typename Value, std::size_t... I>
733  Value
734  undelimit_(const Value& l, seq<I...>) const
735  {
736  return Value{set<I>().undelimit(std::get<I>(l))...};
737  }
738 
739  template <typename... VS, std::size_t... I>
740  value_t
742  const typename tupleset<VS...>::value_t& v,
743  seq<I...>) const
744  {
745  return value_t{set<I>().conv(vs.template set<I>(), std::get<I>(v))...};
746  }
747 
750  value_t
751  conv_(std::istream& i, bool quoted, std::true_type) const
752  {
753  if (i.peek() == EOF)
754  return one();
755  else
756  // This is not the empty string, bounce to the regular case.
757  return conv_(i, quoted, std::false_type{});
758  }
759 
761  value_t
762  conv_(std::istream& i, bool quoted, std::false_type) const
763  {
764  bool par = i.peek() == '(';
765  if (par)
766  eat(i, '(');
767  value_t res = conv_(i, quoted, indices);
768  if (par)
769  eat(i, ')');
770  return res;
771  }
772 
773  template <std::size_t... I>
774  value_t
775  conv_(std::istream& i, bool quoted, seq<I...>) const
776  {
777 #if VCSN_HAVE_CORRECT_LIST_INITIALIZER_ORDER
778  return value_t{(eat_separator_<I>(i),
779  set<I>().conv(i, quoted))...};
780 #else
781  constexpr auto S = sizeof...(ValueSets)-1;
782  return
783  detail::make_gcc_tuple((eat_separator_<S - I>(i),
784  set<S - I>().conv(i, quoted))...);
785 #endif
786  }
787 
792  template <std::size_t I>
793  static void
794  eat_separator_(std::istream& i)
795  {
796  if (I)
797  eat(i, i.peek() == ',' ? ',' : '|');
798  while (isspace(i.peek()))
799  i.ignore();
800  }
801 
802 
803  template <std::size_t... I>
804  std::ostream&
805  print_(const value_t& l, std::ostream& o,
806  format fmt,
807  const char* pre,
808  const char* sep,
809  const char* post,
810  seq<I...>) const
811  {
812  if (!is_special(l))
813  {
814  using swallow = int[];
815  (void) swallow
816  {
817  (o << (I == 0 ? pre : sep),
818  set<I>().print(std::get<I>(l), o, fmt),
819  0)...
820  };
821  o << post;
822  }
823  return o;
824  }
825 
826  template <std::size_t... I>
827  std::ostream&
828  print_set_(std::ostream& o, format fmt,
829  seq<I...>) const
830  {
831  const char *sep = "";
832  if (fmt == format::latex)
833  sep = " \\times ";
834  else if (fmt == format::text)
835  {
836  o << "lat<";
837  sep = ", ";
838  }
839  else
840  raise("invalid format: ", fmt);
841  using swallow = int[];
842  (void) swallow
843  {
844  (o << (I == 0 ? "" : sep),
845  set<I>().print_set(o, fmt),
846  0)...
847  };
848  if (fmt == format::text)
849  o << '>';
850  return o;
851  }
852 
853  template <typename Value, std::size_t... I>
854  Value
855  transpose_(const Value& l, seq<I...>) const
856  {
857  return Value{set<I>().transpose(std::get<I>(l))...};
858  }
859 
861  template <std::size_t... I>
862  self_t
863  meet_(const self_t& rhs, seq<I...>) const
864  {
865  return self_t{meet(set<I>(), rhs.template set<I>())...};
866  }
867 
869  friend
870  self_t
871  meet(const self_t& lhs, const self_t& rhs)
872  {
873  return lhs.meet_(rhs, indices);
874  }
875 
877  friend
878  self_t
879  meet(const self_t& lhs, const b&)
880  {
881  return lhs;
882  }
883 
885  friend
886  self_t
887  meet(const b&, const self_t& rhs)
888  {
889  return rhs;
890  }
891 
893  valuesets_t sets_;
895  mutable bool open__ = false;
896 
897  private:
899  template <std::size_t... I>
900  auto
901  get_letter_(std::istream& i, bool quoted, seq<I...>) const
902  -> letter_t
903  {
904 #if VCSN_HAVE_CORRECT_LIST_INITIALIZER_ORDER
905  return letter_t{(eat_separator_<I>(i),
906  set<I>().get_letter(i, quoted))...};
907 #else
908  constexpr auto S = sizeof...(ValueSets)-1;
909  return
910  detail::make_gcc_tuple((eat_separator_<S - I>(i),
911  set<S - I>().get_letter(i, quoted))...);
912 #endif
913  }
914 
916  template <typename Value, std::size_t... I>
917  static auto
918  letters_of_(const Value& v, seq<I...>)
919  -> decltype(zip(valueset_t<I>::letters_of(std::get<I>(v))...))
920  {
921  return zip(valueset_t<I>::letters_of(std::get<I>(v))...);
922  }
923 
925  template <typename Value, typename... Defaults, std::size_t... I>
926  auto
927  letters_of_padded_(const Value& v,
928  const std::tuple<Defaults...>& def, seq<I...>) const
929  -> decltype(zip_with_padding(def,
930  this->set<I>().letters_of_padded(std::get<I>(v),
931  std::get<I>(def))...))
932  {
933  return zip_with_padding(def,
934  set<I>().letters_of_padded(std::get<I>(v),
935  std::get<I>(def))...);
936  }
937 
938  public:
939  template <std::size_t... I>
940  auto
941  get_letter(std::istream& i, bool quoted = true) const
942  -> decltype(this->get_letter_(i, quoted, indices))
943  {
944  bool par = i.peek() == '(';
945  if (par)
946  eat(i, '(');
947  auto res = get_letter_(i, quoted, indices);
948  if (par)
949  eat(i, ')');
950  return res;
951  }
952 
958  template <typename Value>
959  static auto
960  letters_of(const Value& v)
961  -> decltype(letters_of_(v, indices))
962  {
963  return letters_of_(v, indices);
964  }
965 
971  template <typename Value, typename... Defaults>
972  auto
973  letters_of_padded(const Value& v, const std::tuple<Defaults...>& def) const
974  -> decltype(this->letters_of_padded_(v, def, indices))
975  {
976  return letters_of_padded_(v, def, indices);
977  }
978  };
979 
980  template <typename... ValueSets>
981  tupleset<ValueSets...>
982  make_tupleset(const ValueSets&... vss)
983  {
984  return {vss...};
985  }
986 
987 
988  /*----------------.
989  | is_multitape. |
990  `----------------*/
991 
993  template <typename ValueSet>
994  struct is_multitape
995  : std::false_type
996  {};
997 
998  template <typename... ValueSet>
999  struct is_multitape<tupleset<ValueSet...>>
1000  : std::true_type
1001  {};
1002 
1003  template <typename LabelSet, typename WeightSet>
1004  struct is_multitape<context<LabelSet, WeightSet>>
1005  : is_multitape<LabelSet>
1006  {};
1007 
1008 
1009 
1010  template <typename T1, typename T2>
1011  struct concat_tupleset;
1012 
1013  // Sure, we'd like to use tuple<> instead of
1014  // weightset_mixin<tupleset_impl<>>, however then we hit a Clang
1015  // 3.5.0 bug.
1016  //
1017  // https://llvm.org/bugs/show_bug.cgi?id=19372
1018  template <typename... T1, typename... T2>
1021  {
1022  using type = weightset_mixin<tupleset_impl<T1..., T2...>>;
1023  };
1024 
1026  template <typename... LabelSets>
1027  struct letterized_traits<tupleset<LabelSets...>>
1028  {
1029  using indices_t = make_index_sequence<sizeof...(LabelSets)>;
1030 
1031  template <std::size_t... I>
1032  using seq = index_sequence<I...>;
1033 
1034  template <size_t I>
1035  using letterized_traits_t =
1037  template <std::size_t... I>
1038  static constexpr bool is_letterized_(seq<I...>)
1039  {
1041  }
1042  static constexpr bool is_letterized = is_letterized_(indices_t{});
1043 
1044  using labelset_t =
1046 
1047  static labelset_t labelset(const tupleset<LabelSets...>& ls)
1048  {
1049  return labelset_(ls, indices_t{});
1050  }
1051 
1052  template <std::size_t... I>
1053  static labelset_t labelset_(const tupleset<LabelSets...>& ls,
1054  seq<I...>)
1055  {
1056  return {make_letterized(std::get<I>(ls.sets()))...};
1057  }
1058  };
1059 
1061  template <typename... LabelSets>
1062  struct nullableset_traits<tupleset<LabelSets...>,
1063  enable_if_t<tupleset<LabelSets...>::has_one()>>
1064  {
1065  using labelset_t = tupleset<LabelSets...>;
1066  using type = labelset_t;
1067  static type value(const labelset_t& ls)
1068  {
1069  return ls;
1070  }
1071  };
1072 
1074  template <typename... LabelSets>
1075  struct nullableset_traits<tupleset<LabelSets...>,
1076  enable_if_t<!tupleset<LabelSets...>::has_one()>>
1077  {
1078  using labelset_t = tupleset<LabelSets...>;
1080 
1081  static type value(const labelset_t& ls)
1082  {
1083  return ls;
1084  }
1085  };
1086 
1088  template <typename LabelSet>
1089  struct proper_traits<tupleset<LabelSet>>
1090  {
1092  static type value(const tupleset<LabelSet>& ls)
1093  {
1094  return {proper_traits<LabelSet>::value(ls.template set<0>())};
1095  }
1096  };
1097 
1099  template <typename... LabelSets>
1100  struct law_traits<tupleset<LabelSets...>>
1101  {
1102  using labelset_t = tupleset<LabelSets...>;
1104 
1105  template <std::size_t... I>
1107  {
1108  return {make_wordset(ls.template set<I>())...};
1109  }
1110 
1111  static type value(const labelset_t& ls)
1112  {
1113  return value(ls, make_index_sequence<sizeof...(LabelSets)>{});
1114  }
1115  };
1116 
1118  template <typename... VS1, typename... VS2>
1119  struct join_impl<tupleset<VS1...>, tupleset<VS2...>>
1120  {
1121  static_assert(sizeof...(VS1) == sizeof...(VS2),
1122  "join: tuplesets must have the same sizes");
1123  using vs1_t = tupleset<VS1...>;
1124  using vs2_t = tupleset<VS2...>;
1127 
1128  template <std::size_t... I>
1129  static type join(const vs1_t lhs, const vs2_t& rhs,
1131  {
1132  return {::vcsn::join(lhs.template set<I>(), rhs.template set<I>())...};
1133  }
1134 
1136  static type join(const vs1_t& lhs, const vs2_t& rhs)
1137  {
1138  return join(lhs, rhs,
1139  make_index_sequence<sizeof...(VS1)>{});
1140  }
1141  };
1142 
1144  template <typename... VS1, typename VS2>
1145  struct join_impl<tupleset<VS1...>, VS2>
1146  {
1147  // Cannot just leave "false" as condition: the assertion is then
1148  // always checked, even if the template is not instantiated.
1149  static_assert(is_multitape<VS2>{},
1150  "join: cannot mix tuplesets and non tuplesets");
1151  };
1152 
1153 
1154  /*------------------.
1155  | project_labelset. |
1156  `------------------*/
1157 
1160  template <size_t Tape, typename LabelSet>
1162 
1165  template <size_t Tape, typename LabelSet>
1167 
1169  template <size_t Tape, typename... LabelSets>
1170  struct project_labelset_impl<Tape, tupleset<LabelSets...>>
1171  {
1172  using labelset_t = tupleset<LabelSets...>;
1173  using type = typename labelset_t::template valueset_t<Tape>;
1174  };
1175 
1177  template <size_t Tape, typename Context>
1178  struct project_labelset_impl<Tape, expressionset<Context>>
1179  {
1183  };
1184 
1185 
1186  /*------------------.
1187  | project_context. |
1188  `------------------*/
1189 
1191  template <size_t Tape, typename Context>
1192  using project_context
1195 
1196  }// detail::
1197 }// vcsn::
STL namespace.
valueset_t< 0 >::value_t lnormalize_here_(value_t &vs, seq< I...>) const
Definition: tupleset.hh:708
std::ostream & print(const value_t &l, std::ostream &o, format fmt={}) const
Definition: tupleset.hh:454
value_t rdiv_(const value_t &l, const value_t &r, seq< I...>) const
Definition: tupleset.hh:694
std::tuple< typename ValueSets::value_t...> word_t
Same as value_t.
Definition: tupleset.hh:35
static constexpr bool is_expressionset()
Definition: tupleset.hh:255
static constexpr bool is_idempotent()
Definition: tupleset.hh:121
std::tuple< ValueSets...> valuesets_t
Definition: tupleset.hh:60
const valuesets_t & sets() const
The componants valuesets, as a tuple.
Definition: tupleset.hh:138
value_t rdiv(const value_t &l, const value_t &r) const
Pointwise right division (l / r).
Definition: tupleset.hh:332
value_t value(const std::tuple< Args...> &args) const
Construct a value.
Definition: tupleset.hh:160
weightset_mixin< detail::r_impl > r
Definition: fwd.hh:54
static value_t special()
Definition: tupleset.hh:225
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:415
static constexpr bool is_letterized_(seq< I...>)
Definition: tupleset.hh:1038
static constexpr auto size_(const value_t &,...) -> size_t
The size of the Ith element, if its valueset does not feature a size() function.
Definition: tupleset.hh:528
ValueSet::value_t ldiv(const ValueSet &vs, const typename ValueSet::value_t &lhs, const typename ValueSet::value_t &rhs)
Left-division of values.
Definition: divide.hh:17
static bool is_one(const value_t &l)
Definition: tupleset.hh:286
Ignore its arguments.
Definition: raise.hh:17
tuple_element_t< I, valuesets_t > valueset_t
The Ith valueset type.
Definition: tupleset.hh:68
Provide a range that allows to iterate over the cross product of the provided ranges.
Definition: cross.hh:15
static constexpr bool has_one()
Definition: tupleset.hh:249
auto mul_(const LhsValue &l, const RhsValue &r, seq< I...>) const -> word_t
Definition: tupleset.hh:187
cross_sequences< Sequences...> cross(Sequences &&...seqs)
Definition: cross.hh:272
static void eat_separator_(std::istream &i)
Read the separator from the input stream i if I is not 0.
Definition: tupleset.hh:794
A structure that implements the computation of join(V1, V2).
Definition: join.hh:18
tupleset_impl(ValueSets...ls)
Definition: tupleset.hh:92
static self_t make(std::istream &is)
Build from the description in is.
Definition: tupleset.hh:127
static size_t size(const value_t &v)
Get the max of the sizes of the tapes.
Definition: tupleset.hh:109
static constexpr bool is_letterized()
Definition: tupleset.hh:261
static bool is_special_(const value_t &l, seq< I...>)
Definition: tupleset.hh:612
auto join(const ValueSet &vs) -> ValueSet
The join of a single valueset.
Definition: join.hh:44
static void convs(std::istream &, Fun)
Definition: tupleset.hh:442
static constexpr bool has_one_(seq< I...>)
Definition: tupleset.hh:639
letterized_t< LabelSet > make_letterized(const LabelSet &ls)
Definition: labelset.hh:102
std::istringstream is
The input stream: the specification to translate.
Definition: translate.cc:372
std::ostream & print_set(std::ostream &o, format fmt={}) const
Definition: tupleset.hh:448
char eat(std::istream &is, char c)
Check lookahead character and advance.
Definition: stream.cc:37
static type value(const labelset_t &ls)
Definition: tupleset.hh:1111
value_t ldiv(const value_t &l, const value_t &r) const
Pointwise left division (l \ r).
Definition: tupleset.hh:339
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
Definition: traits.hh:51
value_t zero_(seq< I...>) const
Definition: tupleset.hh:622
typename labelset_t::template valueset_t< Tape > type
Definition: tupleset.hh:1173
Whether a ValueSet, or a context, is multitape.
Definition: tupleset.hh:994
typename std::enable_if< Cond, T >::type enable_if_t
Definition: type_traits.hh:16
ValueSet::value_t rdiv(const ValueSet &vs, const typename ValueSet::value_t &lhs, const typename ValueSet::value_t &rhs)
Right-division of values.
Definition: divide.hh:100
static std::size_t hash_(const value_t &v, seq< I...>)
Definition: tupleset.hh:595
static constexpr bool is_free_(seq< I...>)
Definition: tupleset.hh:555
static bool less_(const value_t &l, const value_t &r, seq< I...>)
Definition: tupleset.hh:580
static labelset_t labelset(const tupleset< LabelSets...> &ls)
Definition: tupleset.hh:1047
static bool is_one_(const value_t &l, seq< I...>)
Definition: tupleset.hh:660
static constexpr star_status_t star_status()
Definition: tupleset.hh:381
static type join(const vs1_t lhs, const vs2_t &rhs, index_sequence< I...>)
Definition: tupleset.hh:1129
value_t zero() const
Definition: tupleset.hh:237
ValueSet::value_t tuple(const ValueSet &vs, const typename ValueSets::value_t &...v)
Definition: tuple.hh:28
static std::string sname_(seq< I...>)
Definition: tupleset.hh:466
void hash_combine(std::size_t &seed, const T &v)
Definition: functional.hh:32
void print_(std::ostream &o, const T &arg, long)
Serialize arg into o.
Definition: raise.hh:25
static constexpr bool is_letterized_(seq< I...>)
Definition: tupleset.hh:653
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:307
bool is_letter(const value_t &) const
Definition: tupleset.hh:298
static constexpr std::size_t size()
Number of tapes.
Definition: tupleset.hh:103
The type of the resulting apparent LabelSet when keeping only tape Tape.
Definition: tupleset.hh:1161
bool open_(bool o, seq< I...>) const
Definition: tupleset.hh:508
value_t conv(const nullableset< tupleset< VS...>> &vs, const typename nullableset< tupleset< VS...>>::value_t &v) const
Convert a value from nullableset> to value_t.
Definition: tupleset.hh:424
An input/output format.
Definition: format.hh:11
Value transpose(const Value &l) const
Transpose a word_t or a value_t.
Definition: tupleset.hh:389
value_t conv(std::istream &i, bool quoted=true) const
Read one label from i, return the corresponding value.
Definition: tupleset.hh:432
value_t value_(const std::tuple< Args...> &args, seq< I...>) const
Definition: tupleset.hh:541
static symbol sname()
Definition: tupleset.hh:96
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
static type value(const tupleset< LabelSet > &ls)
Definition: tupleset.hh:1092
fresh_automaton_t_of< Aut > star(const Aut &aut)
Star of a standard automaton.
Definition: star.hh:60
typename project_labelset_impl< Tape, LabelSet >::type project_labelset
The type of the resulting apparent LabelSet when keeping only tape Tape.
Definition: tupleset.hh:1166
static constexpr bool is_idempotent_(seq< I...>)
Definition: tupleset.hh:489
static bool less(const value_t &l, const value_t &r)
Whether l < r.
Definition: tupleset.hh:212
always valid.
Definition: star-status.hh:17
static bool equal(const value_t &l, const value_t &r)
Whether l equals r.
Definition: tupleset.hh:205
From a labelset, its non-nullable labelset.
Definition: labelset.hh:184
law_t< LabelSet > make_wordset(const LabelSet &ls)
The wordset of a labelset.
Definition: labelset.hh:261
A traits so that tupleset may define types that may exist.
Definition: tupleset.hh:30
value_t conv_(const tupleset< VS...> &vs, const typename tupleset< VS...>::value_t &v, seq< I...>) const
Definition: tupleset.hh:741
std::tuple< typename ValueSets::value_t...> value_t
A tuple of values.
Definition: tupleset.hh:74
value_t conv_(std::istream &i, bool quoted, std::false_type) const
Read a tuple in the stream, possibly parenthesized.
Definition: tupleset.hh:762
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
typename std::tuple_element< I, T >::type tuple_element_t
C++14.
Definition: tuple.hh:14
auto word(const std::tuple< Args...> &v) const -> word_t
Convert to a word.
Definition: tupleset.hh:197
value_t tuple(Args &&...args) const
Construct a value.
Definition: tupleset.hh:167
static self_t make_(std::istream &i, seq< I...>)
Definition: tupleset.hh:495
Value undelimit_(const Value &l, seq< I...>) const
Definition: tupleset.hh:734
const valueset_t< I > & set() const
The Ith component valueset.
Definition: tupleset.hh:145
static constexpr bool is_commutative_(seq< I...>)
Definition: tupleset.hh:482
value_t lgcd_(const value_t &l, const value_t &r, seq< I...>) const
Definition: tupleset.hh:687
static size_t size_(const value_t &v, seq< I...>)
Definition: tupleset.hh:535
decltype(std::declval< LabelSet >().genset()) genset_t
Definition: labelset.hh:18
static bool is_special(const value_t &l)
Definition: tupleset.hh:231
A ValueSet which is a Cartesian product of ValueSets.
Definition: fwd.hh:23
Value delimit(const Value &l) const
Add the special character first and last.
Definition: tupleset.hh:367
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:751
symbol sname()
Definition: name.hh:67
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
Definition: symbol.hh:23
static constexpr bool is_free()
Definition: tupleset.hh:179
value_t star(const value_t &l) const
Definition: tupleset.hh:355
static type value(const labelset_t &ls, index_sequence< I...>)
Definition: tupleset.hh:1106
value_t star_(const value_t &l, seq< I...>) const
Definition: tupleset.hh:720
letter_t value_type
To be iterable.
Definition: tupleset.hh:84
static auto one_(seq< I...>) -> decltype(value_t
Definition: tupleset.hh:268
bool is_zero(const value_t &l) const
Definition: tupleset.hh:243
value_t add_(const value_t &l, const value_t &r, seq< I...>) const
Definition: tupleset.hh:680
The smallest nullableset which includes LabelSet.
Definition: labelset.hh:140
vcsn::enable_if_t<!is_letterized_t< labelset_t_of< Aut > >{}, bool > is_letterized(const Aut &aut)
Definition: letterize.hh:162
static value_t conv(self_t, value_t v)
Definition: tupleset.hh:401
Value undelimit(const Value &l) const
Remove first and last characters, that must be "special".
Definition: tupleset.hh:375
star_status_t
Definition: star-status.hh:5
typename labelset_types< ValueSets...>::letter_t letter_t
A tuple of letters if meaningful, void otherwise.
Definition: tupleset.hh:77
value_t lgcd(const value_t &l, const value_t &r) const
The pointwise LGCD.
Definition: tupleset.hh:325
Value delimit_(const Value &l, seq< I...>) const
Definition: tupleset.hh:727
static bool equal_(const value_t &l, const value_t &r, seq< I...>)
Definition: tupleset.hh:569
static bool show_one_(seq< I...>)
Definition: tupleset.hh:670
bool open(bool o) const
Whether unknown letters should be added, or rejected.
Definition: tupleset.hh:153
value_t conv(b, b::value_t v) const
Definition: tupleset.hh:407
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:28
static auto one() -> decltype(one_(Indices
A tuple of ones.
Definition: tupleset.hh:280
static size_t hash(const value_t &v)
Definition: tupleset.hh:395
value_t add(const value_t &l, const value_t &r) const
Pointwise addition.
Definition: tupleset.hh:306
valueset_t< 0 >::value_t lnormalize_here(value_t &v) const
Eliminate the LGCD between all the tapes.
Definition: tupleset.hh:349
std::ostream & print_set_(std::ostream &o, format fmt, seq< I...>) const
Definition: tupleset.hh:828
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:805
static type join(const vs1_t &lhs, const vs2_t &rhs)
The resulting valueset.
Definition: tupleset.hh:1136
typename labelset_types< ValueSets...>::genset_t genset_t
A tuple of gensets if meaningful, void otherwise.
Definition: tupleset.hh:79
tupleset_impl(valuesets_t vs)
Definition: tupleset.hh:88
word_t word_(const std::tuple< Args...> &l, seq< I...>) const
Definition: tupleset.hh:562
std::integral_constant< bool, B > bool_constant
Definition: type_traits.hh:35
bool is_zero_(const value_t &l, seq< I...>) const
Definition: tupleset.hh:629
context join(const context &c1, const context &c2)
Bridge.
Definition: make-context.hh:92
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:65
value_t conv_(std::istream &i, bool quoted, seq< I...>) const
Definition: tupleset.hh:775
static value_t special_(seq< I...>)
Definition: tupleset.hh:605
typename labelset_types< ValueSets...>::word_t word_t
A tuple of words if meaningful, void otherwise.
Definition: tupleset.hh:81
static labelset_t labelset_(const tupleset< LabelSets...> &ls, seq< I...>)
Definition: tupleset.hh:1053
static constexpr bool is_expressionset_(seq< I...>)
Definition: tupleset.hh:646
static constexpr bool is_commutative()
Definition: tupleset.hh:115
genset_t genset() const
The generators. Meaningful for labelsets only.
Definition: tupleset.hh:174
auto mul(const LhsValue &l, const RhsValue &r) const -> word_t
The product (possibly concatenation) of l and r.
Definition: tupleset.hh:317
bool is_letterized(const Aut &aut)
Check if the transitions are all letters.
Definition: letterize.hh:191
value_t ldiv_(const value_t &l, const value_t &r, seq< I...>) const
Definition: tupleset.hh:701
constant< type_t::one, Context > one
Definition: fwd.hh:111
Implementation of labels are nullables (letter or empty).
Definition: fwd.hh:14
static auto size_(const value_t &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:519
The LAW from a LAL.
Definition: labelset.hh:251
genset_t genset_(seq< I...>) const
Definition: tupleset.hh:548