Awali
Another Weighted Automata library
ratexpset.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_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  version::check_fsmjson<version>();
256  switch (version) {
257  default:
258  json::object_t* obj
259  = context().template to_json<version>()->object();
260  json::object_t* res = new json::object_t();
261  switch (identities())
262  {
263  case identities_t::trivial:
264  case identities_t::associativity:
265  res->push_back("Rational Expression",obj);
266  break;
267  case identities_t::series:
268  res->push_back("Series",obj);
269  break;
270  default:
271  assert(false);
272  };
273  return res;
274  }
275  }
276 
277 
278 
279  template<unsigned version = version::fsm_json>
280  json::node_t*
282  const
283  {
284  switch (version) {
285  case 0:
286  throw parse_exception("[ratexpset] Unsupported fsm-json version:"
287  + std::to_string(version));
288  case 1:
289  default:
290  rat::json_visitor<ratexpset_impl<Context>, version> jsonner(*this);
291  return jsonner(v);
292  }
293  }
294 
295  template<unsigned version = version::fsm_json>
296  value_t
298  const
299  {
300  switch (version) {
301  case 0:
302  throw parse_exception("[ratexpset] Unsupported fsm-json version:"
303  + std::to_string(version));
304  case 1:
305  default:
306  return js_parse_exp_content(*this,p);
307  }
308  }
309 
310 
311  //value_t
312  //js_parse(json::node_t* p) const;
313 
314  value_t
315  parse(const std::string & s, size_t& p) const {
316  auto parser = awali::sttc::internal::exp_parser<ratexpset_impl>(*this, s, p);
317  value_t v=parser.parseE();
318  p=parser.p_;
319  return v;
320  }
321 
322  public:
324  static bool less_than(value_t l, value_t r);
325 
327  static bool equals(value_t l, value_t r);
328 
330  static size_t hash(const value_t& l);
331 
332  // Concrete type implementation.
333  value_t zero() const;
334  static value_t one();
335  value_t add(value_t l, value_t r) const;
336  value_t mul(value_t l, value_t r) const;
337  value_t concat(value_t l, value_t r) const;
338  value_t conjunction(value_t l, value_t r) const;
339  value_t shuffle(value_t l, value_t r) const;
340  value_t ldiv(value_t l, value_t r) const;
341  value_t rdiv(value_t l, value_t r) const;
342  value_t star(value_t e) const;
344  value_t complement(value_t e) const;
346  value_t transposition(value_t e) const;
348  value_t rmul(value_t e, const weight_t& w) const;
350  value_t lmul(const weight_t& w, value_t e) const;
352  value_t transpose(value_t e) const;
353 
355  word_t word(label_t l) const
356  {
357  return l;
358  }
359 
361  template <typename... Args>
362  value_t letter_class(Args&&... chars) const;
363 
364  std::string to_string(value_t e) const; // Mostly for internal convenience.
365 
366  private:
367  void require_weightset_commutativity() const;
368  bool less_than_ignoring_weight_(value_t l, value_t r) const;
369  value_t remove_from_sum_series_(ratexps_t addends,
370  typename ratexps_t::iterator i) const;
371  value_t insert_in_sum_series_(const sum_t& addends, value_t r) const;
372  value_t merge_sum_series_(const sum_t& addends1, value_t aa2) const;
373  value_t add_nonzero_series_(value_t l, value_t r) const;
374  exp::type_t type_ignoring_lweight_(value_t e) const;
375  weight_t possibly_implicit_lweight_(value_t e) const;
376  value_t unwrap_possible_lweight_(value_t e) const;
377  value_t mul_expressions_(value_t l, value_t r) const;
378  value_t mul_series_(value_t l, value_t r) const;
379  value_t mul_(value_t l, value_t r, bool series) const;
380  bool is_unweighted_nonsum_(value_t v) const;
381  bool is_nonsum_(value_t v) const;
382  value_t mul_atoms_(const label_t& l, const label_t& r) const;
383  value_t mul_atoms_(const label_t& l, const label_t& r, std::true_type) const; // law.
384  value_t mul_atoms_(const label_t& l, const label_t& r, std::false_type) const; // ! law.
385  value_t mul_unweighted_nontrivial_products_(value_t a, value_t b) const;
386  value_t mul_products_(value_t a, value_t b) const;
387  value_t nontrivial_mul_expressions_(value_t l, value_t r) const;
388  value_t nontrivial_mul_series_(value_t l, value_t r) const;
389  value_t nontrivial_lmul_expression_(const weight_t& w, value_t s) const;
390  value_t nontrivial_lmul_series_(const weight_t& w, value_t s) const;
391  value_t nontrivial_rmul_expression_(value_t e, const weight_t& w) const;
392  value_t nontrivial_rmul_series_(value_t e, const weight_t& w) const;
393 
397  template <exp::type_t Type>
398  void gather(ratexps_t& res, value_t v) const;
399 
404  template <exp::type_t Type>
405  ratexps_t gather(value_t l, value_t r) const;
406 
408  value_t concat_(value_t l, value_t r, std::true_type) const;
410  value_t concat_(value_t l, value_t r, std::false_type) const;
411 
413  template <typename LabelSet_, typename... Args>
414  value_t letter_class_(const Args&&... chars, std::true_type) const;
415 
417  template <typename LabelSet_>
418  value_t
419  letter_class_(std::set<std::pair<typename LabelSet_::letter_t,
420  typename LabelSet_::letter_t>> chars,
421  bool accept,
422  std::false_type) const;
423 
424  private:
425  context_t ctx_;
426  const identities_t identities_;
427  };
428  } // rat::
429 
431  template <typename Ctx1, typename Ctx2>
432  inline
433  auto
436  {
437  return {meet(a.context(), b.context()),
438  meet(a.identities(), b.identities())};
439  }
440 
442  template <typename Ctx1, typename Ctx2>
443  inline
444  auto
447  {
448  return {join(a.context(), b.context()),
449  join(a.identities(), b.identities())};
450  }
451 
452  // Used as a labelset.
453  template <typename GenSet1, typename Ctx2>
454  inline
455  auto
459  {
462  return {ctx_t{join(a, *b.labelset()), *b.weightset()},
463  b.identities()};
464  }
465 
466  template <typename Ctx1, typename GenSet2>
467  inline
468  auto
470  -> decltype(join(b, a))
471  {
472  return join(b, a);
473  }
474 
475  // B. FIXME: screams for refactoring!
476 
477  template <typename Context>
478  inline
479  ratexpset<Context>
480  join(const ratexpset<Context>& a, const b&)
481  {
482  return a;
483  }
484 
485  template <typename Context>
486  inline
487  ratexpset<Context>
488  join(const b& a, const ratexpset<Context>& b)
489  {
490  return join(b, a);
491  }
492 
493  // Z.
494  template <typename Context>
495  inline
496  auto
497  join(const ratexpset<Context>& rs, const z& ws)
500  {
501  using ctx_t = context<labelset_t_of<Context>,
503  return {ctx_t{*rs.labelset(), join(*rs.weightset(), ws)},
504  rs.identities()};
505  }
506 
507  template <typename Context>
508  inline
509  auto
510  join(const z& ws, const ratexpset<Context>& rs)
512  {
513  return join(rs, ws);
514  }
515 
516  // Q.
517  template <typename Context>
518  inline
519  auto
520  join(const ratexpset<Context>& rs, const q& ws)
523  {
524  using ctx_t = context<labelset_t_of<Context>,
526  return {ctx_t{*rs.labelset(), join(*rs.weightset(), ws)},
527  rs.identities()};
528  }
529 
530  template <typename Context>
531  inline
532  auto
533  join(const q& ws, const ratexpset<Context>& rs)
535  {
536  return join(rs, ws);
537  }
538 
539  // R.
540  template <typename Context>
541  inline
542  auto
543  join(const ratexpset<Context>& rs, const r& ws)
546  {
547  using ctx_t = context<labelset_t_of<Context>,
549  return {ctx_t{*rs.labelset(), join(*rs.weightset(), ws)},
550  rs.identities()};
551  }
552 
553  template <typename Context>
554  inline
555  auto
556  join(const r& ws, const ratexpset<Context>& rs)
557  // FIXME: loops if wrong order.
559  {
560  return join(rs, ws);
561  }
562  }
563 }//end of ns awali::stc
564 
566 
567 #endif // !AWALI_CORE_RAT_RATEXPSET_HH
568 
Definition: node.hh:193
Definition: node.hh:367
object_t * push_back(std::string key, node_t *node)
Definition: qfraction.hh:26
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:42
The semiring of floating Numbers.
Definition: r.hh:35
double value_t
Definition: r.hh:56
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:281
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:297
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:315
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:355
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:35
int value_t
Definition: z.hh:56
#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:163
@ STARRABLE
The star of every element exists.
Definition: enums.hh:165
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:210
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
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
RatExpSet::ratexp_t js_parse_exp_content(const RatExpSet &rs, json::node_t const *p)
Definition: js_parser.hh:95
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:42
Main namespace of Awali.
Definition: ato.hh:22
Exceptions thrown during parsing.
Definition: parse_exception.hh:26
Definition: exp_parser.hh:59
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