mirror of
https://github.com/Z3Prover/z3
synced 2025-04-16 05:48:44 +00:00
add validation code, fix bugs in consequence finder
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
4d9aadde35
commit
c746d46d80
|
@ -403,7 +403,6 @@ namespace smt {
|
||||||
// the previous levels were already inconsistent, or the inconsistency was
|
// the previous levels were already inconsistent, or the inconsistency was
|
||||||
// triggered by an axiom or justification proof wrapper, this two kinds
|
// triggered by an axiom or justification proof wrapper, this two kinds
|
||||||
// of justification are considered level zero.
|
// of justification are considered level zero.
|
||||||
|
|
||||||
if (m_conflict_lvl <= m_ctx.get_search_level()) {
|
if (m_conflict_lvl <= m_ctx.get_search_level()) {
|
||||||
TRACE("conflict", tout << "problem is unsat\n";);
|
TRACE("conflict", tout << "problem is unsat\n";);
|
||||||
if (m_manager.proofs_enabled())
|
if (m_manager.proofs_enabled())
|
||||||
|
|
|
@ -107,11 +107,13 @@ namespace smt {
|
||||||
|
|
||||||
void context::extract_fixed_consequences(unsigned start, obj_map<expr, expr*>& vars, uint_set const& assumptions, expr_ref_vector& conseq) {
|
void context::extract_fixed_consequences(unsigned start, obj_map<expr, expr*>& vars, uint_set const& assumptions, expr_ref_vector& conseq) {
|
||||||
pop_to_search_lvl();
|
pop_to_search_lvl();
|
||||||
|
SASSERT(!inconsistent());
|
||||||
literal_vector const& lits = assigned_literals();
|
literal_vector const& lits = assigned_literals();
|
||||||
unsigned sz = lits.size();
|
unsigned sz = lits.size();
|
||||||
for (unsigned i = start; i < sz; ++i) {
|
for (unsigned i = start; i < sz; ++i) {
|
||||||
extract_fixed_consequences(lits[i], vars, assumptions, conseq);
|
extract_fixed_consequences(lits[i], vars, assumptions, conseq);
|
||||||
}
|
}
|
||||||
|
SASSERT(!inconsistent());
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned context::delete_unfixed(obj_map<expr, expr*>& var2val, expr_ref_vector& unfixed) {
|
unsigned context::delete_unfixed(obj_map<expr, expr*>& var2val, expr_ref_vector& unfixed) {
|
||||||
|
@ -160,6 +162,7 @@ namespace smt {
|
||||||
// Extract equalities that are congruent at the search level.
|
// Extract equalities that are congruent at the search level.
|
||||||
//
|
//
|
||||||
unsigned context::extract_fixed_eqs(obj_map<expr, expr*>& var2val, expr_ref_vector& conseq) {
|
unsigned context::extract_fixed_eqs(obj_map<expr, expr*>& var2val, expr_ref_vector& conseq) {
|
||||||
|
TRACE("context", tout << "extract fixed consequences\n";);
|
||||||
ast_manager& m = m_manager;
|
ast_manager& m = m_manager;
|
||||||
ptr_vector<expr> to_delete;
|
ptr_vector<expr> to_delete;
|
||||||
expr_ref fml(m), eq(m);
|
expr_ref fml(m), eq(m);
|
||||||
|
@ -187,9 +190,10 @@ namespace smt {
|
||||||
}
|
}
|
||||||
eq = mk_eq_atom(k, v);
|
eq = mk_eq_atom(k, v);
|
||||||
internalize_formula(eq, false);
|
internalize_formula(eq, false);
|
||||||
literal lit(get_bool_var(eq), true);
|
literal lit(get_bool_var(eq), false);
|
||||||
literals.push_back(lit);
|
literals.push_back(lit);
|
||||||
mk_clause(literals.size(), literals.c_ptr(), 0);
|
mk_clause(literals.size(), literals.c_ptr(), 0);
|
||||||
|
TRACE("context", display_literals_verbose(tout, literals.size(), literals.c_ptr()););
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (unsigned i = 0; i < to_delete.size(); ++i) {
|
for (unsigned i = 0; i < to_delete.size(); ++i) {
|
||||||
|
@ -247,6 +251,9 @@ namespace smt {
|
||||||
expr* val = it->m_value;
|
expr* val = it->m_value;
|
||||||
push_scope();
|
push_scope();
|
||||||
|
|
||||||
|
TRACE("context", tout << "scope level: " << get_scope_level() << "\n";);
|
||||||
|
SASSERT(!inconsistent());
|
||||||
|
|
||||||
literal lit;
|
literal lit;
|
||||||
if (m.is_bool(e)) {
|
if (m.is_bool(e)) {
|
||||||
lit = literal(get_bool_var(e), m.is_true(val));
|
lit = literal(get_bool_var(e), m.is_true(val));
|
||||||
|
@ -277,19 +284,29 @@ namespace smt {
|
||||||
unfixed.push_back(e);
|
unfixed.push_back(e);
|
||||||
TRACE("context", tout << mk_pp(e, m) << " is unfixed\n";);
|
TRACE("context", tout << mk_pp(e, m) << " is unfixed\n";);
|
||||||
}
|
}
|
||||||
else if (get_assign_level(lit) > get_search_level()) {
|
else if (is_sat == l_true && get_assign_level(lit) > get_search_level()) {
|
||||||
TRACE("context", tout << "Retry fixing: " << mk_pp(e, m) << "\n";);
|
TRACE("context", tout << "Retry fixing: " << mk_pp(e, m) << "\n";);
|
||||||
pop_to_search_lvl();
|
extract_fixed_consequences(num_units, var2val, _assumptions, conseq);
|
||||||
++num_reiterations;
|
++num_reiterations;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TRACE("context", tout << "Fixed: " << mk_pp(e, m) << "\n";);
|
// The state can be labeled as inconsistent when the implied consequence does
|
||||||
|
// not depend on assumptions, then the conflict level sits at the search level
|
||||||
|
// which causes the conflict resolver to decide that the state is unsat.
|
||||||
|
if (l_false == is_sat) {
|
||||||
|
SASSERT(inconsistent());
|
||||||
|
m_conflict = null_b_justification;
|
||||||
|
m_not_l = null_literal;
|
||||||
|
}
|
||||||
|
TRACE("context", tout << "Fixed: " << mk_pp(e, m) << " " << is_sat << "\n";
|
||||||
|
if (is_sat == l_false) display(tout););
|
||||||
|
|
||||||
}
|
}
|
||||||
++num_iterations;
|
++num_iterations;
|
||||||
|
|
||||||
bool apply_slow_pass = model_threshold <= num_iterations || num_iterations <= 2;
|
bool apply_slow_pass = model_threshold <= num_iterations || num_iterations <= 2;
|
||||||
if (apply_slow_pass) {
|
if (apply_slow_pass && is_sat == l_true) {
|
||||||
num_unfixed += delete_unfixed(var2val, unfixed);
|
num_unfixed += delete_unfixed(var2val, unfixed);
|
||||||
// The next time we check the model is after 1.5 additional iterations.
|
// The next time we check the model is after 1.5 additional iterations.
|
||||||
model_threshold *= 3;
|
model_threshold *= 3;
|
||||||
|
@ -320,14 +337,14 @@ namespace smt {
|
||||||
<< ")\n";);
|
<< ")\n";);
|
||||||
}
|
}
|
||||||
TRACE("context", tout << "finishing " << mk_pp(e, m) << "\n";);
|
TRACE("context", tout << "finishing " << mk_pp(e, m) << "\n";);
|
||||||
|
SASSERT(!inconsistent());
|
||||||
if (var2val.contains(e)) {
|
if (var2val.contains(e)) {
|
||||||
TRACE("context", tout << "Fixed value to " << mk_pp(e, m) << " was not processed\n";);
|
TRACE("context", tout << "Fixed value to " << mk_pp(e, m) << " was not processed\n";);
|
||||||
expr_ref fml(m);
|
expr_ref fml(m);
|
||||||
fml = m.mk_eq(e, var2val.find(e));
|
fml = m.mk_eq(e, var2val.find(e));
|
||||||
if (!m_antecedents.contains(lit.var()))
|
if (!m_antecedents.contains(lit.var())) {
|
||||||
{
|
extract_fixed_consequences(lit, var2val, _assumptions, conseq);
|
||||||
extract_fixed_consequences(lit, var2val, _assumptions, conseq);
|
}
|
||||||
}
|
|
||||||
fml = m.mk_implies(antecedent2fml(m_antecedents[lit.var()]), fml);
|
fml = m.mk_implies(antecedent2fml(m_antecedents[lit.var()]), fml);
|
||||||
conseq.push_back(fml);
|
conseq.push_back(fml);
|
||||||
var2val.erase(e);
|
var2val.erase(e);
|
||||||
|
@ -335,7 +352,48 @@ namespace smt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end_search();
|
end_search();
|
||||||
|
DEBUG_CODE(validate_consequences(assumptions, vars, conseq, unfixed););
|
||||||
return l_true;
|
return l_true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void context::validate_consequences(expr_ref_vector const& assumptions, expr_ref_vector const& vars,
|
||||||
|
expr_ref_vector const& conseq, expr_ref_vector const& unfixed) {
|
||||||
|
ast_manager& m = m_manager;
|
||||||
|
expr_ref tmp(m);
|
||||||
|
SASSERT(!inconsistent());
|
||||||
|
for (unsigned i = 0; i < conseq.size(); ++i) {
|
||||||
|
push();
|
||||||
|
for (unsigned j = 0; j < assumptions.size(); ++j) {
|
||||||
|
assert_expr(assumptions[j]);
|
||||||
|
}
|
||||||
|
TRACE("context", tout << "checking: " << mk_pp(conseq[i], m) << "\n";);
|
||||||
|
tmp = m.mk_not(conseq[i]);
|
||||||
|
assert_expr(tmp);
|
||||||
|
lbool is_sat = check();
|
||||||
|
SASSERT(is_sat != l_true);
|
||||||
|
pop(1);
|
||||||
|
}
|
||||||
|
model_ref mdl;
|
||||||
|
for (unsigned i = 0; i < unfixed.size(); ++i) {
|
||||||
|
push();
|
||||||
|
for (unsigned j = 0; j < assumptions.size(); ++j) {
|
||||||
|
assert_expr(assumptions[j]);
|
||||||
|
}
|
||||||
|
TRACE("context", tout << "checking unfixed: " << mk_pp(unfixed[i], m) << "\n";);
|
||||||
|
lbool is_sat = check();
|
||||||
|
SASSERT(is_sat != l_false);
|
||||||
|
if (is_sat == l_true) {
|
||||||
|
get_model(mdl);
|
||||||
|
mdl->eval(unfixed[i], tmp);
|
||||||
|
if (m.is_value(tmp)) {
|
||||||
|
tmp = m.mk_not(m.mk_eq(unfixed[i], tmp));
|
||||||
|
assert_expr(tmp);
|
||||||
|
is_sat = check();
|
||||||
|
SASSERT(is_sat != l_false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pop(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1354,6 +1354,9 @@ namespace smt {
|
||||||
|
|
||||||
expr_ref antecedent2fml(uint_set const& ante);
|
expr_ref antecedent2fml(uint_set const& ante);
|
||||||
|
|
||||||
|
void validate_consequences(expr_ref_vector const& assumptions, expr_ref_vector const& vars,
|
||||||
|
expr_ref_vector const& conseq, expr_ref_vector const& unfixed);
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
context(ast_manager & m, smt_params & fp, params_ref const & p = params_ref());
|
context(ast_manager & m, smt_params & fp, params_ref const & p = params_ref());
|
||||||
|
|
Loading…
Reference in a new issue