91 Move_Blue_or_Red_to_a_new_block_NewB_swap_3_29, max_counter), );
95 if (0 == --swapcount)
break;
118 Move_Blue_or_Red_to_a_new_block_NewB_pointer_3_29, max_counter), );
121 (*s_iter)->block = NewB;
169 Move_Blue_or_Red_to_a_new_block_NewB_swap_3_29, max_counter), );
173 if (0 == --swapcount)
break;
195 Move_Blue_or_Red_to_a_new_block_NewB_pointer_3_29, max_counter), );
198 (*s_iter)->block = NewB;
226 if (0 != end - begin)
229 << (1 < end-begin ?
"s:\n" :
":\n");
233 << (*begin)->debug_id();
234 if (B != (*begin)->block)
237 "points to " << (*begin)->block->debug_id();
239 if (begin != (*begin)->pos)
242 <<
", inconsistent pointer to state_info_entry";
246 while (++begin != end);
261 assert(C->begin() < C->end());
262 for (
const block_t* B = (*C->begin())->block; ; )
265 if (C != B->constln())
268 "points to " << B->constln()->debug_id();
271 print_block(
"Non-bottom state", B, B->nonbottom_begin(),
279 <<
"no transitions to its own constellation.\n";
280 assert(B->inert_begin() == B->inert_end());
284 assert(B->inert_end() ==
285 B->inert_end()[-1].B_to_C_slice->end);
286 assert(B->inert_end()[-1].B_to_C_slice->from_block() == B);
287 assert(B->inert_end()[-1].B_to_C_slice->to_constln() == C);
289 B->inert_end()[-1].B_to_C_slice->begin
290 <<
" transition(s) to its own constellation,\n\t\tof which "
291 << B->inert_end() - B->inert_begin()
292 << (1 == B->inert_end() - B->inert_begin()
293 ?
" is inert.\n" :
" are inert.\n");
296 if (C->end() == B->end())
break;
297 B = (*B->end())->
block;
301 C = (*C->end())->constln();
314 state_info.begin(); state_info_end != state_iter; ++state_iter)
318 if (state_iter->succ_end() != succ_constln_iter)
322 assert(state_iter->succ_begin() <=
323 state_iter->inert_succ_begin());
324 assert(state_iter->inert_succ_begin() <=
325 state_iter->inert_succ_end());
326 assert(state_iter->succ_begin()==state_iter->inert_succ_begin()
327 || *state_iter->inert_succ_begin()[-1].target->constln() <=
328 *state_iter->constln());
329 assert(state_iter->succ_begin()==state_iter->inert_succ_begin()
330 || state_iter->inert_succ_begin()[-1].target->block !=
332 assert(state_iter->inert_succ_begin() ==
333 state_iter->inert_succ_end() ||
334 (state_iter->inert_succ_begin()->target->block ==
336 state_iter->inert_succ_end()[-1].target->block ==
338 assert(state_iter->succ_end() == state_iter->inert_succ_end()||
339 *state_iter->constln() <
340 *state_iter->inert_succ_end()->target->constln());
345 << succ_constln_iter->target->constln()->debug_id()
351 for ( ;s_iter != succ_constln_iter ;++s_iter)
354 << s_iter->target->debug_id();
355 if (state_iter->inert_succ_begin() <= s_iter &&
356 s_iter < state_iter->inert_succ_end())
360 if (state_iter->current_constln() == s_iter)
363 <<
" <- current_constln";
366 assert(s_iter->B_to_C->pred->succ == s_iter);
367 assert(s_iter->B_to_C->pred->source == &*state_iter);
370 while (state_iter->succ_end() != succ_constln_iter);
371 if (state_iter->current_constln() == state_iter->succ_end())
374 <<
"\t\t<- current_constln\n";
392void part_trans_t::split_inert_to_C(block_t* const SpB)
395 if (SpB->inert_begin() == SpB->inert_end())
397 if (SpB->inert_end() != B_to_C.begin())
401 SpB->SetFromRed(SpB->inert_end()[-1].B_to_C_slice);
403 SpB->set_inert_begin(B_to_C.begin());
404 SpB->set_inert_end(B_to_C.begin());
410 if (slice->begin == SpB->inert_begin())
419 if(SpB->inert_begin() - slice->begin < slice->end - SpB->inert_begin())
422 SpB->to_constln.emplace_front(slice->begin, SpB->inert_begin());
423 new_slice = SpB->to_constln.begin();
424 assert(new_slice->from_block() == SpB);
425 slice->begin = SpB->inert_begin();
427 new_slice->work_counter = slice->work_counter;
432 Register_that_inert_transitions_from_s_go_to_NewC_B_to_C_2_17,
439 SpB->to_constln.emplace_back(SpB->inert_begin(), slice->end);
440 new_slice = std::prev(SpB->to_constln.end());
441 slice->end = SpB->inert_begin();
442 SpB->SetFromRed(slice);
444 new_slice->work_counter = slice->work_counter;
446 Register_that_inert_transitions_from_s_go_to_NewC_B_to_C_2_17,
451 for (
B_to_C_iter_t iter = new_slice->begin; new_slice->end != iter; ++iter)
453 assert(B_to_C.end() > iter); assert(iter->pred->succ->B_to_C == iter);
454 iter->B_to_C_slice = new_slice;
475 bool const first_transition_of_state,
bool const first_transition_of_block)
476{ assert(pred_iter<
pred.end()); assert(pred_iter->succ->B_to_C->pred==pred_iter);
480 B_to_C_iter_t const old_B_to_C_pos = pred_iter->succ->B_to_C;
482 B_to_C_iter_t const new_B_to_C_pos = old_B_to_C_slice->begin; assert(new_B_to_C_pos <
B_to_C.end());
483 B_to_C_desc_iter_t new_B_to_C_slice; assert(new_B_to_C_pos->pred->succ->B_to_C == new_B_to_C_pos);
484 if (first_transition_of_block)
487 block_t*
const RfnB = pred_iter->source->block;
488 RfnB->
to_constln.emplace_back(new_B_to_C_pos, new_B_to_C_pos);
489 new_B_to_C_slice = std::prev(RfnB->
to_constln.end());
491 new_B_to_C_slice->work_counter = old_B_to_C_slice->work_counter;
497 new_B_to_C_slice = new_B_to_C_pos[-1].B_to_C_slice;
499 ++new_B_to_C_slice->end;
500 ++old_B_to_C_slice->begin; assert(new_B_to_C_slice->end == old_B_to_C_slice->begin);
501 if (old_B_to_C_slice->begin == old_B_to_C_slice->end)
504 block_t*
const RfnB = pred_iter->source->block;
505 if (RfnB->
inert_end() == old_B_to_C_slice->begin)
510 } assert(RfnB->
to_constln.begin() == old_B_to_C_slice);
513 swap_B_to_C(pred_iter->succ, new_B_to_C_pos->pred->succ);
514 new_B_to_C_pos->B_to_C_slice = new_B_to_C_slice;
517 succ_iter_t const old_out_pos = pred_iter->succ; assert(
succ.end() > old_out_pos);
518 assert(old_out_pos->B_to_C->pred->succ == old_out_pos);
519 assert(*NewC < *SpC);
520 succ_iter_t const new_out_pos = old_out_pos->slice_begin();
521 swap_out(pred_iter, new_out_pos->B_to_C->pred);
523 old_slice_end > new_out_pos + 1)
528 old_slice_end[-1].set_slice_begin_or_before_end(new_out_pos + 1); assert(old_slice_end - 1 == new_out_pos->slice_begin_or_before_end());
530 { assert(old_slice_end - 1 == new_out_pos);
531 assert(old_slice_end-1==old_slice_end[-1].slice_begin_or_before_end());
533 if (first_transition_of_state)
535 new_out_pos->set_slice_begin_or_before_end(new_out_pos);
538 { assert(pred_iter->source->current_constln() == new_out_pos);
539 new_out_pos->set_slice_begin_or_before_end(
540 new_out_pos[-1].slice_begin_or_before_end());
542 return new_out_pos + 1;
560 succ_iter_t split = s->inert_succ_begin(), to_C_end = s->inert_succ_end(); assert(s->succ_begin() == to_C_end ||
561 to_C_end[-1].slice_begin_or_before_end() < to_C_end);
562 succ_iter_t to_C_begin = s->succ_begin() == to_C_end ? to_C_end
563 : to_C_end[-1].slice_begin_or_before_end();
567 bool result = to_C_begin <
split; assert(to_C_begin <=
split); assert(
split <= to_C_end);
569 assert(
succ.end() == to_C_end || to_C_end->B_to_C->pred->succ == to_C_end);
570 assert(
succ.end() == to_C_begin ||
571 to_C_begin->B_to_C->pred->succ == to_C_begin);
573 else if (
split < to_C_end)
579 assert(*NewC < *OldC);
582 split = to_C_end -
split + to_C_begin; assert(0 != swapcount);
590 Register_that_inert_transitions_from_s_go_to_NewC_swap_2_17,
592 pos1->target = pos2->target;
593 pos1->B_to_C = pos2->B_to_C;
594 pos1->B_to_C->pred->succ = pos1;
596 if (0 == --swapcount)
break;
597 pos2->target = pos1->target;
598 pos2->B_to_C = pos1->B_to_C;
599 pos2->B_to_C->pred->succ = pos2;
601 pos2->target = temp_target;
602 pos2->B_to_C = temp_B_to_C;
603 pos2->B_to_C->pred->succ = pos2;
606 *s->inert_succ_begin()[-1].target->constln() < *NewC);
607 assert(s->inert_succ_begin()->target->block == s->block);
608 assert(s->inert_succ_end()[-1].target->block == s->block);
609 assert(s->inert_succ_end() < s->succ_end());
610 assert(OldC == s->inert_succ_end()->target->constln());
611 to_C_end[-1].set_slice_begin_or_before_end(
split);
612 split[-1].set_slice_begin_or_before_end(to_C_begin);
616 Register_that_inert_transitions_from_s_go_to_NewC_succ_2_17,
618 assert(
succ.end() > succ_iter);
619 assert(succ_iter->B_to_C->pred->succ == succ_iter);
620 succ_iter->set_slice_begin_or_before_end(
split - 1);
623 else if (*to_C_begin->target->constln() > *NewC)
626 assert(to_C_begin->target->constln() == OldC);
627 s->set_inert_succ_begin_and_end(to_C_begin, to_C_begin); assert(s->succ_begin() == s->inert_succ_begin() ||
628 *s->inert_succ_begin()[-1].target->constln() < *NewC);
629 assert(s->succ_end() > s->inert_succ_end()); assert(to_C_end ==
split);
630 assert(OldC == s->inert_succ_end()->target->constln());
639 if (
succ_iter_t succ_iter = s->succ_begin(); succ_iter != s->succ_end())
643 assert(succ_iter->B_to_C->pred->source == s);
645 while (++succ_iter != s->succ_end());
646 assert(s->succ_begin() == s->inert_succ_begin() ||
647 *s->inert_succ_begin()[-1].target->constln() < *NewC);
648 assert(s->inert_succ_begin() == s->inert_succ_end() ||
649 (s->inert_succ_begin()->target->block == s->block &&
650 s->inert_succ_end()[-1].target->block == s->block));
651 assert(s->inert_succ_end() == s->succ_end() ||
652 *NewC < *s->inert_succ_end()->
target->constln());
674 Move_Blue_or_Red_to_a_new_block_states_3_29, max_counter), );
678 for (
succ_iter_t succ_iter = (*s_iter)->succ_begin();
679 (*s_iter)->succ_end() != succ_iter; ++succ_iter)
681 Move_Blue_or_Red_to_a_new_block_succ_3_29, max_counter), );
682 assert(
succ.end()>succ_iter); assert(succ_iter->B_to_C->pred->succ==succ_iter);
686 assert(old_pos->pred->succ->B_to_C == old_pos);
687 assert(
B_to_C.end() == after_new_pos ||
688 after_new_pos->pred->succ->B_to_C == after_new_pos);
690 if (
B_to_C.end() == after_new_pos ||
691 after_new_pos->pred->source->block != NewB ||
692 after_new_pos->pred->succ->target->
constln() !=
693 succ_iter->target->constln())
698 if (!old_B_to_C_slice->needs_postprocessing())
718 NewB->
to_constln.emplace_back(after_new_pos,after_new_pos);
719 new_B_to_C_slice = std::prev(NewB->
to_constln.end());
722 new_B_to_C_slice->work_counter = old_B_to_C_slice->work_counter;
735 new_B_to_C_slice = after_new_pos->B_to_C_slice;
737 --new_B_to_C_slice->begin;
738 --old_B_to_C_slice->end; assert(new_B_to_C_slice->begin == old_B_to_C_slice->end);
740 assert(new_pos->pred->succ->B_to_C == new_pos);
754 new_B_to_C_slice->begin->pred->succ);
766 if (old_B_to_C_slice->begin == old_B_to_C_slice->end)
782 if (old_B_to_C_slice->begin == old_B_to_C_slice->end)
787 new_pos->B_to_C_slice = new_B_to_C_slice;
793 (RfnB->
inert_end()[-1].pred->source->block != RfnB ||
794 RfnB->
inert_end()[-1].pred->succ->target->constln()
797 assert(0 &&
"The old block has no transitions to its own "
798 "constellation, but its inert_begin and "
799 "inert_end pointers are not set to B_to_C.begin()");
803 assert(RfnB->
inert_end()[-1].pred->source->block == RfnB);
804 assert(RfnB->
inert_end()[-1].pred->succ->target->constln() ==
809 (NewB->
inert_end()[-1].pred->source->block != NewB ||
810 NewB->
inert_end()[-1].pred->succ->target->constln()
813 assert(0 &&
"The new block has no transitions to its own "
814 "constellation, but its inert_begin and "
815 "inert_end pointers are not set to B_to_C.begin()");
819 assert(NewB->
inert_end()[-1].pred->source->block == NewB);
820 assert(NewB->
inert_end()[-1].pred->succ->target->constln() ==
838 block_t*
const NewB,
bool const postprocessing)
841 bool old_fromred_invalid =
false;
846 Move_Blue_or_Red_to_a_new_block_states_3_29, max_counter), );
850 for (
succ_iter_t succ_iter = (*s_iter)->succ_begin();
851 (*s_iter)->succ_end() != succ_iter; ++succ_iter)
853 Move_Blue_or_Red_to_a_new_block_succ_3_29, max_counter), );
854 assert(
succ.end()>succ_iter); assert(succ_iter->B_to_C->pred->succ==succ_iter);
857 B_to_C_iter_t new_pos = old_B_to_C_slice->begin; assert(
B_to_C.end() > old_pos); assert(old_pos->pred->succ->B_to_C == old_pos);
858 assert(
B_to_C.end() > new_pos); assert(new_pos->pred->succ->B_to_C == new_pos);
860 if (
B_to_C.begin() == new_pos ||
861 new_pos[-1].pred->source->block != NewB ||
862 new_pos[-1].pred->succ->target->
constln() !=
863 succ_iter->target->constln())
868 if (!postprocessing ? !old_fromred_invalid &&
870 : !old_B_to_C_slice->needs_postprocessing())
880 NewB->
to_constln.emplace_front(new_pos, new_pos);
894 NewB->
to_constln.emplace_back(new_pos, new_pos);
895 new_B_to_C_slice = std::prev(NewB->
to_constln.end());
898 new_B_to_C_slice->work_counter = old_B_to_C_slice->work_counter;
900 if (RfnB->
inert_end() == old_B_to_C_slice->end)
911 new_B_to_C_slice = new_pos[-1].B_to_C_slice;
913 ++new_B_to_C_slice->end;
914 ++old_B_to_C_slice->begin; assert(new_B_to_C_slice->end == old_B_to_C_slice->begin);
915 if (RfnB->
inert_end() == old_B_to_C_slice->end)
939 if (old_B_to_C_slice->begin == old_B_to_C_slice->end)
946 if (!old_fromred_invalid &&
949 old_fromred_invalid =
true;
960 if (old_B_to_C_slice->begin == old_B_to_C_slice->end)
962 if (!old_fromred_invalid &&
965 old_fromred_invalid =
true;
970 new_pos->B_to_C_slice = new_B_to_C_slice;
976 (RfnB->
inert_end()[-1].pred->source->block != RfnB ||
977 RfnB->
inert_end()[-1].pred->succ->target->constln()
980 assert(0 &&
"The old block has no transitions to its own "
981 "constellation, but its inert_begin and "
982 "inert_end pointers are not set to B_to_C.begin()");
986 assert(RfnB->
inert_end()[-1].pred->source->block == RfnB);
987 assert(RfnB->
inert_end()[-1].pred->succ->target->constln() ==
992 (NewB->
inert_end()[-1].pred->source->block != NewB ||
993 NewB->
inert_end()[-1].pred->succ->target->constln()
996 assert(0 &&
"The new block has no transitions to its own "
997 "constellation, but its inert_begin and "
998 "inert_end pointers are not set to B_to_C.begin()");
1002 assert(NewB->
inert_end()[-1].pred->source->block == NewB);
1003 assert(NewB->
inert_end()[-1].pred->succ->target->constln() ==
1021 #ifdef PARANOID_CHECK
1022 std::vector<state_info_const_ptr> part_st_predecessors;
1027 state_type nr_of_nontrivial_constellations = 0;
1033 ++nr_of_nontrivial_constellations;
1036 assert(
nullptr != C);
1055 assert(B->
end() == C->
end());
1060 assert(B->
end() < C->
end());
1061 --nr_of_nontrivial_constellations;
1081 #ifdef PARANOID_CHECK
1082 state_type nr_of_inert_predecessors=nr_of_inert_successors;
1097 assert(part_st_predecessors.empty());
1104 nr_of_inert_predecessors -=
1112 assert(pred_iter->succ->B_to_C->B_to_C_slice->
1114 assert(pred_iter->succ->B_to_C->B_to_C_slice->
1116 assert(pred_iter->succ->target == s);
1124 assert(
pred->block == B);
1130 part_st_predecessors.push_back(
pred);
1137 while(++s_iter < B->bottom_end());
1144 for (std::vector<state_info_const_ptr>::iterator s_iter =
1145 part_st_predecessors.begin();
1146 s_iter < part_st_predecessors.end(); ++s_iter)
1149 nr_of_inert_predecessors -=
1157 assert(pred_iter->succ->B_to_C->B_to_C_slice->
1159 assert(pred_iter->succ->B_to_C->B_to_C_slice->
1161 assert(pred_iter->succ->target == s);
1169 assert(
pred->block == B);
1175 part_st_predecessors.push_back(
pred);
1182 assert(part_st_predecessors.size() == (std::size_t)
1184 part_st_predecessors.clear();
1185 assert(0 == nr_of_inert_predecessors);
1190 bool to_own_constln =
false;
1194 assert(iter->from_block() == B);
1198 if (iter->to_constln() == C)
1200 assert(!to_own_constln);
1201 to_own_constln =
true;
1206 if (!to_own_constln)
1214 s_iter = B->
begin();
1219 assert(s->
pos == s_iter);
1220 assert(s->
block == B);
1243 succ_iter->slice_begin_or_before_end();
1245 assert(succ_iter < slice_end);
1246 assert(before_end->slice_begin_or_before_end() ==
1249 succ_iter->target->constln();
1257 for (; succ_iter < slice_end; ++succ_iter)
1261 assert(succ_iter->target->block != B);
1262 assert(succ_iter->target->constln()==targetC);
1263 if (succ_iter != before_end)
1266 slice_begin_or_before_end()==before_end);
1270 assert(succ_iter->B_to_C->B_to_C_slice->
1272 assert(succ_iter->B_to_C->B_to_C_slice->
1273 to_constln() == targetC);
1274 assert(succ_iter->B_to_C->pred->succ ==
1276 assert(succ_iter->B_to_C->pred->source == s);
1280 succ_iter->target->constln()->size()),
1282 ilog2(succ_iter->target->block->size()),
1292 succ_iter < slice_end; ++succ_iter)
1296 assert(succ_iter->target->block == B);
1297 if (succ_iter != before_end)
1299 assert(before_end == succ_iter->
1300 slice_begin_or_before_end());
1304 assert(succ_iter->B_to_C < B->
inert_end());
1305 assert(succ_iter->B_to_C->B_to_C_slice->
1307 assert(succ_iter->B_to_C->B_to_C_slice->
1308 to_constln() == targetC);
1309 assert(succ_iter->B_to_C->pred->succ ==
1311 assert(succ_iter->B_to_C->pred->source==s);
1313 no_temporary_work(max_B,
1314 max_C, max_B,
false), );
1321 --nr_of_reachable_constlns;
1324 if (s->
succ_end() <= succ_iter)
break;
1325 assert(0 != nr_of_reachable_constlns);
1326 assert(*targetC < *succ_iter->
target->constln());
1330 if (s_iter < B->bottom_begin())
1333 nr_of_inert_successors -=
1339 assert(0 != nr_of_reachable_constlns);
1341 #ifdef PARANOID_CHECK
1353 nr_of_reachable_constlns);
1369 assert(pred_iter->succ->B_to_C->B_to_C_slice->
1371 assert(pred_iter->succ->B_to_C->B_to_C_slice->
1373 assert(pred_iter->succ->target == s);
1374 assert(pred_iter->source->block != B);
1377 #ifndef PARANOID_CHECK
1383 assert(pred_iter->succ->B_to_C->B_to_C_slice->
1385 assert(pred_iter->succ->B_to_C->B_to_C_slice->
1387 assert(pred_iter->succ->target == s);
1388 assert(pred_iter->source->block == B);
1395 while (++s_iter < B->end());
1396 assert(0 == nr_of_inert_successors);
1398 if (B->
end() == C->
end())
break;
1399 assert(B->
end() < C->
end());
1400 assert(B->
end() == (*B->
end())->block->begin());
1401 B = (*B->
end())->block;
1406 assert(C->
end() == (*C->
end())->constln()->begin());
1407 C = (*C->
end())->constln();
1409 assert(0 == nr_of_nontrivial_constellations);
1414template<
class LTS_TYPE>
1417 bool const preserve_divergence)
1419 nr_of_states(l.num_states()),
1420 orig_nr_of_states(l.num_states()),
1421 nr_of_transitions(l.num_transitions()),
1422 noninert_out_per_state(l.num_states(), 0),
1423 inert_out_per_state(l.num_states(), 0),
1424 noninert_in_per_state(l.num_states(), 0),
1425 inert_in_per_state(l.num_states(), 0),
1426 noninert_out_per_block(1, 0),
1427 inert_out_per_block(1, 0),
1428 states_per_block(1, l.num_states()),
1429 nr_of_nonbottom_states(0)
1434 << (preserve_divergence ?
"Divergence preserving b" :
"B")
1435 << (branching ?
"ranching b" :
"")
1436 <<
"isimulation partitioner created for " << l.num_states()
1437 <<
" states and " << l.num_transitions()
1438 <<
" transitions [GJKW 2017]\n";
1442 if (!branching || !
aut.is_tau(
aut.apply_hidden_label_map(t.label())) ||
1443 (preserve_divergence && t.from() == t.to()))
1446 Key const k(
aut.apply_hidden_label_map(t.label()), t.to());
1450 if (extra_state.second)
1458 std::pair<std::unordered_map<label_type, state_type>::iterator,
1460 std::make_pair(
aut.apply_hidden_label_map(t.label()),
1462 if (action_block.second)
1500template<
class LTS_TYPE>
1503 bool const branching,
bool const preserve_divergence)
1504{ assert(part_st.
state_size() == get_nr_of_states());
1505 assert(part_tr.
trans_size() == get_nr_of_transitions());
1510 if (1 < states_per_block.size())
1514 std::vector<block_t*> blocks(states_per_block.size());
1516 for (
state_type B = 0; B < states_per_block.size(); ++B)
1519 blocks[B] =
new block_t(constln, begin, end);
1520 if (0 == noninert_out_per_block[B] && 0 == inert_out_per_block[B])
1522 blocks[B]->set_inert_begin_and_end(part_tr.
B_to_C.begin(),
1523 part_tr.
B_to_C.begin()); assert(blocks[B]->to_constln.empty());
1527 blocks[B]->set_inert_begin_and_end(B_to_C_begin +
1528 noninert_out_per_block[B],
1529 B_to_C_begin + noninert_out_per_block[B] +
1530 inert_out_per_block[B]);
1531 blocks[B]->to_constln.emplace_back(B_to_C_begin,
1532 blocks[B]->inert_end());
1534 std::prev(blocks[B]->to_constln.end()); assert(B_to_C_begin < slice->end);
1535 for (; slice->end != B_to_C_begin; ++B_to_C_begin)
1537 B_to_C_begin->B_to_C_slice = slice;
1542 assert(part_tr.
B_to_C.end() == B_to_C_begin);
1543 blocks[0]->assign_seqnr();
1544 blocks[0]->set_bottom_begin(blocks[0]->begin() + nr_of_nonbottom_states);
1545 blocks[0]->set_marked_nonbottom_begin(blocks[0]->bottom_begin());
1550 for (
state_type s = 0; get_nr_of_states() != s; ++s)
1553 noninert_in_per_state[s] + inert_in_per_state[s]);
1555 pred_begin() + noninert_in_per_state[s]);
1561 noninert_out_per_state[s] + inert_out_per_state[s];
1562 part_st.
state_info[s].set_succ_end(succ_end);
1563 part_st.
state_info[s].set_current_constln(succ_end);
1564 part_st.
state_info[s].set_inert_succ_begin_and_end(part_st.
1565 state_info[s].succ_begin() + noninert_out_per_state[s], succ_end);
1566 if (succ_iter < succ_end)
1569 for (; succ_iter < succ_end; ++succ_iter)
1571 succ_iter->set_slice_begin_or_before_end(succ_end);
1572 } assert(succ_iter == succ_end);
1573 succ_end->set_slice_begin_or_before_end(
1575 }
else assert(succ_end == succ_iter);
1576 if (s < aut.num_states())
1580 if (0 != inert_out_per_state[s])
1582 assert(0 != nr_of_nonbottom_states);
1583 --nr_of_nonbottom_states;
1584 part_st.
state_info[s].pos = blocks[0]->begin() +
1585 nr_of_nonbottom_states;
1591 assert(0 != states_per_block[0]);
1592 --states_per_block[0];
1593 part_st.
state_info[s].pos = blocks[0]->begin() +
1594 states_per_block[0]; assert(part_st.
state_info[s].pos >= blocks[0]->bottom_begin());
1602 for (
const transition& t: aut.get_transitions())
1604 if (!branching || !aut.is_tau(aut.apply_hidden_label_map(t.label())) ||
1605 (preserve_divergence && t.from() == t.to()))
1608 Key const k(aut.apply_hidden_label_map(t.label()), t.to());
1609 state_type const extra_state = extra_kripke_states[k];
1610 if (0 != noninert_out_per_state[extra_state])
1613 action_block_map[aut.apply_hidden_label_map(t.label())];
1615 part_st.
state_info[extra_state].block = blocks[extra_block]; assert(0 != states_per_block[extra_block]);
1616 --states_per_block[extra_block];
1617 part_st.
state_info[extra_state].pos = blocks[extra_block]->
1618 begin() + states_per_block[extra_block];
1625 assert(0 != noninert_in_per_state[t.to()]);
1626 --noninert_in_per_state[t.to()];
1628 part_st.
state_info[t.to()].noninert_pred_begin() +
1629 noninert_in_per_state[t.to()];
1630 --noninert_out_per_state[extra_state]; assert(0 == noninert_out_per_state[extra_state]);
1632 part_st.
state_info[extra_state].succ_begin(); assert(0 != noninert_out_per_block[extra_block]);
1634 blocks[extra_block]->inert_begin() -
1635 noninert_out_per_block[extra_block]--;
1636 t_pred->source = &part_st.
state_info[extra_state];
1637 t_pred->succ = t_succ;
1638 t_succ->target = &part_st.
state_info[t.to()];
1639 t_succ->B_to_C = t_B_to_C;
1641 t_B_to_C->pred = t_pred;
1643 assert(0 != noninert_in_per_state[extra_state]);
1644 --noninert_in_per_state[extra_state];
1646 part_st.
state_info[extra_state].noninert_pred_begin() +
1647 noninert_in_per_state[extra_state]; assert(0 != noninert_out_per_state[t.from()]);
1648 --noninert_out_per_state[t.from()];
1650 noninert_out_per_state[t.from()]; assert(0 != noninert_out_per_block[0]);
1652 noninert_out_per_block[0]--;
1654 t_pred->source = &part_st.
state_info[t.from()];
1655 t_pred->succ = t_succ;
1656 t_succ->target = &part_st.
state_info[extra_state];
1657 t_succ->B_to_C = t_B_to_C;
1659 t_B_to_C->pred = t_pred;
1663 assert(0 != inert_in_per_state[t.to()]);
1664 --inert_in_per_state[t.to()];
1666 part_st.
state_info[t.to()].inert_pred_begin() +
1667 inert_in_per_state[t.to()]; assert(0 != inert_out_per_state[t.from()]);
1668 --inert_out_per_state[t.from()];
1670 part_st.
state_info[t.from()].inert_succ_begin() +
1671 inert_out_per_state[t.from()]; assert(0 != inert_out_per_block[0]);
1672 --inert_out_per_block[0];
1674 inert_out_per_block[0];
1676 t_pred->source = &part_st.
state_info[t.from()];
1677 t_pred->succ = t_succ;
1678 t_succ->target = &part_st.
state_info[t.to()];
1679 t_succ->B_to_C = t_B_to_C;
1681 t_B_to_C->pred = t_pred;
1684 noninert_out_per_state.clear(); inert_out_per_state.clear();
1685 noninert_in_per_state.clear(); inert_in_per_state.clear();
1686 noninert_out_per_block.clear(); inert_out_per_block.clear();
1687 states_per_block.clear();
1689 aut.clear_transitions();
1692 << get_nr_of_states() <<
" states and "
1693 << get_nr_of_transitions() <<
" transitions.\n";
1712template <
class LTS_TYPE>
1715 const bool preserve_divergence)
1717 std::unordered_map <state_type, Key> to_lts_map;
1719 for (
typename std::unordered_map<Key, state_type, KeyHasher>::iterator it =
1720 extra_kripke_states.begin(); it != extra_kripke_states.end(); ++it)
1722 to_lts_map.insert(std::make_pair(it->second, it->first));
1724 extra_kripke_states.clear();
1726 label_type const tau_label = aut.tau_label_index();
1733 block_t *B = (*s_iter)->block;
1744 (*s_iter)->succ_end() != succ_iter; )
1746 if (
state_type t_eq = succ_iter->target->block->seqnr();
1748 { assert(branching);
1753 if (!preserve_divergence)
1761 if (*s_iter != succ_iter->target)
1769 aut.add_transition(
transition(s_eq, tau_label, t_eq));
1773 state_type const tgt_id = succ_iter->target -
1778 Key const k = to_lts_map.find(tgt_id)->
second;
1783 assert(&part_st.
state_info[k.
second]==succ_iter->target->succ_begin()->target);
1784 assert(1 == succ_iter->target->succ_end() - succ_iter->target->succ_begin());
1796 if (aut.has_state_info())
1801 for(std::size_t i=aut.num_states(); i>0; )
1804 const std::size_t new_index=part_st.
block(i)->
seqnr();
1805 new_labels[new_index] = new_labels[new_index] + aut.state_label(i);
1811 aut.set_state_label(i,new_labels[i]);
1819 aut.set_initial_state(part_st.
block(aut.initial_state())->
seqnr());
1832template <
class LTS_TYPE>
1834 bool const branching,
bool const preserve_divergence)
1839 init_helper.init_transitions(part_st, part_tr, branching,
1840 preserve_divergence);
1844template <
class LTS_TYPE>
1851 part_st.print_part(part_tr);
1852 part_st.print_trans();
1855 part_tr.assert_stability(part_st);
1858 while (
nullptr != bisim_gjkw::constln_t::get_some_nontrivial())
1861 bisim_gjkw::constln_t::get_some_nontrivial();
1872 unsigned const max_counter = check_complexity::log_n -
1873 check_complexity::ilog2(SpB->
size());
1876 while_C_contains_a_nontrivial_constellation_2_4, max_counter), );
1877 assert(
nullptr == bisim_gjkw::block_t::get_some_refinable());
1883 part_tr.split_inert_to_C(SpB);
1886 add_work(check_complexity::for_all_s_in_SpB_2_10, max_counter), );
1889 SpB->
begin() != s_iter; )
1897 check_complexity::for_all_s_prime_in_pred_s_2_11, max_counter), );
1898 assert(part_tr.pred_end() > pred_iter);
1899 assert(pred_iter->succ->B_to_C->pred == pred_iter);
1902 bool const first_transition_of_block =
1905 bool const first_transition_of_state =
1911 first_transition_of_state, first_transition_of_block));
1932 SpB->
end() != s_iter; ++s_iter)
1940 pred_iter->source->current_constln() - 1;
1941 if (succ != before_end)
1942 { assert(succ<before_end); assert(succ>=before_end->slice_begin_or_before_end());
1943 assert(succ->slice_begin_or_before_end() ==
1944 before_end->slice_begin_or_before_end());
1945 succ->set_slice_begin_or_before_end(before_end);
1953 SpB->
end() != s_iter; ++s_iter)
1964 *SpC <= *s_prime->current_constln()->
target->constln());
1998 if (1 == SpB->
size())
2010 postprocess_new_bottom(RedB);
2020 while (
nullptr != bisim_gjkw::block_t::get_some_refinable())
2023 bisim_gjkw::block_t::get_some_refinable();
2035 assert(s_mark_iter < RfnB->marked_nonbottom_end());
2040 std::prev((*s_mark_iter)->current_constln());
2041 assert((*s_mark_iter)->succ_begin() <= to_NewC);
2042 assert(to_NewC->target->constln() == NewC);
2044 check_complexity::for_all_refinable_blocks_RfnB_2_20, max_counter), );
2046 if (1 == RfnB->
size())
2061 RedB = postprocess_new_bottom(RedB);
2062 if (
nullptr == RedB)
continue;
2073 if (1 == RedB->
size() ||
nullptr == RedB->
FromRed(SpC))
2089 postprocess_new_bottom(RedB);
2104 part_st.print_part(part_tr);
2105 part_st.print_trans();
2108 part_tr.assert_stability(part_st);
2115 << bisim_gjkw::block_t::nr_of_blocks <<
'\n';
2118 namespace bisim_gjkw
2138 assert(
nullptr != RedB);
2139 if (
nullptr != BlueB)
2141 assert(BlueB->
size() <= RedB->
size());
2142 unsigned const max_NewB =
nullptr == BlueB ? 0
2148 while_Test_is_not_empty_3_6l_s_is_blue_3_11l,
2152 while_Blue_contains_unvisited_states_3_15l,
2160 if___s_prime_has_transition_to_SpC_3_23l,
2168 for_all_s_prime_in_pred_s_setminus_Red_3_18l,
2176 unsigned const max_NewC =
nullptr == NewC ? 0
2182 while_Red_contains_unvisited_states_3_15r), );
2192 while_Test_is_not_empty_3_6l_s_is_red_3_9l,
2195 succ->target->constln() == NewC ? max_NewC : 0), );
2200 while_Test_is_not_empty_3_6l_s_is_red_3_9l_postprocessing,
2210 refine_outgoing_transition_from_new_bottom_3_23l, 1), );
2215 for_all_s_prime_in_pred_s_3_18r), );
2231 assert(
nullptr != BlueB);
2232 assert(
nullptr != RedB);
2233 assert(BlueB->
size() >= RedB->
size());
2238 while_Test_is_not_empty_3_6l_s_is_blue_3_11l), );
2240 while_Blue_contains_unvisited_states_3_15l), );
2245 if___s_prime_has_transition_to_SpC_3_23l), );
2250 for_all_s_prime_in_pred_s_setminus_Red_3_18l), );
2259 while_Red_contains_unvisited_states_3_15r,
2266 refine_outgoing_transition_3_6_or_23l, max_NewB), );
2269 while_Test_is_not_empty_3_6l_s_is_red_3_9l), );
2272 while_Test_is_not_empty_3_6l_s_is_red_3_9l_postprocessing), );
2275 if___s_prime_has_transition_to_SpC_3_23l), );
2280 for_all_s_prime_in_pred_s_3_18r,
2360template <
class LTS_TYPE>
2368 if (
nullptr != FromRed)
2372 assert(
nullptr != SpC);
2379 assert(1 < RfnB->
size());
2402 bool FromRed_is_empty =
nullptr == FromRed;
2420 (REFINE_BLUE_TESTING)
2421 (REFINE_BLUE_STATE_HANDLED)
2422 (REFINE_BLUE_COLLECT_BOTTOM)
2423 (REFINE_RED_COLLECT_FROMRED)
2424 (REFINE_RED_PREDECESSOR_HANDLED)
2425 (REFINE_RED_STATE_HANDLED))
2482 if (FromRed_is_empty)
2499 blue_s = *blue_visited_end;
2508 bisim_gjkw::swap_permutation(blue_visited_end,
2526 if (to_SpC == blue_s->
succ_end() || to_SpC->target->constln() != SpC)
2530 assert(to_SpC->target->constln() == SpC);
2532 bisim_gjkw::succ_entry::slice_add_work_to_transns(to_SpC,
2534 while_Test_is_not_empty_3_6l_s_is_red_3_9l_postprocessing, 1);
2543 if (to_NewC == blue_s->
succ_end() || to_NewC->target->constln() == SpC)
2547 assert(to_NewC->target->constln() != SpC);
2549 bisim_gjkw::succ_entry::slice_add_work_to_transns(to_NewC,
2550 check_complexity::while_Test_is_not_empty_3_6l_s_is_red_3_9l, 1);
2565 check_complexity::while_Test_is_not_empty_3_6l_s_is_blue_3_11l, 1), );
2578 RedB = RfnB;
ONLY_IF_DEBUG( blue_is_smaller(
nullptr, RedB, NewC); )
2588 blue_visited_end != blue_blue_nonbottom_end)
2591 blue_s = *blue_visited_end; assert(blue_visited_end < blue_blue_nonbottom_end ||
2595 assert(blue_blue_nonbottom_end <= notblue_initialised_end);
2603 blue_s_prime = blue_pred_iter->source;
2606 check_complexity::for_all_s_prime_in_pred_s_setminus_Red_3_18l, 1), );
2610 if (blue_s_prime->
pos >= notblue_initialised_end)
2615 bisim_gjkw::swap_permutation(blue_s_prime->
pos,
2616 notblue_initialised_end);
2617 ++notblue_initialised_end;
2623 if (0 != blue_s_prime->
notblue)
2625 check_complexity::for_all_s_prime_in_pred_s_setminus_Red_3_18l, 1), );
2630 if (!FromRed_is_empty)
2634 check_complexity::for_all_s_prime_in_pred_s_setminus_Red_3_18l, 1), );
2644 blue_end = blue_s_prime->
succ_end() ),
2645 blue_begin < blue_end, (
void) 0)
2650 blue_begin + (blue_end - blue_begin) / 2;
2651 if (*SpC <= *mid->
target->constln())
2653 blue_end = mid->slice_begin();
2655 if (*mid->target->constln() <= *SpC)
2658 bisim_gjkw::succ_entry::slice_end(mid);
2661 bisim_gjkw::succ_entry::slice_add_work_to_transns(mid,
2662 check_complexity::if___s_prime_has_transition_to_SpC_3_23l, 1);
2666 if (blue_begin != blue_end)
2668 check_complexity::for_all_s_prime_in_pred_s_setminus_Red_3_18l, 1), );
2674 bisim_gjkw::swap_permutation(blue_s_prime->
pos,
2675 blue_blue_nonbottom_end);
2676 ++blue_blue_nonbottom_end;
2678 if (blue_blue_nonbottom_end -
2687 check_complexity::for_all_s_prime_in_pred_s_setminus_Red_3_18l, 1), );
2691 check_complexity::while_Blue_contains_unvisited_states_3_15l, 1), );
2709 part_tr.new_blue_block_created(RfnB, NewB);
2711 unsigned const max_counter = check_complexity::log_n -
2712 check_complexity::ilog2(NewB->
size());
2714 add_work(check_complexity::for_all_s_in_NewB_3_31, max_counter), );
2718 NewB->
end() != s_iter; ++s_iter)
2725 check_complexity::for_all_s_prime_in_pred_s_3_32l, max_counter), );
2726 assert(part_tr.pred_end() > blue_pred_iter);
2727 assert(blue_pred_iter->succ->B_to_C->pred == blue_pred_iter);
2728 blue_s_prime = blue_pred_iter->source;
2729 if (blue_s_prime->
block == NewB) {
continue; } assert(blue_s_prime->
block == RfnB);
2731 part_tr.make_noninert(blue_pred_iter->succ);
2740 swap_permutation(blue_s_prime->
pos,
2749 RedB = RfnB;
ONLY_IF_DEBUG( blue_is_smaller(NewB, RedB, NewC); )
2794 if (
nullptr != FromRed)
2796 red_fromred_visited_begin = FromRed->
end; assert(RfnB->
inert_end() <= FromRed->
begin ||
2797 (RfnB->
inert_begin() >= red_fromred_visited_begin &&
2798 RfnB->
inert_end() > red_fromred_visited_begin));
2800 FromRed->
begin != red_fromred_visited_begin)
2805 --red_fromred_visited_begin;
2808 red_fromred_visited_begin->pred->source; assert(RfnB->
begin() <= red_s->
pos);
2809 assert(red_s->
pos < RfnB->
end());
2812 if (red_s->
pos < notblue_initialised_end)
2817 bisim_gjkw::swap_permutation(red_s->
pos,
2818 --notblue_initialised_end);
2820 if (RfnB->
mark(red_s) &&
2827 add_work(check_complexity::while_FromRed_is_not_empty_3_6r, 1), );
2834 FromRed_is_empty =
true;
2835 } assert(FromRed_is_empty); assert(0 != RfnB->
marked_size());
2856 red_s = *red_visited_begin;
2863 red_pred_iter->source;
2865 if (s_prime->
pos < notblue_initialised_end)
2870 bisim_gjkw::swap_permutation(s_prime->
pos,
2871 --notblue_initialised_end);
2880 add_work(check_complexity::for_all_s_prime_in_pred_s_3_18r, 1), );
2884 check_complexity::while_Red_contains_unvisited_states_3_15r, 1), );
2901 part_tr.new_red_block_created(RfnB, RedB, postprocessing);
2903 unsigned const max_counter = check_complexity::log_n -
2904 check_complexity::ilog2(RedB->
size());
2906 add_work(check_complexity::for_all_s_in_NewB_3_31, max_counter), );
2921 check_complexity::for_all_s_prime_in_succ_s_3_32r, max_counter), );
2922 assert(part_tr.succ_end() > succ_iter);
2923 assert(succ_iter->B_to_C->pred->succ == succ_iter);
2926 s_prime->block == RedB)
2929 }
else assert(s_prime->block == RfnB);
2931 part_tr.make_noninert(succ_iter);
2944 } assert(RfnB->
end() < red_end);
2950 assert(RedB->
end() == red_end);
2984typedef std::set<bisim_gjkw::constln_t*, constln_ptr_less>
R_map_t;
3003template <
class LTS_TYPE>
3022 ResultB = refine(RedB,
nullptr,
nullptr,
false); assert(
nullptr != ResultB); assert(0 == ResultB->
unmarked_bottom_size());
3026 RfnB = ResultB->
begin()[-1]->block;
3032 } assert(ResultB != RfnB); assert(RfnB->
begin() == blue_begin);
3034 if (1 == RfnB->
size())
3042 while (!RfnB->
to_constln.front().needs_postprocessing())
3048 for_all_transitions_from_bottom_states_a_priori_4_4, 1))
3053 for_all_constellations_C_not_in_R_from_RfnB_4_4, 1), );
3058 if (!R.insert(C).second)
3059 { assert(0 &&
"The constellation already was in R");
3075 add_work(check_complexity::for_all_bottom_states_s_in_RfnB_4_8, 1), );
3096 bisim_gjkw::block_t*
const B = B_iter->pred->source->block; assert(B_iter->pred->succ->B_to_C == B_iter);
3099 bool postproc_a_posteriori = !FromRed->
3101 for_all_transitions_that_need_postproc_a_priori_4_12, 1);
3108 { assert(FromRed->from_block() == B);
3114 { assert(!postproc_a_posteriori);
3116 if (0 != FromRed->work_counter.get_work_counter_4_4())
3119 for_all_transitions_from_bottom_states_a_posteriori_4_4, 1));
3120 FromRed->work_counter.reset_work_counter_4_4();
3133 RedB = refine(B, SpC, &*FromRed,
true);
3135 FromRed = FromRed_save->succ->B_to_C->B_to_C_slice;
3136 if (postproc_a_posteriori && !FromRed->add_work_to_bottom_transns(
3138 for_all_transitions_that_need_postproc_a_posteriori_4_12, 1))
3140 assert(0 &&
"no new bottom states to assign work to");
3144 if (0 != FromRed->work_counter.get_work_counter_4_4())
3147 for_all_transitions_from_bottom_states_a_posteriori_4_4, 1))
3149 assert(0 &&
"no new bottom states to assign work to");
3151 FromRed->work_counter.reset_work_counter_4_4();
3166 bisim_gjkw::succ_entry::slice_add_work_to_transns(s->
current_constln(),
3167 check_complexity::for_all_old_bottom_states_s_in_RedB_4_15,1);
3173 for_all_old_bottom_states_s_in_RedB_selfloop_4_15, 1), );
3178 *SpC < *s->current_constln()->
target->constln());
3186 blue_begin = RedB->
begin();
3190 RedB = refine(RedB,
nullptr,
nullptr,
true); assert(
nullptr != RedB); assert(0 == RedB->
unmarked_bottom_size());
3194 RfnB = RedB->
begin()[-1]->block;
3202 } assert(RedB != RfnB);
3203 assert(RfnB->
begin() == blue_begin);
3205 if (1 == RfnB->
size())
3212 SpC->
postprocess_begin[-1].B_to_C_slice; assert(new_slice->from_block() == RfnB);
3213 assert(new_slice->to_constln() == SpC);
3249template class bisim_partitioner_gjkw_initialise_helper<lts_lts_t>;
3250template class bisim_partitioner_gjkw_initialise_helper<lts_aut_t>;
3251template class bisim_partitioner_gjkw_initialise_helper<lts_fsm_t>;
3255template class bisim_partitioner_gjkw<lts_lts_t>;
3256template class bisim_partitioner_gjkw<lts_aut_t>;
3257template class bisim_partitioner_gjkw<lts_fsm_t>;
#define mCRL2complexity(unit, call, info_for_debug)
Assigns work to a counter and checks for errors.
stores information about a block
stores information about a constellation
refinable partition data structure
stores information about a single state
implements the main algorithm for the stutter equivalence quotient
class for time complexity checks
static int ilog2(state_type size)
calculate the base-2 logarithm, rounded down
static unsigned char log_n
value of floor(log2(n)) for easy access
@ refine_incoming_transition_3_18
@ refine_outgoing_transition_to_marked_state_3_6l
@ refine_visited_state_3_15
@ if___s_prime_has_transition_to_SpC_3_23l
@ refine_outgoing_transition_postprocess_new_bottom_3_6l
@ refine_outgoing_transition_3_6_or_23l
@ refine_bottom_state_3_6l
@ while_FromRed_is_not_empty_3_6r
static void check_temporary_work()
check that not too much superfluous work has been done
static void init(state_type n)
starts counting for a new refinement run
function object to compare two constln_t pointers based on their contents
bool operator()(const bisim_gjkw::constln_t *a, const bisim_gjkw::constln_t *b) const
A class containing triples, source label and target representing transitions.
helper macros for coroutines
#define ABORT_THIS_COROUTINE()
indicates that this coroutine gives up control to the other one
#define END_COROUTINE
Ends the definition of code for a coroutine.
#define ABORT_OTHER_COROUTINE()
indicates that the other coroutine should give up control
#define COROUTINE_FOR(location, init, condition, update)
a for loop where every iteration incurs one unit of work
#define COROUTINE_WHILE(location, condition)
a while loop where every iteration incurs one unit of work
#define COROUTINES_SECTION
begin a section with two coroutines
#define COROUTINE_DO_WHILE(location, condition)
a do { } while loop where every iteration incurs one unit of work
#define END_COROUTINES_SECTION
Close a section containing coroutines.
#define COROUTINE
Define the code for a coroutine.
#define END_COROUTINE_WHILE
ends a loop started with COROUTINE_WHILE
#define END_COROUTINE_FOR
ends a loop started with COROUTINE_FOR
#define COROUTINE_LABELS(locations)
Declare the interrupt locations for the coroutines.
#define END_COROUTINE_DO_WHILE
ends a loop started with COROUTINE_DO_WHILE
#define TERMINATE_COROUTINE_SUCCESSFULLY()
terminate the pair of coroutines successfully
fixed_vector< B_to_C_entry > B_to_C
permutation_t permutation
permutation array
succ_iter_t change_to_C(pred_iter_t pred_iter, ONLY_IF_DEBUG(constln_t *SpC, constln_t *NewC,) bool first_transition_of_state, bool first_transition_of_block)
transition target is moved to a new constellation
permutation_const_iter_t end() const
iterator past the last state in the block
void set_inert_begin(B_to_C_iter_t new_inert_begin)
void assert_stability(const part_state_t &part_st) const
assert that the data structure is consistent and stable
const constln_t * to_constln() const
compute the goal constellation of the transitions in this slice
static state_type nr_of_blocks
total number of blocks with unique sequence number allocated
state_type unmarked_bottom_size() const
provides the number of unmarked bottom states in the block
void replace_transition_system(const part_state_t &part_st, ONLY_IF_DEBUG(bool branching,) bool preserve_divergence)
Replaces the transition relation of the current LTS by the transitions of the bisimulation-reduced tr...
bool split_s_inert_out(state_info_ptr s ONLY_IF_DEBUG(, constln_t *OldC))
Split outgoing transitions of a state in the splitter.
void set_marked_bottom_begin(permutation_iter_t new_marked_bottom_begin)
void SetFromRed(B_to_C_desc_iter_t new_fromred)
set FromRed to an existing element in to_constln
void make_nontrivial()
makes a constellation non-trivial (i. e. inserts it into the respective list)
permutation_const_iter_t nonbottom_begin() const
iterator to the first non-bottom state in the block
B_to_C_const_iter_t B_to_C_begin() const
pred_const_iter_t inert_pred_end() const
iterator one past the last inert incoming transition
const block_t * from_block() const
compute the source block of the transitions in this slice
block_t * split_off_small_block()
split off a single block from the constellation
B_to_C_iter_t postprocess_begin
iterator to the first transition into this constellation that needs postprocessing
B_to_C_iter_t B_to_C_end()
const constln_t * constln() const
get constellation where the state belongs
permutation_const_iter_t begin() const
iterator to the first state in the block
void swap_B_to_C(succ_iter_t const pos1, succ_iter_t const pos2)
bool surely_has_no_transition_to(const constln_t *SpC) const
void set_begin(permutation_iter_t new_begin)
permutation_const_iter_t marked_nonbottom_begin() const
iterator to the first marked non-bottom state in the block
permutation_iter_t pos
position of the state in the permutation array
static constln_t * nontrivial_first
first constellation in the list of non-trivial constellations
std::unordered_map< label_type, state_type > action_block_map
trans_type nr_of_transitions
permutation_const_iter_t end() const
constant iterator past the last state in the constellation
permutation_const_iter_t unmarked_bottom_begin() const
iterator to the first unmarked bottom state in the block
std::vector< state_type > inert_out_per_state
fixed_vector< pred_entry > pred
void set_inert_begin_and_end(B_to_C_iter_t new_inert_begin, B_to_C_iter_t new_inert_end)
B_to_C_const_iter_t inert_begin() const
iterator to the first inert transition of the block
void make_nonrefinable()
makes a block non-refinable (i. e. removes it from the respective list)
permutation_const_iter_t marked_bottom_begin() const
iterator to the first marked bottom state in the block
pred_const_iter_t noninert_pred_begin() const
iterator to first non-inert incoming transition
bool mark_nonbottom(state_info_ptr s)
mark a non-bottom state
permutation_const_iter_t bottom_begin() const
iterator to the first bottom state in the block
void swap_out(pred_iter_t const pos1, pred_iter_t const pos2)
state_type size() const
provides the number of states in the block
void init_transitions(part_state_t &part_st, part_trans_t &part_tr, bool branching, bool preserve_divergence)
initialise the state in part_st and the transitions in part_tr
block_t * split_off_blue(permutation_iter_t blue_nonbottom_end)
refine the block (the blue subblock is smaller)
permutation_const_iter_t marked_bottom_end() const
iterator past the last marked bottom state in the block
std::vector< state_type > inert_out_per_block
state_type notblue
number of inert transitions to non-blue states
permutation_const_iter_t marked_nonbottom_end() const
iterator one past the last marked non-bottom state in the block
const state_type sort_key
sort key to order constellation-related information
state_type marked_bottom_size() const
provides the number of marked bottom states in the block
std::vector< state_type > states_per_block
bool is_trivial() const
returns true iff the constellation is trivial
state_type nr_of_nonbottom_states
B_to_C_desc_list to_constln
list of B_to_C with transitions from this block
static succ_iter_t slice_end(succ_iter_t this_)
block_t * block
block where the state belongs
const constln_t * get_nontrivial_next() const
provides the next non-trivial constellation
void set_marked_nonbottom_begin(permutation_iter_t new_marked_nonbottom_begin)
static permutation_const_iter_t perm_begin
bool make_refinable()
makes a block refinable (i. e. inserts it into the respective list)
fixed_vector< state_info_entry > state_info
array with all other information about states
state_type state_size() const
provide size of state space
state_type size() const
returns number of states in the constellation
B_to_C_const_iter_t inert_end() const
iterator past the last inert transition of the block
const constln_t * constln() const
constellation where the block belongs to
permutation_const_iter_t bottom_end() const
iterator past the last bottom state in the block
static block_t * refinable_first
first block in the list of refinable blocks
succ_const_iter_t succ_begin() const
iterator to first outgoing transition
succ_const_iter_t current_constln() const
void new_red_block_created(block_t *OldB, block_t *NewB, bool postprocessing)
handle B_to_C slices after a new red block has been created
void set_end(permutation_iter_t new_end)
void print_trans() const
print all transitions
std::vector< state_type > inert_in_per_state
bool is_refinable() const
checks whether the block is refinable
block_t * split_off_red(permutation_iter_t red_nonbottom_begin)
refine the block (the red subblock is smaller)
succ_const_iter_t inert_succ_begin() const
iterator to first inert outgoing transition
permutation_const_iter_t begin() const
constant iterator to the first state in the constellation
void assign_seqnr()
assigns a unique sequence number
std::unordered_map< Key, state_type, KeyHasher > extra_kripke_states
void new_blue_block_created(block_t *OldB, block_t *NewB)
handle B_to_C slices after a new blue block has been created
static state_info_const_ptr s_i_begin
pointer at the first entry in the state_info array
static constln_t * get_some_nontrivial()
provides an arbitrary non-trivial constellation
permutation_const_iter_t unmarked_bottom_end() const
iterator past the last unmarked bottom state in the block
void set_bottom_begin(permutation_iter_t new_bottom_begin)
void set_inert_succ_begin_and_end(succ_iter_t new_inert_out_begin, succ_iter_t new_inert_out_end)
void swap3_B_to_C(succ_iter_t const pos1, succ_iter_t const pos2, succ_iter_t const pos3)
const block_t * block(state_type s) const
find block of a state
succ_const_iter_t inert_succ_end() const
iterator past the last inert outgoing transition
check_complexity::block_counter_t work_counter
std::vector< state_type > noninert_in_per_state
bisim_partitioner_gjkw_initialise_helper(LTS_TYPE &l, bool branching, bool preserve_divergence)
constructor of the helper class
pred_const_iter_t inert_pred_begin() const
iterator to first inert incoming transition
pred_const_iter_t noninert_pred_end() const
iterator past the last non-inert incoming transition
void set_inert_end(B_to_C_iter_t new_inert_end)
pred_const_iter_t pred_end() const
iterator past the last incoming transition
fixed_vector< succ_entry > succ
static state_info_const_ptr s_i_end
pointer past the last actual entry in the state_info array
permutation_const_iter_t unmarked_nonbottom_begin() const
iterator to the first unmarked non-bottom state in the block
permutation_const_iter_t nonbottom_end() const
iterator past the last non-bottom state in the block
succ_const_iter_t succ_end() const
iterator past the last outgoing transition
B_to_C_descriptor * FromRed(const constln_t *SpC)
read FromRed
std::vector< state_type > noninert_out_per_block
permutation_const_iter_t unmarked_nonbottom_end() const
iterator past the last unmarked non-bottom state in the block
void print_block(const char *message, const block_t *B, permutation_const_iter_t begin, permutation_const_iter_t end) const
print a slice of the partition (typically a block)
state_type marked_size() const
provides the number of marked states in the block
std::vector< state_type > noninert_out_per_state
trans_type trans_size() const
B_to_C_iter_t postprocess_end
iterator past the last transition into this constellation that needs postprocessing
void print_part(const part_trans_t &part_tr) const
print the partition as a tree (per constellation and block)
void set_current_constln(succ_iter_t const new_current_constln)
bool mark(state_info_ptr s)
mark a state
pred_const_iter_t pred_begin() const
iterator to first incoming transition
bool surely_has_transition_to(const constln_t *SpC) const
#define ONLY_IF_DEBUG(...)
include something in Debug mode
O(m log n)-time stuttering equivalence algorithm.
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
This file contains a class that contains labelled transition systems in aut format.
This file contains a class that contains labelled transition systems in fsm format.
This file contains some utility functions to manipulate lts's.
const state_info_entry * state_info_const_ptr
fixed_vector< pred_entry >::iterator pred_iter_t
fixed_vector< succ_entry >::const_iterator succ_const_iter_t
static void red_is_smaller(block_t *BlueB, block_t *RedB)
moves temporary counters to normal ones if the red block is smaller
permutation_t::iterator permutation_iter_t
fixed_vector< pred_entry >::const_iterator pred_const_iter_t
permutation_t::const_iterator permutation_const_iter_t
B_to_C_desc_list::const_iterator B_to_C_desc_const_iter_t
B_to_C_desc_list::iterator B_to_C_desc_iter_t
fixed_vector< B_to_C_entry >::iterator B_to_C_iter_t
static void blue_is_smaller(block_t *BlueB, block_t *RedB, const constln_t *NewC)
moves temporary counters to normal ones if the blue block is smaller
fixed_vector< succ_entry >::iterator succ_iter_t
std::size_t state_type
type used to store state (numbers and) counts
std::set< bisim_gjkw::constln_t *, constln_ptr_less > R_map_t
std::size_t label_type
type used to store label numbers and counts
std::size_t trans_type
type used to store transition (numbers and) counts
std::vector< std::string > split(const std::string &line, const std::string &separators)
Split the text.
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...