Vcsn  2.1
Be Rational
expressionset.hh
Go to the documentation of this file.
1 #ifndef VCSN_CORE_RAT_EXPRESSIONSET_HH
2 # define VCSN_CORE_RAT_EXPRESSIONSET_HH
3 
4 # include <set>
5 # include <string>
6 
8 # include <vcsn/core/rat/printer.hh>
10 # include <vcsn/ctx/context.hh>
11 # include <vcsn/labelset/labelset.hh>
13 # include <vcsn/labelset/oneset.hh>
14 # include <vcsn/misc/raise.hh>
15 # include <vcsn/misc/star-status.hh>
16 # include <vcsn/weightset/b.hh>
17 # include <vcsn/weightset/nmin.hh>
18 # include <vcsn/weightset/q.hh>
19 # include <vcsn/weightset/r.hh>
20 # include <vcsn/weightset/z.hh>
21 # include <vcsn/weightset/zmin.hh>
22 
23 namespace vcsn
24 {
25  namespace rat
26  {
29  template <typename Context>
31  {
32  public:
34  using context_t = Context;
38  using labelset_ptr = typename context_t::labelset_ptr;
39  using weightset_ptr = typename context_t::weightset_ptr;
41  using weight_t = typename weightset_t::value_t;
44 
46  //
47  // See http://stackoverflow.com/questions/15537023 to know why we
48  // add the vcsn::rat:: part: GCC wants it, Clang does not care,
49  // both are right.
50 # define DEFINE(Type) \
51  using Type ## _t = vcsn::rat::Type<context_t>
70 # undef DEFINE
71 
73  using value_t = typename node_t::value_t;
75  using type_t = typename node_t::type_t;
77  using values_t = typename node_t::values_t;
78 
79  template <type_t Type>
81  template <type_t Type>
83 
84  using word_t = value_t;
85  using letter_t = value_t;
86 
87  public:
89  static symbol sname();
91  static self_t make(std::istream& is);
92 
97 
101  bool open(bool o) const;
102 
104  const context_t& context() const;
105 
107  identities_t identities() const;
108 
110  const labelset_ptr& labelset() const;
112  const weightset_ptr& weightset() const;
113 
115  static value_t special()
116  {
117  return atom(labelset_t::special());
118  }
119 
121  static bool is_special(const value_t& v)
122  {
123  return equal(special(), v);
124  }
125 
127  bool is_letter(value_t) const
128  {
129  return false;
130  }
131 
133  bool is_zero(const value_t& v) const ATTRIBUTE_PURE;
134 
136  static bool is_one(const value_t& v) ATTRIBUTE_PURE;
137 
139  static constexpr bool is_letterized()
140  {
141  return false;
142  }
143 
145  static constexpr bool is_commutative()
146  {
147  return false;
148  }
149 
151  static constexpr bool is_idempotent()
152  {
153  // FIXME: well, the truth is that we are idempotent if the
154  // weightset is, _and_ we apply ACI to addition.
155  return weightset_t::is_idempotent();
156  }
157 
159  static constexpr bool show_one()
160  {
161  return false;
162  }
163 
165  static constexpr bool has_one()
166  {
167  return true;
168  }
169 
171  static constexpr bool is_expressionset()
172  {
173  return true;
174  }
175 
177  static constexpr bool is_free()
178  {
179  return false;
180  }
181 
183  static constexpr star_status_t star_status()
184  {
186  }
187 
188  template <typename GenSet>
189  value_t conv(const letterset<GenSet>& ls,
190  typename letterset<GenSet>::value_t v) const;
191  value_t conv(b, typename b::value_t v) const;
192  value_t conv(const z& ws, typename z::value_t v) const;
193  value_t conv(const q& ws, typename q::value_t v) const;
194  value_t conv(const r& ws, typename r::value_t v) const;
195  value_t conv(const nmin& ws, typename nmin::value_t v) const;
196  value_t conv(const zmin& ws, typename zmin::value_t v) const;
197  template <typename Ctx2>
198  value_t conv(const expressionset<Ctx2>& ws,
199  typename expressionset<Ctx2>::value_t v) const;
200 
202  static size_t size(const value_t& v);
203 
205  static bool less(const value_t& l, const value_t& r);
206 
211  static bool less_linear(const value_t& l, const value_t& r);
212 
214  static bool equal(const value_t& l, const value_t& r);
215 
217  static size_t hash(const value_t& v);
218 
220  static auto atom(const label_t& v)
221  -> value_t;
222 
223  // Concrete type implementation.
224  value_t zero() const;
225  static value_t one();
226  value_t add(const value_t& l, const value_t& r) const;
227  value_t mul(const value_t& l, const value_t& r) const;
228 
238  value_t concat(const value_t& l, const value_t& r) const;
239 
240  value_t conjunction(const value_t& l, const value_t& r) const;
241  value_t infiltration(const value_t& l, const value_t& r) const;
242  value_t shuffle(const value_t& l, const value_t& r) const;
243  template <typename... Value>
244  value_t tuple(Value&&... v) const;
246  value_t power(const value_t& e, unsigned n) const;
247  value_t ldiv(const value_t& l, const value_t& r) const;
248  value_t rdiv(const value_t& l, const value_t& r) const;
249  value_t star(const value_t& e) const;
251  value_t complement(const value_t& e) const;
253  value_t transposition(const value_t& e) const;
255  value_t rmul(const value_t& e, const weight_t& w) const;
257  value_t lmul(const weight_t& w, const value_t& e) const;
259  value_t transpose(const value_t& e) const;
260 
262  word_t word(label_t l) const
263  {
264  return l;
265  }
266 
268  template <typename... Args>
269  value_t letter_class(Args&&... chars) const;
270 
272  value_t conv(std::istream& is, bool = true) const;
273 
275  value_t conv(const self_t&, const value_t& v) const;
276 
278  template <typename Fun>
279  static void convs(std::istream&, Fun)
280  {
281  raise(sname(), ": ranges not implemented");
282  }
283 
284  std::ostream& print(const value_t& v, std::ostream& o,
285  format fmt = {}) const;
286 
288  std::ostream& print_set(std::ostream& o,
289  format fmt = {}) const;
290 
292  template <unsigned Tape, typename Ctx = context_t>
293  using focus_t
295 
296 
297  template <typename Sequence>
299 
300  template <size_t... I>
301  struct as_tupleset_impl<detail::index_sequence<I...>>
302  {
305 
306  static type value(const self_t& self)
307  {
308  return {detail::make_project<I>(self)...};
309  }
310  };
311 
313  template <typename Ctx = context_t>
314  using as_tupleset_t
316 
318  template <typename Ctx = context_t>
319  auto as_tupleset() const
320  -> enable_if_t<Ctx::is_lat, as_tupleset_t<Ctx>>
321  {
323  }
324 
325  private:
336  const self_t& self() const { return static_cast<const self_t&>(*this); }
337 
340  value_t add_(values_t&& vs) const;
341 
342  value_t add_linear_(const sum_t& addends, const value_t& r) const;
343  value_t add_linear_(const sum_t& s1, const sum_t& s2) const;
344 
348  value_t add_linear_(const value_t& l, const value_t& r) const;
349 
352  static value_t unwrap_possible_lweight_(const value_t& e);
355  static type_t type_ignoring_lweight_(const value_t& e);
359 
363  template <type_t Type>
364  void gather_(values_t& res, const value_t& v) const;
365 
370  template <type_t Type>
371  values_t gather_(const value_t& l, const value_t& r) const;
372 
374  value_t concat_(const value_t& l, const value_t& r, std::true_type) const;
376  value_t concat_(const value_t& l, const value_t& r, std::false_type) const;
377 
379  template <typename LabelSet_, typename... Args>
380  value_t letter_class_(const Args&&... chars, std::true_type) const;
381 
383  template <typename LabelSet_>
384  value_t
385  letter_class_(std::set<std::pair<typename LabelSet_::letter_t,
386  typename LabelSet_::letter_t>> chars,
387  bool accept,
388  std::false_type) const;
389 
391  template <typename Dummy = void>
393  {
395  static bool is_label(const tuple_t& v)
396  {
397  return is_label_(v, labelset_t::indices);
398  }
399 
402  static label_t as_label(const tuple_t& v)
403  {
404  return as_label_(v, labelset_t::indices);
405  }
406 
407  template <size_t... I>
409  {
410  for (auto b: {(std::get<I>(v.sub())->type() == type_t::atom
411  || (std::get<I>(v.sub())->type() == type_t::one
412  && labelset_t::template valueset_t<I>::has_one()))...})
413  if (!b)
414  return false;
415  return true;
416  }
417 
418  template <size_t... I>
420  {
421  return label_t{as_label_<I>(v)...};
422  }
423 
424  template <size_t I>
425  static typename focus_t<I>::label_t as_label_(const tuple_t& v)
426  {
427  if (std::get<I>(v.sub())->type() == type_t::one)
428  return detail::label_one<typename labelset_t::template valueset_t<I>>();
429  else
430  return std::dynamic_pointer_cast<const typename focus_t<I>::atom_t>
431  (std::get<I>(v.sub()))->value();
432  }
433  };
434 
435  private:
440  };
441  } // rat::
442 
443  namespace detail
444  {
446  template <typename Ctx>
448  {
450  static type value(const type& ls)
451  {
452  return ls;
453  }
454  };
455 
457  template <typename Ctx>
459  {
461  static type value(const type& ls)
462  {
463  return ls;
464  }
465  };
466 
468  template <typename Ctx1, typename Ctx2>
469  struct join_impl<expressionset<Ctx1>, expressionset<Ctx2>>
470  {
472 
473  static type join(const expressionset<Ctx1>& lhs,
474  const expressionset<Ctx2>& rhs)
475  {
476  return {vcsn::join(lhs.context(), rhs.context()),
477  vcsn::join(lhs.identities(), rhs.identities())};
478  }
479  };
480 
482  // FIXME: what about the other labelsets?
483  template <typename GenSet1, typename Ctx2>
484  struct join_impl<letterset<GenSet1>, expressionset<Ctx2>>
485  {
489 
490  static type join(const letterset<GenSet1>& a,
491  const expressionset<Ctx2>& b)
492  {
493  return {context_t{vcsn::join(a, *b.labelset()), *b.weightset()},
494  b.identities()};
495  }
496  };
497 
498  // B. FIXME: screams for refactoring!
499  template <typename Context>
500  struct join_impl<b, expressionset<Context>>
501  {
503  static type join(const b&, const expressionset<Context>& rhs)
504  {
505  return rhs;
506  }
507  };
508 
509  template <typename W1, typename W2>
511 
512  template <typename WeightSet, typename Context>
514  {
518  static type join(const WeightSet& ws, const expressionset<Context>& rs)
519  {
520  return {context_t{*rs.labelset(), vcsn::join(ws, *rs.weightset())},
521  rs.identities()};
522  }
523  };
524 #define JOIN_IMPL_SIMPLE(WS) \
525  template <typename Context> \
526  struct join_impl<WS, expressionset<Context>> \
527  : public join_impl_simple<WS, expressionset<Context>> \
528  {};
529 
530 
535 
536 #undef JOIN_IMPL_SIMPLE
537 
538  }
539 
541  template <typename Context>
544  {
545  return {ctx, identities};
546  }
547 
549  template <typename Ctx1, typename Ctx2>
550  inline
551  auto
554  {
555  return {meet(a.context(), b.context()),
556  meet(a.identities(), b.identities())};
557  }
558 
559 } // namespace vcsn
560 
562 
563 #endif // !VCSN_CORE_RAT_EXPRESSIONSET_HH
564 
565 // This is ugly, yet I don't know how to address this circular
566 // dependency another way: expressionset.hxx uses is-valid-expression.hh,
567 // which, of course, also uses expressionset.hh.
568 //
569 // So let's have expressionset.hh first accept a forward declaration (via
570 // algos/fwd.hh), then provide here the needed definition. Do not
571 // leave this inside the CPP guard.
572 
typename node_t::value_t value_t
An expression (a shared pointer to a tree).
static constexpr star_status_t star_status()
When used as WeightSet.
static label_t as_label_(const tuple_t &v, detail::index_sequence< I...>)
static constexpr bool show_one()
When used as WeightSet.
typename context_t::labelset_ptr labelset_ptr
static void convs(std::istream &, Fun)
Read a range of expressions.
value_t concat_(const value_t &l, const value_t &r, std::true_type) const
If labelset is wordset.
weightset_t_of< context_t > weightset_t
auto as_tupleset() const -> enable_if_t< Ctx::is_lat, as_tupleset_t< Ctx >>
If we are multitape, ourself as a tupleset.
static bool less_linear(const value_t &l, const value_t &r)
Whether l < r, ignoring lweight.
Implementation of labels are letters.
Definition: fwd.hh:10
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
Definition: traits.hh:46
The root from which to derive the final node types.
Definition: expression.hh:302
static constexpr bool is_commutative()
When used as WeightSet.
label_t_of< context_t > label_t
static bool is_special(const value_t &v)
When used as a LabelSet.
static type join(const letterset< GenSet1 > &a, const expressionset< Ctx2 > &b)
auto label_one() -> enable_if_t< LabelSet::has_one(), typename LabelSet::value_t >
This LabelSet's one(), if supported.
Definition: labelset.hh:41
static focus_t< I >::label_t as_label_(const tuple_t &v)
const identities_t ids_
The set of rewriting rules to apply.
identities_t identities() const
Accessor to the identities set.
value_t ldiv(const value_t &l, const value_t &r) const
The abstract parameterized, root for all rational expression types.
Definition: expression.hh:80
A structure that implements the computation of join(V1, V2).
Definition: join.hh:18
std::string type(const automaton &a)
The implementation type of a.
Definition: others.cc:197
context_t ctx_
The context of the expressions.
type_t
The possible types of expressions.
Definition: fwd.hh:39
auto join(const ValueSet &vs) -> ValueSet
The join of a single valueset.
Definition: join.hh:44
std::istringstream is
The input stream: the specification to translate.
Definition: translate.cc:372
static size_t size(const value_t &v)
The size of v.
static constexpr bool is_letterized()
When used as a labelset.
Turn a tuple of expressions that are labels into a multi-tape label.
static size_t hash(const value_t &v)
Hash v.
vcsn::rat::sum< context_t > sum_t
value_t power(const value_t &e, unsigned n) const
Add a power operator.
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
Definition: traits.hh:51
labelset_t_of< context_t > labelset_t
static value_t special()
When used as a LabelSet.
typename std::enable_if< Cond, T >::type enable_if_t
Definition: type_traits.hh:16
value_t letter_class(Args &&...chars) const
An expression matching one character amongst chars.
static bool equal(const value_t &l, const value_t &r)
Whether l == r.
static value_t unwrap_possible_lweight_(const value_t &e)
If e is an lweight, then its child, otherwise e.
word_t word(label_t l) const
Make a `word' out of an expression.
#define DEFINE(Type)
Type of expressions.
typename context_t::weightset_ptr weightset_ptr
value_t complement(const value_t &e) const
Add a complement operator.
value_t mul(const value_t &l, const value_t &r) const
static type join(const b &, const expressionset< Context > &rhs)
static constexpr bool has_one()
When used as WeightSet.
typename as_tupleset_impl< typename labelset_t_of< Ctx >::indices_t::type >::type as_tupleset_t
If we are multitape, our type as a tupleset.
value_t add(const value_t &l, const value_t &r) const
value_t letter_class_(const Args &&...chars, std::true_type) const
If labelset is oneset.
typename node_t::values_t values_t
A list (vector) of expressions.
const labelset_ptr & labelset() const
Accessor to the labelset.
static dyn::context ctx(const driver &d)
Get the context of the driver.
Definition: parse.cc:80
std::vector< value_t > values_t
Definition: expression.hh:89
static bool is_label_(const tuple_t &v, detail::index_sequence< I...>)
typename node_t::type_t type_t
Type tag for AST classes.
An input/output format.
Definition: format.hh:11
#define JOIN_IMPL_SIMPLE(WS)
value_t transposition(const value_t &e) const
Add a transposition operator.
bool open(bool o) const
Whether unknown letters should be added, or rejected.
value_t shuffle(const value_t &l, const value_t &r) const
expressionset_impl(const context_t &ctx, identities_t ids={})
Constructor.
value_t star(const value_t &e) const
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
static bool less(const value_t &l, const value_t &r)
Whether l < r.
bool is_letter(value_t) const
When used as a LabelSet.
rat::type_t type_t
The possible types of expressions.
Definition: expression.hh:26
value_t rdiv(const value_t &l, const value_t &r) const
static type join(const WeightSet &ws, const expressionset< Context > &rs)
bool is_zero(const value_t &v) const ATTRIBUTE_PURE
When used as WeightSet.
always valid.
Definition: star-status.hh:17
Implementation of nodes of tuple of rational expressions.
Definition: expression.hh:182
value_t conv(const letterset< GenSet > &ls, typename letterset< GenSet >::value_t v) const
static identities ids(const driver &d)
Get the identities of the driver.
Definition: parse.cc:87
decltype(join(std::declval< ValueSets >()...)) join_t
The type of the join of the ValueSets.
Definition: join.hh:79
const weightset_ptr & weightset() const
Accessor to the weightset.
std::ostream & print_set(std::ostream &o, format fmt={}) const
Format the description of this expressionset.
A typed expression set.
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:47
value_t conjunction(const value_t &l, const value_t &r) const
static type join(const expressionset< Ctx1 > &lhs, const expressionset< Ctx2 > &rhs)
const context_t & context() const
Accessor to the context.
std::ostream & print(const value_t &v, std::ostream &o, format fmt={}) const
expressionset< Context > make_expressionset(const Context &ctx, rat::identities identities={})
Shorthand to expressionset constructor.
auto rs
Definition: lift.hh:151
static constexpr bool is_free()
When used as WeightSet.
typename weightset_t::value_t weight_t
static weight_t possibly_implicit_lweight_(const value_t &e)
The weight of e if it's an lweight, otherwise the weight one().
static label_t as_label(const tuple_t &v)
All the components are (single-tape) labels: make this a multitape label.
static self_t make(std::istream &is)
Build from the description in is.
value_t tuple(Value &&...v) const
static bool is_label(const tuple_t &v)
Are all the components labels?
std::shared_ptr< const node_t > value_t
An expression usable with value semantics.
Definition: expression.hh:88
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
Definition: symbol.hh:23
An expressionset can implement several different sets of identities on expressions.
Definition: identities.hh:21
static symbol sname()
Static description key.
expressionset< detail::project_context< Tape, Ctx >> focus_t
The type of the expressionset for the Tape-th tape.
static constexpr bool is_expressionset()
When used as WeightSet.
The smallest nullableset which includes LabelSet.
Definition: labelset.hh:140
static auto atom(const label_t &v) -> value_t
Build a label.
value_t infiltration(const value_t &l, const value_t &r) const
pair_automaton< Aut > pair(const Aut &aut, bool keep_initials=false)
Definition: pair.hh:243
star_status_t
Definition: star-status.hh:5
identities meet(identities i1, identities i2)
Definition: identities.cc:71
value_t add_(values_t &&vs) const
From a list of values, build a sum, taking care of the empty and singleton cases. ...
letter_t value_t
Definition: letterset.hh:32
value_t transpose(const value_t &e) const
The transposed of this rational expression.
An inner node implementing a weight.
Definition: expression.hh:264
static bool is_one(const value_t &v) ATTRIBUTE_PURE
When used as WeightSet.
const values_t sub() const
Definition: expression.hh:219
value_t rmul(const value_t &e, const weight_t &w) const
Right-multiplication by a weight.
void gather_(values_t &res, const value_t &v) const
Push v in res, applying associativity if possible.
value_t add_linear_(const sum_t &addends, const value_t &r) const
static type_t type_ignoring_lweight_(const value_t &e)
The type of e, or the type of its child if e is a lweight.
value_t concat(const value_t &l, const value_t &r) const
Similar to mul, but in the case of LAW, merge the labels.
An inner node.
Definition: expression.hh:101
static constexpr bool is_idempotent()
When used as WeightSet.
expressionset< Context > self_t
value_t lmul(const weight_t &w, const value_t &e) const
Left-multiplication by a weight.
The LAW from a LAL.
Definition: labelset.hh:251
rat::identities identities(const expression &exp)
Bridge.
Definition: identities.hh:19
An inner node with multiple children.
Definition: expression.hh:118