Vcsn  2.3
Be Rational
transpose.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <vcsn/core/rat/fwd.hh>
4 #include <vcsn/ctx/traits.hh>
5 
6 namespace vcsn
7 {
8 
13  template <typename ExpSet>
14  typename ExpSet::value_t
15  transpose(const ExpSet& rs, const typename ExpSet::value_t& v);
16 
17  namespace detail
18  {
19 
20  /*-------------------------.
21  | transpose(expression). |
22  `-------------------------*/
23 
27  template <typename ExpSet>
29  : public ExpSet::const_visitor
30  {
31  public:
32  using expressionset_t = ExpSet;
33  using expression_t = typename expressionset_t::value_t;
34  using super_t = typename expressionset_t::const_visitor;
37 
39  constexpr static const char* me() { return "transpose"; }
40 
42  : rs_{rs}
43  , res_{}
44  {}
45 
49  {
50  e->accept(*this);
51  return std::move(res_);
52  }
53 
54  private:
58  {
59  auto res = expression_t{};
60  std::swap(res_, res);
61  e->accept(*this);
62  std::swap(res_, res);
63  return res;
64  }
65 
67  {
68  res_ = rs_.zero();
69  }
70 
72  {
73  res_ = rs_.one();
74  }
75 
76  VCSN_RAT_VISIT(atom, e)
77  {
78  res_ = rs_.atom(rs_.labelset()->transpose(e.value()));
79  }
80 
82  using binary_t =
84  const expression_t&) const;
85 
86  template <rat::type_t Type>
88 
90  template <rat::type_t Type>
92  {
93  res_ = transpose(v.head());
94  for (const auto& c: v.tail())
95  res_ = (rs_.*f)(res_, transpose(c));
96  }
97 
99 #define DEFINE(Node) \
100  VCSN_RAT_VISIT(Node, e) \
101  { \
102  visit_(e, &expressionset_t::Node); \
103  }
104 
105  DEFINE(add);
106  DEFINE(compose);
108  DEFINE(infiltrate);
109  DEFINE(shuffle);
110 #undef DEFINE
111 
113  {
114  res_ = transpose(e.head());
115  for (const auto& c: e.tail())
116  res_ = rs_.mul(transpose(c), res_);
117  }
118 
119  VCSN_RAT_VISIT(star, e)
120  {
121  res_ = rs_.star(transpose(e.sub()));
122  }
123 
124  VCSN_RAT_VISIT(complement, e)
125  {
126  res_ = rs_.complement(transpose(e.sub()));
127  }
128 
129  VCSN_RAT_VISIT(transposition, e)
130  {
131  // Don't stack indefinitly transpositions on top of
132  // transitions. Not only is this useless, it would also break
133  // the involution as r.transpose().transpose() would not be r,
134  // but "r{T}{T}". On the other hand, if "(abc){T}".transpose()
135  // returns "abc", we also lose the involution.
136  //
137  // So rather, don't stack more that two transpositions:
138  //
139  // (abc){T}.transpose() => (abc){T}{T}
140  // (abc){T}{T}.transpose() => (abc){T}
141  //
142  // Do the same with ldivide, for the same reasons: involution.
143  //
144  // (E\F).transpose() => (E\F){T}
145  // (E\F){T}.transpose() => (E\F)
146  if (e.sub()->type() == rat::type_t::transposition
147  || e.sub()->type() == rat::type_t::ldivide)
148  res_ = e.sub();
149  else
150  res_ = rs_.transposition(e.shared_from_this());
151  }
152 
153  VCSN_RAT_VISIT(ldivide, e)
154  {
155  // There is nothing we can do here but leaving an explicit
156  // transposition.
157  res_ = rs_.transposition(e.shared_from_this());
158  }
159 
160  VCSN_RAT_VISIT(lweight, e)
161  {
162  res_ = rs_.rweight(transpose(e.sub()),
163  rs_.weightset()->transpose(e.weight()));
164  }
165 
166  VCSN_RAT_VISIT(rweight, e)
167  {
168  res_ = rs_.lweight(rs_.weightset()->transpose(e.weight()),
169  transpose(e.sub()));
170  }
171 
172  /*---------.
173  | tuple. |
174  `---------*/
175 
176  using tuple_t = typename super_t::tuple_t;
177 
178  template <bool = context_t::is_lat,
179  typename Dummy = void>
180  struct visit_tuple
181  {
183  template <size_t I>
184  auto work_(const tuple_t& v)
185  {
186  return vcsn::transpose(detail::project<I>(visitor_.rs_),
187  std::get<I>(v.sub()));
188  }
189 
191  template <size_t... I>
193  {
194  return visitor_.rs_.tuple(work_<I>(v)...);
195  }
196 
198  auto operator()(const tuple_t& v)
199  {
201  }
203  };
204 
205  template <typename Dummy>
206  struct visit_tuple<false, Dummy>
207  {
209  {
211  }
213  };
214 
215  void visit(const tuple_t& v, std::true_type) override
216  {
217  res_ = visit_tuple<>{*this}(v);
218  }
219 
220  private:
223  };
224  }
225 
226  template <typename ExpSet>
227  typename ExpSet::value_t
228  transpose(const ExpSet& rs, const typename ExpSet::value_t& v)
229  {
230  auto tr = detail::transpose_impl<ExpSet>{rs};
231  return tr(v);
232  }
233 }
return v
Definition: multiply.hh:361
expression_t operator()(const expression_t &e)
An expression denoting the transposition of e.
Definition: transpose.hh:48
Aut transpose(const transpose_automaton< Aut > &aut)
Definition: transpose.hh:238
expression_t transpose(const expression_t &e)
Easy recursion.
Definition: transpose.hh:57
#define BUILTIN_UNREACHABLE()
Definition: builtins.hh:13
VCSN_RAT_VISIT(transposition, e)
Definition: transpose.hh:129
context_t_of< expressionset_t > context_t
Definition: transpose.hh:36
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:63
typename super_t::tuple_t tuple_t
Definition: transpose.hh:176
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:61
auto conjunction(const Aut &a, const Auts &...as)
Build the (accessible part of the) conjunction.
Definition: conjunction.hh:622
auto work_(const tuple_t &v)
Copy one tape.
Definition: transpose.hh:184
static constexpr const char * me()
Name of this algorithm, for error messages.
Definition: transpose.hh:39
auto work_(const tuple_t &v, detail::index_sequence< I... >)
Copy all the tapes.
Definition: transpose.hh:192
auto operator()(const tuple_t &v)
Entry point.
Definition: transpose.hh:198
typename expressionset_t::const_visitor super_t
Definition: transpose.hh:34
return res
Definition: multiply.hh:398
auto rs
Definition: lift.hh:152
Definition: a-star.hh:8
void visit_(const variadic_t< Type > &v, binary_t f)
Factor the visitation of "commutative" variadic nodes.
Definition: transpose.hh:91
A visitor to create a transposed expression,.
Definition: transpose.hh:28
VCSN_RAT_VISIT(complement, e)
Definition: transpose.hh:124
auto tail() const -> decltype(boost::make_iterator_range(*this, 1, 0))
The non-first items.
Definition: expression.hxx:111
typename expressionset_t::value_t expression_t
Definition: transpose.hh:33
An inner node with multiple children.
Definition: expression.hh:118
void visit(const tuple_t &v, std::true_type) override
Definition: transpose.hh:215
const value_t head() const
The first item of this variadic.
Definition: expression.hxx:99
#define DEFINE(Node)
Handle variadic operations.
Definition: transpose.hh:99
expression_t(expressionset_t::*)(const expression_t &, const expression_t &) const binary_t
Binary member functions of the expressionset.
Definition: transpose.hh:84
transpose_impl(const expressionset_t &rs)
Definition: transpose.hh:41