Vcsn  2.8
Be Rational
letterset.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <memory>
4 
5 #include <boost/optional.hpp>
6 
7 #include <vcsn/alphabets/setalpha.hh> // intersection
8 #include <vcsn/core/kind.hh>
12 #include <vcsn/labelset/wordset.hh>
13 #include <vcsn/misc/attributes.hh>
14 #include <vcsn/misc/escape.hh>
15 #include <vcsn/misc/raise.hh>
16 #include <vcsn/misc/set.hh> // intersection
17 
18 namespace vcsn
19 {
21  template <typename GenSet>
22  class letterset: public detail::genset_labelset<GenSet>
23  {
24  public:
25  using genset_t = GenSet;
27  using self_t = letterset;
28  using genset_ptr = std::shared_ptr<const genset_t>;
29 
30  using letter_t = typename genset_t::letter_t;
31  using word_t = typename genset_t::word_t;
32 
33  using value_t = letter_t;
34  using values_t = std::set<value_t, vcsn::less<self_t>>;
35 
37 
38  letterset(const genset_ptr& gs)
39  : super_t{gs}
40  {}
41 
42  letterset(const genset_t& gs = {})
43  : letterset(std::make_shared<const genset_t>(gs))
44  {}
45 
46  letterset(std::initializer_list<letter_t> letters)
47  : letterset(std::make_shared<const genset_t>(letters))
48  {}
49 
50  static symbol sname()
51  {
52  static auto res = symbol{"letterset<" + super_t::sname() + '>'};
53  return res;
54  }
55 
57  static letterset make(std::istream& is)
58  {
59  // name: letterset<char_letters(abc)>.
60  // ^^^^^^^^^ ^^^^^^^^^^^^^^^^^
61  // kind genset
62  eat(is, "letterset<");
63  auto gs = genset_t::make(is);
64  eat(is, '>');
65  return gs;
66  }
67 
71  bool open(bool o) const
72  {
73  return this->genset()->open(o);
74  }
75 
76  static constexpr bool is_free()
77  {
78  return true;
79  }
80 
81  auto generators() const
82  {
83  return super_t::generators();
84  }
85 
86  auto pregenerators() const
87  {
88  return super_t::generators();
89  }
90 
92  template <typename... Args>
93  value_t value(Args&&... args) const
94  {
95  return value_t{std::forward<Args>(args)...};
96  }
97 
99  static word_t word(value_t v)
100  {
101  return {v};
102  }
103 
105  static word_t
107  {
108  return v;
109  }
110 
113  static word_t
115  {
116  return v;
117  }
118 
120  static word_t
122  {
123  return word(v);
124  }
125 
128  static word_t
130  {
131  return word(v);
132  }
133 
134 
135  static value_t
136  special() ATTRIBUTE_PURE
137  {
138  return genset_t::template special<value_t>();
139  }
140 
142  static int compare(const value_t l, const value_t r)
143  {
144  return genset_t::compare(l, r);
145  }
146 
148  static bool
149  equal(const value_t l, const value_t r)
150  {
151  return genset_t::equal(l, r);
152  }
153 
155  static bool less(const value_t l, const value_t r)
156  {
157  return genset_t::less(l, r);
158  }
159 
160  static constexpr bool
162  {
163  return false;
164  }
165 
166  static constexpr bool
168  {
169  return false;
170  }
171 
172  static constexpr bool
174  {
175  return true;
176  }
177 
178  static bool
179  is_special(value_t v) ATTRIBUTE_PURE
180  {
181  return v == special();
182  }
183 
184  static constexpr bool
186  {
187  return false;
188  }
189 
190  bool
192  {
193  return this->has(v);
194  }
195 
196  static size_t size(value_t)
197  {
198  return 1;
199  }
200 
201  static size_t hash(value_t v)
202  {
203  return hash_value(v);
204  }
205 
206  value_t
208  {
210  *this, ": conv: invalid label: ", str_escape(v));
211  return v;
212  }
213 
215  template <typename LabelSet_>
216  value_t
218  typename nullableset<LabelSet_>::value_t v) const
219  {
220  require(!ls.is_one(v),
221  *this, ": conv: invalid label: \\e");
222  return conv(*ls.labelset(), ls.get_value(v));
223  }
224 
226  value_t
227  conv(std::istream& i, bool quoted = true) const
228  {
229  // Check for '\e', to generate a nicer error message than the
230  // one from get_letter.
231  if (i.good() && i.peek() == '\\')
232  {
233  i.ignore();
234  require(i.peek() != 'e',
235  *this, ": cannot represent \\e");
236  !i.unget();
237  }
238  return this->get_letter(i, quoted);
239  }
240 
250  template <typename Fun>
251  void convs(std::istream& i, Fun fun) const
252  {
253  this->convs_(i, fun);
254  }
255 
272  value_t lgcd(const value_t l, const value_t r) const
273  {
274  raise(*this, ": lgcd: impossible operation. Arguments: ",
275  to_string(*this, l), ", ", to_string(*this, r));
276  }
277 
279  value_t ldivide(const value_t l, const value_t r) const
280  {
281  raise(*this, ": ldivide: impossible operation. Arguments: ",
282  to_string(*this, l), ", ", to_string(*this, r));
283  }
284 
285  boost::optional<value_t>
286  maybe_ldivide(const value_t l, const value_t r) const
287  {
288  raise(*this, ": maybe_ldivide: impossible operation. Arguments: ",
289  to_string(*this, l), ", ", to_string(*this, r));
290  }
291 
293  value_t rdivide(const value_t l, const value_t r) const
294  {
295  raise(*this, ": rdivide: impossible operation. Arguments: ",
296  to_string(*this, l), ", ", to_string(*this, r));
297  }
298 
299  boost::optional<value_t>
300  maybe_rdivide(const value_t l, const value_t r) const
301  {
302  raise(*this, ": maybe_rdivide: impossible operation. Arguments: ",
303  to_string(*this, l), ", ", to_string(*this, r));
304  }
305 
306 
307  value_t conjunction(const value_t l, const value_t r) const
308  {
309  if (equal(l, r))
310  return l;
311  else
312  raise("conjunction: invalid operation (lhs and rhs are not equal)."
313  " Arguments: ",
314  to_string(*this, l), ", ", to_string(this, r));
315  }
316 
317  std::ostream&
318  print(const value_t& l, std::ostream& o = std::cout,
319  format fmt = {}) const
320  {
321  return this->genset()->print(l, o, fmt);
322  }
323 
324  std::ostream&
325  print_set(std::ostream& o, format fmt = {}) const
326  {
327  switch (fmt.kind())
328  {
329  case format::latex:
330  this->genset()->print_set(o, fmt);
331  break;
332  case format::sname:
333  o << "letterset<";
334  this->genset()->print_set(o, fmt);
335  o << '>';
336  break;
337  case format::text:
338  case format::utf8:
339  this->genset()->print_set(o, fmt);
340  break;
341  case format::raw:
342  assert(0);
343  break;
344  }
345  return o;
346  }
347  };
348 
349  namespace detail
350  {
352  template <typename GenSet>
353  struct letterized_traits<letterset<GenSet>>
354  {
355  static constexpr bool is_letterized = true;
356 
357  using labelset_t = nullableset<letterset<GenSet>>;
358 
359  static labelset_t labelset(const letterset<GenSet>& ls)
360  {
361  return {ls.genset()};
362  }
363  };
364 
366  template <typename GenSet>
367  struct nullableset_traits<letterset<GenSet>>
368  {
369  using type = nullableset<letterset<GenSet>>;
370  static type value(const letterset<GenSet>& ls)
371  {
372  return ls;
373  }
374  };
375 
377  template <typename GenSet>
378  struct law_traits<letterset<GenSet>>
379  {
380  using type = wordset<GenSet>;
381  static type value(const letterset<GenSet>& ls)
382  {
383  return ls.genset();
384  }
385  };
386 
387  /*-------.
388  | Join. |
389  `-------*/
390 
391  template <typename GenSet>
392  struct join_impl<letterset<GenSet>, letterset<GenSet>>
393  {
394  using type = letterset<GenSet>;
395  static type join(const letterset<GenSet>& lhs,
396  const letterset<GenSet>& rhs)
397  {
398  return {set_union(*lhs.genset(), *rhs.genset())};
399  }
400  };
401  }
402 
404  template <typename GenSet>
405  letterset<GenSet>
406  meet(const letterset<GenSet>& lhs, const letterset<GenSet>& rhs)
407  {
408  return {set_intersection(*lhs.genset(), *rhs.genset())};
409  }
410 }
Print as a parsable type string.
Definition: format.hh:26
std::ostream & print(const value_t &l, std::ostream &o=std::cout, format fmt={}) const
Definition: letterset.hh:318
static bool equal(const value_t l, const value_t r)
Whether l == r.
Definition: letterset.hh:149
static value_t special() ATTRIBUTE_PURE
Definition: letterset.hh:136
Implementation of labels are letters.
Definition: fwd.hh:10
auto generators(Args &&... args) const -> decltype(this->genset() -> generators(std::forward< Args >(args)...))
value_t conv(const nullableset< LabelSet_ > &ls, typename nullableset< LabelSet_ >::value_t v) const
Convert from nullableset to letterset.
Definition: letterset.hh:217
static word_t letters_of_padded(letter_t v, letter_t)
Prepare to iterate over v.
Definition: letterset.hh:129
boost::optional< value_t > maybe_rdivide(const value_t l, const value_t r) const
Definition: letterset.hh:300
char eat(std::istream &is, char c)
Check lookahead character and advance.
Definition: stream.cc:147
typename genset_t::word_t word_t
value_t rdivide(const value_t l, const value_t r) const
Compute w1 / w2.
Definition: letterset.hh:293
value_t conv(std::istream &i, bool quoted=true) const
Read one letter from i, return the corresponding label.
Definition: letterset.hh:227
static int compare(const value_t l, const value_t r)
Three-way comparison between l and r.
Definition: letterset.hh:142
auto pregenerators() const
Definition: letterset.hh:86
static constexpr bool is_one(value_t)
Definition: letterset.hh:185
letter_t value_t
Definition: letterset.hh:33
letterset(std::initializer_list< letter_t > letters)
Definition: letterset.hh:46
auto generators() const
Definition: letterset.hh:81
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
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
Definition: symbol.hh:21
static constexpr bool is_free()
Definition: letterset.hh:76
static word_t letters_of(letter_t v)
Prepare to iterate over v.
Definition: letterset.hh:121
value_t value(Args &&... args) const
Value constructor.
Definition: letterset.hh:93
std::ostream & print_set(std::ostream &o, format fmt={}) const
Definition: letterset.hh:325
bool open(bool o) const
Whether unknown letters should be added, or rejected.
Definition: letterset.hh:71
bool is_valid(value_t v) const
Definition: letterset.hh:191
value_t conjunction(const value_t l, const value_t r) const
Definition: letterset.hh:307
static bool is_special(value_t v) ATTRIBUTE_PURE
Definition: letterset.hh:179
An input/output format for valuesets.
Definition: format.hh:13
static symbol sname()
Definition: letterset.hh:50
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
static constexpr bool is_letterized()
Definition: letterset.hh:173
static constexpr bool has_one()
Definition: letterset.hh:161
void convs(std::istream &i, Fun fun) const
Process a label class.
Definition: letterset.hh:251
value_t ldivide(const value_t l, const value_t r) const
Compute w1 \ w2 = w1^{-1}w2.
Definition: letterset.hh:279
typename helper_t::value_t value_t
Definition: nullableset.hh:187
static size_t hash(value_t v)
Definition: letterset.hh:201
auto hash_value(const T &v) -> decltype(std::hash< T >
Following the naming convention of Boost.
Definition: functional.hh:45
This class has no modeling purpose, it only serves to factor code common to letterset and wordset...
ATTRIBUTE_PURE auto has(Args &&... args) const -> decltype(this->genset() -> has(std::forward< Args >(args)...))
value_t lgcd(const value_t l, const value_t r) const
The longest common prefix.
Definition: letterset.hh:272
Implementation of labels are nullables (letter or empty).
Definition: fwd.hh:14
static bool less(const value_t l, const value_t r)
Whether l < r.
Definition: letterset.hh:155
Definition: a-star.hh:8
std::set< value_t, vcsn::less< self_t > > values_t
Definition: letterset.hh:34
const labelset_ptr labelset() const
Definition: nullableset.hh:325
static constexpr bool is_expressionset()
Definition: letterset.hh:167
static letterset make(std::istream &is)
Build from the description in is.
Definition: letterset.hh:57
static ATTRIBUTE_PURE bool is_one(value_t l)
Definition: nullableset.hh:270
typename genset_t::letter_t letter_t
letter_t get_letter(std::istream &i, bool quoted=true) const
Read one letter from i.
static word_t letters_of_padded(word_t v, letter_t)
Prepare to iterate over the letters of v.
Definition: letterset.hh:114
letterset(const genset_ptr &gs)
Definition: letterset.hh:38
return v
Definition: multiply.hh:362
Print for LaTeX.
Definition: format.hh:22
void convs_(std::istream &i, Fun fun) const
Read and process a class of letters.
typename genset_t::letter_t letter_t
Definition: letterset.hh:30
static size_t size(value_t)
Definition: letterset.hh:196
std::shared_ptr< const genset_t > genset_ptr
void require(Bool b, Args &&... args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:87
std::string to_string(direction d)
Conversion to string.
Definition: direction.cc:7
value_t conv(self_t, value_t v) const
Definition: letterset.hh:207
STL namespace.
static word_t letters_of(word_t v)
Prepare to iterate over the letters of v.
Definition: letterset.hh:106
#define VCSN_REQUIRE(Cond,...)
A macro similar to require.
Definition: raise.hh:98
int compare(const Lhs &lhs, const Rhs &rhs)
Comparison between lhs and rhs.
letterset(const genset_t &gs={})
Definition: letterset.hh:42
static word_t word(value_t v)
Convert to a word.
Definition: letterset.hh:99
return res
Definition: multiply.hh:399
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:615
boost::optional< value_t > maybe_ldivide(const value_t l, const value_t r) const
Definition: letterset.hh:286