3
0
Fork 0
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:
Nikolaj Bjorner 2022-10-19 08:34:55 -07:00
parent 77cbd89420
commit 07dd1065db
34 changed files with 505 additions and 122 deletions

View file

@ -432,17 +432,17 @@ namespace sat {
}
void checkpoint() {
if (!m_checkpoint_enabled) return;
if (limit_reached()) {
if (!m_checkpoint_enabled)
return;
if (limit_reached())
throw solver_exception(Z3_CANCELED_MSG);
}
if (memory_exceeded()) {
if (memory_exceeded())
throw solver_exception(Z3_MAX_MEMORY_MSG);
}
}
void set_par(parallel* p, unsigned id);
bool canceled() { return !m_rlimit.inc(); }
config const& get_config() const { return m_config; }
void set_drat(bool d) { m_config.m_drat = d; }
drat& get_drat() { return m_drat; }
drat* get_drat_ptr() { return &m_drat; }
void set_incremental(bool b) { m_config.m_incremental = b; }

View file

@ -661,6 +661,10 @@ public:
return ext;
}
void register_on_clause(void* ctx, user_propagator::on_clause_eh_t& on_clause) override {
ensure_euf()->register_on_clause(ctx, on_clause);
}
void user_propagate_init(
void* ctx,
user_propagator::push_eh_t& push_eh,

View file

@ -772,6 +772,6 @@ namespace bv {
eqs.push_back(~eq);
}
TRACE("bv", for (auto l : eqs) tout << mk_bounded_pp(literal2expr(l), m) << " "; tout << "\n";);
s().add_clause(eqs.size(), eqs.data(), sat::status::th(m_is_redundant, get_id()));
add_clause(eqs);
}
}

View file

