Vcsn  2.8
Be Rational
minimize-hopcroft.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <algorithm>
4 
6 #include <vcsn/algos/quotient.hh>
10 #include <vcsn/misc/set.hh>
11 #include <vcsn/misc/vector.hh>
12 #include <vcsn/misc/wet.hh>
13 #include <vcsn/weightset/b.hh>
15 
16 namespace vcsn
17 {
18 
19  /*------------------------------------------.
20  | minimization with Hopcrofts's algorithm. |
21  `------------------------------------------*/
22 
24  struct hopcroft_tag {};
25 
26  template <Automaton Aut>
27  std::enable_if_t<is_free_boolean<Aut>(), quotient_t<Aut>>
28  minimize(const Aut& a, hopcroft_tag)
29  {
30  using state_t = state_t_of<Aut>;
31  using stateset_t = stateset<Aut>;
32  auto ctx = make_context(stateset_t(a), *a->weightset());
33  auto ps = detail::make_polynomialset<decltype(ctx),
35  using set_t = typename decltype(ps)::value_t;
36  using partition_t = std::set<set_t>;
37 
38  auto size = states_size(a);
39 
40  auto f = set_t(size);
41  f.set(a->post());
42 
43  auto q = set_t(size);
44  for (auto s: a->all_states())
45  q.set(s);
46  q.erase(a->post());
47 
48  auto p = partition_t{f, q};
49  auto w = partition_t{f};
50 
51  const auto& ls = *a->labelset();
52  auto generators = detail::make_vector(ls.generators());
53  generators.emplace_back(ls.special());
54 
55  while (!w.empty())
56  {
57  auto sub_w = std::move(*begin(w));
58  w.erase(begin(w));
59  for (const auto l: generators)
60  {
61  auto x = set_t(size);
62  for (auto s: sub_w)
63  for (auto t: in(a, label_of(s), l))
64  x.set(a->src_of(t));
65  auto p2 = partition_t(p);
66  for (auto y: p2)
67  {
68  auto xny = x & y;
69  auto x_y = y - x;
70  if (!xny.empty() && !x_y.empty())
71  {
72  auto it = w.find(y);
73  if (it != end(w))
74  {
75  w.erase(it);
76  w.insert(xny);
77  w.insert(x_y);
78  }
79  else
80  w.insert(xny.size() <= x_y.size() ? xny : x_y);
81  p.erase(y);
82  p.insert(std::move(xny));
83  p.insert(std::move(x_y));
84  }
85  }
86  }
87  }
88  auto res = std::vector<std::vector<state_t>>{};
89  std::transform(begin(p), end(p), std::back_inserter(res),
90  [](const set_t& set)
91  {
92  auto res = std::vector<state_t>();
93  res.reserve(set.size());
94  for (auto s: set)
95  res.push_back(label_of(s));
96  return res;
97  });
98  return quotient(a, res);
99  }
100 
101  namespace dyn
102  {
103  namespace detail
104  {
105  template <Automaton Aut>
106  ATTRIBUTE_NORETURN
107  std::enable_if_t<!is_free_boolean<Aut>(), quotient_t<Aut>>
108  minimize(const Aut&, hopcroft_tag)
109  {
110  raise("minimize: invalid algorithm"
111  " (non-Boolean or non-free labelset):",
112  " hopcroft");
113  }
114  }
115  }
116 } // namespace vcsn
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
typename detail::state_t_of_impl< base_t< ValueSet > >::type state_t_of
Definition: traits.hh:64
size_t states_size(const Aut &aut)
The largest state number, plus one.
Definition: automaton.hh:41
auto quotient(const Aut &a, typename detail::quotienter< Aut >::class_to_set_t &cs) -> quotient_t< Aut >
Definition: quotient.hh:123
std::vector< typename Cont::value_type > make_vector(const Cont &cont)
The content of cont as a vector.
Definition: vector.hh:18
polynomialset< Context, Kind > make_polynomialset(const Context &context)
Ctx make_context(const std::string &name)
Build a context from its name.
Definition: make-context.hh:21
State labelset.
Definition: stateset.hh:14
auto transform(const Container &c, Fun &&fun)
Map a unary function on a container of values, and return the vector the results. ...
Definition: algorithm.hh:211
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
Definition: a-star.hh:8
auto in(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions arriving to state s.
Definition: automaton.hh:135
Request the bitset implementation (bool weights).
Request for Hopcroft implementation of minimize (B and free).
partition_automaton_t< Aut > quotient_t
The return type when calling quotient on Aut.
Definition: quotient.hh:119
auto minimize(const Aut &a, brzozowski_tag) -> std::enable_if_t< is_free_boolean< Aut >(), determinized_automaton< codeterminized_automaton< Aut >, wet_kind_t::bitset >>
Brzozowski-based minimization.
auto label_of(const welement< Label, Weight > &m) -> decltype(m.label())
The label of a welement.
Definition: wet.hh:146
return res
Definition: multiply.hh:399