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:
parent
b7de813c63
commit
14f29e7265
6 changed files with 200 additions and 13 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue