minimize_wdba: improve handling of terminal automata
Part of #444. * spot/twaalgos/minimize.cc (minimize_wdba): Terminal automata do not need a product to decide which states are accepting in the DBA. This is faster, and also determinize more formulas of #443. * tests/core/ltl2tgba2.test: Adjust the expected iteration where determinization will be aborted.
This commit is contained in:
parent
48edfd80c2
commit
2d6c7ac045
2 changed files with 32 additions and 16 deletions
|
|
@ -384,7 +384,7 @@ namespace spot
|
||||||
hash_set* non_final;
|
hash_set* non_final;
|
||||||
|
|
||||||
twa_graph_ptr det_a;
|
twa_graph_ptr det_a;
|
||||||
|
bool has_sinks = false;
|
||||||
{
|
{
|
||||||
bool input_is_det = is_deterministic(a);
|
bool input_is_det = is_deterministic(a);
|
||||||
if (input_is_det)
|
if (input_is_det)
|
||||||
|
|
@ -396,13 +396,13 @@ namespace spot
|
||||||
// Find any accepting sink state, to speed up the
|
// Find any accepting sink state, to speed up the
|
||||||
// determinization by merging all states containing a sink
|
// determinization by merging all states containing a sink
|
||||||
// state.
|
// state.
|
||||||
//
|
|
||||||
// We only as consider as "accepting sink" any state
|
|
||||||
// that have an accepting self-loop labeled by true.
|
|
||||||
std::vector<unsigned> acc_sinks;
|
std::vector<unsigned> acc_sinks;
|
||||||
unsigned ns = a->num_states();
|
unsigned ns = a->num_states();
|
||||||
for (unsigned n = 0; n < ns; ++n)
|
if (!a->prop_terminal().is_true())
|
||||||
{
|
{
|
||||||
|
// We only consider as "accepting sink" any state
|
||||||
|
// that has an accepting self-loop labeled by true.
|
||||||
|
for (unsigned n = 0; n < ns; ++n)
|
||||||
for (auto& e: a->out(n))
|
for (auto& e: a->out(n))
|
||||||
if (e.dst == n && e.cond == bddtrue
|
if (e.dst == n && e.cond == bddtrue
|
||||||
&& a->acc().accepting(e.acc))
|
&& a->acc().accepting(e.acc))
|
||||||
|
|
@ -411,6 +411,15 @@ namespace spot
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// All accepting SCCs are terminal.
|
||||||
|
scc_info si(a, scc_info_options::NONE);
|
||||||
|
for (unsigned n = 0; n < ns; ++n)
|
||||||
|
if (si.is_accepting_scc(si.scc_of(n)))
|
||||||
|
acc_sinks.push_back(n);
|
||||||
|
}
|
||||||
|
has_sinks = !acc_sinks.empty();
|
||||||
det_a = tgba_powerset(a, aborter, &acc_sinks);
|
det_a = tgba_powerset(a, aborter, &acc_sinks);
|
||||||
if (!det_a)
|
if (!det_a)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
@ -441,6 +450,13 @@ namespace spot
|
||||||
for (unsigned m = 0; m < scc_count; ++m)
|
for (unsigned m = 0; m < scc_count; ++m)
|
||||||
is_accepting_scc[m] = sm.is_accepting_scc(m);
|
is_accepting_scc[m] = sm.is_accepting_scc(m);
|
||||||
}
|
}
|
||||||
|
else if (a->prop_terminal())
|
||||||
|
{
|
||||||
|
// tgba_powerset has gathered all terminal states on
|
||||||
|
// powerstate 0.
|
||||||
|
if (has_sinks)
|
||||||
|
is_accepting_scc[sm.scc_of(0)] = true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
twa_graph_ptr prod = spot::product(a, det_a, aborter);
|
twa_graph_ptr prod = spot::product(a, det_a, aborter);
|
||||||
|
|
|
||||||
|
|
@ -481,7 +481,7 @@ test 34,0 = `ltl2tgba -B --stats=%s,%d "$f"`
|
||||||
# Issue #444. Because WDBA-minimization disables itself for large
|
# Issue #444. Because WDBA-minimization disables itself for large
|
||||||
# automata, the output is only deterministic up to a certain point,
|
# automata, the output is only deterministic up to a certain point,
|
||||||
# and the goal is to raise that point.
|
# and the goal is to raise that point.
|
||||||
f='(!(G({(a)} |=> {(b)[*9]})))'
|
f='(!(G({(a)} |=> {(b)[*12]})))'
|
||||||
test 11,1 = `ltl2tgba -B --stats=%s,%d "$f"`
|
test 14,1 = `ltl2tgba -B --stats=%s,%d "$f"`
|
||||||
f='(!(G({(a)} |=> {(b)[*10]})))'
|
f='(!(G({(a)} |=> {(b)[*13]})))'
|
||||||
test 12,0 = `ltl2tgba -B --stats=%s,%d "$f"`
|
test 15,0 = `ltl2tgba -B --stats=%s,%d "$f"`
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue