Vcsn  2.5
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 
193 #undef DEFINE
194 
195  using tuple_t = typename super_t::tuple_t;
196  void visit(const tuple_t&, std::true_type) override
197  {
198  raise(me(), ": tuple is not supported");
199  }
200 
202  {
203  e.sub()->accept(*this);
204  res_ = ps_.lweight(e.weight(), res_);
205  }
206 
208  {
209  e.sub()->accept(*this);
210  res_ = ps_.rweight(res_, e.weight());
211  }
212 
213  private:
216  weightset_t ws_ = *rs_.weightset();
220  };
221  }
222 
224  template <typename ExpSet>
226  split(const ExpSet& rs, const typename ExpSet::value_t& e)
227  {
229  return split(e);
230  }
231 
232  namespace dyn
233  {
234  namespace detail
235  {
237  template <typename ExpSet>
238  polynomial
239  split(const expression& exp)
240  {
241  const auto& e = exp->as<ExpSet>();
242  const auto& rs = e.valueset();
244  return {ps, vcsn::split<ExpSet>(rs, e.value())};
245  }
246  }
247  }
248 
250  template <typename PolynomialSet>
251  typename PolynomialSet::value_t
252  split_polynomial(const PolynomialSet& ps,
253  const typename PolynomialSet::value_t& p)
254  {
255  // This is a polynomial of rational expressions.
256  const auto& rs = *ps.labelset();
257  auto res = ps.zero();
258  for (const auto& m: p)
259  res = ps.add(res, ps.lweight(weight_of(m), split(rs, label_of(m))));
260  return res;
261  }
262 
264  template <typename ExpSet>
266  split(const ExpSet& rs, const rat::expression_polynomial_t<ExpSet>& p)
267  {
269  }
270 
271  namespace dyn
272  {
273  namespace detail
274  {
276  template <typename PolynomialSet>
277  polynomial
279  {
280  const auto& p = poly->as<PolynomialSet>();
281  const auto& ps = p.valueset();
282  return {ps, vcsn::split_polynomial<PolynomialSet>(ps, p.value())};
283  }
284  }
285  }
286 } // vcsn::
expressionset_t rs_
Definition: split.hh:214
rat::expression_polynomial_t< ExpSet > split(const ExpSet &rs, const typename ExpSet::value_t &e)
Split an expression.
Definition: split.hh:226
typename super_t::tuple_t tuple_t
Definition: split.hh:195
weightset_t_of< expressionset_t > weightset_t
Definition: split.hh:84
return v
Definition: multiply.hh:361
Definition: a-star.hh:8
polynomial_t res_
The result.
Definition: split.hh:219
return res
Definition: multiply.hh:398
value_impl< detail::expression_tag > expression
Definition: fwd.hh:31
VCSN_RAT_VISIT(rweight, e)
Definition: split.hh:207
auto weight_of(const welement< Label, Weight > &m) -> decltype(m.weight())
The weight of a welement.
Definition: wet.hh:154
polynomial_t multiply(const expression_t &l, const expression_t &r)
The split-multiplation of l with r.
Definition: split.hh:134
auto label_of(const welement< Label, Weight > &m) -> decltype(m.label())
The label of a welement.
Definition: wet.hh:146
#define DEFINE(Type)
These are just propagated as monomials.
Definition: split.hh:177
typename polynomialset_t::value_t polynomial_t
Definition: split.hh:88
auto & as()
Extract wrapped typed value.
Definition: value.hh:53
split_visitor(const expressionset_t &rs)
Definition: split.hh:98
expression_polynomialset_t< ExpSet > make_expression_polynomialset(const ExpSet &rs)
From a ExpSet to its polynomialset.
Definition: split.hh:31
typename detail::labelset_t_of_impl< base_t< ValueSet > >::type labelset_t_of
Definition: traits.hh:63
typename detail::weightset_t_of_impl< base_t< ValueSet > >::type weightset_t_of
Definition: traits.hh:67
VCSN_RAT_VISIT(mul, e)
Handle an n-ary multiplication.
Definition: split.hh:168
typename expressionset_t::value_t expression_t
Definition: split.hh:83
value_impl< detail::polynomial_tag > polynomial
Definition: fwd.hh:33
static constexpr const char * me()
Name of this algorithm, for error messages.
Definition: split.hh:96
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
label_t_of< context_t > label_t
Definition: split.hh:82
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:252
typename expressionset_t::const_visitor super_t
Definition: split.hh:90
typename weightset_t::value_t weight_t
Definition: split.hh:85
An inner node with multiple children.
Definition: expression.hh:118
An inner node implementing a weight.
Definition: expression.hh:255
weightset_mixin< detail::polynomialset_impl< Context, Kind > > polynomialset
Definition: fwd.hh:63
typename super_t::template variadic_t< Type > variadic_t
Definition: split.hh:93
const weightset_ptr & weightset() const
Definition: context.hh:100
polynomialset< context< ExpSet, weightset_t_of< ExpSet > >> expression_polynomialset_t
Type of PolynomialSet of expressions from the ExpSet type.
Definition: split.hh:21
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
A dyn Value/ValueSet.
Definition: fwd.hh:29
polynomial_t multiply(const polynomial_t &l, const expression_t &r)
The split-multiplation of l with r.
Definition: split.hh:156
polynomial_t split(const expression_t &v)
Easy recursion.
Definition: split.hh:109
Break a rational expression into a polynomial.
Definition: split.hh:75
void visit(const tuple_t &, std::true_type) override
Definition: split.hh:196
context_t_of< expressionset_t > context_t
Definition: split.hh:80
VCSN_RAT_VISIT(lweight, e)
Definition: split.hh:201
typename detail::label_t_of_impl< base_t< ValueSet > >::type label_t_of
Definition: traits.hh:62
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
typename detail::context_t_of_impl< base_t< ValueSet > >::type context_t_of
Definition: traits.hh:61