Vcsn  2.3
Be Rational
tuple-automaton.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <deque>
4 #include <iostream>
5 #include <map>
6 #include <utility>
7 
8 #include <boost/bimap.hpp>
9 #include <boost/bimap/unordered_set_of.hpp>
10 
12 #include <vcsn/ctx/context.hh>
13 #include <vcsn/ctx/traits.hh>
14 #include <vcsn/misc/bimap.hh> // has
15 #include <vcsn/misc/map.hh> // has
16 #include <vcsn/misc/static-if.hh>
17 #include <vcsn/misc/tuple.hh>
18 
19 namespace vcsn
20 {
21  namespace detail
22  {
23  /*-------------------------------------.
24  | tuple_automaton_impl<Aut, Auts...>. |
25  `-------------------------------------*/
26 
33  template <Automaton Aut, Automaton... Auts>
35  : public automaton_decorator<Aut>
36  {
37  public:
39  using automaton_t = Aut;
41 
43  using state_t = typename super_t::state_t;
45  using state_name_t = std::tuple<state_t_of<Auts>...>;
46 
56 
57  using label_t = typename labelset_t::value_t;
58  using weight_t = typename weightset_t::value_t;
59 
60  static symbol sname()
61  {
62  static auto res = symbol{"tuple_automaton" + sname_()};
63  return res;
64  }
65 
66  std::ostream& print_set(std::ostream& o, format fmt = {}) const
67  {
68  o << "tuple_automaton";
69  print_set_(o, fmt);
70  return o;
71  }
72 
74  using automata_t = std::tuple<Auts...>;
75 
77  template <size_t I>
79 
81  using super_t::aut_;
82 
83  tuple_automaton_impl(const automaton_t& aut, const Auts&... auts)
84  : super_t(aut)
85  , auts_(auts...)
86  {
87  pmap_().insert({pre_(), aut_->pre()});
88  pmap_().insert({post_(), aut_->post()});
89  }
90 
91  bool state_has_name(state_t s) const
92  {
93  return has(origins(), s);
94  }
95 
97  std::ostream&
98  print_state_name(state_t s, std::ostream& o,
99  format fmt = {}, bool delimit = false) const
100  {
101  return print_state_name_(s, o, fmt, delimit, indices);
102  }
103 
105  std::ostream&
106  print_state_name(const state_name_t& sn, std::ostream& o,
107  format fmt = {}, bool delimit = false) const
108  {
109  return print_state_name_(sn, o, fmt, delimit, indices);
110  }
111 
112  using bimap_t
113  = boost::bimap<boost::bimaps::unordered_set_of<state_name_t>,
114  boost::bimaps::unordered_set_of<state_t>>;
115  using map_t = typename bimap_t::left_map;
116  using origins_t = typename bimap_t::right_map;
117 
118 
120  const origins_t&
121  origins() const
122  {
123  return bimap_.right;
124  }
125 
126  // FIXME: protected:
128  template <std::size_t... I>
130 
133  static constexpr indices_t indices{};
134 
136  template <typename... T>
137  static std::string sname_(const T&... t)
138  {
139  std::string res = "<" ;
140  using swallow = int[];
141  const char* sep = "";
142  (void) swallow
143  {
144  (res += sep + t, sep = ", ", 0)...
145  };
146  res += sep + Aut::element_type::sname();
147  (void) swallow
148  {
149  (res += ", " + Auts::element_type::sname(), 0)...
150  };
151  res += ">";
152  return res;
153  }
154 
156  std::ostream& print_set_(std::ostream& o, format fmt) const
157  {
158  return print_set_(o, fmt, indices);
159  }
160 
161  template <size_t... I>
162  std::ostream& print_set_(std::ostream& o, format fmt,
163  seq<I...>) const
164  {
165  o << '<';
166  aut_->print_set(o, fmt);
167  o << ", ";
168  const char* sep = "";
169  using swallow = int[];
170  (void) swallow
171  {
172  (o << sep,
173  std::get<I>(auts_)->print_set(o, fmt),
174  sep = ", ",
175  0)...
176  };
177  return o << '>';
178  }
179 
181  state_name_t pre_() const
182  {
183  return pre_(indices);
184  }
185 
186  template <size_t... I>
187  state_name_t pre_(seq<I...>) const
188  {
189  // clang 3.4 on top of libstdc++ wants this ctor to be
190  // explicitly called.
191  return state_name_t{(std::get<I>(auts_)->pre())...};
192  }
193 
195  state_name_t post_() const
196  {
197  return post_(indices);
198  }
199 
200  template <size_t... I>
201  state_name_t post_(seq<I...>) const
202  {
203  // clang 3.4 on top of libstdc++ wants this ctor to be
204  // explicitly called.
205  return state_name_t{(std::get<I>(auts_)->post())...};
206  }
207 
214  template <bool Lazy = false>
215  state_t state(const state_name_t& state)
216  {
217  auto lb = pmap_().find(state);
218  if (lb == pmap_().end())
219  {
220  state_t s = aut_->new_state();
221  if (Lazy)
222  aut_->set_lazy(s, true);
223  lb = pmap_().insert(lb, {state, s});
224  todo_.emplace_back(state, s);
225  }
226  return lb->second;
227  }
228 
229  template <bool Lazy = false>
230  state_t state(state_t_of<Auts>... ss)
231  {
232  return state<Lazy>(std::make_tuple(ss...));
233  }
234 
235  template <size_t... I>
236  std::ostream&
237  print_state_name_(state_t s, std::ostream& o, format fmt,
238  bool delimit, seq<I...> indices) const
239  {
240  const auto& origs = origins();
241  auto i = origs.find(s);
242  if (i == std::end(origs))
243  this->print_state(s, o);
244  else
245  print_state_name_(i->second, o, fmt, delimit, indices);
246  return o;
247  }
248 
249  template <size_t... I>
250  std::ostream&
251  print_state_name_(const state_name_t& sn, std::ostream& o,
252  format fmt, bool delimit, seq<I...>) const
253  {
254  if (delimit)
255  o << '(';
256  const char* sep = "";
257  using swallow = int[];
258  (void) swallow
259  {
260  (o << sep,
261  std::get<I>(auts_)->print_state_name(std::get<I>(sn),
262  o, fmt, true),
263  sep = ", ",
264  0)...
265  };
266  if (delimit)
267  o << ')';
268  return o;
269  }
270 
273  map_t&
274  pmap_()
275  {
276  return bimap_.left;
277  }
278 
280  automata_t auts_;
281 
283  mutable bimap_t bimap_;
284 
286  std::deque<std::pair<state_name_t, state_t>> todo_;
287  };
288  }
289 
291  template <Automaton... Auts>
292  using tuple_automaton
293  = std::shared_ptr<detail::tuple_automaton_impl<Auts...>>;
294 
295  template <Automaton... Auts>
296  auto
297  make_tuple_automaton(const Auts&... auts)
298  -> tuple_automaton<Auts...>
299  {
300  using res_t = tuple_automaton<Auts...>;
301  return make_shared_ptr<res_t>(auts...);
302  }
303 }
const origins_t & origins() const
A map from result state to tuple of original states.
map_t & pmap_()
A map from original state and status (spontaneous or proper state) to result state.
#define Automaton
Definition: automaton.hh:23
automata_t auts_
Input automata, supplied at construction time.
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
Definition: symbol.hh:23
typename bimap_t::right_map origins_t
base_t< tuple_element_t< I, automata_t >> input_automaton_t
The type of the Ith input automaton, unqualified.
weightset_t_of< context_t > weightset_t
state_t_of< automaton_t > state_t
symbol sname()
Definition: name.hh:65
std::ostream & print_set_(std::ostream &o, format fmt, seq< I... >) const
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:63
Aggregate an automaton, and forward calls to it.
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:61
state_name_t post_() const
The name of the post of the output automaton.
boost::bimap< boost::bimaps::unordered_set_of< state_name_t >, boost::bimaps::unordered_set_of< state_t >> bimap_t
std::ostream & print_set(std::ostream &o, format fmt={}) const
typename super_t::state_t state_t
Result state type.
std::ostream & print_state_name(const state_name_t &sn, std::ostream &o, format fmt={}, bool delimit=false) const
Print a state name from its state name.
labelset_t_of< context_t > labelset_t
return res
Definition: multiply.hh:398
An automaton whose states are tuples of states of automata.
state_name_t pre_() const
The name of the pre of the output automaton.
context_t_of< Aut > context_t
The type of context of the result.
std::tuple< state_t_of< Auts >... > state_name_t
State names: Tuple of states of input automata.
typename weightset_t::value_t weight_t
ATTRIBUTE_PURE bool has(const boost::container::flat_set< Key, Compare, Allocator > &s, const Key &e)
Whether e is member of s.
Definition: setalpha.hh:25
Definition: a-star.hh:8
bool state_has_name(state_t s) const
static std::string sname_(const T &...t)
The sname of the sub automata.
std::ostream & print_state_name_(state_t s, std::ostream &o, format fmt, bool delimit, seq< I... > indices) const
An input/output format for valuesets.
Definition: format.hh:13
tuple_automaton_impl(const automaton_t &aut, const Auts &...auts)
std::tuple< Auts... > automata_t
The type of input automata.
typename bimap_t::left_map map_t
std::ostream & print_set_(std::ostream &o, format fmt) const
The setname of the sub automata.
std::remove_cv_t< std::remove_reference_t< T >> base_t
T without reference or const/volatile qualifiers.
Definition: traits.hh:13
automaton tuple(const std::vector< automaton > &as)
Bridge.
Aut automaton_t
The type of the resulting automaton.
typename labelset_t::value_t label_t
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
Definition: traits.hh:67
automaton_t aut_
The wrapped automaton, possibly const.
bimap_t bimap_
Bijective map state_name_t -> state_t.
static constexpr indices_t indices
std::ostream & print_state_name(state_t s, std::ostream &o, format fmt={}, bool delimit=false) const
Print a state name from its state index.