3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-27 10:55:50 +00:00

Add get_sort(expr * n) function that does not depend on ast_manager. Move power_of_two to rational class. Add arith_recognizers and bv_recognizers classes. The two new classes contain the 'read-only' methods from arith_util and bv_util.

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2012-12-18 14:44:51 -08:00
parent 4f0d5a5756
commit cec328cfdc
17 changed files with 314 additions and 282 deletions

View file

@ -283,12 +283,12 @@ br_status bv_rewriter::mk_leq_core(bool is_signed, expr * a, expr * b, expr_ref
if (is_num1 || is_num2) {
if (is_signed) {
lower = - m_util.power_of_two(sz - 1);
upper = m_util.power_of_two(sz - 1) - numeral(1);
lower = - rational::power_of_two(sz - 1);
upper = rational::power_of_two(sz - 1) - numeral(1);
}
else {
lower = numeral(0);
upper = m_util.power_of_two(sz) - numeral(1);
upper = rational::power_of_two(sz) - numeral(1);
}
}
@ -387,14 +387,14 @@ br_status bv_rewriter::mk_extract(unsigned high, unsigned low, expr * arg, expr_
if (is_numeral(arg, v, sz)) {
sz = high - low + 1;
if (v.is_neg())
mod(v, m_util.power_of_two(sz), v);
mod(v, rational::power_of_two(sz), v);
if (v.is_uint64()) {
uint64 u = v.get_uint64();
uint64 e = shift_right(u, low) & (shift_left(1ull, sz) - 1ull);
result = mk_numeral(numeral(e, numeral::ui64()), sz);
return BR_DONE;
}
div(v, m_util.power_of_two(low), v);
div(v, rational::power_of_two(low), v);
result = mk_numeral(v, sz);
return BR_DONE;
}
@ -519,7 +519,7 @@ br_status bv_rewriter::mk_bv_shl(expr * arg1, expr * arg2, expr_ref & result) {
SASSERT(r2 < numeral(bv_size));
SASSERT(r2.is_unsigned());
r1 = m_util.norm(r1 * m_util.power_of_two(r2.get_unsigned()), bv_size);
r1 = m_util.norm(r1 * rational::power_of_two(r2.get_unsigned()), bv_size);
result = mk_numeral(r1, bv_size);
return BR_DONE;
}
@ -567,7 +567,7 @@ br_status bv_rewriter::mk_bv_lshr(expr * arg1, expr * arg2, expr_ref & result) {
SASSERT(r2.is_unsigned());
unsigned sh = r2.get_unsigned();
div(r1, m_util.power_of_two(sh), r1);
div(r1, rational::power_of_two(sh), r1);
result = mk_numeral(r1, bv_size);
return BR_DONE;
}
@ -626,7 +626,7 @@ br_status bv_rewriter::mk_bv_ashr(expr * arg1, expr * arg2, expr_ref & result) {
if (is_num1 && is_num2 && numeral(bv_size) <= r2) {
if (m_util.has_sign_bit(r1, bv_size))
result = mk_numeral(m_util.power_of_two(bv_size) - numeral(1), bv_size);
result = mk_numeral(rational::power_of_two(bv_size) - numeral(1), bv_size);
else
result = mk_numeral(0, bv_size);
return BR_DONE;
@ -635,7 +635,7 @@ br_status bv_rewriter::mk_bv_ashr(expr * arg1, expr * arg2, expr_ref & result) {
if (is_num1 && is_num2) {
SASSERT(r2 < numeral(bv_size));
bool sign = m_util.has_sign_bit(r1, bv_size);
div(r1, m_util.power_of_two(r2.get_unsigned()), r1);
div(r1, rational::power_of_two(r2.get_unsigned()), r1);
if (sign) {
// pad ones.
numeral p(1);
@ -697,7 +697,7 @@ br_status bv_rewriter::mk_bv_sdiv_core(expr * arg1, expr * arg2, bool hi_div0, e
// The "hardware interpretation" for (bvsdiv x 0) is (ite (bvslt x #x0000) #x0001 #xffff)
result = m().mk_ite(m().mk_app(get_fid(), OP_SLT, arg1, mk_numeral(0, bv_size)),
mk_numeral(1, bv_size),
mk_numeral(m_util.power_of_two(bv_size) - numeral(1), bv_size));
mk_numeral(rational::power_of_two(bv_size) - numeral(1), bv_size));
return BR_REWRITE2;
}
}
@ -746,7 +746,7 @@ br_status bv_rewriter::mk_bv_udiv_core(expr * arg1, expr * arg2, bool hi_div0, e
}
else {
// The "hardware interpretation" for (bvudiv x 0) is #xffff
result = mk_numeral(m_util.power_of_two(bv_size) - numeral(1), bv_size);
result = mk_numeral(rational::power_of_two(bv_size) - numeral(1), bv_size);
return BR_DONE;
}
@ -845,7 +845,7 @@ bool bv_rewriter::is_minus_one_core(expr * arg) const {
numeral r;
unsigned bv_size;
if (is_numeral(arg, r, bv_size)) {
return r == (m_util.power_of_two(bv_size) - numeral(1));
return r == (rational::power_of_two(bv_size) - numeral(1));
}
return false;
}
@ -924,7 +924,7 @@ br_status bv_rewriter::mk_bv_urem_core(expr * arg1, expr * arg2, bool hi_div0, e
if (is_x_minus_one(arg1, x) && x == arg2) {
bv_size = get_bv_size(arg1);
expr * x_minus_1 = arg1;
expr * minus_one = mk_numeral(m_util.power_of_two(bv_size) - numeral(1), bv_size);
expr * minus_one = mk_numeral(rational::power_of_two(bv_size) - numeral(1), bv_size);
result = m().mk_ite(m().mk_eq(x, mk_numeral(0, bv_size)),
m().mk_app(get_fid(), OP_BUREM0, minus_one),
x_minus_1);
@ -1068,7 +1068,7 @@ br_status bv_rewriter::mk_concat(unsigned num_args, expr * const * args, expr_re
if (i > 0)
prev = new_args.back();
if (is_numeral(arg, v1, sz1) && prev != 0 && is_numeral(prev, v2, sz2)) {
v2 *= m_util.power_of_two(sz1);
v2 *= rational::power_of_two(sz1);
v2 += v1;
new_args.pop_back();
new_args.push_back(mk_numeral(v2, sz1+sz2));
@ -1137,7 +1137,7 @@ br_status bv_rewriter::mk_sign_extend(unsigned n, expr * arg, expr_ref & result)
if (is_numeral(arg, r, bv_size)) {
unsigned result_bv_size = bv_size + n;
r = m_util.norm(r, bv_size, true);
mod(r, m_util.power_of_two(result_bv_size), r);
mod(r, rational::power_of_two(result_bv_size), r);
result = mk_numeral(r, result_bv_size);
return BR_DONE;
}
@ -1213,7 +1213,7 @@ br_status bv_rewriter::mk_bv_or(unsigned num, expr * const * args, expr_ref & re
if (m_util.is_bv_not(arg)) {
expr * atom = to_app(arg)->get_arg(0);
if (pos_args.is_marked(atom)) {
result = mk_numeral(m_util.power_of_two(sz) - numeral(1), sz);
result = mk_numeral(rational::power_of_two(sz) - numeral(1), sz);
return BR_DONE;
}
else if (neg_args.is_marked(atom)) {
@ -1229,7 +1229,7 @@ br_status bv_rewriter::mk_bv_or(unsigned num, expr * const * args, expr_ref & re
continue;
}
else if (neg_args.is_marked(arg)) {
result = mk_numeral(m_util.power_of_two(sz) - numeral(1), sz);
result = mk_numeral(rational::power_of_two(sz) - numeral(1), sz);
return BR_DONE;
}
pos_args.mark(arg, true);
@ -1237,7 +1237,7 @@ br_status bv_rewriter::mk_bv_or(unsigned num, expr * const * args, expr_ref & re
}
}
if (v1 == m_util.power_of_two(sz) - numeral(1)) {
if (v1 == rational::power_of_two(sz) - numeral(1)) {
result = mk_numeral(v1, sz);
return BR_DONE;
}
@ -1294,7 +1294,7 @@ br_status bv_rewriter::mk_bv_or(unsigned num, expr * const * args, expr_ref & re
}
if (i != low) {
unsigned num_sz = i - low;
exs.push_back(m_util.mk_numeral(m_util.power_of_two(num_sz) - numeral(1), num_sz));
exs.push_back(m_util.mk_numeral(rational::power_of_two(num_sz) - numeral(1), num_sz));
low = i;
}
while (i < sz && mod(v1, two).is_zero()) {
@ -1385,7 +1385,7 @@ br_status bv_rewriter::mk_bv_xor(unsigned num, expr * const * args, expr_ref & r
else if (pos_args.is_marked(atom)) {
pos_args.mark(atom, false);
merged = true;
v1 = bitwise_xor(v1, m_util.power_of_two(sz) - numeral(1));
v1 = bitwise_xor(v1, rational::power_of_two(sz) - numeral(1));
}
else {
neg_args.mark(atom, true);
@ -1399,7 +1399,7 @@ br_status bv_rewriter::mk_bv_xor(unsigned num, expr * const * args, expr_ref & r
else if (neg_args.is_marked(arg)) {
neg_args.mark(arg, false);
merged = true;
v1 = bitwise_xor(v1, m_util.power_of_two(sz) - numeral(1));
v1 = bitwise_xor(v1, rational::power_of_two(sz) - numeral(1));
}
else {
pos_args.mark(arg, true);
@ -1455,7 +1455,7 @@ br_status bv_rewriter::mk_bv_xor(unsigned num, expr * const * args, expr_ref & r
return BR_REWRITE3;
}
if (!merged && !flattened && (num_coeffs == 0 || (num_coeffs == 1 && !v1.is_zero() && v1 != (m_util.power_of_two(sz) - numeral(1)))))
if (!merged && !flattened && (num_coeffs == 0 || (num_coeffs == 1 && !v1.is_zero() && v1 != (rational::power_of_two(sz) - numeral(1)))))
return BR_FAILED;
ptr_buffer<expr> new_args;
@ -1611,7 +1611,7 @@ br_status bv_rewriter::mk_bv_redand(expr * arg, expr_ref & result) {
numeral r;
unsigned bv_size;
if (is_numeral(arg, r, bv_size)) {
result = (r == m_util.power_of_two(bv_size) - numeral(1)) ? mk_numeral(1, 1) : mk_numeral(0, 1);
result = (r == rational::power_of_two(bv_size) - numeral(1)) ? mk_numeral(1, 1) : mk_numeral(0, 1);
return BR_DONE;
}
return BR_FAILED;
@ -1707,7 +1707,7 @@ bool bv_rewriter::is_zero_bit(expr * x, unsigned idx) {
if (is_numeral(x, val, bv_size)) {
if (val.is_zero())
return true;
div(val, m_util.power_of_two(idx), val);
div(val, rational::power_of_two(idx), val);
return (val % numeral(2)).is_zero();
}
if (m_util.is_concat(x)) {