Vcsn  2.1
Be Rational
sum.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <map>
4 
5 #include <vcsn/algos/standard.hh> // is_standard
7 #include <vcsn/ctx/traits.hh>
8 #include <vcsn/dyn/automaton.hh> // dyn::make_automaton
9 #include <vcsn/dyn/expression.hh> // dyn::make_expression
10 #include <vcsn/dyn/polynomial.hh>
11 #include <vcsn/dyn/weight.hh>
12 #include <vcsn/misc/raise.hh> // require
13 
14 namespace vcsn
15 {
16 
17  /*----------------------------.
18  | sum(automaton, automaton). |
19  `----------------------------*/
20 
25  template <typename A, typename B>
26  A&
27  sum_here(A& res, const B& b)
28  {
29  require(is_standard(res), __func__, ": lhs must be standard");
30  require(is_standard(b), __func__, ": rhs must be standard");
31 
32  // State in B -> state in Res.
33  std::map<state_t_of<B>, state_t_of<A>> m;
34  state_t_of<A> initial = res->dst_of(res->initial_transitions().front());
35  for (auto s: b->states())
36  m.emplace(s, b->is_initial(s) ? initial : res->new_state());
37  m.emplace(b->pre(), res->pre());
38  m.emplace(b->post(), res->post());
39 
40  // Add b.
41  for (auto t: b->all_transitions())
42  // Do not add initial transitions, the unique initial state is
43  // already declared as such, and its weight must remain 1.
44  if (b->src_of(t) != b->pre())
45  {
46  if (b->dst_of(t) == b->post())
47  res->add_transition(m[b->src_of(t)], m[b->dst_of(t)],
48  b->label_of(t),
49  res->weightset()->conv(*b->weightset(),
50  b->weight_of(t)));
51  else
52  res->new_transition(m[b->src_of(t)], m[b->dst_of(t)],
53  b->label_of(t),
54  res->weightset()->conv(*b->weightset(),
55  b->weight_of(t)));
56  }
57  return res;
58  }
59 
60 
61  template <typename A, typename B>
62  inline
63  auto
64  sum(const A& lhs, const B& rhs)
65  -> decltype(join_automata(lhs, rhs))
66  {
67  auto res = join_automata(lhs, rhs);
68  // A standard automaton has a single initial state.
69  res->set_initial(res->new_state());
70  sum_here(res, lhs);
71  sum_here(res, rhs);
72  return res;
73  }
74 
75  namespace dyn
76  {
77  namespace detail
78  {
80  template <typename Lhs, typename Rhs>
81  automaton
82  sum(const automaton& lhs, const automaton& rhs)
83  {
84  const auto& l = lhs->as<Lhs>();
85  const auto& r = rhs->as<Rhs>();
86  return make_automaton(::vcsn::sum(l, r));
87  }
88  }
89  }
90 
91 
92  /*---------------------.
93  | sum(Value, Value). |
94  `---------------------*/
95 
97  template <typename ValueSet>
98  inline
99  typename ValueSet::value_t
100  sum(const ValueSet& vs,
101  const typename ValueSet::value_t& lhs,
102  const typename ValueSet::value_t& rhs)
103  {
104  return vs.add(lhs, rhs);
105  }
106 
107 
108  namespace dyn
109  {
110  namespace detail
111  {
113  template <typename PolynomialSetLhs, typename PolynomialSetRhs>
114  polynomial
115  sum_polynomial(const polynomial& lhs, const polynomial& rhs)
116  {
117  const auto& l = lhs->as<PolynomialSetLhs>();
118  const auto& r = rhs->as<PolynomialSetRhs>();
119  auto rs = join(l.polynomialset(), r.polynomialset());
120  auto lr = rs.conv(l.polynomialset(), l.polynomial());
121  auto rr = rs.conv(r.polynomialset(), r.polynomial());
122  return make_polynomial(rs, sum(rs, lr, rr));
123  }
124  }
125  }
126 
127 
128  /*-------------------------------.
129  | sum(expression, expression). |
130  `-------------------------------*/
131 
132  namespace dyn
133  {
134  namespace detail
135  {
137  template <typename ExpSetLhs, typename ExpSetRhs>
138  expression
139  sum_expression(const expression& lhs, const expression& rhs)
140  {
141  const auto& l = lhs->as<ExpSetLhs>();
142  const auto& r = rhs->as<ExpSetRhs>();
143  auto rs = join(l.expressionset(), r.expressionset());
144  auto lr = rs.conv(l.expressionset(), l.expression());
145  auto rr = rs.conv(r.expressionset(), r.expression());
146  return make_expression(rs, ::vcsn::sum(rs, lr, rr));
147  }
148  }
149  }
150 
151 
152  /*----------------------.
153  | sum(weight, weight). |
154  `----------------------*/
155 
156  namespace dyn
157  {
158  namespace detail
159  {
161  template <typename WeightSetLhs, typename WeightSetRhs>
162  weight
163  sum_weight(const weight& lhs, const weight& rhs)
164  {
165  const auto& l = lhs->as<WeightSetLhs>();
166  const auto& r = rhs->as<WeightSetRhs>();
167  auto rs = join(l.weightset(), r.weightset());
168  auto lr = rs.conv(l.weightset(), l.weight());
169  auto rr = rs.conv(r.weightset(), r.weight());
170  return make_weight(rs, sum(rs, lr, rr));
171  }
172  }
173  }
174 }
A & sum_here(A &res, const B &b)
Merge transitions of b into those of res.
Definition: sum.hh:27
automaton sum(const automaton &lhs, const automaton &rhs)
Bridge.
Definition: sum.hh:82
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:48
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
Definition: automaton.hh:75
expression sum_expression(const expression &lhs, const expression &rhs)
Bridge (sum).
Definition: sum.hh:139
std::shared_ptr< const detail::weight_base > weight
Definition: fwd.hh:86
polynomial make_polynomial(const PolynomialSet &ps, const typename PolynomialSet::value_t &p)
Definition: polynomial.hh:88
bool is_standard(const Aut &a)
Whether a is standard.
Definition: standard.hh:27
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
weight make_weight(const WeightSet &ws, const typename WeightSet::value_t &w)
Definition: weight.hh:79
std::shared_ptr< detail::automaton_base > automaton
Definition: automaton.hh:69
void require(bool b, Args &&...args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:75
auto rs
Definition: lift.hh:151
std::shared_ptr< const detail::polynomial_base > polynomial
Definition: fwd.hh:68
expression make_expression(const ExpSet &rs, const typename ExpSet::value_t &r)
Definition: expression.hh:83
polynomial sum_polynomial(const polynomial &lhs, const polynomial &rhs)
Bridge (sum).
Definition: sum.hh:115
auto sum(const A &lhs, const B &rhs) -> decltype(join_automata(lhs, rhs))
Definition: sum.hh:64
auto join_automata(Auts &&...auts) -> decltype(make_mutable_automaton(join(auts->context()...)))
An automaton whose type is the join between those of auts.
weight sum_weight(const weight &lhs, const weight &rhs)
Bridge (sum).
Definition: sum.hh:163
std::shared_ptr< detail::expression_base > expression
Definition: expression.hh:78
context join(const context &c1, const context &c2)
Bridge.
Definition: make-context.hh:92