Vcsn  2.2
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/mutable-automaton.hh> // fresh_automaton_t_of
10 #include <vcsn/ctx/context.hh>
11 #include <vcsn/dyn/automaton.hh>
12 #include <vcsn/labelset/oneset.hh>
13 #include <vcsn/misc/name.hh>
14 
15 namespace vcsn
16 {
17 
18  namespace detail
19  {
20  /*---------.
21  | lifter. |
22  `---------*/
23 
29  template <typename Context, typename Tapes, typename Enable = void>
30  struct lifter_impl;
31 
33  template <typename Context>
35  {
37  using in_context_t = Context;
39 
44 
47  {
48  return {oneset{}, weightset_t{ctx, ids}};
49  }
50 
52  static oneset::value_t
54  {
55  return oneset::one();
56  }
57 
59  static in_label_t
61  {
62  return l;
63  }
64  };
65 
67  template <typename... LabelSets, typename WeightSet,
68  size_t... Tapes>
69  struct lifter_impl<context<tupleset<LabelSets...>, WeightSet>,
70  vcsn::detail::index_sequence<Tapes...>,
71  std::enable_if_t<(0 < sizeof...(Tapes))>>
72  {
74  using in_labelset_t = tupleset<LabelSets...>;
75  using in_context_t = context<in_labelset_t, WeightSet>;
76  using in_label_t = typename in_labelset_t::value_t;
77 
79  template <std::size_t... I>
80  using seq = detail::index_sequence<I...>;
81 
83  template <typename S, typename L>
84  struct tape_set;
85 
86  // Set of no tape is oneset
87  template <typename LabelSet>
88  struct tape_set<seq<>, LabelSet>
89  {
90  using type = oneset;
91  };
92 
93  template <size_t... I, typename LabelSet>
94  struct tape_set<seq<I...>, LabelSet>
95  {
96  using type = tupleset<typename LabelSet::template valueset_t<I>...>;
97  };
98 
100  using index_t
102 
103  static constexpr size_t number_of_tapes = in_labelset_t::size();
104 
105  template <size_t I>
106  using tape_labelset_t = typename in_labelset_t::template valueset_t<I>;
107 
110  using kept_index_t
111  = sequence_difference<index_t, seq<Tapes...>>;
112 
114  using labelset_t = typename tape_set<kept_index_t, in_labelset_t>::type;
115 
117  using weight_index_t = seq<Tapes...>;
118 
120  using weight_tapes_t
122 
123  using inner_context_t = context<weight_tapes_t, WeightSet>;
124 
126  using weightset_t = expressionset<inner_context_t>;
127 
129  using context_t = context<labelset_t, weightset_t>;
130 
132  static context_t value(const in_context_t& ctx,
134  {
135  return value_(ctx, ids, weight_index_t{}, kept_index_t{});
136  }
137 
138  template <size_t... WeightTapes, size_t... KeptTapes>
139  static context_t value_(const in_context_t& ctx,
141  seq<WeightTapes...>,
142  seq<KeptTapes...>)
143  {
144  // The labelset.
145  auto ls = labelset_t{ctx.labelset()->template set<KeptTapes>()...};
146 
147  // The weightset.
148  auto weight_tapes
149  = weight_tapes_t{ctx.labelset()->template set<WeightTapes>()...};
150  auto ictx = inner_context_t{weight_tapes, *ctx.weightset()};
151  auto rs = weightset_t{ictx, ids};
152 
153  return {ls, rs};
154  }
155 
157  static typename labelset_t::value_t
158  kept_label(const in_label_t& l)
159  {
160  return kept_label_(l, kept_index_t{});
161  }
162 
163  template <size_t... I>
164  static typename labelset_t::value_t
165  kept_label_(const in_label_t& l, seq<I...>)
166  {
167  return typename labelset_t::value_t{std::get<I>(l)...};
168  }
169 
171  static typename weight_tapes_t::value_t
172  weight_label(const in_label_t& l)
173  {
174  return weight_label_(l, weight_index_t{});
175  }
176 
177  template <size_t... I>
178  static typename weight_tapes_t::value_t
179  weight_label_(const in_label_t& l, seq<I...>)
180  {
181  return typename weight_tapes_t::value_t{std::get<I>(l)...};
182  }
183  };
184 
186  template <typename Ctx, size_t... Tapes>
187  using lifter_t = lifter_impl<Ctx, detail::index_sequence<Tapes...>>;
188 
189  template <Automaton Aut, size_t... Tapes>
190  using lifted_automaton_t =
192  Tapes...>::context_t>;
193 
195  template <typename LabelSet, typename WeightSet, size_t... Tapes>
196  typename lifter_t<context<LabelSet, WeightSet>, Tapes...>::context_t
198  {
199  return (lifter_t<context<LabelSet, WeightSet>, Tapes...>
200  ::value(ctx, {}));
201  }
202  }
203 
204  /*-------------------.
205  | lift(automaton). |
206  `-------------------*/
207 
212  template <Automaton Aut, size_t... Tapes>
213  inline
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.lmul(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.lmul(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.lmul(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
262  {
263  const auto& a = aut->as<Aut>();
264  return make_automaton(::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  inline
293  typename detail::lifted_expressionset_t<ExpSet>::value_t
294  lift(const ExpSet& rs, const typename ExpSet::value_t& e)
295  {
296  auto lrs = detail::lift_expressionset(rs);
297  return lrs.lmul(e, lrs.one());
298  }
299 
300 
301  namespace dyn
302  {
303  namespace detail
304  {
306  template <typename ExpSet>
307  expression
309  {
310  const auto& e = exp->as<ExpSet>();
311  const auto& es = e.expressionset();
313  ::vcsn::lift(es, e.expression()));
314  }
315  }
316  }
317 } // vcsn::
static context_t value(const in_context_t &ctx, vcsn::rat::identities ids)
Lift a context.
Definition: lift.hh:46
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:160
static in_label_t weight_label(const in_label_t &l)
Weight in the output.
Definition: lift.hh:60
auto ictx
Definition: lift.hh:150
expressionset< typename lifter_t< context_t_of< ExpSet >>::context_t > lifted_expressionset_t
Definition: lift.hh:277
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
Definition: automaton.hh:75
std::shared_ptr< detail::mutable_automaton_impl< Context >> mutable_automaton
Definition: fwd.hh:25
static oneset::value_t kept_label(const in_label_t &)
Label in the output.
Definition: lift.hh:53
An expressionset can implement several different sets of identities on expressions.
Definition: identities.hh:21
static weight_tapes_t::value_t weight_label_(const in_label_t &l, seq< I... >)
Definition: lift.hh:179
A simple placeholder for integral constants.
Definition: name.hh:198
Definition: a-star.hh:8
auto weight_tapes
Definition: lift.hh:149
std::string type(const automaton &a)
The implementation type of a.
Definition: others.cc:206
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
lifted_expressionset_t< expressionset< Context > > lift_expressionset(const expressionset< Context > &rs, boost::optional< vcsn::rat::identities > ids={})
lift(expressionset) -> expressionset
Definition: lift.hh:282
static labelset_t::value_t kept_label(const in_label_t &l)
Label in the output.
Definition: lift.hh:158
Helper structure for a lift of several tapes.
Definition: lift.hh:30
std::shared_ptr< detail::automaton_base > automaton
Definition: automaton.hh:69
auto rs
Definition: lift.hh:151
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:145
bool value_t
Definition: oneset.hh:20
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
Definition: traits.hh:54
std::shared_ptr< const node< Context >> expression
Definition: fwd.hh:182
static dyn::context ctx(const driver &d)
Get the context of the driver.
Definition: parse.cc:82
Implementation of labels are ones: there is a single instance of label.
Definition: oneset.hh:16
expression lift_expression(const expression &exp)
Bridge (lift).
Definition: lift.hh:308
std::shared_ptr< detail::expression_base > expression
Definition: expression.hh:92
static labelset_t::value_t kept_label_(const in_label_t &l, seq< I... >)
Definition: lift.hh:165
automaton lift_automaton(const automaton &aut, vcsn::rat::identities ids, integral_constant)
Bridge.
Definition: lift.hh:260
static identities ids(const driver &d)
Get the identities of the driver.
Definition: parse.cc:89
auto all_transitions(const Aut &aut)
All the transition indexes between all states (including pre and post).
Definition: automaton.hh:184
#define Automaton
Definition: automaton.hh:24
static weight_tapes_t::value_t weight_label(const in_label_t &l)
Weight in the output.
Definition: lift.hh:172
typename index_sequence_difference< typename S1::type, typename S2::type >::type sequence_difference
Definition: tuple.hh:138
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
static value_t one()
Definition: oneset.hh:102
mutable_automaton< typename lifter_t< context_t_of< Aut >, Tapes... >::context_t > lifted_automaton_t
Definition: lift.hh:192
detail::lifted_automaton_t< Aut, Tapes... > lift(const Aut &a, vcsn::rat::identities ids={})
Lift some tapes of the transducer.
Definition: lift.hh:215
expression make_expression(const ExpSet &rs, const typename ExpSet::value_t &r)
Definition: expression.hh:97
lifter_t< context< LabelSet, WeightSet >, Tapes... >::context_t lift_context(const context< LabelSet, WeightSet > &ctx)
lift(ctx) -> ctx
Definition: lift.hh:197