mirror of
https://github.com/Z3Prover/z3
synced 2025-08-04 18:30:24 +00:00
normalizing inequality
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
9a5fa60e98
commit
7e9d0537d7
3 changed files with 38 additions and 11 deletions
|
@ -183,6 +183,20 @@ void bv2int_translator::translate_app(app* e) {
|
||||||
set_translated(e, m.mk_app(f, m_args));
|
set_translated(e, m.mk_app(f, m_args));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expr_ref bv2int_translator::mk_le(expr* x, expr* y) {
|
||||||
|
if (a.is_numeral(y))
|
||||||
|
return expr_ref(a.mk_le(x, y), m);
|
||||||
|
if (a.is_numeral(x))
|
||||||
|
return expr_ref(a.mk_ge(y, x), m);
|
||||||
|
return expr_ref(a.mk_le(a.mk_sub(x, y), a.mk_numeral(rational(0), x->get_sort())), m);
|
||||||
|
}
|
||||||
|
|
||||||
|
expr_ref bv2int_translator::mk_lt(expr* x, expr* y) {
|
||||||
|
return expr_ref(m.mk_not(mk_le(y, x)), m);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void bv2int_translator::translate_bv(app* e) {
|
void bv2int_translator::translate_bv(app* e) {
|
||||||
|
|
||||||
auto bnot = [&](expr* e) {
|
auto bnot = [&](expr* e) {
|
||||||
|
@ -229,35 +243,35 @@ void bv2int_translator::translate_bv(app* e) {
|
||||||
break;
|
break;
|
||||||
case OP_ULEQ:
|
case OP_ULEQ:
|
||||||
bv_expr = e->get_arg(0);
|
bv_expr = e->get_arg(0);
|
||||||
r = a.mk_le(umod(bv_expr, 0), umod(bv_expr, 1));
|
r = mk_le(umod(bv_expr, 0), umod(bv_expr, 1));
|
||||||
break;
|
break;
|
||||||
case OP_UGEQ:
|
case OP_UGEQ:
|
||||||
bv_expr = e->get_arg(0);
|
bv_expr = e->get_arg(0);
|
||||||
r = a.mk_ge(umod(bv_expr, 0), umod(bv_expr, 1));
|
r = mk_ge(umod(bv_expr, 0), umod(bv_expr, 1));
|
||||||
break;
|
break;
|
||||||
case OP_ULT:
|
case OP_ULT:
|
||||||
bv_expr = e->get_arg(0);
|
bv_expr = e->get_arg(0);
|
||||||
r = a.mk_lt(umod(bv_expr, 0), umod(bv_expr, 1));
|
r = mk_lt(umod(bv_expr, 0), umod(bv_expr, 1));
|
||||||
break;
|
break;
|
||||||
case OP_UGT:
|
case OP_UGT:
|
||||||
bv_expr = e->get_arg(0);
|
bv_expr = e->get_arg(0);
|
||||||
r = a.mk_gt(umod(bv_expr, 0), umod(bv_expr, 1));
|
r = mk_gt(umod(bv_expr, 0), umod(bv_expr, 1));
|
||||||
break;
|
break;
|
||||||
case OP_SLEQ:
|
case OP_SLEQ:
|
||||||
bv_expr = e->get_arg(0);
|
bv_expr = e->get_arg(0);
|
||||||
r = a.mk_le(smod(bv_expr, 0), smod(bv_expr, 1));
|
r = mk_le(smod(bv_expr, 0), smod(bv_expr, 1));
|
||||||
break;
|
break;
|
||||||
case OP_SGEQ:
|
case OP_SGEQ:
|
||||||
bv_expr = e->get_arg(0);
|
bv_expr = e->get_arg(0);
|
||||||
r = a.mk_ge(smod(bv_expr, 0), smod(bv_expr, 1));
|
r = mk_ge(smod(bv_expr, 0), smod(bv_expr, 1));
|
||||||
break;
|
break;
|
||||||
case OP_SLT:
|
case OP_SLT:
|
||||||
bv_expr = e->get_arg(0);
|
bv_expr = e->get_arg(0);
|
||||||
r = a.mk_lt(smod(bv_expr, 0), smod(bv_expr, 1));
|
r = mk_lt(smod(bv_expr, 0), smod(bv_expr, 1));
|
||||||
break;
|
break;
|
||||||
case OP_SGT:
|
case OP_SGT:
|
||||||
bv_expr = e->get_arg(0);
|
bv_expr = e->get_arg(0);
|
||||||
r = a.mk_gt(smod(bv_expr, 0), smod(bv_expr, 1));
|
r = mk_gt(smod(bv_expr, 0), smod(bv_expr, 1));
|
||||||
break;
|
break;
|
||||||
case OP_BNEG:
|
case OP_BNEG:
|
||||||
r = a.mk_uminus(arg(0));
|
r = a.mk_uminus(arg(0));
|
||||||
|
@ -308,7 +322,7 @@ void bv2int_translator::translate_bv(app* e) {
|
||||||
}
|
}
|
||||||
case OP_BUMUL_NO_OVFL: {
|
case OP_BUMUL_NO_OVFL: {
|
||||||
bv_expr = e->get_arg(0);
|
bv_expr = e->get_arg(0);
|
||||||
r = a.mk_lt(mul(umod(bv_expr, 0), umod(bv_expr, 1)), a.mk_int(bv_size(bv_expr)));
|
r = mk_lt(mul(umod(bv_expr, 0), umod(bv_expr, 1)), a.mk_int(bv_size(bv_expr)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_BSHL: {
|
case OP_BSHL: {
|
||||||
|
|
|
@ -47,6 +47,11 @@ class bv2int_translator {
|
||||||
expr_ref if_eq(expr* n, unsigned k, expr* th, expr* el);
|
expr_ref if_eq(expr* n, unsigned k, expr* th, expr* el);
|
||||||
expr* amod(expr* bv_expr, expr* x, rational const& N);
|
expr* amod(expr* bv_expr, expr* x, rational const& N);
|
||||||
rational bv_size(expr* bv_expr);
|
rational bv_size(expr* bv_expr);
|
||||||
|
expr_ref mk_le(expr* a, expr* b);
|
||||||
|
expr_ref mk_lt(expr* a, expr* b);
|
||||||
|
expr_ref mk_ge(expr* a, expr* b) { return mk_le(b, a); }
|
||||||
|
expr_ref mk_gt(expr* a, expr* b) { return mk_lt(b, a); }
|
||||||
|
|
||||||
|
|
||||||
void translate_bv(app* e);
|
void translate_bv(app* e);
|
||||||
void translate_basic(app* e);
|
void translate_basic(app* e);
|
||||||
|
|
|
@ -2573,6 +2573,14 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expr_ref mk_le(expr* x, expr* y) {
|
||||||
|
if (a.is_numeral(y))
|
||||||
|
return expr_ref(a.mk_le(x, y), m);
|
||||||
|
if (a.is_numeral(x))
|
||||||
|
return expr_ref(a.mk_ge(y, x), m);
|
||||||
|
return expr_ref(a.mk_le(a.mk_sub(x, y), a.mk_numeral(rational(0), x->get_sort())), m);
|
||||||
|
}
|
||||||
|
|
||||||
void mk_bv_axiom(app* n) {
|
void mk_bv_axiom(app* n) {
|
||||||
unsigned sz = 0;
|
unsigned sz = 0;
|
||||||
expr* _x = nullptr, * _y = nullptr;
|
expr* _x = nullptr, * _y = nullptr;
|
||||||
|
@ -2592,8 +2600,8 @@ public:
|
||||||
// x&y <= y
|
// x&y <= y
|
||||||
// TODO? x = y => x&y = x
|
// TODO? x = y => x&y = x
|
||||||
|
|
||||||
ctx().mk_th_axiom(get_id(), mk_literal(a.mk_le(n, x)));
|
ctx().mk_th_axiom(get_id(), mk_literal(mk_le(n, x)));
|
||||||
ctx().mk_th_axiom(get_id(), mk_literal(a.mk_le(n, y)));
|
ctx().mk_th_axiom(get_id(), mk_literal(mk_le(n, y)));
|
||||||
}
|
}
|
||||||
else if (a.is_shl(n)) {
|
else if (a.is_shl(n)) {
|
||||||
// y >= sz => n = 0
|
// y >= sz => n = 0
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue