Awali
Another Weighted Automata library
split.hh
Go to the documentation of this file.
1 // This file is part of Awali.
2 // Copyright 2016-2022 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_ALGOS_SPLIT_HH
18 # define AWALI_ALGOS_SPLIT_HH
19 
21 #include <awali/sttc/ctx/fwd.hh>
22 #include <awali/sttc/misc/raise.hh>
24 
25 namespace awali { namespace sttc {
26 
27 
28  namespace rat
29  {
30  // FIXME: this is a general feature which is useful elsewhere.
31  // E.g., expand.
32 
34  template <typename RatExpSet>
36  = polynomialset<context<RatExpSet,
38 
40  template <typename RatExpSet>
43 
45  template <typename RatExpSet>
46  inline
48  make_ratexp_polynomialset(const RatExpSet& rs)
49  {
50  using context_t = context<RatExpSet,
52  return context_t{rs, *rs.weightset()};
53  }
54  }
55 
56 
57  /*----------------.
58  | split(ratexp). |
59  `----------------*/
60 
61  namespace rat
62  {
63  template <typename RatExpSet>
65  : public RatExpSet::const_visitor
66  {
67  public:
68  using ratexpset_t = RatExpSet;
72  using ratexp_t = typename ratexpset_t::value_t;
74  using weight_t = typename weightset_t::value_t;
75 
78 
79  using super_type = typename ratexpset_t::const_visitor;
80 
81  constexpr static const char* me() { return "split"; }
82 
84  : rs_(rs)
85  {}
86 
89  {
90  return split(v);
91  }
92 
95  {
96  v->accept(*this);
97  return std::move(res_);
98  }
99 
101  {
102  res_ = ps_.zero();
103  }
104 
106  {
107  res_ = polynomial_t{{rs_.one(), ws_.one()}};
108  }
109 
111  {
112  res_ = polynomial_t{{rs_.atom(e.value()), ws_.one()}};
113  }
114 
116  {
117  polynomial_t res = ps_.zero();
118  for (const auto& v: e)
119  {
120  v->accept(*this);
121  ps_.add_here(res, res_);
122  }
123  res_ = std::move(res);
124  }
125 
131  {
132  // B(l).
133  polynomial_t l_split = split(l);
134  // constant-term(B(l)).
135  weight_t l_split_const = ps_.get_weight(l_split, rs_.one());
136  // proper(B(l)).
137  ps_.del_weight(l_split, rs_.one());
138 
139  // res = proper(B(l)).r + constant-term(B(l))B(r).
140  return ps_.add(ps_.rmul_letter(l_split, r),
141  ps_.lmul(l_split_const, split(r)));
142  }
143 
148  {
149  polynomial_t res;
150  for (const auto& m: l)
151  ps_.add_here(res, ps_.lmul(m.second, product(m.first, r)));
152  return res;
153  }
154 
157  {
158  auto res = product(e[0], e[1]);
159  for (unsigned i = 2, n = e.size(); i < n; ++i)
160  res = product(res, e[i]);
161  res_ = std::move(res);
162  }
163 
169  {
170  // B(l).
171  polynomial_t l_split = split(l);
172  // constant-term(B(l)).
173  weight_t l_split_const = ps_.get_weight(l_split, rs_.one());
174  // proper(B(l)).
175  ps_.del_weight(l_split, rs_.one());
176 
177  // res = proper(B(l))&r.
178  polynomial_t res;
179  for (const auto& e: l_split)
180  ps_.add_here(res, rs_.conjunction(e.first, r), e.second);
181  // res += constant-term(B(l))B(r)
182  ps_.add_here(res,
183  ps_.lmul(l_split_const, split(r)));
184  return res;
185  }
186 
191  {
192  polynomial_t res;
193  for (const auto& m: l)
194  ps_.add_here(res, ps_.lmul(m.second, conjunction(m.first, r)));
195  return res;
196  }
197 
200  {
201  auto res = conjunction(e[0], e[1]);
202  for (unsigned i = 2, n = e.size(); i < n; ++i)
203  res = conjunction(res, e[i]);
204  res_ = std::move(res);
205  }
206 
211 
213  {
214  res_ = polynomial_t{{e.shared_from_this(), ws_.one()}};
215  }
216 
218  {
219  e.sub()->accept(*this);
220  res_ = ps_.lmul(e.weight(), res_);
221  }
222 
224  {
225  e.sub()->accept(*this);
226  res_ = ps_.rmul(res_, e.weight());
227  }
228 
229  private:
230  ratexpset_t rs_;
232  weightset_t ws_ = *rs_.weightset();
235  polynomial_t res_;
236  };
237  }//end of ns rat
238 
240  template <typename RatExpSet>
241  inline
242  rat::ratexp_polynomial_t<RatExpSet>
243  split(const RatExpSet& rs, const typename RatExpSet::ratexp_t& e)
244  {
246  return split(e);
247  }
248 
250  template <typename RatExpSet>
251  inline
252  rat::ratexp_polynomial_t<RatExpSet>
253  split(const RatExpSet& rs, const rat::ratexp_polynomial_t<RatExpSet>& p)
254  {
255  auto ps = rat::make_ratexp_polynomialset(rs);
256  using polynomial_t = rat::ratexp_polynomial_t<RatExpSet>;
258  polynomial_t res;
259  for (const auto& m: p)
260  res = ps.add(res, ps.lmul(m.second, split(m.first)));
261  return res;
262  }
263 
264 
265 }}//end of ns awali::stc
266 
267 #endif // !AWALI_ALGOS_SPLIT_HH
carries the algebraic settings of automata
Definition: context.hh:40
const weightset_ptr & weightset() const
Definition: context.hh:157
The semiring of Natural numbers.
Definition: n.hh:34
Linear combination of labels: map labels to weights.
Definition: polynomialset.hh:69
std::map< label_t, weight_t, internal::less< labelset_t > > value_t
Definition: polynomialset.hh:83
value_t & add_here(value_t &v, const value_t &p) const
v += p.
Definition: polynomialset.hh:130
value_t & del_weight(value_t &v, const label_t &w) const
Remove the monomial of w in v.
Definition: polynomialset.hh:111
value_t add(const value_t &l, const value_t &r) const
The sum of polynomials l and r.
Definition: polynomialset.hh:182
const weight_t get_weight(const value_t &v, const label_t &w) const ATTRIBUTE_PURE
Definition: polynomialset.hh:171
const value_t & zero() const
Definition: polynomialset.hh:353
value_t rmul(const value_t &v, const weight_t &w) const
Right exterior product.
Definition: polynomialset.hh:266
value_t lmul(const weight_t &w, const value_t &v) const
Left exterior product.
Definition: polynomialset.hh:241
value_t rmul_letter(const value_t &v, const label_t &rhs) const
Right product.
Definition: polynomialset.hh:277
The semiring of floating Numbers.
Definition: r.hh:35
Definition: ratexp.hh:280
Definition: ratexp.hh:262
Definition: split.hh:66
polynomial_t product(const polynomial_t &l, const ratexp_t &r)
The split-product of l with r.
Definition: split.hh:147
AWALI_RAT_VISIT(atom, e)
Definition: split.hh:110
polynomial_t conjunction(const ratexp_t &l, const ratexp_t &r)
The split-product of l with r.
Definition: split.hh:168
RatExpSet ratexpset_t
Definition: split.hh:68
typename weightset_t::value_t weight_t
Definition: split.hh:74
AWALI_RAT_VISIT(rweight, e)
Definition: split.hh:223
AWALI_RAT_VISIT(one,)
Definition: split.hh:105
typename polynomialset_t::value_t polynomial_t
Definition: split.hh:77
polynomial_t product(const ratexp_t &l, const ratexp_t &r)
The split-product of l with r.
Definition: split.hh:130
ratexp_polynomialset_t< ratexpset_t > polynomialset_t
Definition: split.hh:76
weightset_t_of< ratexpset_t > weightset_t
Definition: split.hh:73
AWALI_RAT_VISIT(sum, e)
Definition: split.hh:115
typename ratexpset_t::const_visitor super_type
Definition: split.hh:79
AWALI_RAT_VISIT(prod, e)
Handle an n-ary product.
Definition: split.hh:156
polynomial_t operator()(const ratexp_t &v)
Break a ratexp into a polynomial.
Definition: split.hh:88
polynomial_t conjunction(const polynomial_t &l, const ratexp_t &r)
The split-product of l with r.
Definition: split.hh:190
labelset_t_of< context_t > labelset_t
Definition: split.hh:70
typename ratexpset_t::value_t ratexp_t
Definition: split.hh:72
polynomial_t split(const ratexp_t &v)
Easy recursion.
Definition: split.hh:94
constexpr static const char * me()
Definition: split.hh:81
AWALI_RAT_VISIT(zero,)
Definition: split.hh:100
AWALI_RAT_VISIT(conjunction, e)
Handle an n-ary conjunction.
Definition: split.hh:199
context_t_of< ratexpset_t > context_t
Definition: split.hh:69
AWALI_RAT_VISIT(lweight, e)
Definition: split.hh:217
split_visitor(const ratexpset_t &rs)
Definition: split.hh:83
label_t_of< context_t > label_t
Definition: split.hh:71
Definition: ratexp.hh:176
An inner node with multiple children.
Definition: ratexp.hh:115
An inner node implementing a weight.
Definition: ratexp.hh:208
typename ratexp_polynomialset_t< RatExpSet >::value_t ratexp_polynomial_t
Type of polynomials of ratexps from the RatExpSet type.
Definition: split.hh:42
ratexp_polynomialset_t< RatExpSet > make_ratexp_polynomialset(const RatExpSet &rs)
From a RatExpSet to its polynomialset.
Definition: split.hh:48
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
typename internal::context_t_of_impl< internal::base_t< ValueSet > >::type context_t_of
Helper to retrieve the type of the context of a value set.
Definition: traits.hh:66
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
rat::ratexp_polynomial_t< RatExpSet > split(const RatExpSet &rs, const typename RatExpSet::ratexp_t &e)
Split a ratexp.
Definition: split.hh:243
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
Main namespace of Awali.
Definition: ato.hh:22
#define AWALI_RAT_UNSUPPORTED(Type)
Definition: visitor.hh:73