17 #ifndef AWALI_ALGOS_HOPCROFT_QUOTIENT_HH
18 #define AWALI_ALGOS_HOPCROFT_QUOTIENT_HH
20 #include <unordered_map>
83 template <
typename Aut>
84 unsigned hopcroft_quotient(
const Aut& aut, std::vector<std::list<state_t> >& states_in_part,
bool cancellative =
false) {
86 using automaton_t = Aut;
91 const auto& weightset_ = *aut->weightset();
92 std::vector<unsigned > size_of_part;
94 states_in_part.resize(3);
95 size_of_part.resize(3);
97 state_t state_capacity=aut->max_state()+1;
98 std::vector<unsigned> part(state_capacity);
99 std::vector<std::list<state_t>::iterator> address_in_part(state_capacity);
102 states_in_part[0].emplace_back(aut->pre());
104 states_in_part[1].emplace_back(aut->post());
106 size_of_part[0]=size_of_part[1]=1;
107 for(
auto s : aut->states() ) {
108 states_in_part[2].emplace_front(s);
110 address_in_part[s]=states_in_part[2].begin();
112 size_of_part[2]=aut->num_states();
117 std::queue<unsigned> splitters;
118 std::vector<bool> is_in_queue;
119 splitters.emplace(1);
120 splitters.emplace(2);
121 is_in_queue.push_back(
false);
122 is_in_queue.push_back(
true);
123 is_in_queue.push_back(
true);
125 unsigned iterations=0;
126 while(!splitters.empty()) {
129 unsigned i= splitters.front();
131 is_in_queue[i]=
false;
134 for(
auto s : states_in_part[i]) {
135 for(
auto tr : aut->all_in(s) ) {
137 if(size_of_part[part[
r]]==1)
141 meet[a].emplace_back(std::pair<state_t, weight_t>{
r,w});
144 if(
meet.domain().empty())
154 for(
auto a :
meet.domain())
155 for(
auto p :
meet[a]) {
158 if(signature.
count(
r)==0 || signature[
r].back().first!=a)
159 signature[
r].emplace_back(std::pair<label_t, weight_t>{a,w});
161 weight_t& w1 = signature[
r].back().second;
162 w1 = weightset_.add(w1,w);
171 std::queue<std::vector<state_t> > list;
174 for(
auto r : signature.
domain())
175 tmplist[part[
r]].emplace_back(
r);
176 for(
auto j : tmplist.
domain())
177 list.push(std::move(tmplist[j]));
179 while(!list.empty()) {
180 std::vector<state_t>& pp = list.front();
181 std::vector<state_t> shorter;
182 unsigned current_part = part[pp.front()];
185 std::vector<std::pair<label_t, weight_t>>& sig = signature[
r];
187 shorter.push_back(
r);
189 std::pair<label_t,weight_t>&
pair= sig.back();
190 tmplist[
pair].emplace_back(
r);
196 list.push(std::move(tmplist[
pair]));
198 new_parts_in_this_part[current_part].push_back(std::move(shorter));
202 for(
unsigned p : new_parts_in_this_part.
domain()) {
204 auto &pp=new_parts_in_this_part[p];
207 bool all_states_met= size_of_part[p]==s;
211 if(pp.size()>1 || !all_states_met) {
216 if(first && all_states_met) {
218 size_of_part[p]=
c.size();
222 states_in_part.emplace_back(std::list<state_t>());
223 size_of_part.push_back(
c.size());
227 states_in_part[p].erase(address_in_part[
r]);
228 states_in_part[k].emplace_front(
r);
229 address_in_part[
r]=states_in_part[k].begin();
234 if(cancellative && !is_in_queue[p]) {
235 unsigned max=p, size_max=size_of_part[p];
236 for(
unsigned k=
n; k<
nn; ++k)
237 if(size_of_part[k]>size_max) {
238 size_max=size_of_part[k];
242 splitters.emplace(p);
245 for(
unsigned k=
n; k<
nn; ++k)
247 splitters.emplace(k);
248 is_in_queue.push_back(
true);
251 is_in_queue.push_back(
false);
253 if(!is_in_queue[p]) {
254 splitters.emplace(p);
257 for(
unsigned k=
n; k<
nn; ++k) {
258 splitters.emplace(k);
259 is_in_queue.push_back(
true);
The semiring of complex numbers.
Definition: c.hh:44
The semiring of Natural numbers.
Definition: n.hh:34
The semiring of natural numbers bounded by K.
Definition: nn.hh:42
The semiring of floating Numbers.
Definition: r.hh:35
any_t label_t
Type for (transition) labels; it is an alias to any_t since its precise type depends on the weightset...
Definition: typedefs.hh:48
any_t weight_t
Type for (transition) weights; it is an alias to any_t since the its precise type depends on the weig...
Definition: typedefs.hh:61
typename internal::label_t_of_impl< internal::base_t< ValueSet > >::type label_t_of
Helper to retrieve the type of the labels of a value set.
Definition: traits.hh:71
typename internal::weight_t_of_impl< internal::base_t< ValueSet > >::type weight_t_of
Helper to retrieve the type of the weights of a value set.
Definition: traits.hh:81
auto meet(const ratexpset< Ctx1 > &a, const ratexpset< Ctx2 > &b) -> ratexpset< meet_t< Ctx1, Ctx2 >>
The meet of two ratexpsets.
Definition: ratexpset.hh:434
pair_automaton< Aut > pair(const Aut &aut, bool keep_initials=false)
Definition: synchronizing_word.hh:266
unsigned hopcroft_quotient(const Aut &aut, std::vector< std::list< state_t > > &states_in_part, bool cancellative=false)
Definition: hopcroft_quotient.hh:84
ATTRIBUTE_CONST int max(int a, int b)
Definition: arith.hh:54
Main namespace of Awali.
Definition: ato.hh:22
unsigned state_t
Definition: types.hh:21
Definition: linkedhashmap.hh:31
unsigned count(const K &k) const
Definition: linkedhashmap.hh:46
const std::vector< K > & domain() const
Definition: linkedhashmap.hh:36