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
|
@ -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; }
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue