mirror of
https://github.com/Z3Prover/z3
synced 2025-04-15 21:38:44 +00:00
Merge branch 'unstable' of https://github.com/Z3Prover/z3 into unstable
This commit is contained in:
commit
dc52ebd312
|
@ -1,6 +1,6 @@
|
||||||
RELEASE NOTES
|
RELEASE NOTES
|
||||||
|
|
||||||
Version 4.4
|
Version 4.4.0
|
||||||
=============
|
=============
|
||||||
|
|
||||||
- New feature: Support for the theory of floating-point numbers. This comes in the form of logics (QF_FP and QF_FPBV), tactics (qffp and qffpbv), as well as a theory plugin that allows theory combinations. Z3 supports the official SMT theory definition of FP (see http://smtlib.cs.uiowa.edu/theories/FloatingPoint.smt2) in SMT2 files, as well as all APIs.
|
- New feature: Support for the theory of floating-point numbers. This comes in the form of logics (QF_FP and QF_FPBV), tactics (qffp and qffpbv), as well as a theory plugin that allows theory combinations. Z3 supports the official SMT theory definition of FP (see http://smtlib.cs.uiowa.edu/theories/FloatingPoint.smt2) in SMT2 files, as well as all APIs.
|
||||||
|
|
|
@ -9,7 +9,7 @@ from mk_util import *
|
||||||
|
|
||||||
# Z3 Project definition
|
# Z3 Project definition
|
||||||
def init_project_def():
|
def init_project_def():
|
||||||
set_version(4, 4, 0, 0)
|
set_version(4, 4, 1, 0)
|
||||||
add_lib('util', [])
|
add_lib('util', [])
|
||||||
add_lib('polynomial', ['util'], 'math/polynomial')
|
add_lib('polynomial', ['util'], 'math/polynomial')
|
||||||
add_lib('sat', ['util'])
|
add_lib('sat', ['util'])
|
||||||
|
|
|
@ -86,6 +86,9 @@ VS_PAR_NUM=8
|
||||||
GPROF=False
|
GPROF=False
|
||||||
GIT_HASH=False
|
GIT_HASH=False
|
||||||
|
|
||||||
|
FPMATH="Default"
|
||||||
|
FPMATH_FLAGS="-mfpmath=sse -msse -msse2"
|
||||||
|
|
||||||
def check_output(cmd):
|
def check_output(cmd):
|
||||||
return str(subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0]).rstrip('\r\n')
|
return str(subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0]).rstrip('\r\n')
|
||||||
|
|
||||||
|
@ -227,10 +230,37 @@ def test_openmp(cc):
|
||||||
t.add('#include<omp.h>\nint main() { return omp_in_parallel() ? 1 : 0; }\n')
|
t.add('#include<omp.h>\nint main() { return omp_in_parallel() ? 1 : 0; }\n')
|
||||||
t.commit()
|
t.commit()
|
||||||
if IS_WINDOWS:
|
if IS_WINDOWS:
|
||||||
return exec_compiler_cmd([cc, CPPFLAGS, 'tstomp.cpp', LDFLAGS, '/openmp']) == 0
|
r = exec_compiler_cmd([cc, CPPFLAGS, 'tstomp.cpp', LDFLAGS, '/openmp']) == 0
|
||||||
|
try:
|
||||||
|
rmf('tstomp.obj')
|
||||||
|
rmf('tstomp.exe')
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return r
|
||||||
else:
|
else:
|
||||||
return exec_compiler_cmd([cc, CPPFLAGS, 'tstomp.cpp', LDFLAGS, '-fopenmp']) == 0
|
return exec_compiler_cmd([cc, CPPFLAGS, 'tstomp.cpp', LDFLAGS, '-fopenmp']) == 0
|
||||||
|
|
||||||
|
def test_fpmath(cc):
|
||||||
|
global FPMATH_FLAGS
|
||||||
|
if is_verbose():
|
||||||
|
print("Testing floating point support...")
|
||||||
|
t = TempFile('tstsse.cpp')
|
||||||
|
t.add('int main() { return 42; }\n')
|
||||||
|
t.commit()
|
||||||
|
if exec_compiler_cmd([cc, CPPFLAGS, 'tstsse.cpp', LDFLAGS, '-mfpmath=sse -msse -msse2']) == 0:
|
||||||
|
FPMATH_FLAGS="-mfpmath=sse -msse -msse2"
|
||||||
|
return "SSE2-GCC"
|
||||||
|
elif exec_compiler_cmd([cc, CPPFLAGS, 'tstsse.cpp', LDFLAGS, '-msse -msse2']) == 0:
|
||||||
|
FPMATH_FLAGS="-msse -msse2"
|
||||||
|
return "SSE2-CLANG"
|
||||||
|
elif exec_compiler_cmd([cc, CPPFLAGS, 'tstsse.cpp', LDFLAGS, '-mfpu=vfp -mfloat-abi=hard']) == 0:
|
||||||
|
FPMATH_FLAGS="-mfpu=vfp -mfloat-abi=hard"
|
||||||
|
return "ARM-VFP"
|
||||||
|
else:
|
||||||
|
FPMATH_FLAGS=""
|
||||||
|
return "UNKNOWN"
|
||||||
|
|
||||||
|
|
||||||
def find_jni_h(path):
|
def find_jni_h(path):
|
||||||
for root, dirs, files in os.walk(path):
|
for root, dirs, files in os.walk(path):
|
||||||
for f in files:
|
for f in files:
|
||||||
|
@ -357,10 +387,14 @@ def check_ml():
|
||||||
r = exec_cmd([OCAMLOPT, '-o', 'a.out', 'hello.ml'])
|
r = exec_cmd([OCAMLOPT, '-o', 'a.out', 'hello.ml'])
|
||||||
if r != 0:
|
if r != 0:
|
||||||
raise MKException('Failed testing ocamlopt compiler. Set environment variable OCAMLOPT with the path to the Ocaml native compiler. Note that ocamlopt may require flexlink to be in your path.')
|
raise MKException('Failed testing ocamlopt compiler. Set environment variable OCAMLOPT with the path to the Ocaml native compiler. Note that ocamlopt may require flexlink to be in your path.')
|
||||||
rmf('hello.cmi')
|
try:
|
||||||
rmf('hello.cmo')
|
rmf('hello.cmi')
|
||||||
rmf('hello.cmx')
|
rmf('hello.cmo')
|
||||||
rmf('a.out')
|
rmf('hello.cmx')
|
||||||
|
rmf('a.out')
|
||||||
|
rmf('hello.o')
|
||||||
|
except:
|
||||||
|
pass
|
||||||
find_ml_lib()
|
find_ml_lib()
|
||||||
find_ocaml_find()
|
find_ocaml_find()
|
||||||
|
|
||||||
|
@ -1777,7 +1811,7 @@ def mk_config():
|
||||||
print('OCaml Native: %s' % OCAMLOPT)
|
print('OCaml Native: %s' % OCAMLOPT)
|
||||||
print('OCaml Library: %s' % OCAML_LIB)
|
print('OCaml Library: %s' % OCAML_LIB)
|
||||||
else:
|
else:
|
||||||
global CXX, CC, GMP, FOCI2, CPPFLAGS, CXXFLAGS, LDFLAGS, EXAMP_DEBUG_FLAG
|
global CXX, CC, GMP, FOCI2, CPPFLAGS, CXXFLAGS, LDFLAGS, EXAMP_DEBUG_FLAG, FPMATH_FLAGS
|
||||||
OS_DEFINES = ""
|
OS_DEFINES = ""
|
||||||
ARITH = "internal"
|
ARITH = "internal"
|
||||||
check_ar()
|
check_ar()
|
||||||
|
@ -1806,9 +1840,11 @@ def mk_config():
|
||||||
if GIT_HASH:
|
if GIT_HASH:
|
||||||
CPPFLAGS = '%s -DZ3GITHASH=%s' % (CPPFLAGS, GIT_HASH)
|
CPPFLAGS = '%s -DZ3GITHASH=%s' % (CPPFLAGS, GIT_HASH)
|
||||||
CXXFLAGS = '%s -fvisibility=hidden -c' % CXXFLAGS
|
CXXFLAGS = '%s -fvisibility=hidden -c' % CXXFLAGS
|
||||||
|
FPMATH = test_fpmath(CXX)
|
||||||
|
CXXFLAGS = '%s %s' % (CXXFLAGS, FPMATH_FLAGS)
|
||||||
HAS_OMP = test_openmp(CXX)
|
HAS_OMP = test_openmp(CXX)
|
||||||
if HAS_OMP:
|
if HAS_OMP:
|
||||||
CXXFLAGS = '%s -fopenmp -mfpmath=sse' % CXXFLAGS
|
CXXFLAGS = '%s -fopenmp' % CXXFLAGS
|
||||||
LDFLAGS = '%s -fopenmp' % LDFLAGS
|
LDFLAGS = '%s -fopenmp' % LDFLAGS
|
||||||
SLIBEXTRAFLAGS = '%s -fopenmp' % SLIBEXTRAFLAGS
|
SLIBEXTRAFLAGS = '%s -fopenmp' % SLIBEXTRAFLAGS
|
||||||
else:
|
else:
|
||||||
|
@ -1861,7 +1897,6 @@ def mk_config():
|
||||||
CPPFLAGS = '%s -DZ3DEBUG' % CPPFLAGS
|
CPPFLAGS = '%s -DZ3DEBUG' % CPPFLAGS
|
||||||
if TRACE or DEBUG_MODE:
|
if TRACE or DEBUG_MODE:
|
||||||
CPPFLAGS = '%s -D_TRACE' % CPPFLAGS
|
CPPFLAGS = '%s -D_TRACE' % CPPFLAGS
|
||||||
CXXFLAGS = '%s -msse -msse2' % CXXFLAGS
|
|
||||||
config.write('PREFIX=%s\n' % PREFIX)
|
config.write('PREFIX=%s\n' % PREFIX)
|
||||||
config.write('CC=%s\n' % CC)
|
config.write('CC=%s\n' % CC)
|
||||||
config.write('CXX=%s\n' % CXX)
|
config.write('CXX=%s\n' % CXX)
|
||||||
|
@ -1892,6 +1927,7 @@ def mk_config():
|
||||||
print('OpenMP: %s' % HAS_OMP)
|
print('OpenMP: %s' % HAS_OMP)
|
||||||
print('Prefix: %s' % PREFIX)
|
print('Prefix: %s' % PREFIX)
|
||||||
print('64-bit: %s' % is64())
|
print('64-bit: %s' % is64())
|
||||||
|
print('FP math: %s' % FPMATH)
|
||||||
if GPROF:
|
if GPROF:
|
||||||
print('gprof: enabled')
|
print('gprof: enabled')
|
||||||
print('Python version: %s' % distutils.sysconfig.get_python_version())
|
print('Python version: %s' % distutils.sysconfig.get_python_version())
|
||||||
|
|
|
@ -47,16 +47,16 @@ def set_build_dir(path):
|
||||||
mk_dir(BUILD_X64_DIR)
|
mk_dir(BUILD_X64_DIR)
|
||||||
|
|
||||||
def display_help():
|
def display_help():
|
||||||
print "mk_win_dist.py: Z3 Windows distribution generator\n"
|
print("mk_win_dist.py: Z3 Windows distribution generator\n")
|
||||||
print "This script generates the zip files containing executables, dlls, header files for Windows."
|
print("This script generates the zip files containing executables, dlls, header files for Windows.")
|
||||||
print "It must be executed from the Z3 root directory."
|
print("It must be executed from the Z3 root directory.")
|
||||||
print "\nOptions:"
|
print("\nOptions:")
|
||||||
print " -h, --help display this message."
|
print(" -h, --help display this message.")
|
||||||
print " -s, --silent do not print verbose messages."
|
print(" -s, --silent do not print verbose messages.")
|
||||||
print " -b <sudir>, --build=<subdir> subdirectory where x86 and x64 Z3 versions will be built (default: build-dist)."
|
print(" -b <sudir>, --build=<subdir> subdirectory where x86 and x64 Z3 versions will be built (default: build-dist).")
|
||||||
print " -f, --force force script to regenerate Makefiles."
|
print(" -f, --force force script to regenerate Makefiles.")
|
||||||
print " --nojava do not include Java bindings in the binary distribution files."
|
print(" --nojava do not include Java bindings in the binary distribution files.")
|
||||||
print " --githash include git hash in the Zip file."
|
print(" --githash include git hash in the Zip file.")
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
# Parse configuration option for mk_make script
|
# Parse configuration option for mk_make script
|
||||||
|
@ -180,7 +180,7 @@ def mk_dist_dir_core(x64):
|
||||||
mk_util.JAVA_ENABLED = JAVA_ENABLED
|
mk_util.JAVA_ENABLED = JAVA_ENABLED
|
||||||
mk_win_dist(build_path, dist_path)
|
mk_win_dist(build_path, dist_path)
|
||||||
if is_verbose():
|
if is_verbose():
|
||||||
print "Generated %s distribution folder at '%s'" % (platform, dist_path)
|
print("Generated %s distribution folder at '%s'") % (platform, dist_path)
|
||||||
|
|
||||||
def mk_dist_dir():
|
def mk_dist_dir():
|
||||||
mk_dist_dir_core(False)
|
mk_dist_dir_core(False)
|
||||||
|
@ -208,7 +208,7 @@ def mk_zip_core(x64):
|
||||||
ZIPOUT = zipfile.ZipFile(zfname, 'w', zipfile.ZIP_DEFLATED)
|
ZIPOUT = zipfile.ZipFile(zfname, 'w', zipfile.ZIP_DEFLATED)
|
||||||
os.path.walk(dist_path, mk_zip_visitor, '*')
|
os.path.walk(dist_path, mk_zip_visitor, '*')
|
||||||
if is_verbose():
|
if is_verbose():
|
||||||
print "Generated '%s'" % zfname
|
print("Generated '%s'") % zfname
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
ZIPOUT = None
|
ZIPOUT = None
|
||||||
|
@ -253,7 +253,7 @@ def cp_vs_runtime_core(x64):
|
||||||
for f in VS_RUNTIME_FILES:
|
for f in VS_RUNTIME_FILES:
|
||||||
shutil.copy(f, bin_dist_path)
|
shutil.copy(f, bin_dist_path)
|
||||||
if is_verbose():
|
if is_verbose():
|
||||||
print "Copied '%s' to '%s'" % (f, bin_dist_path)
|
print("Copied '%s' to '%s'") % (f, bin_dist_path)
|
||||||
|
|
||||||
def cp_vs_runtime():
|
def cp_vs_runtime():
|
||||||
cp_vs_runtime_core(True)
|
cp_vs_runtime_core(True)
|
||||||
|
|
|
@ -2516,7 +2516,7 @@ namespace Microsoft.Z3
|
||||||
/// Create a bit-vector numeral.
|
/// Create a bit-vector numeral.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="v">value of the numeral.</param>
|
/// <param name="v">value of the numeral.</param>
|
||||||
/// /// <param name="size">the size of the bit-vector</param>
|
/// <param name="size">the size of the bit-vector</param>
|
||||||
public BitVecNum MkBV(long v, uint size)
|
public BitVecNum MkBV(long v, uint size)
|
||||||
{
|
{
|
||||||
Contract.Ensures(Contract.Result<BitVecNum>() != null);
|
Contract.Ensures(Contract.Result<BitVecNum>() != null);
|
||||||
|
|
|
@ -1043,6 +1043,13 @@ func_decl * basic_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters
|
||||||
case OP_DISTINCT: {
|
case OP_DISTINCT: {
|
||||||
func_decl_info info(m_family_id, OP_DISTINCT);
|
func_decl_info info(m_family_id, OP_DISTINCT);
|
||||||
info.set_pairwise();
|
info.set_pairwise();
|
||||||
|
for (unsigned i = 1; i < arity; i++) {
|
||||||
|
if (domain[i] != domain[0]) {
|
||||||
|
std::ostringstream buffer;
|
||||||
|
buffer << "Sort mismatch between first argument and argument " << (i+1);
|
||||||
|
throw ast_exception(buffer.str().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
return m_manager->mk_func_decl(symbol("distinct"), arity, domain, m_bool_sort, info);
|
return m_manager->mk_func_decl(symbol("distinct"), arity, domain, m_bool_sort, info);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -2338,6 +2345,10 @@ quantifier * ast_manager::update_quantifier(quantifier * q, bool is_forall, unsi
|
||||||
num_patterns == 0 ? q->get_no_patterns() : 0);
|
num_patterns == 0 ? q->get_no_patterns() : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app * ast_manager::mk_distinct(unsigned num_args, expr * const * args) {
|
||||||
|
return mk_app(m_basic_family_id, OP_DISTINCT, num_args, args);
|
||||||
|
}
|
||||||
|
|
||||||
app * ast_manager::mk_distinct_expanded(unsigned num_args, expr * const * args) {
|
app * ast_manager::mk_distinct_expanded(unsigned num_args, expr * const * args) {
|
||||||
if (num_args < 2)
|
if (num_args < 2)
|
||||||
return mk_true();
|
return mk_true();
|
||||||
|
|
|
@ -2000,7 +2000,7 @@ public:
|
||||||
app * mk_and(expr * arg1, expr * arg2, expr * arg3) { return mk_app(m_basic_family_id, OP_AND, arg1, arg2, arg3); }
|
app * mk_and(expr * arg1, expr * arg2, expr * arg3) { return mk_app(m_basic_family_id, OP_AND, arg1, arg2, arg3); }
|
||||||
app * mk_implies(expr * arg1, expr * arg2) { return mk_app(m_basic_family_id, OP_IMPLIES, arg1, arg2); }
|
app * mk_implies(expr * arg1, expr * arg2) { return mk_app(m_basic_family_id, OP_IMPLIES, arg1, arg2); }
|
||||||
app * mk_not(expr * n) { return mk_app(m_basic_family_id, OP_NOT, n); }
|
app * mk_not(expr * n) { return mk_app(m_basic_family_id, OP_NOT, n); }
|
||||||
app * mk_distinct(unsigned num_args, expr * const * args) { return mk_app(m_basic_family_id, OP_DISTINCT, num_args, args); }
|
app * mk_distinct(unsigned num_args, expr * const * args);
|
||||||
app * mk_distinct_expanded(unsigned num_args, expr * const * args);
|
app * mk_distinct_expanded(unsigned num_args, expr * const * args);
|
||||||
app * mk_true() { return m_true; }
|
app * mk_true() { return m_true; }
|
||||||
app * mk_false() { return m_false; }
|
app * mk_false() { return m_false; }
|
||||||
|
|
|
@ -1041,80 +1041,54 @@ void fpa2bv_converter::mk_min(func_decl * f, unsigned num, expr * const * args,
|
||||||
split_fp(x, x_sgn, x_exp, x_sig);
|
split_fp(x, x_sgn, x_exp, x_sig);
|
||||||
split_fp(y, y_sgn, y_exp, y_sig);
|
split_fp(y, y_sgn, y_exp, y_sig);
|
||||||
|
|
||||||
expr_ref c1(m), c2(m), x_is_nan(m), y_is_nan(m), x_is_zero(m), y_is_zero(m), c1_and(m);
|
expr_ref x_is_nan(m), y_is_nan(m), x_is_zero(m), y_is_zero(m), both_zero(m), pzero(m);
|
||||||
mk_is_zero(x, x_is_zero);
|
mk_is_zero(x, x_is_zero);
|
||||||
mk_is_zero(y, y_is_zero);
|
mk_is_zero(y, y_is_zero);
|
||||||
m_simp.mk_and(x_is_zero, y_is_zero, c1_and);
|
m_simp.mk_and(x_is_zero, y_is_zero, both_zero);
|
||||||
mk_is_nan(x, x_is_nan);
|
mk_is_nan(x, x_is_nan);
|
||||||
m_simp.mk_or(x_is_nan, c1_and, c1);
|
|
||||||
|
|
||||||
mk_is_nan(y, y_is_nan);
|
mk_is_nan(y, y_is_nan);
|
||||||
c2 = y_is_nan;
|
mk_pzero(f, pzero);
|
||||||
|
|
||||||
|
expr_ref lt(m);
|
||||||
|
mk_float_lt(f, num, args, lt);
|
||||||
|
|
||||||
expr_ref c3(m);
|
result = y;
|
||||||
mk_float_lt(f, num, args, c3);
|
mk_ite(lt, x, result, result);
|
||||||
|
mk_ite(both_zero, pzero, result, result);
|
||||||
|
mk_ite(y_is_nan, x, result, result);
|
||||||
|
mk_ite(x_is_nan, y, result, result);
|
||||||
|
|
||||||
expr_ref r_sgn(m), r_sig(m), r_exp(m);
|
SASSERT(is_well_sorted(m, result));
|
||||||
|
|
||||||
expr_ref c3xy(m), c2c3(m);
|
|
||||||
m_simp.mk_ite(c3, x_sgn, y_sgn, c3xy);
|
|
||||||
m_simp.mk_ite(c2, x_sgn, c3xy, c2c3);
|
|
||||||
m_simp.mk_ite(c1, y_sgn, c2c3, r_sgn);
|
|
||||||
|
|
||||||
expr_ref c3xy_sig(m), c2c3_sig(m);
|
|
||||||
m_simp.mk_ite(c3, x_sig, y_sig, c3xy_sig);
|
|
||||||
m_simp.mk_ite(c2, x_sig, c3xy_sig, c2c3_sig);
|
|
||||||
m_simp.mk_ite(c1, y_sig, c2c3_sig, r_sig);
|
|
||||||
|
|
||||||
expr_ref c3xy_exp(m), c2c3_exp(m);
|
|
||||||
m_simp.mk_ite(c3, x_exp, y_exp, c3xy_exp);
|
|
||||||
m_simp.mk_ite(c2, x_exp, c3xy_exp, c2c3_exp);
|
|
||||||
m_simp.mk_ite(c1, y_exp, c2c3_exp, r_exp);
|
|
||||||
|
|
||||||
mk_fp(r_sgn, r_exp, r_sig, result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void fpa2bv_converter::mk_max(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
void fpa2bv_converter::mk_max(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
||||||
SASSERT(num == 2);
|
SASSERT(num == 2);
|
||||||
|
|
||||||
expr * x = args[0], * y = args[1];
|
|
||||||
|
|
||||||
expr * x_sgn, * x_sig, * x_exp;
|
expr * x = args[0], *y = args[1];
|
||||||
expr * y_sgn, * y_sig, * y_exp;
|
|
||||||
|
expr * x_sgn, *x_sig, *x_exp;
|
||||||
|
expr * y_sgn, *y_sig, *y_exp;
|
||||||
split_fp(x, x_sgn, x_exp, x_sig);
|
split_fp(x, x_sgn, x_exp, x_sig);
|
||||||
split_fp(y, y_sgn, y_exp, y_sig);
|
split_fp(y, y_sgn, y_exp, y_sig);
|
||||||
|
|
||||||
expr_ref c1(m), c2(m), x_is_nan(m), y_is_nan(m), y_is_zero(m), x_is_zero(m), c1_and(m);
|
expr_ref x_is_nan(m), y_is_nan(m), x_is_zero(m), y_is_zero(m), both_zero(m), pzero(m);
|
||||||
mk_is_zero(y, y_is_zero);
|
|
||||||
mk_is_zero(x, x_is_zero);
|
mk_is_zero(x, x_is_zero);
|
||||||
m_simp.mk_and(y_is_zero, x_is_zero, c1_and);
|
mk_is_zero(y, y_is_zero);
|
||||||
mk_is_nan(x, x_is_nan);
|
m_simp.mk_and(x_is_zero, y_is_zero, both_zero);
|
||||||
m_simp.mk_or(x_is_nan, c1_and, c1);
|
mk_is_nan(x, x_is_nan);
|
||||||
|
|
||||||
mk_is_nan(y, y_is_nan);
|
mk_is_nan(y, y_is_nan);
|
||||||
c2 = y_is_nan;
|
mk_pzero(f, pzero);
|
||||||
|
|
||||||
expr_ref c3(m);
|
|
||||||
mk_float_gt(f, num, args, c3);
|
|
||||||
|
|
||||||
expr_ref r_sgn(m), r_sig(m), r_exp(m);
|
expr_ref gt(m);
|
||||||
|
mk_float_gt(f, num, args, gt);
|
||||||
expr_ref c3xy_sgn(m), c2c3_sgn(m);
|
|
||||||
m_simp.mk_ite(c3, x_sgn, y_sgn, c3xy_sgn);
|
|
||||||
m_simp.mk_ite(c2, x_sgn, c3xy_sgn, c2c3_sgn);
|
|
||||||
m_simp.mk_ite(c1, y_sgn, c2c3_sgn, r_sgn);
|
|
||||||
|
|
||||||
expr_ref c3xy_sig(m), c2c3_sig(m);
|
result = y;
|
||||||
m_simp.mk_ite(c3, x_sig, y_sig, c3xy_sig);
|
mk_ite(gt, x, result, result);
|
||||||
m_simp.mk_ite(c2, x_sig, c3xy_sig, c2c3_sig);
|
mk_ite(both_zero, pzero, result, result);
|
||||||
m_simp.mk_ite(c1, y_sig, c2c3_sig, r_sig);
|
mk_ite(y_is_nan, x, result, result);
|
||||||
|
mk_ite(x_is_nan, y, result, result);
|
||||||
|
|
||||||
expr_ref c3xy_exp(m), c2c3_exp(m);
|
SASSERT(is_well_sorted(m, result));
|
||||||
m_simp.mk_ite(c3, x_exp, y_exp, c3xy_exp);
|
|
||||||
m_simp.mk_ite(c2, x_exp, c3xy_exp, c2c3_exp);
|
|
||||||
m_simp.mk_ite(c1, y_exp, c2c3_exp, r_exp);
|
|
||||||
|
|
||||||
mk_fp(r_sgn, r_exp, r_sig, result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
||||||
|
@ -2096,79 +2070,89 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr *
|
||||||
bool is_int;
|
bool is_int;
|
||||||
m_util.au().is_numeral(x, q, is_int);
|
m_util.au().is_numeral(x, q, is_int);
|
||||||
|
|
||||||
scoped_mpf v(m_mpf_manager);
|
if (q.is_zero())
|
||||||
m_util.fm().set(v, ebits, sbits, rm, q.to_mpq());
|
return mk_pzero(f, result);
|
||||||
|
else {
|
||||||
|
scoped_mpf v(m_mpf_manager);
|
||||||
|
m_util.fm().set(v, ebits, sbits, rm, q.to_mpq());
|
||||||
|
|
||||||
expr_ref sgn(m), s(m), e(m), unbiased_exp(m);
|
|
||||||
sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v)) ? 1 : 0, 1);
|
|
||||||
s = m_bv_util.mk_numeral(m_util.fm().sig(v), sbits - 1);
|
|
||||||
unbiased_exp = m_bv_util.mk_numeral(m_util.fm().exp(v), ebits);
|
|
||||||
mk_bias(unbiased_exp, e);
|
|
||||||
|
|
||||||
mk_fp(sgn, e, s, result);
|
|
||||||
|
expr_ref sgn(m), s(m), e(m), unbiased_exp(m);
|
||||||
|
sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v)) ? 1 : 0, 1);
|
||||||
|
s = m_bv_util.mk_numeral(m_util.fm().sig(v), sbits - 1);
|
||||||
|
unbiased_exp = m_bv_util.mk_numeral(m_util.fm().exp(v), ebits);
|
||||||
|
mk_bias(unbiased_exp, e);
|
||||||
|
|
||||||
|
mk_fp(sgn, e, s, result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (m_util.au().is_numeral(x)) {
|
else if (m_util.au().is_numeral(x)) {
|
||||||
rational q;
|
rational q;
|
||||||
bool is_int;
|
bool is_int;
|
||||||
m_util.au().is_numeral(x, q, is_int);
|
m_util.au().is_numeral(x, q, is_int);
|
||||||
|
|
||||||
expr_ref rm_nta(m), rm_nte(m), rm_tp(m), rm_tn(m), rm_tz(m);
|
if (m_util.au().is_zero(x))
|
||||||
mk_is_rm(rm, BV_RM_TIES_TO_AWAY, rm_nta);
|
mk_pzero(f, result);
|
||||||
mk_is_rm(rm, BV_RM_TIES_TO_EVEN, rm_nte);
|
else {
|
||||||
mk_is_rm(rm, BV_RM_TO_POSITIVE, rm_tp);
|
expr_ref rm_nta(m), rm_nte(m), rm_tp(m), rm_tn(m), rm_tz(m);
|
||||||
mk_is_rm(rm, BV_RM_TO_NEGATIVE, rm_tn);
|
mk_is_rm(rm, BV_RM_TIES_TO_AWAY, rm_nta);
|
||||||
mk_is_rm(rm, BV_RM_TO_ZERO, rm_tz);
|
mk_is_rm(rm, BV_RM_TIES_TO_EVEN, rm_nte);
|
||||||
|
mk_is_rm(rm, BV_RM_TO_POSITIVE, rm_tp);
|
||||||
|
mk_is_rm(rm, BV_RM_TO_NEGATIVE, rm_tn);
|
||||||
|
mk_is_rm(rm, BV_RM_TO_ZERO, rm_tz);
|
||||||
|
|
||||||
scoped_mpf v_nta(m_mpf_manager), v_nte(m_mpf_manager), v_tp(m_mpf_manager);
|
scoped_mpf v_nta(m_mpf_manager), v_nte(m_mpf_manager), v_tp(m_mpf_manager);
|
||||||
scoped_mpf v_tn(m_mpf_manager), v_tz(m_mpf_manager);
|
scoped_mpf v_tn(m_mpf_manager), v_tz(m_mpf_manager);
|
||||||
m_util.fm().set(v_nta, ebits, sbits, MPF_ROUND_NEAREST_TAWAY, q.to_mpq());
|
m_util.fm().set(v_nta, ebits, sbits, MPF_ROUND_NEAREST_TAWAY, q.to_mpq());
|
||||||
m_util.fm().set(v_nte, ebits, sbits, MPF_ROUND_NEAREST_TEVEN, q.to_mpq());
|
m_util.fm().set(v_nte, ebits, sbits, MPF_ROUND_NEAREST_TEVEN, q.to_mpq());
|
||||||
m_util.fm().set(v_tp, ebits, sbits, MPF_ROUND_TOWARD_POSITIVE, q.to_mpq());
|
m_util.fm().set(v_tp, ebits, sbits, MPF_ROUND_TOWARD_POSITIVE, q.to_mpq());
|
||||||
m_util.fm().set(v_tn, ebits, sbits, MPF_ROUND_TOWARD_NEGATIVE, q.to_mpq());
|
m_util.fm().set(v_tn, ebits, sbits, MPF_ROUND_TOWARD_NEGATIVE, q.to_mpq());
|
||||||
m_util.fm().set(v_tz, ebits, sbits, MPF_ROUND_TOWARD_ZERO, q.to_mpq());
|
m_util.fm().set(v_tz, ebits, sbits, MPF_ROUND_TOWARD_ZERO, q.to_mpq());
|
||||||
|
|
||||||
expr_ref v1(m), v2(m), v3(m), v4(m);
|
expr_ref v1(m), v2(m), v3(m), v4(m);
|
||||||
|
|
||||||
expr_ref sgn(m), s(m), e(m), unbiased_exp(m);
|
expr_ref sgn(m), s(m), e(m), unbiased_exp(m);
|
||||||
sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v_nta)) ? 1 : 0, 1);
|
sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v_nta)) ? 1 : 0, 1);
|
||||||
s = m_bv_util.mk_numeral(m_util.fm().sig(v_nta), sbits - 1);
|
s = m_bv_util.mk_numeral(m_util.fm().sig(v_nta), sbits - 1);
|
||||||
unbiased_exp = m_bv_util.mk_numeral(m_util.fm().exp(v_nta), ebits);
|
unbiased_exp = m_bv_util.mk_numeral(m_util.fm().exp(v_nta), ebits);
|
||||||
mk_bias(unbiased_exp, e);
|
mk_bias(unbiased_exp, e);
|
||||||
mk_fp(sgn, e, s, v1);
|
mk_fp(sgn, e, s, v1);
|
||||||
|
|
||||||
sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v_nte)) ? 1 : 0, 1);
|
sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v_nte)) ? 1 : 0, 1);
|
||||||
s = m_bv_util.mk_numeral(m_util.fm().sig(v_nte), sbits - 1);
|
s = m_bv_util.mk_numeral(m_util.fm().sig(v_nte), sbits - 1);
|
||||||
unbiased_exp = m_bv_util.mk_numeral(m_util.fm().exp(v_nte), ebits);
|
unbiased_exp = m_bv_util.mk_numeral(m_util.fm().exp(v_nte), ebits);
|
||||||
mk_bias(unbiased_exp, e);
|
mk_bias(unbiased_exp, e);
|
||||||
mk_fp(sgn, e, s, v2);
|
mk_fp(sgn, e, s, v2);
|
||||||
|
|
||||||
sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v_tp)) ? 1 : 0, 1);
|
sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v_tp)) ? 1 : 0, 1);
|
||||||
s = m_bv_util.mk_numeral(m_util.fm().sig(v_tp), sbits - 1);
|
s = m_bv_util.mk_numeral(m_util.fm().sig(v_tp), sbits - 1);
|
||||||
unbiased_exp = m_bv_util.mk_numeral(m_util.fm().exp(v_tp), ebits);
|
unbiased_exp = m_bv_util.mk_numeral(m_util.fm().exp(v_tp), ebits);
|
||||||
mk_bias(unbiased_exp, e);
|
mk_bias(unbiased_exp, e);
|
||||||
mk_fp(sgn, e, s, v3);
|
mk_fp(sgn, e, s, v3);
|
||||||
|
|
||||||
sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v_tn)) ? 1 : 0, 1);
|
sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v_tn)) ? 1 : 0, 1);
|
||||||
s = m_bv_util.mk_numeral(m_util.fm().sig(v_tn), sbits - 1);
|
s = m_bv_util.mk_numeral(m_util.fm().sig(v_tn), sbits - 1);
|
||||||
unbiased_exp = m_bv_util.mk_numeral(m_util.fm().exp(v_tn), ebits);
|
unbiased_exp = m_bv_util.mk_numeral(m_util.fm().exp(v_tn), ebits);
|
||||||
mk_bias(unbiased_exp, e);
|
mk_bias(unbiased_exp, e);
|
||||||
mk_fp(sgn, e, s, v4);
|
mk_fp(sgn, e, s, v4);
|
||||||
|
|
||||||
sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v_tp)) ? 1 : 0, 1);
|
sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v_tp)) ? 1 : 0, 1);
|
||||||
s = m_bv_util.mk_numeral(m_util.fm().sig(v_tp), sbits - 1);
|
s = m_bv_util.mk_numeral(m_util.fm().sig(v_tp), sbits - 1);
|
||||||
unbiased_exp = m_bv_util.mk_numeral(m_util.fm().exp(v_tp), ebits);
|
unbiased_exp = m_bv_util.mk_numeral(m_util.fm().exp(v_tp), ebits);
|
||||||
mk_bias(unbiased_exp, e);
|
mk_bias(unbiased_exp, e);
|
||||||
|
|
||||||
mk_fp(sgn, e, s, result);
|
mk_fp(sgn, e, s, result);
|
||||||
mk_ite(rm_tn, v4, result, result);
|
mk_ite(rm_tn, v4, result, result);
|
||||||
mk_ite(rm_tp, v3, result, result);
|
mk_ite(rm_tp, v3, result, result);
|
||||||
mk_ite(rm_nte, v2, result, result);
|
mk_ite(rm_nte, v2, result, result);
|
||||||
mk_ite(rm_nta, v1, result, result);
|
mk_ite(rm_nta, v1, result, result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
bv_util & bu = m_bv_util;
|
bv_util & bu = m_bv_util;
|
||||||
arith_util & au = m_arith_util;
|
arith_util & au = m_arith_util;
|
||||||
|
|
||||||
expr_ref bv0(m), bv1(m), zero(m), two(m);
|
expr_ref bv0(m), bv1(m), zero(m), two(m);
|
||||||
bv0 = bu.mk_numeral(0, 1);
|
bv0 = bu.mk_numeral(0, 1);
|
||||||
bv1 = bu.mk_numeral(1, 1);
|
bv1 = bu.mk_numeral(1, 1);
|
||||||
|
@ -2182,6 +2166,10 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr *
|
||||||
|
|
||||||
expr_ref rme(rm, m);
|
expr_ref rme(rm, m);
|
||||||
round(s, rme, sgn, sig, exp, result);
|
round(s, rme, sgn, sig, exp, result);
|
||||||
|
|
||||||
|
expr_ref c0(m);
|
||||||
|
mk_is_zero(x, c0);
|
||||||
|
mk_ite(c0, x, result, result);
|
||||||
|
|
||||||
expr * e = m.mk_eq(m_util.mk_to_real(result), x);
|
expr * e = m.mk_eq(m_util.mk_to_real(result), x);
|
||||||
m_extra_assertions.push_back(e);
|
m_extra_assertions.push_back(e);
|
||||||
|
@ -2209,38 +2197,43 @@ void fpa2bv_converter::mk_to_fp_real_int(func_decl * f, unsigned num, expr * con
|
||||||
SASSERT(e.is_int64());
|
SASSERT(e.is_int64());
|
||||||
SASSERT(m_mpz_manager.eq(e.to_mpq().denominator(), 1));
|
SASSERT(m_mpz_manager.eq(e.to_mpq().denominator(), 1));
|
||||||
|
|
||||||
scoped_mpf nte(m_mpf_manager), nta(m_mpf_manager), tp(m_mpf_manager), tn(m_mpf_manager), tz(m_mpf_manager);
|
if (q.is_zero())
|
||||||
m_mpf_manager.set(nte, ebits, sbits, MPF_ROUND_NEAREST_TEVEN, q.to_mpq(), e.to_mpq().numerator());
|
return mk_pzero(f, result);
|
||||||
m_mpf_manager.set(nta, ebits, sbits, MPF_ROUND_NEAREST_TAWAY, q.to_mpq(), e.to_mpq().numerator());
|
else {
|
||||||
m_mpf_manager.set(tp, ebits, sbits, MPF_ROUND_TOWARD_POSITIVE, q.to_mpq(), e.to_mpq().numerator());
|
scoped_mpf nte(m_mpf_manager), nta(m_mpf_manager), tp(m_mpf_manager), tn(m_mpf_manager), tz(m_mpf_manager);
|
||||||
m_mpf_manager.set(tn, ebits, sbits, MPF_ROUND_TOWARD_NEGATIVE, q.to_mpq(), e.to_mpq().numerator());
|
m_mpf_manager.set(nte, ebits, sbits, MPF_ROUND_NEAREST_TEVEN, q.to_mpq(), e.to_mpq().numerator());
|
||||||
m_mpf_manager.set(tz, ebits, sbits, MPF_ROUND_TOWARD_ZERO, q.to_mpq(), e.to_mpq().numerator());
|
m_mpf_manager.set(nta, ebits, sbits, MPF_ROUND_NEAREST_TAWAY, q.to_mpq(), e.to_mpq().numerator());
|
||||||
|
m_mpf_manager.set(tp, ebits, sbits, MPF_ROUND_TOWARD_POSITIVE, q.to_mpq(), e.to_mpq().numerator());
|
||||||
|
m_mpf_manager.set(tn, ebits, sbits, MPF_ROUND_TOWARD_NEGATIVE, q.to_mpq(), e.to_mpq().numerator());
|
||||||
|
m_mpf_manager.set(tz, ebits, sbits, MPF_ROUND_TOWARD_ZERO, q.to_mpq(), e.to_mpq().numerator());
|
||||||
|
|
||||||
app_ref a_nte(m), a_nta(m), a_tp(m), a_tn(m), a_tz(m);
|
app_ref a_nte(m), a_nta(m), a_tp(m), a_tn(m), a_tz(m);
|
||||||
a_nte = m_plugin->mk_numeral(nte);
|
a_nte = m_plugin->mk_numeral(nte);
|
||||||
a_nta = m_plugin->mk_numeral(nta);
|
a_nta = m_plugin->mk_numeral(nta);
|
||||||
a_tp = m_plugin->mk_numeral(tp);
|
a_tp = m_plugin->mk_numeral(tp);
|
||||||
a_tn = m_plugin->mk_numeral(tn);
|
a_tn = m_plugin->mk_numeral(tn);
|
||||||
a_tz = m_plugin->mk_numeral(tz);
|
a_tz = m_plugin->mk_numeral(tz);
|
||||||
|
|
||||||
expr_ref bv_nte(m), bv_nta(m), bv_tp(m), bv_tn(m), bv_tz(m);
|
expr_ref bv_nte(m), bv_nta(m), bv_tp(m), bv_tn(m), bv_tz(m);
|
||||||
mk_numeral(a_nte->get_decl(), 0, 0, bv_nte);
|
mk_numeral(a_nte->get_decl(), 0, 0, bv_nte);
|
||||||
mk_numeral(a_nta->get_decl(), 0, 0, bv_nta);
|
mk_numeral(a_nta->get_decl(), 0, 0, bv_nta);
|
||||||
mk_numeral(a_tp->get_decl(), 0, 0, bv_tp);
|
mk_numeral(a_tp->get_decl(), 0, 0, bv_tp);
|
||||||
mk_numeral(a_tn->get_decl(), 0, 0, bv_tn);
|
mk_numeral(a_tn->get_decl(), 0, 0, bv_tn);
|
||||||
mk_numeral(a_tz->get_decl(), 0, 0, bv_tz);
|
mk_numeral(a_tz->get_decl(), 0, 0, bv_tz);
|
||||||
|
|
||||||
expr_ref c1(m), c2(m), c3(m), c4(m);
|
expr_ref c1(m), c2(m), c3(m), c4(m);
|
||||||
c1 = m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TO_POSITIVE, 3));
|
c1 = m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TO_POSITIVE, 3));
|
||||||
c2 = m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TO_POSITIVE, 3));
|
c2 = m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TO_POSITIVE, 3));
|
||||||
c3 = m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TIES_TO_AWAY, 3));
|
c3 = m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TIES_TO_AWAY, 3));
|
||||||
c4 = m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TIES_TO_EVEN, 3));
|
c4 = m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TIES_TO_EVEN, 3));
|
||||||
|
|
||||||
mk_ite(c1, bv_tn, bv_tz, result);
|
mk_ite(c1, bv_tn, bv_tz, result);
|
||||||
mk_ite(c2, bv_tp, result, result);
|
mk_ite(c2, bv_tp, result, result);
|
||||||
mk_ite(c3, bv_nta, result, result);
|
mk_ite(c3, bv_nta, result, result);
|
||||||
mk_ite(c4, bv_nte, result, result);
|
mk_ite(c4, bv_nte, result, result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fpa2bv_converter::mk_to_real(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
void fpa2bv_converter::mk_to_real(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
||||||
TRACE("fpa2bv_to_real", for (unsigned i = 0; i < num; i++)
|
TRACE("fpa2bv_to_real", for (unsigned i = 0; i < num; i++)
|
||||||
tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl;);
|
tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl;);
|
||||||
|
@ -2367,10 +2360,9 @@ void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const
|
||||||
mk_pinf(f, pinf);
|
mk_pinf(f, pinf);
|
||||||
|
|
||||||
// Special case: x == 0 -> p/n zero
|
// Special case: x == 0 -> p/n zero
|
||||||
expr_ref c1(m), v1(m), rm_is_to_neg(m);
|
expr_ref c1(m), v1(m);
|
||||||
c1 = is_zero;
|
c1 = is_zero;
|
||||||
mk_is_rm(rm, BV_RM_TO_NEGATIVE, rm_is_to_neg);
|
v1 = pzero;
|
||||||
mk_ite(rm_is_to_neg, nzero, pzero, v1);
|
|
||||||
|
|
||||||
// Special case: x != 0
|
// Special case: x != 0
|
||||||
expr_ref is_neg_bit(m), exp_too_large(m), sig_4(m), exp_2(m);
|
expr_ref is_neg_bit(m), exp_too_large(m), sig_4(m), exp_2(m);
|
||||||
|
@ -2508,10 +2500,9 @@ void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * con
|
||||||
mk_pinf(f, pinf);
|
mk_pinf(f, pinf);
|
||||||
|
|
||||||
// Special case: x == 0 -> p/n zero
|
// Special case: x == 0 -> p/n zero
|
||||||
expr_ref c1(m), v1(m), rm_is_to_neg(m);
|
expr_ref c1(m), v1(m);
|
||||||
c1 = is_zero;
|
c1 = is_zero;
|
||||||
mk_is_rm(rm, BV_RM_TO_NEGATIVE, rm_is_to_neg);
|
v1 = pzero;
|
||||||
mk_ite(rm_is_to_neg, nzero, pzero, v1);
|
|
||||||
|
|
||||||
// Special case: x != 0
|
// Special case: x != 0
|
||||||
expr_ref exp_too_large(m), sig_4(m), exp_2(m);
|
expr_ref exp_too_large(m), sig_4(m), exp_2(m);
|
||||||
|
@ -3182,7 +3173,7 @@ void fpa2bv_converter::unpack(expr * e, expr_ref & sgn, expr_ref & sig, expr_ref
|
||||||
m_simp.mk_ite(m.mk_or(is_normal, is_sig_zero), zero_e, lz_d, lz);
|
m_simp.mk_ite(m.mk_or(is_normal, is_sig_zero), zero_e, lz_d, lz);
|
||||||
dbg_decouple("fpa2bv_unpack_lz", lz);
|
dbg_decouple("fpa2bv_unpack_lz", lz);
|
||||||
|
|
||||||
expr_ref shift(m);
|
expr_ref shift(m);
|
||||||
m_simp.mk_ite(is_sig_zero, zero_e, lz, shift);
|
m_simp.mk_ite(is_sig_zero, zero_e, lz, shift);
|
||||||
dbg_decouple("fpa2bv_unpack_shift", shift);
|
dbg_decouple("fpa2bv_unpack_shift", shift);
|
||||||
SASSERT(is_well_sorted(m, is_sig_zero));
|
SASSERT(is_well_sorted(m, is_sig_zero));
|
||||||
|
|
|
@ -879,12 +879,20 @@ void fpa_decl_plugin::get_sort_names(svector<builtin_name> & sort_names, symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
expr * fpa_decl_plugin::get_some_value(sort * s) {
|
expr * fpa_decl_plugin::get_some_value(sort * s) {
|
||||||
SASSERT(s->is_sort_of(m_family_id, FLOATING_POINT_SORT));
|
if (s->is_sort_of(m_family_id, FLOATING_POINT_SORT)) {
|
||||||
mpf tmp;
|
mpf tmp;
|
||||||
m_fm.mk_nan(s->get_parameter(0).get_int(), s->get_parameter(1).get_int(), tmp);
|
m_fm.mk_nan(s->get_parameter(0).get_int(), s->get_parameter(1).get_int(), tmp);
|
||||||
expr * res = this->mk_numeral(tmp);
|
expr * res = mk_numeral(tmp);
|
||||||
m_fm.del(tmp);
|
m_fm.del(tmp);
|
||||||
return res;
|
return res;
|
||||||
|
}
|
||||||
|
else if (s->is_sort_of(m_family_id, ROUNDING_MODE_SORT)) {
|
||||||
|
func_decl * f = mk_rm_const_decl(OP_FPA_RM_TOWARD_ZERO, 0, 0, 0, 0, s);
|
||||||
|
return m_manager->mk_const(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
UNREACHABLE();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fpa_decl_plugin::is_value(app * e) const {
|
bool fpa_decl_plugin::is_value(app * e) const {
|
||||||
|
|
|
@ -411,14 +411,20 @@ br_status fpa_rewriter::mk_min(expr * arg1, expr * arg2, expr_ref & result) {
|
||||||
result = arg1;
|
result = arg1;
|
||||||
return BR_DONE;
|
return BR_DONE;
|
||||||
}
|
}
|
||||||
// expand as using ite's
|
if (m_util.is_zero(arg1) && m_util.is_zero(arg2)) {
|
||||||
result = m().mk_ite(m().mk_or(mk_eq_nan(arg1), m().mk_and(m_util.mk_is_zero(arg1), m_util.mk_is_zero(arg2))),
|
result = m_util.mk_pzero(m().get_sort(arg1));
|
||||||
|
return BR_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = m().mk_ite(mk_eq_nan(arg1),
|
||||||
arg2,
|
arg2,
|
||||||
m().mk_ite(mk_eq_nan(arg2),
|
m().mk_ite(mk_eq_nan(arg2),
|
||||||
arg1,
|
arg1,
|
||||||
m().mk_ite(m_util.mk_lt(arg1, arg2),
|
m().mk_ite(m().mk_and(m_util.mk_is_zero(arg1), m_util.mk_is_zero(arg2)),
|
||||||
arg1,
|
m_util.mk_pzero(m().get_sort(arg1)),
|
||||||
arg2)));
|
m().mk_ite(m_util.mk_lt(arg1, arg2),
|
||||||
|
arg1,
|
||||||
|
arg2))));
|
||||||
return BR_REWRITE_FULL;
|
return BR_REWRITE_FULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,14 +437,20 @@ br_status fpa_rewriter::mk_max(expr * arg1, expr * arg2, expr_ref & result) {
|
||||||
result = arg1;
|
result = arg1;
|
||||||
return BR_DONE;
|
return BR_DONE;
|
||||||
}
|
}
|
||||||
// expand as using ite's
|
if (m_util.is_zero(arg1) && m_util.is_zero(arg2)) {
|
||||||
result = m().mk_ite(m().mk_or(mk_eq_nan(arg1), m().mk_and(m_util.mk_is_zero(arg1), m_util.mk_is_zero(arg2))),
|
result = m_util.mk_pzero(m().get_sort(arg1));
|
||||||
|
return BR_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = m().mk_ite(mk_eq_nan(arg1),
|
||||||
arg2,
|
arg2,
|
||||||
m().mk_ite(mk_eq_nan(arg2),
|
m().mk_ite(mk_eq_nan(arg2),
|
||||||
arg1,
|
arg1,
|
||||||
m().mk_ite(m_util.mk_gt(arg1, arg2),
|
m().mk_ite(m().mk_and(m_util.mk_is_zero(arg1), m_util.mk_is_zero(arg2)),
|
||||||
arg1,
|
m_util.mk_pzero(m().get_sort(arg1)),
|
||||||
arg2)));
|
m().mk_ite(m_util.mk_gt(arg1, arg2),
|
||||||
|
arg1,
|
||||||
|
arg2))));
|
||||||
return BR_REWRITE_FULL;
|
return BR_REWRITE_FULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -398,10 +398,27 @@ public:
|
||||||
s.assert_expr(to_expr(cnsts[i].raw()));
|
s.assert_expr(to_expr(cnsts[i].raw()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void get_proof_assumptions(z3pf proof, std::vector<ast> &cnsts, hash_set<ast> &memo){
|
||||||
|
if(memo.find(proof) != memo.end())return;
|
||||||
|
memo.insert(proof);
|
||||||
|
pfrule dk = pr(proof);
|
||||||
|
if(dk == PR_ASSERTED)
|
||||||
|
cnsts.push_back(conc(proof));
|
||||||
|
else {
|
||||||
|
unsigned nprems = num_prems(proof);
|
||||||
|
for(unsigned i = 0; i < nprems; i++){
|
||||||
|
z3pf arg = prem(proof,i);
|
||||||
|
get_proof_assumptions(arg,cnsts,memo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
iz3interp(ast_manager &_m_manager)
|
iz3interp(ast_manager &_m_manager)
|
||||||
: iz3base(_m_manager) {}
|
: iz3base(_m_manager) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void iz3interpolate(ast_manager &_m_manager,
|
void iz3interpolate(ast_manager &_m_manager,
|
||||||
ast *proof,
|
ast *proof,
|
||||||
const ptr_vector<ast> &cnsts,
|
const ptr_vector<ast> &cnsts,
|
||||||
|
@ -475,6 +492,13 @@ void iz3interpolate(ast_manager &_m_manager,
|
||||||
_cnsts[i] = itp.cook(cnsts[i]);
|
_cnsts[i] = itp.cook(cnsts[i]);
|
||||||
iz3mgr::ast _proof = itp.cook(proof);
|
iz3mgr::ast _proof = itp.cook(proof);
|
||||||
iz3mgr::ast _tree = itp.cook(tree);
|
iz3mgr::ast _tree = itp.cook(tree);
|
||||||
|
|
||||||
|
// if consts isn't provided, we can reconstruct it
|
||||||
|
if(_cnsts.empty()){
|
||||||
|
hash_set<iz3mgr::ast> memo;
|
||||||
|
itp.get_proof_assumptions(_proof,_cnsts,memo);
|
||||||
|
}
|
||||||
|
|
||||||
itp.proof_to_interpolant(_proof,_cnsts,_tree,_interps,options);
|
itp.proof_to_interpolant(_proof,_cnsts,_tree,_interps,options);
|
||||||
interps.resize(_interps.size());
|
interps.resize(_interps.size());
|
||||||
for(unsigned i = 0; i < interps.size(); i++)
|
for(unsigned i = 0; i < interps.size(); i++)
|
||||||
|
|
|
@ -67,7 +67,11 @@ void iz3interpolate(ast_manager &_m_manager,
|
||||||
interpolation_options_struct * options = 0);
|
interpolation_options_struct * options = 0);
|
||||||
|
|
||||||
/* Compute an interpolant from a proof. This version uses the ast
|
/* Compute an interpolant from a proof. This version uses the ast
|
||||||
representation, for compatibility with the new API. */
|
representation, for compatibility with the new API. Here, cnsts is
|
||||||
|
a vector of all the assertions in the proof. This can be
|
||||||
|
over-approximated by the set of all assertions in the
|
||||||
|
solver. However, if it is empty it will be reconstructed from the
|
||||||
|
proof, so it can be considered a hint. */
|
||||||
|
|
||||||
void iz3interpolate(ast_manager &_m_manager,
|
void iz3interpolate(ast_manager &_m_manager,
|
||||||
ast *proof,
|
ast *proof,
|
||||||
|
|
|
@ -447,9 +447,28 @@ void test_bvneg() {
|
||||||
Z3_del_context(ctx);
|
Z3_del_context(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool cb_called = false;
|
||||||
|
static void my_cb(Z3_context, Z3_error_code) {
|
||||||
|
cb_called = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_mk_distinct() {
|
||||||
|
Z3_config cfg = Z3_mk_config();
|
||||||
|
Z3_context ctx = Z3_mk_context(cfg);
|
||||||
|
Z3_set_error_handler(ctx, my_cb);
|
||||||
|
|
||||||
|
Z3_sort bv8 = Z3_mk_bv_sort(ctx, 8);
|
||||||
|
Z3_sort bv32 = Z3_mk_bv_sort(ctx, 32);
|
||||||
|
Z3_ast args[] = { Z3_mk_int64(ctx, 0, bv8), Z3_mk_int64(ctx, 0, bv32) };
|
||||||
|
Z3_ast d = Z3_mk_distinct(ctx, 2, args);
|
||||||
|
SASSERT(cb_called);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void tst_api() {
|
void tst_api() {
|
||||||
test_apps();
|
test_apps();
|
||||||
test_bvneg();
|
test_bvneg();
|
||||||
|
test_mk_distinct();
|
||||||
// bv_invariant();
|
// bv_invariant();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -1475,6 +1475,9 @@ void mpf_manager::mk_ninf(unsigned ebits, unsigned sbits, mpf & o) {
|
||||||
|
|
||||||
void mpf_manager::unpack(mpf & o, bool normalize) {
|
void mpf_manager::unpack(mpf & o, bool normalize) {
|
||||||
// Insert the hidden bit or adjust the exponent of denormal numbers.
|
// Insert the hidden bit or adjust the exponent of denormal numbers.
|
||||||
|
if (is_zero(o))
|
||||||
|
return;
|
||||||
|
|
||||||
if (is_normal(o))
|
if (is_normal(o))
|
||||||
m_mpz_manager.add(o.significand, m_powers2(o.sbits-1), o.significand);
|
m_mpz_manager.add(o.significand, m_powers2(o.sbits-1), o.significand);
|
||||||
else {
|
else {
|
||||||
|
|
Loading…
Reference in a new issue