3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-01-18 16:28:56 +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;
}