Commit 07ee3d2d authored by Alexandre Duret-Lutz's avatar Alexandre Duret-Lutz
Browse files

allow scc_filter() and scc_filter_states() on any TωA

Note however that scc_info does not provide a precise accept/reject
characterization for SCCs when using Fin acceptance.  However whenever
it tells that an SCC is rejecting, scc_filter_states() may safely remove
it.

* src/twaalgos/sccfilter.cc (scc_filter_states): Allow on any TωA.
(scc_filter): Only use acceptance simplifications on TGBA.
* src/tests/unambig.test: Add a co-Büchi test.
parent 332694a4
...@@ -82,6 +82,19 @@ State: 0 ...@@ -82,6 +82,19 @@ State: 0
State: 1 State: 1
[0] 1 {0} [0] 1 {0}
--END-- --END--
HOA: v1
States: 2
Start: 0
AP: 2 "a" "b"
Acceptance: 1 Fin(0)
--BODY--
State: 0
[0] 1 {0}
[1] 1
State: 1
[0] 1 {0}
[!0] 1
--END--
EOF EOF
run 1 $autfilt -q --is-unambiguous input run 1 $autfilt -q --is-unambiguous input
......
...@@ -52,9 +52,9 @@ namespace spot ...@@ -52,9 +52,9 @@ namespace spot
return true; return true;
} }
unsigned accsets(unsigned n) void fix_acceptance(const twa_graph_ptr& out)
{ {
return n; out->copy_acceptance_of(this->si->get_aut());
} }
// Accept all transitions, unmodified // Accept all transitions, unmodified
...@@ -112,7 +112,7 @@ namespace spot ...@@ -112,7 +112,7 @@ namespace spot
cond = bdd_exist(cond, ignoredvars); cond = bdd_exist(cond, ignoredvars);
// Remove the suspension variables only if // Remove the suspension variables only if
// the destination in not in an accepting SCC, // the destination in a rejecting SCC,
// or if we are between SCC with early_susp unset. // or if we are between SCC with early_susp unset.
unsigned u = this->si->scc_of(dst); unsigned u = this->si->scc_of(dst);
if (this->si->is_rejecting_scc(u) if (this->si->is_rejecting_scc(u)
...@@ -192,13 +192,15 @@ namespace spot ...@@ -192,13 +192,15 @@ namespace spot
{ {
} }
unsigned accsets(unsigned n) void fix_acceptance(const twa_graph_ptr& out)
{ {
unsigned scc_count = this->si->scc_count();
auto& acc = this->si->get_aut()->acc(); auto& acc = this->si->get_aut()->acc();
assert(n == acc.num_sets()); if (!acc.is_generalized_buchi())
(void) n; throw std::runtime_error
("simplification of SCC acceptance work only with "
"generalized Büchi acceptance");
unsigned scc_count = this->si->scc_count();
auto used_acc = this->si->used_acc(); auto used_acc = this->si->used_acc();
assert(used_acc.size() == scc_count); assert(used_acc.size() == scc_count);
strip_.resize(scc_count); strip_.resize(scc_count);
...@@ -223,7 +225,8 @@ namespace spot ...@@ -223,7 +225,8 @@ namespace spot
if (cnt[n] < max) if (cnt[n] < max)
strip_[n].remove_some(max - cnt[n]); strip_[n].remove_some(max - cnt[n]);
} }
return max;
out->set_generalized_buchi(max);
} }
filtered_trans trans(unsigned src, unsigned dst, bdd cond, filtered_trans trans(unsigned src, unsigned dst, bdd cond,
...@@ -249,12 +252,8 @@ namespace spot ...@@ -249,12 +252,8 @@ namespace spot
template<class F, typename... Args> template<class F, typename... Args>
twa_graph_ptr scc_filter_apply(const_twa_graph_ptr aut, twa_graph_ptr scc_filter_apply(const_twa_graph_ptr aut,
scc_info* given_si, Args&&... args) scc_info* given_si, Args&&... args)
{ {
if (!aut->acc().is_generalized_buchi())
throw std::runtime_error
("scc_filter() works only with generalized Büchi acceptance");
twa_graph_ptr filtered = make_twa_graph(aut->get_dict()); twa_graph_ptr filtered = make_twa_graph(aut->get_dict());
unsigned in_n = aut->num_states(); // Number of input states. unsigned in_n = aut->num_states(); // Number of input states.
if (in_n == 0) // Nothing to filter. if (in_n == 0) // Nothing to filter.
...@@ -278,8 +277,7 @@ namespace spot ...@@ -278,8 +277,7 @@ namespace spot
else else
inout.push_back(-1U); inout.push_back(-1U);
filtered-> filter.fix_acceptance(filtered);
set_generalized_buchi(filter.accsets(aut->acc().num_sets()));
filtered->new_states(out_n); filtered->new_states(out_n);
for (unsigned isrc = 0; isrc < in_n; ++isrc) for (unsigned isrc = 0; isrc < in_n; ++isrc)
{ {
...@@ -326,14 +324,27 @@ namespace spot ...@@ -326,14 +324,27 @@ namespace spot
scc_info* given_si) scc_info* given_si)
{ {
twa_graph_ptr res; twa_graph_ptr res;
if (remove_all_useless) // acc_filter_simplify only work for generalized Büchi
res = scc_filter_apply<state_filter if (aut->acc().is_generalized_buchi())
<acc_filter_all {
<acc_filter_simplify<>>>>(aut, given_si); if (remove_all_useless)
res = scc_filter_apply<state_filter
<acc_filter_all
<acc_filter_simplify<>>>>(aut, given_si);
else
res = scc_filter_apply<state_filter
<acc_filter_some
<acc_filter_simplify<>>>>(aut, given_si);
}
else else
res = scc_filter_apply<state_filter {
<acc_filter_some if (remove_all_useless)
<acc_filter_simplify<>>>>(aut, given_si); res = scc_filter_apply<state_filter
<acc_filter_all<>>>(aut, given_si);
else
res = scc_filter_apply<state_filter
<acc_filter_some<>>>(aut, given_si);
}
res->merge_transitions(); res->merge_transitions();
res->prop_copy(aut, res->prop_copy(aut,
{ false, // state-based acceptance is not preserved { false, // state-based acceptance is not preserved
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment