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:
Alexandre Duret-Lutz 2015-03-03 14:44:28 +01:00
parent 19a273929c
commit 0874980574
15 changed files with 419 additions and 147 deletions

View file

@ -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)

View file

@ -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;