8 #include <vcsn/config.hh>
29 template <
typename Enable =
void,
typename... ValueSets>
39 template <
typename... ValueSets>
49 template <
typename... ValueSets>
56 template <
typename... ValueSets>
63 template <std::size_t... I>
67 template <std::
size_t I>
89 : sets_(
std::move(vs))
98 static symbol res(sname_(indices));
103 static constexpr std::size_t
size()
105 return sizeof...(ValueSets);
111 return size_(v, indices);
114 static constexpr
bool
117 return is_commutative_(indices);
120 static constexpr
bool
123 return is_idempotent_(indices);
132 auto res = make_(is, indices);
147 return std::get<I>(sets());
155 return this->open_(o, indices);
159 template <
typename... Args>
162 return this->value_(args, indices);
166 template <
typename... Args>
176 return this->genset_(indices);
181 return is_free_(indices);
185 template <
typename LhsValue,
typename RhsValue, std::size_t... I>
190 return word_t{set<I>().mul(std::get<I>(l), std::get<I>(
r))...};
195 template <
typename... Args>
197 word(
const std::tuple<Args...>&
v)
const
200 return this->word_(
v, indices);
207 return equal_(l, r, indices);
221 return less_(l, r, indices);
227 return special_(indices);
233 return is_special_(l, indices);
239 return this->zero_(indices);
245 return is_zero_(l, indices);
248 static constexpr
bool
251 return has_one_(indices);
254 static constexpr
bool
257 return is_expressionset_(indices);
260 static constexpr
bool
263 return is_letterized_(indices);
267 template <std::size_t... I>
279 template <
typename Indices = indices_t>
280 static auto one() -> decltype(one_(Indices{}))
282 return one_(Indices{});
288 return is_one_(l, indices);
294 return show_one_(indices);
308 return this->add_(l, r, indices);
315 template <
typename LhsValue,
typename RhsValue>
317 mul(
const LhsValue& l,
const RhsValue&
r)
const
320 return this->mul_(l,
r, indices);
327 return this->lgcd_(l, r, indices);
334 return this->rdiv_(l, r, indices);
341 return this->ldiv_(l, r, indices);
348 typename valueset_t<0>::value_t
351 return this->lnormalize_here_(v, indices);
357 return this->star_(l, indices);
365 template <
typename Value>
369 return this->delimit_(l, indices);
373 template <
typename Value>
377 return this->undelimit_(l, indices);
387 template <
typename Value>
391 return this->transpose_(l, indices);
397 return hash_(v, indices);
409 return v ? one() : zero();
413 template <
typename... VS>
418 return this->conv_(vs, v, indices);
422 template <
typename... VS>
427 return conv(*vs.labelset(), vs.get_value(v));
432 conv(std::istream& i,
bool quoted =
true)
const
436 constexpr
auto has_label_one
441 template <
typename Fun>
442 static void convs(std::istream&, Fun)
444 raise(
"tupleset: ranges not implemented");
450 return this->print_set_(o, fmt, indices);
457 if (fmt.is_for_labels())
458 this->
print_(l, o, fmt,
"",
"|",
"", indices);
460 this->
print_(l, o, fmt,
"(",
",",
")", indices);
465 template <std::size_t... I>
468 std::string res =
"lat<";
469 const char *sep =
"";
480 template <std::size_t... I>
481 static constexpr
bool
484 return all_<valueset_t<I>::is_commutative()...>();
487 template <std::size_t... I>
488 static constexpr
bool
491 return all_<valueset_t<I>::is_idempotent()...>();
494 template <std::size_t... I>
497 #if VCSN_HAVE_CORRECT_LIST_INITIALIZER_ORDER
498 return self_t{(eat_separator_<I>(i),
502 ((eat_separator_<
sizeof...(ValueSets)-1 -I>(i),
503 valueset_t<
sizeof...(ValueSets)-1 -I>::make(i))...);
507 template <std::size_t... I>
510 using swallow =
int[];
511 (
void) swallow { set<I>().open(o)... };
512 std::swap(o, open__);
518 template <std::
size_t I>
527 template <std::
size_t I>
534 template <std::size_t... I>
537 return std::max({size_<I>(
v, 0)...});
540 template <
typename... Args, std::size_t... I>
543 return value_t{set<I>().value(std::get<I>(args))...};
546 template <std::size_t... I>
553 template <std::size_t... I>
554 static constexpr
bool
557 return all_<valueset_t<I>::is_free()...>();
560 template <
typename... Args, std::size_t... I>
564 return word_t{set<I>().word(std::get<I>(l))...};
567 template <std::size_t... I>
578 template <std::size_t... I>
585 std::get<I>(l)))...})
593 template <std::size_t... I>
603 template <std::size_t... I>
610 template <std::size_t... I>
620 template <std::size_t... I>
624 return value_t{set<I>().zero()...};
627 template <std::size_t... I>
631 for (
auto n: {set<I>().is_zero(std::get<I>(l))...})
637 template <std::size_t... I>
638 static constexpr
bool
641 return all_<valueset_t<I>::has_one()...>();
644 template <std::size_t... I>
645 static constexpr
bool
648 return all_<valueset_t<I>::is_expressionset()...>();
651 template <std::size_t... I>
652 static constexpr
bool
658 template <std::size_t... I>
668 template <std::size_t... I>
678 template <std::size_t... I>
682 return value_t{set<I>().add(std::get<I>(l), std::get<I>(
r))...};
685 template <std::size_t... I>
689 return value_t{set<I>().
lgcd(std::get<I>(l), std::get<I>(
r))...};
692 template <std::size_t... I>
696 return value_t{set<I>().
rdiv(std::get<I>(l), std::get<I>(
r))...};
699 template <std::size_t... I>
703 return value_t{set<I>().
ldiv(std::get<I>(l), std::get<I>(
r))...};
706 template <std::size_t... I>
707 typename valueset_t<0>::value_t
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)... };
718 template <std::size_t... I>
725 template <
typename Value, std::size_t... I>
729 return Value{set<I>().delimit(std::get<I>(l))...};
732 template <
typename Value, std::size_t... I>
736 return Value{set<I>().undelimit(std::get<I>(l))...};
739 template <
typename... VS, std::size_t... I>
745 return value_t{set<I>().
conv(vs.template set<I>(), std::get<I>(
v))...};
751 conv_(std::istream& i,
bool quoted, std::true_type)
const
757 return conv_(i, quoted, std::false_type{});
762 conv_(std::istream& i,
bool quoted, std::false_type)
const
764 bool par = i.peek() ==
'(';
767 value_t res = conv_(i, quoted, indices);
773 template <std::size_t... I>
777 #if VCSN_HAVE_CORRECT_LIST_INITIALIZER_ORDER
778 return value_t{(eat_separator_<I>(i),
779 set<I>().conv(i, quoted))...};
781 constexpr
auto S =
sizeof...(ValueSets)-1;
784 set<S - I>().
conv(i, quoted))...);
792 template <std::
size_t I>
797 eat(i, i.peek() ==
',' ?
',' :
'|');
798 while (isspace(i.peek()))
803 template <std::size_t... I>
814 using swallow =
int[];
817 (o << (I == 0 ? pre : sep),
818 set<I>().print(std::get<I>(l), o, fmt),
826 template <std::size_t... I>
831 const char *sep =
"";
840 raise(
"invalid format: ", fmt);
841 using swallow =
int[];
844 (o << (I == 0 ?
"" : sep),
845 set<I>().print_set(o, fmt),
853 template <typename Value, std::size_t... I>
855 transpose_(const Value& l, seq<I...>) const
857 return Value{set<I>().transpose(std::get<I>(l))...};
861 template <std::size_t... I>
863 meet_(const self_t& rhs, seq<I...>) const
865 return self_t{meet(set<I>(), rhs.template set<I>())...};
871 meet(const self_t& lhs, const self_t& rhs)
873 return lhs.meet_(rhs, indices);
879 meet(const self_t& lhs, const b&)
887 meet(const b&, const self_t& rhs)
895 mutable bool open__ = false;
899 template <std::size_t... I>
901 get_letter_(std::istream& i, bool quoted, seq<I...>) const
904 #if VCSN_HAVE_CORRECT_LIST_INITIALIZER_ORDER
905 return letter_t{(eat_separator_<I>(i),
906 set<I>().get_letter(i, quoted))...};
908 constexpr auto S = sizeof...(ValueSets)-1;
910 detail::make_gcc_tuple((eat_separator_<S - I>(i),
911 set<S - I>().get_letter(i, quoted))...);
916 template <typename Value, std::size_t... I>
918 letters_of_(const Value& v, seq<I...>)
919 -> decltype(zip(valueset_t<I>::letters_of(std::get<I>(v))...))
921 return zip(valueset_t<I>::letters_of(std::get<I>(v))...);
925 template <typename Value, typename... Defaults, std::size_t... I>
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))...))
933 return zip_with_padding(def,
934 set<I>().letters_of_padded(std::get<I>(v),
935 std::get<I>(def))...);
939 template <std::size_t... I>
941 get_letter(std::istream& i, bool quoted = true) const
942 -> decltype(this->get_letter_(i, quoted, indices))
944 bool par = i.peek() == '(
';
947 auto res = get_letter_(i, quoted, indices);
958 template <typename Value>
960 letters_of(const Value& v)
961 -> decltype(letters_of_(v, indices))
963 return letters_of_(v, indices);
971 template <typename Value, typename... Defaults>
973 letters_of_padded(const Value& v, const std::tuple<Defaults...>& def) const
974 -> decltype(this->letters_of_padded_(v, def, indices))
976 return letters_of_padded_(v, def, indices);
980 template <typename... ValueSets>
981 tupleset<ValueSets...>
982 make_tupleset(const ValueSets&... vss)
993 template <typename ValueSet>
998 template <typename... ValueSet>
999 struct is_multitape<tupleset<ValueSet...>>
1003 template <typename LabelSet, typename WeightSet>
1004 struct is_multitape<context<LabelSet, WeightSet>>
1005 : is_multitape<LabelSet>
1010 template <typename T1, typename T2>
1011 struct concat_tupleset;
1013 // Sure, we'd like to use tuple<> instead of
1018 template <typename... T1, typename... T2>
1026 template <
typename... LabelSets>
1031 template <std::size_t... I>
1037 template <std::size_t... I>
1052 template <std::size_t... I>
1061 template <
typename... LabelSets>
1074 template <
typename... LabelSets>
1088 template <
typename LabelSet>
1099 template <
typename... LabelSets>
1105 template <std::size_t... I>
1118 template <
typename... VS1,
typename... VS2>
1121 static_assert(
sizeof...(VS1) ==
sizeof...(VS2),
1122 "join: tuplesets must have the same sizes");
1128 template <std::size_t... I>
1132 return {
::vcsn::join(lhs.template set<I>(), rhs.template set<I>())...};
1138 return join(lhs, rhs,
1144 template <
typename... VS1,
typename VS2>
1150 "join: cannot mix tuplesets and non tuplesets");
1160 template <
size_t Tape,
typename LabelSet>
1165 template <
size_t Tape,
typename LabelSet>
1169 template <
size_t Tape,
typename... LabelSets>
1173 using type =
typename labelset_t::template valueset_t<Tape>;
1177 template <
size_t Tape,
typename Context>
1191 template <
size_t Tape,
typename Context>
valueset_t< 0 >::value_t lnormalize_here_(value_t &vs, seq< I...>) const
std::ostream & print(const value_t &l, std::ostream &o, format fmt={}) const
value_t rdiv_(const value_t &l, const value_t &r, seq< I...>) const
std::tuple< typename ValueSets::value_t...> word_t
Same as value_t.
static constexpr bool is_expressionset()
static constexpr bool is_idempotent()
std::tuple< ValueSets...> valuesets_t
const valuesets_t & sets() const
The componants valuesets, as a tuple.
value_t rdiv(const value_t &l, const value_t &r) const
Pointwise right division (l / r).
value_t value(const std::tuple< Args...> &args) const
Construct a value.
weightset_mixin< detail::r_impl > r
value_t conv(const tupleset< VS...> &vs, const typename tupleset< VS...>::value_t &v) const
Convert a value from tupleset<...> to value_t.
static constexpr bool is_letterized_(seq< I...>)
static constexpr auto size_(const value_t &,...) -> size_t
The size of the Ith element, if its valueset does not feature a size() function.
ValueSet::value_t ldiv(const ValueSet &vs, const typename ValueSet::value_t &lhs, const typename ValueSet::value_t &rhs)
Left-division of values.
static bool is_one(const value_t &l)
tuple_element_t< I, valuesets_t > valueset_t
The Ith valueset type.
Provide a range that allows to iterate over the cross product of the provided ranges.
static constexpr bool has_one()
auto mul_(const LhsValue &l, const RhsValue &r, seq< I...>) const -> word_t
cross_sequences< Sequences...> cross(Sequences &&...seqs)
static void eat_separator_(std::istream &i)
Read the separator from the input stream i if I is not 0.
A structure that implements the computation of join(V1, V2).
tupleset_impl(ValueSets...ls)
static self_t make(std::istream &is)
Build from the description in is.
static size_t size(const value_t &v)
Get the max of the sizes of the tapes.
static constexpr bool is_letterized()
static bool is_special_(const value_t &l, seq< I...>)
auto join(const ValueSet &vs) -> ValueSet
The join of a single valueset.
static void convs(std::istream &, Fun)
static constexpr bool has_one_(seq< I...>)
letterized_t< LabelSet > make_letterized(const LabelSet &ls)
std::istringstream is
The input stream: the specification to translate.
std::ostream & print_set(std::ostream &o, format fmt={}) const
char eat(std::istream &is, char c)
Check lookahead character and advance.
static type value(const labelset_t &ls)
value_t ldiv(const value_t &l, const value_t &r) const
Pointwise left division (l \ r).
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
value_t zero_(seq< I...>) const
typename labelset_t::template valueset_t< Tape > type
Whether a ValueSet, or a context, is multitape.
typename std::enable_if< Cond, T >::type enable_if_t
ValueSet::value_t rdiv(const ValueSet &vs, const typename ValueSet::value_t &lhs, const typename ValueSet::value_t &rhs)
Right-division of values.
static std::size_t hash_(const value_t &v, seq< I...>)
static constexpr bool is_free_(seq< I...>)
static bool less_(const value_t &l, const value_t &r, seq< I...>)
static labelset_t labelset(const tupleset< LabelSets...> &ls)
static type value(const labelset_t &ls)
static bool is_one_(const value_t &l, seq< I...>)
static constexpr star_status_t star_status()
static type join(const vs1_t lhs, const vs2_t &rhs, index_sequence< I...>)
ValueSet::value_t tuple(const ValueSet &vs, const typename ValueSets::value_t &...v)
static std::string sname_(seq< I...>)
void hash_combine(std::size_t &seed, const T &v)
void print_(std::ostream &o, const T &arg, long)
Serialize arg into o.
static constexpr bool is_letterized_(seq< I...>)
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...
bool is_letter(const value_t &) const
static constexpr std::size_t size()
Number of tapes.
The type of the resulting apparent LabelSet when keeping only tape Tape.
bool open_(bool o, seq< I...>) const
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.
Value transpose(const Value &l) const
Transpose a word_t or a value_t.
value_t conv(std::istream &i, bool quoted=true) const
Read one label from i, return the corresponding value.
value_t value_(const std::tuple< Args...> &args, seq< I...>) const
Provide a variadic mul on top of a binary mul(), and one().
static type value(const tupleset< LabelSet > &ls)
fresh_automaton_t_of< Aut > star(const Aut &aut)
Star of a standard automaton.
typename project_labelset_impl< Tape, LabelSet >::type project_labelset
The type of the resulting apparent LabelSet when keeping only tape Tape.
static constexpr bool is_idempotent_(seq< I...>)
static bool less(const value_t &l, const value_t &r)
Whether l < r.
static bool equal(const value_t &l, const value_t &r)
Whether l equals r.
From a labelset, its non-nullable labelset.
law_t< LabelSet > make_wordset(const LabelSet &ls)
The wordset of a labelset.
A traits so that tupleset may define types that may exist.
value_t conv_(const tupleset< VS...> &vs, const typename tupleset< VS...>::value_t &v, seq< I...>) const
std::tuple< typename ValueSets::value_t...> value_t
A tuple of values.
value_t conv_(std::istream &i, bool quoted, std::false_type) const
Read a tuple in the stream, possibly parenthesized.
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
typename std::tuple_element< I, T >::type tuple_element_t
C++14.
auto word(const std::tuple< Args...> &v) const -> word_t
Convert to a word.
value_t tuple(Args &&...args) const
Construct a value.
static self_t make_(std::istream &i, seq< I...>)
Value undelimit_(const Value &l, seq< I...>) const
const valueset_t< I > & set() const
The Ith component valueset.
static constexpr bool is_commutative_(seq< I...>)
value_t lgcd_(const value_t &l, const value_t &r, seq< I...>) const
static size_t size_(const value_t &v, seq< I...>)
decltype(std::declval< LabelSet >().genset()) genset_t
static bool is_special(const value_t &l)
A ValueSet which is a Cartesian product of ValueSets.
Value delimit(const Value &l) const
Add the special character first and last.
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...
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
static constexpr bool is_free()
value_t star(const value_t &l) const
static type value(const labelset_t &ls, index_sequence< I...>)
std::tuple< typename ValueSets::letter_t...> letter_t
value_t star_(const value_t &l, seq< I...>) const
letter_t value_type
To be iterable.
static auto one_(seq< I...>) -> decltype(value_t
bool is_zero(const value_t &l) const
value_t add_(const value_t &l, const value_t &r, seq< I...>) const
The smallest nullableset which includes LabelSet.
vcsn::enable_if_t<!is_letterized_t< labelset_t_of< Aut > >{}, bool > is_letterized(const Aut &aut)
static value_t conv(self_t, value_t v)
Value undelimit(const Value &l) const
Remove first and last characters, that must be "special".
typename labelset_types< ValueSets...>::letter_t letter_t
A tuple of letters if meaningful, void otherwise.
value_t lgcd(const value_t &l, const value_t &r) const
The pointwise LGCD.
Value delimit_(const Value &l, seq< I...>) const
static bool equal_(const value_t &l, const value_t &r, seq< I...>)
static bool show_one_(seq< I...>)
bool open(bool o) const
Whether unknown letters should be added, or rejected.
value_t conv(b, b::value_t v) const
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.
static auto one() -> decltype(one_(Indices
A tuple of ones.
static size_t hash(const value_t &v)
value_t add(const value_t &l, const value_t &r) const
Pointwise addition.
valueset_t< 0 >::value_t lnormalize_here(value_t &v) const
Eliminate the LGCD between all the tapes.
std::ostream & print_set_(std::ostream &o, format fmt, seq< I...>) const
std::ostream & print_(const value_t &l, std::ostream &o, format fmt, const char *pre, const char *sep, const char *post, seq< I...>) const
static type join(const vs1_t &lhs, const vs2_t &rhs)
The resulting valueset.
typename labelset_types< ValueSets...>::genset_t genset_t
A tuple of gensets if meaningful, void otherwise.
tupleset_impl(valuesets_t vs)
word_t word_(const std::tuple< Args...> &l, seq< I...>) const
std::integral_constant< bool, B > bool_constant
bool is_zero_(const value_t &l, seq< I...>) const
context join(const context &c1, const context &c2)
Bridge.
ValueSet::value_t lgcd(const ValueSet &vs, const typename ValueSet::value_t &lhs, const typename ValueSet::value_t &rhs)
Left-division of values.
value_t conv_(std::istream &i, bool quoted, seq< I...>) const
static value_t special_(seq< I...>)
typename labelset_types< ValueSets...>::word_t word_t
A tuple of words if meaningful, void otherwise.
std::tuple< typename ValueSets::word_t...> word_t
static labelset_t labelset_(const tupleset< LabelSets...> &ls, seq< I...>)
static constexpr bool is_expressionset_(seq< I...>)
static constexpr bool is_commutative()
genset_t genset() const
The generators. Meaningful for labelsets only.
auto mul(const LhsValue &l, const RhsValue &r) const -> word_t
The product (possibly concatenation) of l and r.
bool is_letterized(const Aut &aut)
Check if the transitions are all letters.
value_t ldiv_(const value_t &l, const value_t &r, seq< I...>) const
constant< type_t::one, Context > one
static type value(const labelset_t &ls)
Implementation of labels are nullables (letter or empty).
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.
genset_t genset_(seq< I...>) const