Vcsn  2.3
Be Rational
letterset.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <memory>
4 
5 #include <vcsn/alphabets/setalpha.hh> // intersection
6 #include <vcsn/core/kind.hh>
10 #include <vcsn/labelset/wordset.hh>
11 #include <vcsn/misc/attributes.hh>
12 #include <vcsn/misc/escape.hh>
13 #include <vcsn/misc/raise.hh>
14 #include <vcsn/misc/set.hh> // intersection
15 
16 namespace vcsn
17 {
19  template <typename GenSet>
20  class letterset: public detail::genset_labelset<GenSet>
21  {
22  public:
23  using genset_t = GenSet;
25  using self_t = letterset;
26  using genset_ptr = std::shared_ptr<const genset_t>;
27 
28  using letter_t = typename genset_t::letter_t;
29  using word_t = typename genset_t::word_t;
30  using letters_t = std::set<letter_t, vcsn::less<self_t, letter_t>>;
31 
32  using value_t = letter_t;
33  using values_t = std::set<value_t, vcsn::less<self_t>>;
34 
36 
37  letterset(const genset_ptr& gs)
38  : super_t{gs}
39  {}
40 
41  letterset(const genset_t& gs = {})
42  : letterset(std::make_shared<const genset_t>(gs))
43  {}
44 
45  letterset(std::initializer_list<letter_t> letters)
46  : letterset(std::make_shared<const genset_t>(letters))
47  {}
48 
49  static symbol sname()
50  {
51  static auto res = symbol{"letterset<" + super_t::sname() + '>'};
52  return res;
53  }
54 
56  static letterset make(std::istream& is)
57  {
58  // name: letterset<char_letters(abc)>.
59  // ^^^^^^^^^ ^^^^^^^^^^^^^^^^^
60  // kind genset
61  eat(is, "letterset<");
62  auto gs = genset_t::make(is);
63  eat(is, '>');
64  return gs;
65  }
66 
70  bool open(bool o) const
71  {
72  return this->genset()->open(o);
73  }
74 
75  static constexpr bool is_free()
76  {
77  return true;
78  }
79 
81  template <typename... Args>
82  value_t value(Args&&... args) const
83  {
84  return value_t{std::forward<Args>(args)...};
85  }
86 
88  static word_t word(value_t v)
89  {
90  return {v};
91  }
92 
94  static word_t
96  {
97  return v;
98  }
99 
102  static word_t
104  {
105  return v;
106  }
107 
109  static word_t
111  {
112  return word(v);
113  }
114 
117  static word_t
119  {
120  return word(v);
121  }
122 
123 
124  static value_t
125  special() ATTRIBUTE_PURE
126  {
127  return genset_t::template special<value_t>();
128  }
129 
131  static bool
132  equal(const value_t l, const value_t r)
133  {
134  return genset_t::equal(l, r);
135  }
136 
138  static bool less(const value_t l, const value_t r)
139  {
140  return genset_t::less(l, r);
141  }
142 
143  static constexpr bool
145  {
146  return false;
147  }
148 
149  static constexpr bool
151  {
152  return false;
153  }
154 
155  static constexpr bool
157  {
158  return true;
159  }
160 
161  static bool
162  is_special(value_t v) ATTRIBUTE_PURE
163  {
164  return v == special();
165  }
166 
167  static constexpr bool
169  {
170  return false;
171  }
172 
173  bool
175  {
176  return this->has(v);
177  }
178 
179  static size_t size(value_t)
180  {
181  return 1;
182  }
183 
184  static size_t hash(value_t v)
185  {
186  return hash_value(v);
187  }
188 
189  value_t
191  {
193  *this, ": conv: invalid label: ", str_escape(v));
194  return v;
195  }
196 
198  template <typename LabelSet_>
199  value_t
201  typename nullableset<LabelSet_>::value_t v) const
202  {
203  require(!ls.is_one(v),
204  *this, ": conv: invalid label: \\e");
205  return conv(*ls.labelset(), ls.get_value(v));
206  }
207 
209  value_t
210  conv(std::istream& i, bool quoted = true) const
211  {
212  // Check for '\e', to generate a nicer error message than the
213  // one from get_letter.
214  if (i.good() && i.peek() == '\\')
215  {
216  i.ignore();
217  require(i.peek() != 'e',
218  *this, ": cannot represent \\e");
219  !i.unget();
220  }
221  return this->get_letter(i, quoted);
222  }
223 
233  template <typename Fun>
234  void convs(std::istream& i, Fun fun) const
235  {
236  this->convs_(i, fun);
237  }
238 
256  {
257  raise(*this, ": lgcd: impossible operation");
258  }
259 
262  {
263  raise(*this, ": ldivide: impossible operation");
264  }
265 
266  value_t conjunction(const value_t& l, const value_t& r) const
267  {
268  if (equal(l, r))
269  return l;
270  else
271  raise("conjunction: invalid operation (lhs and rhs are not equal)");
272  }
273 
274  std::ostream&
275  print(const value_t& l, std::ostream& o = std::cout,
276  format fmt = {}) const
277  {
278  return this->genset()->print(l, o, fmt);
279  }
280 
281  std::ostream&
282  print_set(std::ostream& o, format fmt = {}) const
283  {
284  switch (fmt.kind())
285  {
286  case format::latex:
287  this->genset()->print_set(o, fmt);
288  break;
289  case format::sname:
290  o << "letterset<";
291  this->genset()->print_set(o, fmt);
292  o << '>';
293  break;
294  case format::text:
295  case format::utf8:
296  this->genset()->print_set(o, fmt);
297  break;
298  case format::raw:
299  assert(0);
300  break;
301  }
302  return o;
303  }
304  };
305 
306  namespace detail
307  {
309  template <typename GenSet>
310  struct letterized_traits<letterset<GenSet>>
311  {
312  static constexpr bool is_letterized = true;
313 
314  using labelset_t = nullableset<letterset<GenSet>>;
315 
316  static labelset_t labelset(const letterset<GenSet>& ls)
317  {
318  return {ls.genset()};
319  }
320  };
321 
323  template <typename GenSet>
324  struct nullableset_traits<letterset<GenSet>>
325  {
326  using type = nullableset<letterset<GenSet>>;
327  static type value(const letterset<GenSet>& ls)
328  {
329  return ls;
330  }
331  };
332 
334  template <typename GenSet>
335  struct law_traits<letterset<GenSet>>
336  {
337  using type = wordset<GenSet>;
338  static type value(const letterset<GenSet>& ls)
339  {
340  return ls.genset();
341  }
342  };
343 
344  /*-------.
345  | Join. |
346  `-------*/
347 
348  template <typename GenSet>
349  struct join_impl<letterset<GenSet>, letterset<GenSet>>
350  {
351  using type = letterset<GenSet>;
352  static type join(const letterset<GenSet>& lhs,
353  const letterset<GenSet>& rhs)
354  {
355  return {set_union(*lhs.genset(), *rhs.genset())};
356  }
357  };
358  }
359 
361  template <typename GenSet>
362  letterset<GenSet>
363  meet(const letterset<GenSet>& lhs, const letterset<GenSet>& rhs)
364  {
365  return {set_intersection(*lhs.genset(), *rhs.genset())};
366  }
367 }
return v
Definition: multiply.hh:361
static ATTRIBUTE_PURE bool is_one(value_t l)
Definition: nullableset.hh:246
value_t conv(std::istream &i, bool quoted=true) const
Read one letter from i, return the corresponding label.
Definition: letterset.hh:210
static size_t hash(value_t v)
Definition: letterset.hh:184
value_t ldivide(value_t, value_t) const
Compute w1 \ w2 = w1^{-1}w2.
Definition: letterset.hh:261
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
Definition: symbol.hh:23
STL namespace.
static value_t special() ATTRIBUTE_PURE
Definition: letterset.hh:125
static labelset_t::value_t get_value(const value_t &v)
The (inner) value when it (the outer value) is not one.
Definition: nullableset.hh:549
static word_t letters_of(letter_t v)
Prepare to iterate over v.
Definition: letterset.hh:110
std::shared_ptr< const genset_t > genset_ptr
std::ostream & print(const value_t &l, std::ostream &o=std::cout, format fmt={}) const
Definition: letterset.hh:275
std::ostream & str_escape(std::ostream &os, const std::string &str, const char *special=nullptr)
Output a string, escaping special characters.
Definition: escape.cc:51
Implementation of labels are letters.
Definition: fwd.hh:10
static bool equal(const value_t l, const value_t r)
Whether l == r.
Definition: letterset.hh:132
void convs(std::istream &i, Fun fun) const
Process a label class.
Definition: letterset.hh:234
typename helper_t::value_t value_t
Definition: nullableset.hh:166
letterset(const genset_ptr &gs)
Definition: letterset.hh:37
Print as a parsable type string.
Definition: format.hh:26
void require(Bool b, Args &&...args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:91
letter_t get_letter(std::istream &i, bool quoted=true) const
Read one letter from i.
static word_t letters_of_padded(letter_t v, letter_t)
Prepare to iterate over v.
Definition: letterset.hh:118
bool is_valid(value_t v) const
Definition: letterset.hh:174
Implementation of labels are nullables (letter or empty).
Definition: fwd.hh:14
void convs_(std::istream &i, Fun fun) const
Read and process a class of letters.
return res
Definition: multiply.hh:398
static constexpr bool has_one()
Definition: letterset.hh:144
auto hash_value(const T &v) -> decltype(std::hash< T >
Following the naming convention of Boost.
Definition: functional.hh:30
value_t lgcd(value_t, value_t) const
The longest common prefix.
Definition: letterset.hh:255
This class has no modeling purpose, it only serves to factor code common to letterset and wordset...
typename genset_t::letters_t letters_t
letter_t value_t
Definition: letterset.hh:32
value_t conjunction(const value_t &l, const value_t &r) const
Definition: letterset.hh:266
value_t conv(const nullableset< LabelSet_ > &ls, typename nullableset< LabelSet_ >::value_t v) const
Convert from nullableset to letterset.
Definition: letterset.hh:200
typename genset_t::word_t word_t
Definition: letterset.hh:29
static letterset make(std::istream &is)
Build from the description in is.
Definition: letterset.hh:56
static bool less(const value_t l, const value_t r)
Whether l < r.
Definition: letterset.hh:138
Definition: a-star.hh:8
value_t conv(self_t, value_t v) const
Definition: letterset.hh:190
#define VCSN_REQUIRE(Cond,...)
A macro similar to require.
Definition: raise.hh:111
static constexpr bool is_letterized()
Definition: letterset.hh:156
letterset(std::initializer_list< letter_t > letters)
Definition: letterset.hh:45
static constexpr bool is_expressionset()
Definition: letterset.hh:150
static constexpr bool is_free()
Definition: letterset.hh:75
An input/output format for valuesets.
Definition: format.hh:13
ATTRIBUTE_PURE auto has(Args &&...args) const -> decltype(this->genset() -> has(std::forward< Args >(args)...))
static size_t size(value_t)
Definition: letterset.hh:179
static word_t letters_of_padded(word_t v, letter_t)
Prepare to iterate over the letters of v.
Definition: letterset.hh:103
typename genset_t::word_t word_t
value_t value(Args &&...args) const
Value constructor.
Definition: letterset.hh:82
bool open(bool o) const
Whether unknown letters should be added, or rejected.
Definition: letterset.hh:70
static word_t letters_of(word_t v)
Prepare to iterate over the letters of v.
Definition: letterset.hh:95
typename genset_t::letter_t letter_t
static symbol sname()
Definition: letterset.hh:49
static word_t word(value_t v)
Convert to a word.
Definition: letterset.hh:88
static bool is_special(value_t v) ATTRIBUTE_PURE
Definition: letterset.hh:162
Print for LaTeX.
Definition: format.hh:22
static constexpr bool is_one(value_t)
Definition: letterset.hh:168
letterset(const genset_t &gs={})
Definition: letterset.hh:41
const labelset_ptr labelset() const
Definition: nullableset.hh:292
typename genset_t::letter_t letter_t
Definition: letterset.hh:28
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
char eat(std::istream &is, char c)
Check lookahead character and advance.
Definition: stream.cc:90
std::set< value_t, vcsn::less< self_t >> values_t
Definition: letterset.hh:33
std::ostream & print_set(std::ostream &o, format fmt={}) const
Definition: letterset.hh:282