Awali
Another Weighted Automata library
ratexpset.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_CORE_RAT_RATEXPSET_HH
18 # define AWALI_CORE_RAT_RATEXPSET_HH
19 
20 # include <set>
21 # include <string>
22 
27 #include <awali/sttc/misc/raise.hh>
28 #include <awali/common/enums.hh>
38 
39 namespace awali {
40  namespace sttc {
41  namespace rat {
44  template <typename Context>
46  {
47  public:
49  using context_t = Context;
53  using labelset_ptr = typename context_t::labelset_ptr;
54  using weightset_ptr = typename context_t::weightset_ptr;
56  using weight_t = typename weightset_t::value_t;
60  //
61  // See http://stackoverflow.com/questions/15537023 to know why we
62  // add the sttc::rat:: part: GCC wants it, Clang does not care,
63  // both are right.
64 # define DEFINE(Type) \
65  using Type ## _t = ::awali::sttc::rat::Type<label_t, weight_t>
82 # undef DEFINE
83  template <exp::type_t Type>
85  template <exp::type_t Type>
87  using ratexp_t = std::shared_ptr<const node_t>;
88 
89  using type_t = typename node_t::type_t;
90  using ratexps_t = typename node_t::ratexps_t;
91 
93  using value_t = typename node_t::value_t;
94 
96  using values_t = std::vector<value_t>;
97 
98  using word_t = self_type;
100 
101  public:
103  static std::string sname();
105  std::string vname(bool full = true) const;
107  static self_type make(std::istream& is);
108 
112  ratexpset_impl(const context_t& ctx,
113  identities_t identities); // FIXME: make this optional again?
114 
118  bool open(bool o) const;
119 
120  const context_t& context() const;
121 
122 
123  identities_t identities() const;
124  bool is_series() const;
125 
126  const labelset_ptr& labelset() const;
127  const weightset_ptr& weightset() const;
128 
129  static auto atom(const label_t& v)
130  -> value_t;
131 
133  static value_t special()
134  {
135  return atom(labelset_t::special());
136  }
137 
140  static bool is_special(value_t v)
141  {
142  return equals(special(), v);
143  }
144 
145  bool is_letter(value_t) const
146  {
147  return false;
148  }
149 
150  bool is_zero(value_t v) const ATTRIBUTE_PURE;
151  static bool is_one(value_t v) ATTRIBUTE_PURE;
152 
153  static constexpr bool is_commutative_semiring()
154  {
155  return false;
156  }
157 
158  static constexpr bool show_one()
159  {
160  return false;
161  }
162 
163  static constexpr bool has_one()
164  {
165  return true;
166  }
167 
168  static constexpr bool is_ratexpset()
169  {
170  return true;
171  }
172 
173  static constexpr bool is_free()
174  {
175  return false;
176  }
177 
178  static constexpr star_status_t star_status()
179  {
181  }
182 
183  value_t conv(std::istream& is) const;
184  template <typename GenSet>
186  typename letterset<GenSet>::value_t v) const;
187  value_t conv(b, typename b::value_t v) const;
188  value_t conv(const z& ws, typename z::value_t v) const;
189  value_t conv(const q& ws, typename q::value_t v) const;
190  value_t conv(const r& ws, typename r::value_t v) const;
191  template <typename Ctx2>
193  typename ratexpset_impl<Ctx2>::value_t v) const;
194 
195  value_t conv(self_type, value_t v) const;
196 
197  std::set<value_t> convs(std::istream&) const
198  {
199  raise(vname(), ": ranges not implemented");
200  }
201 
202  std::ostream& print(const value_t v, std::ostream& o,
203  const std::string& format = "text") const;
204 
205  std::ostream&
206  print_set(std::ostream& o, const std::string& format = "text") const
207  {
208  if (format == "latex")
209  {
210  o << "\\mathsf{";
211  switch (identities())
212  {
213  case identities_t::trivial:
214  case identities_t::associativity:
215  o << "RatE";
216  break;
217  case identities_t::series:
218  o << "Series";
219  break;
220  default:
221  assert(false);
222  };
223  o << "}[";
224  context().print_set(o, format);
225  o << ']';
226  }
227  else if (format == "text") {
228  switch (identities())
229  {
230  case identities_t::trivial:
231  case identities_t::associativity:
232  o << "RatExp";
233  break;
234  case identities_t::series:
235  o << "Series";
236  break;
237  default:
238  assert(false);
239  };
240  o << "[";
241  context().print_set(o, format);
242  o << ']';
243  }
244  else
245  raise("invalid format: ", format);
246  return o;
247  }
248 
249 
250 
251  template<unsigned version = version::fsm_json>
253  const
254  {
255  switch (version) {
256  case 0:
257  throw parse_exception("[ratexpset] Unsupported fsm-json version:"
258  + std::to_string(version));
259  case 1:
260  default:
261  json::object_t* obj
262  = context().template to_json<version>()->object();
263  json::object_t* res = new json::object_t();
264  switch (identities())
265  {
266  case identities_t::trivial:
267  case identities_t::associativity:
268  res->push_back("Rational Expression",obj);
269  break;
270  case identities_t::series:
271  res->push_back("Series",obj);
272  break;
273  default:
274  assert(false);
275  };
276  return res;
277  }
278  }
279 
280 
281 
282  template<unsigned version = version::fsm_json>
283  json::node_t*
285  const
286  {
287  switch (version) {
288  case 0:
289  throw parse_exception("[ratexpset] Unsupported fsm-json version:"
290  + std::to_string(version));
291  case 1:
292  default:
293  rat::json_visitor<ratexpset_impl<Context>, version> jsonner(*this);
294  return jsonner(v);
295  }
296  }
297 
298  template<unsigned version = version::fsm_json>
299  value_t
301  const
302  {
303  switch (version) {
304  case 0:
305  throw parse_exception("[ratexpset] Unsupported fsm-json version:"
306  + std::to_string(version));
307  case 1:
308  default:
309  return js_parse_exp_content<self_type>(*this,p);
310  }
311  }
312 
313 
314  //value_t
315  //js_parse(json::node_t* p) const;
316 
317  value_t
318  parse(const std::string & s, size_t& p) const {
319  auto parser = awali::sttc::internal::exp_parser<ratexpset_impl>(*this, s, p);
320  value_t v=parser.parseE();
321  p=parser.p_;
322  return v;
323  }
324 
325  public:
327  static bool less_than(value_t l, value_t r);
328 
330  static bool equals(value_t l, value_t r);
331 
333  static size_t hash(const value_t& l);
334 
335  // Concrete type implementation.
336  value_t zero() const;
337  static value_t one();
338  value_t add(value_t l, value_t r) const;
339  value_t mul(value_t l, value_t r) const;
340  value_t concat(value_t l, value_t r) const;
341  value_t conjunction(value_t l, value_t r) const;
342  value_t shuffle(value_t l, value_t r) const;
343  value_t ldiv(value_t l, value_t r) const;
344  value_t rdiv(value_t l, value_t r) const;
345  value_t star(value_t e) const;
347  value_t complement(value_t e) const;
349  value_t transposition(value_t e) const;
351  value_t rmul(value_t e, const weight_t& w) const;
353  value_t lmul(const weight_t& w, value_t e) const;
355  value_t transpose(value_t e) const;
356 
358  word_t word(label_t l) const
359  {
360  return l;
361  }
362 
364  template <typename... Args>
365  value_t letter_class(Args&&... chars) const;
366 
367  std::string to_string(value_t e) const; // Mostly for internal convenience.
368 
369  private:
370  void require_weightset_commutativity() const;
371  bool less_than_ignoring_weight_(value_t l, value_t r) const;
372  value_t remove_from_sum_series_(ratexps_t addends,
373  typename ratexps_t::iterator i) const;
374  value_t insert_in_sum_series_(const sum_t& addends, value_t r) const;
375  value_t merge_sum_series_(const sum_t& addends1, value_t aa2) const;
376  value_t add_nonzero_series_(value_t l, value_t r) const;
377  exp::type_t type_ignoring_lweight_(value_t e) const;
378  weight_t possibly_implicit_lweight_(value_t e) const;
379  value_t unwrap_possible_lweight_(value_t e) const;
380  value_t mul_expressions_(value_t l, value_t r) const;
381  value_t mul_series_(value_t l, value_t r) const;
382  value_t mul_(value_t l, value_t r, bool series) const;
383  bool is_unweighted_nonsum_(value_t v) const;
384  bool is_nonsum_(value_t v) const;
385  value_t mul_atoms_(const label_t& l, const label_t& r) const;
386  value_t mul_atoms_(const label_t& l, const label_t& r, std::true_type) const; // law.
387  value_t mul_atoms_(const label_t& l, const label_t& r, std::false_type) const; // ! law.
388  value_t mul_unweighted_nontrivial_products_(value_t a, value_t b) const;
389  value_t mul_products_(value_t a, value_t b) const;
390  value_t nontrivial_mul_expressions_(value_t l, value_t r) const;
391  value_t nontrivial_mul_series_(value_t l, value_t r) const;
392  value_t nontrivial_lmul_expression_(const weight_t& w, value_t s) const;
393  value_t nontrivial_lmul_series_(const weight_t& w, value_t s) const;
394  value_t nontrivial_rmul_expression_(value_t e, const weight_t& w) const;
395  value_t nontrivial_rmul_series_(value_t e, const weight_t& w) const;
396 
400  template <exp::type_t Type>
401  void gather(ratexps_t& res, value_t v) const;
402 
407  template <exp::type_t Type>
408  ratexps_t gather(value_t l, value_t r) const;
409 
411  value_t concat_(value_t l, value_t r, std::true_type) const;
413  value_t concat_(value_t l, value_t r, std::false_type) const;
414 
416  template <typename LabelSet_, typename... Args>
417  value_t letter_class_(const Args&&... chars, std::true_type) const;
418 
420  template <typename LabelSet_>
421  value_t
422  letter_class_(std::set<std::pair<typename LabelSet_::letter_t,
423  typename LabelSet_::letter_t>> chars,
424  bool accept,
425  std::false_type) const;
426 
427  private:
428  context_t ctx_;
429  const identities_t identities_;
430  };
431  } // rat::
432 
434  template <typename Ctx1, typename Ctx2>
435  inline
436  auto
439  {
440  return {meet(a.context(), b.context()),
441  meet(a.identities(), b.identities())};
442  }
443 
445  template <typename Ctx1, typename Ctx2>
446  inline
447  auto
450  {
451  return {join(a.context(), b.context()),
452  join(a.identities(), b.identities())};
453  }
454 
455  // Used as a labelset.
456  template <typename GenSet1, typename Ctx2>
457  inline
458  auto
462  {
465  return {ctx_t{join(a, *b.labelset()), *b.weightset()},
466  b.identities()};
467  }
468 
469  template <typename Ctx1, typename GenSet2>
470  inline
471  auto
473  -> decltype(join(b, a))
474  {
475  return join(b, a);
476  }
477 
478  // B. FIXME: screams for refactoring!
479 
480  template <typename Context>
481  inline
482  ratexpset<Context>
483  join(const ratexpset<Context>& a, const b&)
484  {
485  return a;
486  }
487 
488  template <typename Context>
489  inline
490  ratexpset<Context>
491  join(const b& a, const ratexpset<Context>& b)
492  {
493  return join(b, a);
494  }
495 
496  // Z.
497  template <typename Context>
498  inline
499  auto
500  join(const ratexpset<Context>& rs, const z& ws)
503  {
504  using ctx_t = context<labelset_t_of<Context>,
506  return {ctx_t{*rs.labelset(), join(*rs.weightset(), ws)},
507  rs.identities()};
508  }
509 
510  template <typename Context>
511  inline
512  auto
513  join(const z& ws, const ratexpset<Context>& rs)
515  {
516  return join(rs, ws);
517  }
518 
519  // Q.
520  template <typename Context>
521  inline
522  auto
523  join(const ratexpset<Context>& rs, const q& ws)
526  {
527  using ctx_t = context<labelset_t_of<Context>,
529  return {ctx_t{*rs.labelset(), join(*rs.weightset(), ws)},
530  rs.identities()};
531  }
532 
533  template <typename Context>
534  inline
535  auto
536  join(const q& ws, const ratexpset<Context>& rs)
538  {
539  return join(rs, ws);
540  }
541 
542  // R.
543  template <typename Context>
544  inline
545  auto
546  join(const ratexpset<Context>& rs, const r& ws)
549  {
550  using ctx_t = context<labelset_t_of<Context>,
552  return {ctx_t{*rs.labelset(), join(*rs.weightset(), ws)},
553  rs.identities()};
554  }
555 
556  template <typename Context>
557  inline
558  auto
559  join(const r& ws, const ratexpset<Context>& rs)
560  // FIXME: loops if wrong order.
562  {
563  return join(rs, ws);
564  }
565  }
566 }//end of ns awali::stc
567 
569 
570 #endif // !AWALI_CORE_RAT_RATEXPSET_HH
571 
Definition: node.hh:191
Definition: node.hh:365
object_t * push_back(std::string key, node_t *node)
The Boolean semring.
Definition: b.hh:38
bool value_t
Definition: b.hh:56
carries the algebraic settings of automata
Definition: context.hh:40
Implementation of labels are letters.
Definition: letterset.hh:43
letter_t value_t
Definition: letterset.hh:53
The semiring of rational numbers.
Definition: q.hh:41
The semiring of floating Numbers.
Definition: r.hh:34
double value_t
Definition: r.hh:55
Definition: ratexp.hh:280
Definition: visitor.hh:30
Definition: ratexp.hh:262
rat::type_t type_t
The possible types of ratexps.
Definition: ratexp.hh:43
An inner node.
Definition: ratexp.hh:96
Definition: json_visitor.hxx:40
The root from which to derive the final node types.
Definition: ratexp.hh:248
The abstract parameterized, root for all rational expression types.
Definition: ratexp.hh:74
std::shared_ptr< const node_t > value_t
Definition: ratexp.hh:79
std::vector< value_t > ratexps_t
Definition: ratexp.hh:82
A typed ratexp set.
Definition: ratexpset.hh:46
static constexpr bool is_commutative_semiring()
Definition: ratexpset.hh:153
identities_t identities() const
Definition: ratexpset.hxx:126
value_t star(value_t e) const
Definition: ratexpset.hxx:639
typename node_t::value_t value_t
The value this is a set of: typeful shared pointers.
Definition: ratexpset.hh:93
value_t conv(const ratexpset_impl< Ctx2 > &ws, typename ratexpset_impl< Ctx2 >::value_t v) const
bool is_series() const
Definition: ratexpset.hxx:131
typename context_t::weightset_ptr weightset_ptr
Definition: ratexpset.hh:54
value_t letter_class(Args &&... chars) const
A ratexp matching one character amongst chars.
static std::string sname()
Static description key.
Definition: ratexpset.hxx:66
value_t conjunction(value_t l, value_t r) const
Definition: ratexpset.hxx:503
const labelset_ptr & labelset() const
Definition: ratexpset.hxx:136
json::node_t * value_to_json(value_t v) const
Definition: ratexpset.hh:284
static constexpr bool is_ratexpset()
Definition: ratexpset.hh:168
std::string to_string(value_t e) const
Definition: ratexpset.hxx:783
value_t concat(value_t l, value_t r) const
Definition: ratexpset.hxx:588
labelset_t_of< context_t > labelset_t
Definition: ratexpset.hh:50
static constexpr bool has_one()
Definition: ratexpset.hh:163
bool open(bool o) const
Whether unknown letters should be added, or rejected.
Definition: ratexpset.hxx:115
std::vector< value_t > values_t
A value sequence.
Definition: ratexpset.hh:96
value_t transpose(value_t e) const
The transposed of this rational expression.
Definition: ratexpset.hxx:912
value_t ldiv(value_t l, value_t r) const
Definition: ratexpset.hxx:542
static bool is_one(value_t v) ATTRIBUTE_PURE
Definition: ratexpset.hxx:801
value_t transposition(value_t e) const
Add a transposition operator.
Definition: ratexpset.hxx:668
value_t mul(value_t l, value_t r) const
Definition: ratexpset.hxx:334
value_t rmul(value_t e, const weight_t &w) const
Right-multiplication by a weight.
Definition: ratexpset.hxx:734
std::set< value_t > convs(std::istream &) const
Definition: ratexpset.hh:197
json::node_t * to_json() const
Definition: ratexpset.hh:252
static constexpr bool show_one()
Definition: ratexpset.hh:158
label_t_of< context_t > label_t
Definition: ratexpset.hh:55
typename context_t::labelset_ptr labelset_ptr
Definition: ratexpset.hh:53
value_t conv(const letterset< GenSet > &ls, typename letterset< GenSet >::value_t v) const
Context context_t
Definition: ratexpset.hh:49
std::string vname(bool full=true) const
Dynamic description key.
Definition: ratexpset.hxx:72
value_t value_from_json(json::node_t const *p) const
Definition: ratexpset.hh:300
ratexpset_impl(const context_t &ctx, identities_t identities)
Constructor.
Definition: ratexpset.hxx:44
std::ostream & print_set(std::ostream &o, const std::string &format="text") const
Definition: ratexpset.hh:206
value_t lmul(const weight_t &w, value_t e) const
Left-multiplication by a weight.
Definition: ratexpset.hxx:692
typename node_t::type_t type_t
Definition: ratexpset.hh:89
value_t shuffle(value_t l, value_t r) const
Definition: ratexpset.hxx:567
static size_t hash(const value_t &l)
Hash l.
Definition: ratexpset.hxx:833
const context_t & context() const
Definition: ratexpset.hxx:121
value_t complement(value_t e) const
Add a complement operator.
Definition: ratexpset.hxx:655
value_t zero() const
Definition: ratexpset.hxx:154
static auto atom(const label_t &v) -> value_t
Definition: ratexpset.hxx:146
static bool less_than(value_t l, value_t r)
Whether l < r.
Definition: ratexpset.hxx:807
static value_t special()
When used as a LabelSet for automata.
Definition: ratexpset.hh:133
static bool is_special(value_t v)
When used as a LabelSet for automata.
Definition: ratexpset.hh:140
bool is_zero(value_t v) const ATTRIBUTE_PURE
Definition: ratexpset.hxx:795
value_t parse(const std::string &s, size_t &p) const
Definition: ratexpset.hh:318
value_t conv(std::istream &is) const
Definition: ratexpset.hxx:897
static self_type make(std::istream &is)
Build from the description in is.
Definition: ratexpset.hxx:98
bool is_letter(value_t) const
Definition: ratexpset.hh:145
word_t word(label_t l) const
Make a ‘word’ out of a ratexp.
Definition: ratexpset.hh:358
weightset_t_of< context_t > weightset_t
Definition: ratexpset.hh:51
ratexpset< Context > self_type
Definition: ratexpset.hh:48
static value_t one()
Definition: ratexpset.hxx:160
std::shared_ptr< const node_t > ratexp_t
Definition: ratexpset.hh:87
const weightset_ptr & weightset() const
Definition: ratexpset.hxx:141
std::ostream & print(const value_t v, std::ostream &o, const std::string &format="text") const
Definition: ratexpset.hxx:905
typename node_t::ratexps_t ratexps_t
Definition: ratexpset.hh:90
typename weightset_t::value_t weight_t
Definition: ratexpset.hh:56
static constexpr bool is_free()
Definition: ratexpset.hh:173
value_t add(value_t l, value_t r) const
Definition: ratexpset.hxx:199
static constexpr star_status_t star_status()
Definition: ratexpset.hh:178
value_t rdiv(value_t l, value_t r) const
Definition: ratexpset.hxx:560
static bool equals(value_t l, value_t r)
Whether l == r.
Definition: ratexpset.hxx:824
Definition: ratexp.hh:176
An inner node with multiple children.
Definition: ratexp.hh:115
An inner node implementing a weight.
Definition: ratexp.hh:208
The semiring of Integers.
Definition: z.hh:34
int value_t
Definition: z.hh:55
#define DEFINE(Type)
Type of ratexps.
Definition: ratexpset.hh:64
star_status_t
The different behaviours a weightset may have with respect to the star.
Definition: enums.hh:161
@ STARRABLE
The star of every element exists.
Definition: enums.hh:163
type_t
The possible types of ratexps.
Definition: fwd.hh:48
identities
A ratexpset can implement several different sets of identities on expressions.
Definition: identities.hh:32
std::string to_string(identities i)
typename internal::label_t_of_impl< internal::base_t< ValueSet > >::type label_t_of
Helper to retrieve the type of the labels of a value set.
Definition: traits.hh:71
decltype(join(std::declval< ValueSets >()...)) join_t
Computation of the join of some value sets.
Definition: context.hh:206
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
typename internal::labelset_t_of_impl< internal::base_t< ValueSet > >::type labelset_t_of
Helper to retrieve the type of the labelset of a value set.
Definition: traits.hh:76
auto format(const ValueSet &vs, const typename ValueSet::value_t &v, Args &&... args) -> std::string
Format v via vs.print.
Definition: stream.hh:109
pair_automaton< Aut > pair(const Aut &aut, bool keep_initials=false)
Definition: synchronizing_word.hh:266
typename internal::weightset_t_of_impl< internal::base_t< ValueSet > >::type weightset_t_of
Helper to retrieve the type of the weightset of a value set.
Definition: traits.hh:86
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
Definition: qfraction.hh:26
Definition: exp_parser.hh:52
marker type for labelsets where labels are rational expressions
Definition: kind.hh:82
Provide a variadic mul on top of a binary mul(), and one().
Definition: weightset.hh:38