Vcsn  2.1
Be Rational
focus.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <vcsn/algos/fwd.hh>
4 #include <vcsn/algos/project.hh> // make_project_context
7 #include <vcsn/ctx/context.hh>
8 #include <vcsn/ctx/traits.hh>
9 #include <vcsn/dyn/automaton.hh>
10 #include <vcsn/dyn/context.hh>
12 #include <vcsn/misc/name.hh> // integral_constant
13 #include <vcsn/misc/tuple.hh> // make_index_range
14 
15 namespace vcsn
16 {
17 
18  /*-------------------.
19  | focus_automaton. |
20  `-------------------*/
21 
22  namespace detail
23  {
24  template <typename A, typename I>
26 
27  template <typename Aut, std::size_t... I>
28  struct hidden_label_type<Aut, index_sequence<I...>>
29  {
32  };
33 
34 
36  template <std::size_t Tape, typename Aut>
38  : public automaton_decorator<Aut,
39  project_context<Tape, context_t_of<Aut>>>
40  {
41  public:
43  using automaton_t = Aut;
44 
45  static_assert(context_t_of<Aut>::is_lat,
46  "focus: requires labels_are_tuples");
47  static_assert(Tape < labelset_t_of<Aut>::size(),
48  "focus: invalid tape number");
49 
54 
58  using full_labelset_t = typename full_context_t::labelset_t;
60  using full_label_t = typename full_labelset_t::value_t;
61 
64 
68  using label_t = typename labelset_t::value_t;
69 
73  using weight_t = typename weightset_t::value_t;
74 
92  template <typename = void>
93  using fresh_automaton_t
94  = focus_automaton<Tape,
96 
98  using hidden_indices_t
101  make_index_range_t<Tape + 1,
102  std::tuple_size<full_label_t>::value - Tape - 1>>;
103 
104  // All tapes except the exposed one.
105  using res_labelset_t
107  using res_label_t = typename res_labelset_t::value_t;
108 
110 
111  public:
112 
115  {}
116 
118  : super_t(aut)
119  {}
120 
121  static symbol sname()
122  {
123  static symbol res(("focus_automaton<" + std::to_string(Tape) + ", "
125  return res;
126  }
127 
128  std::ostream& print_set(std::ostream& o, format fmt = {}) const
129  {
130  o << "focus_automaton<" << std::to_string(Tape) << ", ";
131  aut_->print_set(o, fmt);
132  return o << '>';
133  }
134 
135  full_context_t full_context() const
136  {
137  return aut_->context();
138  }
139 
140  context_t context() const
141  {
142  return context_;
143  }
144 
145  res_label_t
146  hidden_label_of(transition_t t) const
147  {
148  return hidden_label_of_(t, hidden_indices);
149  }
150 
151  res_label_t
152  hidden_one() const
153  {
154  return hidden_one_<full_labelset_t>(hidden_indices);
155  }
156 
157  res_labelset_t
158  res_labelset() const
159  {
160  return res_labelset_(hidden_indices);
161  }
162 
164  std::shared_ptr<labelset_t>
165  labelset() const
166  {
167  return std::make_shared<labelset_t>(aut_->labelset()->template set<Tape>());
168  }
169 
170  private:
171  using super_t::aut_;
172 
173  hidden_indices_t hidden_indices{};
174 
175  static label_t hide_(full_label_t l)
176  {
177  return std::get<Tape>(l);
178  }
179 
180  template <std::size_t... I>
181  res_label_t hidden_label_of_(transition_t t, index_sequence<I...>) const
182  {
183  full_label_t l = aut_->label_of(t);
184  return std::make_tuple(std::get<I>(l)...);
185  }
186 
187  template <typename L, std::size_t... I>
188  vcsn::enable_if_t<L::has_one(), res_label_t>
189  hidden_one_(index_sequence<I...>) const
190  {
191  full_label_t l = aut_->labelset()->one();
192  return std::make_tuple(std::get<I>(l)...);
193  }
194 
195  template <typename L, std::size_t... I>
196  vcsn::enable_if_t<!L::has_one(), res_label_t>
197  hidden_one_(index_sequence<I...>) const
198  {
199  raise("Should not get here");
200  }
201 
202  template <std::size_t... I>
203  res_labelset_t res_labelset_(index_sequence<I...>) const
204  {
205  return res_labelset_t{std::get<I>(aut_->labelset()->sets())...};
206  }
207 
208  public:
209 
210  /*----------------------------.
211  | const methods that change. |
212  `----------------------------*/
213 
215  auto label_of(transition_t t) const
216  -> label_t
217  {
218  return hide_(aut_->label_of(t));
219  }
220 
221  // FIXME: http://llvm.org/bugs/show_bug.cgi?id=20175.
222  // using super_t::out;
223  auto
224  out(state_t s) const
225  -> decltype(aut_->out(s))
226  {
227  return aut_->out(s);
228  }
229 
234  std::vector<transition_t>
235  out(state_t s, label_t l) const
236  {
237  std::vector<transition_t> res;
238  for (auto t: aut_->all_out(s))
239  if (labelset()->equal(label_of(t), l))
240  res.emplace_back(t);
241  return res;
242  }
243 
248  using super_t::in;
249  std::vector<transition_t>
250  in(state_t s, label_t l) const
251  {
252  std::vector<transition_t> res;
253  for (auto t: aut_->all_in(s))
254  if (this->labelset()->equal(label_of(t), l))
255  res.emplace_back(t);
256  return res;
257  }
258 
259  // FIXME: Having support for predicates in
260  // mutable_automaton::get_transition would help.
261  transition_t
262  get_transition(state_t src, state_t dst, label_t l) const
263  {
264  for (auto t: out(src, l))
265  if (aut_->dst_of(t) == dst)
266  return t;
267  return aut_->null_transition();
268  }
269 
271  bool
272  has_transition(state_t src, state_t dst, label_t l) const
273  {
274  return get_transition(src, dst, l) != aut_->null_transition();
275  }
276 
277  using super_t::del_transition;
279  void
280  del_transition(state_t src, state_t dst, label_t l)
281  {
282  auto t = get_transition(src, dst, l);
283  if (t != aut_->null_transition())
284  aut_->del_transition(t);
285  }
286 
288  template <typename A>
289  transition_t
290  new_transition_copy(state_t src, state_t dst,
291  const A& aut,
292  typename A::element_type::transition_t t,
293  bool transpose = false)
294  {
295  return aut_->new_transition_copy(src, dst,
296  aut->strip(), t, transpose);
297  }
298 
300  template <typename A>
301  transition_t
302  add_transition_copy(state_t src, state_t dst,
303  const A& aut,
304  typename A::element_type::transition_t t,
305  bool transpose = false)
306  {
307  return aut_->add_transition_copy(src, dst,
308  aut->strip(), t, transpose);
309  }
310 
311 #define DEFINE(Name, Sig) \
312  auto Name Sig \
313  { \
314  raise("focus: cannot provide " #Name); \
315  }
316 
317  DEFINE(add_transition,
318  (state_t, state_t, label_t, weight_t) -> transition_t);
319  DEFINE(add_transition,
320  (state_t, state_t, label_t) -> transition_t);
321  DEFINE(new_transition,
322  (state_t, state_t, label_t, weight_t) -> transition_t);
323  DEFINE(new_transition,
324  (state_t, state_t, label_t) -> transition_t);
325  DEFINE(set_transition,
326  (state_t, state_t, label_t, weight_t) -> transition_t);
327 #undef DEFINE
328 
329  private:
334  context_t context_ = make_project_context<Tape>(full_context());
335  };
336  }
337 
338  template <unsigned Tape, typename Aut>
339  inline
340  focus_automaton<Tape, Aut>
341  focus(Aut aut)
342  {
343  return std::make_shared<detail::focus_automaton_impl<Tape, Aut>>(aut);
344  }
345 
346 
347  namespace dyn
348  {
349  namespace detail
350  {
352  template <typename Aut, typename Tape>
353  automaton
354  focus(const automaton& aut, integral_constant)
355  {
356  auto& a = aut->as<Aut>();
357  return make_automaton(vcsn::focus<Tape::value>(a));
358  }
359  }
360  }
361 }
Aut automaton_t
The type of the wrapped automaton.
Definition: focus.hh:43
std::shared_ptr< const weightset_t > weightset_ptr
Definition: context.hh:24
context_t_of< automaton_t > full_context_t
Underlying automaton context.
Definition: focus.hh:56
std::string to_string(identities i)
Wrapper around operator<<.
Definition: identities.cc:17
std::ostream & print_set(std::ostream &o, format fmt={}) const
Definition: focus.hh:128
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:48
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:45
state_t_of< automaton_t > state_t
This automaton's state and transition types are those of the wrapped automaton.
Definition: focus.hh:52
Aggregate an automaton, and forward calls to it.
typename context_t::labelset_t labelset_t
Exposed labelset.
Definition: focus.hh:66
concat_sequence< make_index_range_t< 0, Tape >, make_index_range_t< Tape+1, std::tuple_size< full_label_t >::value-Tape-1 >> hidden_indices_t
Indices of the remaining tapes.
Definition: focus.hh:102
SharedPtr make_shared_ptr(Args &&...args)
Same as std::make_shared, but parameterized by the shared_ptr type, not the (pointed to) element_type...
Definition: memory.hh:14
typename concat_index_sequence< S1, S2 >::type concat_sequence
Definition: tuple.hh:84
typename res_labelset_t::value_t res_label_t
Definition: focus.hh:107
typename Aut::element_type::template fresh_automaton_t< Context > fresh_automaton_t_of
Definition: traits.hh:57
typename context_t::weightset_ptr weightset_ptr
Definition: focus.hh:72
static dyn::context ctx(const driver &d)
Get the context of the driver.
Definition: parse.cc:80
typename context_t::weightset_t weightset_t
Exposed weightset.
Definition: focus.hh:71
focus_automaton_impl(const automaton_t &aut)
Definition: focus.hh:117
An input/output format.
Definition: format.hh:11
focus_automaton_impl(const full_context_t &ctx)
Definition: focus.hh:113
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
typename context_t::labelset_ptr labelset_ptr
Definition: focus.hh:67
typename labelset_t::value_t label_t
Definition: focus.hh:68
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:47
std::shared_ptr< const labelset_t > labelset_ptr
Definition: context.hh:23
typename detail::transition_t_of_impl< base_t< ValueSet >>::type transition_t_of
Definition: traits.hh:49
symbol sname()
Definition: name.hh:67
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
Definition: symbol.hh:23
Read-write on an automaton, that hides all tapes but one.
Definition: focus.hh:37
LabelSet labelset_t
Definition: context.hh:21
typename hidden_label_type< Aut, hidden_indices_t >::type res_labelset_t
Definition: focus.hh:106
typename full_labelset_t::value_t full_label_t
Underlying automaton label.
Definition: focus.hh:60
std::shared_ptr< detail::focus_automaton_impl< Tape, Aut >> focus_automaton
A focus automaton as a shared pointer.
Definition: fwd.hh:41
typename weightset_t::value_t weight_t
Definition: focus.hh:73
typename full_context_t::labelset_t full_labelset_t
Underlying automaton labelset.
Definition: focus.hh:58
focus_automaton< Tape, fresh_automaton_t_of< automaton_t, full_context_t >> fresh_automaton_t
The type of automata to produce this kind of automata.
Definition: focus.hh:95
WeightSet weightset_t
Definition: context.hh:22
typename make_index_range< S, L >::type make_index_range_t
Definition: tuple.hh:74
transition_t_of< automaton_t > transition_t
Definition: focus.hh:53