mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 01:25:31 +00:00
FPA: bugfixes, naming convention, core theory additions
Signed-off-by: Christoph M. Wintersteiger <cwinter@microsoft.com>
This commit is contained in:
parent
f11ee40c38
commit
47325c5fd3
10 changed files with 287 additions and 114 deletions
|
@ -163,6 +163,11 @@ decl_plugin * float_decl_plugin::mk_fresh() {
|
|||
}
|
||||
|
||||
sort * float_decl_plugin::mk_float_sort(unsigned ebits, unsigned sbits) {
|
||||
if (ebits > sbits)
|
||||
m_manager->raise_exception("floating point sorts with ebits > sbits are currently not supported");
|
||||
if (ebits <= 2)
|
||||
m_manager->raise_exception("floating point sorts with ebits <= 2 are currently not supported");
|
||||
|
||||
parameter p1(ebits), p2(sbits);
|
||||
parameter ps[2] = { p1, p2 };
|
||||
sort_size sz;
|
||||
|
@ -841,13 +846,13 @@ app * float_util::mk_nan(unsigned ebits, unsigned sbits) {
|
|||
return mk_value(v);
|
||||
}
|
||||
|
||||
app * float_util::mk_plus_inf(unsigned ebits, unsigned sbits) {
|
||||
app * float_util::mk_pinf(unsigned ebits, unsigned sbits) {
|
||||
scoped_mpf v(fm());
|
||||
fm().mk_pinf(ebits, sbits, v);
|
||||
return mk_value(v);
|
||||
}
|
||||
|
||||
app * float_util::mk_minus_inf(unsigned ebits, unsigned sbits) {
|
||||
app * float_util::mk_ninf(unsigned ebits, unsigned sbits) {
|
||||
scoped_mpf v(fm());
|
||||
fm().mk_ninf(ebits, sbits, v);
|
||||
return mk_value(v);
|
||||
|
|
|
@ -221,11 +221,11 @@ public:
|
|||
app * mk_round_toward_zero() { return m().mk_const(m_fid, OP_FLOAT_RM_TOWARD_ZERO); }
|
||||
|
||||
app * mk_nan(unsigned ebits, unsigned sbits);
|
||||
app * mk_plus_inf(unsigned ebits, unsigned sbits);
|
||||
app * mk_minus_inf(unsigned ebits, unsigned sbits);
|
||||
app * mk_pinf(unsigned ebits, unsigned sbits);
|
||||
app * mk_ninf(unsigned ebits, unsigned sbits);
|
||||
app * mk_nan(sort * s) { return mk_nan(get_ebits(s), get_sbits(s)); }
|
||||
app * mk_plus_inf(sort * s) { return mk_plus_inf(get_ebits(s), get_sbits(s)); }
|
||||
app * mk_minus_inf(sort * s) { return mk_minus_inf(get_ebits(s), get_sbits(s)); }
|
||||
app * mk_pinf(sort * s) { return mk_pinf(get_ebits(s), get_sbits(s)); }
|
||||
app * mk_ninf(sort * s) { return mk_ninf(get_ebits(s), get_sbits(s)); }
|
||||
|
||||
app * mk_value(mpf const & v) { return m_plugin->mk_value(v); }
|
||||
bool is_value(expr * n) { return m_plugin->is_value(n); }
|
||||
|
@ -238,8 +238,8 @@ public:
|
|||
app * mk_nzero(sort * s) { return mk_nzero(get_ebits(s), get_sbits(s)); }
|
||||
|
||||
bool is_nan(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_nan(v); }
|
||||
bool is_plus_inf(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_pinf(v); }
|
||||
bool is_minus_inf(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_ninf(v); }
|
||||
bool is_pinf(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_pinf(v); }
|
||||
bool is_ninf(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_ninf(v); }
|
||||
bool is_zero(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_zero(v); }
|
||||
bool is_pzero(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_pzero(v); }
|
||||
bool is_nzero(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_nzero(v); }
|
||||
|
|
|
@ -103,9 +103,9 @@ void fpa2bv_converter::mk_value(func_decl * f, unsigned num, expr * const * args
|
|||
mk_nan(f, result);
|
||||
else if (m_util.fm().is_inf(v)) {
|
||||
if (m_util.fm().sgn(v))
|
||||
mk_minus_inf(f, result);
|
||||
mk_ninf(f, result);
|
||||
else
|
||||
mk_plus_inf(f, result);
|
||||
mk_pinf(f, result);
|
||||
}
|
||||
else {
|
||||
expr_ref bv_sgn(m), bv_sig(m), e(m), biased_exp(m);
|
||||
|
@ -298,7 +298,7 @@ void fpa2bv_converter::mk_rm_const(func_decl * f, expr_ref & result) {
|
|||
}
|
||||
}
|
||||
|
||||
void fpa2bv_converter::mk_plus_inf(func_decl * f, expr_ref & result) {
|
||||
void fpa2bv_converter::mk_pinf(func_decl * f, expr_ref & result) {
|
||||
sort * srt = f->get_range();
|
||||
SASSERT(is_float(srt));
|
||||
unsigned sbits = m_util.get_sbits(srt);
|
||||
|
@ -311,7 +311,7 @@ void fpa2bv_converter::mk_plus_inf(func_decl * f, expr_ref & result) {
|
|||
result);
|
||||
}
|
||||
|
||||
void fpa2bv_converter::mk_minus_inf(func_decl * f, expr_ref & result) {
|
||||
void fpa2bv_converter::mk_ninf(func_decl * f, expr_ref & result) {
|
||||
sort * srt = f->get_range();
|
||||
SASSERT(is_float(srt));
|
||||
unsigned sbits = m_util.get_sbits(srt);
|
||||
|
@ -633,8 +633,8 @@ void fpa2bv_converter::mk_mul(func_decl * f, unsigned num, expr * const * args,
|
|||
mk_nan(f, nan);
|
||||
mk_nzero(f, nzero);
|
||||
mk_pzero(f, pzero);
|
||||
mk_minus_inf(f, ninf);
|
||||
mk_plus_inf(f, pinf);
|
||||
mk_ninf(f, ninf);
|
||||
mk_pinf(f, pinf);
|
||||
|
||||
expr_ref x_is_nan(m), x_is_zero(m), x_is_pos(m), x_is_inf(m);
|
||||
expr_ref y_is_nan(m), y_is_zero(m), y_is_pos(m), y_is_inf(m);
|
||||
|
@ -781,8 +781,8 @@ void fpa2bv_converter::mk_div(func_decl * f, unsigned num, expr * const * args,
|
|||
mk_nan(f, nan);
|
||||
mk_nzero(f, nzero);
|
||||
mk_pzero(f, pzero);
|
||||
mk_minus_inf(f, ninf);
|
||||
mk_plus_inf(f, pinf);
|
||||
mk_ninf(f, ninf);
|
||||
mk_pinf(f, pinf);
|
||||
|
||||
expr_ref x_is_nan(m), x_is_zero(m), x_is_pos(m), x_is_inf(m);
|
||||
expr_ref y_is_nan(m), y_is_zero(m), y_is_pos(m), y_is_inf(m);
|
||||
|
@ -927,8 +927,8 @@ void fpa2bv_converter::mk_rem(func_decl * f, unsigned num, expr * const * args,
|
|||
mk_nan(f, nan);
|
||||
mk_nzero(f, nzero);
|
||||
mk_pzero(f, pzero);
|
||||
mk_minus_inf(f, ninf);
|
||||
mk_plus_inf(f, pinf);
|
||||
mk_ninf(f, ninf);
|
||||
mk_pinf(f, pinf);
|
||||
|
||||
expr_ref x_is_nan(m), x_is_zero(m), x_is_pos(m), x_is_inf(m);
|
||||
expr_ref y_is_nan(m), y_is_zero(m), y_is_pos(m), y_is_inf(m);
|
||||
|
@ -1137,8 +1137,8 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args,
|
|||
mk_nan(f, nan);
|
||||
mk_nzero(f, nzero);
|
||||
mk_pzero(f, pzero);
|
||||
mk_minus_inf(f, ninf);
|
||||
mk_plus_inf(f, pinf);
|
||||
mk_ninf(f, ninf);
|
||||
mk_pinf(f, pinf);
|
||||
|
||||
expr_ref x_is_nan(m), x_is_zero(m), x_is_pos(m), x_is_neg(m), x_is_inf(m);
|
||||
expr_ref y_is_nan(m), y_is_zero(m), y_is_pos(m), y_is_neg(m), y_is_inf(m);
|
||||
|
@ -1447,8 +1447,8 @@ void fpa2bv_converter::mk_sqrt(func_decl * f, unsigned num, expr * const * args,
|
|||
mk_nan(f, nan);
|
||||
mk_nzero(f, nzero);
|
||||
mk_pzero(f, pzero);
|
||||
mk_minus_inf(f, ninf);
|
||||
mk_plus_inf(f, pinf);
|
||||
mk_ninf(f, ninf);
|
||||
mk_pinf(f, pinf);
|
||||
|
||||
expr_ref x_is_nan(m), x_is_zero(m), x_is_pos(m), x_is_inf(m);
|
||||
mk_is_nan(x, x_is_nan);
|
||||
|
@ -1871,9 +1871,11 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args
|
|||
mk_triple(args[0], args[1], args[2], result);
|
||||
}
|
||||
else if (num == 2 &&
|
||||
m_bv_util.is_bv(args[0]) &&
|
||||
m_bv_util.is_bv(args[0]) &&
|
||||
m_bv_util.get_bv_size(args[0]) == 3 &&
|
||||
m_bv_util.is_bv(args[1]))
|
||||
{
|
||||
|
||||
mk_to_fp_signed(f, num, args, result);
|
||||
}
|
||||
else if (num == 3 &&
|
||||
|
@ -1968,8 +1970,8 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args
|
|||
|
||||
one1 = m_bv_util.mk_numeral(1, 1);
|
||||
expr_ref ninf(m), pinf(m);
|
||||
mk_plus_inf(f, pinf);
|
||||
mk_minus_inf(f, ninf);
|
||||
mk_pinf(f, pinf);
|
||||
mk_ninf(f, ninf);
|
||||
|
||||
// NaN -> NaN
|
||||
mk_is_nan(x, c1);
|
||||
|
@ -2152,38 +2154,146 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args
|
|||
void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
||||
TRACE("fpa2bv_to_fp_signed", for (unsigned i = 0; i < num; i++)
|
||||
tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl;);
|
||||
|
||||
// This is meant to be a conversion from signed bitvector to float:
|
||||
|
||||
// This is a conversion from signed bitvector to float:
|
||||
// ; from signed machine integer, represented as a 2's complement bit vector
|
||||
// ((_ to_fp eb sb) RoundingMode(_ BitVec m) (_ FloatingPoint eb sb))
|
||||
|
||||
|
||||
// Semantics:
|
||||
//((_ to_fp eb sb) RoundingMode (_ BitVec m) (_ FloatingPoint eb sb)):
|
||||
// Semantics:
|
||||
// Let b in[[(_ BitVec m)]] and let n be the signed integer represented by b (in 2's complement format).
|
||||
// [[(_ to_fp eb sb)]](r, b) = +/ -infinity if n is too large / too small to be represented as a finite
|
||||
// number of [[(_ FloatingPoint eb sb)]]; [[(_ to_fp eb sb)]](r, x) = y otherwise, where y is the finite
|
||||
// number such that [[fp.to_real]](y) is closest to n according to rounding mode r.
|
||||
|
||||
NOT_IMPLEMENTED_YET();
|
||||
// number such that [[fp.to_real]](y) is closest to n according to rounding mode r.
|
||||
|
||||
SASSERT(num == 2);
|
||||
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());
|
||||
unsigned sz = sbits + ebits;
|
||||
SASSERT(m_bv_util.get_bv_size(args[0]) == 3);
|
||||
SASSERT(m_bv_util.get_bv_size(args[1]) == sz);
|
||||
SASSERT(m_bv_util.is_bv(args[0]));
|
||||
SASSERT(m_bv_util.is_bv(args[1]));
|
||||
|
||||
expr_ref rm(m), x(m);
|
||||
rm = args[0];
|
||||
x = args[1];
|
||||
|
||||
expr_ref sgn(m), sig(m), exp(m);
|
||||
sgn = m_bv_util.mk_extract(sz - 1, sz - 1, x);
|
||||
sig = m_bv_util.mk_extract(sz - ebits - 2, 0, x);
|
||||
exp = m_bv_util.mk_extract(sz - 2, sz - ebits - 1, x);
|
||||
dbg_decouple("fpa2bv_to_fp_signed_x", x);
|
||||
|
||||
round(f->get_range(), rm, sgn, sig, exp, result);
|
||||
unsigned ebits = m_util.get_ebits(f->get_range());
|
||||
unsigned sbits = m_util.get_sbits(f->get_range());
|
||||
unsigned f_sz = sbits + ebits;
|
||||
unsigned bv_sz = m_bv_util.get_bv_size(x);
|
||||
SASSERT(m_bv_util.get_bv_size(rm) == 3);
|
||||
|
||||
//if (bv_sz < f_sz) {
|
||||
// x = m_bv_util.mk_zero_extend(f_sz - bv_sz, x);
|
||||
// bv_sz = f_sz;
|
||||
//}
|
||||
|
||||
expr_ref bv0_1(m), bv1_1(m), bv0_sz(m), bv1_sz(m);
|
||||
bv0_1 = m_bv_util.mk_numeral(0, 1);
|
||||
bv1_1 = m_bv_util.mk_numeral(1, 1);
|
||||
bv0_sz = m_bv_util.mk_numeral(0, bv_sz);
|
||||
bv1_sz = m_bv_util.mk_numeral(1, bv_sz);
|
||||
|
||||
expr_ref is_zero(m), nzero(m), pzero(m), ninf(m), pinf(m);
|
||||
is_zero = m.mk_eq(x, bv0_sz);
|
||||
mk_nzero(f, nzero);
|
||||
mk_pzero(f, pzero);
|
||||
mk_ninf(f, ninf);
|
||||
mk_pinf(f, pinf);
|
||||
|
||||
// Special case: x == 0 -> p/n zero
|
||||
expr_ref c1(m), v1(m), rm_is_to_neg(m);
|
||||
c1 = is_zero;
|
||||
mk_is_rm(rm, BV_RM_TO_NEGATIVE, rm_is_to_neg);
|
||||
mk_ite(rm_is_to_neg, nzero, pzero, v1);
|
||||
|
||||
// Special case: x != 0
|
||||
expr_ref is_neg_bit(m), exp_too_large(m), sig_4(m), exp_2(m);
|
||||
expr_ref is_neg(m), x_abs(m);
|
||||
is_neg_bit = m_bv_util.mk_extract(bv_sz - 1, bv_sz - 1, x);
|
||||
is_neg = m.mk_eq(is_neg_bit, bv1_1);
|
||||
x_abs = m.mk_ite(is_neg, m_bv_util.mk_bv_neg(x), x);
|
||||
dbg_decouple("fpa2bv_to_fp_signed_is_neg", is_neg);
|
||||
// x_abs has an extra bit in the front.
|
||||
// x_abs is [bv_sz-1, bv_sz-2] . [bv_sz-3 ... 0] * 2^(bv_sz-2)
|
||||
// bv_sz-2 is the "1.0" bit for the rounder.
|
||||
|
||||
expr_ref lz(m), e_bv_sz(m), e_rest_sz(m);
|
||||
mk_leading_zeros(x_abs, bv_sz, lz);
|
||||
e_bv_sz = m_bv_util.mk_numeral(bv_sz, bv_sz);
|
||||
e_rest_sz = m_bv_util.mk_bv_sub(e_bv_sz, lz);
|
||||
SASSERT(m_bv_util.get_bv_size(lz) == m_bv_util.get_bv_size(e_bv_sz));
|
||||
dbg_decouple("fpa2bv_to_fp_signed_lz", lz);
|
||||
expr_ref shifted_sig(m);
|
||||
shifted_sig = m_bv_util.mk_bv_shl(x_abs, lz);
|
||||
|
||||
expr_ref sticky(m);
|
||||
// shifted_sig is [bv_sz-1, bv_sz-2] . [bv_sz-3 ... 0] * 2^(bv_sz-2) * 2^(-lz)
|
||||
unsigned sig_sz = sbits + 4; // we want extra rounding bits.
|
||||
if (sig_sz <= bv_sz) {
|
||||
expr_ref sig_rest(m);
|
||||
sig_4 = m_bv_util.mk_extract(bv_sz - 1, bv_sz - sig_sz + 1, shifted_sig); // one short
|
||||
sig_rest = m_bv_util.mk_extract(bv_sz - sig_sz, 0, shifted_sig);
|
||||
sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, sig_rest);
|
||||
sig_4 = m_bv_util.mk_concat(sig_4, sticky);
|
||||
}
|
||||
else {
|
||||
unsigned extra_bits = sig_sz - bv_sz;
|
||||
expr_ref extra_zeros(m);
|
||||
extra_zeros = m_bv_util.mk_numeral(0, extra_bits);
|
||||
sig_4 = m_bv_util.mk_concat(shifted_sig, extra_zeros);
|
||||
lz = m_bv_util.mk_bv_add(m_bv_util.mk_concat(extra_zeros, lz),
|
||||
m_bv_util.mk_numeral(extra_bits, sig_sz));
|
||||
bv_sz = bv_sz + extra_bits;
|
||||
SASSERT(is_well_sorted(m, lz));
|
||||
}
|
||||
SASSERT(m_bv_util.get_bv_size(sig_4) == sig_sz);
|
||||
|
||||
expr_ref s_exp(m), exp_rest(m);
|
||||
s_exp = m_bv_util.mk_bv_sub(m_bv_util.mk_numeral(bv_sz - 2, bv_sz), lz);
|
||||
// s_exp = (bv_sz-2) + (-lz) signed
|
||||
SASSERT(m_bv_util.get_bv_size(s_exp) == bv_sz);
|
||||
|
||||
unsigned exp_sz = ebits + 2; // (+2 for rounder)
|
||||
exp_2 = m_bv_util.mk_extract(exp_sz - 1, 0, s_exp);
|
||||
// the remaining bits are 0 if ebits is large enough.
|
||||
exp_too_large = m.mk_false(); // This is always in range.
|
||||
|
||||
// The exponent is at most bv_sz, i.e., we need ld(bv_sz)+1 ebits.
|
||||
// exp < bv_sz (+sign bit which is [0])
|
||||
unsigned exp_worst_case_sz = (unsigned)((log(bv_sz) / log(2)) + 1);
|
||||
|
||||
if (exp_sz < exp_worst_case_sz) {
|
||||
// exp_sz < exp_worst_case_sz and exp >= 0.
|
||||
// Take the maximum legal exponent; this
|
||||
// allows us to keep the most precision.
|
||||
expr_ref max_exp(m), max_exp_bvsz(m);
|
||||
mk_max_exp(exp_sz, max_exp);
|
||||
max_exp_bvsz = m_bv_util.mk_zero_extend(bv_sz - exp_sz, max_exp);
|
||||
|
||||
exp_too_large = m_bv_util.mk_ule(m_bv_util.mk_bv_add(
|
||||
max_exp_bvsz,
|
||||
m_bv_util.mk_numeral(1, bv_sz)),
|
||||
s_exp);
|
||||
sig_4 = m.mk_ite(exp_too_large, m_bv_util.mk_numeral(0, sig_sz), sig_4);
|
||||
exp_2 = m.mk_ite(exp_too_large, max_exp, exp_2);
|
||||
}
|
||||
dbg_decouple("fpa2bv_to_fp_signed_exp_too_large", exp_too_large);
|
||||
|
||||
expr_ref sgn(m), sig(m), exp(m);
|
||||
sgn = is_neg_bit;
|
||||
sig = sig_4;
|
||||
exp = exp_2;
|
||||
|
||||
dbg_decouple("fpa2bv_to_fp_signed_sgn", sgn);
|
||||
dbg_decouple("fpa2bv_to_fp_signed_sig", sig);
|
||||
dbg_decouple("fpa2bv_to_fp_signed_exp", exp);
|
||||
|
||||
SASSERT(m_bv_util.get_bv_size(sig) == sbits + 4);
|
||||
SASSERT(m_bv_util.get_bv_size(exp) == ebits + 2);
|
||||
|
||||
expr_ref v2(m);
|
||||
round(f->get_range(), rm, sgn, sig, exp, v2);
|
||||
|
||||
mk_ite(c1, v1, v2, result);
|
||||
}
|
||||
|
||||
void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
||||
|
@ -2538,7 +2648,7 @@ void fpa2bv_converter::mk_bias(expr * e, expr_ref & result) {
|
|||
|
||||
void fpa2bv_converter::mk_unbias(expr * e, expr_ref & result) {
|
||||
unsigned ebits = m_bv_util.get_bv_size(e);
|
||||
SASSERT(ebits >= 3);
|
||||
SASSERT(ebits >= 2);
|
||||
|
||||
expr_ref e_plus_one(m);
|
||||
e_plus_one = m_bv_util.mk_bv_add(e, m_bv_util.mk_numeral(1, ebits));
|
||||
|
|
|
@ -86,8 +86,8 @@ public:
|
|||
void mk_uninterpreted_function(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
|
||||
void mk_var(unsigned base_inx, sort * srt, expr_ref & result);
|
||||
|
||||
void mk_plus_inf(func_decl * f, expr_ref & result);
|
||||
void mk_minus_inf(func_decl * f, expr_ref & result);
|
||||
void mk_pinf(func_decl * f, expr_ref & result);
|
||||
void mk_ninf(func_decl * f, expr_ref & result);
|
||||
void mk_nan(func_decl * f, expr_ref & result);
|
||||
void mk_nzero(func_decl *f, expr_ref & result);
|
||||
void mk_pzero(func_decl *f, expr_ref & result);
|
||||
|
|
|
@ -113,8 +113,8 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg {
|
|||
case OP_FLOAT_RM_TOWARD_POSITIVE:
|
||||
case OP_FLOAT_RM_TOWARD_ZERO: m_conv.mk_rounding_mode(f, result); return BR_DONE;
|
||||
case OP_FLOAT_VALUE: m_conv.mk_value(f, num, args, result); return BR_DONE;
|
||||
case OP_FLOAT_PLUS_INF: m_conv.mk_plus_inf(f, result); return BR_DONE;
|
||||
case OP_FLOAT_MINUS_INF: m_conv.mk_minus_inf(f, result); return BR_DONE;
|
||||
case OP_FLOAT_PLUS_INF: m_conv.mk_pinf(f, result); return BR_DONE;
|
||||
case OP_FLOAT_MINUS_INF: m_conv.mk_ninf(f, result); return BR_DONE;
|
||||
case OP_FLOAT_PLUS_ZERO: m_conv.mk_pzero(f, result); return BR_DONE;
|
||||
case OP_FLOAT_MINUS_ZERO: m_conv.mk_nzero(f, result); return BR_DONE;
|
||||
case OP_FLOAT_NAN: m_conv.mk_nan(f, result); return BR_DONE;
|
||||
|
|
|
@ -205,14 +205,14 @@ br_status float_rewriter::mk_neg(expr * arg1, expr_ref & result) {
|
|||
result = arg1;
|
||||
return BR_DONE;
|
||||
}
|
||||
if (m_util.is_plus_inf(arg1)) {
|
||||
if (m_util.is_pinf(arg1)) {
|
||||
// - +oo --> -oo
|
||||
result = m_util.mk_minus_inf(m().get_sort(arg1));
|
||||
result = m_util.mk_ninf(m().get_sort(arg1));
|
||||
return BR_DONE;
|
||||
}
|
||||
if (m_util.is_minus_inf(arg1)) {
|
||||
if (m_util.is_ninf(arg1)) {
|
||||
// - -oo -> +oo
|
||||
result = m_util.mk_plus_inf(m().get_sort(arg1));
|
||||
result = m_util.mk_pinf(m().get_sort(arg1));
|
||||
return BR_DONE;
|
||||
}
|
||||
if (m_util.is_neg(arg1)) {
|
||||
|
@ -366,22 +366,22 @@ br_status float_rewriter::mk_lt(expr * arg1, expr * arg2, expr_ref & result) {
|
|||
result = m().mk_false();
|
||||
return BR_DONE;
|
||||
}
|
||||
if (m_util.is_minus_inf(arg1)) {
|
||||
if (m_util.is_ninf(arg1)) {
|
||||
// -oo < arg2 --> not(arg2 = -oo) and not(arg2 = NaN)
|
||||
result = m().mk_and(m().mk_not(m().mk_eq(arg2, arg1)), mk_neq_nan(arg2));
|
||||
return BR_REWRITE3;
|
||||
}
|
||||
if (m_util.is_minus_inf(arg2)) {
|
||||
if (m_util.is_ninf(arg2)) {
|
||||
// arg1 < -oo --> false
|
||||
result = m().mk_false();
|
||||
return BR_DONE;
|
||||
}
|
||||
if (m_util.is_plus_inf(arg1)) {
|
||||
if (m_util.is_pinf(arg1)) {
|
||||
// +oo < arg2 --> false
|
||||
result = m().mk_false();
|
||||
return BR_DONE;
|
||||
}
|
||||
if (m_util.is_plus_inf(arg2)) {
|
||||
if (m_util.is_pinf(arg2)) {
|
||||
// arg1 < +oo --> not(arg1 = +oo) and not(arg1 = NaN)
|
||||
result = m().mk_and(m().mk_not(m().mk_eq(arg1, arg2)), mk_neq_nan(arg1));
|
||||
return BR_REWRITE3;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue