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

fpa2bv slight refactoring

Signed-off-by: Christoph M. Wintersteiger <cwinter@microsoft.com>
This commit is contained in:
Christoph M. Wintersteiger 2015-01-02 18:59:27 +00:00
parent f684675a6e
commit 3266e96e80
2 changed files with 181 additions and 174 deletions

View file

@ -1873,7 +1873,7 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args
m_arith_util.is_numeral(args[1]) &&
m_arith_util.is_numeral(args[2]))
{
// Three arguments, some of them are not numerals.
// rm + real + int -> float
SASSERT(m_util.is_float(f->get_range()));
unsigned ebits = m_util.get_ebits(f->get_range());
unsigned sbits = m_util.get_sbits(f->get_range());
@ -1938,14 +1938,25 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args
result);
}
else if (num == 2 &&
m_util.is_rm(args[0]) &&
is_app(args[1]) &&
m_util.is_float(m.get_sort(args[1]))) {
// We also support float to float conversion
sort * s = f->get_range();
expr_ref rm(m), x(m);
rm = args[0];
x = args[1];
// float -> float conversion
mk_to_fp_float(f, f->get_range(), args[0], args[1], result);
}
else if (num == 2 &&
m_util.is_rm(args[0]),
m_arith_util.is_real(args[1])) {
// rm + real -> float
mk_to_fp_real(f, f->get_range(), args[0], args[1], result);
}
else
UNREACHABLE();
SASSERT(is_well_sorted(m, result));
}
void fpa2bv_converter::mk_to_fp_float(func_decl * f, sort * s, expr * rm, expr * x, expr_ref & result) {
unsigned from_sbits = m_util.get_sbits(m.get_sort(x));
unsigned from_ebits = m_util.get_ebits(m.get_sort(x));
unsigned to_sbits = m_util.get_sbits(s);
@ -2000,13 +2011,11 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args
SASSERT(m_bv_util.get_bv_size(exp) == from_ebits);
SASSERT(m_bv_util.get_bv_size(lz) == from_ebits);
if (from_sbits < (to_sbits + 3))
{
if (from_sbits < (to_sbits + 3)) {
// make sure that sig has at least to_sbits + 3
res_sig = m_bv_util.mk_concat(sig, m_bv_util.mk_numeral(0, to_sbits + 3 - from_sbits));
}
else if (from_sbits > (to_sbits + 3))
{
else if (from_sbits >(to_sbits + 3)) {
// collapse the extra bits into a sticky bit.
expr_ref sticky(m), low(m), high(m);
low = m_bv_util.mk_extract(from_sbits - to_sbits - 3, 0, sig);
@ -2024,8 +2033,7 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args
expr_ref exponent_overflow(m);
exponent_overflow = m.mk_false();
if (from_ebits < (to_ebits + 2))
{
if (from_ebits < (to_ebits + 2)) {
res_exp = m_bv_util.mk_sign_extend(to_ebits - from_ebits + 2, exp);
// subtract lz for subnormal numbers.
@ -2033,8 +2041,7 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args
lz_ext = m_bv_util.mk_zero_extend(to_ebits - from_ebits + 2, lz);
res_exp = m_bv_util.mk_bv_sub(res_exp, lz_ext);
}
else if (from_ebits > (to_ebits + 2))
{
else if (from_ebits >(to_ebits + 2)) {
expr_ref high(m), low(m), lows(m), high_red_or(m), high_red_and(m), h_or_eq(m), h_and_eq(m);
expr_ref no_ovf(m), zero1(m), s_is_one(m), s_is_zero(m);
high = m_bv_util.mk_extract(from_ebits - 1, to_ebits + 2, exp);
@ -2076,7 +2083,7 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args
dbg_decouple("fpa2bv_to_float_res_exp", res_exp);
expr_ref rounded(m);
round(s, rm, res_sgn, res_sig, res_exp, rounded);
round(s, expr_ref (rm, m), res_sgn, res_sig, res_exp, rounded);
expr_ref is_neg(m), sig_inf(m);
m_simp.mk_eq(sgn, one1, is_neg);
@ -2092,25 +2099,24 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args
mk_ite(c2, v2, result, result);
mk_ite(c1, v1, result, result);
}
}
else if (num == 2 &&
m_util.is_rm(args[0]),
m_arith_util.is_real(args[1])) {
// .. other than that, we only support rationals for to_fp
SASSERT(m_util.is_float(f->get_range()));
unsigned ebits = m_util.get_ebits(f->get_range());
unsigned sbits = m_util.get_sbits(f->get_range());
SASSERT(m_bv_util.is_numeral(args[0]));
SASSERT(is_well_sorted(m, result));
}
void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * x, expr_ref & result) {
SASSERT(m_util.is_float(s));
unsigned ebits = m_util.get_ebits(s);
unsigned sbits = m_util.get_sbits(s);
if (m_bv_util.is_numeral(rm) && m_util.au().is_numeral(x)) {
rational tmp_rat; unsigned sz;
m_bv_util.is_numeral(to_expr(args[0]), tmp_rat, sz);
m_bv_util.is_numeral(to_expr(rm), tmp_rat, sz);
SASSERT(tmp_rat.is_int32());
SASSERT(sz == 3);
BV_RM_VAL bv_rm = (BV_RM_VAL)tmp_rat.get_unsigned();
mpf_rounding_mode rm;
switch (bv_rm)
{
switch (bv_rm) {
case BV_RM_TIES_TO_AWAY: rm = MPF_ROUND_NEAREST_TAWAY; break;
case BV_RM_TIES_TO_EVEN: rm = MPF_ROUND_NEAREST_TEVEN; break;
case BV_RM_TO_NEGATIVE: rm = MPF_ROUND_TOWARD_NEGATIVE; break;
@ -2119,10 +2125,8 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args
default: UNREACHABLE();
}
SASSERT(m_util.au().is_numeral(args[1]));
rational q;
m_util.au().is_numeral(args[1], q);
m_util.au().is_numeral(x, q);
scoped_mpf v(m_mpf_manager);
m_util.fm().set(v, ebits, sbits, rm, q.to_mpq());
@ -2135,8 +2139,9 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args
mk_triple(sgn, s, e, result);
}
else
UNREACHABLE();
else {
NOT_IMPLEMENTED_YET();
}
SASSERT(is_well_sorted(m, result));
}

View file

@ -130,6 +130,8 @@ public:
void mk_fp(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
void mk_to_fp(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
void mk_to_fp_float(func_decl * f, sort * s, expr * rm, expr * x, expr_ref & result);
void mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * x, expr_ref & result);
void mk_to_fp_signed(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
void mk_to_fp_unsigned(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
void mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * args, expr_ref & result);