@@ -147,36 +147,11 @@ void fpa2bv_converter::mk_distinct(func_decl * f, unsigned num, expr * const * a
147
147
148
148
void fpa2bv_converter::mk_numeral (func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
149
149
SASSERT (num == 0 );
150
- sort* s = f->get_range ();
151
- if (f->get_num_parameters () == 1 ) {
152
- SASSERT (f->get_parameter (0 ).is_external ());
153
- unsigned p_id = f->get_parameter (0 ).get_ext_id ();
154
- mpf const & v = m_plugin->get_value (p_id);
155
- mk_numeral (s, v, result);
156
- return ;
157
- }
158
- scoped_mpf v (m_mpf_manager);
159
- unsigned ebits = m_util.get_ebits (s), sbits = m_util.get_sbits (s);
160
- switch (f->get_decl_kind ()) {
161
- case OP_FPA_PLUS_INF:
162
- m_util.fm ().mk_pinf (ebits, sbits, v);
163
- break ;
164
- case OP_FPA_MINUS_INF:
165
- m_util.fm ().mk_ninf (ebits, sbits, v);
166
- break ;
167
- case OP_FPA_NAN:
168
- m_util.fm ().mk_nan (ebits, sbits, v);
169
- break ;
170
- case OP_FPA_PLUS_ZERO:
171
- m_util.fm ().mk_pzero (ebits, sbits, v);
172
- break ;
173
- case OP_FPA_MINUS_ZERO:
174
- m_util.fm ().mk_nzero (ebits, sbits, v);
175
- break ;
176
- default :
177
- UNREACHABLE ();
178
- }
179
- mk_numeral (s, v, result);
150
+ scoped_mpf v (m_mpf_manager);
151
+ expr_ref a (m);
152
+ a = m.mk_app (f, num, args);
153
+ m_util.is_numeral (a, v);
154
+ mk_numeral (f->get_range (), v, result);
180
155
}
181
156
182
157
void fpa2bv_converter::mk_numeral (sort * s, mpf const & v, expr_ref & result) {
@@ -941,8 +916,8 @@ void fpa2bv_converter::mk_div(sort * s, expr_ref & rm, expr_ref & x, expr_ref &
941
916
dbg_decouple (" fpa2bv_div_y_is_pos" , y_is_pos);
942
917
dbg_decouple (" fpa2bv_div_y_is_inf" , y_is_inf);
943
918
944
- expr_ref c1 (m), c2 (m), c3 (m), c4 (m), c5 (m), c6 (m), c7 (m);
945
- expr_ref v1 (m), v2 (m), v3 (m), v4 (m), v5 (m), v6 (m), v7 (m), v8 (m);
919
+ expr_ref c1 (m), c2 (m), c3 (m), c4 (m), c5 (m), c6 (m), c7 (m), c8 (m) ;
920
+ expr_ref v1 (m), v2 (m), v3 (m), v4 (m), v5 (m), v6 (m), v7 (m), v8 (m), v9 (m) ;
946
921
947
922
// (x is NaN) || (y is NaN) -> NaN
948
923
m_simp.mk_or (x_is_nan, y_is_nan, c1);
@@ -998,6 +973,9 @@ void fpa2bv_converter::mk_div(sort * s, expr_ref & rm, expr_ref & x, expr_ref &
998
973
a_sig_ext = m_bv_util.mk_concat (a_sig, m_bv_util.mk_numeral (0 , sbits + extra_bits));
999
974
b_sig_ext = m_bv_util.mk_zero_extend (sbits + extra_bits, b_sig);
1000
975
976
+ dbg_decouple (" fpa2bv_div_a_sig_ext" , a_sig_ext);
977
+ dbg_decouple (" fpa2bv_div_b_sig_ext" , b_sig_ext);
978
+
1001
979
expr_ref a_exp_ext (m), b_exp_ext (m);
1002
980
a_exp_ext = m_bv_util.mk_sign_extend (2 , a_exp);
1003
981
b_exp_ext = m_bv_util.mk_sign_extend (2 , b_exp);
@@ -1017,14 +995,21 @@ void fpa2bv_converter::mk_div(sort * s, expr_ref & rm, expr_ref & x, expr_ref &
1017
995
expr_ref quotient (m);
1018
996
// b_sig_ext can't be 0 here, so it's safe to use OP_BUDIV_I
1019
997
quotient = m.mk_app (m_bv_util.get_fid (), OP_BUDIV_I, a_sig_ext, b_sig_ext);
1020
-
1021
998
dbg_decouple (" fpa2bv_div_quotient" , quotient);
1022
999
1023
1000
SASSERT (m_bv_util.get_bv_size (quotient) == (sbits + sbits + extra_bits));
1024
1001
1025
- expr_ref sticky (m);
1002
+ expr_ref sticky (m), upper (m), upper_reduced (m), too_large (m) ;
1026
1003
sticky = m.mk_app (m_bv_util.get_fid (), OP_BREDOR, m_bv_util.mk_extract (extra_bits-2 , 0 , quotient));
1027
1004
res_sig = m_bv_util.mk_concat (m_bv_util.mk_extract (extra_bits+sbits+1 , extra_bits-1 , quotient), sticky);
1005
+ upper = m_bv_util.mk_extract (sbits + sbits + extra_bits-1 , extra_bits+sbits+2 , quotient);
1006
+ upper_reduced = m.mk_app (m_bv_util.get_fid (), OP_BREDOR, upper.get ());
1007
+ too_large = m.mk_eq (upper_reduced, m_bv_util.mk_numeral (1 , 1 ));
1008
+ c8 = too_large;
1009
+ mk_ite (signs_xor, ninf, pinf, v8);
1010
+ dbg_decouple (" fpa2bv_div_res_sig_p4" , res_sig);
1011
+ dbg_decouple (" fpa2bv_div_upper" , upper);
1012
+ dbg_decouple (" fpa2bv_div_too_large" , too_large);
1028
1013
1029
1014
SASSERT (m_bv_util.get_bv_size (res_sig) == (sbits + 4 ));
1030
1015
@@ -1042,10 +1027,14 @@ void fpa2bv_converter::mk_div(sort * s, expr_ref & rm, expr_ref & x, expr_ref &
1042
1027
m_simp.mk_ite (shift_cond, res_sig, res_sig_shifted, res_sig);
1043
1028
m_simp.mk_ite (shift_cond, res_exp, res_exp_shifted, res_exp);
1044
1029
1045
- round (s, rm, res_sgn, res_sig, res_exp, v8);
1030
+ dbg_decouple (" fpa2bv_div_res_sig" , res_sig);
1031
+ dbg_decouple (" fpa2bv_div_res_exp" , res_exp);
1032
+
1033
+ round (s, rm, res_sgn, res_sig, res_exp, v9);
1046
1034
1047
1035
// And finally, we tie them together.
1048
- mk_ite (c7, v7, v8, result);
1036
+ mk_ite (c8, v8, v9, result);
1037
+ mk_ite (c7, v7, result, result);
1049
1038
mk_ite (c6, v6, result, result);
1050
1039
mk_ite (c5, v5, result, result);
1051
1040
mk_ite (c4, v4, result, result);
@@ -2809,8 +2798,46 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr *
2809
2798
2810
2799
expr * e = m.mk_eq (m_util.mk_to_real (result), x);
2811
2800
m_extra_assertions.push_back (e);
2812
- // x = 0 -> result = 0+
2813
- m_extra_assertions.push_back (m.mk_implies (m.mk_eq (x, zero), m.mk_eq (result, m_util.mk_pzero (result->get_sort ()))));
2801
+
2802
+ expr_ref r_is_nan (m);
2803
+ mk_is_nan (result, r_is_nan);
2804
+ m_extra_assertions.push_back (m.mk_not (r_is_nan));
2805
+
2806
+ rational min_real, max_real;
2807
+ const mpz& max_exp_z = m_mpf_manager.m_powers2 .m1 (ebits-1 );
2808
+ SASSERT (m_mpz_manager.is_uint (max_exp_z));
2809
+ unsigned max_exp = m_mpz_manager.get_uint (max_exp_z);
2810
+ rational max_sig = m_mpf_manager.m_powers2 .m1 (sbits) / m_mpf_manager.m_powers2 (sbits-1 );
2811
+ max_real = max_sig * rational (m_mpf_manager.m_powers2 (max_exp));
2812
+ TRACE (" fpa2bv_to_real" , tout << " max exp: " << max_exp << " max real: " << max_real << std::endl;);
2813
+
2814
+ expr_ref r_is_pinf (m), r_is_ninf (m);
2815
+ mk_is_pinf (result, r_is_pinf);
2816
+ mk_is_ninf (result, r_is_ninf);
2817
+
2818
+ expr_ref e_max_real (m), e_max_real_neg (m);
2819
+ e_max_real = m_arith_util.mk_numeral (max_real, false );
2820
+ e_max_real_neg = m_arith_util.mk_numeral (-max_real, false );
2821
+
2822
+ expr_ref rm_nta (m), rm_nte (m), rm_tp (m), rm_tn (m), rm_tz (m);
2823
+ mk_is_rm (bv_rm, BV_RM_TIES_TO_AWAY, rm_nta);
2824
+ mk_is_rm (bv_rm, BV_RM_TIES_TO_EVEN, rm_nte);
2825
+ mk_is_rm (bv_rm, BV_RM_TO_POSITIVE, rm_tp);
2826
+ mk_is_rm (bv_rm, BV_RM_TO_NEGATIVE, rm_tn);
2827
+ mk_is_rm (bv_rm, BV_RM_TO_ZERO, rm_tz);
2828
+
2829
+ expr_ref implies_gt_max_real (m), implies_lt_min_real (m);
2830
+ implies_gt_max_real = m.mk_implies (r_is_pinf, m.mk_and (rm_tp, m_arith_util.mk_gt (x, e_max_real)));
2831
+ implies_lt_min_real = m.mk_implies (r_is_ninf, m.mk_and (rm_tn, m_arith_util.mk_lt (x, e_max_real_neg)));
2832
+
2833
+ m_extra_assertions.push_back (implies_gt_max_real);
2834
+ m_extra_assertions.push_back (implies_lt_min_real);
2835
+
2836
+ // x = 0 -> result = +0/-0
2837
+ expr_ref pzero (m), nzero (m);
2838
+ mk_pzero (result->get_sort (), pzero);
2839
+ mk_nzero (result->get_sort (), nzero);
2840
+ m_extra_assertions.push_back (m.mk_implies (m.mk_eq (x, zero), m.mk_or (m.mk_eq (result, pzero), m.mk_eq (result, nzero))));
2814
2841
}
2815
2842
2816
2843
SASSERT (is_well_sorted (m, result));
@@ -2854,19 +2881,13 @@ void fpa2bv_converter::mk_to_fp_real_int(func_decl * f, unsigned num, expr * con
2854
2881
m_mpf_manager.set (tn, ebits, sbits, MPF_ROUND_TOWARD_NEGATIVE, e.to_mpq ().numerator (), q.to_mpq ());
2855
2882
m_mpf_manager.set (tz, ebits, sbits, MPF_ROUND_TOWARD_ZERO, e.to_mpq ().numerator (), q.to_mpq ());
2856
2883
2857
- app_ref a_nte (m), a_nta (m), a_tp (m), a_tn (m), a_tz (m);
2858
- a_nte = m_plugin->mk_numeral (nte);
2859
- a_nta = m_plugin->mk_numeral (nta);
2860
- a_tp = m_plugin->mk_numeral (tp);
2861
- a_tn = m_plugin->mk_numeral (tn);
2862
- a_tz = m_plugin->mk_numeral (tz);
2863
-
2864
2884
expr_ref bv_nte (m), bv_nta (m), bv_tp (m), bv_tn (m), bv_tz (m);
2865
- mk_numeral (a_nte->get_decl (), 0 , nullptr , bv_nte);
2866
- mk_numeral (a_nta->get_decl (), 0 , nullptr , bv_nta);
2867
- mk_numeral (a_tp->get_decl (), 0 , nullptr , bv_tp);
2868
- mk_numeral (a_tn->get_decl (), 0 , nullptr , bv_tn);
2869
- mk_numeral (a_tz->get_decl (), 0 , nullptr , bv_tz);
2885
+ sort *s = f->get_range ();
2886
+ mk_numeral (s, nte, bv_nte);
2887
+ mk_numeral (s, nta, bv_nta);
2888
+ mk_numeral (s, tp, bv_tp);
2889
+ mk_numeral (s, tn, bv_tn);
2890
+ mk_numeral (s, tz, bv_tz);
2870
2891
2871
2892
expr_ref c1 (m), c2 (m), c3 (m), c4 (m);
2872
2893
c1 = m.mk_eq (bv_rm, m_bv_util.mk_numeral (BV_RM_TO_POSITIVE, 3 ));
@@ -3003,30 +3024,42 @@ void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const
3003
3024
unsigned bv_sz = m_bv_util.get_bv_size (x);
3004
3025
SASSERT (m_bv_util.get_bv_size (rm) == 3 );
3005
3026
3027
+ expr_ref rm_is_to_neg (m);
3028
+ mk_is_rm (rm, BV_RM_TO_NEGATIVE, rm_is_to_neg);
3029
+
3006
3030
expr_ref bv1_1 (m), bv0_sz (m);
3007
3031
bv1_1 = m_bv_util.mk_numeral (1 , 1 );
3008
3032
bv0_sz = m_bv_util.mk_numeral (0 , bv_sz);
3009
3033
3010
- expr_ref is_zero (m), pzero (m);
3034
+ expr_ref is_zero (m), pzero (m), nzero (m) ;
3011
3035
is_zero = m.mk_eq (x, bv0_sz);
3012
3036
mk_pzero (f, pzero);
3037
+ mk_nzero (f, nzero);
3013
3038
3014
- // Special case: x == 0 -> p/n zero
3039
+ // Special case: x == 0 -> + zero
3015
3040
expr_ref c1 (m), v1 (m);
3016
3041
c1 = is_zero;
3017
- v1 = pzero;
3042
+ v1 = pzero; // No -zero? zeros_consistent_4.smt2 requires +zero.
3018
3043
3019
3044
// Special case: x != 0
3020
- expr_ref is_neg_bit (m), exp_too_large (m), sig_4 (m), exp_2 (m);
3045
+ expr_ref sign_bit (m), exp_too_large (m), sig_4 (m), exp_2 (m), rest (m);
3021
3046
expr_ref is_neg (m), x_abs (m), neg_x (m);
3022
- is_neg_bit = m_bv_util.mk_extract (bv_sz - 1 , bv_sz - 1 , x);
3023
- is_neg = m.mk_eq (is_neg_bit, bv1_1);
3024
- neg_x = m_bv_util.mk_bv_neg (x); // overflow problem?
3047
+ sign_bit = m_bv_util.mk_extract (bv_sz - 1 , bv_sz - 1 , x);
3048
+ rest = m_bv_util.mk_extract (bv_sz - 2 , 0 , x);
3049
+ dbg_decouple (" fpa2bv_to_fp_signed_rest" , rest);
3050
+ is_neg = m.mk_eq (sign_bit, bv1_1);
3051
+ neg_x = m_bv_util.mk_bv_neg (x);
3025
3052
x_abs = m.mk_ite (is_neg, neg_x, x);
3026
3053
dbg_decouple (" fpa2bv_to_fp_signed_is_neg" , is_neg);
3027
3054
// x_abs has an extra bit in the front.
3028
3055
// x_abs is [bv_sz-1, bv_sz-2] . [bv_sz-3 ... 0] * 2^(bv_sz-2)
3029
3056
// bv_sz-2 is the "1.0" bit for the rounder.
3057
+ expr_ref is_max_neg (m);
3058
+ is_max_neg = m.mk_and (is_neg, m.mk_eq (rest, m_bv_util.mk_numeral (0 , bv_sz-1 )));
3059
+ dbg_decouple (" fpa2bv_to_fp_signed_is_max_neg" , is_max_neg);
3060
+
3061
+ x_abs = m.mk_ite (is_max_neg, m_bv_util.mk_concat (bv1_1, m_bv_util.mk_numeral (0 , bv_sz-1 )), x_abs);
3062
+ dbg_decouple (" fpa2bv_to_fp_signed_x_abs" , x_abs);
3030
3063
3031
3064
expr_ref lz (m);
3032
3065
mk_leading_zeros (x_abs, bv_sz, lz);
@@ -3061,6 +3094,7 @@ void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const
3061
3094
expr_ref s_exp (m), exp_rest (m);
3062
3095
s_exp = m_bv_util.mk_bv_sub (m_bv_util.mk_numeral (bv_sz - 2 , bv_sz), lz);
3063
3096
// s_exp = (bv_sz-2) + (-lz) signed
3097
+ s_exp = m.mk_ite (is_max_neg, m_bv_util.mk_bv_sub (s_exp, m_bv_util.mk_numeral (1 , bv_sz)), s_exp);
3064
3098
SASSERT (m_bv_util.get_bv_size (s_exp) == bv_sz);
3065
3099
dbg_decouple (" fpa2bv_to_fp_signed_s_exp" , s_exp);
3066
3100
@@ -3093,7 +3127,7 @@ void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const
3093
3127
dbg_decouple (" fpa2bv_to_fp_signed_exp_too_large" , exp_too_large);
3094
3128
3095
3129
expr_ref sgn (m), sig (m), exp (m);
3096
- sgn = is_neg_bit ;
3130
+ sgn = sign_bit ;
3097
3131
sig = sig_4;
3098
3132
exp = exp_2;
3099
3133
@@ -3132,6 +3166,9 @@ void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * con
3132
3166
rm = to_app (args[0 ])->get_arg (0 );
3133
3167
x = args[1 ];
3134
3168
3169
+ expr_ref rm_is_to_neg (m);
3170
+ mk_is_rm (rm, BV_RM_TO_NEGATIVE, rm_is_to_neg);
3171
+
3135
3172
dbg_decouple (" fpa2bv_to_fp_unsigned_x" , x);
3136
3173
3137
3174
unsigned ebits = m_util.get_ebits (f->get_range ());
@@ -3143,14 +3180,15 @@ void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * con
3143
3180
bv0_1 = m_bv_util.mk_numeral (0 , 1 );
3144
3181
bv0_sz = m_bv_util.mk_numeral (0 , bv_sz);
3145
3182
3146
- expr_ref is_zero (m), pzero (m);
3183
+ expr_ref is_zero (m), pzero (m), nzero (m) ;
3147
3184
is_zero = m.mk_eq (x, bv0_sz);
3148
3185
mk_pzero (f, pzero);
3186
+ mk_nzero (f, nzero);
3149
3187
3150
- // Special case: x == 0 -> p/n zero
3188
+ // Special case: x == 0 -> + zero
3151
3189
expr_ref c1 (m), v1 (m);
3152
3190
c1 = is_zero;
3153
- v1 = pzero;
3191
+ v1 = pzero; // No nzero?
3154
3192
3155
3193
// Special case: x != 0
3156
3194
expr_ref exp_too_large (m), sig_4 (m), exp_2 (m);
@@ -3194,7 +3232,7 @@ void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * con
3194
3232
unsigned exp_sz = ebits + 2 ; // (+2 for rounder)
3195
3233
exp_2 = m_bv_util.mk_extract (exp_sz - 1 , 0 , s_exp);
3196
3234
// the remaining bits are 0 if ebits is large enough.
3197
- exp_too_large = m.mk_false (); // This is always in range.
3235
+ exp_too_large = m.mk_false ();
3198
3236
3199
3237
// The exponent is at most bv_sz, i.e., we need ld(bv_sz)+1 ebits.
3200
3238
// exp < bv_sz (+sign bit which is [0])
0 commit comments