Vcsn  2.3
Be Rational
lift.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <map>
4 
5 #include <boost/optional.hpp>
6 
7 #include <vcsn/core/automaton.hh> // all_transitions
8 #include <vcsn/core/mutable-automaton.hh> // fresh_automaton_t_of
11 #include <vcsn/ctx/context.hh>
12 #include <vcsn/dyn/automaton.hh>
13 #include <vcsn/labelset/oneset.hh>
14 #include <vcsn/dyn/name.hh>
15 
16 namespace vcsn
17 {
18 
19  namespace detail
20  {
21  /*---------.
22  | lifter. |
23  `---------*/
24 
30  template <typename Context, typename Tapes, typename Enable = void>
31  struct lifter_impl;
32 
34  template <typename Context>
36  {
38  using in_context_t = Context;
40 
45 
48  {
49  return {oneset{}, weightset_t{ctx, ids}};
50  }
51 
53  static oneset::value_t
55  {
56  return oneset::one();
57  }
58 
60  static in_label_t
62  {
63  return l;
64  }
65  };
66 
68  template <typename... LabelSets, typename WeightSet,
69  size_t... Tapes>
70  struct lifter_impl<context<tupleset<LabelSets...>, WeightSet>,
71  vcsn::detail::index_sequence<Tapes...>,
72  std::enable_if_t<(0 < sizeof...(Tapes))>>
73  {
75  using in_labelset_t = tupleset<LabelSets...>;
76  using in_context_t = context<in_labelset_t, WeightSet>;
77  using in_label_t = typename in_labelset_t::value_t;
78 
80  template <std::size_t... I>
81  using seq = detail::index_sequence<I...>;
82 
84  template <typename S, typename L>
85  struct tape_set;
86 
87  // Set of no tape is oneset
88  template <typename LabelSet>
89  struct tape_set<seq<>, LabelSet>
90  {
91  using type = oneset;
92  };
93 
94  template <size_t... I, typename LabelSet>
95  struct tape_set<seq<I...>, LabelSet>
96  {
97  using type = tupleset<typename LabelSet::template valueset_t<I>...>;
98  };
99 
101  using index_t
103 
104  static constexpr size_t number_of_tapes = in_labelset_t::size();
105 
106  template <size_t I>
107  using tape_labelset_t = typename in_labelset_t::template valueset_t<I>;
108 
111  using kept_index_t
112  = sequence_difference<index_t, seq<Tapes...>>;
113 
115  using labelset_t = typename tape_set<kept_index_t, in_labelset_t>::type;
116 
118  using weight_index_t = seq<Tapes...>;
119 
121  using weight_tapes_t
123 
124  using inner_context_t = context<weight_tapes_t, WeightSet>;
125 
127  using weightset_t = expressionset<inner_context_t>;
128 
130  using context_t = context<labelset_t, weightset_t>;
131 
133  static context_t value(const in_context_t& ctx,
135  {
136  return value_(ctx, ids, weight_index_t{}, kept_index_t{});
137  }
138 
139  template <size_t... WeightTapes, size_t... KeptTapes>
140  static context_t value_(const in_context_t& ctx,
142  seq<WeightTapes...>,
143  seq<KeptTapes...>)
144  {
145  // The labelset.
146  auto ls = labelset_t{ctx.labelset()->template set<KeptTapes>()...};
147 
148  // The weightset.
149  auto weight_tapes
150  = weight_tapes_t{ctx.labelset()->template set<WeightTapes>()...};
151  auto ictx = inner_context_t{weight_tapes, *ctx.weightset()};
152  auto rs = weightset_t{ictx, ids};
153 
154  return {ls, rs};
155  }
156 
158  static typename labelset_t::value_t
159  kept_label(const in_label_t& l)
160  {
161  return kept_label_(l, kept_index_t{});
162  }
163 
164  template <size_t... I>
165  static typename labelset_t::value_t
166  kept_label_(const in_label_t& l, seq<I...>)
167  {
168  return typename labelset_t::value_t{std::get<I>(l)...};
169  }
170 
172  static typename weight_tapes_t::value_t
173  weight_label(const in_label_t& l)
174  {
175  return weight_label_(l, weight_index_t{});
176  }
177 
178  template <size_t... I>
179  static typename weight_tapes_t::value_t
180  weight_label_(const in_label_t& l, seq<I...>)
181  {
182  return typename weight_tapes_t::value_t{std::get<I>(l)...};
183  }
184  };
185 
187  template <typename Ctx, size_t... Tapes>
188  using lifter_t = lifter_impl<Ctx, detail::index_sequence<Tapes...>>;
189 
190  template <Automaton Aut, size_t... Tapes>
191  using lifted_automaton_t =
193  Tapes...>::context_t>;
194 
196  template <typename LabelSet, typename WeightSet, size_t... Tapes>
197  typename lifter_t<context<LabelSet, WeightSet>, Tapes...>::context_t
199  {
200  return (lifter_t<context<LabelSet, WeightSet>, Tapes...>
201  ::value(ctx, {}));
202  }
203  }
204 
205  /*-------------------.
206  | lift(automaton). |
207  `-------------------*/
208 
213  template <Automaton Aut, size_t... Tapes>
214  detail::lifted_automaton_t<Aut, Tapes...>
215  lift(const Aut& a, vcsn::rat::identities ids = {})
216  {
217  using auto_in_t = Aut;
218  using state_in_t = state_t_of<auto_in_t>;
219 
220  using lifter = detail::lifter_t<context_t_of<Aut>, Tapes...>;
221  auto ctx_out = lifter::value(a->context(), ids);
222 
223  // ExpressionSet
224  const auto& rs_in = *ctx_out.weightset();
225 
226  using auto_out_t = detail::lifted_automaton_t<auto_in_t, Tapes...>;
227  using state_out_t = state_t_of<auto_out_t>;
228  auto_out_t res = make_shared_ptr<auto_out_t>(ctx_out);
229 
230  // FIXME: a sufficiently generic vcsn::copy should suffice.
231  auto map = std::map<state_in_t, state_out_t>{};
232  map[a->pre()] = res->pre();
233  map[a->post()] = res->post();
234  for (auto s: a->states())
235  map[s] = res->new_state();
236 
237  for (auto t: all_transitions(a))
238  if (a->src_of(t) == a->pre())
239  res->add_initial(map[a->dst_of(t)],
240  rs_in.lweight(a->weight_of(t), rs_in.one()));
241  else if (a->dst_of(t) == a->post())
242  res->add_final(map[a->src_of(t)],
243  rs_in.lweight(a->weight_of(t), rs_in.one()));
244  else
245  res->add_transition
246  (map[a->src_of(t)], map[a->dst_of(t)],
247  lifter::kept_label(a->label_of(t)),
248  rs_in.lweight(a->weight_of(t),
249  rs_in.atom(lifter::weight_label(a->label_of(t)))));
250  return res;
251  }
252 
253  namespace dyn
254  {
255  namespace detail
256  {
258  template <Automaton Aut, typename Ids, typename... Tapes>
259  automaton
261  identities ids, integral_constant)
262  {
263  const auto& a = aut->as<Aut>();
264  return ::vcsn::lift<Aut, Tapes::value...>(a, ids);
265  }
266  }
267  }
268 
269  /*--------------------.
270  | lift(expression). |
271  `--------------------*/
272 
273  namespace detail
274  {
275  template <typename ExpSet>
276  using lifted_expressionset_t =
278 
280  template <typename Context>
283  boost::optional<vcsn::rat::identities> ids = {})
284  {
285  // FIXME: Boost 1.56 deprecates get_value_or in favor of value_or.
286  return {lift_context(rs.context()), ids.get_value_or(rs.identities())};
287  }
288  }
289 
291  template <typename ExpSet>
292  typename detail::lifted_expressionset_t<ExpSet>::value_t
293  lift(const ExpSet& rs, const typename ExpSet::value_t& e)
294  {
295  auto lrs = detail::lift_expressionset(rs);
296  return lrs.lweight(e, lrs.one());
297  }
298 
299 
300  namespace dyn
301  {
302  namespace detail
303  {
305  template <typename ExpSet>
306  expression
308  {
309  const auto& e = exp->as<ExpSet>();
310  const auto& es = e.valueset();
312  ::vcsn::lift(es, e.value())};
313  }
314  }
315  }
316 } // vcsn::
detail::lifted_automaton_t< Aut, Tapes... > lift(const Aut &a, vcsn::rat::identities ids={})
Lift some tapes of the transducer.
Definition: lift.hh:215
expressionset< typename lifter_t< context_t_of< ExpSet >>::context_t > lifted_expressionset_t
Definition: lift.hh:277
typename index_sequence_difference< typename S1::type, typename S2::type >::type sequence_difference
Definition: tuple.hh:154
#define Automaton
Definition: automaton.hh:23
std::string type(const automaton &a)
The implementation type of a.
Definition: others.cc:231
auto ictx
Definition: lift.hh:151
std::shared_ptr< const node< Context >> expression
Definition: fwd.hh:187
lifted_expressionset_t< expressionset< Context > > lift_expressionset(const expressionset< Context > &rs, boost::optional< vcsn::rat::identities > ids={})
lift(expressionset) -> expressionset
Definition: lift.hh:282
std::shared_ptr< detail::mutable_automaton_impl< Context >> mutable_automaton
Definition: fwd.hh:25
bool value_t
Definition: oneset.hh:20
static weight_tapes_t::value_t weight_label(const in_label_t &l)
Weight in the output.
Definition: lift.hh:173
static value_t one()
Definition: oneset.hh:102
static context_t value(const in_context_t &ctx, vcsn::rat::identities ids)
Lift a context.
Definition: lift.hh:47
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
lifter_t< context< LabelSet, WeightSet >, Tapes... >::context_t lift_context(const context< LabelSet, WeightSet > &ctx)
lift(ctx) -> ctx
Definition: lift.hh:198
auto all_transitions(const Aut &aut)
All the transition indexes between all states (including pre and post).
Definition: automaton.hh:192
static oneset::value_t kept_label(const in_label_t &)
Label in the output.
Definition: lift.hh:54
return res
Definition: multiply.hh:398
Implementation of labels are ones: there is a single instance of label.
Definition: oneset.hh:16
static labelset_t::value_t kept_label_(const in_label_t &l, seq< I... >)
Definition: lift.hh:166
auto rs
Definition: lift.hh:152
Definition: a-star.hh:8
mutable_automaton< typename lifter_t< context_t_of< Aut >, Tapes... >::context_t > lifted_automaton_t
Definition: lift.hh:193
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
Definition: traits.hh:62
static labelset_t::value_t kept_label(const in_label_t &l)
Label in the output.
Definition: lift.hh:159
A dyn automaton.
Definition: automaton.hh:17
auto weight_tapes
Definition: lift.hh:150
An expressionset can implement several different sets of identities on expressions.
Definition: identities.hh:21
auto map(const std::tuple< Ts... > &ts, Fun f) -> decltype(map_tuple_(f, ts, make_index_sequence< sizeof...(Ts)>()))
Map a function on a tuple, return tuple of the results.
Definition: tuple.hh:177
A simple placeholder for integral constants.
Definition: name.hh:196
detail::lifted_expressionset_t< ExpSet >::value_t lift(const ExpSet &rs, const typename ExpSet::value_t &e)
Move all the labels to the weights.
Definition: lift.hh:293
static weight_tapes_t::value_t weight_label_(const in_label_t &l, seq< I... >)
Definition: lift.hh:180
static in_label_t weight_label(const in_label_t &l)
Weight in the output.
Definition: lift.hh:61
expression lift_expression(const expression &exp)
Bridge (lift).
Definition: lift.hh:307
Helper structure for a lift of several tapes.
Definition: lift.hh:31
auto & as()
Extract wrapped typed automaton.
Definition: automaton.hh:37
static identities ids(const driver &d)
Get the identities of the driver.
Definition: parse.cc:89
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
value_impl< detail::expression_tag > expression
Definition: fwd.hh:25
automaton lift_automaton(const automaton &aut, identities ids, integral_constant)
Bridge.
Definition: lift.hh:260
struct lifter_impl< context< tupleset< LabelSets... >, WeightSet >, vcsn::detail::index_sequence< Tapes... >, std::enable_if_t<(0< sizeof...(Tapes))> >{using in_labelset_t=tupleset< LabelSets... >;using in_context_t=context< in_labelset_t, WeightSet >;using in_label_t=typename in_labelset_t::value_t;template< std::size_t...I > using seq=detail::index_sequence< I... >;template< typename S, typename L > struct tape_set;template< typename LabelSet > struct tape_set< seq<>, LabelSet >{using type=oneset;};template< size_t...I, typename LabelSet > struct tape_set< seq< I... >, LabelSet >{using type=tupleset< typename LabelSet::template valueset_t< I >... >;};using index_t=typename detail::make_index_sequence< in_labelset_t::size()>::type;static constexpr size_t number_of_tapes=in_labelset_t::size();template< size_t I > using tape_labelset_t=typename in_labelset_t::template valueset_t< I >;using kept_index_t=sequence_difference< index_t, seq< Tapes... > >;using labelset_t=typename tape_set< kept_index_t, in_labelset_t >::type;using weight_index_t=seq< Tapes... >;using weight_tapes_t=typename tape_set< weight_index_t, in_labelset_t >::type;using inner_context_t=context< weight_tapes_t, WeightSet >;using weightset_t=expressionset< inner_context_t >;using context_t=context< labelset_t, weightset_t >;static context_t value(const in_context_t &ctx, vcsn::rat::identities ids){return value_(ctx, ids, weight_index_t{}, kept_index_t{});}template< size_t...WeightTapes, size_t...KeptTapes > static context_t value_(const in_context_t &ctx, vcsn::rat::identities ids, seq< WeightTapes... >, seq< KeptTapes... >){auto ls=labelset_t{ctx.labelset() -> template set< KeptTapes >()...}
Specialization: lift only some tapes.
Definition: lift.hh:146