Vcsn  2.0
Be Rational
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
derivation.hh
Go to the documentation of this file.
1 #ifndef VCSN_ALGOS_DERIVATION_HH
2 # define VCSN_ALGOS_DERIVATION_HH
3 
5 # include <vcsn/algos/split.hh>
6 # include <vcsn/core/rat/visitor.hh>
7 # include <vcsn/ctx/fwd.hh>
8 # include <vcsn/dyn/label.hh>
9 # include <vcsn/dyn/polynomial.hh>
10 # include <vcsn/dyn/ratexp.hh>
11 # include <vcsn/misc/raise.hh>
13 
14 namespace vcsn
15 {
16 
17  /*---------------------.
18  | derivation(ratexp). |
19  `---------------------*/
20 
21  namespace rat
22  {
23  template <typename RatExpSet>
25  : public RatExpSet::const_visitor
26  {
27  public:
28  using ratexpset_t = RatExpSet;
32  using ratexp_t = typename ratexpset_t::value_t;
34  using weight_t = typename weightset_t::value_t;
35 
38 
39  using super_t = typename ratexpset_t::const_visitor;
40  using node_t = typename super_t::node_t;
41 
42  constexpr static const char* me() { return "derivation"; }
43 
45  : rs_(rs)
46  {}
47 
49  operator()(const ratexp_t& v, label_t var)
50  {
51  variable_ = var;
52  v->accept(*this);
53  return std::move(res_);
54  }
55 
56  // FIXME: duplicate with expand.
57  ratexp_t
59  {
60  ratexp_t res = rs_.zero();
61  for (const auto& m: p)
62  res = rs_.add(res, rs_.lmul(m.second, m.first));
63  return res;
64  }
65 
68 
70  {
71  res_ = ps_.zero();
72  }
73 
75  {
76  res_ = ps_.zero();
77  }
78 
80  {
81  if (e.value() == variable_)
82  res_ = ps_.one();
83  else
84  res_ = ps_.zero();
85  }
86 
88  {
89  polynomial_t res = ps_.zero();
90  for (const auto& v: e)
91  {
92  v->accept(*this);
93  ps_.add_here(res, res_);
94  }
95  res_ = std::move(res);
96  }
97 
99  {
100  // We generate a sum.
101  auto res = ps_.zero();
102  // Accumulate the product of the constant terms of the
103  // previous factors.
104  weight_t constant = ws_.one();
105  for (unsigned i = 0, n = e.size(); i < n; ++i)
106  {
107  const auto& v = e[i];
108  v->accept(*this);
109  for (unsigned j = i + 1; j < n; ++j)
110  res_ = ps_.rmul(res_, e[j]);
111  ps_.add_here(res, ps_.lmul(constant, res_));
112  constant = ws_.mul(constant, constant_term(rs_, v));
113  }
114  res_ = std::move(res);
115  }
116 
118  {
119  // The first polynomial.
120  e.head()->accept(*this);
121  auto res = res_;
122  for (unsigned i = 1, n = e.size(); i < n; ++i)
123  {
124  const auto& v = e[i];
125  v->accept(*this);
126  res = ps_.conjunction(res, res_);
127  }
128  res_ = std::move(res);
129  }
130 
132  {
133  polynomial_t res = ps_.zero();
134  for (unsigned i = 0; i < e.size(); ++i)
135  {
136  e[i]->accept(*this);
137  for (const auto& m: res_)
138  {
139  typename node_t::values_t ratexps;
140  for (unsigned j = 0; j < e.size(); ++j)
141  if (i == j)
142  ratexps.emplace_back(m.first);
143  else
144  ratexps.emplace_back(e[j]);
145  // FIXME: we need better n-ary constructors.
146  ps_.add_here(res,
147  std::make_shared<shuffle_t>(ratexps),
148  m.second);
149  }
150  }
151  res_ = std::move(res);
152  }
153 
155  {
156  e.sub()->accept(*this);
157  // Turn the polynomial into a ratexp, and complement it.
158  res_ = polynomial_t{{rs_.complement(ratexp(res_)), ws_.one()}};
159  }
160 
162  {
163  e.sub()->accept(*this);
164  // We need a copy of e, but without its weights.
165  res_ = ps_.lmul(ws_.star(constant_term(rs_, e.sub())),
166  ps_.rmul(res_, e.shared_from_this()));
167  }
168 
170  {
171  e.sub()->accept(*this);
172  res_ = ps_.lmul(e.weight(), res_);
173  }
174 
176  {
177  e.sub()->accept(*this);
178  polynomial_t res;
179  for (const auto& m: res_)
180  ps_.add_here(res, rs_.rmul(m.first, e.weight()), m.second);
181  res_ = res;
182  }
183 
184  private:
187  weightset_t ws_ = *rs_.weightset();
193  };
194 
195  } // rat::
196 
198  template <typename RatExpSet>
199  inline
201  derivation(const RatExpSet& rs,
202  const typename RatExpSet::value_t& e,
204  bool breaking = false)
205  {
206  static_assert(RatExpSet::context_t::labelset_t::is_free(),
207  "derivation: requires free labelset");
209  auto res = derivation(e, a);
210  if (breaking)
211  res = split(rs, res);
212  return res;
213  }
214 
215 
217  template <typename RatExpSet>
218  inline
219  rat::ratexp_polynomial_t<RatExpSet>
220  derivation(const RatExpSet& rs,
223  bool breaking = false)
224  {
225  auto ps = rat::make_ratexp_polynomialset(rs);
226  using polynomial_t = rat::ratexp_polynomial_t<RatExpSet>;
227  polynomial_t res;
228  for (const auto& m: p)
229  res = ps.add(res,
230  ps.lmul(m.second, derivation(rs, m.first, a, breaking)));
231  return res;
232  }
233 
234 
236  template <typename RatExpSet>
237  inline
238  rat::ratexp_polynomial_t<RatExpSet>
239  derivation(const RatExpSet& rs,
240  const typename RatExpSet::value_t& e,
241  const typename RatExpSet::labelset_t::word_t& l,
242  bool breaking = false)
243  {
244  auto word = rs.labelset()->letters_of(l);
245  auto i = std::begin(word);
246  auto end = std::end(word);
247  require(i != end, "derivation: word cannot be empty");
248  auto res = derivation(rs, e, *i, breaking);
249  for (++i; i != end; ++i)
250  res = derivation(rs, res, *i, breaking);
251  return res;
252  }
253 
254 
255  namespace dyn
256  {
257  namespace detail
258  {
260  template <typename RatExpSet, typename Label, typename Bool>
261  polynomial
262  derivation(const ratexp& exp, const label& lbl, bool breaking = false)
263  {
264  const auto& e = exp->as<RatExpSet>();
265  const auto& l = lbl->as<Label>().label();
266  const auto& rs = e.ratexpset();
268  return make_polynomial(ps,
269  vcsn::derivation(rs, e.ratexp(), l, breaking));
270  }
271 
273  (const ratexp& e, const label& l,
274  bool breaking) -> polynomial);
275  }
276  }
277 
278 } // vcsn::
279 
280 #endif // !VCSN_ALGOS_DERIVATION_HH
typename super_t::node_t node_t
Definition: derivation.hh:40
Linear combination of labels: map labels to weights.
Definition: fwd.hh:32
typename ratexpset_t::value_t ratexp_t
Definition: derivation.hh:32
value_t & add_here(value_t &v, const value_t &p) const
v += p.
An inner node with multiple children.
Definition: fwd.hh:123
#define VCSN_RAT_UNSUPPORTED(Type)
Definition: visitor.hh:54
typename ratexpset_t::const_visitor super_t
Definition: derivation.hh:39
REGISTER_DECLARE(accessible,(const automaton &) -> automaton)
labelset_t_of< context_t > labelset_t
Definition: derivation.hh:30
weightset_t ws_
Shorthand to the weightset.
Definition: derivation.hh:187
polynomial make_polynomial(const PolynomialSet &ps, const typename PolynomialSet::value_t &polynomial)
Definition: polynomial.hh:91
ratexp_polynomialset_t< RatExpSet > make_ratexp_polynomialset(const RatExpSet &rs)
From a RatExpSet to its polynomialset.
Definition: split.hh:34
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:34
typename polynomialset_t::value_t polynomial_t
Definition: derivation.hh:37
value_t rmul(const value_t &v, const weight_t &w) const
Right exterior product.
const value_t & zero() const
std::shared_ptr< detail::ratexp_base > ratexp
Definition: fwd.hh:64
typename weightset_t::value_t weight_t
Definition: derivation.hh:34
value_t lmul(const weight_t &w, const value_t &v) const
Left exterior product.
polynomial_t res_
The result.
Definition: derivation.hh:190
polynomial derivation(const ratexp &exp, const label &lbl, bool breaking=false)
Bridge.
Definition: derivation.hh:262
ratexp_t ratexp(const polynomial_t p)
Definition: derivation.hh:58
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:32
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
Definition: traits.hh:33
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
Definition: traits.hh:38
context_t_of< ratexpset_t > context_t
Definition: derivation.hh:29
label_t_of< context_t > label_t
Definition: derivation.hh:31
label_t variable_
The derivation variable.
Definition: derivation.hh:192
VCSN_RAT_VISIT(conjunction, e)
Definition: derivation.hh:117
std::shared_ptr< const detail::label_base > label
Definition: fwd.hh:46
polynomial_t operator()(const ratexp_t &v, label_t var)
Definition: derivation.hh:49
value_t conjunction(const value_t &l, const value_t &r) const
The conjunction of polynomials l and r.
weightset_t_of< ratexpset_t > weightset_t
Definition: derivation.hh:33
An inner node implementing a weight.
Definition: fwd.hh:145
weight_t_of< RatExpSet > constant_term(const RatExpSet &rs, const typename RatExpSet::value_t &e)
typename ratexp_polynomialset_t< RatExpSet >::value_t ratexp_polynomial_t
Type of polynomials of ratexps from the RatExpSet type.
Definition: split.hh:28
std::map< label_t, weight_t, vcsn::less< labelset_t >> value_t
rat::ratexp_polynomial_t< RatExpSet > derivation(const RatExpSet &rs, const typename RatExpSet::value_t &e, label_t_of< RatExpSet > a, bool breaking=false)
Derive a ratexp wrt to a letter.
Definition: derivation.hh:201
derivation_visitor(const ratexpset_t &rs)
Definition: derivation.hh:44
rat::ratexp_polynomial_t< RatExpSet > split(const RatExpSet &rs, const typename RatExpSet::value_t &e)
Split a ratexp.
Definition: split.hh:257
static constexpr const char * me()
Definition: derivation.hh:42
const value_t & one() const
std::shared_ptr< const detail::polynomial_base > polynomial
Definition: fwd.hh:55
void require(bool b, Args &&...args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:39