6 #include <boost/optional.hpp> 28 template <
typename LabelSet>
32 using value_t = std::pair<typename labelset_t::value_t, bool>;
38 return value_t{labelset_t::special(),
true};
45 return value_t{labelset_t::special(),
false};
48 template <
typename Ls>
50 static std::enable_if_t<Ls::has_one(), bool>
53 return std::get<1>(l) || Ls::is_one(
get_value(l));
56 template <
typename Ls>
58 static std::enable_if_t<!Ls::has_one(), bool>
61 return std::get<1>(l);
68 return is_one_<labelset_t>(l);
71 template <
typename Value>
81 return {ls.transpose(
get_value(l)),
false};
84 template <
typename... Args>
88 return {ls.value(std::forward<Args>(args)...),
false};
92 static typename labelset_t::value_t
95 return std::get<0>(
v);
100 return ls.generators();
105 return ls.pregenerators();
115 template <
typename GenSet>
126 return genset_t::special();
133 return genset_t::one_letter();
143 template <
typename Value>
150 template <
typename... Args>
154 return ls.
value(std::forward<Args>(args)...);
171 return ls.
genset()->pregenerators();
177 template <
typename LabelSet>
189 using word_t =
typename labelset_t::word_t;
206 :
nullableset{std::make_shared<const labelset_t>(ls)}
224 eat(is,
"nullableset<");
225 auto ls = labelset_t::make(is);
235 return this->ls_->open(o);
238 static constexpr
bool 244 static constexpr
bool 250 static constexpr
bool 272 return helper_t::is_one(l);
284 return ls_->genset();
291 return helper_t::generators(*ls_);
298 return helper_t::pregenerators(*ls_);
305 *
this,
": conv: invalid label: ",
to_string(*
this, v));
318 template <
typename LabelSet_>
320 conv(
const LabelSet_& ls,
typename LabelSet_::value_t
v)
const 322 return value(ls_->conv(ls, v));
330 template <
typename... Args>
334 return helper_t::value(*ls_, std::forward<Args>(args)...);
349 -> decltype(labelset_t::letters_of(
v))
351 return labelset_t::letters_of(
v);
358 -> decltype(ls_->letters_of_padded(
v, l))
360 return ls_->letters_of_padded(
v, l);
365 -> decltype(this->letters_of_padded(this->word(
v), l))
367 return letters_of_padded(word(
v), l);
407 raise(*
this,
": mul: invalid arguments: ",
425 if (
auto res = maybe_ldivide(l, r))
428 raise(*
this,
": ldivide: invalid arguments: ",
432 boost::optional<value_t>
450 if (
auto res = maybe_rdivide(l, r))
453 raise(*
this,
": rdivide: invalid arguments: ",
457 boost::optional<value_t>
475 return helper_t::special();
499 return ls_->get_letter(i, quoted);
504 conv(std::istream& i,
bool quoted =
true)
const 507 if (i.good() && i.peek() ==
'\\')
519 return value(ls_->conv(i, quoted));
531 template <
typename Fun>
532 void convs(std::istream& i, Fun&& fun)
const 535 [
this,fun](
const typename labelset_t::value_t& l)
549 ": conjunction: invalid operation (lhs and rhs are not equal): ",
574 template <
typename Value>
589 ls_->print_set(o, fmt);
595 ls_->print_set(o, fmt);
601 ls_->print_set(o, fmt); 614 static typename labelset_t::value_t 615 get_value(const value_t& v) 618 return helper_t::get_value(v); 625 template <typename LabelSet> 626 struct letterized_traits<nullableset<LabelSet>> 628 using traits = letterized_traits<LabelSet>; 629 static constexpr bool is_letterized = traits::is_letterized; 631 using labelset_t = typename traits::labelset_t; 633 static labelset_t labelset(const nullableset<LabelSet>& ls) 635 return make_letterized(*ls.labelset()); 640 template <typename LabelSet> 641 struct nullableset_traits<nullableset<LabelSet>> 643 using type = nullableset<LabelSet>; 644 static type value(const nullableset<LabelSet>& ls) 650 template <typename LabelSet> 651 struct proper_traits<nullableset<LabelSet>> 653 using type = LabelSet; 654 static type value(const nullableset<LabelSet>& ls) 656 return *ls.labelset(); 661 template <typename LabelSet> 662 struct law_traits<nullableset<LabelSet>> 664 using type = law_t<LabelSet>; 665 static type value(const nullableset<LabelSet>& ls) 667 return make_wordset(*ls.labelset()); 676 template <typename LS> 677 struct join_impl<oneset, LS, 678 std::enable_if_t<!LS::has_one()>> 680 using type = nullableset<LS>; 681 static type join(const oneset&, const LS& ls) 688 template <typename LS> 689 struct join_impl<oneset, LS, 690 std::enable_if_t<LS::has_one()>> 693 static type join(const oneset&, const LS& ls) 700 template <typename LS1, typename LS2> 701 struct join_impl<nullableset<LS1>, LS2> 703 using type = std::conditional_t<LS2::has_one(), 705 nullableset<join_t<LS1, LS2>>>; 706 static type join(const nullableset<LS1>& ls1, const LS2& ls2) 708 return {::vcsn::join(*ls1.labelset(), ls2)}; 716 template <typename LS1, typename LS2> 717 struct join_impl<nullableset<LS1>, nullableset<LS2>> 719 using type = nullableset<join_t<LS1, LS2>>; 720 static type join(const nullableset<LS1>& ls1, 721 const nullableset<LS2>& ls2) 723 return {::vcsn::join(*ls1.labelset(), *ls2.labelset())}; 732 #define DEFINE(Lhs, Rhs, Res) \ 733 template <typename GenSet> \ 735 meet(const Lhs& lhs, const Rhs& rhs) \ 737 return {set_intersection(*lhs.genset(), *rhs.genset())}; \ 741 DEFINE(nullableset<letterset<GenSet>>, 742 nullableset<letterset<GenSet>>, nullableset<letterset<GenSet>>); 744 DEFINE(letterset<GenSet>, 745 nullableset<letterset<GenSet>>, nullableset<letterset<GenSet>>); 747 DEFINE(nullableset<letterset<GenSet>>, 748 letterset<GenSet>, nullableset<letterset<GenSet>>); 750 template <typename Lls, typename Rls> 751 nullableset<meet_t<Lls, Rls>> 752 meet(const nullableset<Lls>& lhs, const nullableset<Rls>& rhs) 754 return nullableset<meet_t<Lls, Rls>>{meet(*lhs.labelset(), 766 template <typename LabelSet, 767 typename RandomGenerator = std::default_random_engine> 768 typename nullableset<LabelSet>::value_t 769 random_label(const nullableset<LabelSet>& ls, 770 RandomGenerator& gen = RandomGenerator()) 772 // FIXME: the proportion should be controllable. 773 auto dis = std::bernoulli_distribution(0.5); 774 if (dis(gen) || ls.generators().empty()) 777 return ls.value(random_label(*ls.labelset(), gen)); genset_ptr genset() const
Aut transpose(const transpose_automaton< Aut > &aut)
The transpose of a transpose automaton is the original automaton.
std::pair< typename labelset_t::value_t, bool > value_t
nullableset(const labelset_ptr &ls)
static Value transpose(const labelset_t &ls, const Value &l)
static auto generators(const labelset_t &ls)
Implementation of labels are ones: there is a single instance of label.
Print as a parsable type string.
value_t conjunction(const value_t &l, const value_t &r) const
static ATTRIBUTE_PURE constexpr value_t one()
value_t rdivide(const value_t &l, const value_t &r) const
Compute l / r.
weightset_mixin< detail::r_impl > r
static ATTRIBUTE_PURE constexpr value_t one()
typename labelset_t::letter_t letter_t
bool is_valid(const Aut &aut)
Value transpose(const Value &l) const
Mirror label.
static ATTRIBUTE_PURE constexpr value_t special()
static ATTRIBUTE_PURE std::enable_if_t< Ls::has_one(), bool > is_one_(const value_t &l)
decltype(ls_->generators()) genset_t
static auto generators(const labelset_t &ls)
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
value_t lgcd(const value_t &l, const value_t &r) const
The longest common prefix.
Implementation of labels are letters.
static constexpr bool has_one()
value_t ldivide(const value_t &l, const value_t &r) const
Compute l \ r = l^{-1}r.
char eat(std::istream &is, char c)
Check lookahead character and advance.
value_t conv(oneset, typename oneset::value_t) const
nullableset(const labelset_t &ls={})
boost::optional< value_t > maybe_ldivide(const value_t &l, const value_t &r) const
bool is_letter(const value_t &v) const
void convs(std::istream &i, Fun &&fun) const
Process a label class.
bool is_special(const Aut &aut, transition_t_of< Aut > t)
Whether this transition is from pre or to post.
static constexpr bool is_letterized()
constant< type_t::one, Context > one
static ATTRIBUTE_PURE labelset_t::value_t get_value(const value_t &v)
static auto pregenerators(const labelset_t &ls)
Add support for an empty word to a LabelSet that does not provide such special label to this end...
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
static int compare(const value_t &l, const value_t &r)
Three way comparison between l and r.
static bool equal(const value_t &l, const value_t &r)
Whether l == r.
value_t value(Args &&... args) const
Value constructor.
static ATTRIBUTE_PURE value_t get_value(const value_t &v)
static size_t size(const value_t &v)
static nullableset make(std::istream &is)
Build from the description in is.
Print as rich UTF-8 text, escaped.
An input/output format for valuesets.
Provide a variadic mul on top of a binary mul(), and one().
word_t word(const value_t &l) const
static constexpr bool is_free()
value_t mul(const value_t &l, const value_t &r) const
The concatenation.
typename helper_t::value_t value_t
static ATTRIBUTE_PURE bool is_one(const value_t &l)
bool is_valid(value_t v) const
Implementation of labels are nullables (letter or empty).
static auto letters_of(const word_t &v) -> decltype(labelset_t::letters_of(v))
Prepare to iterate over the letters of v.
value_t conv(const LabelSet_ &ls, typename LabelSet_::value_t v) const
Conversion from another type: first by the wrapped labelset, and then by our wrappers (in case the wr...
std::ostream & print(const value_t &l, std::ostream &o=std::cout, format fmt={}) const
Print label to stream.
const labelset_ptr labelset() const
static ATTRIBUTE_PURE bool is_one(value_t l)
labelset_ptr ls_
The wrapped LabelSet.
bool open(bool o) const
Whether unknown letters should be added, or rejected.
genset_ptr genset() const
static ATTRIBUTE_PURE bool is_one(value_t l)
std::shared_ptr< const labelset_t > labelset_ptr
ATTRIBUTE_PURE auto transpose(Args &&... args) const -> decltype(this->genset() -> transpose(std::forward< Args >(args)...))
letter_t get_letter(std::istream &i, bool quoted=true) const
value_t conv(self_t, value_t v) const
static ATTRIBUTE_PURE constexpr value_t one()
auto letters_of_padded(value_t v, letter_t l) const -> decltype(this->letters_of_padded(this->word(v), l))
static constexpr bool is_expressionset()
static value_t value(const labelset_t &ls, Args &&... args)
law_t< LabelSet > make_wordset(const LabelSet &ls)
The wordset of a labelset.
static ATTRIBUTE_PURE constexpr value_t special()
typename labelset_t::value_t value_t
typename labelset_t::word_t word_t
std::ostream & print_set(std::ostream &o, format fmt={}) const
Print labelset description.
decltype(ls_->genset()) genset_ptr
value_t value(Args &&... args) const
static size_t hash(const value_t &v)
boost::optional< value_t > maybe_rdivide(const value_t &l, const value_t &r) const
auto letters_of_padded(const word_t &v, letter_t l) const -> decltype(ls_->letters_of_padded(v, l))
Prepare to iterate over the letters of v.
std::string to_string(direction d)
Conversion to string.
static bool is_special(const value_t &v)
static bool less(const value_t &l, const value_t &r)
Whether l < r.
std::enable_if_t<!is_letterized_t< labelset_t_of< Aut > >{}, bool > is_letterized(const Aut &aut)
static auto pregenerators(const labelset_t &ls)
static value_t value(const labelset_t &ls, Args &&... args)
#define VCSN_REQUIRE(Cond,...)
A macro similar to require.
int compare(const Lhs &lhs, const Rhs &rhs)
Comparison between lhs and rhs.
static ATTRIBUTE_PURE std::enable_if_t<!Ls::has_one(), bool > is_one_(const value_t &l)
value_t conv(std::istream &i, bool quoted=true) const
Read a label from a stream.
static Value transpose(const labelset_t &ls, Value l)