Vcsn  2.0
Be Rational
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
sort.hh
Go to the documentation of this file.
1 #ifndef VCSN_ALGOS_SORT_HH
2 # define VCSN_ALGOS_SORT_HH
3 
4 # include <map>
5 # include <queue>
6 # include <vector>
7 
9 # include <vcsn/ctx/traits.hh>
10 # include <vcsn/dyn/automaton.hh>
11 # include <vcsn/dyn/fwd.hh>
12 # include <vcsn/misc/algorithm.hh>
13 # include <vcsn/misc/attributes.hh>
15 
16 # include <vcsn/algos/copy.hh> // real_context
17 # include <vcsn/ctx/traits.hh> // base_t
18 
19 namespace vcsn
20 {
21 
22  /*------------------.
23  | is_label_sorted. |
24  `------------------*/
25 
28  template <typename Aut>
29  inline
30  bool
31  is_out_sorted(const Aut& a)
32  {
33  using transition_t = transition_t_of<Aut>;
34  for (state_t_of<Aut> s: a->states())
35  if (!detail::is_sorted(a->out(s),
36  [&a] (transition_t l, transition_t r)
37  {
38  return a->labelset()->less_than(a->label_of(l),
39  a->label_of(r));
40  }))
41  return false;
42  return true;
43  }
44 
45  namespace dyn
46  {
47  namespace detail
48  {
50  template <typename Aut>
51  bool
53  {
54  const auto& a = aut->as<Aut>();
55  return is_out_sorted(a);
56  }
57 
59  (const automaton&) -> bool);
60  }
61  }
62 
63 
64  /*-------.
65  | sort. |
66  `-------*/
67  namespace detail
68  {
70  template <typename Aut>
71  class sorter
72  {
74  using input_automaton_t = Aut;
75 
78 
82 
83  public:
86  {}
87 
89  {
93  return std::move(res_);
94  }
95 
96  private:
98  {
99  while (! res_->todo_.empty())
100  {
101  auto p = res_->todo_.front();
102  res_->todo_.pop();
103  visit_successors_of_(p.first, p.second);
104  }
105  }
106 
108  {
109  std::vector<input_transition_t> ts;
110  // Here a_->out(s) would just as well as a_->all_out(s) but it
111  // would be slower; later we have to test one condition per
112  // transition anyway, which is just the additional work
113  // performed by out.
114  for (auto t: res_->input_->all_out(s))
115  ts.emplace_back(t);
116 
117  // There is a difference in performance between using lambdas
118  // or std::bind. See
119  // http://www.gockelhut.com/c++/articles/lambda_vs_bind and
120  // especially the bench program
121  // http://www.gockelhut.com/c++/files/lambda_vs_bind.cpp.
122  //
123  // It gives, with -O3
124  //
125  // Clang 3.5 GCC 4.9
126  // lambda 1001 7000
127  // bind 3716166405 2530142000
128  // bound lambda 2438421993 1700834000
129  // boost bind 2925777511 2529615000
130  // boost bound lambda 2420710412 1683458000
131  std::sort(ts.begin(), ts.end(),
132  [&](const input_transition_t t1,
133  const input_transition_t t2) -> bool
134  {
135  return transition_less_than_(t1, t2);
136  });
137 
138  for (auto t: ts)
139  res_->new_transition_copy(res_s, res_->state(res_->input_->dst_of(t)),
140  res_->input_, t);
141  }
142 
144  {
145  // States are processed in order. Like above, a_->states()
146  // would work.
147  for (auto s: res_->input_->all_states())
148  res_->state(s);
149  }
150 
152  const input_transition_t t2) const
153  ATTRIBUTE_PURE
154  {
155  // We intentionally ignore source states: they should always
156  // be identical when we call this.
157  auto& aut = res_->input_;
158  assert(aut->src_of(t1) == aut->src_of(t2));
159  if (ls_.less_than(aut->label_of(t1), aut->label_of(t2)))
160  return true;
161  else if (ls_.less_than(aut->label_of(t2), aut->label_of(t1)))
162  return false;
163  else if (ws_.less_than(aut->weight_of(t1), aut->weight_of(t2)))
164  return true;
165  else if (ws_.less_than(aut->weight_of(t2), aut->weight_of(t1)))
166  return false;
167  else if (aut->dst_of(t1) < aut->dst_of(t2))
168  return true;
169  else if (aut->dst_of(t2) < aut->dst_of(t1))
170  return false;
171  else
172  return false;
173  }
174 
177  const labelset_t_of<input_automaton_t>& ls_ = *res_->input_->labelset();
178  const weightset_t_of<input_automaton_t>& ws_ = *res_->input_->weightset();
179  }; // class
180  } // namespace
181 
182  template <typename Aut>
183  inline
184  auto
185  sort(const Aut& a)
187  {
188  detail::sorter<Aut> sorter(a);
189  return sorter();
190  }
191 
192  namespace dyn
193  {
194  namespace detail
195  {
196 
198  template <typename Aut>
199  automaton
200  sort(const automaton& aut)
201  {
202  const auto& a = aut->as<Aut>();
203  return make_automaton(::vcsn::sort(a));
204  }
205 
207  (const automaton&) -> automaton);
208  }
209  }
210 }
211 
212 #endif // !VCSN_ALGOS_SORT_HH
const labelset_t_of< input_automaton_t > & ls_
Definition: sort.hh:177
state_t_of< input_automaton_t > input_state_t
Definition: sort.hh:76
state_t_of< automaton_t > state_t
Definition: sort.hh:81
REGISTER_DECLARE(accessible,(const automaton &) -> automaton)
std::shared_ptr< detail::automaton_base > automaton
Definition: automaton.hh:71
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:34
bool is_out_sorted(const automaton &aut)
Bridge.
Definition: sort.hh:52
void visit_successors_of_(input_state_t s, state_t res_s)
Definition: sort.hh:107
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
Definition: automaton.hh:77
sorter(const input_automaton_t &a)
Definition: sort.hh:84
bool transition_less_than_(const input_transition_t t1, const input_transition_t t2) const ATTRIBUTE_PURE
Definition: sort.hh:151
A function to sort an automaton.
Definition: sort.hh:71
std::shared_ptr< detail::permutation_automaton_impl< Aut >> permutation_automaton
A permutation automaton as a shared pointer.
Definition: fwd.hh:38
bool is_sorted(const Container &container, Compare comp)
Definition: algorithm.hh:11
auto sort(const Aut &a) -> permutation_automaton< Aut >
Definition: sort.hh:185
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
Definition: traits.hh:38
void visit_and_update_res_()
Definition: sort.hh:97
automaton sort(const automaton &aut)
Bridge.
Definition: sort.hh:200
typename detail::transition_t_of_impl< base_t< ValueSet >>::type transition_t_of
Definition: traits.hh:36
transition_t_of< input_automaton_t > input_transition_t
Definition: sort.hh:77
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:36
automaton_t operator()()
Definition: sort.hh:88
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:35
SharedPtr make_shared_ptr(Args &&...args)
Same as std::make_shared, but parameterized by the shared_ptr type, not the (pointed to) element_type...
Definition: memory.hh:15
permutation_automaton< input_automaton_t > automaton_t
Result automaton type.
Definition: sort.hh:80
const weightset_t_of< input_automaton_t > & ws_
Definition: sort.hh:178
Aut input_automaton_t
Input automaton type.
Definition: sort.hh:74
automaton_t res_
Sorted automaton.
Definition: sort.hh:176
variadic_mul_mixin< detail::r_impl > r
Definition: fwd.hh:42
bool is_out_sorted(const Aut &a)
Whether for each state, the outgoing transitions are sorted by increasing label.
Definition: sort.hh:31
void push_inaccessible_states_()
Definition: sort.hh:143