17#ifndef LIBLTS_BISIM_GJ_H
18#define LIBLTS_BISIM_GJ_H
28#define linked_list simple_list
33#define USE_FOUR_WAY_SPLIT
42template <
class LTS_TYPE>
class bisim_partitioner_gj;
44namespace bisimulation_gj
73#ifdef USE_FOUR_WAY_SPLIT
79 (std::numeric_limits<transition_index>::max()-2)/3;
119template <
class CONTAINER>
120static inline void clear(CONTAINER& c)
122 if (c.size()>1000) { c=CONTAINER(); }
else { c.clear(); }
198 std::vector<state_in_block_pointer>
m_vec;
226 void swap_vec(std::vector<state_in_block_pointer>& other_vec)
228 m_vec.swap(other_vec);
239 return m_vec.empty();
244 return m_vec.begin();
264 return m_vec.front();
272#ifdef USE_FOUR_WAY_SPLIT
273 void reserve(std::vector<state_in_block_pointer>::size_type new_cap)
275 m_vec.reserve(new_cap);
278 typedef std::vector<state_in_block_pointer>::iterator
iterator;
282 return m_vec.begin();
331 template<
class LTS_TYPE>
334 assert(partitioner.
m_states.data()<=
this);
335 assert(
this<partitioner.
m_states.data_end());
336 return std::to_string(
this-partitioner.
m_states.data());
340 template<
class LTS_TYPE>
346 #if !defined(NDEBUG) || defined(COUNT_WORK_BALANCE)
416 template<
class LTS_TYPE>
428 return "Empty "+result;
432 result += partitioner.
m_states[partitioner.
m_aut.get_transitions()[*
start_same_BLC].to()].block->c.onstellation->debug_id(partitioner);
433 result +=
" containing the ";
437 result +=
" transitions ";
441 result +=
"transition ";
448 result += partitioner.
m_transitions[*iter].debug_id_short(partitioner);
453 result += partitioner.
m_transitions[*iter].debug_id_short(partitioner);
461 result += partitioner.
m_transitions[*iter].debug_id_short(partitioner);
470 #if !defined(NDEBUG) || defined(COUNT_WORK_BALANCE)
491 template<
class LTS_TYPE>
498 return partitioner.
m_states[t.
from()].debug_id_short(partitioner) +
" -" +
500 partitioner.
m_states[t.
to()].debug_id_short(partitioner);
505 template<
class LTS_TYPE>
511 #if !defined(NDEBUG) || defined(COUNT_WORK_BALANCE)
583 <linked_list<BLC_indicators> >::value);
597 std::vector<state_in_block_pointer>*
R;
614 btc_R test_should_be_empty_BLC_list=
btc_R(); assert(
nullptr==test_should_be_empty_BLC_list.
R);
615 if constexpr (
sizeof(test_should_be_empty_BLC_list.
R)!=
622 linked_list<BLC_indicators>())
630 new (&test_should_be_empty_BLC_list) linked_list<BLC_indicators>();
637 :
c(other.
c.onstellation),
639 sta(other.
sta.rt_non_bottom_states),
651#ifndef USE_FOUR_WAY_SPLIT
656 sta(beginning_of_states),
670 sta(start_non_bottom),
674 { assert(start_bottom<=start_non_bottom); assert(start_non_bottom<=end);
678 template<
class LTS_TYPE>
684 return"block ["+std::to_string
685 (std::distance<const state_in_block_pointer*>
688 (std::distance<const state_in_block_pointer*>
692 #if !defined(NDEBUG) || defined(COUNT_WORK_BALANCE)
713 template<
class LTS_TYPE>
718 return "constellation ["+std::to_string
719 (std::distance<const state_in_block_pointer*>
722 (std::distance<const state_in_block_pointer*>
740template <
class LTS_TYPE>
773#ifndef USE_FOUR_WAY_SPLIT
778 std::vector<state_in_block_pointer> m_U_counter_reset_vector;
784 std::vector<linked_list<BLC_indicators>::iterator>
787#ifndef USE_FOUR_WAY_SPLIT
791 std::vector<std::pair<BLC_list_iterator, block_type*> >
792 m_co_splitters_to_be_checked;
809 (
typename LTS_TYPE::labels_size_type l)
839 m_aut.is_tau(result))
841 return divergent_label;
864 const bool check_temporary_complexity_counters,
865 const bool check_block_to_constellation =
true)
const
870 m_transitions[ti].ref_outgoing_transitions->ref.BLC_transitions;
874 assert(&*
m_states[t.
to()].start_incoming_transitions<=&t);
875 if (t.
to()+1!=
m_aut.num_states())
877 assert(&t<=&*std::prev(
m_states[t.
to()+1].start_incoming_transitions));
881 assert(&t<=&
m_aut.get_transitions().back());
898 transitions_per_block_to_constellation->start_same_BLC<=btc_ti);
900 transitions_per_block_to_constellation->end_same_BLC);
902 if (!check_block_to_constellation)
911 if (!blc.is_stable())
913 assert(blc.start_same_BLC<=blc.start_marked_BLC);
914 assert(blc.start_marked_BLC<=blc.end_same_BLC);
916 assert(blc.start_same_BLC<blc.end_same_BLC);
920 m_states[first_t.
to()].block->c.onstellation ==
925 assert(blc.start_same_BLC <= btc_ti);
926 assert(btc_ti<blc.end_same_BLC);
927 assert(&blc == &*
m_transitions[ti].transitions_per_block_to_constellation);
932 if (check_temporary_complexity_counters)
943 no_temporary_work(max_sourceB, max_targetC, max_targetB,
945 0==
m_states[t.
from()].no_of_outgoing_block_inert_transitions),
958 bool check_data_structures(
const std::string&
tag,
const bool initialisation=
false,
const bool check_temporary_complexity_counters=
true)
const
988 const std::vector<transition>::const_iterator end_it1=
989 std::next(si)>=
m_states.end() ?
m_aut.get_transitions().end()
990 : std::next(si)->start_incoming_transitions;
991 for (std::vector<transition>::const_iterator
1012 std::unordered_set<std::pair<label_index, const constellation_type*> >
1013 constellations_seen;
1019 : std::next(si)->start_outgoing_transitions;
1024 ? *it->ref.BLC_transitions : it->ref.transitions];
1027 assert(
m_transitions[!initialisation ? *it->ref.BLC_transitions
1028 : it->ref.transitions].ref_outgoing_transitions==it);
1029 assert((it->start_same_saC>it &&
1031 ((it+1)->start_same_saC==it->start_same_saC ||
1032 (it+1)->start_same_saC<=it)) ||
1033 (it->start_same_saC<=it &&
1035 (it+1)->start_same_saC>it)));
1040 itt<it->start_same_saC->start_same_saC; ++itt)
1043 ? *itt->ref.BLC_transitions : itt->ref.transitions];
1047 assert(
m_states[t.
to()].block->c.onstellation==
1056 if (constellations_seen.count(std::pair(
label,t_to_constellation))>0)
1060 ? *std::prev(it)->ref.BLC_transitions
1061 : std::prev(it)->ref.transitions];
1063 assert(t_to_constellation==
1077 constellations_seen.emplace(
label,t_to_constellation);
1082 if (!initialisation)
1109 assert(is->ref_state->block==&b);
1110 assert(is->ref_state->no_of_outgoing_block_inert_transitions==0);
1111 if (check_temporary_complexity_counters)
1115 !initialisation), *
this);
1121 assert(is->ref_state->block==&b);
1122 assert(is->ref_state->no_of_outgoing_block_inert_transitions>0);
1131 if (!initialisation)
1134 for (linked_list<BLC_indicators>::const_iterator
1138 assert(ind->start_same_BLC<ind->end_same_BLC);
1140 m_aut.get_transitions()[*(ind->start_same_BLC)];
1144 m_states[first_transition.
from()].block->c.onstellation!=
1145 m_states[first_transition.
to()].block->c.onstellation)
1147 ++actual_no_of_non_constellation_inert_BLC_sets;
1150 i<ind->end_same_BLC; ++i)
1153 assert(
m_transitions[*i].transitions_per_block_to_constellation==
1155 all_transitions.emplace(*i);
1157 assert(
m_states[t.
to()].block->c.onstellation==
1158 m_states[first_transition.
to()].block->c.onstellation);
1168 if (check_temporary_complexity_counters)
1173 [first_transition.
to()].block->c.onstellation))), *
this);
1178 if (!initialisation) {
1179 assert(all_transitions.size()==
m_aut.num_transitions());
1180 assert(actual_no_of_non_constellation_inert_BLC_sets==
1193 assert(si==si->ref_state->ref_states_in_blocks);
1199 assert(bi->contains_new_bottom_states);
1206 const block_type*
const first_bi=ci->start_const_states->ref_state->
block;
1207 const block_type*
const last_bi=std::prev(ci->end_const_states)->ref_state->
block;
1208 assert(first_bi != last_bi);
1241 const std::vector<std::pair<BLC_list_iterator, BLC_list_iterator> >*
1243 const std::pair<BLC_list_iterator,BLC_list_iterator>* calM_elt=
nullptr,
1252 old_constellation!=new_constellation ));
1258 bool previous_stable=
true;
1259 for (linked_list<BLC_indicators>::const_iterator
1265 assert(ind->start_same_BLC<ind->end_same_BLC);
1266 const transition&first_t=
m_aut.get_transitions()[*ind->start_same_BLC];
1268 const bool all_transitions_in_BLC_are_inert =
1270 m_states[first_t.
to()].block->c.onstellation;
1271 assert(!all_transitions_in_BLC_are_inert ||
1274 i<ind->end_same_BLC; ++i)
1282 assert(
m_states[t.
to()].block->c.onstellation==
1283 m_states[first_t.
to()].block->c.onstellation);
1287 assert(all_transitions_in_BLC_are_inert);
1292 assert(!all_transitions_in_BLC_are_inert);
1293 if (0 ==
m_states[t.
from()].no_of_outgoing_block_inert_transitions)
1299 all_source_bottom_states.emplace(t.
from());
1309 assert(all_source_bottom_states.size()<=
static_cast<std::size_t
>
1312 bool eventual_instability_is_ok =
true;
1313 bool eventual_marking_is_ok =
true;
1314 if (!all_transitions_in_BLC_are_inert &&
1315 all_source_bottom_states.size()!=
static_cast<std::size_t
>
1321 << (
m_branching ?
" bottom states have a transition in the "
1322 :
" states have a transition in the ")
1323 << ind->debug_id(*
this) <<
": transitions found from states";
1324 for (set_of_states_type::iterator
1325 asbc_it=all_source_bottom_states.begin();
1326 asbc_it!=all_source_bottom_states.end() ; ++asbc_it)
1329 eventual_instability_is_ok =
false;
1331 if (!ind->is_stable())
1334 mCRL2log(
log::debug) << ind->debug_id(*
this) <<
" contains " << std::distance(ind->start_marked_BLC, ind->end_same_BLC) <<
" marked transitions.\n";
1335 eventual_marking_is_ok =
false;
1361 if (!(eventual_instability_is_ok && eventual_marking_is_ok))
1364 eventual_instability_is_ok =
true;
1365 eventual_marking_is_ok =
true;
1368 if (!(eventual_instability_is_ok && eventual_marking_is_ok) &&
nullptr != calM && calM->begin() != calM->end())
1370 std::vector<std::pair<BLC_list_iterator, BLC_list_iterator> >::const_iterator calM_iter = calM->begin();
1371 if (
nullptr != calM_elt)
1375 assert(calM->end() != calM_iter);
1376 if (calM_iter->first <= calM_elt->first && calM_elt->second <= calM_iter->second)
1382 if (calM_elt->first<=ind->start_same_BLC && ind->end_same_BLC<=calM_elt->second)
1387 block->c.onstellation->debug_id(*
this)
1388 <<
") is soon going to be a main splitter.\n";
1389 eventual_instability_is_ok =
true;
1390 eventual_marking_is_ok =
true;
1394 if (old_constellation==
1395 m_states[first_t.
to()].block->c.onstellation)
1400 assert(main_splitter->start_same_BLC < main_splitter->end_same_BLC);
1401 const transition& main_t =
m_aut.get_transitions()[*main_splitter->start_same_BLC];
1404 &&
m_states[main_t.
to()].block->c.onstellation==
1408 if (calM_elt->first<=main_splitter->start_same_BLC && main_splitter->end_same_BLC<=calM_elt->second)
1410 assert(new_constellation==
1411 m_states[main_t.
to()].block->c.onstellation);
1412 mCRL2log(
log::debug) <<
" This is ok because the BLC set (" << b.
debug_id(*
this) <<
" -" <<
m_aut.action_label(first_t.
label()) <<
"-> " << old_constellation->debug_id(*
this) <<
") is soon going to be a co-splitter.\n";
1413 eventual_instability_is_ok =
true;
1414 eventual_marking_is_ok =
true;
1423 for(; !(eventual_instability_is_ok && eventual_marking_is_ok) && calM->end() != calM_iter; ++calM_iter)
1425 if (calM_iter->first<=ind->start_same_BLC && ind->end_same_BLC<=calM_iter->second)
1430 <<
m_states[first_t.
to()].block->c.onstellation->debug_id(*
this)
1431 <<
") is going to be a main splitter later.\n";
1432 eventual_instability_is_ok =
true;
1433 eventual_marking_is_ok =
true;
1437 if (old_constellation==
1438 m_states[first_t.
to()].block->c.onstellation)
1443 assert(main_splitter->start_same_BLC < main_splitter->end_same_BLC);
1444 const transition& main_t =
m_aut.get_transitions()[*main_splitter->start_same_BLC];
1447 &&
m_states[main_t.
to()].block->c.onstellation==
1450 if (calM_iter->first<=main_splitter->start_same_BLC && main_splitter->end_same_BLC<=calM_iter->second)
1452 assert(new_constellation==
1453 m_states[main_t.
to()].block->c.onstellation);
1455 "set (" << b.
debug_id(*
this) <<
" -"
1457 <<
"-> " << old_constellation->debug_id(*
this)
1458 <<
") is going to be a co-splitter later.\n";
1459 eventual_instability_is_ok =
true;
1460 eventual_marking_is_ok =
true;
1471 if (!eventual_marking_is_ok)
1473 mCRL2log(
log::debug) <<
" (This is ok because the source block contains only 1 state.)\n";
1474 eventual_marking_is_ok =
true;
1480 assert(eventual_marking_is_ok);
1481 assert(eventual_instability_is_ok);
1483 assert(previous_stable);
1487 previous_stable=
false;
1502 const transition& first_t=
m_aut.get_transitions()[*blc_it.start_same_BLC];
1506 blc_it.start_same_BLC) <<
" -- "
1508 blc_it.end_same_BLC)
1509 <<
" of " << (
null_action==l ?
"divergent self-loop " :
pp(
m_aut.action_label(l))+
"-")
1510 <<
"transitions to " <<
m_states[first_t.
to()].block->c.onstellation->debug_id(*
this) <<
":\n";
1513 if (i == blc_it.start_marked_BLC)
1516 " following transitions are marked.)\n";
1518 if (i>=blc_it.end_same_BLC)
1544 const bool initialisation=
false)
const
1546 if (!mCRL2logEnabled(
log::debug)) {
return; }
1547 mCRL2log(
log::debug) <<
"========= PRINT DATASTRUCTURE: " << header <<
" =======================================\n"
1548 "++++++++++++++++++++ States ++++++++++++++++++++++++++++\n";
1552 " #Inert outgoing transitions: " <<
m_states[si].no_of_outgoing_block_inert_transitions <<
"\n"
1554 " Incoming transitions:\n";
1555 std::vector<transition>::const_iterator end=(si+1==
m_aut.num_states()?
m_aut.get_transitions().end():
m_states[si+1].start_incoming_transitions);
1556 for(std::vector<transition>::const_iterator it=
m_states[si].start_incoming_transitions; it!=end; ++it)
1566 (si+1>=
m_aut.num_states() || it!=
m_states[si+1].start_outgoing_transitions);
1570 ? *it->ref.BLC_transitions : it->ref.transitions];
1571 bool start_same_saC_valid=
1574 if (start_same_saC_valid &&
1575 it->start_same_saC->start_same_saC==it &&
1576 it->start_same_saC >= it)
1581 to_constln=
m_states[t.
to()].block->c.onstellation;
1583 << (
null_action==t_label ?
"divergent self-loop " :
pp(
m_aut.action_label(t_label))+
"-")
1584 <<
"transitions to " << to_constln->
debug_id(*
this)
1585 << (
m_aut.is_tau(t_label) && !
m_aut.is_tau(old_t_label)
1586 ?
" -- error: tau-transitions should come first\n"
1590 if (start_same_saC_valid)
1596 if (!initialisation &&
m_states[t.
to()].block->c.onstellation!=to_constln)
1600 if (it->start_same_saC->start_same_saC == it)
1607 !initialisation ? *std::prev(it)->ref.BLC_transitions
1608 : std::prev(it)->ref.transitions];
1612 m_states[prev_t.
to()].block->c.onstellation==
1622 !initialisation ? *std::next(it)->ref.BLC_transitions
1623 : std::next(it)->ref.transitions];
1627 m_states[next_t.
to()].block->c.onstellation==
1634 else if (it->start_same_saC > it ? it->start_same_saC->start_same_saC > it : it->start_same_saC->start_same_saC < it)
1641 mCRL2log(
log::debug) <<
" Ref states in blocks: " << std::distance<fixed_vector<state_type_gj>::const_iterator>(
m_states.cbegin(),
m_states[si].ref_states_in_blocks->ref_state) <<
". Must be " << si <<
".\n";
1644 mCRL2log(
log::debug) <<
"++++++++++++++++++++ Transitions ++++++++++++++++++++++++++++\n";
1649 <<
" -" <<
m_aut.action_label(t.
label()) <<
"-> "
1653 mCRL2log(
log::debug) <<
"++++++++++++++++++++ Blocks ++++++++++++++++++++++++++++\n";
1659 if (!initialisation) {
1676 <<
" Non-bottom state" << (1==std::distance
1689 if (!initialisation)
1696 mCRL2log(
log::debug) <<
"++++++++++++++++++++ Constellations ++++++++++++++++++++++++++++\n";
1699 si=si->ref_state->block->c.onstellation->end_const_states)
1721 "\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"
1722 "Outgoing transitions:\n";
1728 ? *pi->ref.BLC_transitions : pi->ref.transitions];
1735 ? *pi->start_same_saC->ref.BLC_transitions
1736 : pi->start_same_saC->ref.transitions];
1739 if (pi->start_same_saC->start_same_saC == pi)
1746 !initialisation ? *std::prev(pi)->ref.BLC_transitions
1747 : std::prev(pi)->ref.transitions];
1751 m_states[prev_t.
to()].block->c.onstellation==
1761 !initialisation ? *std::next(pi)->ref.BLC_transitions
1762 : std::next(pi)->ref.transitions];
1766 m_states[next_t.
to()].block->c.onstellation==
1773 else if (pi->start_same_saC > pi ? pi->start_same_saC->start_same_saC > pi : pi->start_same_saC->start_same_saC < pi)
1781 mCRL2log(
log::debug) <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"
1782 "New bottom blocks to be investigated:";
1789 mCRL2log(
log::debug) <<
"\n========= END PRINT DATASTRUCTURE: " << header <<
" =======================================\n";
1812 return m_states[si].block->sta.te_in_reduced_LTS;
1838 si=si->ref_state->block->end_states)
1848 typename std::remove_reference<
decltype(
m_aut.get_transitions())>::type
1852 si=si->ref_state->block->end_states)
1861 assert(blc_ind.start_same_BLC<blc_ind.end_same_BLC);
1870 m_aut.clear_transitions();
1871 T.swap(
m_aut.get_transitions());
1876 if (
m_aut.has_state_info())
1879 typename std::remove_reference<
decltype(
m_aut.state_labels())>::type
1882 for(std::size_t i=0; i<
m_aut.num_states(); ++i)
1887 new_labels[new_index]=new_labels[new_index]+
m_aut.state_label(i);
1892 new_labels.swap(
m_aut.state_labels());
1916 "-> "+std::to_string(t.
to());
1969 { assert(pos3<pos1);
1975 pos3->
ref_state->ref_states_in_blocks=pos3;
1977 pos1->
ref_state->ref_states_in_blocks=pos1;
1978 pos2->
ref_state->ref_states_in_blocks=pos2;
2010 #
if !defined(NDEBUG) || defined(COUNT_WORK_BALANCE)
2012 unsigned char const max_B,
2014 multiple_swap_states_in_block__swap_state_in_small_block
2020 std::make_signed<state_index>::type
2021 overlap=std::distance(pos2, pos1)+count;
2025 #if !defined(NDEBUG) || defined(COUNT_WORK_BALANCE)
2029 if (pos2==assign_work_to) {
2030 assign_work_to+=overlap;
2031 }
else { assert(assign_work_to+count<=pos2+overlap ||
2032 pos2+overlap+count<=assign_work_to); }
2036 } assert(0 < count);
2040 #if !defined(NDEBUG) || defined(COUNT_WORK_BALANCE)
2044 pos1->
ref_state->ref_states_in_blocks=pos1;
2047 pos2->
ref_state->ref_states_in_blocks=pos2;
2051 pos1->
ref_state->ref_states_in_blocks=pos1;
2053 pos2->
ref_state->ref_states_in_blocks=pos2;
2058 assert(si==si->ref_states_in_blocks->ref_state);
2069 linked_list<BLC_indicators>::iterator ind =
2070 m_transitions[*old_pos].transitions_per_block_to_constellation; assert(ind->start_same_BLC<=old_pos);
2072 assert(old_pos<ind->end_same_BLC); assert(!ind->is_stable());
2073 if (old_pos < ind->start_marked_BLC)
2075 assert(ind->start_same_BLC<ind->start_marked_BLC);
2076 BLC_list_iterator new_pos = std::prev(ind->start_marked_BLC); assert(ind->start_same_BLC<=new_pos); assert(new_pos<ind->end_same_BLC);
2078 if (old_pos < new_pos)
2082 ref.BLC_transitions = old_pos; assert(out_pos==
m_transitions[*new_pos].ref_outgoing_transitions);
2083 out_pos->ref.BLC_transitions = new_pos;
2085 ind->start_marked_BLC--;
2092 assert(
m_transitions[*it].ref_outgoing_transitions->ref.BLC_transitions==
2094 assert(
m_transitions[*it].transitions_per_block_to_constellation->
2095 start_same_BLC<=it);
2097 m_transitions[*it].transitions_per_block_to_constellation->end_same_BLC);
2102#ifndef USE_FOUR_WAY_SPLIT
2108 template <
bool initialisation=false>
2123 assert(first_bottom_state_in_R<=last_bottom_state_in_R);
2124 assert(last_bottom_state_in_R<=B->sta.rt_non_bottom_states);
2127 #ifdef USE_POOL_ALLOCATOR
2129 template construct<block_type>
2135 #if !defined(NDEBUG) || defined(COUNT_WORK_BALANCE)
2148 #if !defined(NDEBUG) || defined(COUNT_WORK_BALANCE)
2151 last_bottom_state_in_R) + R.
size());
2154 { assert(first_bottom_state_in_R!=last_bottom_state_in_R);
2157 std::distance(first_bottom_state_in_R, last_bottom_state_in_R)
2158 #
if !defined(NDEBUG) || defined(COUNT_WORK_BALANCE)
2159 , first_bottom_state_in_R, max_B
2163 std::distance(first_bottom_state_in_R, last_bottom_state_in_R);
2170 s_it=first_bottom_state_in_R; s_it<last_bottom_state_in_R; ++s_it)
2172 split_block_B_into_R_and_BminR__carry_out_split, max_B), *this);
2174 assert(B==s_it->ref_state->block);
2175 s_it->ref_state->block=B_new; assert(s_it->ref_state->ref_states_in_blocks==s_it);
2185 split_block_B_into_R_and_BminR__carry_out_split, max_B), *this);
2187 assert(B==s.ref_state->block);
2188 s.ref_state->block=B_new;
2207 { assert(i3<=i2); assert(i2<=i1);
2212 if ((i1==i2)||(i2==i3))
2215 m_transitions[*i1].ref_outgoing_transitions->ref.BLC_transitions = i1;
2216 m_transitions[*i3].ref_outgoing_transitions->ref.BLC_transitions = i3;
2224 m_transitions[*i1].ref_outgoing_transitions->ref.BLC_transitions = i1;
2225 m_transitions[*i2].ref_outgoing_transitions->ref.BLC_transitions = i2;
2226 m_transitions[*i3].ref_outgoing_transitions->ref.BLC_transitions = i3;
2250 linked_list<BLC_indicators>::iterator new_BLC_block,
2251 linked_list<BLC_indicators>::iterator old_BLC_block)
2252 { assert(new_BLC_block->is_stable());
2254 m_transitions[ti].ref_outgoing_transitions->ref.BLC_transitions; assert(old_BLC_block->start_same_BLC <= old_position);
2255 assert(old_position<old_BLC_block->end_same_BLC);
2256 assert(new_BLC_block->end_same_BLC==old_BLC_block->start_same_BLC);
2257 assert(
m_transitions[ti].transitions_per_block_to_constellation == old_BLC_block);
2258 assert(ti == *old_position);
2259 if (!old_BLC_block->is_stable())
2260 { assert(old_BLC_block->start_same_BLC<=old_BLC_block->start_marked_BLC);
2261 assert(old_BLC_block->start_marked_BLC<=old_BLC_block->end_same_BLC);
2262 if (old_BLC_block->start_marked_BLC<=old_position)
2263 { assert(
m_states[
m_aut.get_transitions()[ti].from()].block->
2264 contains_new_bottom_states ||
2273 old_BLC_block->start_marked_BLC=old_BLC_block->end_same_BLC;
2276 if (old_position!=old_BLC_block->start_same_BLC)
2278 std::swap(*old_position,*old_BLC_block->start_same_BLC);
2280 ref.BLC_transitions = old_position;
2282 ref_outgoing_transitions->ref.BLC_transitions =
2283 old_BLC_block->start_same_BLC;
2285 new_BLC_block->end_same_BLC=++old_BLC_block->start_same_BLC;
2286 m_transitions[ti].transitions_per_block_to_constellation=new_BLC_block;
2288 return old_BLC_block->start_same_BLC==old_BLC_block->end_same_BLC;
2314 { assert(
m_states[t.
to()].block==index_block_B);
2318 linked_list<BLC_indicators>::iterator this_block_to_constellation=
2323 i!=this_block_to_constellation; ++i)
2329 assert(this_block_to_constellation->start_same_BLC <=
m_transitions[ti].ref_outgoing_transitions->ref.BLC_transitions);
2333 this_block_to_constellation->is_stable() ||
2334 m_transitions[ti].ref_outgoing_transitions->ref.BLC_transitions<this_block_to_constellation->start_marked_BLC);
2335 linked_list<BLC_indicators>::iterator next_block_to_constellation;
2340 next_block_to_constellation=from_block->
block.
to_constellation.begin(); assert(next_block_to_constellation->start_same_BLC <
2341 next_block_to_constellation->end_same_BLC);
2342 assert(
m_states[
m_aut.get_transitions()[*(next_block_to_constellation->start_same_BLC)].from()].block==index_block_B);
2344 if (next_block_to_constellation==this_block_to_constellation)
2352 this_block_to_constellation->start_same_BLC,
2353 this_block_to_constellation->start_same_BLC,
true);
2354 #if !defined(NDEBUG) || defined(COUNT_WORK_BALANCE)
2355 next_block_to_constellation->work_counter = this_block_to_constellation->work_counter;
2360 assert(
m_states[
m_aut.get_transitions()[*(next_block_to_constellation->start_same_BLC)].to()].block==index_block_B);
2374 next_block_to_constellation=from_block->
2375 block.to_constellation.next(this_block_to_constellation);
2377 if (next_block_to_constellation==
2379 (first_t=&
m_aut.get_transitions()
2380 [*(next_block_to_constellation->start_same_BLC)],
2382 m_states[first_t->
to()].block!=index_block_B) ||
2387 new_block_created =
true;
2389 emplace_after(this_block_to_constellation,
2390 this_block_to_constellation->start_same_BLC,
2391 this_block_to_constellation->start_same_BLC,
true);
2392 #if !defined(NDEBUG) || defined(COUNT_WORK_BALANCE)
2393 next_block_to_constellation->work_counter=
2394 this_block_to_constellation->work_counter;
2402 next_block_to_constellation, this_block_to_constellation))
2421 return new_block_created;
2443 linked_list<BLC_indicators>::iterator new_BLC_block,
2444 linked_list<BLC_indicators>::iterator old_BLC_block)
2445 { assert(new_BLC_block->end_same_BLC==old_BLC_block->start_same_BLC);
2447 m_transitions[ti].ref_outgoing_transitions->ref.BLC_transitions; assert(old_BLC_block->start_same_BLC<=old_position);
2448 assert(old_position<old_BLC_block->end_same_BLC);
2450 if (!old_BLC_block->is_stable())
2452 assert(old_BLC_block->start_same_BLC<=old_BLC_block->start_marked_BLC);
2453 assert(old_BLC_block->start_marked_BLC<=old_BLC_block->end_same_BLC);
2455 if (!new_BLC_block->is_stable())
2457 assert(new_BLC_block->start_same_BLC<=new_BLC_block->start_marked_BLC);
2458 assert(new_BLC_block->start_marked_BLC<=new_BLC_block->end_same_BLC);
2461 assert(
m_transitions[ti].transitions_per_block_to_constellation==
2464 assert(ti==*old_position);
2465 if (old_BLC_block->is_stable() ||
2466 old_position<old_BLC_block->start_marked_BLC)
2467 { assert(old_BLC_block->start_same_BLC <= old_position);
2469 if (new_BLC_block->is_stable())
2472 if (!old_BLC_block->is_stable())
2482 if (old_position!=old_BLC_block->start_same_BLC)
2484 std::swap(*old_position, *old_BLC_block->start_same_BLC);
2486 ref.BLC_transitions=old_position;
2488 ref_outgoing_transitions->ref.BLC_transitions=
2489 old_BLC_block->start_same_BLC;
2493 { assert(new_BLC_block->start_marked_BLC<=old_BLC_block->start_same_BLC);
2495 if (old_BLC_block->is_stable())
2506 old_BLC_block->start_same_BLC, new_BLC_block->start_marked_BLC++);
2510 { assert(old_BLC_block->start_marked_BLC <= old_position);
2512 assert(old_BLC_block->start_same_BLC <= old_BLC_block->start_marked_BLC);
2513 assert(!new_BLC_block->is_stable());
2515 old_BLC_block->start_marked_BLC++, old_BLC_block->start_same_BLC);
2517 m_transitions[ti].transitions_per_block_to_constellation=new_BLC_block;
2518 new_BLC_block->end_same_BLC=++old_BLC_block->start_same_BLC;
2520 return old_BLC_block->start_same_BLC==old_BLC_block->end_same_BLC;
2570 linked_list<BLC_indicators>::iterator this_block_to_constellation=
2576 i!=this_block_to_constellation; ++i)
2584 linked_list<BLC_indicators>::iterator new_BLC_block;
2591 new_BLC_block=new_bi->
block.
to_constellation.begin(); assert(this_block_to_constellation->start_same_BLC==new_BLC_block->end_same_BLC);
2594 if (new_BLC_block->start_same_BLC<new_BLC_block->end_same_BLC)
2596 const transition& inert_t=
m_aut.get_transitions()[*new_BLC_block->start_same_BLC];
2599 assert(to_constln==
m_states[inert_t.
to()].block->c.onstellation);
2607 if (this_block_to_constellation->start_same_BLC!=
2609 (perhaps_new_BLC_block_transition=
2610 *std::prev(this_block_to_constellation->start_same_BLC),
2612 &
m_aut.get_transitions()[perhaps_new_BLC_block_transition],
2616 [perhaps_new_BLC_t->
to()].block->c.onstellation)
2620 new_BLC_block=
m_transitions[perhaps_new_BLC_block_transition].
2621 transitions_per_block_to_constellation;
2624 if (this_block_to_constellation->is_stable()) { assert(new_BLC_block->is_stable()); }
2625 else { assert(!new_BLC_block->is_stable()); }
2635 linked_list<BLC_indicators>::iterator new_position=
2637#ifndef USE_FOUR_WAY_SPLIT
2639 if (this_block_to_constellation->is_stable())
2670 ((to_constln==new_constellation &&
2676 (to_constln==old_constellation &&
2688 { assert(old_constellation!=new_constellation);
2692 linked_list<BLC_indicators>::const_iterator old_co_splitter;
2694 if ((old_constellation==to_constln &&
2697 next(this_block_to_constellation),
2698 co_to_constln=new_constellation,
2701 (new_constellation==to_constln &&
2704 prev(this_block_to_constellation),
2705 co_to_constln=old_constellation,
2725 old_co_splitter->start_same_BLC)
2733 *std::prev(old_co_splitter->start_same_BLC);
2735 m_aut.get_transitions()[perhaps_new_co_spl_transition];
2736 if(new_bi==
m_states[perhaps_new_co_spl_t.
from()].block &&
2739 [perhaps_new_co_spl_t.
to()].block->c.onstellation)
2746 [perhaps_new_co_spl_transition].
2747 transitions_per_block_to_constellation;
2748 if (old_constellation==to_constln)
2761 if (old_co_splitter->start_same_BLC<old_co_splitter->end_same_BLC)
2764 [*old_co_splitter->start_same_BLC];
2768 assert(co_to_constln==
m_states[co_t.
to()].block->c.onstellation);
2775#ifdef USE_FOUR_WAY_SPLIT
2778 else if (new_constellation==to_constln)
2781 if (old_co_splitter->start_same_BLC<
2782 old_co_splitter->end_same_BLC &&
2783 (co_t=&
m_aut.get_transitions()
2784 [*old_co_splitter->start_same_BLC], assert(old_bi==
m_states[co_t->
from()].block ||
2788 [co_t->
to()].block->c.onstellation)
2791 old_co_splitter_end=old_co_splitter->end_same_BLC;
2801 assert(old_constellation==to_constln);
2806#ifdef USE_FOUR_WAY_SPLIT
2809 else if (new_constellation==to_constln)
2812 if (old_co_splitter->start_same_BLC<
2813 old_co_splitter->end_same_BLC &&
2814 (co_t=&
m_aut.get_transitions()
2815 [*old_co_splitter->start_same_BLC], assert(old_bi==
m_states[co_t->
from()].block ||
2819 [co_t->
to()].block->c.onstellation)
2822 old_co_splitter_end=old_co_splitter->end_same_BLC;
2833 assert(old_constellation==to_constln);
2856#ifdef USE_FOUR_WAY_SPLIT
2857 else if (this_block_to_constellation->is_stable())
2866 const BLC_list_iterator old_BLC_start=this_block_to_constellation->start_same_BLC;
2868 (new_position, old_BLC_start, old_BLC_start,
2869 this_block_to_constellation->is_stable());
2870 #if !defined(NDEBUG) || defined(COUNT_WORK_BALANCE)
2871 new_BLC_block->work_counter=this_block_to_constellation->work_counter;
2874#ifndef USE_FOUR_WAY_SPLIT
2879 if (old_constellation==to_constln)
2883 m_co_splitters_to_be_checked.emplace_back
2884 (new_BLC_block->start_same_BLC, new_bi);
2887 m_co_splitters_to_be_checked.emplace_back
2888 (std::prev(this_block_to_constellation->end_same_BLC), old_bi);
2891 { assert(new_constellation==to_constln);
2892 assert(
nullptr!=old_co_splitter_end);
2895 m_co_splitters_to_be_checked.emplace_back
2896 (std::prev(old_co_splitter_end), old_bi);
2903 const bool last_element_removed=
2905 new_BLC_block, this_block_to_constellation);
2907 if (last_element_removed)
2925 (this_block_to_constellation);
2946#ifdef USE_FOUR_WAY_SPLIT
2953 std::vector<state_in_block_pointer>::const_iterator begin,
2954 std::vector<state_in_block_pointer>::const_iterator
const end,
2959 { assert(block==begin->ref_state->block);
2978 { assert(
Rmarked == si.ref_state->counter);
2984 { assert(m_U_counter_reset_vector.empty());
2989 assert(
Rmarked!=si.ref_state->counter);
2994 clear(m_U_counter_reset_vector);
3023 template <
bool initialisation=
false,
3024 class Iterator=linked_list<BLC_indicators>::iterator>
3032 typedef enum { initializing, state_checking, aborted,
3033 aborted_after_initialisation,
3034 incoming_inert_transition_checking,
3037 status_type R_status=initializing; assert(m_U.
empty()); assert(m_U_counter_reset_vector.empty());
3039 if constexpr (initialisation)
3041 M_it=splitter_end_unmarked_BLC;
3044 { assert(splitter_end_unmarked_BLC<=splitter->end_same_BLC);
3045 M_it=splitter->start_same_BLC; assert(splitter_end_unmarked_BLC==splitter->start_marked_BLC ||
3046 splitter_end_unmarked_BLC==M_it);
3048 assert(splitter->start_same_BLC<splitter->end_same_BLC);
3051 [*splitter->start_same_BLC].from()].block==B);
3053 std::vector<transition>::iterator current_U_incoming_transition_iterator;
3054 std::vector<transition>::iterator
3055 current_U_incoming_transition_iterator_end; assert(M_it <= splitter_end_unmarked_BLC);
3059 std::vector<transition>::iterator current_R_incoming_transition_iterator;
3061 B->
start_bottom_states; assert(current_R_incoming_bottom_state_iterator<=first_unmarked_bottom_state);
3062 std::vector<transition>::iterator
3063 current_R_incoming_transition_iterator_end; assert(current_R_incoming_bottom_state_iterator<first_unmarked_bottom_state ||
3064 !m_R.
empty() || M_it<splitter_end_unmarked_BLC);
3066 first_unmarked_bottom_state; assert(current_U_incoming_bottom_state_iterator<B->sta.rt_non_bottom_states);
3067 const std::make_signed<state_index>::type max_R_nonbottom_size=
3070 first_unmarked_bottom_state);
3071 if (max_R_nonbottom_size <
3072 static_cast<std::make_signed<state_index>::type
>(m_R.
size()))
3075 R_status = (M_it == splitter_end_unmarked_BLC)
3076 ? aborted_after_initialisation : aborted;
3084 first_unmarked_bottom_state) <=
3086 assert(m_R.
empty());
3087 assert(m_U.
empty());
3088 assert(m_U_counter_reset_vector.empty());
3090 ptr_to_new_block=split_block_B_into_R_and_BminR<initialisation>
3092 return ptr_to_new_block;
3094 else if (M_it==splitter_end_unmarked_BLC)
3099 R_status=state_checking;
3102 const std::make_signed<state_index>::type max_U_nonbottom_size=
3104 std::distance(first_unmarked_bottom_state,
3106 if (max_U_nonbottom_size<0)
3107 { assert(
static_cast<std::make_signed<state_index>::type
>
3110 U_status=aborted_after_initialisation; assert(aborted != R_status); assert(aborted_after_initialisation != R_status);
3113 { assert(
static_cast<std::make_signed<state_index>::type
>
3117 { assert(first_unmarked_bottom_state<B->sta.rt_non_bottom_states);
3118 assert(std::distance(first_unmarked_bottom_state,
3121 assert(m_R.
empty());
3122 assert(m_U.
empty());
3123 assert(m_U_counter_reset_vector.empty());
3125 ptr_to_new_block=split_block_B_into_R_and_BminR<initialisation>
3126 (B, first_unmarked_bottom_state, B->
end_states, m_U);
3132 if constexpr (!initialisation)
3133 { assert(splitter->start_same_BLC<splitter->end_same_BLC);
3135 m_aut.get_transitions()[*splitter->start_same_BLC];
3137 C=
m_states[first_t.
to()].block->c.onstellation;
3138 }
else{assert(state_checking==R_status||aborted_after_initialisation==R_status);}
3140 if constexpr (!initialisation)
3142 if (initializing==R_status || aborted==R_status)
3153 { assert(U_status!=aborted_after_initialisation ||
3154 (R_status!=aborted && R_status!=aborted_after_initialisation));
3158 if (si.ref_state->block!=B || 0==si.ref_state->no_of_outgoing_block_inert_transitions)
3160 assert((initialisation &&
3161 0!=si.ref_state->no_of_outgoing_block_inert_transitions) ||
3163 assert(!m_R.
find(si));
3164 assert(!m_U.
find(si));
3165 assert(std::find(m_U_counter_reset_vector.begin(), m_U_counter_reset_vector.end(), si) == m_U_counter_reset_vector.end());
3169 switch(si.ref_state->counter)
3172 assert(std::find(m_U_counter_reset_vector.begin(), m_U_counter_reset_vector.end(), si) == m_U_counter_reset_vector.end());
3181 assert(std::find(m_U_counter_reset_vector.begin(), m_U_counter_reset_vector.end(), si) != m_U_counter_reset_vector.end());
3183 default: assert(!m_R.
find(si)); assert(!m_U.
find(si));
3184 assert(std::find(m_U_counter_reset_vector.begin(), m_U_counter_reset_vector.end(), si) != m_U_counter_reset_vector.end());
3190 if (incoming_inert_transition_checking==R_status)
3191 { assert(current_R_incoming_transition_iterator <
3192 current_R_incoming_transition_iterator_end);
3196 assert(
m_states[current_R_incoming_transition_iterator->to()].block==B);
3197 const transition& tr=*current_R_incoming_transition_iterator;
3209 { assert(aborted_after_initialisation!=U_status);
3210 R_status=aborted_after_initialisation;
3211 goto R_handled_and_is_not_state_checking;
3216 ++current_R_incoming_transition_iterator;
3217 if (current_R_incoming_transition_iterator!=
3218 current_R_incoming_transition_iterator_end &&
3220 (current_R_incoming_transition_iterator->label())))
3222 goto R_handled_and_is_not_state_checking;
3224 R_status=state_checking;
3226 else if (state_checking==R_status)
3229 (current_R_incoming_bottom_state_iterator<
3230 first_unmarked_bottom_state
3231 ? *current_R_incoming_bottom_state_iterator++
3238 current_R_incoming_transition_iterator_end=
3239 m_aut.get_transitions().end();
3243 current_R_incoming_transition_iterator_end=
3244 std::next(s.
ref_state)->start_incoming_transitions;
3246 current_R_incoming_transition_iterator=
3247 s.
ref_state->start_incoming_transitions;
3248 if (current_R_incoming_transition_iterator!=
3249 current_R_incoming_transition_iterator_end &&
3251 (current_R_incoming_transition_iterator->label())))
3253 R_status=incoming_inert_transition_checking;
3254 goto R_handled_and_is_not_state_checking;
3257 else if (initializing!=R_status)
3259 assert(aborted_after_initialisation==R_status ||
3261 goto R_handled_and_is_not_state_checking;
3264 { assert(M_it<splitter_end_unmarked_BLC);
3268 simple_splitB_R__handle_transition_from_R_state, 1), *this);
3269 assert(si.ref_state->block==B);
3272 m_states[
m_aut.get_transitions()[*M_it].to()].block->c.onstellation);
3274 if (0==si.ref_state->no_of_outgoing_block_inert_transitions)
3276 assert(si.ref_state->ref_states_in_blocks<first_unmarked_bottom_state);
3277 assert(!m_R.
find(si));
3279 else if (si.ref_state->counter!=
Rmarked)
3281 assert(si.ref_state->ref_states_in_blocks<B->
end_states);
3283 si.ref_state->counter=
Rmarked;
3286 { assert(aborted_after_initialisation!=U_status);
3288 goto R_handled_and_is_not_state_checking;
3290 }
else { assert(m_R.
find(si)); }
3291 assert(!m_U.
find(si));
3292 if (M_it!=splitter_end_unmarked_BLC)
3294 goto R_handled_and_is_not_state_checking;
3296 R_status=state_checking;
3297 } assert(state_checking==R_status);
3298 if (current_R_incoming_bottom_state_iterator==
3301 first_unmarked_bottom_state) + m_R.
size());
3305 ptr_to_new_block=split_block_B_into_R_and_BminR
3307 first_unmarked_bottom_state, m_R);
3311 return ptr_to_new_block;
3313 R_handled_and_is_not_state_checking: assert(state_checking!=R_status ||
3314 current_R_incoming_bottom_state_iterator!=first_unmarked_bottom_state ||
3318 si.ref_state<
m_states.end(); ++si.ref_state)
3320 if (si.ref_state->block!=B ||
3321 0==si.ref_state->no_of_outgoing_block_inert_transitions)
3323 assert((initialisation &&
3324 0!=si.ref_state->no_of_outgoing_block_inert_transitions) ||
3326 assert(!m_R.
find(si));
3327 assert(!m_U.
find(si));
3328 assert(std::find(m_U_counter_reset_vector.begin(),
3329 m_U_counter_reset_vector.end(), si)==m_U_counter_reset_vector.end());
3333 switch(si.ref_state->counter)
3336 assert(std::find(m_U_counter_reset_vector.begin(), m_U_counter_reset_vector.end(), si) == m_U_counter_reset_vector.end());
3345 assert(std::find(m_U_counter_reset_vector.begin(), m_U_counter_reset_vector.end(), si) != m_U_counter_reset_vector.end());
3347 default: assert(!m_R.
find(si)); assert(!m_U.
find(si));
3348 assert(std::find(m_U_counter_reset_vector.begin(), m_U_counter_reset_vector.end(), si) != m_U_counter_reset_vector.end());
3355 if (incoming_inert_transition_checking==U_status)
3356 { assert(current_U_incoming_transition_iterator<
3357 current_U_incoming_transition_iterator_end);
3360 (current_U_incoming_transition_iterator->label())));
3362 current_U_incoming_transition_iterator)],
3364 simple_splitB_U__handle_transition_to_U_state, 1), *this);
3366 current_U_incoming_transition_iterator->from()); assert(
m_states[current_U_incoming_transition_iterator->to()].block==B);
3367 current_U_incoming_transition_iterator++;
3369 if (current_U_outgoing_state.
ref_state->block==B &&
3371 std::prev(current_U_incoming_transition_iterator)->from()==
3372 std::prev(current_U_incoming_transition_iterator)->to()))
3373 { assert(!m_U.
find(current_U_outgoing_state));
3382 no_of_outgoing_block_inert_transitions;
3383 m_U_counter_reset_vector.push_back(current_U_outgoing_state);
3386 { assert(std::find(m_U_counter_reset_vector.begin(),
3387 m_U_counter_reset_vector.end(),
3388 current_U_outgoing_state) != m_U_counter_reset_vector.end());
3390 current_U_outgoing_state.
ref_state->counter--;
3396 if (initializing==R_status || aborted==R_status)
3400 current_U_outgoing_transition_iterator=
3402 start_outgoing_transitions; assert(
m_outgoing_transitions.begin()<=current_U_outgoing_transition_iterator);
3404 current_U_outgoing_transition_iterator_end=
3405 (std::next(current_U_outgoing_state.
ref_state)>=
3408 : std::next(current_U_outgoing_state.
ref_state)->
3409 start_outgoing_transitions); assert(current_U_outgoing_transition_iterator<
3410 current_U_outgoing_transition_iterator_end);
3411 assert(
m_states.begin()+
m_aut.get_transitions()[*current_U_outgoing_transition_iterator->ref.BLC_transitions].from()==current_U_outgoing_state.
ref_state);
3412 U_status=outgoing_action_constellation_check;
3413 goto U_handled_and_is_not_state_checking;
3417 if constexpr (!initialisation)
3423 : std::next(current_U_outgoing_state.
ref_state)->
3424 start_outgoing_transitions;
3426 start_outgoing_transitions;
3427 out_it<out_it_end; ++out_it)
3434 assert(*out_it->ref.BLC_transitions<
m_aut.num_transitions());
3435 assert(
m_transitions[*out_it->ref.BLC_transitions].ref_outgoing_transitions==out_it);
3436 const transition& t=
m_aut.get_transitions()[*out_it->ref.BLC_transitions];
3443 assert(out_it->ref.BLC_transitions>=splitter_end_unmarked_BLC);
3444 assert(splitter->start_same_BLC<=out_it->ref.BLC_transitions);
3445 assert(out_it->ref.BLC_transitions<splitter->end_same_BLC);
3450 m_U.
add_todo(current_U_outgoing_state);
3453 { assert(aborted!=R_status); assert(aborted_after_initialisation!=R_status);
3454 U_status=aborted_after_initialisation;
3455 goto U_handled_and_is_not_state_checking;
3458 }
else { assert(m_R.
find(current_U_outgoing_state)); }
3460 if (current_U_incoming_transition_iterator!=
3461 current_U_incoming_transition_iterator_end &&
3463 current_U_incoming_transition_iterator->label())))
3464 { assert(incoming_inert_transition_checking==U_status);
3465 goto U_handled_and_is_not_state_checking;
3467 U_status=state_checking;
3469 else if (state_checking==U_status)
3475 (current_U_incoming_bottom_state_iterator<
3476 B->sta.rt_non_bottom_states
3477 ? *current_U_incoming_bottom_state_iterator++
3481 current_U_incoming_transition_iterator=
3482 s.
ref_state->start_incoming_transitions;
3483 current_U_incoming_transition_iterator_end=
3485 ?
m_aut.get_transitions().end()
3486 : std::next(s.
ref_state)->start_incoming_transitions);
3487 if (current_U_incoming_transition_iterator!=
3488 current_U_incoming_transition_iterator_end &&
3490 current_U_incoming_transition_iterator->label())))
3492 U_status=incoming_inert_transition_checking;
3493 goto U_handled_and_is_not_state_checking;
3496 else if (initialisation ||
3497 aborted_after_initialisation==U_status)
3498 { assert(aborted_after_initialisation==U_status);
3499 goto U_handled_and_is_not_state_checking;
3501 else if constexpr (!initialisation)
3502 { assert(outgoing_action_constellation_check==U_status);
3504 assert(current_U_outgoing_transition_iterator!=
3505 current_U_outgoing_transition_iterator_end);
3507 assert(!
m_aut.is_tau(a) || B->c.onstellation!=C);
3508 assert(splitter_end_unmarked_BLC==splitter->start_marked_BLC);
3513 for (
outgoing_transitions_it out_it=current_U_outgoing_transition_iterator; out_it<current_U_outgoing_transition_iterator->start_same_saC; )
3520 [*current_U_outgoing_transition_iterator->ref.BLC_transitions];
3521 current_U_outgoing_transition_iterator=
3522 current_U_outgoing_transition_iterator->start_same_saC;
3523 ++current_U_outgoing_transition_iterator; assert(
m_states.begin()+t_local.
from()==current_U_outgoing_state.
ref_state);
3525 if (
m_states[t_local.
to()].block->c.onstellation==C &&
3530 else if (current_U_outgoing_transition_iterator==
3531 current_U_outgoing_transition_iterator_end)
3532 { assert(!m_U.
find(current_U_outgoing_state));
3534 m_U.
add_todo(current_U_outgoing_state);
3537 { assert(aborted!=R_status); assert(aborted_after_initialisation!=R_status);
3538 U_status=aborted_after_initialisation;
3539 goto U_handled_and_is_not_state_checking;
3544 goto U_handled_and_is_not_state_checking;
3547 if (current_U_incoming_transition_iterator!=
3548 current_U_incoming_transition_iterator_end &&
3550 current_U_incoming_transition_iterator->label())))
3552 U_status = incoming_inert_transition_checking;
3553 goto U_handled_and_is_not_state_checking;
3555 U_status=state_checking;
3556 }
else { assert(0); }
3557 assert(state_checking==U_status);
3558 if (current_U_incoming_bottom_state_iterator==
3563 assert(0 < std::distance(first_unmarked_bottom_state,
3564 B->sta.rt_non_bottom_states) + m_U.
size());
3565 assert(std::distance(first_unmarked_bottom_state, B->sta.rt_non_bottom_states)+
3567 ptr_to_new_block=split_block_B_into_R_and_BminR<initialisation>
3568 (B, first_unmarked_bottom_state, B->sta.rt_non_bottom_states, m_U);
3574 U_handled_and_is_not_state_checking: assert(state_checking!=U_status ||
3575 current_U_incoming_bottom_state_iterator!=B->sta.rt_non_bottom_states ||
3596 not_all_bottom_states_are_touched(
3598 linked_list<BLC_indicators>::iterator splitter
3604 { assert(!splitter->is_stable());
3607 m_states[
m_aut.get_transitions()[*splitter->start_same_BLC].from()].block);
3608 assert(splitter_end_unmarked_BLC<=splitter->start_marked_BLC);
3615 for(; marked_t_it<splitter->end_same_BLC; ++marked_t_it)
3621 if (first_unmarked_bottom_state<=pos_s)
3623 if (0==s.
ref_state->no_of_outgoing_block_inert_transitions)
3626 first_unmarked_bottom_state++;
3637 assert(splitter->start_same_BLC <= splitter_end_unmarked_BLC);
3640 assert(splitter_end_unmarked_BLC == splitter->start_marked_BLC);
3648 if (0==s.
ref_state->no_of_outgoing_block_inert_transitions)
3651 assert(pos_s<first_unmarked_bottom_state);
3666 return first_unmarked_bottom_state;
3672 void make_transition_non_block_inert(
const transition& t)
3698 const linked_list<BLC_indicators>::iterator splitter)
3700 splitter->make_stable(); assert(splitter->start_same_BLC<splitter->end_same_BLC);
3702 const transition& t=
m_aut.get_transitions()[*splitter->start_same_BLC];
3706 if (splitter!=btc.begin())
3708 linked_list<BLC_indicators>::iterator move_splitter_after=btc.end();
3712 m_aut.get_transitions()[*btc.begin()->start_same_BLC];
3714 m_states[perhaps_inert_t.
to()].block->c.onstellation==
3717 move_splitter_after=btc.begin();
3720 btc.splice_to_after(move_splitter_after, btc, splitter);
3724#ifndef USE_FOUR_WAY_SPLIT
3728 template<
bool initialisation,
class Iterator>
3731 if constexpr (initialisation)
3738 [*splitter->start_same_BLC].to()].block->c.onstellation;
3766 template <
bool initialisation=
false,
3767 class Iterator=linked_list<BLC_indicators>::iterator>
3777 const bool split_off_new_bottom_states=
true)
3789 if constexpr (initialisation) {
3792 assert(!split_off_new_bottom_states);
3794 assert(split_off_new_bottom_states ||
3797 if constexpr (!initialisation) {
3798 assert(
m_states[
m_aut.get_transitions()[*splitter->start_same_BLC].from()].
3800 assert(!splitter->is_stable());
3801 assert(!split_off_new_bottom_states ||
3802 splitter_end_unmarked_BLC==splitter->start_marked_BLC);
3810 block_type* R_block=simple_splitB<initialisation, Iterator>(B, splitter,
3811 first_unmarked_bottom_state, splitter_end_unmarked_BLC, bi); assert(bi == R_block || B == R_block);
3822 linked_list<BLC_indicators>::iterator R_to_U_tau_splitter =
3825 bool make_splitter_stable_early=
false;
3827 if (initialisation || !split_off_new_bottom_states ||
3829 target_constellation<initialisation, Iterator>(splitter)==
3834 make_splitter_stable_early=
true;
3836 if constexpr (!initialisation)
3842 (initialisation || split_off_new_bottom_states ||
3843 splitter_end_unmarked_BLC==splitter->start_marked_BLC))
3845 splitter->make_stable();
3852 skip_transitions_in_splitter=
true;
3855 else if (!initialisation && split_off_new_bottom_states &&
3867 splitter->make_stable();
3871 assert(
nullptr==splitter);
3875 else if constexpr (!initialisation)
3877 { assert(!splitter->is_stable());
3880 splitter->start_marked_BLC=splitter->end_same_BLC;
3888 splitter->end_same_BLC, splitter->end_same_BLC,
false)
3898 skip_transitions_in_splitter=
true;
3900 }
else { assert(0); }
3901 assert(!initialisation || make_splitter_stable_early);
3907 if (initialisation || split_off_new_bottom_states ||
3908 !make_splitter_stable_early || !skip_transitions_in_splitter)
3913 (t=&
m_aut.get_transitions()[*bi->
3914 block.to_constellation.begin()->start_same_BLC],
3924 linked_list<BLC_indicators>::iterator new_inert_BLC_set=
3926 start_inert_BLC,
true);
3927 #if !defined(NDEBUG) || defined(COUNT_WORK_BALANCE)
3929 start_inert_BLC<B->
block.to_constellation.begin()->end_same_BLC)
3933 const transition&perhaps_inert_t=
m_aut.get_transitions()[*start_inert_BLC];
3942 new_inert_BLC_set->work_counter=
3947 (void) new_inert_BLC_set;
3964 #ifndef USE_FOUR_WAY_SPLIT
3965 assert(m_co_splitters_to_be_checked.empty());
3973 (std::next(ssi->ref_state)==
m_states.end())
3975 : std::next(ssi->ref_state)->start_outgoing_transitions; assert(s.
block==bi);
3976 if constexpr (!initialisation)
3982 [*ti->ref.BLC_transitions].from()==ssi->ref_state);
3985 if (!skip_transitions_in_splitter ||
3987 transitions_per_block_to_constellation!=splitter)
3990 *ti->ref.BLC_transitions, old_constellation, new_constellation);
4003 bool non_bottom_state_becomes_bottom_state=
true; assert(
m_branching);
4010 ? *ti->ref.BLC_transitions : ti->ref.transitions]; assert(
m_states.begin()+t.
from()==ssi->ref_state);
4022 make_transition_non_block_inert(t);
4023 if (!initialisation && split_off_new_bottom_states)
4025 const linked_list<BLC_indicators>::iterator new_splitter=
4027 transitions_per_block_to_constellation; assert(R_block->
block.
to_constellation.begin()==new_splitter);
4028 if (R_to_U_tau_splitter==
4031 R_to_U_tau_splitter=new_splitter;
4032 R_to_U_tau_splitter->make_unstable();
4035 assert(R_to_U_tau_splitter==new_splitter);
4036 assert(!R_to_U_tau_splitter->is_stable());
4049 non_bottom_state_becomes_bottom_state=
false;
4052 if (non_bottom_state_becomes_bottom_state)
4053 { assert(initialisation || !split_off_new_bottom_states ||
4063 const std::vector<transition>::iterator it_end =
4064 std::next(ssi->ref_state)>=
m_states.end()
4065 ?
m_aut.get_transitions().end()
4066 : std::next(ssi->ref_state)->start_incoming_transitions;
4067 for(std::vector<transition>::iterator it =
4080 if (
from->block==R_block)
4084 make_transition_non_block_inert(t);
4085 if (!initialisation && split_off_new_bottom_states)
4087 const linked_list<BLC_indicators>::iterator new_splitter=
4089 it)].transitions_per_block_to_constellation; assert(R_block->
block.
to_constellation.begin()==new_splitter);
4092 R_to_U_tau_splitter=new_splitter;
4093 R_to_U_tau_splitter->make_unstable();
4096 assert(R_to_U_tau_splitter==new_splitter);
4097 assert(!R_to_U_tau_splitter->is_stable());
4100 [std::distance(
m_aut.get_transitions().begin(), it)].
4101 ref_outgoing_transitions);
4104 if (
from->no_of_outgoing_block_inert_transitions==0)
4114 if constexpr (!initialisation)
4121 linked_list<BLC_indicators>::iterator
4123 if (inert_ind->start_same_BLC==inert_ind->end_same_BLC)
4124 { assert(inert_ind->is_stable());
4131 m_aut.get_transitions()[*inert_ind->start_same_BLC];
4138 for (std::vector<linked_list<BLC_indicators>::iterator>::iterator