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