3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-22 16:45:31 +00:00

fixes and rename sls-cc to sls-euf-plugin

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2024-07-15 21:45:30 -07:00
parent 5767dfac49
commit 6bd2a39fb7
10 changed files with 90 additions and 74 deletions

View file

@ -9,9 +9,9 @@ z3_add_component(ast_sls
sls_arith_plugin.cpp
sls_basic_plugin.cpp
sls_bv_plugin.cpp
sls_cc.cpp
sls_context.cpp
sls_engine.cpp
sls_euf_plugin.cpp
sls_smt_solver.cpp
sls_valuation.cpp
COMPONENT_DEPENDENCIES

View file

@ -590,7 +590,7 @@ namespace bv {
rw(v);
rational r;
VERIFY(bv.is_numeral(v, r));
val.set_value(m_tmp, r);
val.set_value(val.eval, r);
break;
}
case OP_BREDAND:
@ -630,14 +630,18 @@ namespace bv {
digit_t sls_eval::random_bits() {
return sls_valuation::random_bits(m_rand);
}
bool sls_eval::repair_down(app* e, unsigned i) {
if (e->get_family_id() == bv.get_family_id() && try_repair_bv(e, i)) {
commit_eval(to_app(e->get_arg(i)));
ctx.new_value_eh(e->get_arg(i));
if (eval_is_correct(e))
commit_eval(e);
else
ctx.new_value_eh(e); // re-queue repair
if (bv.is_bv(e)) {
auto& val = eval(e);
if (val.eval != val.bits()) {
commit_eval(e);
ctx.new_value_eh(e);
}
}
return true;
}
return false;
@ -648,45 +652,45 @@ namespace bv {
case OP_BAND:
SASSERT(e->get_num_args() >= 2);
if (e->get_num_args() == 2)
return try_repair_band(eval_value(e), wval(e, i), wval(e, 1 - i));
return try_repair_band(assign_value(e), wval(e, i), wval(e, 1 - i));
else
return try_repair_band(e, i);
case OP_BOR:
SASSERT(e->get_num_args() >= 2);
if (e->get_num_args() == 2)
return try_repair_bor(eval_value(e), wval(e, i), wval(e, 1 - i));
return try_repair_bor(assign_value(e), wval(e, i), wval(e, 1 - i));
else
return try_repair_bor(e, i);
case OP_BXOR:
SASSERT(e->get_num_args() >= 2);
if (e->get_num_args() == 2)
return try_repair_bxor(eval_value(e), wval(e, i), wval(e, 1 - i));
return try_repair_bxor(assign_value(e), wval(e, i), wval(e, 1 - i));
else
return try_repair_bxor(e, i);
case OP_BADD:
SASSERT(e->get_num_args() >= 2);
if (e->get_num_args() == 2)
return try_repair_add(eval_value(e), wval(e, i), wval(e, 1 - i));
return try_repair_add(assign_value(e), wval(e, i), wval(e, 1 - i));
else
return try_repair_add(e, i);
case OP_BSUB:
return try_repair_sub(eval_value(e), wval(e, 0), wval(e, 1), i);
return try_repair_sub(assign_value(e), wval(e, 0), wval(e, 1), i);
case OP_BMUL:
SASSERT(e->get_num_args() >= 2);
if (e->get_num_args() == 2)
return try_repair_mul(eval_value(e), wval(e, i), eval_value(to_app(e->get_arg(1 - i))));
return try_repair_mul(assign_value(e), wval(e, i), assign_value(to_app(e->get_arg(1 - i))));
else {
auto const& a = wval(e, 0);
auto f = [&](bvect& out, bvval const& c) {
a.set_mul(out, out, c.bits());
};
fold_oper(m_mul_tmp, e, i, f);
return try_repair_mul(eval_value(e), wval(e, i), m_mul_tmp);
return try_repair_mul(assign_value(e), wval(e, i), m_mul_tmp);
}
case OP_BNOT:
return try_repair_bnot(eval_value(e), wval(e, i));
return try_repair_bnot(assign_value(e), wval(e, i));
case OP_BNEG:
return try_repair_bneg(eval_value(e), wval(e, i));
return try_repair_bneg(assign_value(e), wval(e, i));
case OP_BIT0:
return false;
case OP_BIT1:
@ -694,7 +698,7 @@ namespace bv {
case OP_BV2INT:
return false;
case OP_INT2BV:
return try_repair_int2bv(eval_value(e), e->get_arg(0));
return try_repair_int2bv(assign_value(e), e->get_arg(0));
case OP_ULEQ:
if (i == 0)
return try_repair_ule(bval0(e), wval(e, i), wval(e, 1 - i));
@ -736,11 +740,11 @@ namespace bv {
else
return try_repair_sle(!bval0(e), wval(e, i), wval(e, 1 - i));
case OP_BASHR:
return try_repair_ashr(eval_value(e), wval(e, 0), wval(e, 1), i);
return try_repair_ashr(assign_value(e), wval(e, 0), wval(e, 1), i);
case OP_BLSHR:
return try_repair_lshr(eval_value(e), wval(e, 0), wval(e, 1), i);
return try_repair_lshr(assign_value(e), wval(e, 0), wval(e, 1), i);
case OP_BSHL:
return try_repair_shl(eval_value(e), wval(e, 0), wval(e, 1), i);
return try_repair_shl(assign_value(e), wval(e, 0), wval(e, 1), i);
case OP_BIT2BOOL: {
unsigned idx;
expr* arg;
@ -751,37 +755,37 @@ namespace bv {
case OP_BUDIV:
case OP_BUDIV_I:
case OP_BUDIV0:
return try_repair_udiv(eval_value(e), wval(e, 0), wval(e, 1), i);
return try_repair_udiv(assign_value(e), wval(e, 0), wval(e, 1), i);
case OP_BUREM:
case OP_BUREM_I:
case OP_BUREM0:
return try_repair_urem(eval_value(e), wval(e, 0), wval(e, 1), i);
return try_repair_urem(assign_value(e), wval(e, 0), wval(e, 1), i);
case OP_ROTATE_LEFT:
return try_repair_rotate_left(eval_value(e), wval(e, 0), e->get_parameter(0).get_int());
return try_repair_rotate_left(assign_value(e), wval(e, 0), e->get_parameter(0).get_int());
case OP_ROTATE_RIGHT:
return try_repair_rotate_left(eval_value(e), wval(e, 0), wval(e).bw - e->get_parameter(0).get_int());
return try_repair_rotate_left(assign_value(e), wval(e, 0), wval(e).bw - e->get_parameter(0).get_int());
case OP_EXT_ROTATE_LEFT:
return try_repair_rotate_left(eval_value(e), wval(e, 0), wval(e, 1), i);
return try_repair_rotate_left(assign_value(e), wval(e, 0), wval(e, 1), i);
case OP_EXT_ROTATE_RIGHT:
return try_repair_rotate_right(eval_value(e), wval(e, 0), wval(e, 1), i);
return try_repair_rotate_right(assign_value(e), wval(e, 0), wval(e, 1), i);
case OP_ZERO_EXT:
return try_repair_zero_ext(eval_value(e), wval(e, 0));
return try_repair_zero_ext(assign_value(e), wval(e, 0));
case OP_SIGN_EXT:
return try_repair_sign_ext(eval_value(e), wval(e, 0));
return try_repair_sign_ext(assign_value(e), wval(e, 0));
case OP_CONCAT:
return try_repair_concat(eval_value(e), wval(e, 0), wval(e, 1), i);
return try_repair_concat(assign_value(e), wval(e, 0), wval(e, 1), i);
case OP_EXTRACT: {
unsigned hi, lo;
expr* arg;
VERIFY(bv.is_extract(e, lo, hi, arg));
return try_repair_extract(eval_value(e), wval(arg), lo);
return try_repair_extract(assign_value(e), wval(arg), lo);
}
case OP_BUMUL_NO_OVFL:
return try_repair_umul_ovfl(!bval0(e), wval(e, 0), wval(e, 1), i);
case OP_BUMUL_OVFL:
return try_repair_umul_ovfl(bval0(e), wval(e, 0), wval(e, 1), i);
case OP_BCOMP:
return try_repair_comp(eval_value(e), wval(e, 0), wval(e, 1), i);
return try_repair_comp(assign_value(e), wval(e, 0), wval(e, 1), i);
case OP_BUADD_OVFL:
case OP_BNAND:
@ -887,7 +891,7 @@ namespace bv {
}
bool sls_eval::try_repair_band(app* t, unsigned i) {
bvect const& e = eval_value(t);
bvect const& e = assign_value(t);
auto f = [&](bvect& out, bvval const& c) {
for (unsigned j = 0; j < c.nw; ++j)
out[j] &= c.bits()[j];
@ -913,7 +917,7 @@ namespace bv {
}
bool sls_eval::try_repair_bor(app* t, unsigned i) {
bvect const& e = eval_value(t);
bvect const& e = assign_value(t);
auto f = [&](bvect& out, bvval const& c) {
for (unsigned j = 0; j < c.nw; ++j)
out[j] |= c.bits()[j];
@ -935,7 +939,7 @@ namespace bv {
bool sls_eval::try_repair_bxor(app* t, unsigned i) {
bvect const& e = eval_value(t);
bvect const& e = assign_value(t);
auto f = [&](bvect& out, bvval const& c) {
for (unsigned j = 0; j < c.nw; ++j)
out[j] ^= c.bits()[j];
@ -965,7 +969,7 @@ namespace bv {
bool sls_eval::try_repair_add(app* t, unsigned i) {
bvval& a = wval(t, i);
bvect const& e = eval_value(t);
bvect const& e = assign_value(t);
if (m_rand(20) != 0) {
auto f = [&](bvect& out, bvval const& c) {
a.set_add(m_tmp2, m_tmp2, c.bits());
@ -1827,11 +1831,9 @@ namespace bv {
}
bool sls_eval::try_repair_int2bv(bvect const& e, expr* arg) {
expr_ref intval(m);
intval = bv.mk_bv2int(bv.mk_numeral(e.get_value(e.nw), e.bw));
th_rewriter rw(m);
rw(intval);
verbose_stream() << "repair " << mk_pp(arg, m) << " " << intval << "\n";
rational r = e.get_value(e.nw);
arith_util a(m);
expr_ref intval(a.mk_int(r), m);
ctx.set_value(arg, intval);
return true;
}
@ -1906,8 +1908,8 @@ namespace bv {
return false;
if (m.is_bool(e))
return bval0(e) == bval1(e);
if (bv.is_bv(e)) {
auto const& v = wval(e);
if (bv.is_bv(e)) {
auto const& v = eval(e);
return v.eval == v.bits();
}
UNREACHABLE();

View file

@ -123,7 +123,7 @@ namespace bv {
void eval(app* e, sls_valuation& val) const;
bvect const& eval_value(app* e) const { return wval(e).eval; }
bvect const& assign_value(app* e) const { return wval(e).bits(); }
bool bval0(expr* e) const { return ctx.is_true(e); }

View file

@ -558,7 +558,7 @@ namespace sls {
if (m_bool_vars.get(bv, nullptr))
return;
expr* e = ctx.atom(bv);
verbose_stream() << "bool var " << bv << " " << mk_bounded_pp(e, m) << "\n";
// verbose_stream() << "bool var " << bv << " " << mk_bounded_pp(e, m) << "\n";
if (!e)
return;
expr* x, * y;
@ -1048,7 +1048,7 @@ namespace sls {
num_t n;
if (!is_num(v, n))
return;
verbose_stream() << "set value " << w << " " << mk_bounded_pp(e, m) << " " << n << " " << value(w) << "\n";
// verbose_stream() << "set value " << w << " " << mk_bounded_pp(e, m) << " " << n << " " << value(w) << "\n";
if (n == value(w))
return;
update(w, n);

View file

@ -56,7 +56,7 @@ namespace sls {
std::ostream& basic_plugin::display(std::ostream& out) const {
for (auto t : ctx.subterms())
if (is_app(t) && m.is_bool(t) && to_app(t)->get_family_id() == basic_family_id)
out << mk_bounded_pp(t, m) << " " << bval0(t) << " ~ " << bval1(to_app(t)) << "\n";
out << mk_bounded_pp(t, m) << " := " << (bval0(t)?"T":"F") << " eval: " << (bval1(to_app(t))?"T":"F") << "\n";
return out;
}

View file

@ -16,6 +16,7 @@ Author:
--*/
#include "ast/sls/sls_bv_plugin.h"
#include "ast/ast_ll_pp.h"
#include "ast/ast_pp.h"
namespace sls {
@ -124,7 +125,7 @@ namespace sls {
return;
}
}
IF_VERBOSE(3, verbose_stream() << "revert repair: " << mk_bounded_pp(e, m) << "\n");
IF_VERBOSE(0, verbose_stream() << "revert repair: " << mk_bounded_pp(e, m) << "\n");
repair_up(e);
}

View file

@ -14,10 +14,9 @@ Author:
Nikolaj Bjorner (nbjorner) 2024-06-24
--*/
#pragma once
#include "ast/sls/sls_context.h"
#include "ast/sls/sls_cc.h"
#include "ast/sls/sls_euf_plugin.h"
#include "ast/sls/sls_arith_plugin.h"
#include "ast/sls/sls_bv_plugin.h"
#include "ast/sls/sls_basic_plugin.h"
@ -36,7 +35,7 @@ namespace sls {
m_ld(*this),
m_repair_down(m.get_num_asts(), m_gd),
m_repair_up(m.get_num_asts(), m_ld) {
register_plugin(alloc(cc_plugin, *this));
register_plugin(alloc(euf_plugin, *this));
register_plugin(alloc(arith_plugin, *this));
register_plugin(alloc(bv_plugin, *this));
register_plugin(alloc(basic_plugin, *this));
@ -64,6 +63,8 @@ namespace sls {
propagate_boolean_assignment();
// display(verbose_stream());
if (m_new_constraint || !unsat().empty())
return l_undef;
@ -96,7 +97,8 @@ namespace sls {
while (!m_new_constraint && (!m_repair_up.empty() || !m_repair_down.empty())) {
while (!m_repair_down.empty() && !m_new_constraint) {
auto id = m_repair_down.erase_min();
expr* e = term(id);
expr* e = term(id);
// verbose_stream() << "repair down " << mk_bounded_pp(e, m) << "\n";
if (is_app(e)) {
auto p = m_plugins.get(to_app(e)->get_family_id(), nullptr);
if (p)
@ -106,6 +108,7 @@ namespace sls {
while (!m_repair_up.empty() && !m_new_constraint) {
auto id = m_repair_up.erase_min();
expr* e = term(id);
// verbose_stream() << "repair up " << mk_bounded_pp(e, m) << "\n";
if (is_app(e)) {
auto p = m_plugins.get(to_app(e)->get_family_id(), nullptr);
if (p)
@ -205,8 +208,8 @@ namespace sls {
auto v = m_atom2bool_var.get(e->get_id(), sat::null_bool_var);
if (v == sat::null_bool_var) {
v = s.add_var();
register_terms(e);
register_atom(v, e);
register_terms(e);
}
return v;
}
@ -271,11 +274,14 @@ namespace sls {
}
}
);
// verbose_stream() << "new value " << mk_bounded_pp(e, m) << " " << mk_bounded_pp(get_value(e), m) << "\n";
m_repair_down.reserve(e->get_id() + 1);
m_repair_down.insert(e->get_id());
if (!m_repair_down.contains(e->get_id()))
m_repair_down.insert(e->get_id());
for (auto p : parents(e)) {
m_repair_up.reserve(p->get_id() + 1);
m_repair_up.insert(p->get_id());
if (!m_repair_up.contains(p->get_id()))
m_repair_up.insert(p->get_id());
}
}

View file

@ -3,7 +3,7 @@ Copyright (c) 2024 Microsoft Corporation
Module Name:
sls_cc.cpp
sls_euf_plugin.cpp
Abstract:
@ -15,27 +15,27 @@ Author:
--*/
#include "ast/sls/sls_cc.h"
#include "ast/sls/sls_euf_plugin.h"
#include "ast/ast_ll_pp.h"
#include "ast/ast_pp.h"
namespace sls {
cc_plugin::cc_plugin(context& c):
euf_plugin::euf_plugin(context& c):
plugin(c),
m_values(8U, value_hash(*this), value_eq(*this)) {
m_fid = m.mk_family_id("cc");
}
cc_plugin::~cc_plugin() {}
euf_plugin::~euf_plugin() {}
expr_ref cc_plugin::get_value(expr* e) {
expr_ref euf_plugin::get_value(expr* e) {
UNREACHABLE();
return expr_ref(m);
}
void cc_plugin::register_term(expr* e) {
void euf_plugin::register_term(expr* e) {
if (!is_app(e))
return;
if (!is_uninterp(e))
@ -49,14 +49,14 @@ namespace sls {
m_app[f].push_back(a);
}
unsigned cc_plugin::value_hash::operator()(app* t) const {
unsigned euf_plugin::value_hash::operator()(app* t) const {
unsigned r = 0;
for (auto arg : *t)
r *= 3, r += cc.ctx.get_value(arg)->hash();
return r;
}
bool cc_plugin::value_eq::operator()(app* a, app* b) const {
bool euf_plugin::value_eq::operator()(app* a, app* b) const {
SASSERT(a->get_num_args() == b->get_num_args());
for (unsigned i = a->get_num_args(); i-- > 0; )
if (cc.ctx.get_value(a->get_arg(i)) != cc.ctx.get_value(b->get_arg(i)))
@ -64,7 +64,7 @@ namespace sls {
return true;
}
bool cc_plugin::is_sat() {
bool euf_plugin::is_sat() {
for (auto& [f, ts] : m_app) {
if (ts.size() <= 1)
continue;
@ -84,7 +84,7 @@ namespace sls {
return true;
}
bool cc_plugin::propagate() {
bool euf_plugin::propagate() {
bool new_constraint = false;
for (auto & [f, ts] : m_app) {
if (ts.size() <= 1)
@ -101,6 +101,12 @@ namespace sls {
for (unsigned i = t->get_num_args(); i-- > 0; )
ors.push_back(m.mk_not(m.mk_eq(t->get_arg(i), u->get_arg(i))));
ors.push_back(m.mk_eq(t, u));
#if 0
verbose_stream() << "conflict: " << mk_bounded_pp(t, m) << " != " << mk_bounded_pp(u, m) << "\n";
verbose_stream() << "value " << ctx.get_value(t) << " != " << ctx.get_value(u) << "\n";
for (unsigned i = t->get_num_args(); i-- > 0; )
verbose_stream() << ctx.get_value(t->get_arg(i)) << " == " << ctx.get_value(u->get_arg(i)) << "\n";
#endif
ctx.add_constraint(m.mk_or(ors));
new_constraint = true;
}
@ -111,7 +117,7 @@ namespace sls {
return new_constraint;
}
std::ostream& cc_plugin::display(std::ostream& out) const {
std::ostream& euf_plugin::display(std::ostream& out) const {
for (auto& [f, ts] : m_app) {
for (auto* t : ts)
out << mk_bounded_pp(t, m) << "\n";
@ -120,7 +126,7 @@ namespace sls {
return out;
}
void cc_plugin::mk_model(model& mdl) {
void euf_plugin::mk_model(model& mdl) {
expr_ref_vector args(m);
for (auto& [f, ts] : m_app) {
func_interp* fi = alloc(func_interp, m, f->get_arity());

View file

@ -3,7 +3,7 @@ Copyright (c) 2024 Microsoft Corporation
Module Name:
cc_sls.h
sls_euf_plugin.h
Abstract:
@ -21,22 +21,22 @@ Author:
namespace sls {
class cc_plugin : public plugin {
class euf_plugin : public plugin {
obj_map<func_decl, ptr_vector<app>> m_app;
struct value_hash {
cc_plugin& cc;
value_hash(cc_plugin& cc) : cc(cc) {}
euf_plugin& cc;
value_hash(euf_plugin& cc) : cc(cc) {}
unsigned operator()(app* t) const;
};
struct value_eq {
cc_plugin& cc;
value_eq(cc_plugin& cc) : cc(cc) {}
euf_plugin& cc;
value_eq(euf_plugin& cc) : cc(cc) {}
bool operator()(app* a, app* b) const;
};
hashtable<app*, value_hash, value_eq> m_values;
public:
cc_plugin(context& c);
~cc_plugin() override;
euf_plugin(context& c);
~euf_plugin() override;
family_id fid() { return m_fid; }
expr_ref get_value(expr* e) override;
void initialize() override {}

View file

@ -51,6 +51,7 @@ namespace sls {
m_context.check();
if (!m_new_clause_added)
break;
TRACE("sls", display(tout));
m_ddfw.reinit();
m_new_clause_added = false;
}