3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-09-05 17:47:41 +00:00

testing / debugging arithmetic

This commit is contained in:
Nikolaj Bjorner 2024-07-19 11:31:43 -07:00
parent ae55d30961
commit 5b0d49cd76
10 changed files with 269 additions and 139 deletions

View file

@ -17,6 +17,8 @@ Author:
#include "ast/sls/sls_basic_plugin.h"
#include "ast/ast_ll_pp.h"
#include "ast/ast_pp.h"
#include "ast/ast_util.h"
namespace sls {
@ -24,50 +26,76 @@ namespace sls {
return expr_ref(m.mk_bool_val(bval0(e)), m);
}
bool basic_plugin::is_basic(expr* e) const {
if (!e || !is_app(e))
return false;
if (to_app(e)->get_family_id() != basic_family_id)
return false;
if (!m.is_bool(e))
return false;
expr* x, * y;
if (m.is_eq(e, x, y) && !m.is_bool(x))
return false;
if (m.is_distinct(e) && !m.is_bool(to_app(e)->get_arg(0)))
return false;
return true;
}
void basic_plugin::propagate_literal(sat::literal lit) {
auto a = ctx.atom(lit.var());
if (!a || !is_app(a))
return;
if (to_app(a)->get_family_id() != basic_family_id)
if (!is_basic(a))
return;
if (bval1(to_app(a)) != bval0(to_app(a)))
ctx.new_value_eh(a);
}
void basic_plugin::register_term(expr* e) {
if (is_app(e) && m.is_bool(e) && to_app(e)->get_family_id() == basic_family_id)
if (is_basic(e))
m_values.setx(e->get_id(), bval1(to_app(e)), false);
}
void basic_plugin::initialize() {
}
bool basic_plugin::propagate() {
for (auto t : ctx.subterms())
if (is_basic(t) && !m.is_not(t) &&
bval0(t) != bval1(to_app(t))) {
add_clause(to_app(t));
return true;
}
return false;
}
bool basic_plugin::is_sat() {
for (auto t : ctx.subterms())
if (is_app(t) &&
m.is_bool(t) &&
to_app(t)->get_family_id() == basic_family_id &&
bval0(t) != bval1(to_app(t)))
return false;
if (is_basic(t) && !m.is_not(t) &&
bval0(t) != bval1(to_app(t))) {
verbose_stream() << mk_bounded_pp(t, m) << " := " << (bval0(t) ? "T" : "F") << " eval: " << (bval1(to_app(t)) ? "T" : "F") << "\n";
return false;
}
return true;
}
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)
if (is_basic(t))
out << mk_bounded_pp(t, m) << " := " << (bval0(t)?"T":"F") << " eval: " << (bval1(to_app(t))?"T":"F") << "\n";
return out;
}
void basic_plugin::set_value(expr* e, expr* v) {
if (!m.is_bool(e))
if (!is_basic(e))
return;
SASSERT(m.is_true(v) || m.is_false(v));
set_value(e, m.is_true(v));
}
bool basic_plugin::bval1(app* e) const {
if (m.is_not(e))
return bval1(to_app(e->get_arg(0)));
SASSERT(m.is_bool(e));
SASSERT(e->get_family_id() == basic_family_id);
@ -103,6 +131,7 @@ namespace sls {
auto b = e->get_arg(1);
if (m.is_bool(a))
return bval0(a) == bval0(b);
verbose_stream() << mk_bounded_pp(e, m) << " " << ctx.get_value(a) << " " << ctx.get_value(b) << "\n";
return ctx.get_value(a) == ctx.get_value(b);
}
case OP_DISTINCT: {
@ -123,11 +152,14 @@ namespace sls {
bool basic_plugin::bval0(expr* e) const {
SASSERT(m.is_bool(e));
bool b = true;
while (m.is_not(e, e))
b = !b;
sat::bool_var v = ctx.atom2bool_var(e);
if (v == sat::null_bool_var)
return m_values.get(e->get_id(), false);
return b == m_values.get(e->get_id(), false);
else
return ctx.is_true(v);
return b == ctx.is_true(v);
}
bool basic_plugin::try_repair(app* e, unsigned i) {
@ -158,6 +190,56 @@ namespace sls {
}
}
void basic_plugin::add_clause(app* e) {
expr_ref_vector es(m);
expr_ref fml(m);
expr* x, *y;
switch (e->get_decl_kind()) {
case OP_AND:
for (expr* arg : *e) {
ctx.add_constraint(m.mk_or(m.mk_not(e), arg));
es.push_back(mk_not(m, arg));
}
es.push_back(e);
ctx.add_constraint(m.mk_or(es));
break;
case OP_OR:
for (expr* arg : *e) {
ctx.add_constraint(m.mk_or(mk_not(m, arg), e));
es.push_back(arg);
}
es.push_back(m.mk_not(e));
ctx.add_constraint(m.mk_or(es));
break;
case OP_NOT:
break;
case OP_FALSE:
break;
case OP_TRUE:
break;
case OP_EQ:
VERIFY(m.is_eq(e, x, y));
ctx.add_constraint(m.mk_or(m.mk_not(e), mk_not(m, x), y));
ctx.add_constraint(m.mk_or(m.mk_not(e), mk_not(m, y), x));
ctx.add_constraint(m.mk_or(e, y, x));
ctx.add_constraint(m.mk_or(e, mk_not(m, x), mk_not(m, y)));
break;
case OP_IMPLIES:
NOT_IMPLEMENTED_YET();
case OP_XOR:
NOT_IMPLEMENTED_YET();
case OP_ITE:
NOT_IMPLEMENTED_YET();
case OP_DISTINCT:
NOT_IMPLEMENTED_YET();
default:
UNREACHABLE();
break;
}
}
bool basic_plugin::try_repair_and_or(app* e, unsigned i) {
auto b = bval0(e);
if ((b && m.is_and(e)) || (!b && m.is_or(e))) {
@ -245,7 +327,7 @@ namespace sls {
}
void basic_plugin::repair_up(app* e) {
if (!m.is_bool(e) || e->get_family_id() != basic_family_id)
if (!is_basic(e))
return;
auto b = bval1(e);
if (bval0(e) == b)
@ -256,7 +338,7 @@ namespace sls {
void basic_plugin::repair_down(app* e) {
SASSERT(m.is_bool(e));
unsigned n = e->get_num_args();
if (n == 0 || e->get_family_id() != m.get_basic_family_id())
if (n == 0 || !is_basic(e))
return;
if (bval0(e) == bval1(e))