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