Awali
Another Weighted Automata library
setalpha.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_ALPHABETS_SETALPHA_HH
18 # define AWALI_ALPHABETS_SETALPHA_HH
19 
20 # include <initializer_list>
21 # include <stdexcept>
22 # include <cassert>
23 # include <sstream>
24 
25 
26 #include <awali/common/version.hh>
28 #include <awali/common/json/node.cc>
29 #include <awali/sttc/misc/raise.hh>
30 #include <awali/sttc/misc/set.hh>
31 #include <awali/sttc/misc/stream.hh> // eat.
32 
33 namespace awali {
34  namespace sttc {
35 
42  template <typename L>
43  class set_alphabet: public L
44  {
45  public:
46  using letter_t = typename L::letter_t;
47  //using word_t = typename L::word_t;
48  using letters_t = std::set<letter_t>;
51 
52  static std::string sname()
53  {
54  return L::sname();
55  }
56 
57  virtual std::string vname(bool full = true) const override
58  {
59  std::ostringstream res;
60  res << sname();
61  if (full)
62  {
63  res << '(';
64  for (letter_t c: alphabet_)
65  L::print(c,res) ;
66  res << ')';
67  }
68  return res.str();
69  }
70 
71  /*
72  static set_alphabet make(std::istream& is)
73  {
74  // name: char(abc)_ratexpset<law_char(xyz)_b>.
75  // ^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^
76  // | | weightset
77  // | +-- gens
78  // +-- letter_type
79  std::string letter_type;
80  {
81  char c;
82  while (is >> c)
83  {
84  if (c == '(')
85  {
86  is.unget();
87  break;
88  }
89  letter_type.append(1, c);
90  }
91  }
92  // The list of generators (letters).
93  letters_t gens;
94  // Previously read character.
95  int prev = -1;
96  {
97  sttc::eat(is, '(');
98  char l;
99  while (is >> l && l != ')')
100  switch (l)
101  {
102  case '-':
103  if (prev == -1)
104  goto insert;
105  else
106  {
107  int l2 = is.get();
108  require(l2 != EOF,
109  "unexpected end in character class");
110  if (l2 == '\\')
111  {
112  l2 = is.get();
113  require(l2 != EOF,
114  "unexpected end after escape in character class");
115  }
116  for (l = prev; l <= l2; ++l)
117  gens.insert(l);
118  prev = -1;
119  continue;
120  }
121 
122  case '\\':
123  {
124  int l2 = is.get();
125  require(l2 != EOF,
126  "unexpected end after escape");
127  l = l2;
128  goto insert;
129  }
130 
131  default:
132  insert:
133  gens.insert(l);
134  prev = l;
135  }
136  }
137  return gens;
138  }
139  */
140 
141  set_alphabet() = default;
142  set_alphabet(const set_alphabet&) = default;
143  set_alphabet(const std::initializer_list<letter_t>& l)
144  : alphabet_{l}
145  {}
146 
148  : alphabet_{l}
149  {}
150 
154  bool open(bool o) const
155  {
156  std::swap(o, open_);
157  return o;
158  }
159 
160 
162  set_alphabet&
164  {
165  assert(l != this->special_letter());
166  alphabet_.insert(l);
167  return *this;
168  }
169 
170  set_alphabet&
172  {
173  assert(l != this->special_letter());
174  alphabet_.erase(l);
175  return *this;
176  }
177 
178  unsigned size() const {
179  return alphabet_.size();
180  }
181 
182  set_alphabet&
184  {
185  alphabet_.clear();
186  return *this;
187  }
188 
190  bool
191  has(letter_t l) const
192  {
193  if (open_)
194  {
195  // FIXME: OMG...
196  const_cast<set_alphabet&>(*this).add_letter(l);
197  return true;
198  }
199  else
200  return alphabet_.find(l)!=alphabet_.end();
201  }
202 
203  /*
205  word_t
206  conv(std::istream& i) const
207  {
208  word_t res;
209  require(!i.bad(),
210  "conv: invalid stream");
211  if (i.good() && i.peek() == '\\')
212  {
213  i.ignore();
214  int c = i.peek();
215  if (c != 'e')
216  throw std::domain_error("invalid label: unexpected \\"
217  + str_escape(c));
218  i.ignore();
219  }
220  else
221  {
222  // FIXME: This wrongly assumes that letters are characters.
223  // It will break with integer or string alphabets.
224  int c;
225  while (i.good()
226  && (c = i.peek()) != EOF
227  && c != ','
228  && c != '('
229  && c != ')'
230  && has(c))
231  res = this->concat(res, letter_t(i.get()));
232  }
233  return res;
234  }
235 
236  word_t
237  parse(const std::string& str, size_t& p) const
238  {
239  word_t w = this->empty_word();
240  while (p>0) { //FIXME: this wrongly assumes that there is no delimiter
241  // between letters
242  letter_t l = this->parse_one_letter(str,p);
243  if (this->has(l)) {
244  w = this->concat(l,w);
245  }
246  else {
247  p++;
248  break;
249  }
250  }
251  return w;
252  }
253  */
254 
255  using iterator = typename letters_t::const_iterator;
256  using const_iterator = typename letters_t::const_iterator;
257 
259  {
260  return alphabet_.begin();
261  }
262 
264  {
265  return alphabet_.end();
266  }
267 
269  {
270  return alphabet_.begin();
271  }
272 
274  {
275  return alphabet_.end();
276  }
277 
279  {
280  return alphabet_.find(l);
281  }
282 
283  std::ostream&
284  print_set(std::ostream& o, const std::string& format = "text") const
285  {
286  if (format == "latex")
287  {
288  const char *sep = "\\{";
289  for (auto c: *this)
290  {
291  o << sep;
292  L::print(c, o);
293  sep = ", ";
294  }
295  o << "\\}";
296  }
297  else if (format == "text")
298  o << vname(true);
299  else
300  raise("invalid format: ", format);
301  return o;
302  }
303 
304 
305  template<unsigned version = version::fsm_json>
307  to_json() const {
308  version::check_fsmjson<version>();
309  switch (version) {
310  default:
311  json::object_t* obj = new json::object_t();
312  obj->push_back("letterType", L::to_json());
313  json::array_t* l = new json::array_t();
314  for (auto x: *this)
315  l->push_back(this->template letter_to_json<version>(x));
316  obj->push_back("alphabet", l);
317  return obj;
318  }
319  }
320 
321 
322 
323 
324 // template<unsigned version = version::fsm_json>
325 // json::string_t*
326 // letter_to_json(const letter_t& l) const
327 // {
328 // switch (version) {
329 // case 0:
330 // throw parse_exception("[Set Alpha] Unsupported fsm-json version:"
331 // + std::to_string(version));
332 // case 1:
333 // default:
334 // std::stringstream ss;
335 // ss << l;
336 // return new json::string_t(ss.str());
337 // }
338 // }
339 
341  template <typename L2>
342  friend set_alphabet<L2>
343  intersection(const set_alphabet<L2>& lhs, const set_alphabet<L2>& rhs);
344 
346  template <typename L2>
347  friend set_alphabet<L2>
348  get_union(const set_alphabet<L2>& lhs, const set_alphabet<L2>& rhs);
349  private:
350  // FIXME: OMG...
351  mutable letters_t alphabet_;
352  mutable bool open_ = false;
353  };
354 
355  template <typename L2>
356  set_alphabet<L2>
358  {
359  return {internal::intersection(lhs.alphabet_, rhs.alphabet_)};
360  }
361 
362  template <typename L2>
365  {
366  return {internal::get_union(lhs.alphabet_, rhs.alphabet_)};
367  }
368  }
369 }//end of ns awali::stc
370 
371 #endif // !AWALI_ALPHABETS_SETALPHA_HH
Definition: node.hh:431
array_t * push_back(node_t *p)
Definition: node.hh:367
object_t * push_back(std::string key, node_t *node)
The semiring of complex numbers.
Definition: c.hh:44
objets that represent the alphabets of letters as char
Definition: setalpha.hh:44
set_alphabet(const std::initializer_list< letter_t > &l)
Definition: setalpha.hh:143
json::object_t * to_json() const
Definition: setalpha.hh:307
const_iterator cend() const
Definition: setalpha.hh:273
const_iterator begin() const
Definition: setalpha.hh:258
virtual std::string vname(bool full=true) const override
Definition: setalpha.hh:57
bool open(bool o) const
Whether unknown letters should be added, or rejected.
Definition: setalpha.hh:154
typename letters_t::const_iterator iterator
Definition: setalpha.hh:255
set_alphabet & clear()
Definition: setalpha.hh:183
const_iterator end() const
Definition: setalpha.hh:263
letter_t value_type
The type of our values, when seen as a container.
Definition: setalpha.hh:50
unsigned size() const
Definition: setalpha.hh:178
typename L::letter_t letter_t
Definition: setalpha.hh:46
std::set< letter_t > letters_t
Definition: setalpha.hh:48
set_alphabet(const letters_t &l)
Definition: setalpha.hh:147
typename letters_t::const_iterator const_iterator
Definition: setalpha.hh:256
std::ostream & print_set(std::ostream &o, const std::string &format="text") const
Definition: setalpha.hh:284
const_iterator cbegin() const
Definition: setalpha.hh:268
set_alphabet & remove_letter(letter_t l)
Definition: setalpha.hh:171
static std::string sname()
Definition: setalpha.hh:52
friend set_alphabet< L2 > intersection(const set_alphabet< L2 > &lhs, const set_alphabet< L2 > &rhs)
Compute the intersection with another alphabet.
Definition: setalpha.hh:357
bool has(letter_t l) const
Whether l is a letter.
Definition: setalpha.hh:191
set_alphabet(const set_alphabet &)=default
const_iterator find(letter_t l) const
Definition: setalpha.hh:278
set_alphabet & add_letter(letter_t l)
Modify this by adding l, and return *this.
Definition: setalpha.hh:163
friend set_alphabet< L2 > get_union(const set_alphabet< L2 > &lhs, const set_alphabet< L2 > &rhs)
Compute the union with another alphabet.
Definition: setalpha.hh:364
std::ostream & print(const std::tuple< Args... > &args, std::ostream &o)
Definition: tuple.hh:254
std::set< T, Compare, Alloc > intersection(const std::set< T, Compare, Alloc > &set1, const std::set< T, Compare, Alloc > &set2)
The intersection of two sets.
std::set< T, Compare, Alloc > get_union(const std::set< T, Compare, Alloc > &set1, const std::set< T, Compare, Alloc > &set2)
The union of two sets.
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
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