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