3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-24 01:25:31 +00:00

fill in missing pieces of proof hint checker for Farkas and RUP

The proof validator based on SMT format proof logs uses RUP to check propositional inferences and has plugins for theory axioms/lemmas.
This commit is contained in:
Nikolaj Bjorner 2022-08-31 05:29:15 -07:00
parent d2b618df23
commit 4abff18e8d
6 changed files with 99 additions and 33 deletions

View file

@ -416,6 +416,8 @@ namespace sat {
void drat::verify(unsigned n, literal const* c) {
if (!m_check_unsat)
return;
if (m_inconsistent)
return;
for (unsigned i = 0; i < n; ++i)
declare(c[i]);
if (is_drup(n, c)) {
@ -690,7 +692,7 @@ namespace sat {
++m_stats.m_num_add;
if (m_check) {
switch (sz) {
case 0: add(); break;
case 0: if (st.is_input()) m_inconsistent = true; else add(); break;
case 1: append(lits[0], st); break;
default: append(mk_clause(sz, lits, st.is_redundant()), st); break;
}

View file

@ -140,11 +140,13 @@ namespace arith {
SASSERT(m_todo.empty());
m_todo.push_back({ mul, e });
rational coeff1;
expr* e1, *e2;
expr* e1, *e2, *e3;
for (unsigned i = 0; i < m_todo.size(); ++i) {
auto [coeff, e] = m_todo[i];
if (a.is_mul(e, e1, e2) && a.is_numeral(e1, coeff1))
m_todo.push_back({coeff*coeff1, e2});
else if (a.is_mul(e, e1, e2) && a.is_uminus(e1, e3) && a.is_numeral(e3, coeff1))
m_todo.push_back({-coeff*coeff1, e2});
else if (a.is_mul(e, e1, e2) && a.is_numeral(e2, coeff1))
m_todo.push_back({coeff*coeff1, e1});
else if (a.is_add(e))
@ -158,6 +160,8 @@ namespace arith {
}
else if (a.is_numeral(e, coeff1))
r.m_coeff += coeff*coeff1;
else if (a.is_uminus(e, e1) && a.is_numeral(e1, coeff1))
r.m_coeff -= coeff*coeff1;
else
add(r, e, coeff);
}
@ -361,8 +365,14 @@ namespace arith {
return out;
}
bool check(expr_ref_vector const& clause, app* jst) override {
bool check(expr_ref_vector const& clause, app* jst, expr_ref_vector& units) override {
reset();
expr_mark pos, neg;
for (expr* e : clause)
if (m.is_not(e, e))
neg.mark(e, true);
else
pos.mark(e, true);
if (jst->get_name() == symbol("farkas")) {
bool even = true;
@ -387,13 +397,24 @@ namespace arith {
}
else
return false;
if (sign && !pos.is_marked(arg)) {
units.push_back(m.mk_not(arg));
pos.mark(arg, false);
}
else if (!sign && !neg.is_marked(arg)) {
units.push_back(arg);
neg.mark(arg, false);
}
}
even = !even;
}
if (check_farkas())
if (check_farkas()) {
return true;
}
IF_VERBOSE(0, verbose_stream() << "did not check farkas\n" << mk_pp(jst, m) << "\n");
IF_VERBOSE(0, verbose_stream() << "did not check farkas\n" << mk_pp(jst, m) << "\n"; display(verbose_stream()); );
return false;
}

View file

@ -35,13 +35,14 @@ namespace euf {
m_map.insert(rule, p);
}
bool proof_checker::check(expr_ref_vector const& clause, expr* e) {
bool proof_checker::check(expr_ref_vector const& clause, expr* e, expr_ref_vector& units) {
if (!e || !is_app(e))
return false;
units.reset();
app* a = to_app(e);
proof_checker_plugin* p = nullptr;
if (m_map.find(a->get_decl()->get_name(), p))
return p->check(clause, a);
return p->check(clause, a, units);
return false;
}

View file

@ -27,7 +27,7 @@ namespace euf {
class proof_checker_plugin {
public:
virtual ~proof_checker_plugin() {}
virtual bool check(expr_ref_vector const& clause, app* jst) = 0;
virtual bool check(expr_ref_vector const& clause, app* jst, expr_ref_vector& units) = 0;
virtual void register_plugins(proof_checker& pc) = 0;
};
@ -39,7 +39,7 @@ namespace euf {
proof_checker(ast_manager& m);
~proof_checker();
void register_plugin(symbol const& rule, proof_checker_plugin*);
bool check(expr_ref_vector const& clause, expr* e);
bool check(expr_ref_vector const& clause, expr* e, expr_ref_vector& units);
};
}