3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-03-09 23:00:30 +00:00

better equality solver for bit-vectors

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2024-07-29 21:02:57 -07:00
parent 16fb86b636
commit fd66d2f26c
7 changed files with 123 additions and 5 deletions

View file

@ -212,9 +212,11 @@ namespace polysat {
sat::check_result core::check() {
lbool r = l_true;
verbose_stream() << "check-propagate\n";
if (propagate())
return sat::check_result::CR_CONTINUE;
verbose_stream() << "check-assign-variable\n";
switch (assign_variable()) {
case l_true:
break;
@ -228,6 +230,7 @@ namespace polysat {
break;
}
verbose_stream() << "check-saturate\n";
saturation saturate(*this);
switch (saturate()) {
case l_true:
@ -240,7 +243,8 @@ namespace polysat {
r = l_undef;
break;
}
verbose_stream() << "check-refine\n";
switch (m_monomials.refine()) {
case l_true:
break;
@ -253,6 +257,7 @@ namespace polysat {
break;
}
verbose_stream() << "check-blast\n";
switch (m_monomials.bit_blast()) {
case l_true:
break;

View file

@ -456,6 +456,8 @@ namespace polysat {
auto rv = c.subst(r);
auto& C = c.cs();
verbose_stream() << "saturate and: " << p << " & " << q << " = " << r << "\n";
if (!pv.is_val() || !qv.is_val() || !rv.is_val())
return false;

View file

@ -359,7 +359,9 @@ namespace polysat {
if (a.degree(v) < r.degree(v))
return;
verbose_stream() << "resolve: " << a << " = " << b << " => " << r << "\n";
add_clause("ax + b = 0 & cx + d = 0 ==> cb - da = 0", { i.dep(), j.dep(), C.eq(r) }, true);
exit(0);
}

View file

@ -868,7 +868,7 @@ v0[19] := 0 v0 [-131062 ; 0[ := [-131062;0[ src ~4 <= 43691*v0;
}
}
IF_VERBOSE(1, {
IF_VERBOSE(3, {
for (auto const& e : m_explain)
if (e.mark)
display_explain(verbose_stream() << "redundant: ", e) << "\n";

View file

@ -18,6 +18,7 @@ Author:
#include "params/bv_rewriter_params.hpp"
#include "sat/smt/polysat_solver.h"
#include "sat/smt/euf_solver.h"
#include "ast/rewriter/bit_blaster/bit_blaster.h"
namespace polysat {
@ -159,7 +160,9 @@ namespace polysat {
m_delayed_axioms.push_back(a);
ctx.push(push_back_vector(m_delayed_axioms));
break;
case OP_BIT2BOOL:
internalize_bit2bool(a);
break;
default:
IF_VERBOSE(0, verbose_stream() << mk_pp(a, m) << "\n");
NOT_IMPLEMENTED_YET();
@ -286,6 +289,16 @@ namespace polysat {
m_core.shl(expr2pdd(x), expr2pdd(y), expr2pdd(n));
}
void solver::internalize_bit2bool(app* n) {
expr* b = nullptr;
unsigned idx;
VERIFY(bv.is_bit2bool(n, b, idx));
pdd p = expr2pdd(b);
auto sc = m_core.bit(p, idx);
add_axiom("bit2bool", { eq_internalize(n, constraint2expr(sc)) });
}
bool solver::propagate_delayed_axioms() {
if (m_delayed_axioms_qhead == m_delayed_axioms.size())
return false;
@ -687,7 +700,7 @@ namespace polysat {
void solver::internalize_mul(app* a) {
vector<dd::pdd> args;
for (expr* arg : *to_app(a))
for (expr* arg : *a)
args.push_back(expr2pdd(arg));
if (args.size() == 1) {
internalize_set(a, args[0]);
@ -701,6 +714,29 @@ namespace polysat {
internalize_set(a, args[0] * args[1]);
return;
}
#if 0
// experiment with eagerly bit-blasting multiplication.
if (args.size() == 2) {
unsigned sz = bv.get_bv_size(a);
expr_ref_vector xs(m), ys(m), zs(m);
for (unsigned i = 0; i < sz; ++i) {
xs.push_back(bv.mk_bit2bool(a->get_arg(0), i));
ys.push_back(bv.mk_bit2bool(a->get_arg(1), i));
}
bit_blaster_params p;
bit_blaster bb(m, p);
bb.mk_multiplier(xs.size(), xs.data(), ys.data(), zs);
pdd z = expr2pdd(a);
for (unsigned i = 0; i < sz; ++i) {
// sat::literal bit_i = ctx.internalize(zs.get(i), false, false);
auto sc = m_core.bit(z, i);
add_axiom("mul", { eq_internalize(constraint2expr(sc), zs.get(i)) });
}
return;
}
#endif
auto pv = m_core.mul(args.size(), args.data());
m_pddvar2var.setx(pv, get_th_var(a), UINT_MAX);
internalize_set(a, m_core.var(pv));