Vcsn  2.4
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 
82  template <typename... Args>
83  value_t value(Args&&... args) const
84  {
85  return value_t{std::forward<Args>(args)...};
86  }
87 
89  static word_t word(value_t v)
90  {
91  return {v};
92  }
93 
95  static word_t
97  {
98  return v;
99  }
100 
103  static word_t
105  {
106  return v;
107  }
108 
110  static word_t
112  {
113  return word(v);
114  }
115 
118  static word_t
120  {
121  return word(v);
122  }
123 
124 
125  static value_t
126  special() ATTRIBUTE_PURE
127  {
128  return genset_t::template special<value_t>();
129  }
130 
132  static bool
133  equal(const value_t l, const value_t r)
134  {
135  return genset_t::equal(l, r);
136  }
137 
139  static bool less(const value_t l, const value_t r)
140  {
141  return genset_t::less(l, r);
142  }
143 
144  static constexpr bool
146  {
147  return false;
148  }
149 
150  static constexpr bool
152  {
153  return false;
154  }
155 
156  static constexpr bool
158  {
159  return true;
160  }
161 
162  static bool
163  is_special(value_t v) ATTRIBUTE_PURE
164  {
165  return v == special();
166  }
167 
168  static constexpr bool
170  {
171  return false;
172  }
173 
174  bool
176  {
177  return this->has(v);
178  }
179 
180  static size_t size(value_t)
181  {
182  return 1;
183  }
184 
185  static size_t hash(value_t v)
186  {
187  return hash_value(v);
188  }
189 
190  value_t
192  {
194  *this, ": conv: invalid label: ", str_escape(v));
195  return v;
196  }
197 
199  template <typename LabelSet_>
200  value_t
202  typename nullableset<LabelSet_>::value_t v) const
203  {
204  require(!ls.is_one(v),
205  *this, ": conv: invalid label: \\e");
206  return conv(*ls.labelset(), ls.get_value(v));
207  }
208 
210  value_t
211  conv(std::istream& i, bool quoted = true) const
212  {
213  // Check for '\e', to generate a nicer error message than the
214  // one from get_letter.
215  if (i.good() && i.peek() == '\\')
216  {
217  i.ignore();
218  require(i.peek() != 'e',
219  *this, ": cannot represent \\e");
220  !i.unget();
221  }
222  return this->get_letter(i, quoted);
223  }
224 
234  template <typename Fun>
235  void convs(std::istream& i, Fun fun) const
236  {
237  this->convs_(i, fun);
238  }
239 
256  value_t lgcd(const value_t l, const value_t r) const
257  {
258  raise(*this, ": lgcd: impossible operation. Arguments: ",
259  to_string(*this, l), ", ", to_string(*this, r));
260  }
261 
263  value_t ldivide(const value_t l, const value_t r) const
264  {
265  raise(*this, ": ldivide: impossible operation. Arguments: ",
266  to_string(*this, l), ", ", to_string(*this, r));
267  }
268 
269  boost::optional<value_t>
270  maybe_ldivide(const value_t l, const value_t r) const
271  {
272  raise(*this, ": maybe_ldivide: impossible operation. Arguments: ",
273  to_string(*this, l), ", ", to_string(*this, r));
274  }
275 
277  value_t rdivide(const value_t l, const value_t r) const
278  {
279  raise(*this, ": rdivide: impossible operation. Arguments: ",
280  to_string(*this, l), ", ", to_string(*this, r));
281  }
282 
283  boost::optional<value_t>
284  maybe_rdivide(const value_t l, const value_t r) const
285  {
286  raise(*this, ": maybe_rdivide: impossible operation. Arguments: ",
287  to_string(*this, l), ", ", to_string(*this, r));
288  }
289 
290 
291  value_t conjunction(const value_t l, const value_t r) const
292  {
293  if (equal(l, r))
294  return l;
295  else
296  raise("conjunction: invalid operation (lhs and rhs are not equal)."
297  " Arguments: ",
298  to_string(*this, l), ", ", to_string(this, r));
299  }
300 
301  std::ostream&
302  print(const value_t& l, std::ostream& o = std::cout,
303  format fmt = {}) const
304  {
305  return this->genset()->print(l, o, fmt);
306  }
307 
308  std::ostream&
309  print_set(std::ostream& o, format fmt = {}) const
310  {
311  switch (fmt.kind())
312  {
313  case format::latex:
314  this->genset()->print_set(o, fmt);
315  break;
316  case format::sname:
317  o << "letterset<";
318  this->genset()->print_set(o, fmt);
319  o << '>';
320  break;
321  case format::text:
322  case format::utf8:
323  this->genset()->print_set(o, fmt);
324  break;
325  case format::raw:
326  assert(0);
327  break;
328  }
329  return o;
330  }
331  };
332 
333  namespace detail
334  {
336  template <typename GenSet>
337  struct letterized_traits<letterset<GenSet>>
338  {
339  static constexpr bool is_letterized = true;
340 
341  using labelset_t = nullableset<letterset<GenSet>>;
342 
343  static labelset_t labelset(const letterset<GenSet>& ls)
344  {
345  return {ls.genset()};
346  }
347  };
348 
350  template <typename GenSet>
351  struct nullableset_traits<letterset<GenSet>>
352  {
353  using type = nullableset<letterset<GenSet>>;
354  static type value(const letterset<GenSet>& ls)
355  {
356  return ls;
357  }
358  };
359 
361  template <typename GenSet>
362  struct law_traits<letterset<GenSet>>
363  {
364  using type = wordset<GenSet>;
365  static type value(const letterset<GenSet>& ls)
366  {
367  return ls.genset();
368  }
369  };
370 
371  /*-------.
372  | Join. |
373  `-------*/
374 
375  template <typename GenSet>
376  struct join_impl<letterset<GenSet>, letterset<GenSet>>
377  {
378  using type = letterset<GenSet>;
379  static type join(const letterset<GenSet>& lhs,
380  const letterset<GenSet>& rhs)
381  {
382  return {set_union(*lhs.genset(), *rhs.genset())};
383  }
384  };
385  }
386 
388  template <typename GenSet>
389  letterset<GenSet>
390  meet(const letterset<GenSet>& lhs, const letterset<GenSet>& rhs)
391  {
392  return {set_intersection(*lhs.genset(), *rhs.genset())};
393  }
394 }
STL namespace.
value_t conv(const nullableset< LabelSet_ > &ls, typename nullableset< LabelSet_ >::value_t v) const
Convert from nullableset to letterset.
Definition: letterset.hh:201
std::set< value_t, vcsn::less< self_t >> values_t
Definition: letterset.hh:34
value_t conjunction(const value_t l, const value_t r) const
Definition: letterset.hh:291
static letterset make(std::istream &is)
Build from the description in is.
Definition: letterset.hh:57
char eat(std::istream &is, char c)
Check lookahead character and advance.
Definition: stream.cc:90
Print as a parsable type string.
Definition: format.hh:26
static constexpr bool is_letterized()
Definition: letterset.hh:157
static constexpr bool is_expressionset()
Definition: letterset.hh:151
return res
Definition: multiply.hh:398
boost::optional< value_t > maybe_rdivide(const value_t l, const value_t r) const
Definition: letterset.hh:284
value_t ldivide(const value_t l, const value_t r) const
Compute w1 \ w2 = w1^{-1}w2.
Definition: letterset.hh:263
Print for LaTeX.
Definition: format.hh:22
std::ostream & print(const value_t &l, std::ostream &o=std::cout, format fmt={}) const
Definition: letterset.hh:302
letterset(std::initializer_list< letter_t > letters)
Definition: letterset.hh:46
value_t conv(self_t, value_t v) const
Definition: letterset.hh:191
static bool equal(const value_t l, const value_t r)
Whether l == r.
Definition: letterset.hh:133
value_t lgcd(const value_t l, const value_t r) const
The longest common prefix.
Definition: letterset.hh:256
typename genset_t::letter_t letter_t
value_t value(Args &&...args) const
Value constructor.
Definition: letterset.hh:83
void convs_(std::istream &i, Fun fun) const
Read and process a class of letters.
An input/output format for valuesets.
Definition: format.hh:13
letterset(const genset_ptr &gs)
Definition: letterset.hh:38
static size_t hash(value_t v)
Definition: letterset.hh:185
void require(Bool b, Args &&...args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:91
typename genset_t::letter_t letter_t
Definition: letterset.hh:30
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
static symbol sname()
Definition: letterset.hh:50
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
Definition: symbol.hh:23
auto hash_value(const T &v) -> decltype(std::hash< T >
Following the naming convention of Boost.
Definition: functional.hh:30
letter_t value_t
Definition: letterset.hh:33
static constexpr bool has_one()
Definition: letterset.hh:145
static constexpr bool is_free()
Definition: letterset.hh:76
value_t conv(std::istream &i, bool quoted=true) const
Read one letter from i, return the corresponding label.
Definition: letterset.hh:211
typename genset_t::word_t word_t
Definition: letterset.hh:31
Definition: a-star.hh:8
#define VCSN_REQUIRE(Cond,...)
A macro similar to require.
Definition: raise.hh:111
typename genset_t::word_t word_t
static constexpr bool is_one(value_t)
Definition: letterset.hh:169
This class has no modeling purpose, it only serves to factor code common to letterset and wordset...
Implementation of labels are nullables (letter or empty).
Definition: fwd.hh:14
typename helper_t::value_t value_t
Definition: nullableset.hh:167
static word_t letters_of(word_t v)
Prepare to iterate over the letters of v.
Definition: letterset.hh:96
static word_t letters_of_padded(word_t v, letter_t)
Prepare to iterate over the letters of v.
Definition: letterset.hh:104
std::shared_ptr< const genset_t > genset_ptr
bool open(bool o) const
Whether unknown letters should be added, or rejected.
Definition: letterset.hh:71
std::ostream & print_set(std::ostream &o, format fmt={}) const
Definition: letterset.hh:309
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
ATTRIBUTE_PURE auto has(Args &&...args) const -> decltype(this->genset() -> has(std::forward< Args >(args)...))
static word_t letters_of(letter_t v)
Prepare to iterate over v.
Definition: letterset.hh:111
static ATTRIBUTE_PURE bool is_one(value_t l)
Definition: nullableset.hh:247
return v
Definition: multiply.hh:361
static value_t special() ATTRIBUTE_PURE
Definition: letterset.hh:126
void convs(std::istream &i, Fun fun) const
Process a label class.
Definition: letterset.hh:235
Implementation of labels are letters.
Definition: fwd.hh:10
std::string to_string(direction d)
Conversion to string.
Definition: direction.cc:7
static size_t size(value_t)
Definition: letterset.hh:180
boost::optional< value_t > maybe_ldivide(const value_t l, const value_t r) const
Definition: letterset.hh:270
static word_t letters_of_padded(letter_t v, letter_t)
Prepare to iterate over v.
Definition: letterset.hh:119
const labelset_ptr labelset() const
Definition: nullableset.hh:293
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:586
letterset(const genset_t &gs={})
Definition: letterset.hh:42
static bool less(const value_t l, const value_t r)
Whether l < r.
Definition: letterset.hh:139
static word_t word(value_t v)
Convert to a word.
Definition: letterset.hh:89
bool is_valid(value_t v) const
Definition: letterset.hh:175
letter_t get_letter(std::istream &i, bool quoted=true) const
Read one letter from i.
value_t rdivide(const value_t l, const value_t r) const
Compute w1 / w2.
Definition: letterset.hh:277
static bool is_special(value_t v) ATTRIBUTE_PURE
Definition: letterset.hh:163