Vcsn  2.8
Be Rational
split.hh
Go to the documentation of this file.
1 #pragma once
2 
4 #include <vcsn/ctx/fwd.hh>
5 #include <vcsn/dyn/value.hh>
6 #include <vcsn/misc/raise.hh>
8 
9 namespace vcsn
10 {
11 
12  namespace rat
13  {
14  // FIXME: this is a general feature which is useful elsewhere.
15  // E.g., expand.
16 
18  template <typename ExpSet>
20  = polynomialset<context<ExpSet,
22 
24  template <typename ExpSet>
27 
29  template <typename ExpSet>
32  {
33  using context_t = context<ExpSet,
35  return context_t{rs, *rs.weightset()};
36  }
37  }
38 
39 
40  /*---------------------.
41  | split(expression). |
42  `---------------------*/
43 
44  namespace rat
45  {
74  template <typename ExpSet>
76  : public ExpSet::const_visitor
77  {
78  public:
79  using expressionset_t = ExpSet;
83  using expression_t = typename expressionset_t::value_t;
85  using weight_t = typename weightset_t::value_t;
86 
88  using polynomial_t = typename polynomialset_t::value_t;
89 
90  using super_t = typename expressionset_t::const_visitor;
91 
92  template <type_t Type>
93  using variadic_t = typename super_t::template variadic_t<Type>;
94 
96  constexpr static const char* me() { return "split"; }
97 
99  : rs_(rs)
100  {}
101 
104  {
105  return split(v);
106  }
107 
110  {
111  v->accept(*this);
112  return std::move(res_);
113  }
114 
116  {
117  res_ = ps_.zero();
118  }
119 
121  {
122  auto res = ps_.zero();
123  for (const auto& v: e)
124  {
125  v->accept(*this);
126  ps_.add_here(res, res_);
127  }
128  res_ = std::move(res);
129  }
130 
135  {
136  // B(l).
137  polynomial_t l_split = split(l);
138  // constant-term(B(l)).
139  weight_t l_split_const = ps_.get_weight(l_split, rs_.one());
140  // proper(B(l)).
141  ps_.del_weight(l_split, rs_.one());
142 
143  // res = proper(B(l)) x r.
144  auto res = ps_.zero();
145  for (const auto& e: l_split)
146  ps_.add_here(res, rs_.mul(label_of(e), r), weight_of(e));
147  // res += ⟨constant-term(B(l))⟩.B(r)
148  ps_.add_here(res,
149  ps_.lweight(l_split_const, split(r)));
150  return res;
151  }
152 
157  {
158  auto res = ps_.zero();
160  for (const auto& m: l)
161  ps_.add_here(res,
162  ps_.lweight(weight_of(m),
163  multiply(label_of(m), r)));
164  return res;
165  }
166 
169  {
170  auto res = multiply(e[0], e[1]);
171  for (unsigned i = 2, n = e.size(); i < n; ++i)
172  res = multiply(res, e[i]);
173  res_ = std::move(res);
174  }
175 
177 #define DEFINE(Type) \
178  VCSN_RAT_VISIT(Type, e) \
179  { \
180  res_ = polynomial_t{{e.shared_from_this(), ws_.one()}}; \
181  }
182 
194 #undef DEFINE
195 
196  using tuple_t = typename super_t::tuple_t;
197  void visit(const tuple_t&, std::true_type) override
198  {
199  raise(me(), ": tuple is not supported");
200  }
201 
203  {
204  e.sub()->accept(*this);
205  res_ = ps_.lweight(e.weight(), res_);
206  }
207 
209  {
210  e.sub()->accept(*this);
211  res_ = ps_.rweight(res_, e.weight());
212  }
213 
214  private:
217  weightset_t ws_ = *rs_.weightset();
221  };
222  }
223 
225  template <typename ExpSet>
227  split(const ExpSet& rs, const typename ExpSet::value_t& e)
228  {
230  return split(e);
231  }
232 
233  namespace dyn
234  {
235  namespace detail
236  {
238  template <typename ExpSet>
239  polynomial
240  split(const expression& exp)
241  {
242  const auto& e = exp->as<ExpSet>();
243  const auto& rs = e.valueset();
245  return {ps, vcsn::split<ExpSet>(rs, e.value())};
246  }
247  }
248  }
249 
251  template <typename PolynomialSet>
252  typename PolynomialSet::value_t
253  split_polynomial(const PolynomialSet& ps,
254  const typename PolynomialSet::value_t& p)
255  {
256  // This is a polynomial of rational expressions.
257  const auto& rs = *ps.labelset();
258  auto res = ps.zero();
259  for (const auto& m: p)
260  res = ps.add(res, ps.lweight(weight_of(m), split(rs, label_of(m))));
261  return res;
262  }
263 
265  template <typename ExpSet>
267  split(const ExpSet& rs, const rat::expression_polynomial_t<ExpSet>& p)
268  {
270  }
271 
272  namespace dyn
273  {
274  namespace detail
275  {
277  template <typename PolynomialSet>
278  polynomial
280  {
281  const auto& p = poly->as<PolynomialSet>();
282  const auto& ps = p.valueset();
283  return {ps, vcsn::split_polynomial<PolynomialSet>(ps, p.value())};
284  }
285  }
286  }
287 } // vcsn::
VCSN_RAT_VISIT(lweight, e)
Definition: split.hh:202
typename expressionset_t::value_t expression_t
Definition: split.hh:83
typename detail::weightset_t_of_impl< base_t< ValueSet > >::type weightset_t_of
Definition: traits.hh:67
polynomial_t res_
The result.
Definition: split.hh:220
typename super_t::template variadic_t< Type > variadic_t
Definition: split.hh:93
auto multiply(const Aut1 &lhs, const Aut2 &rhs, Tag tag={}) -> decltype(lhs->null_state(), rhs->null_state(), detail::make_join_automaton(tag, lhs, rhs))
Concatenate two automata, general case.
Definition: multiply.hh:151
polynomial_t multiply(const expression_t &l, const expression_t &r)
The split-multiplation of l with r.
Definition: split.hh:134
void visit(const tuple_t &, std::true_type) override
Definition: split.hh:197
An inner node with multiple children.
Definition: expression.hh:119
PolynomialSet::value_t split_polynomial(const PolynomialSet &ps, const typename PolynomialSet::value_t &p)
Split a polynomial of expressions, given the polynomialset.
Definition: split.hh:253
polynomial_t multiply(const polynomial_t &l, const expression_t &r)
The split-multiplation of l with r.
Definition: split.hh:156
auto & as()
Extract wrapped typed value.
Definition: value.hh:55
rat::expression_polynomial_t< ExpSet > split(const ExpSet &rs, const typename ExpSet::value_t &e)
Split an expression.
Definition: split.hh:227
split_visitor(const expressionset_t &rs)
Definition: split.hh:98
value_impl< detail::polynomial_tag > polynomial
Definition: fwd.hh:33
An inner node to name the subexpression.
Definition: expression.hh:290
typename detail::context_t_of_impl< base_t< ValueSet > >::type context_t_of
Definition: traits.hh:61
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
typename expression_polynomialset_t< ExpSet >::value_t expression_polynomial_t
Type of polynomials of expressions from the ExpSet type.
Definition: split.hh:26
A dyn Value/ValueSet.
Definition: fwd.hh:29
typename detail::labelset_t_of_impl< base_t< ValueSet > >::type labelset_t_of
Definition: traits.hh:63
polynomial_t split(const expression_t &v)
Easy recursion.
Definition: split.hh:109
typename expressionset_t::const_visitor super_t
Definition: split.hh:90
Definition: a-star.hh:8
typename weightset_t::value_t weight_t
Definition: split.hh:85
weightset_mixin< detail::polynomialset_impl< Context, Kind > > polynomialset
Definition: fwd.hh:63
#define DEFINE(Type)
These are just propagated as monomials.
Definition: split.hh:177
typename detail::label_t_of_impl< base_t< ValueSet > >::type label_t_of
Definition: traits.hh:62
typename super_t::tuple_t tuple_t
Definition: split.hh:196
context_t_of< expressionset_t > context_t
Definition: split.hh:80
labelset_t_of< context_t > labelset_t
Definition: split.hh:81
polynomial_t operator()(const expression_t &v)
Break an expression into a polynomial.
Definition: split.hh:103
polynomialset< context< ExpSet, weightset_t_of< ExpSet > >> expression_polynomialset_t
Type of PolynomialSet of expressions from the ExpSet type.
Definition: split.hh:21
An inner node implementing a weight.
Definition: expression.hh:256
static constexpr const char * me()
Name of this algorithm, for error messages.
Definition: split.hh:96
weightset_t_of< expressionset_t > weightset_t
Definition: split.hh:84
VCSN_RAT_VISIT(mul, e)
Handle an n-ary multiplication.
Definition: split.hh:168
auto weight_of(const welement< Label, Weight > &m) -> decltype(m.weight())
The weight of a welement.
Definition: wet.hh:154
return v
Definition: multiply.hh:362
auto label_of(const welement< Label, Weight > &m) -> decltype(m.label())
The label of a welement.
Definition: wet.hh:146
label_t_of< context_t > label_t
Definition: split.hh:82
value_impl< detail::expression_tag > expression
Definition: fwd.hh:31
expression_polynomialset_t< ExpSet > make_expression_polynomialset(const ExpSet &rs)
From a ExpSet to its polynomialset.
Definition: split.hh:31
VCSN_RAT_VISIT(rweight, e)
Definition: split.hh:208
Break a rational expression into a polynomial.
Definition: split.hh:75
const weightset_ptr & weightset() const
Definition: context.hh:101
typename polynomialset_t::value_t polynomial_t
Definition: split.hh:88
return res
Definition: multiply.hh:399
expressionset_t rs_
Definition: split.hh:215