Vcsn  2.0
Be Rational
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
concatenate.hh
Go to the documentation of this file.
1 #ifndef VCSN_ALGOS_CONCATENATE_HH
2 # define VCSN_ALGOS_CONCATENATE_HH
3 
4 # include <unordered_map>
5 # include <vector>
6 
7 # include <vcsn/algos/copy.hh>
8 # include <vcsn/algos/product.hh> // join_automata
9 # include <vcsn/algos/standard.hh>
10 # include <vcsn/algos/sum.hh>
11 # include <vcsn/core/join.hh>
14 # include <vcsn/dyn/automaton.hh> // dyn::make_automaton
15 # include <vcsn/dyn/polynomial.hh>
16 # include <vcsn/dyn/weight.hh>
17 # include <vcsn/misc/raise.hh> // require
18 
19 namespace vcsn
20 {
21  /*------------------------------------.
22  | concatenate(automaton, automaton). |
23  `------------------------------------*/
24 
29  template <typename A, typename B>
30  A&
31  concatenate_here(A& res, const B& b)
32  {
33  require(is_standard(res), __func__, ": lhs must be standard");
34  require(is_standard(b), __func__, ": rhs must be standard");
35 
36  using automaton_t = A;
37  const auto& ls = *res->labelset();
38  const auto& bls = *b->labelset();
39  const auto& ws = *res->weightset();
40  const auto& bws = *b->weightset();
41 
42  // The set of the current (left-hand side) final transitions.
43  auto ftr_ = res->final_transitions();
44  // Store these transitions by copy.
45  using transs_t = std::vector<transition_t_of<automaton_t>>;
46  transs_t ftr{ begin(ftr_), end(ftr_) };
47 
48  state_t_of<B> b_initial = b->dst_of(b->initial_transitions().front());
49  // State in B -> state in Res.
50  // The initial state of b is not copied.
51  std::unordered_map<state_t_of<B>, state_t_of<A>> m;
52  m.emplace(b->post(), res->post());
53  for (auto s: b->states())
54  if (!b->is_initial(s))
55  m.emplace(s, res->new_state());
56 
57  // Import all the B transitions, except the initial ones
58  // and those from its (genuine) initial state.
59  //
60  // FIXME: provide generalized copy() that returns the map of
61  // states orig -> copy.
62  for (auto t: b->all_transitions())
63  if (b->src_of(t) != b->pre() && b->src_of(t) != b_initial)
64  res->new_transition(m[b->src_of(t)], m[b->dst_of(t)],
65  ls.conv(bls, b->label_of(t)),
66  ws.conv(bws, b->weight_of(t)));
67 
68  // Branch all the final transitions of res to the successors of
69  // b's initial state.
70  for (auto t1: ftr)
71  {
72  // Remove the previous final transition first, as we might add
73  // a final transition for the same state later.
74  //
75  // For instance on "<2>a+(<3>\e+<5>a)", the final state s1 of
76  // <2>a will be made final thanks to <3>\e. So if we compute
77  // the new transitions from s1 and then remove t1, we will
78  // have removed the fact that s1 is final thanks to <3>\e.
79  //
80  // Besides, s1 will become final with weight <3>, which might
81  // interfere with <5>a too.
82  auto s1 = res->src_of(t1);
83  auto w1 = res->weight_of(t1);
84  res->del_transition(t1);
85  for (auto t2: b->all_out(b_initial))
86  res->set_transition(s1,
87  m[b->dst_of(t2)],
88  ls.conv(bls, b->label_of(t2)),
89  ws.mul(w1,
90  ws.conv(bws, b->weight_of(t2))));
91  }
92  return res;
93  }
94 
96  template <typename A, typename B>
97  inline
98  auto
99  concatenate(const A& lhs, const B& rhs)
100  -> decltype(join_automata(lhs, rhs))
101  {
102  require(is_standard(lhs), __func__, ": lhs must be standard");
103  require(is_standard(rhs), __func__, ": rhs must be standard");
104  auto res = join_automata(lhs, rhs);
105  ::vcsn::copy_into(lhs, res);
106  concatenate_here(res, rhs);
107  return res;
108  }
109 
110  namespace dyn
111  {
112  namespace detail
113  {
115  template <typename Lhs, typename Rhs>
116  automaton
117  concatenate(const automaton& lhs, const automaton& rhs)
118  {
119  const auto& l = lhs->as<Lhs>();
120  const auto& r = rhs->as<Rhs>();
121  return make_automaton(::vcsn::concatenate(l, r));
122  }
123 
125  (const automaton&, const automaton&) -> automaton);
126  }
127  }
128 
129  /*-----------------------------.
130  | chain(automaton, min, max). |
131  `-----------------------------*/
132 
133  template <typename Aut>
134  Aut
135  chain(const Aut& aut, int min, int max)
136  {
137  Aut res =
138  make_shared_ptr<Aut>(aut->context());
139  if (max == -1)
140  {
141  res = star(aut);
142  if (min != -1)
143  res = concatenate(chain(aut, min, min), res);
144  }
145  else
146  {
147  if (min == -1)
148  min = 0;
149  if (min == 0)
150  {
151  // automatonset::one().
152  auto s = res->new_state();
153  res->set_initial(s);
154  res->set_final(s);
155  }
156  else
157  {
158  res = vcsn::copy(aut);
159  for (int n = 1; n < min; ++n)
160  res = concatenate(res, aut);
161  }
162  if (min < max)
163  {
164  // Aut sum = automatonset.one();
165  Aut sum = make_shared_ptr<Aut>(aut->context());
166  {
167  auto s = sum->new_state();
168  sum->set_initial(s);
169  sum->set_final(s);
170  }
171  for (int n = 1; n <= max - min; ++n)
172  sum = vcsn::sum(sum, chain(aut, n, n));
173  res = vcsn::concatenate(res, sum);
174  }
175  }
176  return res;
177  }
178 
179 
180 
181  namespace dyn
182  {
183  namespace detail
184  {
186  template <typename Aut, typename Int1, typename Int2>
187  automaton
188  chain(const automaton& a, int min, int max)
189  {
190  const auto& aut = a->as<Aut>();
191  return make_automaton(::vcsn::chain(aut, min, max));
192  }
193 
195  (const automaton& aut, int min, int max) -> automaton);
196  }
197  }
198 
199 
200  /*------------------------------.
201  | concatenate(ratexp, ratexp). |
202  `------------------------------*/
203 
205  template <typename ValueSet>
206  inline
207  typename ValueSet::value_t
208  concatenate(const ValueSet& vs,
209  const typename ValueSet::value_t& lhs,
210  const typename ValueSet::value_t& rhs)
211  {
212  return vs.mul(lhs, rhs);
213  }
214 
215  namespace dyn
216  {
217  namespace detail
218  {
220  template <typename RatExpSetLhs, typename RatExpSetRhs>
221  ratexp
222  concatenate_ratexp(const ratexp& lhs, const ratexp& rhs)
223  {
224  const auto& l = lhs->as<RatExpSetLhs>();
225  const auto& r = rhs->as<RatExpSetRhs>();
226  auto rs = vcsn::join(l.ratexpset(), r.ratexpset());
227  auto lr = rs.conv(l.ratexpset(), l.ratexp());
228  auto rr = rs.conv(r.ratexpset(), r.ratexp());
229  return make_ratexp(rs, ::vcsn::concatenate(rs, lr, rr));
230  }
231 
233  (const ratexp&, const ratexp&) -> ratexp);
234  }
235  }
236 
237 
238  /*--------------------------.
239  | chain(ratexp, min, max). |
240  `--------------------------*/
241 
242  template <typename RatExpSet>
243  typename RatExpSet::value_t
244  chain(const RatExpSet& rs, const typename RatExpSet::value_t& r,
245  int min, int max)
246  {
247  typename RatExpSet::value_t res;
248  if (max == -1)
249  {
250  res = rs.star(r);
251  if (min != -1)
252  res = rs.mul(chain(rs, r, min, min), res);
253  }
254  else
255  {
256  if (min == -1)
257  min = 0;
258  if (min == 0)
259  res = rs.one();
260  else
261  {
262  res = r;
263  for (int n = 1; n < min; ++n)
264  res = rs.mul(res, r);
265  }
266  if (min < max)
267  {
268  typename RatExpSet::value_t sum = rs.one();
269  for (int n = 1; n <= max - min; ++n)
270  sum = rs.add(sum, chain(rs, r, n, n));
271  res = rs.mul(res, sum);
272  }
273  }
274  return res;
275  }
276 
277  namespace dyn
278  {
279  namespace detail
280  {
282  template <typename RatExpSet, typename Int1, typename Int2>
283  ratexp
284  chain_ratexp(const ratexp& re, int min, int max)
285  {
286  const auto& r = re->as<RatExpSet>();
287  return make_ratexp(r.ratexpset(),
288  ::vcsn::chain(r.ratexpset(), r.ratexp(), min, max));
289  }
290 
292  (const ratexp&, int, int) -> ratexp);
293  }
294  }
295 
296 
297  /*------------------------------.
298  | mul(polynomial, polynomial). |
299  `------------------------------*/
300 
301  namespace dyn
302  {
303  namespace detail
304  {
306  template <typename PolynomialSetLhs, typename PolynomialSetRhs>
307  polynomial
309  {
310  const auto& l = lhs->as<PolynomialSetLhs>();
311  const auto& r = rhs->as<PolynomialSetRhs>();
312  auto rs = join(l.polynomialset(), r.polynomialset());
313  auto lr = rs.conv(l.polynomialset(), l.polynomial());
314  auto rr = rs.conv(r.polynomialset(), r.polynomial());
315  return make_polynomial(rs, concatenate(rs, lr, rr));
316  }
317 
319  (const polynomial&, const polynomial&) -> polynomial);
320  }
321  }
322 
323  /*----------------------.
324  | mul(weight, weight). |
325  `----------------------*/
326 
328  template <typename ValueSet>
329  inline
330  typename ValueSet::value_t
331  multiply(const ValueSet& vs,
332  const typename ValueSet::value_t& lhs,
333  const typename ValueSet::value_t& rhs)
334  {
335  return vs.mul(lhs, rhs);
336  }
337 
338  namespace dyn
339  {
340  namespace detail
341  {
343  template <typename WeightSetLhs, typename WeightSetRhs>
344  weight
345  multiply_weight(const weight& lhs, const weight& rhs)
346  {
347  const auto& l = lhs->as<WeightSetLhs>();
348  const auto& r = rhs->as<WeightSetRhs>();
349  auto rs = join(l.weightset(), r.weightset());
350  auto lr = rs.conv(l.weightset(), l.weight());
351  auto rr = rs.conv(r.weightset(), r.weight());
352  return make_weight(rs, multiply(rs, lr, rr));
353  }
354 
356  (const weight&, const weight&) -> weight);
357  }
358  }
359 }
360 
361 #endif // !VCSN_ALGOS_CONCATENATE_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
polynomial make_polynomial(const PolynomialSet &ps, const typename PolynomialSet::value_t &polynomial)
Definition: polynomial.hh:91
automaton concatenate(const automaton &lhs, const automaton &rhs)
Bridge.
Definition: concatenate.hh:117
A & concatenate_here(A &res, const B &b)
Append automaton b to res.
Definition: concatenate.hh:31
auto concatenate(const A &lhs, const B &rhs) -> decltype(join_automata(lhs, rhs))
Concatenate two standard automata.
Definition: concatenate.hh:99
bool is_standard(const Aut &a)
Whether a is standard.
Definition: standard.hh:27
weight multiply_weight(const weight &lhs, const weight &rhs)
Bridge.
Definition: concatenate.hh:345
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
AutOut copy(const AutIn &input, Pred keep_state)
A copy of input keeping only its states that are accepted by keep_state.
Definition: copy.hh:171
ValueSet::value_t multiply(const ValueSet &vs, const typename ValueSet::value_t &lhs, const typename ValueSet::value_t &rhs)
Product of weights.
Definition: concatenate.hh:331
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
RatExpSet::value_t chain(const RatExpSet &rs, const typename RatExpSet::value_t &r, int min, int max)
Definition: concatenate.hh:244
auto sum(const A &lhs, const B &rhs) -> decltype(join_automata(lhs, rhs))
Definition: sum.hh:65
void copy_into(const AutIn &in, AutOut &out, Pred keep_state)
Copy an automaton.
Definition: copy.hh:101
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
weight multiply(const weight &lhs, const weight &rhs)
Multiply two weights.
Definition: concatenate.cc:46
ratexp concatenate_ratexp(const ratexp &lhs, const ratexp &rhs)
Bridge.
Definition: concatenate.hh:222
ratexp chain_ratexp(const ratexp &re, int min, int max)
Bridge.
Definition: concatenate.hh:284
Aut::element_type::automaton_nocv_t star(const Aut &aut)
Star of a standard automaton.
Definition: star.hh:61
Aut chain(const Aut &aut, int min, int max)
Definition: concatenate.hh:135
std::shared_ptr< const detail::polynomial_base > polynomial
Definition: fwd.hh:55
variadic_mul_mixin< detail::r_impl > r
Definition: fwd.hh:42
polynomial concatenate_polynomial(const polynomial &lhs, const polynomial &rhs)
Bridge.
Definition: concatenate.hh:308
void require(bool b, Args &&...args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:39
automaton chain(const automaton &a, int min, int max)
Bridge.
Definition: concatenate.hh:188