Awali
Another Weighted Automata library
ratexpset.hh
Go to the documentation of this file.
1 // This file is part of Awali.
2 // Copyright 2016-2023 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>
84 # undef DEFINE
85  template <exp::type_t Type>
87  template <exp::type_t Type>
89  using ratexp_t = std::shared_ptr<const node_t>;
90 
91  using type_t = typename node_t::type_t;
92  using ratexps_t = typename node_t::ratexps_t;
93 
95  using value_t = typename node_t::value_t;
96 
98  using values_t = std::vector<value_t>;
99 
100  using word_t = self_type;
102 
103  public:
105  static std::string sname();
107  std::string vname(bool full = true) const;
109  static self_type make(std::istream& is);
110 
114  ratexpset_impl(const context_t& ctx,
115  identities_t identities); // FIXME: make this optional again?
116 
120  bool open(bool o) const;
121 
122  const context_t& context() const;
123 
124 
125  identities_t identities() const;
126  bool is_series() const;
127 
128  const labelset_ptr& labelset() const;
129  const weightset_ptr& weightset() const;
130 
131  static auto atom(const label_t& v)
132  -> value_t;
133 
135  static value_t special()
136  {
137  return atom(labelset_t::special());
138  }
139 
142  static bool is_special(value_t v)
143  {
144  return equals(special(), v);
145  }
146 
147  bool is_letter(value_t) const
148  {
149  return false;
150  }
151 
152  bool is_zero(value_t v) const ATTRIBUTE_PURE;
153  static bool is_one(value_t v) ATTRIBUTE_PURE;
154 
155  static constexpr bool is_commutative_semiring()
156  {
157  return false;
158  }
159 
160  static constexpr bool show_one()
161  {
162  return false;
163  }
164 
165  static constexpr bool has_one()
166  {
167  return true;
168  }
169 
170  static constexpr bool is_ratexpset()
171  {
172  return true;
173  }
174 
175  static constexpr bool is_free()
176  {
177  return false;
178  }
179 
180  static constexpr star_status_t star_status()
181  {
183  }
184 
185  value_t conv(std::istream& is) const;
186  template <typename GenSet>
188  typename letterset<GenSet>::value_t v) const;
189  value_t conv(b, typename b::value_t v) const;
190  value_t conv(const z& ws, typename z::value_t v) const;
191  value_t conv(const q& ws, typename q::value_t v) const;
192  value_t conv(const r& ws, typename r::value_t v) const;
193  template <typename Ctx2>
195  typename ratexpset_impl<Ctx2>::value_t v) const;
196 
197  value_t conv(self_type, value_t v) const;
198 
199  std::set<value_t> convs(std::istream&) const
200  {
201  raise(vname(), ": ranges not implemented");
202  }
203 
204  std::ostream& print(const value_t v, std::ostream& o,
205  const std::string& format = "text") const;
206 
207  std::ostream&
208  print_set(std::ostream& o, const std::string& format = "text") const
209  {
210  if (format == "latex")
211  {
212  o << "\\mathsf{";
213  switch (identities())
214  {
215  case identities_t::trivial:
216  case identities_t::associativity:
217  o << "RatE";
218  break;
219  case identities_t::series:
220  o << "Series";
221  break;
222  default:
223  assert(false);
224  };
225  o << "}[";
226  context().print_set(o, format);
227  o << ']';
228  }
229  else if (format == "text") {
230  switch (identities())
231  {
232  case identities_t::trivial:
233  case identities_t::associativity:
234  o << "RatExp";
235  break;
236  case identities_t::series:
237  o << "Series";
238  break;
239  default:
240  assert(false);
241  };
242  o << "[";
243  context().print_set(o, format);
244  o << ']';
245  }
246  else
247  raise("invalid format: ", format);
248  return o;
249  }
250 
251 
252 
253  template<unsigned version = version::fsm_json>
255  const
256  {
257  version::check_fsmjson<version>();
258  switch (version) {
259  default:
260  json::object_t* obj
261  = context().template to_json<version>()->object();
262  json::object_t* res = new json::object_t();
263  switch (identities())
264  {
265  case identities_t::trivial:
266  case identities_t::associativity:
267  res->push_back("Rational Expression",obj);
268  break;
269  case identities_t::series:
270  res->push_back("Series",obj);
271  break;
272  default:
273  assert(false);
274  };
275  return res;
276  }
277  }
278 
279 
280 
281  template<unsigned version = version::fsm_json>
282  json::node_t*
284  const
285  {
286  switch (version) {
287  case 0:
288  throw parse_exception("[ratexpset] Unsupported fsm-json version:"
289  + std::to_string(version));
290  case 1:
291  default:
292  rat::json_visitor<ratexpset_impl<Context>, version> jsonner(*this);
293  return jsonner(v);
294  }
295  }
296 
297  template<unsigned version = version::fsm_json>
298  value_t
300  const
301  {
302  switch (version) {
303  case 0:
304  throw parse_exception("[ratexpset] Unsupported fsm-json version:"
305  + std::to_string(version));
306  case 1:
307  default:
308  return js_parse_exp_content(*this,p);
309  }
310  }
311 
312 
313  //value_t
314  //js_parse(json::node_t* p) const;
315 
316  value_t
317  parse(const std::string & s, size_t& p) const {
318  auto parser = awali::sttc::internal::exp_parser<ratexpset_impl>(*this, s, p);
319  value_t v=parser.parseE();
320  p=parser.p_;
321  return v;
322  }
323 
324  public:
326  static bool less_than(value_t l, value_t r);
327 
329  static bool equals(value_t l, value_t r);
330 
332  static size_t hash(const value_t& l);
333 
334  // Concrete type implementation.
335  value_t zero() const;
336  static value_t one();
337  value_t add(value_t l, value_t r) const;
338  value_t mul(value_t l, value_t r) const;
339  value_t concat(value_t l, value_t r) const;
340  value_t conjunction(value_t l, value_t r) const;
341  value_t shuffle(value_t l, value_t r) const;
342  value_t ldiv(value_t l, value_t r) const;
343  value_t rdiv(value_t l, value_t r) const;
344  value_t star(value_t e) const;
345  value_t maybe(value_t e) const;
346  value_t plus(value_t e) const;
348  value_t complement(value_t e) const;
350  value_t transposition(value_t e) const;
352  value_t rmul(value_t e, const weight_t& w) const;
354  value_t lmul(const weight_t& w, value_t e) const;
356  value_t transpose(value_t e) const;
357 
359  word_t word(label_t l) const
360  {
361  return l;
362  }
363 
365  template <typename... Args>
366  value_t letter_class(Args&&... chars) const;
367 
368  std::string to_string(value_t e) const; // Mostly for internal convenience.
369 
370  private:
371  void require_weightset_commutativity() const;
372  bool less_than_ignoring_weight_(value_t l, value_t r) const;
373  value_t remove_from_sum_series_(ratexps_t addends,
374  typename ratexps_t::iterator i) const;
375  value_t insert_in_sum_series_(const sum_t& addends, value_t r) const;
376  value_t merge_sum_series_(const sum_t& addends1, value_t aa2) const;
377  value_t add_nonzero_series_(value_t l, value_t r) const;
378  exp::type_t type_ignoring_lweight_(value_t e) const;
379  weight_t possibly_implicit_lweight_(value_t e) const;
380  value_t unwrap_possible_lweight_(value_t e) const;
381  value_t mul_expressions_(value_t l, value_t r) const;
382  value_t mul_series_(value_t l, value_t r) const;
383  value_t mul_(value_t l, value_t r, bool series) const;
384  bool is_unweighted_nonsum_(value_t v) const;
385  bool is_nonsum_(value_t v) const;
386  value_t mul_atoms_(const label_t& l, const label_t& r) const;
387  value_t mul_atoms_(const label_t& l, const label_t& r, std::true_type) const; // law.
388  value_t mul_atoms_(const label_t& l, const label_t& r, std::false_type) const; // ! law.
389  value_t mul_unweighted_nontrivial_products_(value_t a, value_t b) const;
390  value_t mul_products_(value_t a, value_t b) const;
391  value_t nontrivial_mul_expressions_(value_t l, value_t r) const;
392  value_t nontrivial_mul_series_(value_t l, value_t r) const;
393  value_t nontrivial_lmul_expression_(const weight_t& w, value_t s) const;
394  value_t nontrivial_lmul_series_(const weight_t& w, value_t s) const;
395  value_t nontrivial_rmul_expression_(value_t e, const weight_t& w) const;
396  value_t nontrivial_rmul_series_(value_t e, const weight_t& w) const;
397 
401  template <exp::type_t Type>
402  void gather(ratexps_t& res, value_t v) const;
403 
408  template <exp::type_t Type>
409  ratexps_t gather(value_t l, value_t r) const;
410 
412  value_t concat_(value_t l, value_t r, std::true_type) const;
414  value_t concat_(value_t l, value_t r, std::false_type) const;
415 
417  template <typename LabelSet_, typename... Args>
418  value_t letter_class_(const Args&&... chars, std::true_type) const;
419 
421  template <typename LabelSet_>
422  value_t
423  letter_class_(std::set<std::pair<typename LabelSet_::letter_t,
424  typename LabelSet_::letter_t>> chars,
425  bool accept,
426  std::false_type) const;
427 
428  private:
429  context_t ctx_;
430  const identities_t identities_;
431  };
432  } // rat::
433 
435  template <typename Ctx1, typename Ctx2>
436  inline
437  auto
440  {
441  return {meet(a.context(), b.context()),
442  meet(a.identities(), b.identities())};
443  }
444 
446  template <typename Ctx1, typename Ctx2>
447  inline
448  auto
451  {
452  return {join(a.context(), b.context()),
453  join(a.identities(), b.identities())};
454  }
455 
456  // Used as a labelset.
457  template <typename GenSet1, typename Ctx2>
458  inline
459  auto
463  {
466  return {ctx_t{join(a, *b.labelset()), *b.weightset()},
467  b.identities()};
468  }
469 
470  template <typename Ctx1, typename GenSet2>
471  inline
472  auto
474  -> decltype(join(b, a))
475  {
476  return join(b, a);
477  }
478 
479  // B. FIXME: screams for refactoring!
480 
481  template <typename Context>
482  inline
483  ratexpset<Context>
484  join(const ratexpset<Context>& a, const b&)
485  {
486  return a;
487  }
488 
489  template <typename Context>
490  inline
491  ratexpset<Context>
492  join(const b& a, const ratexpset<Context>& b)
493  {
494  return join(b, a);
495  }
496 
497  // Z.
498  template <typename Context>
499  inline
500  auto
501  join(const ratexpset<Context>& rs, const z& ws)
504  {
505  using ctx_t = context<labelset_t_of<Context>,
507  return {ctx_t{*rs.labelset(), join(*rs.weightset(), ws)},
508  rs.identities()};
509  }
510 
511  template <typename Context>
512  inline
513  auto
514  join(const z& ws, const ratexpset<Context>& rs)
516  {
517  return join(rs, ws);
518  }
519 
520  // Q.
521  template <typename Context>
522  inline
523  auto
524  join(const ratexpset<Context>& rs, const q& ws)
527  {
528  using ctx_t = context<labelset_t_of<Context>,
530  return {ctx_t{*rs.labelset(), join(*rs.weightset(), ws)},
531  rs.identities()};
532  }
533 
534  template <typename Context>
535  inline
536  auto
537  join(const q& ws, const ratexpset<Context>& rs)
539  {
540  return join(rs, ws);
541  }
542 
543  // R.
544  template <typename Context>
545  inline
546  auto
547  join(const ratexpset<Context>& rs, const r& ws)
550  {
551  using ctx_t = context<labelset_t_of<Context>,
553  return {ctx_t{*rs.labelset(), join(*rs.weightset(), ws)},
554  rs.identities()};
555  }
556 
557  template <typename Context>
558  inline
559  auto
560  join(const r& ws, const ratexpset<Context>& rs)
561  // FIXME: loops if wrong order.
563  {
564  return join(rs, ws);
565  }
566  }
567 }//end of ns awali::stc
568 
570 
571 #endif // !AWALI_CORE_RAT_RATEXPSET_HH
572 
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:155
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:95
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:283
static constexpr bool is_ratexpset()
Definition: ratexpset.hh:170
std::string to_string(value_t e) const
Definition: ratexpset.hxx:810
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:165
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:98
value_t transpose(value_t e) const
The transposed of this rational expression.
Definition: ratexpset.hxx:939
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:828
value_t maybe(value_t e) const
Definition: ratexpset.hxx:655
value_t transposition(value_t e) const
Add a transposition operator.
Definition: ratexpset.hxx:695
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:761
std::set< value_t > convs(std::istream &) const
Definition: ratexpset.hh:199
json::node_t * to_json() const
Definition: ratexpset.hh:254
static constexpr bool show_one()
Definition: ratexpset.hh:160
label_t_of< context_t > label_t
Definition: ratexpset.hh:55
typename context_t::labelset_ptr labelset_ptr
Definition: ratexpset.hh:53
value_t plus(value_t e) const
Definition: ratexpset.hxx:666
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:299
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:208
value_t lmul(const weight_t &w, value_t e) const
Left-multiplication by a weight.
Definition: ratexpset.hxx:719
typename node_t::type_t type_t
Definition: ratexpset.hh:91
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:860
const context_t & context() const
Definition: ratexpset.hxx:121
value_t complement(value_t e) const
Add a complement operator.
Definition: ratexpset.hxx:682
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:834
static value_t special()
When used as a LabelSet for automata.
Definition: ratexpset.hh:135
static bool is_special(value_t v)
When used as a LabelSet for automata.
Definition: ratexpset.hh:142
bool is_zero(value_t v) const ATTRIBUTE_PURE
Definition: ratexpset.hxx:822
value_t parse(const std::string &s, size_t &p) const
Definition: ratexpset.hh:317
value_t conv(std::istream &is) const
Definition: ratexpset.hxx:924
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:147
word_t word(label_t l) const
Make a ‘word’ out of a ratexp.
Definition: ratexpset.hh:359
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:89
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:932
typename node_t::ratexps_t ratexps_t
Definition: ratexpset.hh:92
typename weightset_t::value_t weight_t
Definition: ratexpset.hh:56
static constexpr bool is_free()
Definition: ratexpset.hh:175
value_t add(value_t l, value_t r) const
Definition: ratexpset.hxx:199
static constexpr star_status_t star_status()
Definition: ratexpset.hh:180
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:851
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:449
auto meet(const ratexpset< Ctx1 > &a, const ratexpset< Ctx2 > &b) -> ratexpset< meet_t< Ctx1, Ctx2 >>
The meet of two ratexpsets.
Definition: ratexpset.hh:438
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:99
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