Vcsn  2.0
Be Rational
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
quotient.hh
Go to the documentation of this file.
1 #ifndef VCSN_ALGOS_QUOTIENT_HH
2 # define VCSN_ALGOS_QUOTIENT_HH
3 
4 # include <algorithm> // min_element.
5 # include <unordered_map>
6 # include <unordered_set>
7 
8 # include <vcsn/algos/accessible.hh>
11 # include <vcsn/dyn/automaton.hh>
13 
14 namespace vcsn
15 {
16 
17  namespace detail
18  {
20  template <typename Aut>
21  class quotienter
22  {
23  public:
24  using automaton_t = Aut;
26 
27  using class_t = unsigned;
29  using set_t = std::vector<state_t>;
30  using state_to_class_t = std::unordered_map<state_t, class_t>;
31  using class_to_set_t = std::vector<set_t>;
32  using class_to_state_t = std::vector<state_t>;
33 
37  quotienter(class_to_set_t& class_to_set)
38  : class_to_set_(class_to_set)
39  , num_classes_(class_to_set_.size())
40  {
41  sort_classes_();
42  }
43 
51  {
52  /* For each class, put its smallest numbered state first. We
53  don't need to fully sort. */
54  for (unsigned c = 0; c < num_classes_; ++c)
55  std::swap(class_to_set_[c][0],
56  *std::min_element(begin(class_to_set_[c]),
57  end(class_to_set_[c])));
58 
59  /* Sort class numbers by smallest state number. */
61  [](const set_t& lhs, const set_t& rhs) -> bool
62  {
63  return lhs[0] < rhs[0];
64  });
65  }
66 
69  {
70  state_to_class_t state_to_class;
71  for (unsigned c = 0; c < num_classes_; ++c)
72  for (auto s: class_to_set_[c])
73  state_to_class[s] = c;
74 
76  = make_shared_ptr<partition_automaton_t>(aut);
77  class_to_res_state_.resize(num_classes_);
78  for (unsigned c = 0; c < num_classes_; ++c)
79  {
80  const std::vector<state_t>& set = class_to_set_[c];
81  state_t s = set[0];
83  = s == aut->pre() ? res->pre()
84  : s == aut->post() ? res->post()
85  : res->new_state(set);
86  }
87  for (unsigned c = 0; c < num_classes_; ++c)
88  {
89  // Copy the transitions of the first state of the class in
90  // the result.
91  state_t s = class_to_set_[c][0];
93  for (auto t : aut->all_out(s))
94  {
95  state_t d = aut->dst_of(t);
96  state_t dst = class_to_res_state_[state_to_class[d]];
97  res->add_transition(src, dst, aut->label_of(t), aut->weight_of(t));
98  }
99  }
100  return std::move(res);
101  }
102 
105  {
106  return build_result_(aut);
107  }
108 
109  private:
110  std::ostream& print_(const set_t& ss, std::ostream& o) const
111  {
112  o << '{';
113  const char* sep = "";
114  for (auto s : ss)
115  {
116  o << sep << s;
117  sep = ", ";
118  }
119  return o << '}';
120  }
121  std::ostream& print_(const class_to_set_t& c2ss, std::ostream& o) const
122  {
123  const char* sep = "";
124  for (unsigned i = 0; i < c2ss.size(); ++i)
125  {
126  o << sep << '[' << i << "] = ";
127  print_(c2ss[i], o);
128  sep = "\n";
129  }
130  return o;
131  }
132 
133  private:
135  unsigned num_classes_;
137  };
138  } // detail::
139 
140  template <typename Aut>
141  inline
142  auto
143  quotient(const Aut& a,
144  typename detail::quotienter<Aut>::class_to_set_t& classes)
146  {
148  return quotient(a);
149  }
150 
151 } // namespace vcsn
152 
153 #endif // !VCSN_ALGOS_QUOTIENT_HH
class_to_state_t class_to_res_state_
Definition: quotient.hh:136
partition_automaton_t operator()(const automaton_t &aut)
The minimized automaton.
Definition: quotient.hh:104
auto quotient(const Aut &a, typename detail::quotienter< Aut >::class_to_set_t &classes) -> partition_automaton< Aut >
Definition: quotient.hh:143
std::unordered_map< state_t, class_t > state_to_class_t
Definition: quotient.hh:30
void sort_classes_()
Sort the classes.
Definition: quotient.hh:50
partition_automaton< automaton_t > partition_automaton_t
Definition: quotient.hh:25
std::ostream & print_(const set_t &ss, std::ostream &o) const
Definition: quotient.hh:110
std::ostream & print_(const class_to_set_t &c2ss, std::ostream &o) const
Definition: quotient.hh:121
auto sort(const Aut &a) -> permutation_automaton< Aut >
Definition: sort.hh:185
partition_automaton_t build_result_(const automaton_t &aut)
Build the resulting automaton.
Definition: quotient.hh:68
std::vector< state_t > class_to_state_t
Definition: quotient.hh:32
class_to_set_t & class_to_set_
Definition: quotient.hh:134
quotienter(class_to_set_t &class_to_set)
Definition: quotient.hh:37
std::vector< state_t > set_t
Definition: quotient.hh:29
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:35
state_t_of< automaton_t > state_t
Definition: quotient.hh:28
std::shared_ptr< detail::partition_automaton_impl< Aut >> partition_automaton
A partition automaton as a shared pointer.
std::vector< set_t > class_to_set_t
Definition: quotient.hh:31
Apply a quotient onto an automaton: fuse equivalent states.
Definition: quotient.hh:21