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