@ -25,19 +25,25 @@ namespace euf {
if (m_proof_initialized)
return;
if (s().get_config().m_drat &&
(get_config().m_lemmas2console ||
s().get_config().m_smt_proof_check ||
s().get_config().m_smt_proof.is_non_empty_string())) {
if (m_on_clause)
s().set_drat(true);
if (!s().get_config().m_drat)
return;
get_drat().add_theory(get_id(), symbol("euf"));
get_drat().add_theory(m.get_basic_family_id(), symbol("bool"));
TRACE("euf", tout << "init-proof " << s().get_config().m_smt_proof << "\n");
if (s().get_config().m_smt_proof.is_non_empty_string())
m_proof_out = alloc(std::ofstream, s().get_config().m_smt_proof.str(), std::ios_base::out);
get_drat().set_clause_eh(*this);
m_proof_initialized = true;
}
if (!get_config().m_lemmas2console &&
!s().get_config().m_smt_proof_check &&
!m_on_clause &&
!s().get_config().m_smt_proof.is_non_empty_string())
return;
get_drat().add_theory(get_id(), symbol("euf"));
get_drat().add_theory(m.get_basic_family_id(), symbol("bool"));
if (s().get_config().m_smt_proof.is_non_empty_string())
m_proof_out = alloc(std::ofstream, s().get_config().m_smt_proof.str(), std::ios_base::out);
get_drat().set_clause_eh(*this);
m_proof_initialized = true;
}
/**
@ -135,7 +141,6 @@ namespace euf {
ast_manager& m = s.get_manager();
func_decl_ref cc(m), cc_comm(m);
sort* proof = m.mk_proof_sort();
ptr_buffer<sort> sorts;
expr_ref_vector& args = s.m_expr_args;
args.reset();
if (m_cc_head < m_cc_tail) {
@ -161,12 +166,8 @@ namespace euf {
for (unsigned i = m_cc_head; i < m_cc_tail; ++i) {
auto const& [a, b, ts, comm] = s.m_explain_cc[i];
args.push_back(cc_proof(comm, m.mk_eq(a, b)));
}
for (auto * arg : args)
sorts.push_back(arg->get_sort());
func_decl* f = m.mk_func_decl(th, sorts.size(), sorts.data(), proof);
return m.mk_app(f, args);
}
return m.mk_app(th, args.size(), args.data(), proof);
}
smt_proof_hint* solver::mk_smt_clause(symbol const& n, unsigned nl, literal const* lits) {
@ -304,6 +305,17 @@ namespace euf {
on_lemma(n, lits, st);
on_proof(n, lits, st);
on_check(n, lits, st);
on_clause_eh(n, lits, st);
}
void solver::on_clause_eh(unsigned n, literal const* lits, sat::status st) {
if (!m_on_clause)
return;
m_clause.reset();
for (unsigned i = 0; i < n; ++i)
m_clause.push_back(literal2expr(lits[i]));
auto hint = status2proof_hint(st);
m_on_clause(m_on_clause_ctx, hint, m_clause.size(), m_clause.data());
}
void solver::on_proof(unsigned n, literal const* lits, sat::status st) {

View file

@ -1113,6 +1113,14 @@ namespace euf {
return true;
}
void solver::register_on_clause(
void* ctx,
user_propagator::on_clause_eh_t& on_clause) {
m_on_clause_ctx = ctx;
m_on_clause = on_clause;
init_proof();
}
void solver::user_propagate_init(
void* ctx,
user_propagator::push_eh_t& push_eh,

View file

@ -123,8 +123,10 @@ namespace euf {
sat::lookahead* m_lookahead = nullptr;
ast_manager* m_to_m;
sat::sat_internalizer* m_to_si;
scoped_ptr<euf::ackerman> m_ackerman;
user_solver::solver* m_user_propagator = nullptr;
scoped_ptr<euf::ackerman> m_ackerman;
user_propagator::on_clause_eh_t m_on_clause;
void* m_on_clause_ctx = nullptr;
user_solver::solver* m_user_propagator = nullptr;
th_solver* m_qsolver = nullptr;
unsigned m_generation = 0;
std::string m_reason_unknown;
@ -221,6 +223,7 @@ namespace euf {
void on_lemma(unsigned n, literal const* lits, sat::status st);
void on_proof(unsigned n, literal const* lits, sat::status st);
void on_check(unsigned n, literal const* lits, sat::status st);
void on_clause_eh(unsigned n, literal const* lits, sat::status st);
std::ostream& display_literals(std::ostream& out, unsigned n, sat::literal const* lits);
void display_assume(std::ostream& out, unsigned n, literal const* lits);
void display_inferred(std::ostream& out, unsigned n, literal const* lits, expr* proof_hint);
@ -487,6 +490,11 @@ namespace euf {
// diagnostics
func_decl_ref_vector const& unhandled_functions() { return m_unhandled_functions; }
// clause tracing
void register_on_clause(
void* ctx,
user_propagator::on_clause_eh_t& on_clause);
// user propagator
void user_propagate_init(
void* ctx,

View file

@ -389,26 +389,16 @@ namespace q {
expr* q_proof_hint::get_hint(euf::solver& s) const {
ast_manager& m = s.get_manager();
expr_ref_vector args(m);
ptr_buffer<sort> sorts;
expr_ref binding(m);
sort* range = m.mk_proof_sort();
func_decl* d;
for (unsigned i = 0; i < m_num_bindings; ++i)
args.push_back(m_bindings[i]);
for (expr* arg : args)
sorts.push_back(arg->get_sort());
d = m.mk_func_decl(symbol("bind"), args.size(), sorts.data(), range);
binding = m.mk_app(d, args);
binding = m.mk_app(symbol("bind"), args.size(), args.data(), range);
args.reset();
sorts.reset();
for (unsigned i = 0; i < m_num_literals; ++i)
args.push_back(s.literal2expr(~m_literals[i]));
args.push_back(binding);
for (expr* arg : args)
sorts.push_back(arg->get_sort());
d = m.mk_func_decl(symbol("inst"), args.size(), sorts.data(), range);
return m.mk_app(d, args);
args.push_back(binding);
return m.mk_app(symbol("inst"), args.size(), args.data(), range);
}
}