Awali
Another Weighted Automata library
wordset.hh
Go to the documentation of this file.
1 // This file is part of Awali.
2 // Copyright 2016-2021 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  return (l < r);
165  }
166 
167  static value_t
169  {
170  return {genset_t::special_letter()};
171  }
172 
173  static bool
174  is_special(const value_t& v)
175  {
176  return v == special();
177  }
178 
179  bool
180  is_valid(const value_t& v) const
181  {
182  for (auto l: v)
183  if (!genset().has(l))
184  return false;
185  return true;
186  }
187 
188  static constexpr bool
190  {
191  return false;
192  }
193 
194  static constexpr bool
196  {
197  return true;
198  }
199 
200  static constexpr bool
202  {
203  return false;
204  }
205 
206  static value_t
207  one()
208  {
209  return {};
210  }
211 
212  static bool
213  is_one(const value_t& l)
214  {
215  return l.empty();
216  }
217 
218  static size_t size(const value_t& v)
219  {
220  return v.size();
221  }
222 
224  word_t delimit(const word_t& w) const
225  {
226  word_t s=special();
227  s.insert(s.end(),w.begin(),w.end());
228  s.push_back(genset().special_letter());
229  return s;
230  }
231 
233  word_t undelimit(const word_t& w) const
234  {
235  size_t s = w.size();
236  assert(2 <= s);
237  assert(w[0] == genset().special_letter());
238  assert(w[s-1] == genset().special_letter());
239  word_t r(++w.begin(), --w.end());
240  return r;
241  }
242 
243  static size_t hash(const value_t& v)
244  {
245  return utils::hash_value(v);
246  }
247 
248  static value_t
250  {
251  return v;
252  }
253 
254  /*
255  // FIXME: Why do I need to repeat this?
256  // It should be inherited from genset-labelset.
257  value_t
258  conv(std::istream& i) const
259  {
260  return this->genset().conv(i);
261  }
262  */
263 
264  value_t
265  parse(const std::string& s, size_t& p, bool fixed_alphabet=true) const {
266  if (p == 0)
267  return one();
268  value_t tmp{};
269  const std::string& sep=genset_t::separation_mark();
270  size_t sep_length=sep.length();
271  size_t q=p;
272  letter_t l= genset_t::parse_one_letter(s, p);
273  if(genset().has(l))
274  tmp.push_back(l);
275  else {
276  p=q;
277  return one();
278  }
279  while(p>0) {
280  //Look for a separation mark
281  q = p-sep_length;
282  bool find_sep=true;
283  for(size_t i=0; find_sep && i<sep_length; ++i)
284  find_sep=(s[q+i]==sep[i]);
285  if(!find_sep)
286  break;
287  p=q;
288  letter_t l= genset_t::parse_one_letter(s, p);
289  if(genset().has(l)) {
290  tmp.push_back(l);
291  }
292  else if(sep_length>0)
293  throw parse_exception(p,"Word parsing");
294  else {
295  p=q;
296  break;
297  }
298  }
299  value_t result;
300  for(size_t i=tmp.size(); i!=0; --i)
301  result.push_back(tmp[i-1]);
302  return result;
303  }
304 
305  value_t
306  parse(const std::string& s) const {
307  size_t p = s.size();
308  value_t v = parse(s,p);
309  if(p>0)
310  throw parse_exception(p,"Word parsing");
311  return v;
312  }
313  /*
314  std::set<value_t>
315  convs(std::istream& i) const
316  {
317  std::set<value_t> res;
318  for (auto r : this->convs_(i))
319  res.insert(value_t{r});
320  return res;
321  }
322  */
323 
324  std::ostream&
325  print(const value_t& l, std::ostream& o,
326  const std::string& format = "text") const
327  {
328  if (is_one(l))
329  o << (format == "latex" ? "\\varepsilon" : "\\e");
330  else if (!is_special(l)) {
331  bool first=true;
332  for(auto letter : l) {
333  if(first)
334  first=false;
335  else
336  o<< genset_t::separation_mark();
337  genset().print(letter, o);
338  }
339  }
340  return o;
341  }
342 
343  std::ostream&
344  print_set(std::ostream& o, const std::string& format = "text") const
345  {
346  if (format == "latex")
347  {
348  genset().print_set(o, format);
349  o << "^*";
350  }
351  else if (format == "text")
352  o << vname(true);
353  else
354  raise("invalid format: ", format);
355  return o;
356  }
357 
358  template<unsigned version = version::fsm_json>
360  switch (version) {
361  case 0:
362  throw parse_exception("[wordset] Unsupported fsm-json version:"
363  + std::to_string(version));
364  case 1:
365  default:
366  GenSet const& gs = this->genset();
367  json::object_t* obj;
368  obj = gs.template to_json<version>()->object();
369  obj->push_front("labelKind", new json::string_t("Words"));
370  return obj;
371  }
372  }
373 
374 
375  template<unsigned version = version::fsm_json>
377  {
378  switch (version) {
379  case 0:
380  throw parse_exception("[wordset] Unsupported fsm-json version:"
381  + std::to_string(version));
382  case 1:
383  default:
384  json::array_t* arr= new json::array_t();
385  for (auto x: v)
386  arr->push_back(this->genset().template letter_to_json<version>(x));
387  return arr;
388  }
389  }
390 
391 
392  template<unsigned version = version::fsm_json>
393  value_t
394  value_from_json(json::node_t const* p) const {
395  switch (version) {
396  case 0:
397  case 1:
398  default:
399  value_t res;
400  if(p->kind == json::STRING) {
401  std::string const& s = p->string()->value;
402  size_t pos=s.length();
403  res=parse(s,pos);
404  if(pos==0)
405  return res;
406  }
407  else
408  if(p->kind == json::ARRAY) {
409  for(auto val : *(p->array())) {
410  res.push_back(this->genset().template letter_from_json<version>(val));
411  }
412  return res;
413  }
414  throw parse_exception("json parser Word value");
415  }
416  }
417 
418  value_t
419  transpose(const value_t& v) const {
420  value_t res;
421  for(size_t i=v.size(); i!=0; --i)
422  res.push_back(genset().transpose(v[i-1]));
423  return res;
424  }
425  };
426 
428  // FIXME: Factor in genset_labelset?
429  template <typename GenSet>
430  wordset<GenSet>
431  meet(const wordset<GenSet>& lhs, const wordset<GenSet>& rhs)
432  {
433  return {intersection(lhs.genset(), rhs.genset())};
434  }
435 
437  template <typename GenSet>
438  wordset<GenSet>
439  join(const wordset<GenSet>& lhs, const wordset<GenSet>& rhs)
440  {
441  return {get_union(lhs.genset(), rhs.genset())};
442  }
443 
444 
445 
446 }}//end of ns awali::stc
447 
448 #endif // !AWALI_LABELSET_WORDSET_HH
Definition: node.hh:424
array_t * push_back(node_t *p)
Definition: node.hh:191
virtual string_t const * string() const
Casts this node to string_t.
Definition: node.hh:213
node_kind_t const kind
Definition: node.hh:194
virtual array_t const * array() const
Casts this node to array_t.
Definition: node.hh:205
Definition: node.hh:365
virtual object_t * object() override
Casts this node to object_t.
Definition: node.hh:397
object_t * push_front(std::string key, node_t *node)
Definition: node.hh:526
std::string value
Definition: node.hh:528
The semiring of rational numbers.
Definition: q.hh:41
The semiring of floating Numbers.
Definition: r.hh:34
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:265
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:224
static std::string sname()
Definition: wordset.hh:60
static size_t hash(const value_t &v)
Definition: wordset.hh:243
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:325
static size_t size(const value_t &v)
Definition: wordset.hh:218
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:233
json::node_t * value_to_json(value_t v) const
Definition: wordset.hh:376
static value_t one()
Definition: wordset.hh:207
json::node_t * to_json() const
Definition: wordset.hh:359
bool is_valid(const value_t &v) const
Definition: wordset.hh:180
static value_t special()
Definition: wordset.hh:168
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:249
static bool is_special(const value_t &v)
Definition: wordset.hh:174
typename genset_t::letter_t letter_t
Definition: wordset.hh:41
value_t parse(const std::string &s) const
Definition: wordset.hh:306
static bool is_one(const value_t &l)
Definition: wordset.hh:213
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:189
word_t concat(const letter_t l, const word_t &r) const
Definition: wordset.hh:132
static constexpr bool has_one()
Definition: wordset.hh:195
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:201
value_t value_from_json(json::node_t const *p) const
Definition: wordset.hh:394
value_t transpose(const value_t &v) const
Definition: wordset.hh:419
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:344
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:91
@ STRING
Definition: node.hh:94
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:448
auto meet(const ratexpset< Ctx1 > &a, const ratexpset< Ctx2 > &b) -> ratexpset< meet_t< Ctx1, Ctx2 >>
The meet of two ratexpsets.
Definition: ratexpset.hh:437
set_alphabet< L2 > get_union(const set_alphabet< L2 > &lhs, const set_alphabet< L2 > &rhs)
Definition: setalpha.hh:367
set_alphabet< L2 > intersection(const set_alphabet< L2 > &lhs, const set_alphabet< L2 > &rhs)
Definition: setalpha.hh:360
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:40
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