3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-27 08:28:44 +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_arith_plugin.cpp
sls_basic_plugin.cpp sls_basic_plugin.cpp
sls_bv_plugin.cpp sls_bv_plugin.cpp
sls_cc.cpp
sls_context.cpp sls_context.cpp
sls_engine.cpp sls_engine.cpp
sls_euf_plugin.cpp
sls_smt_solver.cpp sls_smt_solver.cpp
sls_valuation.cpp sls_valuation.cpp
COMPONENT_DEPENDENCIES COMPONENT_DEPENDENCIES

View file

@ -590,7 +590,7 @@ namespace bv {
rw(v); rw(v);
rational r; rational r;
VERIFY(bv.is_numeral(v, r)); VERIFY(bv.is_numeral(v, r));
val.set_value(m_tmp, r); val.set_value(val.eval, r);
break; break;
} }
case OP_BREDAND: case OP_BREDAND:
@ -633,11 +633,15 @@ namespace bv {
bool sls_eval::repair_down(app* e, unsigned i) { bool sls_eval::repair_down(app* e, unsigned i) {
if (e->get_family_id() == bv.get_family_id() && try_repair_bv(e, 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)); ctx.new_value_eh(e->get_arg(i));
if (eval_is_correct(e)) if (bv.is_bv(e)) {
commit_eval(e); auto& val = eval(e);
else if (val.eval != val.bits()) {
ctx.new_value_eh(e); // re-queue repair commit_eval(e);
ctx.new_value_eh(e);
}
}
return true; return true;
} }
return false; return false;
@ -648,45 +652,45 @@ namespace bv {
case OP_BAND: case OP_BAND:
SASSERT(e->get_num_args() >= 2); SASSERT(e->get_num_args() >= 2);
if (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 else
return try_repair_band(e, i); return try_repair_band(e, i);
case OP_BOR: case OP_BOR:
SASSERT(e->get_num_args() >= 2); SASSERT(e->get_num_args() >= 2);
if (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 else
return try_repair_bor(e, i); return try_repair_bor(e, i);
case OP_BXOR: case OP_BXOR:
SASSERT(e->get_num_args() >= 2); SASSERT(e->get_num_args() >= 2);
if (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 else
return try_repair_bxor(e, i); return try_repair_bxor(e, i);
case OP_BADD: case OP_BADD:
SASSERT(e->get_num_args() >= 2); SASSERT(e->get_num_args() >= 2);
if (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 else
return try_repair_add(e, i); return try_repair_add(e, i);
case OP_BSUB: 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: case OP_BMUL:
SASSERT(e->get_num_args() >= 2); SASSERT(e->get_num_args() >= 2);
if (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 { else {
auto const& a = wval(e, 0); auto const& a = wval(e, 0);
auto f = [&](bvect& out, bvval const& c) { auto f = [&](bvect& out, bvval const& c) {
a.set_mul(out, out, c.bits()); a.set_mul(out, out, c.bits());
}; };
fold_oper(m_mul_tmp, e, i, f); 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: 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: 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: case OP_BIT0:
return false; return false;
case OP_BIT1: case OP_BIT1:
@ -694,7 +698,7 @@ namespace bv {
case OP_BV2INT: case OP_BV2INT:
return false; return false;
case OP_INT2BV: 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: case OP_ULEQ:
if (i == 0) if (i == 0)
return try_repair_ule(bval0(e), wval(e, i), wval(e, 1 - i)); return try_repair_ule(bval0(e), wval(e, i), wval(e, 1 - i));
@ -736,11 +740,11 @@ namespace bv {
else else
return try_repair_sle(!bval0(e), wval(e, i), wval(e, 1 - i)); return try_repair_sle(!bval0(e), wval(e, i), wval(e, 1 - i));
case OP_BASHR: 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: 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: 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: { case OP_BIT2BOOL: {
unsigned idx; unsigned idx;
expr* arg; expr* arg;
@ -751,37 +755,37 @@ namespace bv {
case OP_BUDIV: case OP_BUDIV:
case OP_BUDIV_I: case OP_BUDIV_I:
case OP_BUDIV0: 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:
case OP_BUREM_I: case OP_BUREM_I:
case OP_BUREM0: 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: 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: 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: 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: 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: 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: 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: 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: { case OP_EXTRACT: {
unsigned hi, lo; unsigned hi, lo;
expr* arg; expr* arg;
VERIFY(bv.is_extract(e, lo, hi, 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: case OP_BUMUL_NO_OVFL:
return try_repair_umul_ovfl(!bval0(e), wval(e, 0), wval(e, 1), i); return try_repair_umul_ovfl(!bval0(e), wval(e, 0), wval(e, 1), i);
case OP_BUMUL_OVFL: case OP_BUMUL_OVFL:
return try_repair_umul_ovfl(bval0(e), wval(e, 0), wval(e, 1), i); return try_repair_umul_ovfl(bval0(e), wval(e, 0), wval(e, 1), i);
case OP_BCOMP: 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_BUADD_OVFL:
case OP_BNAND: case OP_BNAND:
@ -887,7 +891,7 @@ namespace bv {
} }
bool sls_eval::try_repair_band(app* t, unsigned i) { 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) { auto f = [&](bvect& out, bvval const& c) {
for (unsigned j = 0; j < c.nw; ++j) for (unsigned j = 0; j < c.nw; ++j)
out[j] &= c.bits()[j]; out[j] &= c.bits()[j];
@ -913,7 +917,7 @@ namespace bv {
} }
bool sls_eval::try_repair_bor(app* t, unsigned i) { 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) { auto f = [&](bvect& out, bvval const& c) {
for (unsigned j = 0; j < c.nw; ++j) for (unsigned j = 0; j < c.nw; ++j)
out[j] |= c.bits()[j]; out[j] |= c.bits()[j];
@ -935,7 +939,7 @@ namespace bv {
bool sls_eval::try_repair_bxor(app* t, unsigned i) { 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) { auto f = [&](bvect& out, bvval const& c) {
for (unsigned j = 0; j < c.nw; ++j) for (unsigned j = 0; j < c.nw; ++j)
out[j] ^= c.bits()[j]; out[j] ^= c.bits()[j];
@ -965,7 +969,7 @@ namespace bv {
bool sls_eval::try_repair_add(app* t, unsigned i) { bool sls_eval::try_repair_add(app* t, unsigned i) {
bvval& a = wval(t, i); bvval& a = wval(t, i);
bvect const& e = eval_value(t); bvect const& e = assign_value(t);
if (m_rand(20) != 0) { if (m_rand(20) != 0) {
auto f = [&](bvect& out, bvval const& c) { auto f = [&](bvect& out, bvval const& c) {
a.set_add(m_tmp2, m_tmp2, c.bits()); 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) { bool sls_eval::try_repair_int2bv(bvect const& e, expr* arg) {
expr_ref intval(m); rational r = e.get_value(e.nw);
intval = bv.mk_bv2int(bv.mk_numeral(e.get_value(e.nw), e.bw)); arith_util a(m);
th_rewriter rw(m); expr_ref intval(a.mk_int(r), m);
rw(intval);
verbose_stream() << "repair " << mk_pp(arg, m) << " " << intval << "\n";
ctx.set_value(arg, intval); ctx.set_value(arg, intval);
return true; return true;
} }
@ -1907,7 +1909,7 @@ namespace bv {
if (m.is_bool(e)) if (m.is_bool(e))
return bval0(e) == bval1(e); return bval0(e) == bval1(e);
if (bv.is_bv(e)) { if (bv.is_bv(e)) {
auto const& v = wval(e); auto const& v = eval(e);
return v.eval == v.bits(); return v.eval == v.bits();
} }
UNREACHABLE(); UNREACHABLE();

View file

@ -123,7 +123,7 @@ namespace bv {
void eval(app* e, sls_valuation& val) const; 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); } 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)) if (m_bool_vars.get(bv, nullptr))
return; return;
expr* e = ctx.atom(bv); 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) if (!e)
return; return;
expr* x, * y; expr* x, * y;
@ -1048,7 +1048,7 @@ namespace sls {
num_t n; num_t n;
if (!is_num(v, n)) if (!is_num(v, n))
return; 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)) if (n == value(w))
return; return;
update(w, n); update(w, n);

View file

@ -56,7 +56,7 @@ namespace sls {
std::ostream& basic_plugin::display(std::ostream& out) const { std::ostream& basic_plugin::display(std::ostream& out) const {
for (auto t : ctx.subterms()) for (auto t : ctx.subterms())
if (is_app(t) && m.is_bool(t) && to_app(t)->get_family_id() == basic_family_id) 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; return out;
} }

View file

@ -16,6 +16,7 @@ Author:
--*/ --*/
#include "ast/sls/sls_bv_plugin.h" #include "ast/sls/sls_bv_plugin.h"
#include "ast/ast_ll_pp.h" #include "ast/ast_ll_pp.h"
#include "ast/ast_pp.h"
namespace sls { namespace sls {
@ -124,7 +125,7 @@ namespace sls {
return; 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); repair_up(e);
} }

View file

@ -14,10 +14,9 @@ Author:
Nikolaj Bjorner (nbjorner) 2024-06-24 Nikolaj Bjorner (nbjorner) 2024-06-24
--*/ --*/
#pragma once
#include "ast/sls/sls_context.h" #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_arith_plugin.h"
#include "ast/sls/sls_bv_plugin.h" #include "ast/sls/sls_bv_plugin.h"
#include "ast/sls/sls_basic_plugin.h" #include "ast/sls/sls_basic_plugin.h"
@ -36,7 +35,7 @@ namespace sls {
m_ld(*this), m_ld(*this),
m_repair_down(m.get_num_asts(), m_gd), m_repair_down(m.get_num_asts(), m_gd),
m_repair_up(m.get_num_asts(), m_ld) { 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(arith_plugin, *this));
register_plugin(alloc(bv_plugin, *this)); register_plugin(alloc(bv_plugin, *this));
register_plugin(alloc(basic_plugin, *this)); register_plugin(alloc(basic_plugin, *this));
@ -64,6 +63,8 @@ namespace sls {
propagate_boolean_assignment(); propagate_boolean_assignment();
// display(verbose_stream());
if (m_new_constraint || !unsat().empty()) if (m_new_constraint || !unsat().empty())
return l_undef; return l_undef;
@ -97,6 +98,7 @@ namespace sls {
while (!m_repair_down.empty() && !m_new_constraint) { while (!m_repair_down.empty() && !m_new_constraint) {
auto id = m_repair_down.erase_min(); 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)) { if (is_app(e)) {
auto p = m_plugins.get(to_app(e)->get_family_id(), nullptr); auto p = m_plugins.get(to_app(e)->get_family_id(), nullptr);
if (p) if (p)
@ -106,6 +108,7 @@ namespace sls {
while (!m_repair_up.empty() && !m_new_constraint) { while (!m_repair_up.empty() && !m_new_constraint) {
auto id = m_repair_up.erase_min(); auto id = m_repair_up.erase_min();
expr* e = term(id); expr* e = term(id);
// verbose_stream() << "repair up " << mk_bounded_pp(e, m) << "\n";
if (is_app(e)) { if (is_app(e)) {
auto p = m_plugins.get(to_app(e)->get_family_id(), nullptr); auto p = m_plugins.get(to_app(e)->get_family_id(), nullptr);
if (p) if (p)
@ -205,8 +208,8 @@ namespace sls {
auto v = m_atom2bool_var.get(e->get_id(), sat::null_bool_var); auto v = m_atom2bool_var.get(e->get_id(), sat::null_bool_var);
if (v == sat::null_bool_var) { if (v == sat::null_bool_var) {
v = s.add_var(); v = s.add_var();
register_terms(e);
register_atom(v, e); register_atom(v, e);
register_terms(e);
} }
return v; 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.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)) { for (auto p : parents(e)) {
m_repair_up.reserve(p->get_id() + 1); 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: Module Name:
sls_cc.cpp sls_euf_plugin.cpp
Abstract: 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_ll_pp.h"
#include "ast/ast_pp.h" #include "ast/ast_pp.h"
namespace sls { namespace sls {
cc_plugin::cc_plugin(context& c): euf_plugin::euf_plugin(context& c):
plugin(c), plugin(c),
m_values(8U, value_hash(*this), value_eq(*this)) { m_values(8U, value_hash(*this), value_eq(*this)) {
m_fid = m.mk_family_id("cc"); 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(); UNREACHABLE();
return expr_ref(m); return expr_ref(m);
} }
void cc_plugin::register_term(expr* e) { void euf_plugin::register_term(expr* e) {
if (!is_app(e)) if (!is_app(e))
return; return;
if (!is_uninterp(e)) if (!is_uninterp(e))
@ -49,14 +49,14 @@ namespace sls {
m_app[f].push_back(a); 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; unsigned r = 0;
for (auto arg : *t) for (auto arg : *t)
r *= 3, r += cc.ctx.get_value(arg)->hash(); r *= 3, r += cc.ctx.get_value(arg)->hash();
return r; 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()); SASSERT(a->get_num_args() == b->get_num_args());
for (unsigned i = a->get_num_args(); i-- > 0; ) 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))) 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; return true;
} }
bool cc_plugin::is_sat() { bool euf_plugin::is_sat() {
for (auto& [f, ts] : m_app) { for (auto& [f, ts] : m_app) {
if (ts.size() <= 1) if (ts.size() <= 1)
continue; continue;
@ -84,7 +84,7 @@ namespace sls {
return true; return true;
} }
bool cc_plugin::propagate() { bool euf_plugin::propagate() {
bool new_constraint = false; bool new_constraint = false;
for (auto & [f, ts] : m_app) { for (auto & [f, ts] : m_app) {
if (ts.size() <= 1) if (ts.size() <= 1)
@ -101,6 +101,12 @@ namespace sls {
for (unsigned i = t->get_num_args(); i-- > 0; ) 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_not(m.mk_eq(t->get_arg(i), u->get_arg(i))));
ors.push_back(m.mk_eq(t, u)); 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)); ctx.add_constraint(m.mk_or(ors));
new_constraint = true; new_constraint = true;
} }
@ -111,7 +117,7 @@ namespace sls {
return new_constraint; 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& [f, ts] : m_app) {
for (auto* t : ts) for (auto* t : ts)
out << mk_bounded_pp(t, m) << "\n"; out << mk_bounded_pp(t, m) << "\n";
@ -120,7 +126,7 @@ namespace sls {
return out; return out;
} }
void cc_plugin::mk_model(model& mdl) { void euf_plugin::mk_model(model& mdl) {
expr_ref_vector args(m); expr_ref_vector args(m);
for (auto& [f, ts] : m_app) { for (auto& [f, ts] : m_app) {
func_interp* fi = alloc(func_interp, m, f->get_arity()); func_interp* fi = alloc(func_interp, m, f->get_arity());

View file

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

View file

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