genem: replace one recursive call by a loop
* spot/twaalgos/genem.cc: In the spot29 implementation for the generic case, when Fin(fo)=true and Fin(fo)=false have to be tested separately, the second test can be done by a loop instead of a recursion, to avoid unnecessary processing of the acceptance condition. Suggested by Jan Strejček.
This commit is contained in:
parent
a3769dfd81
commit
9caba8bfe8
1 changed files with 39 additions and 34 deletions
|
|
@ -84,40 +84,35 @@ namespace spot
|
||||||
acc_cond acc = autacc.restrict_to(sets);
|
acc_cond acc = autacc.restrict_to(sets);
|
||||||
acc = acc.remove(si.common_sets_of(scc), false);
|
acc = acc.remove(si.common_sets_of(scc), false);
|
||||||
|
|
||||||
auto generic_recurse =
|
|
||||||
[&] (const acc_cond& subacc)
|
|
||||||
{
|
|
||||||
int fo = (SPOT_UNLIKELY(genem_version == spot28)
|
|
||||||
? acc.fin_one() : subacc.fin_one());
|
|
||||||
assert(fo >= 0);
|
|
||||||
// Try to accept when Fin(fo) == true
|
|
||||||
acc_cond::mark_t fo_m = {(unsigned) fo};
|
|
||||||
if (!scc_split_check
|
|
||||||
(si, scc, subacc.remove(fo_m, true), run, fo_m))
|
|
||||||
return false;
|
|
||||||
// Try to accept when Fin(fo) == false
|
|
||||||
if (!is_scc_empty(si, scc, subacc.force_inf(fo_m), run, tocut))
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (SPOT_LIKELY(genem_version == spot29))
|
if (SPOT_LIKELY(genem_version == spot29))
|
||||||
{
|
do
|
||||||
acc_cond::acc_code rest = acc_cond::acc_code::f();
|
{
|
||||||
for (const acc_cond& disjunct: acc.top_disjuncts())
|
acc_cond::acc_code rest = acc_cond::acc_code::f();
|
||||||
if (acc_cond::mark_t fu = disjunct.fin_unit())
|
for (const acc_cond& disjunct: acc.top_disjuncts())
|
||||||
{
|
if (acc_cond::mark_t fu = disjunct.fin_unit())
|
||||||
if (!scc_split_check
|
{
|
||||||
(si, scc, disjunct.remove(fu, true), run, fu))
|
if (!scc_split_check
|
||||||
return false;
|
(si, scc, disjunct.remove(fu, true), run, fu))
|
||||||
}
|
return false;
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
rest |= disjunct.get_acceptance();
|
{
|
||||||
}
|
rest |= disjunct.get_acceptance();
|
||||||
if (!rest.is_f() && !generic_recurse(acc_cond(acc.num_sets(), rest)))
|
}
|
||||||
return false;
|
if (rest.is_f())
|
||||||
}
|
break;
|
||||||
|
acc_cond subacc(acc.num_sets(), std::move(rest));
|
||||||
|
int fo = subacc.fin_one();
|
||||||
|
assert(fo >= 0);
|
||||||
|
// Try to accept when Fin(fo) == true
|
||||||
|
acc_cond::mark_t fo_m = {(unsigned) fo};
|
||||||
|
if (!scc_split_check
|
||||||
|
(si, scc, subacc.remove(fo_m, true), run, fo_m))
|
||||||
|
return false;
|
||||||
|
// Try to accept when Fin(fo) == false
|
||||||
|
acc = subacc.force_inf(fo_m);
|
||||||
|
}
|
||||||
|
while (!acc.is_f());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (const acc_cond& disjunct: acc.top_disjuncts())
|
for (const acc_cond& disjunct: acc.top_disjuncts())
|
||||||
|
|
@ -129,7 +124,17 @@ namespace spot
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!generic_recurse(disjunct))
|
int fo = (SPOT_UNLIKELY(genem_version == spot28)
|
||||||
|
? acc.fin_one() : disjunct.fin_one());
|
||||||
|
assert(fo >= 0);
|
||||||
|
// Try to accept when Fin(fo) == true
|
||||||
|
acc_cond::mark_t fo_m = {(unsigned) fo};
|
||||||
|
if (!scc_split_check
|
||||||
|
(si, scc, disjunct.remove(fo_m, true), run, fo_m))
|
||||||
|
return false;
|
||||||
|
// Try to accept when Fin(fo) == false
|
||||||
|
if (!is_scc_empty(si, scc, disjunct.force_inf(fo_m),
|
||||||
|
run, tocut))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue