sat-minimize: generalize to any acceptance
This is still missing tests. * src/bin/autfilt.cc: Add a --sat-minimize option. * src/misc/optionmap.cc, src/misc/optionmap.hh: Allow passing strings. * src/twa/acc.cc, src/twa/acc.hh: Add helper functions needed by the SAT-encoder. * src/twaalgos/complete.hh: Typos. * src/twaalgos/dtbasat.hh: Adjust comment. * src/twaalgos/dtgbasat.cc, src/twaalgos/dtgbasat.hh: Generalize to take the target acceptance as input. * src/twaalgos/postproc.cc, src/tests/ltl2tgba.cc: Adjust calls. * src/twaalgos/sbacc.cc, src/twaalgos/sbacc.hh: Don't pass the pointer by reference. * src/tests/acc.cc, src/tests/acc.test: More tests for the acceptance helper function.
This commit is contained in:
parent
19a273929c
commit
0874980574
15 changed files with 419 additions and 147 deletions
|
|
@ -293,18 +293,18 @@ namespace spot
|
|||
}
|
||||
}
|
||||
|
||||
bool acc_cond::accepting(mark_t inf) const
|
||||
bool acc_cond::acc_code::accepting(mark_t inf) const
|
||||
{
|
||||
if (code_.empty())
|
||||
if (empty())
|
||||
return true;
|
||||
return eval(inf, &code_.back());
|
||||
return eval(inf, &back());
|
||||
}
|
||||
|
||||
bool acc_cond::inf_satisfiable(mark_t inf) const
|
||||
bool acc_cond::acc_code::inf_satisfiable(mark_t inf) const
|
||||
{
|
||||
if (code_.empty())
|
||||
if (empty())
|
||||
return true;
|
||||
return inf_eval(inf, &code_.back());
|
||||
return inf_eval(inf, &back());
|
||||
}
|
||||
|
||||
acc_cond::mark_t acc_cond::accepting_sets(mark_t inf) const
|
||||
|
|
@ -602,6 +602,81 @@ namespace spot
|
|||
return {true, i};
|
||||
}
|
||||
|
||||
std::vector<std::vector<int>>
|
||||
acc_cond::acc_code::missing(mark_t inf, bool accepting) const
|
||||
{
|
||||
if (empty())
|
||||
{
|
||||
if (accepting)
|
||||
return {};
|
||||
else
|
||||
return {
|
||||
{}
|
||||
};
|
||||
}
|
||||
auto used = acc_cond::acc_code::used_sets();
|
||||
unsigned c = used.count();
|
||||
|
||||
bdd_allocator ba;
|
||||
int base = ba.allocate_variables(c);
|
||||
assert(base == 0);
|
||||
std::vector<bdd> r;
|
||||
std::vector<unsigned> sets(c);
|
||||
bdd known = bddtrue;
|
||||
for (unsigned i = 0; r.size() < c; ++i)
|
||||
{
|
||||
if (used.has(i))
|
||||
{
|
||||
sets[base] = i;
|
||||
bdd v = bdd_ithvar(base++);
|
||||
r.push_back(v);
|
||||
if (inf.has(i))
|
||||
known &= v;
|
||||
}
|
||||
else
|
||||
{
|
||||
r.push_back(bddfalse);
|
||||
}
|
||||
}
|
||||
|
||||
bdd res = to_bdd_rec(&back(), &r[0]);
|
||||
|
||||
res = bdd_restrict(res, known);
|
||||
|
||||
if (accepting)
|
||||
res = !res;
|
||||
|
||||
if (res == bddfalse)
|
||||
return {};
|
||||
|
||||
minato_isop isop(res);
|
||||
bdd cube;
|
||||
std::vector<std::vector<int>> result;
|
||||
while ((cube = isop.next()) != bddfalse)
|
||||
{
|
||||
std::vector<int> partial;
|
||||
while (cube != bddtrue)
|
||||
{
|
||||
// The acceptance set associated to this BDD variable
|
||||
int s = sets[bdd_var(cube)];
|
||||
|
||||
bdd h = bdd_high(cube);
|
||||
if (h == bddfalse) // Negative variable
|
||||
{
|
||||
partial.push_back(s);
|
||||
cube = bdd_low(cube);
|
||||
}
|
||||
else // Positive variable
|
||||
{
|
||||
partial.push_back(-s - 1);
|
||||
cube = h;
|
||||
}
|
||||
}
|
||||
result.emplace_back(std::move(partial));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool acc_cond::acc_code::is_dnf() const
|
||||
{
|
||||
if (empty() || size() == 2)
|
||||
|
|
|
|||
|
|
@ -674,6 +674,18 @@ namespace spot
|
|||
|
||||
acc_code complement() const;
|
||||
|
||||
// Return a list of acceptance marks needed to close a cycle
|
||||
// that already visit INF infinitely often, so that the cycle is
|
||||
// accepting (ACCEPTING=true) or rejecting (ACCEPTING=false).
|
||||
// Positive values describe positive set.
|
||||
// A negative value x means the set -x-1 must be absent.
|
||||
std::vector<std::vector<int>>
|
||||
missing(mark_t inf, bool accepting) const;
|
||||
|
||||
bool accepting(mark_t inf) const;
|
||||
|
||||
bool inf_satisfiable(mark_t inf) const;
|
||||
|
||||
// Remove all the acceptance sets in rem.
|
||||
//
|
||||
// If MISSING is set, the acceptance sets are assumed to be
|
||||
|
|
@ -766,6 +778,14 @@ namespace spot
|
|||
(s == 2 && code_[1].op == acc_op::Inf && code_[0].mark == all_sets());
|
||||
}
|
||||
|
||||
static acc_code generalized_buchi(unsigned n)
|
||||
{
|
||||
mark_t m((1U << n) - 1);
|
||||
if (n == 8 * sizeof(mark_t::value_t))
|
||||
m = mark_t(-1U);
|
||||
return acc_code::inf(m);
|
||||
}
|
||||
|
||||
bool is_buchi() const
|
||||
{
|
||||
unsigned s = code_.size();
|
||||
|
|
@ -900,11 +920,15 @@ namespace spot
|
|||
return all_;
|
||||
}
|
||||
|
||||
bool accepting(mark_t inf) const;
|
||||
bool accepting(mark_t inf) const
|
||||
{
|
||||
return code_.accepting(inf);
|
||||
}
|
||||
|
||||
// Assume all Fin(x) in the condition a true. Would the resulting
|
||||
// condition (involving only Inf(y)) be satisfiable?
|
||||
bool inf_satisfiable(mark_t inf) const;
|
||||
bool inf_satisfiable(mark_t inf) const
|
||||
{
|
||||
return code_.inf_satisfiable(inf);
|
||||
}
|
||||
|
||||
mark_t accepting_sets(mark_t inf) const;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue