mirror of
https://github.com/Z3Prover/z3
synced 2025-04-29 11:55:51 +00:00
wip - updates to proof logging and self-checking
move self-checking functionality to inside sat/smt so it can be used on-line and not just off-line. when self-validation fails, use vs, not clause, to check. It allows self-validation without checking and maintaining RUP validation. new options sat.smt.proof.check_rup, sat.smt.proof.check for online validation. z3 sat.smt.proof.check=true sat.euf=true /v:1 sat.smt.proof.check_rup=true /st file.smt2 sat.smt.proof=p.smt2
This commit is contained in:
parent
993ff40826
commit
ac1552d194
40 changed files with 539 additions and 419 deletions
|
@ -20,7 +20,7 @@ Author:
|
|||
|
||||
namespace euf {
|
||||
|
||||
ackerman::ackerman(solver& s, ast_manager& m): s(s), m(m) {
|
||||
ackerman::ackerman(solver& ctx, ast_manager& m): ctx(ctx), m(m) {
|
||||
new_tmp();
|
||||
}
|
||||
|
||||
|
@ -100,31 +100,31 @@ namespace euf {
|
|||
}
|
||||
|
||||
bool ackerman::enable_cc(app* a, app* b) {
|
||||
if (!s.enable_ackerman_axioms(a))
|
||||
if (!ctx.enable_ackerman_axioms(a))
|
||||
return false;
|
||||
if (!s.enable_ackerman_axioms(b))
|
||||
if (!ctx.enable_ackerman_axioms(b))
|
||||
return false;
|
||||
for (expr* arg : *a)
|
||||
if (!s.enable_ackerman_axioms(arg))
|
||||
if (!ctx.enable_ackerman_axioms(arg))
|
||||
return false;
|
||||
for (expr* arg : *b)
|
||||
if (!s.enable_ackerman_axioms(arg))
|
||||
if (!ctx.enable_ackerman_axioms(arg))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ackerman::enable_eq(expr* a, expr* b, expr* c) {
|
||||
return s.enable_ackerman_axioms(a) &&
|
||||
s.enable_ackerman_axioms(b) &&
|
||||
s.enable_ackerman_axioms(c);
|
||||
return ctx.enable_ackerman_axioms(a) &&
|
||||
ctx.enable_ackerman_axioms(b) &&
|
||||
ctx.enable_ackerman_axioms(c);
|
||||
}
|
||||
|
||||
void ackerman::cg_conflict_eh(expr * n1, expr * n2) {
|
||||
if (!is_app(n1) || !is_app(n2))
|
||||
return;
|
||||
if (!s.enable_ackerman_axioms(n1))
|
||||
if (!ctx.enable_ackerman_axioms(n1))
|
||||
return;
|
||||
SASSERT(!s.m_drating);
|
||||
SASSERT(!ctx.m_drating);
|
||||
app* a = to_app(n1);
|
||||
app* b = to_app(n2);
|
||||
if (a->get_decl() != b->get_decl() || a->get_num_args() != b->get_num_args())
|
||||
|
@ -139,7 +139,7 @@ namespace euf {
|
|||
void ackerman::used_eq_eh(expr* a, expr* b, expr* c) {
|
||||
if (a == b || a == c || b == c)
|
||||
return;
|
||||
if (s.m_drating)
|
||||
if (ctx.m_drating)
|
||||
return;
|
||||
if (!enable_eq(a, b, c))
|
||||
return;
|
||||
|
@ -149,7 +149,7 @@ namespace euf {
|
|||
}
|
||||
|
||||
void ackerman::used_cc_eh(app* a, app* b) {
|
||||
if (s.m_drating)
|
||||
if (ctx.m_drating)
|
||||
return;
|
||||
TRACE("ack", tout << "used cc: " << mk_pp(a, m) << " == " << mk_pp(b, m) << "\n";);
|
||||
SASSERT(a->get_decl() == b->get_decl());
|
||||
|
@ -162,7 +162,7 @@ namespace euf {
|
|||
|
||||
void ackerman::gc() {
|
||||
m_num_propagations_since_last_gc++;
|
||||
if (m_num_propagations_since_last_gc <= s.m_config.m_dack_gc)
|
||||
if (m_num_propagations_since_last_gc <= ctx.m_config.m_dack_gc)
|
||||
return;
|
||||
m_num_propagations_since_last_gc = 0;
|
||||
|
||||
|
@ -175,14 +175,14 @@ namespace euf {
|
|||
}
|
||||
|
||||
void ackerman::propagate() {
|
||||
SASSERT(s.s().at_base_lvl());
|
||||
SASSERT(ctx.s().at_base_lvl());
|
||||
auto* n = m_queue;
|
||||
inference* k = nullptr;
|
||||
unsigned num_prop = static_cast<unsigned>(s.s().get_stats().m_conflict * s.m_config.m_dack_factor);
|
||||
unsigned num_prop = static_cast<unsigned>(ctx.s().get_stats().m_conflict * ctx.m_config.m_dack_factor);
|
||||
num_prop = std::min(num_prop, m_table.size());
|
||||
for (unsigned i = 0; i < num_prop; ++i, n = k) {
|
||||
k = n->next();
|
||||
if (n->m_count < s.m_config.m_dack_threshold)
|
||||
if (n->m_count < ctx.m_config.m_dack_threshold)
|
||||
continue;
|
||||
if (n->m_count >= m_high_watermark && num_prop < m_table.size())
|
||||
++num_prop;
|
||||
|
@ -190,13 +190,13 @@ namespace euf {
|
|||
add_cc(n->a, n->b);
|
||||
else
|
||||
add_eq(n->a, n->b, n->c);
|
||||
++s.m_stats.m_ackerman;
|
||||
++ctx.m_stats.m_ackerman;
|
||||
remove(n);
|
||||
}
|
||||
}
|
||||
|
||||
void ackerman::add_cc(expr* _a, expr* _b) {
|
||||
flet<bool> _is_redundant(s.m_is_redundant, true);
|
||||
flet<bool> _is_redundant(ctx.m_is_redundant, true);
|
||||
app* a = to_app(_a);
|
||||
app* b = to_app(_b);
|
||||
TRACE("ack", tout << mk_pp(a, m) << " " << mk_pp(b, m) << "\n";);
|
||||
|
@ -204,24 +204,33 @@ namespace euf {
|
|||
unsigned sz = a->get_num_args();
|
||||
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
expr_ref eq = s.mk_eq(a->get_arg(i), b->get_arg(i));
|
||||
lits.push_back(~s.mk_literal(eq));
|
||||
expr* ai = a->get_arg(i);
|
||||
expr* bi = b->get_arg(i);
|
||||
if (ai != bi) {
|
||||
expr_ref eq = ctx.mk_eq(ai, bi);
|
||||
lits.push_back(~ctx.mk_literal(eq));
|
||||
}
|
||||
}
|
||||
expr_ref eq = s.mk_eq(a, b);
|
||||
lits.push_back(s.mk_literal(eq));
|
||||
s.s().mk_clause(lits, sat::status::th(true, m.get_basic_family_id()));
|
||||
expr_ref eq = ctx.mk_eq(a, b);
|
||||
lits.push_back(ctx.mk_literal(eq));
|
||||
th_proof_hint* ph = ctx.mk_cc_proof_hint(lits, a, b);
|
||||
ctx.s().mk_clause(lits, sat::status::th(true, m.get_basic_family_id(), ph));
|
||||
}
|
||||
|
||||
void ackerman::add_eq(expr* a, expr* b, expr* c) {
|
||||
flet<bool> _is_redundant(s.m_is_redundant, true);
|
||||
if (a == c || b == c)
|
||||
return;
|
||||
flet<bool> _is_redundant(ctx.m_is_redundant, true);
|
||||
sat::literal lits[3];
|
||||
expr_ref eq1(s.mk_eq(a, c), m);
|
||||
expr_ref eq2(s.mk_eq(b, c), m);
|
||||
expr_ref eq3(s.mk_eq(a, b), m);
|
||||
expr_ref eq1(ctx.mk_eq(a, c), m);
|
||||
expr_ref eq2(ctx.mk_eq(b, c), m);
|
||||
expr_ref eq3(ctx.mk_eq(a, b), m);
|
||||
TRACE("ack", tout << mk_pp(a, m) << " " << mk_pp(b, m) << " " << mk_pp(c, m) << "\n";);
|
||||
lits[0] = ~s.mk_literal(eq1);
|
||||
lits[1] = ~s.mk_literal(eq2);
|
||||
lits[2] = s.mk_literal(eq3);
|
||||
s.s().mk_clause(3, lits, sat::status::th(true, m.get_basic_family_id()));
|
||||
lits[0] = ~ctx.mk_literal(eq1);
|
||||
lits[1] = ~ctx.mk_literal(eq2);
|
||||
lits[2] = ctx.mk_literal(eq3);
|
||||
th_proof_hint* ph = ctx.mk_tc_proof_hint(lits);
|
||||
ctx.s().mk_clause(3, lits, sat::status::th(true, m.get_basic_family_id(), ph));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue