Awali
Another Weighted Automata library
tuple_automaton.hh
Go to the documentation of this file.
1 // This file is part of Awali.
2 // Copyright 2016-2022 Sylvain Lombardy, Victor Marsault, Jacques Sakarovitch
3 //
4 // Awali is a free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 
17 #ifndef AWALI_CORE_TUPLE_AUTOMATON_HH
18 # define AWALI_CORE_TUPLE_AUTOMATON_HH
19 
20 # include <deque>
21 # include <iostream>
22 # include <map>
23 # include <utility>
24 
27 #include <awali/sttc/ctx/traits.hh>
28 #include <awali/sttc/misc/map.hh> // has
29 #include <awali/common/tuple.hh>
30 
31 namespace awali { namespace sttc {
32 
33  namespace internal
34  {
35  /*-------------------------------------.
36  | tuple_automaton_impl<Aut, Auts...>. |
37  `-------------------------------------*/
38 
45  template <typename Aut, typename... Auts>
47  : public automaton_decorator<Aut>
48  {
50  using automaton_t = Aut;
52 
53  public:
54  static std::string sname()
55  {
56  return "tuple_automaton" + sname_();
57  }
58 
59  std::string vname(bool full = true) const
60  {
61  return "tuple_automaton" + vname_(full);
62  }
63 
73 
74  using label_t = typename labelset_t::value_t;
75  using weight_t = typename weightset_t::value_t;
76 
77  public:
79  using automata_t = std::tuple<Auts...>;
80 
82  template <size_t I>
85 
86  using super_t::aut_;
87 
88  tuple_automaton_impl(const automaton_t& aut, const Auts&... auts)
89  : super_t(aut)
90  , auts_(auts...)
91  {
92  pmap_[pre_()] = aut_->pre();
93  pmap_[post_()] = aut_->post();
94  }
95 
96  std::ostream&
97  print_state_name(typename super_t::state_t s, std::ostream& o,
98  const std::string& fmt = "text") const
99  {
100  return print_state_name_(s, o, fmt, indices);
101  }
102 
104  using pair_t = std::tuple<state_t_of<Auts>...>;
105 
107  using origins_t = std::map<state_t, pair_t>;
108 
110  const origins_t& origins() const
111  {
112  if (origins_.empty())
113  for (const auto& p: pmap_)
114  origins_.emplace(p.second, p.first);
115  return origins_;
116  }
117 
118  // FIXME: protected:
120  template <std::size_t... I>
122 
125  static constexpr indices_t indices{};
126 
128  static std::string sname_()
129  {
130  std::string res = "<" + Aut::element_type::sname() + ", ";
131  const char* sep = "";
132  using swallow = int[];
133  (void) swallow
134  {
135  (res += sep + Auts::element_type::sname(), sep = ", ", 0)...
136  };
137  res += ">";
138  return res;
139  }
140 
142  std::string vname_(bool full = true) const
143  {
144  return vname_(full, indices);
145  }
146 
147  template <size_t... I>
148  std::string vname_(bool full, seq<I...>) const
149  {
150  std::string res = "<" + aut_->vname(full) + ", ";
151  const char* sep = "";
152  using swallow = int[];
153  (void) swallow
154  {
155  (res += sep + std::get<I>(auts_)->vname(full), sep = ", ", 0)...
156  };
157  res += ">";
158  return res;
159  }
160 
162  pair_t pre_() const
163  {
164  return pre_(indices);
165  }
166 
167  template <size_t... I>
169  {
170  // clang 3.4 on top of libstdc++ wants this ctor to be
171  // explicitly called.
172  return pair_t{(std::get<I>(auts_)->pre())...};
173  }
174 
176  pair_t post_() const
177  {
178  return post_(indices);
179  }
180 
181  template <size_t... I>
183  {
184  // clang 3.4 on top of libstdc++ wants this ctor to be
185  // explicitly called.
186  return pair_t{(std::get<I>(auts_)->post())...};
187  }
188 
196  {
197  auto lb = pmap_.lower_bound(state);
198  if (lb == pmap_.end() || pmap_.key_comp()(state, lb->first))
199  {
200  lb = pmap_.emplace_hint(lb, state, aut_->add_state());
201  todo_.emplace_back(state);
202  }
203  return lb->second;
204  }
205 
206  state_t state(state_t_of<Auts>... ss)
207  {
208  return state(std::make_tuple(ss...));
209  }
210 
211  template <size_t... I>
212  std::ostream&
213  print_state_name_(typename super_t::state_t s, std::ostream& o,
214  const std::string& fmt,
215  seq<I...>) const
216  {
217  auto i = origins().find(s);
218  if (i == std::end(origins()))
219  this->print_state(s, o);
220  else
221  {
222  const char* sep = "";
223  using swallow = int[];
224  (void) swallow
225  {
226  (o << sep,
227  std::get<I>(auts_)->print_state_name(std::get<I>(i->second),
228  o, fmt),
229  sep = ", ",
230  0)...
231  };
232  }
233  return o;
234  }
235 
238 
240  using map = std::map<pair_t, state_t>;
242 
244  std::deque<pair_t> todo_;
245 
247  };
248  }
249 
251  template <typename... Auts>
253  = std::shared_ptr<internal::tuple_automaton_impl<Auts...>>;
254 
255  template <typename... Auts>
256  inline
257  auto
258  make_tuple_automaton(const Auts&... auts)
259  -> tuple_automaton<Auts...>
260  {
261  using res_t = tuple_automaton<Auts...>;
262  return make_shared_ptr<res_t>(auts...);
263  }
264 }}//end of ns awali::stc
265 
266 #endif // !AWALI_CORE_TUPLE_AUTOMATON_HH
Aggregate an automaton, and forward calls to it.
Definition: automaton_decorator.hh:36
Aut automaton_t
The type of automaton to wrap.
Definition: automaton_decorator.hh:39
auto print_state(Args &&... args) const -> decltype(aut_-> print_state(std::forward< Args >(args)...))
Definition: automaton_decorator.hh:154
typename labelset_t::value_t label_t
Definition: automaton_decorator.hh:50
Context context_t
Definition: automaton_decorator.hh:45
typename weightset_t::value_t weight_t
Definition: automaton_decorator.hh:54
typename context_t::labelset_t labelset_t
Definition: automaton_decorator.hh:48
automaton_t aut_
The wrapped automaton, possibly const.
Definition: automaton_decorator.hh:90
typename context_t::weightset_t weightset_t
Definition: automaton_decorator.hh:52
An automaton whose states are tuples of states of automata.
Definition: tuple_automaton.hh:48
map pmap_
Definition: tuple_automaton.hh:241
static std::string sname_()
The sname of the sub automata.
Definition: tuple_automaton.hh:128
std::map< pair_t, state_t > map
Map state-tuple -> result-state.
Definition: tuple_automaton.hh:240
state_t state(pair_t state)
The state in the product corresponding to a pair of states of operands.
Definition: tuple_automaton.hh:195
pair_t post_() const
The name of the post of the output automaton.
Definition: tuple_automaton.hh:176
static constexpr indices_t indices
Definition: tuple_automaton.hh:125
std::string vname_(bool full=true) const
The vname of the sub automata.
Definition: tuple_automaton.hh:142
const origins_t & origins() const
A map from result state to tuple of original states.
Definition: tuple_automaton.hh:110
static std::string sname()
Definition: tuple_automaton.hh:54
std::tuple< Auts... > automata_t
The type of input automata.
Definition: tuple_automaton.hh:79
pair_t pre_(seq< I... >) const
Definition: tuple_automaton.hh:168
pair_t pre_() const
The name of the pre of the output automaton.
Definition: tuple_automaton.hh:162
internal::base_t< typename std::tuple_element< I, automata_t >::type > input_automaton_t
The type of the Ith input automaton, unqualified.
Definition: tuple_automaton.hh:84
origins_t origins_
Definition: tuple_automaton.hh:246
automata_t auts_
Input automata, supplied at construction time.
Definition: tuple_automaton.hh:237
std::ostream & print_state_name_(typename super_t::state_t s, std::ostream &o, const std::string &fmt, seq< I... >) const
Definition: tuple_automaton.hh:213
std::map< state_t, pair_t > origins_t
A map from result state to tuple of original states.
Definition: tuple_automaton.hh:107
std::string vname(bool full=true) const
Definition: tuple_automaton.hh:59
std::deque< pair_t > todo_
Worklist of state tuples.
Definition: tuple_automaton.hh:244
state_t state(state_t_of< Auts >... ss)
Definition: tuple_automaton.hh:206
std::tuple< state_t_of< Auts >... > pair_t
Tuple of states of input automata.
Definition: tuple_automaton.hh:104
automaton_t aut_
The wrapped automaton, possibly const.
Definition: automaton_decorator.hh:90
std::string vname_(bool full, seq< I... >) const
Definition: tuple_automaton.hh:148
pair_t post_(seq< I... >) const
Definition: tuple_automaton.hh:182
tuple_automaton_impl(const automaton_t &aut, const Auts &... auts)
Definition: tuple_automaton.hh:88
std::ostream & print_state_name(typename super_t::state_t s, std::ostream &o, const std::string &fmt="text") const
Definition: tuple_automaton.hh:97
Definition: tuple.hh:43
typename std::remove_cv< typename std::remove_reference< T >::type >::type base_t
T without reference or const/volatile qualifiers.
Definition: traits.hh:30
std::shared_ptr< internal::tuple_automaton_impl< Auts... > > tuple_automaton
A product automaton as a shared pointer.
Definition: tuple_automaton.hh:253
typename internal::context_t_of_impl< internal::base_t< ValueSet > >::type context_t_of
Helper to retrieve the type of the context of a value set.
Definition: traits.hh:66
typename internal::labelset_t_of_impl< internal::base_t< ValueSet > >::type labelset_t_of
Helper to retrieve the type of the labelset of a value set.
Definition: traits.hh:76
typename internal::weightset_t_of_impl< internal::base_t< ValueSet > >::type weightset_t_of
Helper to retrieve the type of the weightset of a value set.
Definition: traits.hh:86
auto make_tuple_automaton(const Auts &... auts) -> tuple_automaton< Auts... >
Definition: tuple_automaton.hh:258
static const std::string full
Completely version of Awali as a std::string.
Definition: version.hh:42
Main namespace of Awali.
Definition: ato.hh:22
unsigned state_t
Definition: types.hh:21