17 #ifndef AWALI_ALGOS_CONGRUENCE_DET_HH
18 # define AWALI_ALGOS_CONGRUENCE_DET_HH
35 template<
typename Aut,
typename Weightset>
38 using type = std::pair<label_t,typename Weightset::value_t>;
40 template <
typename Tr>
42 return {aut->label_of(tr),aut->weight_of(tr)};
46 template<
typename Aut>
51 template <
typename Tr>
53 return aut->label_of(tr);
57 template <
typename Aut>
59 using automaton_t = Aut;
66 for(
auto s : aut->states()) {
67 for(
auto tr : aut->all_out(s) ) {
68 auto a = extended_label_t::getLabel(aut,tr);
69 meet[a].emplace_back(s);
73 states_in_part.resize(2);
74 states_in_part[0].emplace_back(aut->pre());
75 states_in_part[1].emplace_back(aut->post());
76 if(
meet.domain().empty())
81 for(
auto a:
meet.domain())
83 labels[p].emplace_back(a);
88 std::vector<std::vector<state_t> > list(1);
89 for(
auto s : aut->states() )
90 list[0].emplace_back(s);
92 for(
unsigned k=0;!list.empty();++k) {
93 std::vector<std::vector<state_t> > new_list;
96 std::vector<state_t> shorter_sig_list;
98 if(labels[
r].size()==k)
99 shorter_sig_list.emplace_back(
r);
101 tmplist[labels[
r][k]].emplace_back(
r);
103 if(!shorter_sig_list.empty())
104 states_in_part.push_back(std::move(shorter_sig_list));
105 for(
auto a : tmplist.
domain())
106 new_list.push_back(std::move(tmplist[a]));
142 template <
typename Aut>
143 void moore_det(
const Aut& aut, std::vector<std::vector<state_t> >& states_in_part) {
144 using automaton_t = Aut;
152 for(
auto s : aut->states())
153 for(
auto tr : aut->all_out(s) )
154 meet[aut->label_of(tr)].emplace_back(std::pair<state_t, state_t>{s,aut->dst_of(tr)});
156 for(
auto a:
meet.domain())
158 succs[p.first].emplace_back(p.second);
160 std::queue<unsigned> queue_part;
162 std::vector<unsigned> part(aut->max_state()+1);
163 for(
unsigned k=0; k< states_in_part.size(); ++k) {
164 for(
auto s:states_in_part[k])
166 if(states_in_part[k].size()>1)
167 queue_part.emplace(k);
173 queue_part.emplace(0);
176 while(!queue_part.empty()) {
178 unsigned i= queue_part.front();
187 queue_part.emplace(0);
198 std::vector<std::vector<state_t> > list;
199 std::vector<std::vector<state_t> > new_parts;
200 list.emplace_back(states_in_part[i]);
202 for(
unsigned k=0; !list.empty(); ++k) {
203 std::vector<std::vector<state_t> > new_list;
206 std::vector<state_t> shorter_sig_list;
208 if(succs[
r].size()==k)
209 shorter_sig_list.emplace_back(
r);
211 tmplist[part[succs[
r][k]]].emplace_back(
r);
213 if(!shorter_sig_list.empty())
214 new_parts.push_back(std::move(shorter_sig_list));
215 for(
auto a : tmplist.
domain())
216 new_list.push_back(std::move(tmplist[a]));
222 unsigned lim=new_parts.size();
227 queue_part.emplace(i);
231 unsigned np=states_in_part.size();
232 for(
unsigned k=0; k<lim;++k) {
236 states_in_part[i].swap(new_parts[0]);
240 for(
auto r : new_parts[k])
242 states_in_part.push_back(std::move(new_parts[k]));
244 if(states_in_part[p].size()>1)
245 queue_part.emplace(p);
255 template<
typename Aut,
typename Weightset>
258 static void init(
const Aut& aut,std::vector<std::vector<state_t> >& states_in_part, std::vector<unsigned>& part, std::queue<unsigned>& splitters, std::vector<bool>& is_in_queue) {
265 is_in_queue.push_back(
false);
267 for(
unsigned k=2; k< states_in_part.size(); ++k) {
268 for(
auto s:states_in_part[k])
270 if(states_in_part[k].size()>states_in_part[
max].size())
273 for(
unsigned k=1; k< states_in_part.size(); ++k) {
274 is_in_queue.push_back(k!=
max);
276 splitters.emplace(k);
282 template<
typename Aut>
284 static void init(
const Aut& aut,std::vector<std::vector<state_t> >& states_in_part, std::vector<unsigned>& part, std::queue<unsigned>& splitters, std::vector<bool>& is_in_queue) {
285 states_in_part.resize(3);
286 states_in_part[0].emplace_back(aut->pre());
287 states_in_part[1].emplace_back(aut->post());
290 for(
auto s: aut->states()) {
291 states_in_part[2].emplace_back(s);
294 is_in_queue.push_back(
false);
295 is_in_queue.push_back(
true);
296 is_in_queue.push_back(
true);
297 splitters.emplace(1);
298 splitters.emplace(2);
359 template <
typename Aut>
360 void hopcroft_det(
const Aut& aut, std::vector<std::vector<state_t> >& states_in_part) {
362 using automaton_t = Aut;
368 std::vector<unsigned> part(aut->max_state()+1);
369 std::queue<unsigned> splitters;
370 std::vector<bool> is_in_queue;
375 while(!splitters.empty()) {
377 unsigned i= splitters.front();
379 is_in_queue[i]=
false;
383 for(
auto s : states_in_part[i]) {
384 for(
auto tr : aut->all_in(s) ) {
387 meet[a].emplace_back(
r);
390 if(
meet.domain().empty())
400 for(
auto a :
meet.domain())
401 for(
auto r :
meet[a])
402 signature[
r].emplace_back(a);
413 for(
auto r : signature.
domain()) {
414 tmplist[part[
r]].emplace_back(
r);
417 for(
auto j : tmplist.
domain())
418 lists[j].push_back(std::move(tmplist[j]));
421 std::vector<std::vector<state_t> > new_list;
422 std::vector<state_t> shorter_sig_list;
423 for(
unsigned j: lists.
domain()) {
424 std::vector<std::vector<state_t>> list{std::move(lists[j])};
426 for(
unsigned k=0;!list.empty();++k) {
430 shorter_sig_list.clear();
432 if(signature[
r].size()==k)
433 shorter_sig_list.emplace_back(
r);
435 tmplist[signature[
r][k]].emplace_back(
r);
437 if(!shorter_sig_list.empty())
438 lists[j].push_back(std::move(shorter_sig_list));
439 for(
auto a : tmplist.
domain())
440 new_list.push_back(std::move(tmplist[a]));
445 for(
unsigned p: lists.
domain()) {
446 std::vector<std::vector<state_t> >& new_parts=lists[p];;
448 std::vector<state_t> unmet_states;
449 for(
auto r : states_in_part[p])
451 unmet_states.emplace_back(
r);
452 if(!unmet_states.empty())
453 new_parts.push_back(std::move(unmet_states));
455 unsigned lim=new_parts.size();
456 unsigned np=states_in_part.size();
458 states_in_part[p].swap(new_parts[0]);
459 for(
auto r : states_in_part[p])
461 for(
unsigned k=1; k<lim; ++k) {
462 for(
auto r : new_parts[k])
464 states_in_part.push_back(std::move(new_parts[k]));
465 splitters.emplace(np);
466 is_in_queue.push_back(
true);
474 for(
unsigned k=1; k<lim; ++k) {
475 if(new_parts[k].size() > new_parts[max_part].size())
477 if(new_parts[k].size() <= new_parts[min_part].size())
480 for(
unsigned k=0; k<lim;++k)
483 for(
auto r : new_parts[k])
485 states_in_part[p].swap(new_parts[k]);
488 splitters.emplace(p);
493 for(
auto r : new_parts[k])
495 states_in_part.push_back(std::move(new_parts[k]));
497 splitters.emplace(np);
498 is_in_queue.push_back(
true);
501 is_in_queue.push_back(
false);
The Boolean semring.
Definition: b.hh:38
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
void initialize_partition(const Aut &aut, std::vector< std::vector< state_t > > &states_in_part)
Definition: congruence_det.hh:58
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
auto meet(const ratexpset< Ctx1 > &a, const ratexpset< Ctx2 > &b) -> ratexpset< meet_t< Ctx1, Ctx2 >>
The meet of two ratexpsets.
Definition: ratexpset.hh:434
void moore_det(const Aut &aut, std::vector< std::vector< state_t > > &states_in_part)
Moore algorithm for the minimization of deterministic Boolean automata (DFA), not necessarily complet...
Definition: congruence_det.hh:143
void hopcroft_det(const Aut &aut, std::vector< std::vector< state_t > > &states_in_part)
minimization with Hopcroft for incomplete deterministic automata
Definition: congruence_det.hh:360
typename internal::weightset_t_of_impl< internal::base_t< ValueSet > >::type weightset_t_of
Helper to retrieve the type of the weightset of a value set.
Definition: traits.hh:86
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
static void init(const Aut &aut, std::vector< std::vector< state_t > > &states_in_part, std::vector< unsigned > &part, std::queue< unsigned > &splitters, std::vector< bool > &is_in_queue)
Definition: congruence_det.hh:284
Definition: congruence_det.hh:256
static void init(const Aut &aut, std::vector< std::vector< state_t > > &states_in_part, std::vector< unsigned > &part, std::queue< unsigned > &splitters, std::vector< bool > &is_in_queue)
Definition: congruence_det.hh:258
label_t_of< Aut > label_t
Definition: congruence_det.hh:48
static type getLabel(const Aut &aut, Tr tr)
Definition: congruence_det.hh:52
label_t type
Definition: congruence_det.hh:49
Definition: congruence_det.hh:36
static type getLabel(const Aut &aut, Tr tr)
Definition: congruence_det.hh:41
std::pair< label_t, typename Weightset::value_t > type
Definition: congruence_det.hh:38
label_t_of< Aut > label_t
Definition: congruence_det.hh:37
Definition: linkedhashmap.hh:31
const std::vector< K > & domain() const
Definition: linkedhashmap.hh:36
void clear()
Definition: linkedhashmap.hh:50