mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 01:25:31 +00:00
added API to monitor clause inferences
See RELEASE_NOTES for more information examples pending.
This commit is contained in:
parent
77cbd89420
commit
07dd1065db
34 changed files with 505 additions and 122 deletions
|
@ -304,6 +304,16 @@ namespace smt {
|
|||
}
|
||||
m_instances.push_back(pr1);
|
||||
}
|
||||
else if (m_context.on_clause_active()) {
|
||||
expr_ref_vector bindings_e(m), args(m);
|
||||
for (unsigned i = 0; i < num_bindings; ++i)
|
||||
bindings_e.push_back(bindings[i]->get_expr());
|
||||
args.push_back(m.mk_not(q));
|
||||
args.push_back(instance);
|
||||
args.push_back(m.mk_app(symbol("bind"), num_bindings, bindings_e.data(), m.mk_proof_sort()));
|
||||
pr1 = m.mk_app(symbol("inst"), args.size(), args.data(), m.mk_proof_sort());
|
||||
m_instances.push_back(pr1);
|
||||
}
|
||||
TRACE("qi_queue", tout << mk_pp(lemma, m) << "\n#" << lemma->get_id() << ":=\n" << mk_ll_pp(lemma, m););
|
||||
m_stats.m_num_instances++;
|
||||
unsigned gen = get_new_gen(q, generation, ent.m_cost);
|
||||
|
|
|
@ -36,91 +36,113 @@ namespace smt {
|
|||
}
|
||||
}
|
||||
|
||||
proof* clause_proof::justification2proof(justification* j) {
|
||||
return (m.proofs_enabled() && j) ? j->mk_proof(ctx.get_cr()) : nullptr;
|
||||
proof* clause_proof::justification2proof(status st, justification* j) {
|
||||
proof* r = nullptr;
|
||||
if (j)
|
||||
r = j->mk_proof(ctx.get_cr());
|
||||
if (r)
|
||||
return r;
|
||||
if (!m_on_clause_active)
|
||||
return nullptr;
|
||||
switch (st) {
|
||||
case status::assumption:
|
||||
return m.mk_const("assumption", m.mk_proof_sort());
|
||||
case status::lemma:
|
||||
return m.mk_const("rup", m.mk_proof_sort());
|
||||
case status::th_lemma:
|
||||
case status::th_assumption:
|
||||
return m.mk_const("smt", m.mk_proof_sort());
|
||||
case status::deleted:
|
||||
return m.mk_const("del", m.mk_proof_sort());
|
||||
}
|
||||
UNREACHABLE();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void clause_proof::add(clause& c) {
|
||||
if (ctx.get_fparams().m_clause_proof) {
|
||||
justification* j = c.get_justification();
|
||||
proof_ref pr(justification2proof(j), m);
|
||||
CTRACE("mk_clause", pr.get(), tout << mk_bounded_pp(pr, m, 4) << "\n";);
|
||||
update(c, kind2st(c.get_kind()), pr);
|
||||
}
|
||||
if (!ctx.get_fparams().m_clause_proof && !m_on_clause_active)
|
||||
return;
|
||||
justification* j = c.get_justification();
|
||||
auto st = kind2st(c.get_kind());
|
||||
proof_ref pr(justification2proof(st, j), m);
|
||||
CTRACE("mk_clause", pr.get(), tout << mk_bounded_pp(pr, m, 4) << "\n";);
|
||||
update(c, st, pr);
|
||||
}
|
||||
|
||||
void clause_proof::add(unsigned n, literal const* lits, clause_kind k, justification* j) {
|
||||
if (ctx.get_fparams().m_clause_proof) {
|
||||
proof_ref pr(justification2proof(j), m);
|
||||
CTRACE("mk_clause", pr.get(), tout << mk_bounded_pp(pr, m, 4) << "\n";);
|
||||
m_lits.reset();
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
m_lits.push_back(ctx.literal2expr(lits[i]));
|
||||
}
|
||||
update(kind2st(k), m_lits, pr);
|
||||
}
|
||||
if (!ctx.get_fparams().m_clause_proof && !m_on_clause_active)
|
||||
return;
|
||||
auto st = kind2st(k);
|
||||
proof_ref pr(justification2proof(st, j), m);
|
||||
CTRACE("mk_clause", pr.get(), tout << mk_bounded_pp(pr, m, 4) << "\n";);
|
||||
m_lits.reset();
|
||||
for (unsigned i = 0; i < n; ++i)
|
||||
m_lits.push_back(ctx.literal2expr(lits[i]));
|
||||
update(st, m_lits, pr);
|
||||
}
|
||||
|
||||
|
||||
void clause_proof::shrink(clause& c, unsigned new_size) {
|
||||
if (ctx.get_fparams().m_clause_proof) {
|
||||
m_lits.reset();
|
||||
for (unsigned i = 0; i < new_size; ++i) {
|
||||
m_lits.push_back(ctx.literal2expr(c[i]));
|
||||
}
|
||||
update(status::lemma, m_lits, nullptr);
|
||||
for (unsigned i = new_size; i < c.get_num_literals(); ++i) {
|
||||
m_lits.push_back(ctx.literal2expr(c[i]));
|
||||
}
|
||||
update(status::deleted, m_lits, nullptr);
|
||||
}
|
||||
if (!ctx.get_fparams().m_clause_proof && !m_on_clause_active)
|
||||
return;
|
||||
m_lits.reset();
|
||||
for (unsigned i = 0; i < new_size; ++i)
|
||||
m_lits.push_back(ctx.literal2expr(c[i]));
|
||||
proof* p = justification2proof(status::lemma, nullptr);
|
||||
update(status::lemma, m_lits, p);
|
||||
for (unsigned i = new_size; i < c.get_num_literals(); ++i)
|
||||
m_lits.push_back(ctx.literal2expr(c[i]));
|
||||
p = justification2proof(status::deleted, nullptr);
|
||||
update(status::deleted, m_lits, p);
|
||||
}
|
||||
|
||||
void clause_proof::add(literal lit, clause_kind k, justification* j) {
|
||||
if (ctx.get_fparams().m_clause_proof) {
|
||||
m_lits.reset();
|
||||
m_lits.push_back(ctx.literal2expr(lit));
|
||||
proof* pr = justification2proof(j);
|
||||
update(kind2st(k), m_lits, pr);
|
||||
}
|
||||
if (!ctx.get_fparams().m_clause_proof && !m_on_clause_active)
|
||||
return;
|
||||
m_lits.reset();
|
||||
m_lits.push_back(ctx.literal2expr(lit));
|
||||
auto st = kind2st(k);
|
||||
proof* pr = justification2proof(st, j);
|
||||
update(st, m_lits, pr);
|
||||
}
|
||||
|
||||
void clause_proof::add(literal lit1, literal lit2, clause_kind k, justification* j) {
|
||||
if (ctx.get_fparams().m_clause_proof) {
|
||||
m_lits.reset();
|
||||
m_lits.push_back(ctx.literal2expr(lit1));
|
||||
m_lits.push_back(ctx.literal2expr(lit2));
|
||||
proof* pr = justification2proof(j);
|
||||
m_trail.push_back(info(kind2st(k), m_lits, pr));
|
||||
}
|
||||
if (!ctx.get_fparams().m_clause_proof && !m_on_clause_active)
|
||||
return;
|
||||
m_lits.reset();
|
||||
m_lits.push_back(ctx.literal2expr(lit1));
|
||||
m_lits.push_back(ctx.literal2expr(lit2));
|
||||
auto st = kind2st(k);
|
||||
proof* pr = justification2proof(st, j);
|
||||
update(st, m_lits, pr);
|
||||
}
|
||||
|
||||
|
||||
void clause_proof::del(clause& c) {
|
||||
update(c, status::deleted, nullptr);
|
||||
update(c, status::deleted, justification2proof(status::deleted, nullptr));
|
||||
}
|
||||
|
||||
void clause_proof::update(status st, expr_ref_vector& v, proof* p) {
|
||||
TRACE("clause_proof", tout << m_trail.size() << " " << st << " " << v << "\n";);
|
||||
IF_VERBOSE(3, verbose_stream() << st << " " << v << "\n");
|
||||
m_trail.push_back(info(st, v, p));
|
||||
if (ctx.get_fparams().m_clause_proof)
|
||||
m_trail.push_back(info(st, v, p));
|
||||
if (m_on_clause_eh)
|
||||
m_on_clause_eh(m_on_clause_ctx, p, v.size(), v.data());
|
||||
}
|
||||
|
||||
void clause_proof::update(clause& c, status st, proof* p) {
|
||||
if (ctx.get_fparams().m_clause_proof) {
|
||||
m_lits.reset();
|
||||
for (literal lit : c) {
|
||||
m_lits.push_back(ctx.literal2expr(lit));
|
||||
}
|
||||
update(st, m_lits, p);
|
||||
}
|
||||
if (!ctx.get_fparams().m_clause_proof && !m_on_clause_active)
|
||||
return;
|
||||
m_lits.reset();
|
||||
for (literal lit : c)
|
||||
m_lits.push_back(ctx.literal2expr(lit));
|
||||
update(st, m_lits, p);
|
||||
}
|
||||
|
||||
proof_ref clause_proof::get_proof(bool inconsistent) {
|
||||
TRACE("context", tout << "get-proof " << ctx.get_fparams().m_clause_proof << "\n";);
|
||||
if (!ctx.get_fparams().m_clause_proof) {
|
||||
if (!ctx.get_fparams().m_clause_proof)
|
||||
return proof_ref(m);
|
||||
}
|
||||
proof_ref_vector ps(m);
|
||||
for (auto& info : m_trail) {
|
||||
expr_ref fact = mk_or(info.m_clause);
|
||||
|
@ -143,12 +165,10 @@ namespace smt {
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (inconsistent) {
|
||||
if (inconsistent)
|
||||
ps.push_back(m.mk_false());
|
||||
}
|
||||
else {
|
||||
else
|
||||
ps.push_back(m.mk_const("clause-trail-end", m.mk_bool_sort()));
|
||||
}
|
||||
return proof_ref(m.mk_clause_trail(ps.size(), ps.data()), m);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ Revision History:
|
|||
|
||||
#include "smt/smt_theory.h"
|
||||
#include "smt/smt_clause.h"
|
||||
#include "tactic/user_propagator_base.h"
|
||||
|
||||
namespace smt {
|
||||
class context;
|
||||
|
@ -50,14 +51,17 @@ namespace smt {
|
|||
proof_ref m_proof;
|
||||
info(status st, expr_ref_vector& v, proof* p): m_status(st), m_clause(v), m_proof(p, m_clause.m()) {}
|
||||
};
|
||||
context& ctx;
|
||||
ast_manager& m;
|
||||
context& ctx;
|
||||
ast_manager& m;
|
||||
expr_ref_vector m_lits;
|
||||
vector<info> m_trail;
|
||||
vector<info> m_trail;
|
||||
bool m_on_clause_active = false;
|
||||
user_propagator::on_clause_eh_t m_on_clause_eh;
|
||||
void* m_on_clause_ctx = nullptr;
|
||||
void update(status st, expr_ref_vector& v, proof* p);
|
||||
void update(clause& c, status st, proof* p);
|
||||
status kind2st(clause_kind k);
|
||||
proof* justification2proof(justification* j);
|
||||
proof* justification2proof(status st, justification* j);
|
||||
public:
|
||||
clause_proof(context& ctx);
|
||||
void shrink(clause& c, unsigned new_size);
|
||||
|
@ -67,6 +71,12 @@ namespace smt {
|
|||
void add(unsigned n, literal const* lits, clause_kind k, justification* j);
|
||||
void del(clause& c);
|
||||
proof_ref get_proof(bool inconsistent);
|
||||
bool on_clause_active() const { return m_on_clause_active; }
|
||||
void register_on_clause(void* ctx, user_propagator::on_clause_eh_t& on_clause) {
|
||||
m_on_clause_eh = on_clause;
|
||||
m_on_clause_ctx = ctx;
|
||||
m_on_clause_active = !!m_on_clause_eh;
|
||||
}
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, clause_proof::status st);
|
||||
|
|
|
@ -1706,6 +1706,12 @@ namespace smt {
|
|||
|
||||
void get_units(expr_ref_vector& result);
|
||||
|
||||
bool on_clause_active() const { return m_clause_proof.on_clause_active(); }
|
||||
|
||||
void register_on_clause(void* ctx, user_propagator::on_clause_eh_t& on_clause) {
|
||||
m_clause_proof.register_on_clause(ctx, on_clause);
|
||||
}
|
||||
|
||||
/*
|
||||
* user-propagator
|
||||
*/
|
||||
|
|
|
@ -1626,9 +1626,11 @@ namespace smt {
|
|||
}
|
||||
mk_clause(num_lits, lits, mk_justification(justification_proof_wrapper(*this, pr)));
|
||||
}
|
||||
else {
|
||||
else if (pr && on_clause_active())
|
||||
// support logging of quantifier instantiations and other more detailed information
|
||||
mk_clause(num_lits, lits, mk_justification(justification_proof_wrapper(*this, pr)));
|
||||
else
|
||||
mk_clause(num_lits, lits, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void context::mk_root_clause(literal l1, literal l2, proof * pr) {
|
||||
|
|
|
@ -82,7 +82,8 @@ namespace smt {
|
|||
}
|
||||
|
||||
proof * unit_resolution_justification::mk_proof(conflict_resolution & cr) {
|
||||
SASSERT(m_antecedent);
|
||||
if (!m_antecedent)
|
||||
return nullptr;
|
||||
ast_manager& m = cr.get_manager();
|
||||
proof_ref_vector prs(m);
|
||||
proof * pr = cr.get_proof(m_antecedent);
|
||||
|
|
|
@ -260,6 +260,10 @@ namespace smt {
|
|||
m_imp->m_kernel.user_propagate_init(ctx, push_eh, pop_eh, fresh_eh);
|
||||
}
|
||||
|
||||
void kernel::register_on_clause(void* ctx, user_propagator::on_clause_eh_t& on_clause) {
|
||||
m_imp->m_kernel.register_on_clause(ctx, on_clause);
|
||||
}
|
||||
|
||||
void kernel::user_propagate_register_fixed(user_propagator::fixed_eh_t& fixed_eh) {
|
||||
m_imp->m_kernel.user_propagate_register_fixed(fixed_eh);
|
||||
}
|
||||
|
|
|
@ -290,6 +290,8 @@ namespace smt {
|
|||
*/
|
||||
static void collect_param_descrs(param_descrs & d);
|
||||
|
||||
void register_on_clause(void* ctx, user_propagator::on_clause_eh_t& on_clause);
|
||||
|
||||
/**
|
||||
\brief initialize a user-propagator "theory"
|
||||
*/
|
||||
|
|
|
@ -212,6 +212,10 @@ namespace {
|
|||
return m_context.get_trail(max_level);
|
||||
}
|
||||
|
||||
void register_on_clause(void* ctx, user_propagator::on_clause_eh_t& on_clause) override {
|
||||
m_context.register_on_clause(ctx, on_clause);
|
||||
}
|
||||
|
||||
void user_propagate_init(
|
||||
void* ctx,
|
||||
user_propagator::push_eh_t& push_eh,
|
||||
|
|
|
@ -323,7 +323,13 @@ public:
|
|||
user_propagator::eq_eh_t m_diseq_eh;
|
||||
user_propagator::created_eh_t m_created_eh;
|
||||
user_propagator::decide_eh_t m_decide_eh;
|
||||
|
||||
void* m_on_clause_ctx = nullptr;
|
||||
user_propagator::on_clause_eh_t m_on_clause_eh;
|
||||
|
||||
void on_clause_delay_init() {
|
||||
if (m_on_clause_eh)
|
||||
m_ctx->register_on_clause(m_on_clause_ctx, m_on_clause_eh);
|
||||
}
|
||||
|
||||
void user_propagate_delay_init() {
|
||||
if (!m_user_ctx)
|
||||
|
@ -349,6 +355,13 @@ public:
|
|||
m_diseq_eh = nullptr;
|
||||
m_created_eh = nullptr;
|
||||
m_decide_eh = nullptr;
|
||||
m_on_clause_eh = nullptr;
|
||||
m_on_clause_ctx = nullptr;
|
||||
}
|
||||
|
||||
void register_on_clause(void* ctx, user_propagator::on_clause_eh_t& on_clause) override {
|
||||
m_on_clause_ctx = ctx;
|
||||
m_on_clause_eh = on_clause;
|
||||
}
|
||||
|
||||
void user_propagate_init(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue