Vcsn  2.2
Be Rational
sum.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <map>
4 
6 #include <vcsn/algos/standard.hh> // is_standard
7 #include <vcsn/algos/tags.hh>
9 #include <vcsn/ctx/traits.hh>
10 #include <vcsn/dyn/automaton.hh> // dyn::make_automaton
11 #include <vcsn/dyn/expansion.hh> // dyn::make_expansion
12 #include <vcsn/dyn/expression.hh> // dyn::make_expression
13 #include <vcsn/dyn/polynomial.hh>
14 #include <vcsn/dyn/weight.hh>
15 #include <vcsn/misc/raise.hh> // require
16 
17 namespace vcsn
18 {
19 
20  /*----------------------------.
21  | sum(automaton, automaton). |
22  `----------------------------*/
23 
28  template <Automaton Aut1, Automaton Aut2>
29  Aut1&
30  sum_here(Aut1& res, const Aut2& b, deterministic_tag)
31  {
32  // FIXME: this is a stub: there are better algorithms to compute a
33  // deterministic sum of deterministic automata.
34  sum_here(res, b, standard_tag{});
35  res = determinize(res)->strip();
36  return res;
37  }
38 
43  template <Automaton Aut1, Automaton Aut2>
44  Aut1&
45  sum_here(Aut1& res, const Aut2& b, standard_tag)
46  {
47  require(is_standard(res), __func__, ": lhs must be standard");
48  require(is_standard(b), __func__, ": rhs must be standard");
49 
50  // State in B -> state in Res.
51  auto m = std::map<state_t_of<Aut2>, state_t_of<Aut1>>
52  {
53  {b->pre(), res->pre()},
54  {b->post(), res->post()},
55  };
56  state_t_of<Aut1> initial = res->dst_of(initial_transitions(res).front());
57  for (auto s: b->states())
58  m.emplace(s, b->is_initial(s) ? initial : res->new_state());
59 
60  // Add b.
61  for (auto t: all_transitions(b))
62  if (b->dst_of(t) == b->post())
63  res->add_transition(m[b->src_of(t)], m[b->dst_of(t)],
64  b->label_of(t),
65  res->weightset()->conv(*b->weightset(),
66  b->weight_of(t)));
67  // Do not add initial transitions, the unique initial state is
68  // already declared as such, and its weight must remain 1.
69  else if (b->src_of(t) != b->pre())
70  res->new_transition(m[b->src_of(t)], m[b->dst_of(t)],
71  b->label_of(t),
72  res->weightset()->conv(*b->weightset(),
73  b->weight_of(t)));
74  return res;
75  }
76 
80  template <Automaton Aut1, Automaton Aut2>
81  Aut1&
82  sum_here(Aut1& res, const Aut2& b, general_tag)
83  {
84  copy_into(b, res);
85  return res;
86  }
87 
93  template <Automaton Aut1, Automaton Aut2, typename Tag = general_tag>
94  auto
95  sum(const Aut1& lhs, const Aut2& rhs, Tag tag = {})
96  -> decltype(join_automata(lhs, rhs))
97  {
98  auto res = join_automata(lhs, rhs);
99  copy_into(lhs, res);
100  sum_here(res, rhs, tag);
101  return res;
102  }
103 
104  namespace dyn
105  {
106  namespace detail
107  {
109  template <Automaton Lhs, Automaton Rhs, typename String>
110  automaton
111  sum(const automaton& lhs, const automaton& rhs, const std::string& algo)
112  {
113  const auto& l = lhs->as<Lhs>();
114  const auto& r = rhs->as<Rhs>();
116  [l, r](auto tag)
117  {
118  return make_automaton(::vcsn::sum(l, r, tag));
119  },
120  l, r);
121  }
122  }
123  }
124 
125 
126  /*---------------------.
127  | sum(Value, Value). |
128  `---------------------*/
129 
131  template <typename ValueSet>
132  typename ValueSet::value_t
133  sum(const ValueSet& vs,
134  const typename ValueSet::value_t& lhs,
135  const typename ValueSet::value_t& rhs)
136  {
137  return vs.add(lhs, rhs);
138  }
139 
140 
141  namespace dyn
142  {
143  namespace detail
144  {
146  template <typename PolynomialSetLhs, typename PolynomialSetRhs>
147  polynomial
148  sum_polynomial(const polynomial& lhs, const polynomial& rhs)
149  {
150  auto join_elts = join<PolynomialSetLhs, PolynomialSetRhs>(lhs, rhs);
151  return make_polynomial(std::get<0>(join_elts),
152  sum(std::get<0>(join_elts),
153  std::get<1>(join_elts),
154  std::get<2>(join_elts)));
155  }
156  }
157  }
158 
159 
160  /*-----------------------------.
161  | sum(expansion, expansion). |
162  `-----------------------------*/
163 
164  namespace dyn
165  {
166  namespace detail
167  {
169  template <typename ExpansionSetLhs, typename ExpansionSetRhs>
170  expansion
171  sum_expansion(const expansion& lhs, const expansion& rhs)
172  {
173  const auto& l = lhs->as<ExpansionSetLhs>();
174  const auto& r = rhs->as<ExpansionSetRhs>();
175  auto rs = join(l.expansionset(), r.expansionset());
176  auto lr = rs.conv(l.expansionset(), l.expansion());
177  auto rr = rs.conv(r.expansionset(), r.expansion());
178  return make_expansion(rs, ::vcsn::sum(rs, lr, rr));
179  }
180  }
181  }
182 
183  /*-------------------------------.
184  | sum(expression, expression). |
185  `-------------------------------*/
186 
187  namespace dyn
188  {
189  namespace detail
190  {
192  template <typename ExpSetLhs, typename ExpSetRhs>
193  expression
194  sum_expression(const expression& lhs, const expression& rhs)
195  {
196  auto join_elts = join<ExpSetLhs, ExpSetRhs>(lhs, rhs);
197  return make_expression(std::get<0>(join_elts),
198  ::vcsn::sum(std::get<0>(join_elts),
199  std::get<1>(join_elts),
200  std::get<2>(join_elts)));
201  }
202  }
203  }
204 
205 
206  /*----------------------.
207  | sum(weight, weight). |
208  `----------------------*/
209 
210  namespace dyn
211  {
212  namespace detail
213  {
215  template <typename WeightSetLhs, typename WeightSetRhs>
216  weight
217  sum_weight(const weight& lhs, const weight& rhs)
218  {
219  const auto& l = lhs->as<WeightSetLhs>();
220  const auto& r = rhs->as<WeightSetRhs>();
221  auto rs = join(l.weightset(), r.weightset());
222  auto lr = rs.conv(l.weightset(), l.weight());
223  auto rr = rs.conv(r.weightset(), r.weight());
224  return make_weight(rs, sum(rs, lr, rr));
225  }
226  }
227  }
228 }
Tag for operations on all automata.
Definition: tags.hh:22
std::shared_ptr< const detail::polynomial_base > polynomial
Definition: fwd.hh:70
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
Definition: automaton.hh:75
std::shared_ptr< const detail::weight_base > weight
Definition: fwd.hh:88
auto sum(const Aut1 &lhs, const Aut2 &rhs, Tag tag={}) -> decltype(join_automata(lhs, rhs))
The sum of two automata.
Definition: sum.hh:95
polynomial make_polynomial(const PolynomialSet &ps, const typename PolynomialSet::value_t &p)
Definition: polynomial.hh:103
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
Definition: a-star.hh:8
void require(Bool b, Args &&...args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:78
weight make_weight(const WeightSet &ws, const typename WeightSet::value_t &w)
Definition: weight.hh:79
std::shared_ptr< const detail::expansion_base > expansion
Definition: expansion.hh:73
weightset_mixin< detail::r_impl > r
Definition: fwd.hh:54
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
auto determinize(const Aut &a, Tag={}, bool_constant< Lazy >={})
Definition: determinize.hh:246
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:56
auto initial_transitions(const Aut &aut) -> decltype(aut->all_out(aut->pre()))
Indexes of transitions to (visible) initial states.
Definition: automaton.hh:137
std::shared_ptr< detail::automaton_base > automaton
Definition: automaton.hh:69
auto rs
Definition: lift.hh:151
Aut1 & sum_here(Aut1 &res, const Aut2 &b, deterministic_tag)
Merge transitions of b into those of res.
Definition: sum.hh:30
weight sum_weight(const weight &lhs, const weight &rhs)
Bridge (sum).
Definition: sum.hh:217
polynomial sum_polynomial(const polynomial &lhs, const polynomial &rhs)
Bridge (sum).
Definition: sum.hh:148
expression sum_expression(const expression &lhs, const expression &rhs)
Bridge (sum).
Definition: sum.hh:194
Container::value_type front(const Container &container)
The first member of this Container.
Definition: algorithm.hh:58
Tag for operations on deterministic automata.
Definition: tags.hh:19
auto join_automata(Auts &&...auts) -> decltype(make_mutable_automaton(join(auts->context()...)))
An automaton whose type is the join between those of auts.
expansion sum_expansion(const expansion &lhs, const expansion &rhs)
Bridge (sum).
Definition: sum.hh:171
automaton sum(const automaton &lhs, const automaton &rhs, const std::string &algo)
Bridge.
Definition: sum.hh:111
std::shared_ptr< detail::expression_base > expression
Definition: expression.hh:92
expansion make_expansion(const ExpansionSet &ps, const typename ExpansionSet::value_t &expansion)
Definition: expansion.hh:78
auto all_transitions(const Aut &aut)
All the transition indexes between all states (including pre and post).
Definition: automaton.hh:184
context join(const context &c1, const context &c2)
Bridge.
bool is_standard(const Aut &a)
Whether a is standard.
Definition: standard.hh:28
Tag for operations on standard automata.
Definition: tags.hh:25
expression make_expression(const ExpSet &rs, const typename ExpSet::value_t &r)
Definition: expression.hh:97
auto dispatch_tags(std::string algo, Operation op, Aut &&...auts)
Dispatch an operation between automata depending on their nature.
Definition: tags.hh:32