Vcsn  2.5.dev
Be Rational
tuple-automaton.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <vcsn/algos/tuple.hh>
5 #include <vcsn/dyn/automaton.hh>
6 
7 namespace vcsn
8 {
9  namespace detail
10  {
11  /*-------------------------------.
12  | tuple_automata_impl<Aut...>. |
13  `-------------------------------*/
14 
23  template <Automaton Aut, Automaton... Auts>
25  : public lazy_tuple_automaton<tuple_automata_impl<Aut, Auts...>,
26  false, false, Aut, Auts...>
27  {
29  using automaton_t = Aut;
31  using super_t = lazy_tuple_automaton<self_t, false, false, Aut, Auts...>;
32 
33  public:
35  using state_t = typename super_t::state_t;
36 
37  template <size_t... I>
38  using seq = typename super_t::template seq<I...>;
39 
40  using super_t::ws_;
42 
47 
48  using label_t = typename labelset_t::value_t;
49  using weight_t = typename weightset_t::value_t;
50 
52  using automata_t = std::tuple<Auts...>;
53 
55  template <size_t I>
57 
58  using super_t::aut_;
59 
63  tuple_automata_impl(Aut aut, const Auts&... auts)
64  : super_t{aut, auts...}
65  {
66  aut_->todo_.emplace_back(aut_->pre_(), aut_->pre());
67  }
68 
70  void tuple()
71  {
72  try
73  {
74  while (!aut_->todo_.empty())
75  {
76  const auto& p = aut_->todo_.front();
77  add_tuple_transitions(std::get<1>(p), std::get<0>(p));
78  aut_->todo_.pop_front();
79  }
80  }
81  catch (const std::runtime_error& e)
82  {
83  raise(e, " while tupling automata");
84  }
85  }
86 
87  private:
88  using super_t::out_;
89  using super_t::state;
94  void add_tuple_transitions(const state_t src, const state_name_t& psrc)
95  {
96  add_tuple_transitions_(src, psrc, aut_->indices);
97  }
98 
99  template <std::size_t... I>
100  void add_tuple_transitions_(const state_t src, const state_name_t& psrc,
101  seq<I...>)
102  {
103  // If this is post, we are done.
104  if (!all((std::get<I>(psrc) == std::get<I>(aut_->auts_)->post())...))
105  {
106  const auto& ls = *aut_->labelset();
107  const auto& ws = *aut_->weightset();
108  // A blank label: the labels of each tape will be inserted
109  // one after the other. Using `one` instead of `special` is
110  // tempting, but `one` is not always available.
111  // FIXME: it will be available in Vcsn 3.
112  auto label = ls.special();
113  auto weight = ws.one();
114  auto dst = psrc;
115  add_tape_transitions_<0>(src, psrc, dst, label, weight);
116  }
117  }
118 
127  template <std::size_t I>
128  void add_tape_transitions_(const state_t src, const state_name_t& srcn,
129  state_name_t dstn,
130  label_t label, const weight_t& weight)
131  {
132  const auto& ls = *aut_->labelset();
133  const auto& ws = *aut_->weightset();
134  const auto& aut = std::get<I>(aut_->auts_);
135  // Add an outgoing transition from `src` to `dst` with
136  // `<weight>label`.
137  auto add =
138  static_if<I + 1 == sizeof...(Auts)>
139  ([this](auto src, const auto&, const auto& dstn,
140  const auto& label, const auto& weight)
141  {
142  if (state(dstn) == aut_->post())
143  // The label is actually a tuple of \e (instead of a
144  // tuple of special), don't use it.
145  aut_->set_final(src, weight);
146  else
147  aut_->new_transition(src, state(dstn), label, weight);
148  },
149  [this](auto src, const auto& srcn, const auto& dstn,
150  const auto& label, const auto& weight)
151  {
152  add_tape_transitions_<I + 1>(src, srcn, dstn, label, weight);
153  });
154 
155  if (std::get<I>(srcn) == aut->post())
156  {
157  std::get<I>(label) = label_one(ls.template set<I>());
158  add(src, srcn, dstn, label, weight);
159  }
160  else
161  for (auto t: aut->all_out(std::get<I>(srcn)))
162  {
163  std::get<I>(label)
164  = aut->dst_of(t) == aut->post()
165  ? label_one(ls.template set<I>())
166  : aut->label_of(t);
167  std::get<I>(dstn) = aut->dst_of(t);
168  add(src, srcn, dstn, label, ws.mul(weight, aut->weight_of(t)));
169  }
170  }
171  };
172 
173 
174  /*-----------------------.
175  | tuple(automaton...). |
176  `-----------------------*/
177 
179  template <Automaton... Auts>
180  auto
181  tuple(const Auts&... as)
182  {
183  auto ctx = tuple_context(as->context()...);
184  auto aut = make_mutable_automaton(ctx);
185  auto res = tuple_automata_impl<decltype(aut), Auts...>(aut, as...);
186  res.tuple();
187  return res.strip();
188  }
189  }
190 
191  using detail::tuple;
192 
193  namespace dyn
194  {
195  namespace detail
196  {
198  template <typename Auts, size_t... I>
199  automaton
200  tuple_(const std::vector<automaton>& as,
202  {
203  return tuple(as[I]->as<tuple_element_t<I, Auts>>()...);
204  }
205 
207  template <typename Auts>
208  automaton
209  tuple(const std::vector<automaton>& as)
210  {
211  auto indices
213  return tuple_<Auts>(as, indices);
214  }
215  }
216  }
217 }
typename detail::context_t_of_impl< base_t< ValueSet > >::type context_t_of
Definition: traits.hh:61
typename weightset_t::value_t weight_t
Aut automaton_t
The type of the resulting automaton.
state_t state(Args &&... args)
Conversion from state name to state number.
labelset_t_of< context_t > labelset_t
auto label_one(const LabelSet &ls) -> typename LabelSet::value_t
Enjoy type inference.
Definition: labelset.hh:54
bool all(Bool &&... values)
Whether all the values evaluate as true.
Definition: tuple.hh:492
const weightset_t & ws_
The resulting weightset.
typename super_t::template seq< I... > seq
typename detail::labelset_t_of_impl< base_t< ValueSet > >::type labelset_t_of
Definition: traits.hh:63
A static list of size_t.
Definition: tuple.hh:32
return res
Definition: multiply.hh:399
tuple_automata_impl(Aut aut, const Auts &... auts)
Build a tuple automaton.
typename std::tuple_element< I, T >::type tuple_element_t
C++14.
Definition: tuple.hh:14
typename super_t::state_t state_t
base_t< tuple_element_t< I, automata_t > > input_automaton_t
The type of the Ith input automaton, unqualified.
typename tuple_automaton_impl::state_name_t state_name_t
context_t_of< Aut > context_t
The context of the result.
Build the (accessible part of the) Cartesian product of automata.
void tuple()
Compute the (accessible part of the) tuple.
Decorator implementing the laziness for an algorithm.
std::tuple< typename transition_map_t< Auts >::map_t &... > out_(const state_name_t &ss)
The outgoing tuple of transitions from state tuple ss.
typename detail::weightset_t_of_impl< base_t< ValueSet > >::type weightset_t_of
Definition: traits.hh:67
void add_tuple_transitions_(const state_t src, const state_name_t &psrc, seq< I... >)
void add_tuple_transitions(const state_t src, const state_name_t &psrc)
Add transitions to the result automaton, starting from the given result input state, which must correspond to the given pair of input state automata.
automaton tuple(const std::vector< automaton > &as)
Bridge.
typename labelset_t::value_t label_t
void add_tape_transitions_(const state_t src, const state_name_t &srcn, state_name_t dstn, label_t label, const weight_t &weight)
Add outgoing transitions from src computed by looking at tape I and beyond.
mutable_automaton< Context > make_mutable_automaton(const Context &ctx)
std::tuple< Auts... > automata_t
The type of input automata.
#define Automaton
Definition: automaton.hh:23
value_impl< detail::weight_tag > weight
Definition: fwd.hh:34
Definition: a-star.hh:8
value_impl< detail::label_tag > label
Definition: fwd.hh:32
auto tuple(const Auts &... as)
Build the (accessible part of the) tuple.
A dyn automaton.
Definition: automaton.hh:17
weightset_t_of< context_t > weightset_t
auto static_if(Then &&then, Else &&else_)
Execute the then- or the else-clause depending on cond.
Definition: static-if.hh:27
Build the static sequence of size_t [0, N[.
Definition: tuple.hh:56
std::tuple< transition_map_t< Auts >... > transition_maps_
Transition caches.
automaton_t aut_
The wrapped automaton, possibly const.
auto tuple_context(Ctx &&... ctx) -> context< tupleset< labelset_t_of< Ctx >... >, join_t< weightset_t_of< Ctx >... >>
Definition: tuple.hh:16
automaton tuple_(const std::vector< automaton > &as, vcsn::detail::index_sequence< I... >)
Bridge helper.
typename tuple_automaton_impl::state_t state_t
typename super_t::state_name_t state_name_t
std::remove_cv_t< std::remove_reference_t< T > > base_t
T without reference or const/volatile qualifiers.
Definition: traits.hh:13