Vcsn  2.2a
Be Rational
left-mult.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/expression.hh>
11 #include <vcsn/dyn/expansion.hh>
12 #include <vcsn/dyn/weight.hh>
13 #include <vcsn/misc/getargs.hh>
14 
15 namespace vcsn
16 {
17  namespace detail
18  {
21  template <Automaton Aut>
23  {
24  using automaton_t = Aut;
29 
31  static automaton_t&
33  {
34  const auto& ws = *res->context().weightset();
35  if (ws.is_zero(w))
36  zero_here(res, tag);
37  else if (!ws.is_one(w))
38  for (auto t: initial_transitions(res))
39  res->lmul_weight(t, w);
40  return res;
41  }
42 
44  static automaton_t&
46  {
47  require(is_standard(res), __func__, ": automaton must be standard");
48  const auto& ws = *res->context().weightset();
49  if (ws.is_zero(w))
50  zero_here(res, tag);
51  else if (!ws.is_one(w))
52  {
53  state_t initial = res->dst_of(initial_transitions(res).front());
54  for (auto t: all_out(res, initial))
55  res->lmul_weight(t, w);
56  }
57  return res;
58  }
59 
61  static automaton_t&
63  {
64  if (is_standard(res))
65  return left_mult_here(w, res, standard_tag{});
66  else
67  return left_mult_here(w, res, general_tag{});
68  }
69 
71  template <typename Tag = general_tag>
72  static automaton_t&
73  right_mult_here(automaton_t& res, const weight_t& w, Tag tag = {})
74  {
75  const auto& ws = *res->context().weightset();
76  if (ws.is_zero(w))
77  zero_here(res, tag);
78  else if (!ws.is_one(w))
79  for (auto t: final_transitions(res))
80  res->rmul_weight(t, w);
81  return res;
82  }
83 
85  static automaton_t&
87  {
88  if (is_standard(res))
89  return right_mult_here(res, w, standard_tag{});
90  else
91  return right_mult_here(res, w, general_tag{});
92  }
93 
95  static automaton_t&
97  {
98  res = make_fresh_automaton(res);
99  return res;
100  }
101 
103  static automaton_t&
105  {
106  zero_here(res, general_tag{});
107  res->set_initial(res->new_state());
108  return res;
109  }
110  };
111  }
112 
113  /*-----------------------.
114  | left-mult(automaton). |
115  `-----------------------*/
116 
118  template <Automaton Aut, typename Tag = auto_tag>
119  Aut&
120  left_mult_here(const weight_t_of<Aut>& w, Aut& res, Tag tag = {})
121  {
123  }
124 
126  template <Automaton Aut, typename Tag = auto_tag>
127  auto
128  left_mult(const weight_t_of<Aut>& w, const Aut& aut, Tag tag = {})
129  -> fresh_automaton_t_of<Aut>
130  {
131  auto res = copy(aut);
132  left_mult_here(w, res, tag);
133  return res;
134  }
135 
136  namespace dyn
137  {
138  namespace detail
139  {
141  template <Automaton Aut, typename Tag>
142  automaton
143  left_mult_tag(const weight_t_of<Aut>& w, Aut& aut)
144  {
145  return make_automaton(::vcsn::left_mult_here(w, aut, Tag{}));
146  }
147 
149  template <typename WeightSet, Automaton Aut, typename String>
150  automaton
151  left_mult(const weight& weight, const automaton& aut,
152  const std::string& algo)
153  {
154  const auto& a1 = aut->as<Aut>();
155  const auto& w1 = weight->as<WeightSet>();
156  // FIXME: this is hairy because there is no elegant means (so
157  // far) to copy an automaton to a supertype, because the
158  // incoming context is not automatically converted to the
159  // supertype by vcsn::copy.
160  auto ctx = make_context(*a1->labelset(),
161  join(w1.weightset(), *a1->weightset()));
162  auto a2 = make_mutable_automaton(ctx);
163  copy_into(a1, a2);
164  using automaton_t = decltype(a2);
165  auto w2 = ctx.weightset()->conv(w1.weightset(), w1.weight());
166  using weight_t = decltype(w2);
167  static const auto map
169  {
170  "left-multiply algorithm",
171  {
172  {"auto", left_mult_tag<automaton_t, auto_tag>},
173  {"general", left_mult_tag<automaton_t, general_tag>},
174  {"standard", left_mult_tag<automaton_t, standard_tag>},
175  }
176  };
177  return map[algo](w2, a2);
178  }
179  }
180  }
181 
182  /*-----------------------.
183  | left-mult(valueset). |
184  `-----------------------*/
185 
186  template <typename ValueSet>
187  auto
188  left_mult(const ValueSet& rs,
189  const weight_t_of<ValueSet>& w,
190  const typename ValueSet::value_t& r)
191  -> decltype(rs.lmul(w, r)) // for SFINAE.
192  {
193  return rs.lmul(w, r);
194  }
195 
196  /*------------------------.
197  | left-mult(expansion). |
198  `------------------------*/
199 
200  template <typename WeightSet, typename ExpSet>
201  expansionset<expressionset<context<labelset_t_of<ExpSet>,
202  join_t<WeightSet, weightset_t_of<ExpSet>>>>>
204  const expansionset<ExpSet>& rs)
205  {
207  rs.expressionset()));
208  }
209 
210  namespace dyn
211  {
212  namespace detail
213  {
215  template <typename WeightSet, typename ExpansionSet>
216  expansion
218  {
219  const auto& w1 = weight->as<WeightSet>();
220  const auto& r1 = exp->as<ExpansionSet>();
221  auto rs
222  = join_weightset_expansionset(w1.weightset(), r1.expansionset());
223  auto w2
224  = rs.expressionset().weightset()->conv(w1.weightset(), w1.weight());
225  auto r2 = rs.conv(r1.expansionset(), r1.expansion());
226  return make_expansion(rs, ::vcsn::left_mult(rs, w2, r2));
227  }
228  }
229  }
230 
231  /*-------------------------.
232  | left-mult(expression). |
233  `-------------------------*/
234 
255  template <typename WeightSet, typename ExpSet>
256  expressionset<context<labelset_t_of<ExpSet>,
257  join_t<WeightSet, weightset_t_of<ExpSet>>>>
259  const ExpSet& rs)
260  {
261  auto ctx = make_context(*rs.labelset(), join(ws, *rs.weightset()));
262  return make_expressionset(ctx, rs.identities());
263  }
264 
265  namespace dyn
266  {
267  namespace detail
268  {
270  template <typename WeightSet, typename ExpSet>
271  expression
273  {
274  const auto& w1 = weight->as<WeightSet>();
275  const auto& r1 = exp->as<ExpSet>();
276  auto rs
277  = join_weightset_expressionset(w1.weightset(), r1.expressionset());
278  auto w2 = rs.weightset()->conv(w1.weightset(), w1.weight());
279  auto r2 = rs.conv(r1.expressionset(), r1.expression());
280  return make_expression(rs,
281  ::vcsn::left_mult(rs, w2, r2));
282  }
283  }
284  }
285 
286  /*------------------------.
287  | right-mult(automaton). |
288  `------------------------*/
289 
291  template <Automaton Aut, typename Tag = auto_tag>
292  Aut&
293  right_mult_here(Aut& res, const weight_t_of<Aut>& w, Tag tag = {})
294  {
296  }
297 
299  template <Automaton Aut, typename Tag = auto_tag>
300  fresh_automaton_t_of<Aut>
301  right_mult(const Aut& aut, const weight_t_of<Aut>& w, Tag tag = {})
302  {
303  auto res = copy(aut);
304  right_mult_here(res, w, tag);
305  return res;
306  }
307 
308  namespace dyn
309  {
310  namespace detail
311  {
313  template <Automaton Aut, typename Tag>
314  automaton
315  right_mult_tag(Aut& aut, const weight_t_of<Aut>& w)
316  {
317  return make_automaton(::vcsn::right_mult_here(aut, w, Tag{}));
318  }
319 
321  template <Automaton Aut, typename WeightSet, typename String>
322  automaton
323  right_mult(const automaton& aut, const weight& weight,
324  const std::string& algo)
325  {
326  const auto& a1 = aut->as<Aut>();
327  const auto& w1 = weight->as<WeightSet>();
328  // FIXME: this is hairy because there is no elegant means (so
329  // far) to copy an automaton to a supertype, because the
330  // incoming context is not automatically converted to the
331  // supertype by vcsn::copy.
332  auto ctx = make_context(*a1->labelset(),
333  join(w1.weightset(), *a1->weightset()));
334  auto a2 = make_mutable_automaton(ctx);
335  copy_into(a1, a2);
336  using automaton_t = decltype(a2);
337  auto w2 = ctx.weightset()->conv(w1.weightset(), w1.weight());
338  using weight_t = decltype(w2);
339  static const auto map
341  {
342  "right-multiply algorithm",
343  {
344  {"auto", right_mult_tag<automaton_t, auto_tag>},
345  {"general", right_mult_tag<automaton_t, general_tag>},
346  {"standard", right_mult_tag<automaton_t, standard_tag>},
347  }
348  };
349  return map[algo](a2, w2);
350  }
351  }
352  }
353 
354  /*------------------------.
355  | right-mult(valueset). |
356  `------------------------*/
357 
358  template <typename ValueSet>
359  typename ValueSet::value_t
360  right_mult(const ValueSet& rs,
361  const typename ValueSet::value_t& r,
362  const weight_t_of<ValueSet>& w)
363  {
364  return rs.rmul(r, w);
365  }
366 
367  /*-------------------------.
368  | right-mult(expansion). |
369  `-------------------------*/
370 
371  namespace dyn
372  {
373  namespace detail
374  {
376  template <typename ExpansionSet, typename WeightSet>
377  expansion
379  {
380  const auto& w1 = weight->as<WeightSet>();
381  const auto& r1 = exp->as<ExpansionSet>();
382  auto rs
383  = join_weightset_expansionset(w1.weightset(), r1.expansionset());
384  auto w2
385  = rs.expressionset().weightset()->conv(w1.weightset(), w1.weight());
386  auto r2 = rs.conv(r1.expansionset(), r1.expansion());
387  return make_expansion(rs, ::vcsn::right_mult(rs, r2, w2));
388  }
389  }
390  }
391 
392  /*--------------------------.
393  | right-mult(expression). |
394  `--------------------------*/
395 
396  namespace dyn
397  {
398  namespace detail
399  {
401  template <typename ExpSet, typename WeightSet>
402  expression
404  {
405  const auto& w1 = weight->as<WeightSet>();
406  const auto& r1 = exp->as<ExpSet>();
407  auto rs
408  = join_weightset_expressionset(w1.weightset(), r1.expressionset());
409  auto w2 = rs.weightset()->conv(w1.weightset(), w1.weight());
410  auto r2 = rs.conv(r1.expressionset(), r1.expression());
411  return make_expression(rs, ::vcsn::right_mult(rs, r2, w2));
412  }
413  }
414  }
415 }
context_t_of< automaton_t > context_t
Definition: left-mult.hh:25
auto initial_transitions(const Aut &aut) -> decltype(aut->all_out(aut->pre()))
Indexes of transitions to (visible) initial states.
Definition: automaton.hh:137
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
automaton right_mult_tag(Aut &aut, const weight_t_of< Aut > &w)
Right-product.
Definition: left-mult.hh:315
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:53
A mapping from strings to Values.
Definition: getargs.hh:33
static automaton_t & left_mult_here(const weight_t &w, automaton_t &res, general_tag tag)
Left-multiplication of any automaton by a weight.
Definition: left-mult.hh:32
weightset_t_of< context_t > weightset_t
Definition: left-mult.hh:27
A dyn automaton.
Definition: automaton.hh:19
AutOut make_fresh_automaton(const AutIn &model)
Create an empty, mutable, automaton, based on another one.
Definition: copy.hh:90
static automaton_t & zero_here(automaton_t &res, standard_tag)
Transform res into the (standard) empty automaton.
Definition: left-mult.hh:104
Tag for operations on all automata.
Definition: tags.hh:22
fresh_automaton_t_of< Aut > right_mult(const Aut &aut, const weight_t_of< Aut > &w, Tag tag={})
Right-multiplication of an automaton by a weight.
Definition: left-mult.hh:301
expressionset< Context > make_expressionset(const Context &ctx, rat::identities identities={})
Shorthand to expressionset constructor.
weight_t_of< context_t > weight_t
Definition: left-mult.hh:26
expression make_expression(const ExpSet &rs, const typename ExpSet::value_t &r)
Definition: expression.hh:97
expression left_mult_expression(const weight &weight, const expression &exp)
Bridge (left_mult).
Definition: left-mult.hh:272
context join(const context &c1, const context &c2)
Bridge.
expansion make_expansion(const ExpansionSet &ps, const typename ExpansionSet::value_t &expansion)
Definition: expansion.hh:78
expansion right_mult_expansion(const expansion &exp, const weight &weight)
Bridge (right_mult).
Definition: left-mult.hh:378
detail::automaton automaton
Definition: automaton.hh:108
auto all_out(const Aut &aut, state_t_of< Aut > s)
Indexes of transitions leaving state s.
Definition: automaton.hh:37
Tag for operations on standard automata.
Definition: tags.hh:25
mutable_automaton< Context > make_mutable_automaton(const Context &ctx)
expression right_mult_expression(const expression &exp, const weight &weight)
Bridge (right_mult).
Definition: left-mult.hh:403
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:308
Tag to request the most appropriate version of an algorithm.
Definition: tags.hh:16
automaton right_mult(const automaton &aut, const weight &weight, const std::string &algo)
Bridge.
Definition: left-mult.hh:323
auto final_transitions(const Aut &aut) -> decltype(aut->all_in(aut->post()))
Indexes of transitions from (visible) final states.
Definition: automaton.hh:148
bool is_standard(const Aut &a)
Whether a is standard.
Definition: standard.hh:28
auto rs
Definition: lift.hh:151
Implementation of left- and right- multiplication of an automaton by a weight.
Definition: left-mult.hh:22
auto left_mult(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: left-mult.hh:128
Ctx make_context(const std::string &name)
Definition: make-context.hh:21
Container::value_type front(const Container &container)
The first member of this Container.
Definition: algorithm.hh:58
automaton left_mult_tag(const weight_t_of< Aut > &w, Aut &aut)
Left-product.
Definition: left-mult.hh:143
Aut & left_mult_here(const weight_t_of< Aut > &w, Aut &res, Tag tag={})
In place left-multiplication of an automaton by a weight.
Definition: left-mult.hh:120
Aut & right_mult_here(Aut &res, const weight_t_of< Aut > &w, Tag tag={})
In place right-multiplication of an automaton by a weight.
Definition: left-mult.hh:293
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:260
context make_context(const std::string &name)
Bridge.
Definition: make-context.hh:45
auto join(const ValueSet &vs) -> ValueSet
The join of a single valueset.
Definition: join.hh:44
static automaton_t & zero_here(automaton_t &res, general_tag)
Transform res into the empty automaton.
Definition: left-mult.hh:96
void require(Bool b, Args &&...args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:78
std::shared_ptr< const detail::weight_base > weight
Definition: fwd.hh:71
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
Definition: traits.hh:59
std::shared_ptr< const detail::expansion_base > expansion
Definition: expansion.hh:73
const expressionset_t & expressionset() const
The expressionset.
Definition: expansionset.hh:61
static automaton_t & right_mult_here(automaton_t &res, const weight_t &w, Tag tag={})
Right-multiplication of any automaton by a weight.
Definition: left-mult.hh:73
static automaton_t & left_mult_here(const weight_t &w, automaton_t &res, auto_tag={})
Same as standard if res is standard, otherwise, general.
Definition: left-mult.hh:62
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
Definition: automaton.hh:113
state_t_of< automaton_t > state_t
Definition: left-mult.hh:28
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: left-mult.hh:258
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:56
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: left-mult.hh:203
static dyn::context ctx(const driver &d)
Get the context of the driver.
Definition: parse.cc:82
expansionset< ExpSet > make_expansionset(const ExpSet &expset)
auto & as()
Extract wrapped typed automaton.
Definition: automaton.hh:39
static automaton_t & right_mult_here(automaton_t &res, const weight_t &w, auto_tag={})
Same as standard if res is standard, otherwise, general.
Definition: left-mult.hh:86
static automaton_t & left_mult_here(const weight_t &w, automaton_t &res, standard_tag tag)
Standard-preserving left-multiplication by a weight.
Definition: left-mult.hh:45
std::shared_ptr< detail::expression_base > expression
Definition: expression.hh:92
expansion left_mult_expansion(const weight &weight, const expansion &exp)
Bridge (left_mult).
Definition: left-mult.hh:217
typename detail::weight_t_of_impl< base_t< ValueSet >>::type weight_t_of
Definition: traits.hh:58
automaton left_mult(const weight &weight, const automaton &aut, const std::string &algo)
Bridge.
Definition: left-mult.hh:151
Definition: a-star.hh:8