Awali
Another Weighted Automata library
wordset.hh
Go to the documentation of this file.
1 // This file is part of Awali.
2 // Copyright 2016-2022 Sylvain Lombardy, Victor Marsault, Jacques Sakarovitch
3 //
4 // Awali is a free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 
17 #ifndef AWALI_LABELSET_WORDSET_HH
18 # define AWALI_LABELSET_WORDSET_HH
19 
20 # include <memory>
21 # include <set>
22 
23 #include <awali/sttc/core/kind.hh>
24 //#include <awali/sttc/labelset/genset_labelset.hh>
25 //#include <awali/sttc/labelset/labelset.hh>
27 #include <awali/utils/hash.hh>
28 #include <awali/sttc/misc/raise.hh>
29 
30 namespace awali { namespace sttc {
31 
33  template <typename GenSet>
34  class wordset
35  {
36  public:
37  using genset_t = GenSet;
38  using self_type = wordset;
39  using genset_ptr = std::shared_ptr<const genset_t>;
40 
41  using letter_t = typename genset_t::letter_t;
42  using word_t = typename genset_t::word_t;
43  using letters_t = std::set<letter_t>;
44 
45  using value_t = word_t;
46 
48 
49  private:
50  genset_ptr genset_;
51  public:
52  wordset(const genset_t& gs = {})
53  : genset_{std::make_shared<const genset_t>(gs)}
54  {}
55 
56  const genset_t& genset() const {
57  return *genset_;
58  }
59 
60  static std::string sname()
61  {
62  return "law_" + genset_t::sname();
63  }
64 
65  std::string vname(bool full = true) const
66  {
67  return "law_" + genset().vname(full);
68  }
69 
70  /*
72  static wordset make(std::istream& is)
73  {
74  // name: law_char(abc).
75  // ^^^ ^^^^^^^^^
76  // kind genset
77  kind_t::make(is);
78  eat(is, '_');
79  auto gs = genset_t::make(is);
80  return gs;
81  }
82  */
83 
87  bool open(bool o) const
88  {
89  return genset().open(o);
90  }
91 
92  // If labels are words, the monoid of labels is not free:
93  static constexpr bool is_free()
94  {
95  return false;
96  }
97 
99  template <typename... Args>
100  value_t value(Args&&... args) const
101  {
102  return value_t{std::forward<Args>(args)...};
103  }
104 
106  word_t word(const value_t& v) const
107  {
108  return v;
109  }
110 
112  word_t word(const letter_t& l) const
113  {
114  return {l};
115  }
116 
117  word_t
118  concat(const letter_t l, const letter_t r) const
119  {
120  return {l, r};
121  }
122 
123  word_t
124  concat(const word_t& l, const letter_t r) const
125  {
126  word_t w{l};
127  w.push_back(r);
128  return w;
129  }
130 
131  word_t
132  concat(const letter_t l, const word_t& r) const
133  {
134  word_t w{l};
135  w.insert(w.end(),r.begin(),r.end());
136  return w;
137  }
138 
139  word_t
140  concat(const word_t& l, const word_t& r) const
141  {
142  word_t w{l};
143  w.insert(w.end(),r.begin(),r.end());
144  return w;
145  }
146 
148  static word_t
150  {
151  return v;
152  }
153 
155  static bool
156  equals(const value_t l, const value_t r)
157  {
158  return l == r;
159  }
160 
162  static bool less_than(const value_t l, const value_t r)
163  {
164  if(l.size()<r.size())
165  return true;
166  if(l.size()>r.size())
167  return false;
168  return (l < r);
169  }
170 
171  static value_t
173  {
174  return {genset_t::special_letter()};
175  }
176 
177  static bool
178  is_special(const value_t& v)
179  {
180  return v == special();
181  }
182 
183  bool
184  is_valid(const value_t& v) const
185  {
186  for (auto l: v)
187  if (!genset().has(l))
188  return false;
189  return true;
190  }
191 
192  static constexpr bool
194  {
195  return false;
196  }
197 
198  static constexpr bool
200  {
201  return true;
202  }
203 
204  static constexpr bool
206  {
207  return false;
208  }
209 
210  static value_t
211  one()
212  {
213  return {};
214  }
215 
216  static bool
217  is_one(const value_t& l)
218  {
219  return l.empty();
220  }
221 
222  static size_t size(const value_t& v)
223  {
224  return v.size();
225  }
226 
228  word_t delimit(const word_t& w) const
229  {
230  word_t s=special();
231  s.insert(s.end(),w.begin(),w.end());
232  s.push_back(genset().special_letter());
233  return s;
234  }
235 
237  word_t undelimit(const word_t& w) const
238  {
239  size_t s = w.size();
240  assert(2 <= s);
241  assert(w[0] == genset().special_letter());
242  assert(w[s-1] == genset().special_letter());
243  word_t r(++w.begin(), --w.end());
244  return r;
245  }
246 
247  static size_t hash(const value_t& v)
248  {
249  return utils::hash_value(v);
250  }
251 
252  static value_t
254  {
255  return v;
256  }
257 
258  /*
259  // FIXME: Why do I need to repeat this?
260  // It should be inherited from genset-labelset.
261  value_t
262  conv(std::istream& i) const
263  {
264  return this->genset().conv(i);
265  }
266  */
267 
268  value_t
269  parse(const std::string& s, size_t& p, bool fixed_alphabet=true) const {
270  if (p == 0)
271  return one();
272  value_t tmp{};
273  const std::string& sep=genset_t::separation_mark();
274  size_t sep_length=sep.length();
275  size_t q=p;
276  letter_t l= genset_t::parse_one_letter(s, p);
277  if(genset().has(l))
278  tmp.push_back(l);
279  else {
280  p=q;
281  return one();
282  }
283  while(p>0) {
284  //Look for a separation mark
285  q = p-sep_length;
286  bool find_sep=true;
287  for(size_t i=0; find_sep && i<sep_length; ++i)
288  find_sep=(s[q+i]==sep[i]);
289  if(!find_sep)
290  break;
291  p=q;
292  l= genset_t::parse_one_letter(s, p);
293  if(genset().has(l)) {
294  tmp.push_back(l);
295  }
296  else if(sep_length>0)
297  throw parse_exception(p,"Word parsing");
298  else {
299  p=q;
300  break;
301  }
302  }
303  value_t result;
304  for(size_t i=tmp.size(); i!=0; --i)
305  result.push_back(tmp[i-1]);
306  return result;
307  }
308 
309  value_t
310  parse(const std::string& s) const {
311  size_t p = s.size();
312  value_t v = parse(s,p);
313  if(p>0)
314  throw parse_exception(p,"Word parsing");
315  return v;
316  }
317  /*
318  std::set<value_t>
319  convs(std::istream& i) const
320  {
321  std::set<value_t> res;
322  for (auto r : this->convs_(i))
323  res.insert(value_t{r});
324  return res;
325  }
326  */
327 
328  std::ostream&
329  print(const value_t& l, std::ostream& o,
330  const std::string& format = "text") const
331  {
332  if (is_one(l))
333  o << (format == "latex" ? "\\varepsilon" : "\\e");
334  else if (!is_special(l)) {
335  bool first=true;
336  for(auto letter : l) {
337  if(first)
338  first=false;
339  else
340  o<< genset_t::separation_mark();
341  genset().print(letter, o);
342  }
343  }
344  return o;
345  }
346 
347  std::ostream&
348  print_set(std::ostream& o, const std::string& format = "text") const
349  {
350  if (format == "latex")
351  {
352  genset().print_set(o, format);
353  o << "^*";
354  }
355  else if (format == "text")
356  o << vname(true);
357  else
358  raise("invalid format: ", format);
359  return o;
360  }
361 
362  template<unsigned version = version::fsm_json>
364  version::check_fsmjson<version>();
365  switch (version) {
366  case 1:
367  default:
368  GenSet const& gs = this->genset();
369  json::object_t* obj;
370  obj = gs.template to_json<version>()->object();
371  obj->push_front("labelKind", new json::string_t("Words"));
372  return obj;
373  }
374  }
375 
376 
377  template<unsigned version = version::fsm_json>
379  {
380  switch (version) {
381  case 0:
382  throw parse_exception("[wordset] Unsupported fsm-json version:"
383  + std::to_string(version));
384  case 1:
385  default:
386  json::array_t* arr= new json::array_t();
387  for (auto x: v)
388  arr->push_back(this->genset().template letter_to_json<version>(x));
389  return arr;
390  }
391  }
392 
393 
394  template<unsigned version = version::fsm_json>
395  value_t
396  value_from_json(json::node_t const* p) const {
397  switch (version) {
398  case 0:
399  case 1:
400  default:
401  value_t res;
402  if(p->kind == json::STRING) {
403  std::string const& s = p->string()->value;
404  size_t pos=s.length();
405  res=parse(s,pos);
406  if(pos==0)
407  return res;
408  }
409  else
410  if(p->kind == json::ARRAY) {
411  for(auto val : *(p->array())) {
412  res.push_back(this->genset().template letter_from_json<version>(val));
413  }
414  return res;
415  }
416  throw parse_exception("json parser Word value");
417  }
418  }
419 
420  value_t
421  transpose(const value_t& v) const {
422  value_t res;
423  for(size_t i=v.size(); i!=0; --i)
424  res.push_back(genset().transpose(v[i-1]));
425  return res;
426  }
427  };
428 
430  // FIXME: Factor in genset_labelset?
431  template <typename GenSet>
432  wordset<GenSet>
433  meet(const wordset<GenSet>& lhs, const wordset<GenSet>& rhs)
434  {
435  return {intersection(lhs.genset(), rhs.genset())};
436  }
437 
439  template <typename GenSet>
440  wordset<GenSet>
441  join(const wordset<GenSet>& lhs, const wordset<GenSet>& rhs)
442  {
443  return {get_union(lhs.genset(), rhs.genset())};
444  }
445 
446 
447 
448 }}//end of ns awali::stc
449 
450 #endif // !AWALI_LABELSET_WORDSET_HH
Definition: node.hh:431
array_t * push_back(node_t *p)
Definition: node.hh:193
virtual string_t const * string() const
Casts this node to string_t.
Definition: node.hh:215
node_kind_t const kind
Definition: node.hh:196
virtual array_t const * array() const
Casts this node to array_t.
Definition: node.hh:207
Definition: node.hh:367
virtual object_t * object() override
Casts this node to object_t.
Definition: node.hh:404
object_t * push_front(std::string key, node_t *node)
Definition: node.hh:529
std::string value
Definition: node.hh:531
The semiring of rational numbers.
Definition: q.hh:42
The semiring of floating Numbers.
Definition: r.hh:35
Implementation of labels are words.
Definition: wordset.hh:35
static word_t letters_of(word_t v)
Prepare to iterate over the letters of v.
Definition: wordset.hh:149
std::set< letter_t > letters_t
Definition: wordset.hh:43
value_t parse(const std::string &s, size_t &p, bool fixed_alphabet=true) const
Definition: wordset.hh:269
GenSet genset_t
Definition: wordset.hh:37
word_t concat(const word_t &l, const word_t &r) const
Definition: wordset.hh:140
word_t delimit(const word_t &w) const
Add the special character first and last.
Definition: wordset.hh:228
static std::string sname()
Definition: wordset.hh:60
static size_t hash(const value_t &v)
Definition: wordset.hh:247
std::shared_ptr< const genset_t > genset_ptr
Definition: wordset.hh:39
word_t concat(const letter_t l, const letter_t r) const
Definition: wordset.hh:118
static bool less_than(const value_t l, const value_t r)
Whether l < r.
Definition: wordset.hh:162
std::ostream & print(const value_t &l, std::ostream &o, const std::string &format="text") const
Definition: wordset.hh:329
static size_t size(const value_t &v)
Definition: wordset.hh:222
std::string vname(bool full=true) const
Definition: wordset.hh:65
wordset(const genset_t &gs={})
Definition: wordset.hh:52
word_t undelimit(const word_t &w) const
Remove first and last characters, that must be "special".
Definition: wordset.hh:237
json::node_t * value_to_json(value_t v) const
Definition: wordset.hh:378
static value_t one()
Definition: wordset.hh:211
json::node_t * to_json() const
Definition: wordset.hh:363
bool is_valid(const value_t &v) const
Definition: wordset.hh:184
static value_t special()
Definition: wordset.hh:172
word_t value_t
Definition: wordset.hh:45
const genset_t & genset() const
Definition: wordset.hh:56
word_t word(const letter_t &l) const
Convert to a word.
Definition: wordset.hh:112
static value_t conv(self_type, value_t v)
Definition: wordset.hh:253
static bool is_special(const value_t &v)
Definition: wordset.hh:178
typename genset_t::letter_t letter_t
Definition: wordset.hh:41
value_t parse(const std::string &s) const
Definition: wordset.hh:310
static bool is_one(const value_t &l)
Definition: wordset.hh:217
word_t word(const value_t &v) const
Convert to a word.
Definition: wordset.hh:106
bool open(bool o) const
Whether unknown letters should be added, or rejected.
Definition: wordset.hh:87
typename genset_t::word_t word_t
Definition: wordset.hh:42
static constexpr bool is_ratexpset()
Definition: wordset.hh:193
word_t concat(const letter_t l, const word_t &r) const
Definition: wordset.hh:132
static constexpr bool has_one()
Definition: wordset.hh:199
static bool equals(const value_t l, const value_t r)
Whether l == r.
Definition: wordset.hh:156
static constexpr bool is_free()
Definition: wordset.hh:93
static constexpr bool is_letterized()
Definition: wordset.hh:205
value_t value_from_json(json::node_t const *p) const
Definition: wordset.hh:396
value_t transpose(const value_t &v) const
Definition: wordset.hh:421
value_t value(Args &&... args) const
Value constructor.
Definition: wordset.hh:100
std::ostream & print_set(std::ostream &o, const std::string &format="text") const
Definition: wordset.hh:348
word_t concat(const word_t &l, const letter_t r) const
Definition: wordset.hh:124
any_t word_t
Type for words; it is an alias to any_t since the precise type depends on the context (most of the ti...
Definition: typedefs.hh:67
@ ARRAY
Definition: node.hh:94
@ STRING
Definition: node.hh:97
bool has(const std::map< Key, Value, Compare, Alloc > &s, const Key &e)
Definition: map.hh:53
std::string to_string(identities i)
auto join(const ratexpset< Ctx1 > &a, const ratexpset< Ctx2 > &b) -> ratexpset< join_t< Ctx1, Ctx2 >>
The union of two ratexpsets.
Definition: ratexpset.hh:445
auto meet(const ratexpset< Ctx1 > &a, const ratexpset< Ctx2 > &b) -> ratexpset< meet_t< Ctx1, Ctx2 >>
The meet of two ratexpsets.
Definition: ratexpset.hh:434
set_alphabet< L2 > get_union(const set_alphabet< L2 > &lhs, const set_alphabet< L2 > &rhs)
Definition: setalpha.hh:364
set_alphabet< L2 > intersection(const set_alphabet< L2 > &lhs, const set_alphabet< L2 > &rhs)
Definition: setalpha.hh:357
auto format(const ValueSet &vs, const typename ValueSet::value_t &v, Args &&... args) -> std::string
Format v via vs.print.
Definition: stream.hh:109
std::size_t hash_value(const T &v)
Definition: hash.hh:76
static const std::string full
Completely version of Awali as a std::string.
Definition: version.hh:42
Main namespace of Awali.
Definition: ato.hh:22
Exceptions thrown during parsing.
Definition: parse_exception.hh:26
marker type for labelsets where labels are words
Definition: kind.hh:86