3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-29 20:05:51 +00:00

wip - add bit-vector validator plugins and logging

This commit is contained in:
Nikolaj Bjorner 2022-10-18 14:50:21 -07:00
parent 464d52babe
commit cdfab8cb13
8 changed files with 272 additions and 23 deletions

View file

@ -395,68 +395,123 @@ namespace bv {
sat::literal leq1(s().num_vars() + 1, false);
sat::literal leq2(s().num_vars() + 2, false);
expr_ref eq1(m), eq2(m);
expr* a1 = nullptr, *a2 = nullptr, *b1 = nullptr, *b2 = nullptr;
if (c.m_kind == bv_justification::kind_t::bv2int) {
eq1 = m.mk_eq(c.a->get_expr(), c.b->get_expr());
eq2 = m.mk_eq(c.a->get_expr(), c.c->get_expr());
ctx.set_tmp_bool_var(leq1.var(), eq1);
ctx.set_tmp_bool_var(leq2.var(), eq1);
a1 = c.a->get_expr();
a2 = c.b->get_expr();
b1 = c.a->get_expr();
b2 = c.c->get_expr();
}
else if (c.m_kind != bv_justification::kind_t::bit2ne) {
expr* e1 = var2expr(c.m_v1);
expr* e2 = var2expr(c.m_v2);
eq1 = m.mk_eq(e1, e2);
a1 = var2expr(c.m_v1);
a2 = var2expr(c.m_v2);
}
if (a1) {
eq1 = m.mk_eq(a1, a2);
ctx.set_tmp_bool_var(leq1.var(), eq1);
}
if (b1) {
eq2 = m.mk_eq(b1, b2);
ctx.set_tmp_bool_var(leq2.var(), eq2);
}
ctx.push(value_trail(m_lit_tail));
ctx.push(restore_size_trail(m_proof_literals));
sat::literal_vector lits;
switch (c.m_kind) {
case bv_justification::kind_t::eq2bit:
lits.push_back(~leq1);
lits.push_back(~c.m_antecedent);
lits.push_back(c.m_consequent);
m_proof_literals.append(lits);
lits.push_back(~leq1);
break;
case bv_justification::kind_t::ne2bit:
get_antecedents(c.m_consequent, c.to_index(), lits, true);
for (auto& lit : lits)
lit.neg();
lits.push_back(c.m_consequent);
m_proof_literals.append(lits);
break;
case bv_justification::kind_t::bit2eq:
get_antecedents(leq1, c.to_index(), lits, true);
for (auto& lit : lits)
lit.neg();
m_proof_literals.append(lits);
lits.push_back(leq1);
break;
case bv_justification::kind_t::bit2ne:
get_antecedents(c.m_consequent, c.to_index(), lits, true);
lits.push_back(~c.m_consequent);
for (auto& lit : lits)
lit.neg();
lits.push_back(c.m_consequent);
m_proof_literals.append(lits);
break;
case bv_justification::kind_t::bv2int:
get_antecedents(leq1, c.to_index(), lits, true);
get_antecedents(leq2, c.to_index(), lits, true);
for (auto& lit : lits)
lit.neg();
m_proof_literals.append(lits);
lits.push_back(leq1);
lits.push_back(leq2);
break;
}
ctx.get_drat().add(lits, status());
m_lit_head = m_lit_tail;
m_lit_tail = m_proof_literals.size();
proof_hint* ph = new (get_region()) proof_hint(c.m_kind, m_proof_literals, m_lit_head, m_lit_tail, a1, a2, b1, b2);
auto st = sat::status::th(m_is_redundant, m.get_basic_family_id(), ph);
ctx.get_drat().add(lits, st);
m_lit_head = m_lit_tail;
// TBD, a proper way would be to delete the lemma after use.
ctx.set_tmp_bool_var(leq1.var(), nullptr);
ctx.set_tmp_bool_var(leq2.var(), nullptr);
}
void solver::asserted(literal l) {
expr* solver::proof_hint::get_hint(euf::solver& s) const {
ast_manager& m = s.get_manager();
sort* proof = m.mk_proof_sort();
expr_ref_vector& args = s.expr_args();
ptr_buffer<sort> sorts;
for (unsigned i = m_lit_head; i < m_lit_tail; ++i)
args.push_back(s.literal2expr(m_proof_literals[i]));
if (m_kind == bv_justification::kind_t::eq2bit)
args.push_back(m.mk_not(m.mk_eq(a1, a2)));
else if (a1)
args.push_back(m.mk_eq(a1, a2));
if (b1)
args.push_back(m.mk_eq(b1, b2));
for (auto * arg : args)
sorts.push_back(arg->get_sort());
symbol th;
switch (m_kind) {
case bv_justification::kind_t::eq2bit:
th = "eq2bit"; break;
case bv_justification::kind_t::ne2bit:
th = "ne2bit"; break;
case bv_justification::kind_t::bit2eq:
th = "bit2eq"; break;
case bv_justification::kind_t::bit2ne:
th = "bit2ne"; break;
case bv_justification::kind_t::bv2int:
th = "bv2int"; break;
}
func_decl* f = m.mk_func_decl(th, sorts.size(), sorts.data(), proof);
return m.mk_app(f, args);
};
void solver::asserted(literal l) {
atom* a = get_bv2a(l.var());
TRACE("bv", tout << "asserted: " << l << "\n";);
if (a) {
force_push();
m_prop_queue.push_back(propagation_item(a));
for (auto p : a->m_bit2occ) {
for (auto p : a->m_bit2occ)
del_eq_occurs(p.first, p.second);
}
}
}