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