Vcsn  2.2
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/tuple.hh>
17 
18 namespace vcsn
19 {
20  namespace detail
21  {
22  /*-------------------------------------.
23  | tuple_automaton_impl<Aut, Auts...>. |
24  `-------------------------------------*/
25 
32  template <Automaton Aut, Automaton... Auts>
34  : public automaton_decorator<Aut>
35  {
37  using automaton_t = Aut;
39 
40  public:
41  static symbol sname()
42  {
43  static auto res = symbol{"tuple_automaton" + sname_()};
44  return res;
45  }
46 
47  std::ostream& print_set(std::ostream& o, format fmt = {}) const
48  {
49  o << "tuple_automaton";
50  print_set_(o, fmt);
51  return o;
52  }
53 
63 
64  using label_t = typename labelset_t::value_t;
65  using weight_t = typename weightset_t::value_t;
66 
67  public:
69  using automata_t = std::tuple<Auts...>;
70 
72  template <size_t I>
74 
76  using super_t::aut_;
77 
78  tuple_automaton_impl(const automaton_t& aut, const Auts&... auts)
79  : super_t(aut)
80  , auts_(auts...)
81  {
82  pmap_().insert({pre_(), aut_->pre()});
83  pmap_().insert({post_(), aut_->post()});
84  }
85 
86  bool state_has_name(typename super_t::state_t s) const
87  {
88  return has(origins(), s);
89  }
90 
91  std::ostream&
92  print_state_name(typename super_t::state_t s, std::ostream& o,
93  format fmt = {}, bool delimit = false)
94  const
95  {
96  if (delimit)
97  o << '(';
98  print_state_name_(s, o, fmt, indices);
99  if (delimit)
100  o << ')';
101  return o;
102  }
103 
107  using state_name_t = std::tuple<state_t_of<Auts>...>;
108 
109  using bimap_t = boost::bimap<boost::bimaps::unordered_set_of<state_name_t>, boost::bimaps::unordered_set_of<state_t>>;
110  using map_t = typename bimap_t::left_map;
111  using origins_t = typename bimap_t::right_map;
112 
113 
115  const origins_t&
116  origins() const
117  {
118  return bimap_.right;
119  }
120 
121  // FIXME: protected:
123  template <std::size_t... I>
125 
128  static constexpr indices_t indices{};
129 
131  template <typename... T>
132  static std::string sname_(const T&... t)
133  {
134  std::string res = "<" ;
135  using swallow = int[];
136  const char* sep = "";
137  (void) swallow
138  {
139  (res += sep + t, sep = ", ", 0)...
140  };
141  res += sep + Aut::element_type::sname();
142  (void) swallow
143  {
144  (res += ", " + Auts::element_type::sname(), 0)...
145  };
146  res += ">";
147  return res;
148  }
149 
151  std::ostream& print_set_(std::ostream& o, format fmt) const
152  {
153  return print_set_(o, fmt, indices);
154  }
155 
156  template <size_t... I>
157  std::ostream& print_set_(std::ostream& o, format fmt,
158  seq<I...>) const
159  {
160  o << '<';
161  aut_->print_set(o, fmt);
162  o << ", ";
163  const char* sep = "";
164  using swallow = int[];
165  (void) swallow
166  {
167  (o << sep,
168  std::get<I>(auts_)->print_set(o, fmt),
169  sep = ", ",
170  0)...
171  };
172  return o << '>';
173  }
174 
176  state_name_t pre_() const
177  {
178  return pre_(indices);
179  }
180 
181  template <size_t... I>
182  state_name_t pre_(seq<I...>) const
183  {
184  // clang 3.4 on top of libstdc++ wants this ctor to be
185  // explicitly called.
186  return state_name_t{(std::get<I>(auts_)->pre())...};
187  }
188 
190  state_name_t post_() const
191  {
192  return post_(indices);
193  }
194 
195  template <size_t... I>
196  state_name_t post_(seq<I...>) const
197  {
198  // clang 3.4 on top of libstdc++ wants this ctor to be
199  // explicitly called.
200  return state_name_t{(std::get<I>(auts_)->post())...};
201  }
202 
209  template <bool Lazy = false>
210  state_t state(const state_name_t& state)
211  {
212  auto lb = pmap_().find(state);
213  if (lb == pmap_().end())
214  {
215  state_t s = aut_->new_state();
216  if (Lazy)
217  aut_->set_lazy(s, true);
218  lb = pmap_().insert(lb, {state, s});
219  todo_.emplace_back(state, s);
220  }
221  return lb->second;
222  }
223 
224  template <bool Lazy = false>
225  state_t state(state_t_of<Auts>... ss)
226  {
227  return state<Lazy>(std::make_tuple(ss...));
228  }
229 
230  template <size_t... I>
231  std::ostream&
232  print_state_name_(typename super_t::state_t s, std::ostream& o,
233  format fmt,
234  seq<I...>) const
235  {
236  const auto& origs = origins();
237  auto i = origs.find(s);
238  if (i == std::end(origs))
239  this->print_state(s, o);
240  else
241  {
242  const char* sep = "";
243  using swallow = int[];
244  (void) swallow
245  {
246  (o << sep,
247  std::get<I>(auts_)->print_state_name(std::get<I>(i->second),
248  o, fmt, true),
249  sep = ", ",
250  0)...
251  };
252  }
253  return o;
254  }
255 
258  map_t&
259  pmap_()
260  {
261  return bimap_.left;
262  }
263 
265  automata_t auts_;
266 
268  mutable bimap_t bimap_;
269 
271  std::deque<std::pair<state_name_t, state_t>> todo_;
272  };
273  }
274 
276  template <Automaton... Auts>
277  using tuple_automaton
278  = std::shared_ptr<detail::tuple_automaton_impl<Auts...>>;
279 
280  template <Automaton... Auts>
281  auto
282  make_tuple_automaton(const Auts&... auts)
283  -> tuple_automaton<Auts...>
284  {
285  using res_t = tuple_automaton<Auts...>;
286  return make_shared_ptr<res_t>(auts...);
287  }
288 }
ValueSet::value_t tuple(const ValueSet &vs, const typename ValueSets::value_t &...v)
Definition: tuple.hh:43
automata_t auts_
Input automata, supplied at construction time.
bimap_t bimap_
Bijective map state_name_t -> state_t.
state_t_of< automaton_t > state_t
Result state type.
map_t & pmap_()
A map from original state and status (spontaneous or proper state) to result state.
labelset_t_of< context_t > labelset_t
std::ostream & print_set(std::ostream &o, format fmt={}) const
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
Definition: traits.hh:59
state_t_of< automaton_t > state_t
const origins_t & origins() const
A map from result state to tuple of original states.
Definition: a-star.hh:8
std::remove_cv_t< std::remove_reference_t< T >> base_t
T without reference or const/volatile qualifiers.
Definition: traits.hh:12
automaton_t aut_
The wrapped automaton, possibly const.
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:55
An input/output format for valuesets.
Definition: format.hh:11
bool state_has_name(typename super_t::state_t s) const
static std::string sname_(const T &...t)
The sname of the sub automata.
std::tuple< state_t_of< Auts >... > state_name_t
State names: Tuple of states of input automata.
static constexpr indices_t indices
std::tuple< Auts... > automata_t
The type of input automata.
base_t< tuple_element_t< I, automata_t >> input_automaton_t
The type of the Ith input automaton, unqualified.
context_t_of< Aut > context_t
The type of context of the result.
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:56
Aut automaton_t
The type of the resulting automaton.
typename bimap_t::left_map map_t
std::ostream & print_state_name(typename super_t::state_t s, std::ostream &o, format fmt={}, bool delimit=false) const
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
Definition: symbol.hh:23
Aggregate an automaton, and forward calls to it.
tuple_automaton_impl(const automaton_t &aut, const Auts &...auts)
state_name_t pre_() const
The name of the pre of the output automaton.
std::ostream & print_set_(std::ostream &o, format fmt) const
The setname of the sub automata.
std::ostream & print_state_name_(typename super_t::state_t s, std::ostream &o, format fmt, seq< I... >) const
boost::bimap< boost::bimaps::unordered_set_of< state_name_t >, boost::bimaps::unordered_set_of< state_t >> bimap_t
symbol sname()
Definition: name.hh:67
An automaton whose states are tuples of states of automata.
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:53
std::ostream & print_set_(std::ostream &o, format fmt, seq< I... >) const
typename bimap_t::right_map origins_t
weightset_t_of< context_t > weightset_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
typename weightset_t::value_t weight_t
typename labelset_t::value_t label_t
#define Automaton
Definition: automaton.hh:24
state_name_t post_() const
The name of the post of the output automaton.