3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-24 09:35:32 +00:00

add basic built-in consequence finding

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2016-07-28 11:20:17 -07:00
parent b7de813c63
commit 14f29e7265
6 changed files with 200 additions and 13 deletions

View file

@ -17,6 +17,8 @@ Notes:
--*/
#include"solver.h"
#include"model_evaluator.h"
#include"ast_util.h"
unsigned solver::get_num_assertions() const {
NOT_IMPLEMENTED_YET();
@ -38,3 +40,82 @@ void solver::get_assertions(expr_ref_vector& fmls) const {
fmls.push_back(get_assertion(i));
}
}
struct scoped_assumption_push {
expr_ref_vector& m_vec;
scoped_assumption_push(expr_ref_vector& v, expr* e): m_vec(v) { v.push_back(e); }
~scoped_assumption_push() { m_vec.pop_back(); }
};
lbool solver::get_consequences(expr_ref_vector const& asms, expr_ref_vector const& vars, expr_ref_vector& consequences) {
ast_manager& m = asms.get_manager();
lbool is_sat = check_sat(asms);
if (is_sat != l_true) {
return is_sat;
}
model_ref model;
get_model(model);
expr_ref tmp(m), nlit(m), lit(m), val(m);
expr_ref_vector asms1(asms);
model_evaluator eval(*model.get());
unsigned k = 0;
for (unsigned i = 0; i < vars.size(); ++i) {
expr_ref_vector core(m);
tmp = vars[i];
val = eval(tmp);
if (!m.is_value(val)) {
continue;
}
if (m.is_bool(tmp) && is_uninterp_const(tmp)) {
if (m.is_true(val)) {
nlit = m.mk_not(tmp);
lit = tmp;
}
else if (m.is_false(val)) {
nlit = tmp;
lit = m.mk_not(tmp);
}
else {
continue;
}
scoped_assumption_push _scoped_push(asms1, nlit);
is_sat = check_sat(asms1);
switch (is_sat) {
case l_undef:
return is_sat;
case l_true:
break;
case l_false:
get_unsat_core(core);
k = 0;
for (unsigned j = 0; j < core.size(); ++j) {
if (core[j].get() != nlit) {
core[k] = core[j].get();
++k;
}
}
core.resize(k);
consequences.push_back(m.mk_implies(mk_and(core), lit));
break;
}
}
else {
lit = m.mk_eq(tmp, val);
nlit = m.mk_not(lit);
scoped_push _scoped_push(*this);
assert_expr(nlit);
is_sat = check_sat(asms);
switch (is_sat) {
case l_undef:
return is_sat;
case l_true:
break;
case l_false:
get_unsat_core(core);
consequences.push_back(m.mk_implies(mk_and(core), lit));
break;
}
}
}
return l_true;
}

View file

@ -150,12 +150,13 @@ public:
virtual expr * get_assumption(unsigned idx) const = 0;
/**
\brief under assumptions, asms, retrieve set of consequences that fix values for expressions that can be
built from fns. For functions that take 0 arguments, we require that the function returns all consequences
that mention these functions. The consequences are clauses whose first literal constrain one of the
functions from fns and the other literals are negations of literals from asms.
*/
//virtual lbool get_consequences(expr_ref_vector const& asms, func_ref_vector const& fns, expr_ref_vector& consequences);
\brief under assumptions, asms, retrieve set of consequences that
fix values for expressions that can be built from vars.
The consequences are clauses whose first literal constrain one of the
functions from vars and the other literals are negations of literals from asms.
*/
virtual lbool get_consequences(expr_ref_vector const& asms, expr_ref_vector const& vars, expr_ref_vector& consequences);
/**
\brief Display the content of this solver.