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:
parent
464d52babe
commit
cdfab8cb13
8 changed files with 272 additions and 23 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue