mirror of
https://github.com/Z3Prover/z3
synced 2025-04-25 10:05:32 +00:00
update proof formats for new core
- update proof format for quantifier instantiation to track original literals - update proof replay tools with ability to extract proof object The formats and features are subject to heavy revisions. Example ``` (set-option :sat.euf true) (set-option :sat.smt.proof eufproof.smt2) (declare-fun f (Int) Int) (declare-const x Int) (assert (or (= (f (f (f x))) x) (= (f (f x)) x))) (assert (not (= (f (f (f (f (f (f x)))))) x))) (check-sat) ``` eufproof.smt2 is: ``` (declare-fun x () Int) (declare-fun f (Int) Int) (define-const $24 Int (f x)) (define-const $25 Int (f $24)) (define-const $26 Int (f $25)) (define-const $27 Bool (= $26 x)) (define-const $28 Bool (= $25 x)) (assume $27 $28) (define-const $30 Int (f $26)) (define-const $31 Int (f $30)) (define-const $32 Int (f $31)) (define-const $33 Bool (= $32 x)) (assume (not $33)) (declare-fun rup () Proof) (infer (not $33) rup) (declare-fun euf (Bool Bool Proof Proof Proof Proof) Proof) (declare-fun cc (Bool) Proof) (define-const $42 Bool (= $32 $30)) (define-const $43 Proof (cc $42)) (define-const $40 Bool (= $31 $24)) (define-const $41 Proof (cc $40)) (define-const $38 Bool (= $30 $25)) (define-const $39 Proof (cc $38)) (define-const $36 Bool (= $24 $26)) (define-const $37 Proof (cc $36)) (define-const $34 Bool (not $33)) (define-const $44 Proof (euf $34 $28 $37 $39 $41 $43)) (infer (not $28) $33 $44) (infer (not $28) rup) (infer $27 rup) (declare-fun euf (Bool Bool Proof Proof Proof) Proof) (define-const $49 Bool (= $32 $26)) (define-const $50 Proof (cc $49)) (define-const $47 Bool (= $31 $25)) (define-const $48 Proof (cc $47)) (define-const $45 Bool (= $24 $30)) (define-const $46 Proof (cc $45)) (define-const $51 Proof (euf $34 $27 $46 $48 $50)) (infer $33 $51) (infer rup) ``` Example of inspecting proof from Python: ``` from z3 import * def parse(file): s = Solver() set_option("solver.proof.save", True) set_option("solver.proof.check", False) s.from_file(file) for step in s.proof().children(): print(step) parse("../eufproof.smt2") ``` Proof checking (self-validation) is on by default. Proof saving is off by default. You can use the proof logs and the proof terms to retrieve quantifier instantiations from the new core. The self-checker contains a few built-in tuned checkers but falls back to self-checking inferred clauses using SMT.
This commit is contained in:
parent
9782d4a730
commit
107981f099
40 changed files with 295 additions and 153 deletions
|
@ -39,8 +39,19 @@ void check_sat_result::set_reason_unknown(event_handler& eh) {
|
|||
}
|
||||
}
|
||||
|
||||
proof* check_sat_result::get_proof() {
|
||||
if (!m_log.empty() && !m_proof) {
|
||||
app* last = m_log.back();
|
||||
m_log.push_back(to_app(m.get_fact(last)));
|
||||
m_proof = m.mk_clause_trail(m_log.size(), m_log.data());
|
||||
}
|
||||
if (m_proof)
|
||||
return m_proof.get();
|
||||
return get_proof_core();
|
||||
}
|
||||
|
||||
simple_check_sat_result::simple_check_sat_result(ast_manager & m):
|
||||
check_sat_result(m),
|
||||
m_core(m),
|
||||
m_proof(m) {
|
||||
}
|
||||
|
@ -66,7 +77,7 @@ void simple_check_sat_result::get_model_core(model_ref & m) {
|
|||
m = nullptr;
|
||||
}
|
||||
|
||||
proof * simple_check_sat_result::get_proof() {
|
||||
proof * simple_check_sat_result::get_proof_core() {
|
||||
return m_proof;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,12 +39,15 @@ Notes:
|
|||
*/
|
||||
class check_sat_result {
|
||||
protected:
|
||||
unsigned m_ref_count;
|
||||
lbool m_status;
|
||||
ast_manager& m;
|
||||
proof_ref_vector m_log;
|
||||
proof_ref m_proof;
|
||||
unsigned m_ref_count = 0;
|
||||
lbool m_status = l_undef;
|
||||
model_converter_ref m_mc0;
|
||||
double m_time;
|
||||
double m_time = 0;
|
||||
public:
|
||||
check_sat_result():m_ref_count(0), m_status(l_undef), m_time(0) {}
|
||||
check_sat_result(ast_manager& m): m(m), m_log(m), m_proof(m) {}
|
||||
virtual ~check_sat_result() = default;
|
||||
void inc_ref() { m_ref_count++; }
|
||||
void dec_ref() { SASSERT(m_ref_count > 0); m_ref_count--; if (m_ref_count == 0) dealloc(this); }
|
||||
|
@ -59,7 +62,10 @@ public:
|
|||
get_model_core(m);
|
||||
if (m && mc0()) (*mc0())(m);
|
||||
}
|
||||
virtual proof * get_proof() = 0;
|
||||
void log_inference(proof* p) { m_log.push_back(p); }
|
||||
void set_proof(proof* p) { m_proof = p; }
|
||||
proof* get_proof();
|
||||
virtual proof * get_proof_core() = 0;
|
||||
virtual std::string reason_unknown() const = 0;
|
||||
virtual void set_reason_unknown(char const* msg) = 0;
|
||||
void set_reason_unknown(event_handler& eh);
|
||||
|
@ -97,7 +103,7 @@ struct simple_check_sat_result : public check_sat_result {
|
|||
void collect_statistics(statistics & st) const override;
|
||||
void get_unsat_core(expr_ref_vector & r) override;
|
||||
void get_model_core(model_ref & m) override;
|
||||
proof * get_proof() override;
|
||||
proof * get_proof_core() override;
|
||||
std::string reason_unknown() const override;
|
||||
void get_labels(svector<symbol> & r) override;
|
||||
void set_reason_unknown(char const* msg) override { m_unknown = msg; }
|
||||
|
|
|
@ -115,7 +115,8 @@ private:
|
|||
}
|
||||
|
||||
public:
|
||||
combined_solver(solver * s1, solver * s2, params_ref const & p) {
|
||||
combined_solver(solver * s1, solver * s2, params_ref const & p):
|
||||
solver(s1->get_manager()) {
|
||||
m_solver1 = s1;
|
||||
m_solver2 = s2;
|
||||
updt_local_params(p);
|
||||
|
@ -318,11 +319,11 @@ public:
|
|||
return m_solver2->get_trail(max_level);
|
||||
}
|
||||
|
||||
proof * get_proof() override {
|
||||
proof * get_proof_core() override {
|
||||
if (m_use_solver1_results)
|
||||
return m_solver1->get_proof();
|
||||
return m_solver1->get_proof_core();
|
||||
else
|
||||
return m_solver2->get_proof();
|
||||
return m_solver2->get_proof_core();
|
||||
}
|
||||
|
||||
std::string reason_unknown() const override {
|
||||
|
|
|
@ -52,7 +52,7 @@ class solver : public check_sat_result, public user_propagator::core {
|
|||
params_ref m_params;
|
||||
symbol m_cancel_backup_file;
|
||||
public:
|
||||
solver() {}
|
||||
solver(ast_manager& m): check_sat_result(m) {}
|
||||
|
||||
/**
|
||||
\brief Creates a clone of the solver.
|
||||
|
|
|
@ -24,7 +24,7 @@ Notes:
|
|||
|
||||
|
||||
solver_na2as::solver_na2as(ast_manager & m):
|
||||
m(m),
|
||||
solver(m),
|
||||
m_assumptions(m) {
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ Notes:
|
|||
|
||||
class solver_na2as : public solver {
|
||||
protected:
|
||||
ast_manager & m;
|
||||
expr_ref_vector m_assumptions;
|
||||
unsigned_vector m_scopes;
|
||||
void restore_assumptions(unsigned old_sz);
|
||||
|
|
|
@ -102,10 +102,10 @@ public:
|
|||
}
|
||||
|
||||
|
||||
proof * get_proof() override {
|
||||
proof * get_proof_core() override {
|
||||
scoped_watch _t_(m_pool.m_proof_watch);
|
||||
if (!m_proof.get()) {
|
||||
m_proof = m_base->get_proof();
|
||||
m_proof = m_base->get_proof_core();
|
||||
if (m_proof) {
|
||||
elim_aux_assertions pc(m_pred);
|
||||
pc(m, m_proof, m_proof);
|
||||
|
|
|
@ -70,7 +70,7 @@ public:
|
|||
void collect_statistics(statistics & st) const override;
|
||||
void get_unsat_core(expr_ref_vector & r) override;
|
||||
void get_model_core(model_ref & m) override;
|
||||
proof * get_proof() override;
|
||||
proof * get_proof_core() override;
|
||||
std::string reason_unknown() const override;
|
||||
void set_reason_unknown(char const* msg) override;
|
||||
void get_labels(svector<symbol> & r) override {}
|
||||
|
@ -311,9 +311,9 @@ void tactic2solver::get_model_core(model_ref & m) {
|
|||
}
|
||||
}
|
||||
|
||||
proof * tactic2solver::get_proof() {
|
||||
proof * tactic2solver::get_proof_core() {
|
||||
if (m_result.get())
|
||||
return m_result->get_proof();
|
||||
return m_result->get_proof_core();
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue