acc: recognize parity acceptance

It has two modes: strict or not.  In strict mode (tested in
hoaparse.test), the acceptance formula has to match exactly the one
given in the HOA spec.  In non-strict mode (tested in accparse2.py)
any equivalent formula is accepted.

* src/twa/acc.cc, src/twa/acc.hh (acc_cond::is_parity): New method.
* src/twaalgos/hoa.cc: Use it.
* src/tests/hoaparse.test: Test it.
* wrap/python/spot_impl.i: Bind it.
* wrap/python/tests/accparse2.py: New file.
* wrap/python/tests/Makefile.am: Add it.
This commit is contained in:
Alexandre Duret-Lutz 2015-05-19 22:22:53 +02:00
parent 704eaf26c2
commit 04171207e6
7 changed files with 287 additions and 0 deletions

View file

@ -526,6 +526,76 @@ namespace spot
SPOT_UNREACHABLE();
return bddfalse;
}
static bool
equiv_codes(const acc_cond::acc_code& lhs,
const acc_cond::acc_code& rhs)
{
auto used = lhs.used_sets() | rhs.used_sets();
unsigned c = used.count();
unsigned umax = used.max_set();
bdd_allocator ba;
int base = ba.allocate_variables(c);
assert(base == 0);
std::vector<bdd> r;
for (unsigned i = 0; r.size() < umax; ++i)
if (used.has(i))
r.push_back(bdd_ithvar(base++));
else
r.push_back(bddfalse);
return to_bdd_rec(&lhs.back(), &r[0]) == to_bdd_rec(&rhs.back(), &r[0]);
}
}
bool acc_cond::is_parity(bool& max, bool& odd, bool equiv) const
{
unsigned sets = num_;
if (sets == 0)
{
max = false;
odd = false;
return is_false();
}
if (is_true())
return false;
acc_cond::mark_t u_inf;
acc_cond::mark_t u_fin;
std::tie(u_inf, u_fin) = code_.used_inf_fin_sets();
odd = !u_inf.has(0);
for (auto s: u_inf.sets())
if ((s & 1) != odd)
return false;
auto max_code = acc_code::parity(true, odd, sets);
if (max_code == code_)
{
max = true;
return true;
}
auto min_code = acc_code::parity(false, odd, sets);
if (min_code == code_)
{
max = false;
return true;
}
if (!equiv)
return false;
if (equiv_codes(code_, max_code))
{
max = true;
return true;
}
if (equiv_codes(code_, min_code))
{
max = false;
return true;
}
return false;
}
acc_cond::acc_code acc_cond::acc_code::to_dnf() const

View file

@ -905,6 +905,13 @@ namespace spot
// Return the number of Inf in each pair.
bool is_generalized_rabin(std::vector<unsigned>& pairs) const;
// If EQUIV is false, this return true iff the acceptance
// condition is a parity condition written in the canonical way
// given in the HOA specifications. If EQUIV is true, then we
// check whether the condition is logically equivalent to some
// parity acceptance condition.
bool is_parity(bool& max, bool& odd, bool equiv = false) const;
static acc_code generalized_buchi(unsigned n)
{
mark_t m((1U << n) - 1);