Vcsn  2.1
Be Rational
copy.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <unordered_map>
4 
5 #include <vcsn/algos/fwd.hh> // focus_automaton.
7 #include <vcsn/core/fwd.hh>
9 #include <vcsn/core/rat/copy.hh>
10 #include <vcsn/dyn/automaton.hh>
11 #include <vcsn/dyn/context.hh>
12 #include <vcsn/dyn/expression.hh>
13 #include <vcsn/misc/attributes.hh>
14 #include <vcsn/misc/set.hh>
16 
17 namespace vcsn
18 {
19 
20  /*------------------.
21  | copy(automaton). |
22  `------------------*/
23 
24  namespace detail
25  {
33  template <typename AutIn, typename AutOut = AutIn>
34  struct copier
35  {
36  using in_automaton_t = AutIn;
37  using out_automaton_t = AutOut;
38 
42  using state_map_t = std::unordered_map<in_state_t, out_state_t>;
43 
45  : in_(in)
46  , out_(out)
47  , out_state_{{in_->pre(), out_->pre()},
48  {in_->post(), out_->post()}}
49  {}
50 
55  template <typename KeepState, typename KeepTrans>
56  void operator()(KeepState keep_state, KeepTrans keep_trans,
57  bool safe = true)
58  {
59  // Copy the states. We cannot iterate on the transitions
60  // only, as we would lose the states without transitions. And
61  // this way, we keep the states in the same order.
62  for (auto s: in_->states())
63  if (keep_state(s))
64  out_state_[s] = out_->new_state();
65 
66  for (auto t : in_->all_transitions())
67  if (keep_trans(t))
68  {
69  auto src = out_state_.find(in_->src_of(t));
70  auto dst = out_state_.find(in_->dst_of(t));
71  if (src != out_state_.end() && dst != out_state_.end())
72  {
73  if (safe)
74  out_->new_transition_copy(src->second, dst->second,
75  in_, t);
76  else
77  out_->add_transition_copy(src->second, dst->second,
78  in_, t);
79  }
80  }
81  }
82 
84  void operator()(bool safe = true)
85  {
86  operator()([](state_t_of<in_automaton_t>) { return true; },
87  [](transition_t_of<in_automaton_t>) { return true; },
88  safe);
89  }
90 
92  const state_map_t& state_map() const
93  {
94  return out_state_;
95  }
96 
99  {
100  return out_state_;
101  }
102 
103  private:
110  };
111  }
112 
114  template <typename AutIn, typename AutOut>
116  make_copier(const AutIn& in, AutOut& out)
117  {
118  return {in, out};
119  }
120 
123  template <typename AutIn, typename AutOut,
124  typename KeepState, typename KeepTrans>
125  inline void
126  copy_into(const AutIn& in, AutOut& out,
127  KeepState keep_state, KeepTrans keep_trans)
128  {
129  auto copy = make_copier(in, out);
130  return copy(keep_state, keep_trans);
131  }
132 
135  template <typename AutIn, typename AutOut, typename KeepState>
136  inline
137  void
138  copy_into(const AutIn& in, AutOut& out, KeepState keep_state)
139  {
140  return copy_into(in, out, keep_state,
141  [](transition_t_of<AutIn>) { return true; });
142  }
143 
146  template <typename AutIn, typename AutOut>
147  inline
148  void
149  copy_into(const AutIn& in, AutOut& out)
150  {
151  return copy_into(in, out,
152  [](state_t_of<AutIn>) { return true; },
153  [](transition_t_of<AutIn>) { return true; });
154  }
155 
158  template <typename AutIn, typename AutOut>
159  inline
160  void
161  copy_into(const AutIn& in, AutOut& out, bool safe)
162  {
163  auto copy = make_copier(in, out);
164  return copy([](state_t_of<AutIn>) { return true; },
165  [](transition_t_of<AutIn>) { return true; },
166  safe);
167  }
168 
169  namespace detail
170  {
175  template <typename Aut>
177 
180  template <typename Aut>
181  auto
182  real_context(const Aut& aut)
183  -> decltype(real_context_impl<Aut>::context(aut));
184 
185  template <typename Aut>
186  struct real_context_impl
187  {
188  static auto context(const Aut& aut)
189  -> decltype(aut->context())
190  {
191  return aut->context();
192  }
193  };
194 
195  template <std::size_t Tape, typename Aut>
197  {
198  static auto context(const focus_automaton<Tape, Aut>& aut)
199  -> decltype(aut->full_context())
200  {
201  return aut->full_context();
202  }
203  };
204 
206  //
207  // FIXME: try to recurse on all automaton decorator types without
208  // listing them.
209  template <typename Aut>
211  {
212  static auto context(const automaton_decorator<Aut>& aut)
213  -> decltype(real_context(aut->strip()))
214  {
215  return real_context(aut->strip());
216  }
217  };
218 
219  template <typename Aut>
220  auto
221  real_context(const Aut& aut)
222  -> decltype(real_context_impl<Aut>::context(aut))
223  {
225  }
226  }
227 
236  template <typename AutIn,
237  typename AutOut = fresh_automaton_t_of<AutIn>>
238  inline AutOut
239  make_fresh_automaton(const AutIn& model)
240  {
241  // FIXME: here, we need a means to convert the given input context
242  // (e.g. letter -> B) into the destination one (e.g., letter ->
243  // Q). The automaton constructor wants the exact context type.
244  return make_shared_ptr<AutOut>(detail::real_context(model));
245  }
246 
249  template <typename AutIn,
250  typename AutOut = fresh_automaton_t_of<AutIn>,
251  typename KeepState, typename KeepTrans>
252  inline
253  AutOut
254  copy(const AutIn& input, KeepState keep_state, KeepTrans keep_trans)
255  {
256  auto res = make_fresh_automaton<AutIn, AutOut>(input);
257  ::vcsn::copy_into(input, res, keep_state, keep_trans);
258  return res;
259  }
260 
262  template <typename AutIn,
263  typename AutOut = fresh_automaton_t_of<AutIn>,
264  typename KeepState>
265  inline
266  AutOut
267  copy(const AutIn& input, KeepState keep_state)
268  {
269  return ::vcsn::copy<AutIn, AutOut>(
270  input,
271  keep_state,
272  [](transition_t_of<AutIn>) { return true; }
273  );
274  }
275 
277  template <typename AutIn,
278  typename AutOut = fresh_automaton_t_of<AutIn>>
279  inline
280  AutOut
281  copy(const AutIn& input)
282  {
283  return ::vcsn::copy<AutIn, AutOut>(
284  input,
285  [](state_t_of<AutIn>) { return true; },
286  [](transition_t_of<AutIn>) { return true; }
287  );
288  }
289 
292  template <typename AutIn,
293  typename AutOut = fresh_automaton_t_of<AutIn>>
294  inline
295  AutOut
296  copy(const AutIn& input, const std::set<state_t_of<AutIn>>& keep)
297  {
298  return ::vcsn::copy<AutIn, AutOut>
299  (input,
300  [&keep](state_t_of<AutIn> s) { return has(keep, s); });
301  }
302 
305  template <typename AutIn,
306  typename AutOut = fresh_automaton_t_of<AutIn>>
307  inline
308  AutOut
309  copy(const AutIn& input, const std::unordered_set<state_t_of<AutIn>>& keep)
310  {
311  return ::vcsn::copy<AutIn, AutOut>
312  (input,
313  [&keep](state_t_of<AutIn> s) { return has(keep, s); });
314  }
315 
316  namespace dyn
317  {
318  namespace detail
319  {
321  template <typename Aut, typename Ctx>
322  inline
323  automaton
324  copy_convert(const automaton& aut, const context& ctx)
325  {
326  const auto& a = aut->as<Aut>();
327  const auto& c = ctx->as<Ctx>();
328  auto res = make_mutable_automaton(c);
329  ::vcsn::copy_into(a, res);
330  return make_automaton(res);
331  }
332 
334  template <typename Aut>
335  inline
336  automaton
337  copy(const automaton& aut)
338  {
339  const auto& a = aut->as<Aut>();
340  return make_automaton(::vcsn::copy(a));
341  }
342  }
343  }
344 
345  /*--------------------.
346  | copy(expression). |
347  `--------------------*/
348 
349  namespace dyn
350  {
351  namespace detail
352  {
354  template <typename ExpSet, typename Context, typename Identities>
355  inline
356  expression
358  const context& ctx, rat::identities ids)
359  {
360  const auto& r = exp->as<ExpSet>();
361  const auto& c = ctx->as<Context>();
362  const auto& rs = make_expressionset(c, ids);
363 
364  return make_expression(rs,
365  ::vcsn::rat::copy(r.expressionset(), rs,
366  r.expression()));
367  }
368  }
369  }
370 
371 
372 
373 } // namespace vcsn
static auto context(const focus_automaton< Tape, Aut > &aut) -> decltype(aut->full_context())
Definition: copy.hh:198
Copy an automaton.
Definition: copy.hh:34
void copy_into(const AutIn &in, AutOut &out, bool safe)
Copy an automaton.
Definition: copy.hh:161
std::shared_ptr< const detail::context_base > context
A dyn::context.
Definition: fwd.hh:41
detail::copier< AutIn, AutOut > make_copier(const AutIn &in, AutOut &out)
Build an automaton copier.
Definition: copy.hh:116
void operator()(bool safe=true)
Copy all the states, and all the transitions.
Definition: copy.hh:84
AutOut make_fresh_automaton(const AutIn &model)
Create an empty, mutable, automaton, based on another one.
Definition: copy.hh:239
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:48
OutExpSet::value_t copy(const InExpSet &in_rs, const OutExpSet &out_rs, const typename InExpSet::value_t &v)
Copy/convert a rational expression.
Definition: copy.hh:183
auto real_context(const Aut &aut) -> decltype(real_context_impl< Aut >::context(aut))
For a focus automaton, its genuine context (not the visible one), and for all the other automata...
Definition: copy.hh:221
Aggregate an automaton, and forward calls to it.
copier(const in_automaton_t &in, out_automaton_t &out)
Definition: copy.hh:44
const state_map_t & state_map() const
A map from original state to result state.
Definition: copy.hh:92
KeepTrans void operator()(KeepState keep_state, KeepTrans keep_trans, bool safe=true)
Definition: copy.hh:56
static auto context(const automaton_decorator< Aut > &aut) -> decltype(real_context(aut->strip()))
Definition: copy.hh:212
std::unordered_map< in_state_t, out_state_t > state_map_t
input state -> output state.
Definition: copy.hh:42
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
Definition: automaton.hh:75
state_t_of< in_automaton_t > in_state_t
Definition: copy.hh:39
static dyn::context ctx(const driver &d)
Get the context of the driver.
Definition: parse.cc:80
AutOut copy(const AutIn &input, KeepState keep_state, KeepTrans keep_trans)
A copy of input keeping only its states that are accepted by keep_state.
Definition: copy.hh:254
mutable_automaton< Context > make_mutable_automaton(const Context &ctx)
out_automaton_t out_
Output automaton.
Definition: copy.hh:107
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
std::shared_ptr< detail::automaton_base > automaton
Definition: automaton.hh:69
static identities ids(const driver &d)
Get the identities of the driver.
Definition: parse.cc:87
static auto context(const Aut &aut) -> decltype(aut->context())
Definition: copy.hh:188
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:126
state_map_t & state_map()
A map from original state to result state.
Definition: copy.hh:98
expression copy_expression(const expression &exp, const context &ctx, rat::identities ids)
Bridge (copy).
Definition: copy.hh:357
typename detail::transition_t_of_impl< base_t< ValueSet >>::type transition_t_of
Definition: traits.hh:49
expressionset< Context > make_expressionset(const Context &ctx, rat::identities identities={})
Shorthand to expressionset constructor.
auto rs
Definition: lift.hh:151
An expressionset can implement several different sets of identities on expressions.
Definition: identities.hh:21
AutOut out_automaton_t
Definition: copy.hh:37
expression make_expression(const ExpSet &rs, const typename ExpSet::value_t &r)
Definition: expression.hh:83
state_map_t out_state_
input state -> output state.
Definition: copy.hh:109
AutIn in_automaton_t
Definition: copy.hh:36
std::shared_ptr< detail::focus_automaton_impl< Tape, Aut >> focus_automaton
A focus automaton as a shared pointer.
Definition: fwd.hh:41
ATTRIBUTE_PURE bool has(const std::deque< T, Allocator > &s, const T &e)
Whether e is member of s.
Definition: deque.hh:13
std::shared_ptr< detail::expression_base > expression
Definition: expression.hh:78
automaton copy(const automaton &aut)
Bridge.
Definition: copy.hh:337
state_t_of< out_automaton_t > out_state_t
Definition: copy.hh:40
When we copy a focus automaton, create another focus automaton.
Definition: copy.hh:176
automaton copy_convert(const automaton &aut, const context &ctx)
Bridge (copy).
Definition: copy.hh:324
in_automaton_t in_
Input automaton.
Definition: copy.hh:105