Commit 15c6fd95 authored by Alexandre Duret-Lutz's avatar Alexandre Duret-Lutz
Browse files

alternation: fix detection of non-weak automata

Fixes #218.

* spot/twaalgos/alternation.cc: Adjust check.
* tests/core/alternating.test: Add test case from #218.
* NEWS: Mention the bug.
parent 60bc269f
...@@ -27,6 +27,9 @@ New in spot 2.3.0.dev (not yet released) ...@@ -27,6 +27,9 @@ New in spot 2.3.0.dev (not yet released)
spot::acc_word::op and spot::acc_word::type had to be renamed as spot::acc_word::op and spot::acc_word::type had to be renamed as
spot::acc_word::sub.op and spot::acc_word::sub.type. spot::acc_word::sub.op and spot::acc_word::sub.type.
- alternation_removal() was not always reporting the unsupported
non-weak automata.
New in spot 2.3 (2017-01-19) New in spot 2.3 (2017-01-19)
Build: Build:
......
...@@ -104,33 +104,34 @@ namespace spot ...@@ -104,33 +104,34 @@ namespace spot
unsigned reject_1_count_ = 0; unsigned reject_1_count_ = 0;
std::set<unsigned> true_states_; std::set<unsigned> true_states_;
bool ensure_weak_state(unsigned src, unsigned scc) bool ensure_weak_scc(unsigned scc)
{ {
bool first = true; bool first = true;
bool reject_cycle = false; bool reject_cycle = false;
acc_cond::mark_t m = 0U; acc_cond::mark_t m = 0U;
for (auto& t: aut_->out(src)) for (unsigned src: si_.states_of(scc))
for (unsigned d: aut_->univ_dests(t.dst)) for (auto& t: aut_->out(src))
if (si_.scc_of(d) == scc) for (unsigned d: aut_->univ_dests(t.dst))
{ if (si_.scc_of(d) == scc)
if (first) {
{ if (first)
first = false; {
m = t.acc; first = false;
reject_cycle = !aut_->acc().accepting(m); m = t.acc;
} reject_cycle = !aut_->acc().accepting(m);
else if (m != t.acc) }
{ else if (m != t.acc)
throw std::runtime_error {
("alternation_removal() only work with weak " throw std::runtime_error
"alternating automata"); ("alternation_removal() only work with weak "
} "alternating automata");
// In case of a universal edge we only }
// need to check the first destination // In case of a universal edge we only
// inside the SCC, because the other // need to check the first destination
// have the same t.acc. // inside the SCC, because the other
break; // have the same t.acc.
} break;
}
return reject_cycle; return reject_cycle;
} }
...@@ -155,10 +156,11 @@ namespace spot ...@@ -155,10 +156,11 @@ namespace spot
// decide rejecting/accepting. // decide rejecting/accepting.
assert(si_.is_accepting_scc(n)); assert(si_.is_accepting_scc(n));
unsigned s = si_.states_of(n).front(); // Catch unsupported types of automata
bool rej = ensure_weak_state(s, n); bool rej = ensure_weak_scc(n);
assert(rej == false); assert(rej == false);
// Detect if it is a "true state" // Detect if it is a "true state"
unsigned s = si_.states_of(n).front();
auto& ss = g.state_storage(s); auto& ss = g.state_storage(s);
if (ss.succ == ss.succ_tail) if (ss.succ == ss.succ_tail)
{ {
...@@ -168,14 +170,10 @@ namespace spot ...@@ -168,14 +170,10 @@ namespace spot
} }
} }
} }
else else if (ensure_weak_scc(n))
{ {
for (auto src: si_.states_of(n)) class_of_[n] = reject_more;
if (ensure_weak_state(src, n)) has_reject_more_ = true;
{
class_of_[n] = reject_more;
has_reject_more_ = true;
}
} }
} }
} }
......
...@@ -374,5 +374,25 @@ State: 2 "t" ...@@ -374,5 +374,25 @@ State: 2 "t"
[t] 2 [t] 2
--END-- --END--
EOF EOF
autfilt --tgba in >out 2>&1 && exit 1 autfilt --tgba in 2>out && exit 1
grep 'autfilt.*weak.*alternating' out
cat >in <<EOF
HOA: v1
States: 4
AP: 2 "a" "b"
Start: 0&1
Acceptance: 1 Inf(0)
--BODY--
State: 0 {0}
[0] 2
State: 2 /*{0}*/
[0] 0
State: 1 {0}
[1] 3
State: 3 /*{0}*/
[1] 1
--END--
EOF
autfilt --tgba in 2>out && exit 1
grep 'autfilt.*weak.*alternating' out grep 'autfilt.*weak.*alternating' out
Markdown is supported
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