Vcsn  2.3
Be Rational
weight.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <vcsn/algos/copy.hh>
4 #include <vcsn/algos/standard.hh>
5 #include <vcsn/algos/tags.hh>
8 #include <vcsn/ctx/traits.hh>
9 #include <vcsn/dyn/automaton.hh> // dyn::make_automaton
10 #include <vcsn/dyn/value.hh>
11 #include <vcsn/misc/getargs.hh>
12 
13 namespace vcsn
14 {
15  namespace detail
16  {
19  template <Automaton Aut>
21  {
22  using automaton_t = Aut;
27 
29  static automaton_t&
31  {
32  const auto& ws = *res->context().weightset();
33  if (ws.is_zero(w))
34  zero_here(res, tag);
35  else if (!ws.is_one(w))
36  for (auto t: initial_transitions(res))
37  res->lweight(t, w);
38  return res;
39  }
40 
42  static automaton_t&
44  {
45  require(is_standard(res), __func__, ": automaton must be standard");
46  const auto& ws = *res->context().weightset();
47  if (ws.is_zero(w))
48  zero_here(res, tag);
49  else if (!ws.is_one(w))
50  {
51  state_t initial = res->dst_of(initial_transitions(res).front());
52  for (auto t: all_out(res, initial))
53  res->lweight(t, w);
54  }
55  return res;
56  }
57 
59  static automaton_t&
61  {
62  if (is_standard(res))
63  return lweight_here(w, res, standard_tag{});
64  else
65  return lweight_here(w, res, general_tag{});
66  }
67 
69  template <typename Tag = general_tag>
70  static automaton_t&
71  rweight_here(automaton_t& res, const weight_t& w, Tag tag = {})
72  {
73  const auto& ws = *res->context().weightset();
74  if (ws.is_zero(w))
75  zero_here(res, tag);
76  else if (!ws.is_one(w))
77  for (auto t: final_transitions(res))
78  res->rweight(t, w);
79  return res;
80  }
81 
83  static automaton_t&
84  rweight_here(automaton_t& res, const weight_t& w, auto_tag = {})
85  {
86  if (is_standard(res))
87  return rweight_here(res, w, standard_tag{});
88  else
89  return rweight_here(res, w, general_tag{});
90  }
91 
93  static automaton_t&
95  {
96  res = make_fresh_automaton(res);
97  return res;
98  }
99 
101  static automaton_t&
103  {
104  zero_here(res, general_tag{});
105  res->set_initial(res->new_state());
106  return res;
107  }
108  };
109  }
110 
111  /*---------------------.
112  | lweight(automaton). |
113  `---------------------*/
114 
116  template <Automaton Aut, typename Tag = auto_tag>
117  Aut&
118  lweight_here(const weight_t_of<Aut>& w, Aut& res, Tag tag = {})
119  {
121  }
122 
124  template <Automaton Aut, typename Tag = auto_tag>
125  auto
126  lweight(const weight_t_of<Aut>& w, const Aut& aut, Tag tag = {})
127  -> fresh_automaton_t_of<Aut>
128  {
129  auto res = copy(aut);
130  lweight_here(w, res, tag);
131  return res;
132  }
133 
134  namespace dyn
135  {
136  namespace detail
137  {
139  template <Automaton Aut, typename Tag>
140  automaton
141  lweight_tag(const weight_t_of<Aut>& w, Aut& aut)
142  {
143  return ::vcsn::lweight_here(w, aut, Tag{});
144  }
145 
147  template <typename WeightSet, Automaton Aut, typename String>
148  automaton
149  lweight(const weight& weight, const automaton& aut,
150  const std::string& algo)
151  {
152  const auto& a1 = aut->as<Aut>();
153  const auto& w1 = weight->as<WeightSet>();
154  // FIXME: this is hairy because there is no elegant means (so
155  // far) to copy an automaton to a supertype, because the
156  // incoming context is not automatically converted to the
157  // supertype by vcsn::copy.
158  auto ctx = make_context(*a1->labelset(),
159  join(w1.valueset(), *a1->weightset()));
160  auto a2 = make_mutable_automaton(ctx);
161  copy_into(a1, a2);
162  using automaton_t = decltype(a2);
163  auto w2 = ctx.weightset()->conv(w1.valueset(), w1.value());
164  using weight_t = decltype(w2);
165  static const auto map
167  {
168  "left-multiply algorithm",
169  {
170  {"auto", lweight_tag<automaton_t, auto_tag>},
171  {"general", lweight_tag<automaton_t, general_tag>},
172  {"standard", lweight_tag<automaton_t, standard_tag>},
173  }
174  };
175  return map[algo](w2, a2);
176  }
177  }
178  }
179 
180  /*---------------------.
181  | lweight(valueset). |
182  `---------------------*/
183 
184  template <typename ValueSet>
185  auto
186  lweight(const ValueSet& rs,
187  const weight_t_of<ValueSet>& w,
188  const typename ValueSet::value_t& r)
189  -> decltype(rs.lweight(w, r)) // for SFINAE.
190  {
191  return rs.lweight(w, r);
192  }
193 
194  /*----------------------.
195  | lweight(expansion). |
196  `----------------------*/
197 
198  template <typename WeightSet, typename ExpSet>
199  expansionset<expressionset<context<labelset_t_of<ExpSet>,
200  join_t<WeightSet, weightset_t_of<ExpSet>>>>>
202  const expansionset<ExpSet>& rs)
203  {
205  rs.expressionset()));
206  }
207 
208  namespace dyn
209  {
210  namespace detail
211  {
213  template <typename WeightSet, typename ExpansionSet>
214  expansion
216  {
217  const auto& w1 = weight->as<WeightSet>();
218  const auto& r1 = exp->as<ExpansionSet>();
219  auto rs = join_weightset_expansionset(w1.valueset(), r1.valueset());
220  auto w2
221  = rs.expressionset().weightset()->conv(w1.valueset(), w1.value());
222  auto r2 = rs.conv(r1.valueset(), r1.value());
223  return {rs, ::vcsn::lweight(rs, w2, r2)};
224  }
225  }
226  }
227 
228  /*-----------------------.
229  | lweight(expression). |
230  `-----------------------*/
231 
252  template <typename WeightSet, typename ExpSet>
253  expressionset<context<labelset_t_of<ExpSet>,
254  join_t<WeightSet, weightset_t_of<ExpSet>>>>
256  const ExpSet& rs)
257  {
258  auto ctx = make_context(*rs.labelset(), join(ws, *rs.weightset()));
259  return make_expressionset(ctx, rs.identities());
260  }
261 
262  namespace dyn
263  {
264  namespace detail
265  {
267  template <typename WeightSet, typename ExpSet>
268  expression
270  {
271  const auto& w1 = weight->as<WeightSet>();
272  const auto& r1 = exp->as<ExpSet>();
273  auto rs = join_weightset_expressionset(w1.valueset(), r1.valueset());
274  auto w2 = rs.weightset()->conv(w1.valueset(), w1.value());
275  auto r2 = rs.conv(r1.valueset(), r1.value());
276  return {rs, ::vcsn::lweight(rs, w2, r2)};
277  }
278  }
279  }
280 
281  /*-----------------------.
282  | lweight(polynomial). |
283  `-----------------------*/
284 
285  template <typename WeightSet, typename ExpSet>
286  auto
288  const polynomialset<ExpSet>& ps)
289  {
290  return make_polynomialset(make_context(*ps.labelset(),
291  join(ws, *ps.weightset())));
292  }
293 
294  namespace dyn
295  {
296  namespace detail
297  {
299  template <typename WeightSet, typename PolynomialSet>
300  polynomial
302  {
303  const auto& w1 = weight->as<WeightSet>();
304  const auto& p1 = poly->as<PolynomialSet>();
305  auto ps = join_weightset_polynomialset(w1.valueset(), p1.valueset());
306  auto w2 = ps.weightset()->conv(w1.valueset(), w1.value());
307  auto p2 = ps.conv(p1.valueset(), p1.value());
308  return {ps, ::vcsn::lweight(ps, w2, p2)};
309  }
310  }
311  }
312 
313 
314  /*---------------------.
315  | rweight(automaton). |
316  `---------------------*/
317 
319  template <Automaton Aut, typename Tag = auto_tag>
320  Aut&
321  rweight_here(Aut& res, const weight_t_of<Aut>& w, Tag tag = {})
322  {
324  }
325 
327  template <Automaton Aut, typename Tag = auto_tag>
328  fresh_automaton_t_of<Aut>
329  rweight(const Aut& aut, const weight_t_of<Aut>& w, Tag tag = {})
330  {
331  auto res = copy(aut);
332  rweight_here(res, w, tag);
333  return res;
334  }
335 
336  namespace dyn
337  {
338  namespace detail
339  {
341  template <Automaton Aut, typename Tag>
342  automaton
343  rweight_tag(Aut& aut, const weight_t_of<Aut>& w)
344  {
345  return ::vcsn::rweight_here(aut, w, Tag{});
346  }
347 
349  template <Automaton Aut, typename WeightSet, typename String>
350  automaton
351  rweight(const automaton& aut, const weight& weight,
352  const std::string& algo)
353  {
354  const auto& a1 = aut->as<Aut>();
355  const auto& w1 = weight->as<WeightSet>();
356  // FIXME: this is hairy because there is no elegant means (so
357  // far) to copy an automaton to a supertype, because the
358  // incoming context is not automatically converted to the
359  // supertype by vcsn::copy.
360  auto ctx = make_context(*a1->labelset(),
361  join(w1.valueset(), *a1->weightset()));
362  auto a2 = make_mutable_automaton(ctx);
363  copy_into(a1, a2);
364  using automaton_t = decltype(a2);
365  auto w2 = ctx.weightset()->conv(w1.valueset(), w1.value());
366  using weight_t = decltype(w2);
367  static const auto map
369  {
370  "right-multiply algorithm",
371  {
372  {"auto", rweight_tag<automaton_t, auto_tag>},
373  {"general", rweight_tag<automaton_t, general_tag>},
374  {"standard", rweight_tag<automaton_t, standard_tag>},
375  }
376  };
377  return map[algo](a2, w2);
378  }
379  }
380  }
381 
382  /*---------------------.
383  | rweight(valueset). |
384  `---------------------*/
385 
386  template <typename ValueSet>
387  typename ValueSet::value_t
388  rweight(const ValueSet& rs,
389  const typename ValueSet::value_t& r,
390  const weight_t_of<ValueSet>& w)
391  {
392  return rs.rweight(r, w);
393  }
394 
395  /*----------------------.
396  | rweight(expansion). |
397  `----------------------*/
398 
399  namespace dyn
400  {
401  namespace detail
402  {
404  template <typename ExpansionSet, typename WeightSet>
405  expansion
407  {
408  const auto& w1 = weight->as<WeightSet>();
409  const auto& r1 = exp->as<ExpansionSet>();
410  auto rs = join_weightset_expansionset(w1.valueset(), r1.valueset());
411  auto w2
412  = rs.expressionset().weightset()->conv(w1.valueset(), w1.value());
413  auto r2 = rs.conv(r1.valueset(), r1.value());
414  return {rs, ::vcsn::rweight(rs, r2, w2)};
415  }
416  }
417  }
418 
419  /*-----------------------.
420  | rweight(expression). |
421  `-----------------------*/
422 
423  namespace dyn
424  {
425  namespace detail
426  {
428  template <typename ExpSet, typename WeightSet>
429  expression
431  {
432  const auto& w1 = weight->as<WeightSet>();
433  const auto& r1 = exp->as<ExpSet>();
434  auto rs = join_weightset_expressionset(w1.valueset(), r1.valueset());
435  auto w2 = rs.weightset()->conv(w1.valueset(), w1.value());
436  auto r2 = rs.conv(r1.valueset(), r1.value());
437  return {rs, ::vcsn::rweight(rs, r2, w2)};
438  }
439  }
440  }
441 
442  /*-----------------------.
443  | rweight(polynomial). |
444  `-----------------------*/
445 
446  namespace dyn
447  {
448  namespace detail
449  {
451  template <typename PolynomialSet, typename WeightSet>
452  polynomial
454  {
455  const auto& w1 = weight->as<WeightSet>();
456  const auto& p1 = poly->as<PolynomialSet>();
457  auto ps = join_weightset_polynomialset(w1.valueset(), p1.valueset());
458  auto w2 = ps.weightset()->conv(w1.valueset(), w1.value());
459  auto p2 = ps.conv(p1.valueset(), p1.value());
460  return {ps, ::vcsn::rweight(ps, p2, w2)};
461  }
462  }
463  }
464 }
Tag for operations on all automata.
Definition: tags.hh:22
Aut & rweight_here(Aut &res, const weight_t_of< Aut > &w, Tag tag={})
In place right-multiplication of an automaton by a weight.
Definition: weight.hh:321
expressionset< context< labelset_t_of< ExpSet >, join_t< WeightSet, weightset_t_of< ExpSet > > > > join_weightset_expressionset(const WeightSet &ws, const ExpSet &rs)
Join between an expressionset and a weightset.
Definition: weight.hh:255
typename detail::weight_t_of_impl< base_t< ValueSet >>::type weight_t_of
Definition: traits.hh:66
Ctx make_context(const std::string &name)
Build a context from its name.
Definition: make-context.hh:22
weightset_t_of< context_t > weightset_t
Definition: weight.hh:25
expansionset< expressionset< context< labelset_t_of< ExpSet >, join_t< WeightSet, weightset_t_of< ExpSet > > > > > join_weightset_expansionset(const WeightSet &ws, const expansionset< ExpSet > &rs)
Definition: weight.hh:201
state_t_of< automaton_t > state_t
Definition: weight.hh:26
context_t_of< automaton_t > context_t
Definition: weight.hh:23
Tag for operations on standard automata.
Definition: tags.hh:32
auto lweight(const ValueSet &rs, const weight_t_of< ValueSet > &w, const typename ValueSet::value_t &r) -> decltype(rs.lweight(w, r))
Definition: weight.hh:186
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:61
auto join(const ValueSet &vs) -> ValueSet
The join of a single valueset.
Definition: join.hh:44
Tag to request the most appropriate version of an algorithm.
Definition: tags.hh:16
void require(Bool b, Args &&...args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:91
A dyn Value/ValueSet.
Definition: fwd.hh:23
return res
Definition: multiply.hh:398
weight_t_of< context_t > weight_t
Definition: weight.hh:24
polynomial rweight_polynomial(const polynomial &poly, const weight &weight)
Bridge (rweight).
Definition: weight.hh:453
static automaton_t & lweight_here(const weight_t &w, automaton_t &res, auto_tag={})
Same as standard if res is standard, otherwise, general.
Definition: weight.hh:60
fresh_automaton_t_of< Aut > rweight(const Aut &aut, const weight_t_of< Aut > &w, Tag tag={})
Right-multiplication of an automaton by a weight.
Definition: weight.hh:329
automaton rweight_tag(Aut &aut, const weight_t_of< Aut > &w)
Right-product.
Definition: weight.hh:343
bool is_standard(const Aut &a)
Whether a is standard.
Definition: standard.hh:28
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:64
auto copy(const AutIn &input, KeepState keep_state, KeepTrans keep_trans) -> decltype(keep_state(input->null_state()), keep_trans(input->null_transition()), make_fresh_automaton< AutIn, AutOut >(input))
A copy of input keeping only its states that are accepted by keep_state, and transitions accepted by ...
Definition: copy.hh:322
expression lweight_expression(const weight &weight, const expression &exp)
Bridge (lweight).
Definition: weight.hh:269
auto rs
Definition: lift.hh:152
AutOut make_fresh_automaton(const AutIn &model)
Create an empty, mutable, automaton, based on another one.
Definition: copy.hh:91
static automaton_t & rweight_here(automaton_t &res, const weight_t &w, Tag tag={})
Right-multiplication of any automaton by a weight.
Definition: weight.hh:71
Definition: a-star.hh:8
const expressionset_t & expressionset() const
The expressionset.
Definition: expansionset.hh:62
A dyn automaton.
Definition: automaton.hh:17
Implementation of left- and right- multiplication of an automaton by a weight.
Definition: weight.hh:20
static automaton_t & zero_here(automaton_t &res, general_tag)
Transform res into the empty automaton.
Definition: weight.hh:94
void copy_into(const AutIn &in, AutOut &out, KeepState keep_state, KeepTrans keep_trans)
Copy selected states and transitions of an automaton.
Definition: copy.hh:267
value_impl< detail::polynomial_tag > polynomial
Definition: fwd.hh:27
automaton lweight_tag(const weight_t_of< Aut > &w, Aut &aut)
Left-product.
Definition: weight.hh:141
automaton lweight(const weight &weight, const automaton &aut, const std::string &algo)
Bridge.
Definition: weight.hh:149
auto lweight(const weight_t_of< Aut > &w, const Aut &aut, Tag tag={}) -> fresh_automaton_t_of< Aut >
Left-multiplication of an automaton by a weight.
Definition: weight.hh:126
context join(const context &c1, const context &c2)
Bridge.
auto join_weightset_polynomialset(const WeightSet &ws, const polynomialset< ExpSet > &ps)
Definition: weight.hh:287
static automaton_t & rweight_here(automaton_t &res, const weight_t &w, auto_tag={})
Same as standard if res is standard, otherwise, general.
Definition: weight.hh:84
value_impl< detail::expansion_tag > expansion
Definition: fwd.hh:24
context make_context(const std::string &name)
Bridge.
Definition: make-context.hh:44
automaton rweight(const automaton &aut, const weight &weight, const std::string &algo)
Bridge.
Definition: weight.hh:351
polynomial lweight_polynomial(const weight &weight, const polynomial &poly)
Bridge (lweight).
Definition: weight.hh:301
expression rweight_expression(const expression &exp, const weight &weight)
Bridge (rweight).
Definition: weight.hh:430
auto make_expressionset(const context< LabelSet, WeightSet > &ctx, rat::identities ids={}) -> expressionset< context< LabelSet, WeightSet >>
Shorthand to expressionset constructor.
auto initial_transitions(const Aut &aut) -> decltype(aut->all_out(aut->pre()))
Indexes of transitions to (visible) initial states.
Definition: automaton.hh:145
polynomialset< Context, Kind > make_polynomialset(const Context &context)
expansion rweight_expansion(const expansion &exp, const weight &weight)
Bridge (rweight).
Definition: weight.hh:406
Aut & lweight_here(const weight_t_of< Aut > &w, Aut &res, Tag tag={})
In place left-multiplication of an automaton by a weight.
Definition: weight.hh:118
auto & as()
Extract wrapped typed value.
Definition: value.hh:53
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
Definition: traits.hh:67
auto & as()
Extract wrapped typed automaton.
Definition: automaton.hh:37
ValueSet::value_t rweight(const ValueSet &rs, const typename ValueSet::value_t &r, const weight_t_of< ValueSet > &w)
Definition: weight.hh:388
A mapping from strings to Values.
Definition: getargs.hh:33
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
auto all_out(const Aut &aut, state_t_of< Aut > s)
Indexes of transitions leaving state s.
Definition: automaton.hh:45
static automaton_t & lweight_here(const weight_t &w, automaton_t &res, general_tag tag)
Left-multiplication of any automaton by a weight.
Definition: weight.hh:30
expansion lweight_expansion(const weight &weight, const expansion &exp)
Bridge (lweight).
Definition: weight.hh:215
static automaton_t & lweight_here(const weight_t &w, automaton_t &res, standard_tag tag)
Standard-preserving left-multiplication by a weight.
Definition: weight.hh:43
value_impl< detail::expression_tag > expression
Definition: fwd.hh:25
Container::value_type front(const Container &container)
The first member of this Container.
Definition: algorithm.hh:68
auto final_transitions(const Aut &aut) -> decltype(aut->all_in(aut->post()))
Indexes of transitions from (visible) final states.
Definition: automaton.hh:156
expansionset< ExpSet > make_expansionset(const ExpSet &expset)
static automaton_t & zero_here(automaton_t &res, standard_tag)
Transform res into the (standard) empty automaton.
Definition: weight.hh:102
mutable_automaton< Context > make_mutable_automaton(const Context &ctx)