From d4ba3a886418abff4717cd07339275eef38c3a43 Mon Sep 17 00:00:00 2001 From: Ivo Wever Date: Sat, 28 Mar 2015 23:08:46 +0100 Subject: [PATCH 01/57] Corrected typo: interger -> integer --- src/api/python/z3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/python/z3.py b/src/api/python/z3.py index e58e47640..ca45d8d90 100644 --- a/src/api/python/z3.py +++ b/src/api/python/z3.py @@ -2612,7 +2612,7 @@ def _py2expr(a, ctx=None): _z3_assert(False, "Python bool, int, long or float expected") def IntSort(ctx=None): - """Return the interger sort in the given context. If `ctx=None`, then the global context is used. + """Return the integer sort in the given context. If `ctx=None`, then the global context is used. >>> IntSort() Int From 4e59ba922b356429482e25389206d3dd6e745124 Mon Sep 17 00:00:00 2001 From: "Daniel J. Hofmann" Date: Fri, 3 Apr 2015 19:13:52 +0200 Subject: [PATCH 02/57] Wc++11-extensions --- src/api/z3_api.h | 2 +- src/ast/ast.h | 2 +- src/ast/pattern/expr_pattern_match.h | 2 +- src/smt/params/smt_params.h | 2 +- src/smt/smt_setup.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/api/z3_api.h b/src/api/z3_api.h index 844a4766c..45e5a9266 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -176,7 +176,7 @@ typedef enum Z3_PARAMETER_SYMBOL, Z3_PARAMETER_SORT, Z3_PARAMETER_AST, - Z3_PARAMETER_FUNC_DECL, + Z3_PARAMETER_FUNC_DECL } Z3_parameter_kind; /** diff --git a/src/ast/ast.h b/src/ast/ast.h index 93f456965..277e9120b 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -1143,7 +1143,7 @@ typedef app proof; /* a proof is just an applicaton */ enum label_op_kind { OP_LABEL, - OP_LABEL_LIT, + OP_LABEL_LIT }; /** diff --git a/src/ast/pattern/expr_pattern_match.h b/src/ast/pattern/expr_pattern_match.h index 555d6a67e..c298c2992 100644 --- a/src/ast/pattern/expr_pattern_match.h +++ b/src/ast/pattern/expr_pattern_match.h @@ -37,7 +37,7 @@ class expr_pattern_match { CHECK_TERM, SET_BOUND, CHECK_BOUND, - YIELD, + YIELD }; struct instr { diff --git a/src/smt/params/smt_params.h b/src/smt/params/smt_params.h index 2fbc9b6d4..dc1fc0911 100644 --- a/src/smt/params/smt_params.h +++ b/src/smt/params/smt_params.h @@ -65,7 +65,7 @@ enum case_split_strategy { CS_ACTIVITY_WITH_CACHE, // case split based on activity and cache the activity CS_RELEVANCY, // case split based on relevancy CS_RELEVANCY_ACTIVITY, // case split based on relevancy and activity - CS_RELEVANCY_GOAL, // based on relevancy and the current goal + CS_RELEVANCY_GOAL // based on relevancy and the current goal }; struct smt_params : public preprocessor_params, diff --git a/src/smt/smt_setup.h b/src/smt/smt_setup.h index 6cbcb9602..1a30f3722 100644 --- a/src/smt/smt_setup.h +++ b/src/smt/smt_setup.h @@ -28,7 +28,7 @@ namespace smt { enum config_mode { CFG_BASIC, // install theories based on user options CFG_LOGIC, // install theories and configure Z3 based on the value of the parameter set-logic. - CFG_AUTO, // install theories based on static features of the input formula + CFG_AUTO // install theories based on static features of the input formula }; class context; From 6150083276a1cb4d87e27e56c3a31397cf8807b9 Mon Sep 17 00:00:00 2001 From: "Daniel J. Hofmann" Date: Fri, 3 Apr 2015 19:24:35 +0200 Subject: [PATCH 03/57] Wignored-qualifiers --- src/muz/rel/dl_sparse_table.h | 2 +- src/util/hwf.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/muz/rel/dl_sparse_table.h b/src/muz/rel/dl_sparse_table.h index 0222aa6e2..4768d8862 100644 --- a/src/muz/rel/dl_sparse_table.h +++ b/src/muz/rel/dl_sparse_table.h @@ -350,7 +350,7 @@ namespace datalog { *ptr&=m_write_mask; *ptr|=val< { diff --git a/src/util/hwf.h b/src/util/hwf.h index 9059869a0..be8ad7e0e 100644 --- a/src/util/hwf.h +++ b/src/util/hwf.h @@ -127,15 +127,15 @@ public: void to_rational(hwf const & x, scoped_mpq & o) { to_rational(x, o.m(), o); } - bool sgn(hwf const & x) const { + bool sgn(hwf const & x) const { return (x.get_raw() & 0x8000000000000000ull) != 0; } - const uint64 sig(hwf const & x) const { + uint64 sig(hwf const & x) const { return x.get_raw() & 0x000FFFFFFFFFFFFFull; } - const int exp(hwf const & x) const { + int exp(hwf const & x) const { return ((x.get_raw() & 0x7FF0000000000000ull) >> 52) - 1023; } From 88f6e74a2741818649d00959276d82f12372fa57 Mon Sep 17 00:00:00 2001 From: "Daniel J. Hofmann" Date: Fri, 3 Apr 2015 19:31:09 +0200 Subject: [PATCH 04/57] Wnewline-eof --- src/ast/fpa_decl_plugin.cpp | 2 +- src/smt/params/dyn_ack_params.cpp | 2 +- src/tactic/fpa/fpa2bv_model_converter.h | 2 +- src/tactic/sls/sls_evaluator.h | 2 +- src/tactic/sls/sls_powers.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ast/fpa_decl_plugin.cpp b/src/ast/fpa_decl_plugin.cpp index 48b7adb8b..1e8fbd3f6 100644 --- a/src/ast/fpa_decl_plugin.cpp +++ b/src/ast/fpa_decl_plugin.cpp @@ -1009,4 +1009,4 @@ app * fpa_util::mk_internal_to_sbv_unspecified(unsigned width) { app * fpa_util::mk_internal_to_real_unspecified() { sort * range = m_a_util.mk_real(); return m().mk_app(get_family_id(), OP_FPA_INTERNAL_TO_REAL_UNSPECIFIED, 0, 0, 0, 0, range); -} \ No newline at end of file +} diff --git a/src/smt/params/dyn_ack_params.cpp b/src/smt/params/dyn_ack_params.cpp index c559e2b9b..15f48bad1 100644 --- a/src/smt/params/dyn_ack_params.cpp +++ b/src/smt/params/dyn_ack_params.cpp @@ -27,4 +27,4 @@ void dyn_ack_params::updt_params(params_ref const & _p) { m_dack_threshold = p.dack_threshold(); m_dack_gc = p.dack_gc(); m_dack_gc_inv_decay = p.dack_gc_inv_decay(); -} \ No newline at end of file +} diff --git a/src/tactic/fpa/fpa2bv_model_converter.h b/src/tactic/fpa/fpa2bv_model_converter.h index 7b9598740..dc3df0557 100644 --- a/src/tactic/fpa/fpa2bv_model_converter.h +++ b/src/tactic/fpa/fpa2bv_model_converter.h @@ -103,4 +103,4 @@ model_converter * mk_fpa2bv_model_converter(ast_manager & m, obj_map const & uf2bvuf, obj_map const & uf23bvuf); -#endif \ No newline at end of file +#endif diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index 61afb7457..c70aba0d4 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -812,4 +812,4 @@ public: } }; -#endif \ No newline at end of file +#endif diff --git a/src/tactic/sls/sls_powers.h b/src/tactic/sls/sls_powers.h index d0cc0815e..bf28b80e9 100644 --- a/src/tactic/sls/sls_powers.h +++ b/src/tactic/sls/sls_powers.h @@ -46,4 +46,4 @@ public: } }; -#endif \ No newline at end of file +#endif From 42e0132639da1a3535a6e58299b514784e700205 Mon Sep 17 00:00:00 2001 From: "Daniel J. Hofmann" Date: Fri, 3 Apr 2015 19:45:49 +0200 Subject: [PATCH 05/57] Wshift-sign-overflow See: http://stackoverflow.com/questions/26331035/why-was-1-31-changed-to-be-implementation-defined-in-c14 And Howard Hinnant's explanation: http://stackoverflow.com/questions/19593938/is-left-shifting-a-negative-integer-undefined-behavior-in-c11#comment29091986_19593938 --- src/ast/ast.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ast/ast.h b/src/ast/ast.h index 277e9120b..1e33cc6d2 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -522,7 +522,7 @@ public: /** The ids of expressions and declarations are in different ranges. */ -const unsigned c_first_decl_id = (1 << 31); +const unsigned c_first_decl_id = (1u << 31); /** \brief Superclass for function declarations and sorts. From 2252836cf8d9d87027aae6137f7478efa4e338f1 Mon Sep 17 00:00:00 2001 From: "Daniel J. Hofmann" Date: Fri, 3 Apr 2015 19:53:13 +0200 Subject: [PATCH 06/57] Wstring-conversion static_cast("string lit") evaluates to true. The assert is supposed to always trigger, thus assert(false && "string lit"). --- src/interp/iz3foci.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interp/iz3foci.cpp b/src/interp/iz3foci.cpp index 527e73ae4..fbb52a071 100755 --- a/src/interp/iz3foci.cpp +++ b/src/interp/iz3foci.cpp @@ -272,7 +272,7 @@ public: } break; default: - assert("unknown built-in op"); + assert(false && "unknown built-in op"); } } else if(foci->get_int(i,nval)){ From 4b6b7182227984a928ce616f19adce0b6571fad9 Mon Sep 17 00:00:00 2001 From: "Daniel J. Hofmann" Date: Fri, 3 Apr 2015 20:11:58 +0200 Subject: [PATCH 07/57] Wunused-exception-parameter --- src/muz/duality/duality_dl_interface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/muz/duality/duality_dl_interface.cpp b/src/muz/duality/duality_dl_interface.cpp index aa186bd0a..9227059aa 100755 --- a/src/muz/duality/duality_dl_interface.cpp +++ b/src/muz/duality/duality_dl_interface.cpp @@ -327,10 +327,10 @@ lbool dl_interface::query(::expr * query) { try { ans = rs->Solve(); } - catch (Duality::solver::cancel_exception &exn){ + catch (const Duality::solver::cancel_exception &){ throw default_exception("duality canceled"); } - catch (Duality::Solver::Incompleteness &exn){ + catch (const Duality::Solver::Incompleteness &){ throw default_exception("incompleteness"); } From e8b8393c31b3f39725a798a911506c60fe2c05c4 Mon Sep 17 00:00:00 2001 From: Ben Laurie Date: Sun, 5 Apr 2015 17:44:26 +0100 Subject: [PATCH 08/57] Add Sudoku example. --- examples/c++/example.cpp | 77 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/examples/c++/example.cpp b/examples/c++/example.cpp index b348e7d36..41d90f2a9 100644 --- a/examples/c++/example.cpp +++ b/examples/c++/example.cpp @@ -974,6 +974,82 @@ void substitute_example() { std::cout << new_f << std::endl; } +void sudoku_example() { + std::cout << "sudoku example\n"; + + context c; + + // 9x9 matrix of integer variables + expr_vector x(c); + for (unsigned i = 0; i < 9; ++i) + for (unsigned j = 0; j < 9; ++j) { + std::stringstream x_name; + + x_name << "x_" << i << '_' << j; + x.push_back(c.int_const(x_name.str().c_str())); + } + + // each cell contains a value in {1, ..., 9} + solver s(c); + for (unsigned i = 0; i < 9; ++i) + for (unsigned j = 0; j < 9; ++j) { + s.add(x[i * 9 + j] >= 1 && x[i * 9 + j] <= 9); + } + + // each row contains a digit at most once + for (unsigned i = 0; i < 9; ++i) { + expr_vector t(c); + for (unsigned j = 0; j < 9; ++j) + t.push_back(x[i * 9 + j]); + s.add(distinct(t)); + } + + // each column contains a digit at most once + for (unsigned j = 0; j < 9; ++j) { + expr_vector t(c); + for (unsigned i = 0; i < 9; ++i) + t.push_back(x[i * 9 + j]); + s.add(distinct(t)); + } + + // each 3x3 square contains a digit at most once + for (unsigned i0 = 0; i0 < 3; i0++) { + for (uint j0 = 0; j0 < 3; j0++) { + expr_vector t(c); + for (unsigned i = 0; i < 3; i++) + for (unsigned j = 0; j < 3; j++) + t.push_back(x[(i0 * 3 + i) * 9 + j0 * 3 + j]); + s.add(distinct(t)); + } + } + + // sudoku instance, we use '0' for empty cells + int instance[9][9] = {{0,0,0,0,9,4,0,3,0}, + {0,0,0,5,1,0,0,0,7}, + {0,8,9,0,0,0,0,4,0}, + {0,0,0,0,0,0,2,0,8}, + {0,6,0,2,0,1,0,5,0}, + {1,0,2,0,0,0,0,0,0}, + {0,7,0,0,0,0,5,2,0}, + {9,0,0,0,6,5,0,0,0}, + {0,4,0,9,7,0,0,0,0}}; + + for (unsigned i = 0; i < 9; i++) + for (unsigned j = 0; j < 9; j++) + if (instance[i][j] != 0) + s.add(x[i * 9 + j] == instance[i][j]); + + std::cout << s.check() << std::endl; + std::cout << s << std::endl; + + model m = s.get_model(); + for (unsigned i = 0; i < 9; ++i) { + for (unsigned j = 0; j < 9; ++j) + std::cout << m.eval(x[i * 9 + j]); + std::cout << '\n'; + } +} + int main() { try { demorgan(); std::cout << "\n"; @@ -1012,6 +1088,7 @@ int main() { expr_vector_example(); std::cout << "\n"; exists_expr_vector_example(); std::cout << "\n"; substitute_example(); std::cout << "\n"; + sudoku_example(); std::cout << "\n"; std::cout << "done\n"; } catch (exception & ex) { From 0f467eb5990b6065872e86ff341af6aa70049fbc Mon Sep 17 00:00:00 2001 From: Ben Laurie Date: Sun, 5 Apr 2015 17:57:21 +0100 Subject: [PATCH 09/57] Pull out the solver. --- examples/c++/example.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/c++/example.cpp b/examples/c++/example.cpp index 41d90f2a9..750933cba 100644 --- a/examples/c++/example.cpp +++ b/examples/c++/example.cpp @@ -989,8 +989,9 @@ void sudoku_example() { x.push_back(c.int_const(x_name.str().c_str())); } - // each cell contains a value in {1, ..., 9} solver s(c); + + // each cell contains a value in {1, ..., 9} for (unsigned i = 0; i < 9; ++i) for (unsigned j = 0; j < 9; ++j) { s.add(x[i * 9 + j] >= 1 && x[i * 9 + j] <= 9); From ce9036c300a04e060becd62313755547d1b32389 Mon Sep 17 00:00:00 2001 From: "Daniel J. Hofmann" Date: Thu, 9 Apr 2015 21:24:15 +0200 Subject: [PATCH 10/57] Minor python-related style fixes --- scripts/mk_util.py | 54 ++++++++++++++++----------------- scripts/update_api.py | 70 +++++++++++++++++++++---------------------- 2 files changed, 62 insertions(+), 62 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 547379aec..74d03617a 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -248,7 +248,7 @@ def check_java(): if is_verbose(): print("Finding javac ...") - if JDK_HOME != None: + if JDK_HOME is not None: if IS_WINDOWS: JAVAC = os.path.join(JDK_HOME, 'bin', 'javac.exe') else: @@ -258,7 +258,7 @@ def check_java(): raise MKException("Failed to detect javac at '%s/bin'; the environment variable JDK_HOME is probably set to the wrong path." % os.path.join(JDK_HOME)) else: # Search for javac in the path. - ind = 'javac'; + ind = 'javac' if IS_WINDOWS: ind = ind + '.exe' paths = os.getenv('PATH', None) @@ -270,7 +270,7 @@ def check_java(): JAVAC = cmb break - if JAVAC == None: + if JAVAC is None: raise MKException('No java compiler in the path, please adjust your PATH or set JDK_HOME to the location of the JDK.') if is_verbose(): @@ -305,7 +305,7 @@ def check_java(): if is_verbose(): print("Finding jni.h...") - if JNI_HOME != None: + if JNI_HOME is not None: if not os.path.exists(os.path.join(JNI_HOME, 'jni.h')): raise MKException("Failed to detect jni.h '%s'; the environment variable JNI_HOME is probably set to the wrong path." % os.path.join(JNI_HOME)) else: @@ -337,10 +337,10 @@ def check_java(): for dir in cdirs: q = find_jni_h(dir) - if q != False: + if q is not False: JNI_HOME = q - if JNI_HOME == None: + if JNI_HOME is None: raise MKException("Failed to detect jni.h. Possible solution: set JNI_HOME with the path to JDK.") def check_ml(): @@ -399,12 +399,12 @@ def is64(): def check_ar(): if is_verbose(): print("Testing ar...") - if which('ar')== None: + if which('ar') is None: raise MKException('ar (archive tool) was not found') def find_cxx_compiler(): global CXX, CXX_COMPILERS - if CXX != None: + if CXX is not None: if test_cxx_compiler(CXX): return CXX for cxx in CXX_COMPILERS: @@ -415,7 +415,7 @@ def find_cxx_compiler(): def find_c_compiler(): global CC, C_COMPILERS - if CC != None: + if CC is not None: if test_c_compiler(CC): return CC for c in C_COMPILERS: @@ -760,7 +760,7 @@ class Component: global BUILD_DIR, SRC_DIR, REV_BUILD_DIR if name in _ComponentNames: raise MKException("Component '%s' was already defined." % name) - if path == None: + if path is None: path = name self.name = name path = norm_path(path) @@ -974,7 +974,7 @@ def sort_components(cnames): class ExeComponent(Component): def __init__(self, name, exe_name, path, deps, install): Component.__init__(self, name, path, deps) - if exe_name == None: + if exe_name is None: exe_name = name self.exe_name = exe_name self.install = install @@ -1068,7 +1068,7 @@ def get_so_ext(): class DLLComponent(Component): def __init__(self, name, dll_name, path, deps, export_files, reexports, install, static): Component.__init__(self, name, path, deps) - if dll_name == None: + if dll_name is None: dll_name = name self.dll_name = dll_name self.export_files = export_files @@ -1102,7 +1102,7 @@ class DLLComponent(Component): out.write(' ') out.write(obj) for dep in deps: - if not dep in self.reexports: + if dep not in self.reexports: c_dep = get_component(dep) out.write(' ' + c_dep.get_link_name()) out.write('\n') @@ -1111,7 +1111,7 @@ class DLLComponent(Component): out.write(' ') out.write(obj) for dep in deps: - if not dep in self.reexports: + if dep not in self.reexports: c_dep = get_component(dep) out.write(' ' + c_dep.get_link_name()) out.write(' ' + FOCI2LIB) @@ -1204,9 +1204,9 @@ class DLLComponent(Component): class DotNetDLLComponent(Component): def __init__(self, name, dll_name, path, deps, assembly_info_dir): Component.__init__(self, name, path, deps) - if dll_name == None: + if dll_name is None: dll_name = name - if assembly_info_dir == None: + if assembly_info_dir is None: assembly_info_dir = "." self.dll_name = dll_name self.assembly_info_dir = assembly_info_dir @@ -1270,7 +1270,7 @@ class DotNetDLLComponent(Component): class JavaDLLComponent(Component): def __init__(self, name, dll_name, package_name, manifest_file, path, deps): Component.__init__(self, name, path, deps) - if dll_name == None: + if dll_name is None: dll_name = name self.dll_name = dll_name self.package_name = package_name @@ -1361,7 +1361,7 @@ class JavaDLLComponent(Component): class MLComponent(Component): def __init__(self, name, lib_name, path, deps): Component.__init__(self, name, path, deps) - if lib_name == None: + if lib_name is None: lib_name = name self.lib_name = lib_name @@ -1428,7 +1428,7 @@ class MLComponent(Component): out.write('%s: %s %s\n' % (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'), os.path.join(sub_dir, 'z3native_stubs.c'), - get_component(Z3_DLL_COMPONENT).dll_name+'$(SO_EXT)')); + get_component(Z3_DLL_COMPONENT).dll_name+'$(SO_EXT)')) out.write('\t$(CC) $(CXXFLAGS_OCAML) -I %s -I %s %s $(CXX_OUT_FLAG)%s$(OBJ_EXT)\n' % (OCAML_LIB, api_src, os.path.join(sub_dir, 'z3native_stubs.c'), os.path.join(sub_dir, 'z3native_stubs'))) @@ -2050,7 +2050,7 @@ def to_c_method(s): def def_module_params(module_name, export, params, class_name=None, description=None): pyg = get_curr_pyg() dirname = os.path.split(get_curr_pyg())[0] - if class_name == None: + if class_name is None: class_name = '%s_params' % module_name hpp = os.path.join(dirname, '%s.hpp' % class_name) out = open(hpp, 'w') @@ -2076,7 +2076,7 @@ def def_module_params(module_name, export, params, class_name=None, description= if export: out.write(' /*\n') out.write(" REG_MODULE_PARAMS('%s', '%s::collect_param_descrs')\n" % (module_name, class_name)) - if description != None: + if description is not None: out.write(" REG_MODULE_DESCRIPTION('%s', '%s')\n" % (module_name, description)) out.write(' */\n') # Generated accessors @@ -2140,7 +2140,7 @@ def update_version(): minor = VER_MINOR build = VER_BUILD revision = VER_REVISION - if major == None or minor == None or build == None or revision == None: + if major is None or minor is None or build is None or revision is None: raise MKException("set_version(major, minor, build, revision) must be used before invoking update_version()") if not ONLY_MAKEFILES: mk_version_dot_h(major, minor, build, revision) @@ -2476,7 +2476,7 @@ def mk_bindings(api_files): # Extract enumeration types from API files, and add python definitions. def mk_z3consts_py(api_files): - if Z3PY_SRC_DIR == None: + if Z3PY_SRC_DIR is None: raise MKException("You must invoke set_z3py_dir(path):") blank_pat = re.compile("^ *$") @@ -2570,7 +2570,7 @@ def mk_z3consts_dotnet(api_files): z3consts.write('using System;\n\n' '#pragma warning disable 1591\n\n' 'namespace Microsoft.Z3\n' - '{\n'); + '{\n') for api_file in api_files: api_file_c = dotnet.find_file(api_file, dotnet.name) @@ -2634,7 +2634,7 @@ def mk_z3consts_dotnet(api_files): decls[words[1]] = idx idx = idx + 1 linenum = linenum + 1 - z3consts.write('}\n'); + z3consts.write('}\n') if VERBOSE: print("Generated '%s'" % os.path.join(dotnet.src_dir, 'Enumerations.cs')) @@ -2702,7 +2702,7 @@ def mk_z3consts_java(api_files): if name not in DeprecatedEnums: efile = open('%s.java' % os.path.join(gendir, name), 'w') efile.write('/**\n * Automatically generated file\n **/\n\n') - efile.write('package %s.enumerations;\n\n' % java.package_name); + efile.write('package %s.enumerations;\n\n' % java.package_name) efile.write('/**\n') efile.write(' * %s\n' % name) @@ -2713,7 +2713,7 @@ def mk_z3consts_java(api_files): for k in decls: i = decls[k] if first: - first = False + first = False else: efile.write(',\n') efile.write(' %s (%s)' % (k, i)) diff --git a/scripts/update_api.py b/scripts/update_api.py index e179043e2..f3df62dd2 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -217,16 +217,16 @@ def type2ml(ty): return Type2ML[ty] def _in(ty): - return (IN, ty); + return (IN, ty) def _in_array(sz, ty): - return (IN_ARRAY, ty, sz); + return (IN_ARRAY, ty, sz) def _out(ty): - return (OUT, ty); + return (OUT, ty) def _out_array(sz, ty): - return (OUT_ARRAY, ty, sz, sz); + return (OUT_ARRAY, ty, sz, sz) # cap contains the position of the argument that stores the capacity of the array # sz contains the position of the output argument that stores the (real) size of the array @@ -234,7 +234,7 @@ def _out_array2(cap, sz, ty): return (OUT_ARRAY, ty, cap, sz) def _inout_array(sz, ty): - return (INOUT_ARRAY, ty, sz, sz); + return (INOUT_ARRAY, ty, sz, sz) def _out_managed_array(sz,ty): return (OUT_MANAGED_ARRAY, ty, 0, sz) @@ -314,7 +314,7 @@ def param2javaw(p): else: return "jlongArray" elif k == OUT_MANAGED_ARRAY: - return "jlong"; + return "jlong" else: return type2javaw(param_type(p)) @@ -336,7 +336,7 @@ def param2ml(p): elif k == IN_ARRAY or k == INOUT_ARRAY or k == OUT_ARRAY: return "%s array" % type2ml(param_type(p)) elif k == OUT_MANAGED_ARRAY: - return "%s array" % type2ml(param_type(p)); + return "%s array" % type2ml(param_type(p)) else: return type2ml(param_type(p)) @@ -422,14 +422,14 @@ def mk_dotnet(): dotnet.write('using System.Collections.Generic;\n') dotnet.write('using System.Text;\n') dotnet.write('using System.Runtime.InteropServices;\n\n') - dotnet.write('#pragma warning disable 1591\n\n'); + dotnet.write('#pragma warning disable 1591\n\n') dotnet.write('namespace Microsoft.Z3\n') dotnet.write('{\n') for k in Type2Str: v = Type2Str[k] if is_obj(k): dotnet.write(' using %s = System.IntPtr;\n' % v) - dotnet.write('\n'); + dotnet.write('\n') dotnet.write(' public class Native\n') dotnet.write(' {\n\n') dotnet.write(' [UnmanagedFunctionPointer(CallingConvention.Cdecl)]\n') @@ -437,7 +437,7 @@ def mk_dotnet(): dotnet.write(' public unsafe class LIB\n') dotnet.write(' {\n') dotnet.write(' const string Z3_DLL_NAME = \"libz3.dll\";\n' - ' \n'); + ' \n') dotnet.write(' [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]\n') dotnet.write(' public extern static void Z3_set_error_handler(Z3_context a0, Z3_error_handler a1);\n\n') for name, result, params in _dotnet_decls: @@ -448,7 +448,7 @@ def mk_dotnet(): else: dotnet.write('public extern static %s %s(' % (type2dotnet(result), name)) first = True - i = 0; + i = 0 for param in params: if first: first = False @@ -480,7 +480,7 @@ def mk_dotnet_wrappers(): else: dotnet.write(' public static %s %s(' % (type2dotnet(result), name)) first = True - i = 0; + i = 0 for param in params: if first: first = False @@ -491,9 +491,9 @@ def mk_dotnet_wrappers(): dotnet.write(') {\n') dotnet.write(' ') if result == STRING: - dotnet.write('IntPtr r = '); + dotnet.write('IntPtr r = ') elif result != VOID: - dotnet.write('%s r = ' % type2dotnet(result)); + dotnet.write('%s r = ' % type2dotnet(result)) dotnet.write('LIB.%s(' % (name)) first = True i = 0 @@ -504,14 +504,14 @@ def mk_dotnet_wrappers(): dotnet.write(', ') if param_kind(param) == OUT: if param_type(param) == STRING: - dotnet.write('out '); + dotnet.write('out ') else: dotnet.write('ref ') elif param_kind(param) == OUT_MANAGED_ARRAY: - dotnet.write('out '); + dotnet.write('out ') dotnet.write('a%d' % i) i = i + 1 - dotnet.write(');\n'); + dotnet.write(');\n') if name not in Unwrapped: if name in NULLWrapped: dotnet.write(" if (r == IntPtr.Zero)\n") @@ -576,7 +576,7 @@ def mk_java(): for name, result, params in _dotnet_decls: java_native.write(' protected static native %s INTERNAL%s(' % (type2java(result), java_method_name(name))) first = True - i = 0; + i = 0 for param in params: if first: first = False @@ -590,7 +590,7 @@ def mk_java(): for name, result, params in _dotnet_decls: java_native.write(' public static %s %s(' % (type2java(result), java_method_name(name))) first = True - i = 0; + i = 0 for param in params: if first: first = False @@ -608,7 +608,7 @@ def mk_java(): java_native.write('%s res = ' % type2java(result)) java_native.write('INTERNAL%s(' % (java_method_name(name))) first = True - i = 0; + i = 0 for param in params: if first: first = False @@ -696,7 +696,7 @@ def mk_java(): java_wrapper.write('') for name, result, params in _dotnet_decls: java_wrapper.write('DLL_VIS JNIEXPORT %s JNICALL Java_%s_Native_INTERNAL%s(JNIEnv * jenv, jclass cls' % (type2javaw(result), pkg_str, java_method_name(name))) - i = 0; + i = 0 for param in params: java_wrapper.write(', ') java_wrapper.write('%s a%d' % (param2javaw(param), i)) @@ -802,10 +802,10 @@ def mk_log_header(file, name, params): i = 0 for p in params: if i > 0: - file.write(", "); + file.write(", ") file.write("%s a%s" % (param2str(p), i)) i = i + 1 - file.write(")"); + file.write(")") def log_param(p): kind = param_kind(p) @@ -962,7 +962,7 @@ def def_API(name, result, params): log_c.write(" I(a%s);\n" % i) exe_c.write("in.get_bool(%s)" % i) elif ty == PRINT_MODE or ty == ERROR_CODE: - log_c.write(" U(static_cast(a%s));\n" % i); + log_c.write(" U(static_cast(a%s));\n" % i) exe_c.write("static_cast<%s>(in.get_uint(%s))" % (type2str(ty), i)) else: error("unsupported parameter for %s, %s" % (name, p)) @@ -1074,10 +1074,10 @@ def ml_method_name(name): return name[3:] # Remove Z3_ def is_out_param(p): - if param_kind(p) == OUT or param_kind(p) == INOUT or param_kind(p) == OUT_ARRAY or param_kind(p) == INOUT_ARRAY or param_kind(p) == OUT_MANAGED_ARRAY: - return True - else: - return False + if param_kind(p) == OUT or param_kind(p) == INOUT or param_kind(p) == OUT_ARRAY or param_kind(p) == INOUT_ARRAY or param_kind(p) == OUT_MANAGED_ARRAY: + return True + else: + return False def outparams(params): op = [] @@ -1162,7 +1162,7 @@ def mk_ml(): ml_native.write('(** The native (raw) interface to the dynamic Z3 library. *)\n\n') ml_i.write('(* Automatically generated file *)\n\n') ml_i.write('(** The native (raw) interface to the dynamic Z3 library. *)\n\n') - ml_i.write('(**/**)\n\n'); + ml_i.write('(**/**)\n\n') ml_native.write('open Z3enums\n\n') ml_native.write('(**/**)\n') ml_native.write('type ptr\n') @@ -1225,7 +1225,7 @@ def mk_ml(): ml_native.write(' = "n_%s"\n' % ml_method_name(name)) ml_native.write('\n') ml_native.write(' end\n\n') - ml_i.write('\n(**/**)\n'); + ml_i.write('\n(**/**)\n') # Exception wrappers for name, result, params in _dotnet_decls: @@ -1234,11 +1234,11 @@ def mk_ml(): ml_native.write(' let %s ' % ml_method_name(name)) first = True - i = 0; + i = 0 for p in params: if is_in_param(p): if first: - first = False; + first = False else: ml_native.write(' ') ml_native.write('a%d' % i) @@ -1255,7 +1255,7 @@ def mk_ml(): if len(ip) == 0: ml_native.write(' ()') first = True - i = 0; + i = 0 for p in params: if is_in_param(p): ml_native.write(' a%d' % i) @@ -1469,7 +1469,7 @@ def mk_ml(): if len(op) > 0: if result != VOID: ml_wrapper.write(' %s\n' % ml_set_wrap(result, "res_val", "z3_result")) - i = 0; + i = 0 for p in params: if param_kind(p) == OUT_ARRAY or param_kind(p) == INOUT_ARRAY: ml_wrapper.write(' _a%s_val = caml_alloc(_a%s, 0);\n' % (i, param_array_capacity_pos(p))) @@ -1492,7 +1492,7 @@ def mk_ml(): for p in params: if is_out_param(p): ml_wrapper.write(' Store_field(result, %s, _a%s_val);\n' % (j, i)) - j = j + 1; + j = j + 1 i = i + 1 # local array cleanup From 8e772b428bc0f678a76cd885f75fcc4b3c0bdae7 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Thu, 16 Apr 2015 19:14:34 +0200 Subject: [PATCH 11/57] use a base iz3_exception class for exceptions raised during interpolation Using a base exception class, derived from z3_exception, makes it possible to recover gracefully if something goes wrong during the computation of interpolants. --- src/interp/iz3base.h | 4 +- src/interp/iz3exception.h | 28 ++++++++++++ src/interp/iz3interp.cpp | 2 +- src/interp/iz3interp.h | 7 ++- src/interp/iz3mgr.cpp | 16 +++---- src/interp/iz3mgr.h | 1 + src/interp/iz3pp.h | 3 +- src/interp/iz3proof.h | 4 +- src/interp/iz3proof_itp.cpp | 68 +++++++++++++++++------------- src/interp/iz3proof_itp.h | 4 +- src/interp/iz3translate.cpp | 18 ++++---- src/interp/iz3translate.h | 3 +- src/interp/iz3translate_direct.cpp | 8 +++- 13 files changed, 109 insertions(+), 57 deletions(-) create mode 100644 src/interp/iz3exception.h diff --git a/src/interp/iz3base.h b/src/interp/iz3base.h index 76ed6e3e2..59cbf3a61 100755 --- a/src/interp/iz3base.h +++ b/src/interp/iz3base.h @@ -117,7 +117,7 @@ class iz3base : public iz3mgr, public scopes { /** Interpolator for clauses, to be implemented */ virtual void interpolate_clause(std::vector &lits, std::vector &itps){ - throw "no interpolator"; + throw iz3_exception("no interpolator"); } ast get_proof_check_assump(range &rng){ @@ -129,7 +129,7 @@ class iz3base : public iz3mgr, public scopes { int frame_of_assertion(const ast &ass){ stl_ext::hash_map::iterator it = frame_map.find(ass); if(it == frame_map.end()) - throw "unknown assertion"; + throw iz3_exception("unknown assertion"); return it->second; } diff --git a/src/interp/iz3exception.h b/src/interp/iz3exception.h new file mode 100644 index 000000000..134c049cf --- /dev/null +++ b/src/interp/iz3exception.h @@ -0,0 +1,28 @@ +/*++ +Copyright (c) 2015 Microsoft Corporation + +Module Name: + + iz3exception.h + +Abstract: + + Base class for exceptions raised by interpolation routines + +Author: + +Notes: + +--*/ +#ifndef _IZ3EXCEPTION_H_ +#define _IZ3EXCEPTION_H_ + +#include "z3_exception.h" +#include "error_codes.h" + +class iz3_exception: public default_exception { +public: + iz3_exception(const std::string &msg): default_exception(msg) {} +}; + +#endif diff --git a/src/interp/iz3interp.cpp b/src/interp/iz3interp.cpp index 9d90a05c7..ec9fceecc 100755 --- a/src/interp/iz3interp.cpp +++ b/src/interp/iz3interp.cpp @@ -218,7 +218,7 @@ public: iz3secondary *sp = iz3foci::create(this,num,(int *)(parents.empty()?0:&parents[0])); int res = sp->interpolate(cnsts, interps); if(res != 0) - throw "secondary failed"; + throw iz3_exception("secondary failed"); } void proof_to_interpolant(z3pf proof, diff --git a/src/interp/iz3interp.h b/src/interp/iz3interp.h index 2b1926994..f17b3c405 100644 --- a/src/interp/iz3interp.h +++ b/src/interp/iz3interp.h @@ -21,6 +21,7 @@ #define IZ3_INTERP_H #include "iz3hash.h" +#include "iz3exception.h" #include "solver.h" class iz3base; @@ -35,12 +36,14 @@ public: }; /** This object is thrown if a tree interpolation problem is mal-formed */ -struct iz3_bad_tree { +struct iz3_bad_tree: public iz3_exception { + iz3_bad_tree(): iz3_exception("iz3_bad_tree") {} }; /** This object is thrown when iz3 fails due to an incompleteness in the secondary solver. */ -struct iz3_incompleteness { +struct iz3_incompleteness: public iz3_exception { + iz3_incompleteness(): iz3_exception("iz3_incompleteness") {} }; typedef interpolation_options_struct *interpolation_options; diff --git a/src/interp/iz3mgr.cpp b/src/interp/iz3mgr.cpp index 5a7f71987..845e716ef 100755 --- a/src/interp/iz3mgr.cpp +++ b/src/interp/iz3mgr.cpp @@ -515,7 +515,7 @@ bool iz3mgr::is_farkas_coefficient_negative(const ast &proof, int n){ symb s = sym(proof); bool ok = s->get_parameter(n+2).is_rational(r); if(!ok) - throw "Bad Farkas coefficient"; + throw iz3_exception("Bad Farkas coefficient"); return r.is_neg(); } @@ -532,7 +532,7 @@ void iz3mgr::get_farkas_coeffs(const ast &proof, std::vector& rats){ rational r; bool ok = s->get_parameter(i).is_rational(r); if(!ok) - throw "Bad Farkas coefficient"; + throw iz3_exception("Bad Farkas coefficient"); #if 0 { ast con = conc(prem(proof,i-2)); @@ -577,7 +577,7 @@ void iz3mgr::get_assign_bounds_coeffs(const ast &proof, std::vector& r rational r; bool ok = s->get_parameter(i).is_rational(r); if(!ok) - throw "Bad Farkas coefficient"; + throw iz3_exception("Bad Farkas coefficient"); { ast con = arg(conc(proof),i-1); ast temp = make_real(r); // for debugging @@ -593,7 +593,7 @@ void iz3mgr::get_assign_bounds_coeffs(const ast &proof, std::vector& r if(rats[1].is_neg()){ // work around bug -- if all coeffs negative, negate them for(unsigned i = 1; i < rats.size(); i++){ if(!rats[i].is_neg()) - throw "Bad Farkas coefficients"; + throw iz3_exception("Bad Farkas coefficients"); rats[i] = -rats[i]; } } @@ -623,7 +623,7 @@ void iz3mgr::get_assign_bounds_rule_coeffs(const ast &proof, std::vectorget_parameter(i).is_rational(r); if(!ok) - throw "Bad Farkas coefficient"; + throw iz3_exception("Bad Farkas coefficient"); { ast con = conc(prem(proof,i-2)); ast temp = make_real(r); // for debugging @@ -639,7 +639,7 @@ void iz3mgr::get_assign_bounds_rule_coeffs(const ast &proof, std::vector #include "iz3hash.h" +#include "iz3exception.h" #include"well_sorted.h" #include"arith_decl_plugin.h" diff --git a/src/interp/iz3pp.h b/src/interp/iz3pp.h index bbb10a785..c66b4a4fa 100644 --- a/src/interp/iz3pp.h +++ b/src/interp/iz3pp.h @@ -25,7 +25,8 @@ /** Exception thrown in case of mal-formed tree interpoloation specification */ -struct iz3pp_bad_tree { +struct iz3pp_bad_tree: public iz3_exception { + iz3pp_bad_tree(): iz3_exception("iz3pp_bad_tree") {} }; void iz3pp(ast_manager &m, diff --git a/src/interp/iz3proof.h b/src/interp/iz3proof.h index be85702a2..213afce5e 100755 --- a/src/interp/iz3proof.h +++ b/src/interp/iz3proof.h @@ -57,7 +57,9 @@ class iz3proof { typedef prover::ast ast; /** Object thrown in case of a proof error. */ - struct proof_error {}; + struct proof_error: public iz3_exception { + proof_error(): iz3_exception("proof_error") {} + }; /* Null proof node */ static const node null = -1; diff --git a/src/interp/iz3proof_itp.cpp b/src/interp/iz3proof_itp.cpp index 0bdd51ed8..588ebc2ea 100755 --- a/src/interp/iz3proof_itp.cpp +++ b/src/interp/iz3proof_itp.cpp @@ -250,7 +250,7 @@ class iz3proof_itp_impl : public iz3proof_itp { #if 0 rational r; if(!is_integer(coeff,r)) - throw "ack!"; + throw iz3_exception("ack!"); ast n = make_int(r.numerator()); ast res = make(Times,n,t); if(!r.is_int()) { @@ -433,7 +433,7 @@ class iz3proof_itp_impl : public iz3proof_itp { if(op(foo) == Uninterpreted && sym(foo) == contra){ ast neg_lit = arg(foo,1); if(!is_false(neg_lit) && neg_lits.find(neg_lit) == neg_lits.end()) - throw "lost a literal"; + throw iz3_exception("lost a literal"); return; } else { @@ -506,7 +506,9 @@ class iz3proof_itp_impl : public iz3proof_itp { /* This is where the real work happens. Here, we simplify the proof obtained by cut elimination, obtaining an interpolant. */ - struct cannot_simplify {}; + struct cannot_simplify: public iz3_exception { + cannot_simplify(): iz3_exception("cannot_simplify") {} + }; hash_map simplify_memo; ast simplify(const ast &t){ @@ -582,7 +584,7 @@ class iz3proof_itp_impl : public iz3proof_itp { // if(g == symm) return simplify_rotate_symm(pl,args[0],pf); } if(op(pf) == Leq) - throw "foo!"; + throw iz3_exception("foo!"); throw cannot_simplify(); } @@ -831,7 +833,7 @@ class iz3proof_itp_impl : public iz3proof_itp { return my_implies(cond,ineqs); if(op(ineqs) != And) return my_and(Bconds,my_implies(cond,ineqs)); - throw "help!"; + throw iz3_exception("help!"); } ast add_mixed_eq2ineq(const ast &lhs, const ast &rhs, const ast &equa, const ast &itp){ @@ -871,7 +873,7 @@ class iz3proof_itp_impl : public iz3proof_itp { } } } - throw "help!"; + throw iz3_exception("help!"); } void reverse_modpon(std::vector &args){ @@ -980,7 +982,9 @@ class iz3proof_itp_impl : public iz3proof_itp { return chain; } - struct subterm_normals_failed {}; + struct subterm_normals_failed: public iz3_exception { + subterm_normals_failed(): iz3_exception("subterm_normals_failed") {} + }; void get_subterm_normals(const ast &ineq1, const ast &ineq2, const ast &chain, ast &normals, const ast &pos, hash_set &memo, ast &Aproves, ast &Bproves){ @@ -989,7 +993,7 @@ class iz3proof_itp_impl : public iz3proof_itp { if(o1 == Not || o1 == Leq || o1 == Lt || o1 == Geq || o1 == Gt || o1 == Plus || o1 == Times){ int n = num_args(ineq1); if(o2 != o1 || num_args(ineq2) != n) - throw "bad inequality rewriting"; + throw iz3_exception("bad inequality rewriting"); for(int i = 0; i < n; i++){ ast new_pos = add_pos_to_end(pos,i); get_subterm_normals(arg(ineq1,i), arg(ineq2,i), chain, normals, new_pos, memo, Aproves, Bproves); @@ -1000,7 +1004,7 @@ class iz3proof_itp_impl : public iz3proof_itp { memo.insert(ineq2); ast sub_chain = extract_rewrites(chain,pos); if(is_true(sub_chain)) - throw "bad inequality rewriting"; + throw iz3_exception("bad inequality rewriting"); ast new_normal = make_normal_step(ineq2,ineq1,reverse_chain(sub_chain)); normals = merge_normal_chains(normals,cons_normal(new_normal,mk_true()), Aproves, Bproves); } @@ -1149,7 +1153,7 @@ class iz3proof_itp_impl : public iz3proof_itp { ast interp = contra_chain(Q2,chain); return my_and(Aproves,my_implies(Bproves,interp)); } - throw "bad exmid"; + throw iz3_exception("bad exmid"); } ast simplify_cong(const std::vector &args){ @@ -1163,7 +1167,7 @@ class iz3proof_itp_impl : public iz3proof_itp { ast interp = contra_chain(Q2,chain); return my_and(Aproves,my_implies(Bproves,interp)); } - throw "bad cong"; + throw iz3_exception("bad cong"); } bool is_equivrel(const ast &p){ @@ -1171,7 +1175,9 @@ class iz3proof_itp_impl : public iz3proof_itp { return o == Equal || o == Iff; } - struct rewrites_failed{}; + struct rewrites_failed: public iz3_exception { + rewrites_failed(): iz3_exception("rewrites_failed") {} + }; /* Suppose p in Lang(B) and A |- p -> q and B |- q -> r. Return a z in Lang(B) such that B |- p -> z and A |- z -> q. Collect any side conditions in "rules". */ @@ -1414,7 +1420,7 @@ class iz3proof_itp_impl : public iz3proof_itp { rational r; if(is_numeral(arg(pos,0),r)) return r.get_unsigned(); - throw "bad position!"; + throw iz3_exception("bad position!"); } /* substitute y into position pos in x */ @@ -1429,7 +1435,7 @@ class iz3proof_itp_impl : public iz3proof_itp { args[i] = i == p ? subst_in_pos(arg(x,i),arg(pos,1),y) : arg(x,i); return clone(x,args); } - throw "bad term position!"; + throw iz3_exception("bad term position!"); } ast diff_chain(LitType t, const ast &pos, const ast &x, const ast &y, const ast &prefix){ @@ -1448,10 +1454,10 @@ class iz3proof_itp_impl : public iz3proof_itp { ast make_rewrite(LitType t, const ast &pos, const ast &cond, const ast &equality){ #if 0 if(pos == top_pos && op(equality) == Iff && !is_true(arg(equality,0))) - throw "bad rewrite"; + throw iz3_exception("bad rewrite"); #endif if(!is_equivrel(equality)) - throw "bad rewrite"; + throw iz3_exception("bad rewrite"); return make(t == LitA ? rewrite_A : rewrite_B, pos, cond, equality); } @@ -1662,25 +1668,25 @@ class iz3proof_itp_impl : public iz3proof_itp { if(is_true(rest)){ ast old = rewrite_rhs(last); if(!(op(old) == Not)) - throw "bad negative equality chain"; + throw iz3_exception("bad negative equality chain"); ast equ = arg(old,0); if(!is_equivrel(equ)) - throw "bad negative equality chain"; + throw iz3_exception("bad negative equality chain"); last = rewrite_update_rhs(last,top_pos,make(Not,make(op(equ),arg(equ,1),arg(equ,0))),make(True)); return chain_cons(rest,last); } ast pos = rewrite_pos(last); if(pos == top_pos) - throw "bad negative equality chain"; + throw iz3_exception("bad negative equality chain"); int idx = pos_arg(pos); if(idx != 0) - throw "bad negative equality chain"; + throw iz3_exception("bad negative equality chain"); pos = arg(pos,1); if(pos == top_pos){ ast lhs = rewrite_lhs(last); ast rhs = rewrite_rhs(last); if(op(lhs) != Equal || op(rhs) != Equal) - throw "bad negative equality chain"; + throw iz3_exception("bad negative equality chain"); last = make_rewrite(rewrite_side(last),rewrite_pos(last),rewrite_cond(last), make(Iff,make(Equal,arg(lhs,1),arg(lhs,0)),make(Equal,arg(rhs,1),arg(rhs,0)))); } @@ -1691,7 +1697,7 @@ class iz3proof_itp_impl : public iz3proof_itp { else if(idx == 1) idx = 0; else - throw "bad negative equality chain"; + throw iz3_exception("bad negative equality chain"); pos = pos_add(0,pos_add(idx,arg(pos,1))); last = make_rewrite(rewrite_side(last),pos,rewrite_cond(last),rewrite_equ(last)); } @@ -1708,7 +1714,7 @@ class iz3proof_itp_impl : public iz3proof_itp { return chain; } if(is_true(rest)) - throw "bad rewrite chain"; + throw iz3_exception("bad rewrite chain"); ast head = get_head_chain(rest,tail,is_not); tail = chain_cons(tail,last); return head; @@ -1766,7 +1772,9 @@ class iz3proof_itp_impl : public iz3proof_itp { } - struct cannot_split {}; + struct cannot_split: public iz3_exception { + cannot_split(): iz3_exception("cannot_split") {} + }; /** Split a chain of rewrites two chains, operating on positions 0 and 1. Fail if any rewrite in the chain operates on top position. */ @@ -1808,7 +1816,7 @@ class iz3proof_itp_impl : public iz3proof_itp { } case 1: if(rewrite_lhs(last) != rewrite_rhs(last)) - throw "bad rewrite chain"; + throw iz3_exception("bad rewrite chain"); break; default:; } @@ -1853,7 +1861,9 @@ class iz3proof_itp_impl : public iz3proof_itp { return rewrites_from_to(rest,lhs,mid); } - struct bad_ineq_inference {}; + struct bad_ineq_inference: public iz3_exception { + bad_ineq_inference(): iz3_exception("bad_ineq_inference") {} + }; ast chain_ineqs(opr comp_op, LitType t, const ast &chain, const ast &lhs, const ast &rhs){ if(is_true(chain)){ @@ -1907,7 +1917,7 @@ class iz3proof_itp_impl : public iz3proof_itp { rhs = arg(ineq,1); return; } - throw "bad ineq"; + throw iz3_exception("bad ineq"); } ast chain_pos_add(int arg, const ast &chain){ @@ -1974,7 +1984,7 @@ class iz3proof_itp_impl : public iz3proof_itp { ast make_normal(const ast &ineq, const ast &nrml){ if(!is_ineq(ineq)) - throw "what?"; + throw iz3_exception("what?"); return make(normal,ineq,nrml); } @@ -1985,7 +1995,7 @@ class iz3proof_itp_impl : public iz3proof_itp { return make_normal_step(lhs,rhs,proof); if(rhst == LitMixed && (lhst != LitMixed || ast_id(rhs) < ast_id(lhs))) return make_normal_step(rhs,lhs,reverse_chain(proof)); - throw "help!"; + throw iz3_exception("help!"); } ast chain_side_proves(LitType side, const ast &chain){ diff --git a/src/interp/iz3proof_itp.h b/src/interp/iz3proof_itp.h index e1e0de5cc..bd9eca441 100644 --- a/src/interp/iz3proof_itp.h +++ b/src/interp/iz3proof_itp.h @@ -50,7 +50,9 @@ class iz3proof_itp : public iz3mgr { typedef ast node; /** Object thrown in case of a proof error. */ - struct proof_error {}; + struct proof_error: public iz3_exception { + proof_error(): iz3_exception("proof_error") {} + }; /** Make a resolution node with given pivot literal and premises. diff --git a/src/interp/iz3translate.cpp b/src/interp/iz3translate.cpp index 5b420673c..6d1b3f002 100755 --- a/src/interp/iz3translate.cpp +++ b/src/interp/iz3translate.cpp @@ -132,7 +132,7 @@ public: // if(range_is_empty(r)) range r = ast_scope(quanted); if(range_is_empty(r)) - throw "can't skolemize"; + throw iz3_exception("can't skolemize"); if(frame == INT_MAX || !in_range(frame,r)) frame = range_max(r); // this is desperation -- may fail if(frame >= frames) frame = frames - 1; @@ -1086,10 +1086,10 @@ public: rational xcoeff = get_first_coefficient(arg(x,0),xvar); rational ycoeff = get_first_coefficient(arg(y,0),yvar); if(xcoeff == rational(0) || ycoeff == rational(0) || xvar != yvar) - throw "bad assign-bounds lemma"; + throw iz3_exception("bad assign-bounds lemma"); rational ratio = xcoeff/ycoeff; if(denominator(ratio) != rational(1)) - throw "bad assign-bounds lemma"; + throw iz3_exception("bad assign-bounds lemma"); return make_int(ratio); // better be integer! } @@ -1098,7 +1098,7 @@ public: get_assign_bounds_coeffs(proof,farkas_coeffs); int nargs = num_args(con); if(nargs != (int)(farkas_coeffs.size())) - throw "bad assign-bounds theory lemma"; + throw iz3_exception("bad assign-bounds theory lemma"); #if 0 if(farkas_coeffs[0] != make_int(rational(1))) farkas_coeffs[0] = make_int(rational(1)); @@ -1139,7 +1139,7 @@ public: get_assign_bounds_rule_coeffs(proof,farkas_coeffs); int nargs = num_prems(proof)+1; if(nargs != (int)(farkas_coeffs.size())) - throw "bad assign-bounds theory lemma"; + throw iz3_exception("bad assign-bounds theory lemma"); #if 0 if(farkas_coeffs[0] != make_int(rational(1))) farkas_coeffs[0] = make_int(rational(1)); @@ -1415,7 +1415,7 @@ public: std::vector vals = cvec; if(!is_sat(cnstrs,new_proof,vals)) - throw "Proof error!"; + throw iz3_exception("Proof error!"); std::vector rat_farkas_coeffs; for(unsigned i = 0; i < cvec.size(); i++){ ast bar = vals[i]; @@ -1423,7 +1423,7 @@ public: if(is_numeral(bar,r)) rat_farkas_coeffs.push_back(r); else - throw "Proof error!"; + throw iz3_exception("Proof error!"); } rational the_lcd = lcd(rat_farkas_coeffs); std::vector farkas_coeffs; @@ -1471,7 +1471,7 @@ public: ast new_proof; std::vector dummy; if(is_sat(npcons,new_proof,dummy)) - throw "Proof error!"; + throw iz3_exception("Proof error!"); pfrule dk = pr(new_proof); int nnp = num_prems(new_proof); std::vector my_prems; @@ -1532,7 +1532,7 @@ public: ast new_proof; std::vector dummy; if(is_sat(npcons,new_proof,dummy)) - throw "Proof error!"; + throw iz3_exception("Proof error!"); pfrule dk = pr(new_proof); int nnp = num_prems(new_proof); std::vector my_prems; diff --git a/src/interp/iz3translate.h b/src/interp/iz3translate.h index 2fcf406db..86b0b3d2d 100755 --- a/src/interp/iz3translate.h +++ b/src/interp/iz3translate.h @@ -35,7 +35,8 @@ class iz3translation : public iz3base { virtual ~iz3translation(){} /** This is thrown when the proof cannot be translated. */ - struct unsupported { + struct unsupported: public iz3_exception { + unsupported(): iz3_exception("unsupported") {} }; static iz3translation *create(iz3mgr &mgr, diff --git a/src/interp/iz3translate_direct.cpp b/src/interp/iz3translate_direct.cpp index c1b751c6f..9b9b46cad 100755 --- a/src/interp/iz3translate_direct.cpp +++ b/src/interp/iz3translate_direct.cpp @@ -595,7 +595,9 @@ public: } - struct invalid_lemma {}; + struct invalid_lemma: public iz3_exception { + invalid_lemma(): iz3_exception("invalid_lemma") {} + }; @@ -846,7 +848,9 @@ public: return 1; } - struct non_lit_local_ante {}; + struct non_lit_local_ante: public iz3_exception { + non_lit_local_ante(): iz3_exception("non_lit_local_ante") {} + }; bool local_antes_simple; From f034ed54ab90fad57e1dfe56dc16f882e69c41e3 Mon Sep 17 00:00:00 2001 From: zach shipko Date: Thu, 23 Apr 2015 11:28:17 -0700 Subject: [PATCH 12/57] support openbsd --- scripts/mk_util.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 4641a7b1b..66877485e 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1581,6 +1581,11 @@ def mk_config(): LDFLAGS = '%s -lrt' % LDFLAGS SLIBFLAGS = '-shared' SLIBEXTRAFLAGS = '%s -lrt' % SLIBEXTRAFLAGS + elif sysname == 'OpenBSD': + CXXFLAGS = '%s -fno-strict-aliasing -D_OPENBSD_' % CXXFLAGS + OS_DEFINES = '-D_OPENBSD_' + SO_EXT = '.so' + SLIBFLAGS = '-shared' elif sysname[:6] == 'CYGWIN': CXXFLAGS = '%s -D_CYGWIN -fno-strict-aliasing' % CXXFLAGS OS_DEFINES = '-D_CYGWIN' From 7dcdecfa091a10a186f43ed82c4b1ee3d6e82b7c Mon Sep 17 00:00:00 2001 From: Kevin Borgolte Date: Tue, 5 May 2015 11:29:26 -0700 Subject: [PATCH 13/57] fix mixed tab/spaces indent --- scripts/mk_util.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 72d432eab..b0443c808 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -248,16 +248,16 @@ def test_fpmath(cc): 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" + 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" + 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" + FPMATH_FLAGS="-mfpu=vfp -mfloat-abi=hard" return "ARM-VFP" else: - FPMATH_FLAGS="" + FPMATH_FLAGS="" return "UNKNOWN" @@ -412,7 +412,7 @@ def find_ml_lib(): print ('Finding OCAML_LIB...') t = TempFile('output') null = open(os.devnull, 'wb') - try: + try: subprocess.call([OCAMLC, '-where'], stdout=t.fname, stderr=null) t.commit() except: @@ -553,7 +553,7 @@ def display_help(exit_code): print(" -n, --nodotnet do not generate Microsoft.Z3.dll make rules.") print(" -j, --java generate Java bindings.") print(" --ml generate OCaml bindings.") - print(" --staticlib build Z3 static library.") + print(" --staticlib build Z3 static library.") if not IS_WINDOWS: print(" -g, --gmp use GMP.") print(" --gprof enable gprof") @@ -1841,7 +1841,7 @@ def mk_config(): CPPFLAGS = '%s -DZ3GITHASH=%s' % (CPPFLAGS, GIT_HASH) CXXFLAGS = '%s -fvisibility=hidden -c' % CXXFLAGS FPMATH = test_fpmath(CXX) - CXXFLAGS = '%s %s' % (CXXFLAGS, FPMATH_FLAGS) + CXXFLAGS = '%s %s' % (CXXFLAGS, FPMATH_FLAGS) HAS_OMP = test_openmp(CXX) if HAS_OMP: CXXFLAGS = '%s -fopenmp' % CXXFLAGS From f458423868c8613c57903a038797995d7806c842 Mon Sep 17 00:00:00 2001 From: Kevin Borgolte Date: Tue, 5 May 2015 11:29:48 -0700 Subject: [PATCH 14/57] remove trailing whitespace --- scripts/mk_util.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index b0443c808..f8a9f4468 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1415,7 +1415,7 @@ class MLComponent(Component): fout.close() if VERBOSE: print("Updated '%s'" % ml_meta_out) - + def mk_makefile(self, out): if is_ml_enabled(): @@ -1459,16 +1459,16 @@ class MLComponent(Component): archives = archives + ' ' + os.path.join(sub_dir,m) + '.cma' mls = mls + ' ' + os.path.join(sub_dir, m) + '.ml' - out.write('%s: %s %s\n' % - (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'), - os.path.join(sub_dir, 'z3native_stubs.c'), + out.write('%s: %s %s\n' % + (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'), + os.path.join(sub_dir, 'z3native_stubs.c'), get_component(Z3_DLL_COMPONENT).dll_name+'$(SO_EXT)')); - out.write('\t$(CC) $(CXXFLAGS_OCAML) -I %s -I %s %s $(CXX_OUT_FLAG)%s$(OBJ_EXT)\n' % + out.write('\t$(CC) $(CXXFLAGS_OCAML) -I %s -I %s %s $(CXX_OUT_FLAG)%s$(OBJ_EXT)\n' % (OCAML_LIB, api_src, os.path.join(sub_dir, 'z3native_stubs.c'), os.path.join(sub_dir, 'z3native_stubs'))) out.write('%s: %s %s %s$(SO_EXT)' % ( - os.path.join(sub_dir, "z3ml.cmxa"), - cmis, + os.path.join(sub_dir, "z3ml.cmxa"), + cmis, archives, get_component(Z3_DLL_COMPONENT).dll_name)) out.write(' %s\n' % (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'))) @@ -1507,7 +1507,7 @@ class MLComponent(Component): out.write(' ' + get_component(Z3_DLL_COMPONENT).dll_name + '$(LIB_EXT)') out.write('\n\n') - + def main_component(self): return is_ml_enabled() @@ -1631,7 +1631,7 @@ class MLExampleComponent(ExampleComponent): if ML_ENABLED: out.write('ml_example.byte: api/ml/z3ml.cmxa ') for mlfile in get_ml_files(self.ex_dir): - out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) + out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) out.write('\n') out.write('\t%s ' % OCAMLC) if DEBUG_MODE: @@ -1642,7 +1642,7 @@ class MLExampleComponent(ExampleComponent): out.write('\n') out.write('ml_example$(EXE_EXT): api/ml/z3ml.cmxa ml_example.byte') for mlfile in get_ml_files(self.ex_dir): - out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) + out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) out.write('\n') out.write('\t%s ' % OCAMLOPT) if DEBUG_MODE: @@ -1803,7 +1803,7 @@ def mk_config(): if is_verbose(): print('64-bit: %s' % is64()) print('OpenMP: %s' % HAS_OMP) - if is_java_enabled(): + if is_java_enabled(): print('JNI Bindings: %s' % JNI_HOME) print('Java Compiler: %s' % JAVAC) if is_ml_enabled(): @@ -1927,10 +1927,10 @@ def mk_config(): print('OpenMP: %s' % HAS_OMP) print('Prefix: %s' % PREFIX) print('64-bit: %s' % is64()) - print('FP math: %s' % FPMATH) + print('FP math: %s' % FPMATH) if GPROF: print('gprof: enabled') - print('Python version: %s' % distutils.sysconfig.get_python_version()) + print('Python version: %s' % distutils.sysconfig.get_python_version()) if is_java_enabled(): print('JNI Bindings: %s' % JNI_HOME) print('Java Compiler: %s' % JAVAC) @@ -2819,7 +2819,7 @@ def mk_z3consts_ml(api_files): m2 = comment_pat.match(line) if m1 or m2: # skip blank lines and comments - linenum = linenum + 1 + linenum = linenum + 1 elif mode == SEARCHING: m = typedef_pat.match(line) if m: @@ -2897,7 +2897,7 @@ def mk_z3consts_ml(api_files): m2 = comment_pat.match(line) if m1 or m2: # skip blank lines and comments - linenum = linenum + 1 + linenum = linenum + 1 elif mode == SEARCHING: m = typedef_pat.match(line) if m: From 024923526baec3343d70da9cfa04a5bc1c0f7c35 Mon Sep 17 00:00:00 2001 From: Kevin Borgolte Date: Tue, 5 May 2015 11:31:32 -0700 Subject: [PATCH 15/57] remove unused modules --- scripts/mk_util.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index f8a9f4468..c98f44fa6 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -8,7 +8,6 @@ ############################################ import sys import os -import glob import re import getopt import shutil @@ -17,7 +16,6 @@ from fnmatch import fnmatch import distutils.sysconfig import compileall import subprocess -import string def getenv(name, default): try: From 8b9bf9ea9014f68c01bfd17ab8f9333e834216a1 Mon Sep 17 00:00:00 2001 From: Yan Date: Tue, 5 May 2015 11:38:04 -0700 Subject: [PATCH 16/57] Fix mk_util.py so that it explicitly closes files (instead of relying on reference counting, which doesn't exist in pypy) --- scripts/mk_util.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 72d432eab..ef28155da 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -180,6 +180,8 @@ def exec_cmd(cmd): except: # Failed to create process return 1 + finally: + null.close() # rm -f fname def rmf(fname): @@ -351,6 +353,7 @@ def check_java(): q = os.path.dirname(libdir) if cdirs.count(q) == 0: cdirs.append(q) + t.close() # ... plus some heuristic ones. extra_dirs = [] @@ -417,6 +420,9 @@ def find_ml_lib(): t.commit() except: raise MKException('Failed to find Ocaml library; please set OCAML_LIB') + finally: + null.close() + t = open('output', 'r') for line in t: OCAML_LIB = line[:-1] @@ -475,6 +481,7 @@ def is_cr_lf(fname): # Check whether text files use cr/lf f = open(fname, 'r') line = f.readline() + f.close() sz = len(line) return sz >= 2 and line[sz-2] == '\r' and line[sz-1] == '\n' @@ -663,6 +670,7 @@ def extract_c_includes(fname): elif not system_inc_pat.match(line) and non_std_inc_pat.match(line): raise MKException("Invalid #include directive at '%s':%s" % (fname, line)) linenum = linenum + 1 + f.close() return result @@ -1939,6 +1947,8 @@ def mk_config(): print('OCaml Native: %s' % OCAMLOPT) print('OCaml Library: %s' % OCAML_LIB) + config.close() + def mk_install(out): out.write('install: ') for c in get_components(): @@ -2012,6 +2022,7 @@ def mk_makefile(): if not IS_WINDOWS: mk_install(out) mk_uninstall(out) + out.close() # Finalize if VERBOSE: print("Makefile was successfully generated.") @@ -2125,6 +2136,7 @@ def def_module_params(module_name, export, params, class_name=None, description= (TYPE2CTYPE[param[1]], to_c_method(param[0]), TYPE2GETTER[param[1]], param[0], pyg_default_as_c_literal(param))) out.write('};\n') out.write('#endif\n') + out.close() if is_verbose(): print("Generated '%s'" % hpp) @@ -2167,6 +2179,8 @@ def mk_pat_db(): for line in fin: fout.write('"%s\\n"\n' % line.strip('\n')) fout.write(';\n') + fin.close() + fout.close() if VERBOSE: print("Generated '%s'" % os.path.join(c.src_dir, 'database.h')) @@ -2192,6 +2206,7 @@ def mk_version_dot_h(major, minor, build, revision): fout.write('#define Z3_MINOR_VERSION %s\n' % minor) fout.write('#define Z3_BUILD_NUMBER %s\n' % build) fout.write('#define Z3_REVISION_NUMBER %s\n' % revision) + fout.close() if VERBOSE: print("Generated '%s'" % os.path.join(c.src_dir, 'version.h')) @@ -2283,6 +2298,7 @@ def mk_install_tactic_cpp(cnames, path): exec(line.strip('\n '), globals()) except: raise MKException("Failed processing ADD_PROBE command at '%s'\n%s" % (fullname, line)) + fin.close() # First pass will just generate the tactic factories idx = 0 for data in ADD_TACTIC_DATA: @@ -2298,6 +2314,7 @@ def mk_install_tactic_cpp(cnames, path): for data in ADD_PROBE_DATA: fout.write(' ADD_PROBE("%s", "%s", %s);\n' % data) fout.write('}\n') + fout.close() if VERBOSE: print("Generated '%s'" % fullname) @@ -2350,6 +2367,7 @@ def mk_mem_initializer_cpp(cnames, path): added_include = True fout.write('#include"%s"\n' % h_file) finalizer_cmds.append(m.group(1)) + fin.close() initializer_cmds.sort(key=lambda tup: tup[1]) fout.write('void mem_initialize() {\n') for (cmd, prio) in initializer_cmds: @@ -2361,6 +2379,7 @@ def mk_mem_initializer_cpp(cnames, path): fout.write(cmd) fout.write('\n') fout.write('}\n') + fout.close() if VERBOSE: print("Generated '%s'" % fullname) @@ -2410,6 +2429,7 @@ def mk_gparams_register_modules(cnames, path): m = reg_mod_descr_pat.match(line) if m: mod_descrs.append((m.group(1), m.group(2))) + fin.close() fout.write('void gparams_register_modules() {\n') for code in cmds: fout.write('{ param_descrs d; %s(d); gparams::register_global(d); }\n' % code) @@ -2418,6 +2438,7 @@ def mk_gparams_register_modules(cnames, path): for (mod, descr) in mod_descrs: fout.write('gparams::register_module_descr("%s", "%s");\n' % (mod, descr)) fout.write('}\n') + fout.close() if VERBOSE: print("Generated '%s'" % fullname) @@ -2451,6 +2472,8 @@ def mk_def_file(c): fout.write('\t%s @%s\n' % (f, num)) i = i + 1 num = num + 1 + api.close() + fout.close() if VERBOSE: print("Generated '%s'" % defname) @@ -2585,6 +2608,8 @@ def mk_z3consts_py(api_files): decls[words[1]] = idx idx = idx + 1 linenum = linenum + 1 + api.close() + z3consts.close() if VERBOSE: print("Generated '%s'" % os.path.join(Z3PY_SRC_DIR, 'z3consts.py')) @@ -2670,7 +2695,9 @@ def mk_z3consts_dotnet(api_files): decls[words[1]] = idx idx = idx + 1 linenum = linenum + 1 + api.close() z3consts.write('}\n'); + z3consts.close() if VERBOSE: print("Generated '%s'" % os.path.join(dotnet.src_dir, 'Enumerations.cs')) @@ -2777,6 +2804,7 @@ def mk_z3consts_java(api_files): decls[words[1]] = idx idx = idx + 1 linenum = linenum + 1 + api.close() if VERBOSE: print("Generated '%s'" % ('%s' % gendir)) @@ -2872,6 +2900,8 @@ def mk_z3consts_ml(api_files): decls[words[1]] = idx idx = idx + 1 linenum = linenum + 1 + api.close() + efile.close() if VERBOSE: print ('Generated "%s/z3enums.ml"' % ('%s' % gendir)) efile = open('%s.mli' % os.path.join(gendir, "z3enums"), 'w') @@ -2942,6 +2972,8 @@ def mk_z3consts_ml(api_files): decls[words[1]] = idx idx = idx + 1 linenum = linenum + 1 + api.close() + efile.close() if VERBOSE: print ('Generated "%s/z3enums.mli"' % ('%s' % gendir)) @@ -3078,6 +3110,7 @@ def mk_vs_proj(name, components): f.write(' \n') f.write(' \n') f.write('\n') + f.close() if is_verbose(): print("Generated '%s'" % proj_name) From 64b46f23100c88b1d7755bcb611f7b64399b5ce5 Mon Sep 17 00:00:00 2001 From: John Grosen Date: Mon, 25 May 2015 00:31:04 -0700 Subject: [PATCH 17/57] Fix the Python FPRef.__lt__ implementation --- src/api/python/z3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/python/z3.py b/src/api/python/z3.py index 16d2eb6ba..1f1fc3604 100644 --- a/src/api/python/z3.py +++ b/src/api/python/z3.py @@ -7808,7 +7808,7 @@ class FPRef(ExprRef): return fpLEQ(self, other) def __lt__(self, other): - return fpLEQ(self, other) + return fpLT(self, other) def __ge__(self, other): return fpGEQ(self, other) From 68c086c5896cd496c83956b3b1211287dab1c455 Mon Sep 17 00:00:00 2001 From: vhalros Date: Fri, 24 Jul 2015 15:24:23 -0400 Subject: [PATCH 18/57] Added default operator to array interface. --- src/api/python/z3.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/api/python/z3.py b/src/api/python/z3.py index ce1cc2103..34e1d2645 100644 --- a/src/api/python/z3.py +++ b/src/api/python/z3.py @@ -3906,6 +3906,12 @@ class ArrayRef(ExprRef): arg = self.domain().cast(arg) return _to_expr_ref(Z3_mk_select(self.ctx_ref(), self.as_ast(), arg.as_ast()), self.ctx) + def default(self): + return _to_expr_ref(Z3_mk_array_default(self.ctx_ref(), self.as_ast()), self.ctx) + + + + def is_array(a): """Return `True` if `a` is a Z3 array expression. From ab88708f9a7fa50387d1fc07d616c403521c44c8 Mon Sep 17 00:00:00 2001 From: Dmitriy Trubenkov <403rus@gmail.com> Date: Sat, 25 Jul 2015 20:22:15 +0300 Subject: [PATCH 19/57] Remove extra semicolons in C++ headers. Useful for projects builded with -Wpedantic --- src/api/c++/z3++.h | 2 +- src/api/z3_algebraic.h | 2 +- src/api/z3_api.h | 2 +- src/api/z3_fpa.h | 2 +- src/api/z3_interp.h | 2 +- src/api/z3_polynomial.h | 2 +- src/api/z3_rcf.h | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/api/c++/z3++.h b/src/api/c++/z3++.h index a5d943e95..47a57d67b 100644 --- a/src/api/c++/z3++.h +++ b/src/api/c++/z3++.h @@ -1911,7 +1911,7 @@ namespace z3 { -}; +} /*@}*/ /*@}*/ diff --git a/src/api/z3_algebraic.h b/src/api/z3_algebraic.h index 5e4762551..42a5fc460 100644 --- a/src/api/z3_algebraic.h +++ b/src/api/z3_algebraic.h @@ -234,7 +234,7 @@ extern "C" { /*@}*/ #ifdef __cplusplus -}; +} #endif // __cplusplus #endif diff --git a/src/api/z3_api.h b/src/api/z3_api.h index a646f93ca..7953200dc 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -8107,7 +8107,7 @@ END_MLAPI_EXCLUDE #ifndef CAMLIDL #ifdef __cplusplus -}; +} #endif // __cplusplus #else } diff --git a/src/api/z3_fpa.h b/src/api/z3_fpa.h index b29534621..ee23c7b5d 100644 --- a/src/api/z3_fpa.h +++ b/src/api/z3_fpa.h @@ -935,7 +935,7 @@ extern "C" { /*@}*/ #ifdef __cplusplus -}; +} #endif // __cplusplus #endif diff --git a/src/api/z3_interp.h b/src/api/z3_interp.h index d775ff3ba..84df7a874 100644 --- a/src/api/z3_interp.h +++ b/src/api/z3_interp.h @@ -287,7 +287,7 @@ extern "C" { /*@}*/ #ifdef __cplusplus -}; +} #endif // __cplusplus #endif diff --git a/src/api/z3_polynomial.h b/src/api/z3_polynomial.h index f3e40b3b2..06c492acf 100644 --- a/src/api/z3_polynomial.h +++ b/src/api/z3_polynomial.h @@ -55,7 +55,7 @@ extern "C" { /*@}*/ #ifdef __cplusplus -}; +} #endif // __cplusplus #endif diff --git a/src/api/z3_rcf.h b/src/api/z3_rcf.h index 10903750f..1736b0eba 100644 --- a/src/api/z3_rcf.h +++ b/src/api/z3_rcf.h @@ -208,7 +208,7 @@ extern "C" { /*@}*/ #ifdef __cplusplus -}; +} #endif // __cplusplus #endif From eca2488ab4d7891e17176d5df028c50abf50b627 Mon Sep 17 00:00:00 2001 From: Zachary Kincaid Date: Sun, 26 Jul 2015 19:59:17 -0400 Subject: [PATCH 20/57] If ocamlfind is installed, add destdir/stublibs to rpath --- scripts/mk_util.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index cff98818f..ee2fefb43 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1478,6 +1478,28 @@ class MLComponent(Component): get_component(Z3_DLL_COMPONENT).dll_name)) out.write(' %s\n' % (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'))) out.write('\tocamlmklib -o %s -I %s -ldopt \"-L. -lz3\" ' % (os.path.join(sub_dir, 'z3ml'), sub_dir)) + + # Add ocamlfind destdir to rpath + if OCAMLFIND != '': + if is_verbose(): + print ("Finding ocamlfind destdir") + t = TempFile('output') + null = open(os.devnull, 'wb') + try: + subprocess.call([OCAMLFIND, 'printconf', 'destdir'], stdout=t.fname, stderr=null) + t.commit() + except: + raise MKException('Failed to find Ocamlfind destdir') + t = open('output', 'r') + for line in t: + ocamlfind_destdir = line[:-1] + if is_verbose(): + print ('ocamlfind destdir=%s' % ocamlfind_destdir) + t.close() + rmf('output') + out.write("-rpath %s " % os.path.join(ocamlfind_destdir, 'stublibs')) + out.write("-L%s" % os.path.join(ocamlfind_destdir, 'stublibs')) + for m in modules: out.write(' %s' % (os.path.join(sub_dir, m+'.ml'))) out.write(' %s\n' % (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'))) From 6214ba900b11822b35002978c7d309446007aef2 Mon Sep 17 00:00:00 2001 From: Zachary Kincaid Date: Sun, 26 Jul 2015 21:17:59 -0400 Subject: [PATCH 21/57] Z3_lbool should be signed in API --- src/api/z3_api.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/z3_api.h b/src/api/z3_api.h index a646f93ca..42e0bad27 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -4237,7 +4237,7 @@ END_MLAPI_EXCLUDE /** \brief Return Z3_L_TRUE if \c a is true, Z3_L_FALSE if it is false, and Z3_L_UNDEF otherwise. - def_API('Z3_get_bool_value', UINT, (_in(CONTEXT), _in(AST))) + def_API('Z3_get_bool_value', INT, (_in(CONTEXT), _in(AST))) */ Z3_lbool Z3_API Z3_get_bool_value(Z3_context c, Z3_ast a); @@ -7578,7 +7578,7 @@ END_MLAPI_EXCLUDE \deprecated To be moved outside of API. - def_API('Z3_get_implied_equalities', UINT, (_in(CONTEXT), _in(SOLVER), _in(UINT), _in_array(2, AST), _out_array(2, UINT))) + def_API('Z3_get_implied_equalities', INT, (_in(CONTEXT), _in(SOLVER), _in(UINT), _in_array(2, AST), _out_array(2, UINT))) */ Z3_lbool Z3_API Z3_get_implied_equalities( Z3_context c, From cef7ec2157afc882f0e2cc4883b527be39aea7b2 Mon Sep 17 00:00:00 2001 From: Guang Chen Date: Sun, 13 Sep 2015 13:25:01 +0800 Subject: [PATCH 22/57] fix implies(expr const &, expr const &) in z3++.h --- src/api/c++/z3++.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/api/c++/z3++.h b/src/api/c++/z3++.h index f43ba83e5..9a340698a 100644 --- a/src/api/c++/z3++.h +++ b/src/api/c++/z3++.h @@ -642,13 +642,7 @@ namespace z3 { */ friend expr operator||(bool a, expr const & b) { return b.ctx().bool_val(a) || b; } - friend expr implies(expr const & a, expr const & b) { - check_context(a, b); - assert(a.is_bool() && b.is_bool()); - Z3_ast r = Z3_mk_implies(a.ctx(), a, b); - a.check_error(); - return expr(a.ctx(), r); - } + friend expr implies(expr const & a, expr const & b); friend expr implies(expr const & a, bool b); friend expr implies(bool a, expr const & b); @@ -891,6 +885,13 @@ namespace z3 { }; + inline expr implies(expr const & a, expr const & b) { + check_context(a, b); + assert(a.is_bool() && b.is_bool()); + Z3_ast r = Z3_mk_implies(a.ctx(), a, b); + a.check_error(); + return expr(a.ctx(), r); + } inline expr implies(expr const & a, bool b) { return implies(a, a.ctx().bool_val(b)); } inline expr implies(bool a, expr const & b) { return implies(b.ctx().bool_val(a), b); } From 9e34872e8f79c52a6f35ed5fa945bf6a6aa5f755 Mon Sep 17 00:00:00 2001 From: Zachary Kincaid Date: Sun, 4 Oct 2015 10:10:53 -0400 Subject: [PATCH 23/57] For ocamlfind install, set rpath to package directory if stublibs does not exist --- scripts/mk_util.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index ee2fefb43..33b79bba5 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1497,8 +1497,13 @@ class MLComponent(Component): print ('ocamlfind destdir=%s' % ocamlfind_destdir) t.close() rmf('output') - out.write("-rpath %s " % os.path.join(ocamlfind_destdir, 'stublibs')) - out.write("-L%s" % os.path.join(ocamlfind_destdir, 'stublibs')) + # DLLs are installed into stublibs if it exists, Z3 if not + if os.path.exists(os.path.join(ocamlfind_destdir, 'stublibs')): + dll_path = os.path.join(ocamlfind_destdir, 'stublibs') + else: + dll_path = os.path.join(ocamlfind_destdir, 'Z3') + out.write("-rpath %s " % dll_path) + out.write("-L%s" % dll_path) for m in modules: out.write(' %s' % (os.path.join(sub_dir, m+'.ml'))) From 99e4b321bdcc334f206f3d7a12c471bd5dafb0b5 Mon Sep 17 00:00:00 2001 From: martin-neuhaeusser Date: Wed, 7 Oct 2015 17:27:05 +0200 Subject: [PATCH 24/57] Fixed typo that accidentally prints warning message if a Z3 context is created with the 'timeout' parameter --- src/cmd_context/context_params.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmd_context/context_params.cpp b/src/cmd_context/context_params.cpp index add1b5b3d..30b5a7c4b 100644 --- a/src/cmd_context/context_params.cpp +++ b/src/cmd_context/context_params.cpp @@ -66,7 +66,7 @@ void context_params::set(char const * param, char const * value) { long val = strtol(value, 0, 10); m_timeout = static_cast(val); } - if (p == "rlimit") { + else if (p == "rlimit") { long val = strtol(value, 0, 10); m_rlimit = static_cast(val); } From a2503af585666cf7207d7f918ee9e9e057634c0f Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 8 Oct 2015 11:54:35 +0100 Subject: [PATCH 25/57] Bugfixes for UFs and conversion functions in theory_fpa --- src/ast/fpa/fpa2bv_rewriter.h | 2 +- src/smt/theory_fpa.cpp | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/ast/fpa/fpa2bv_rewriter.h b/src/ast/fpa/fpa2bv_rewriter.h index 69c9a6290..2727a8e73 100644 --- a/src/ast/fpa/fpa2bv_rewriter.h +++ b/src/ast/fpa/fpa2bv_rewriter.h @@ -185,7 +185,7 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { bool is_float_uf = m_conv.is_float(f->get_range()) || m_conv.is_rm(f->get_range()); for (unsigned i = 0; i < num; i++) - is_float_uf |= m_conv.is_float(f->get_domain()[i]) || m_conv.is_rm(f->get_domain()[i]); + is_float_uf |= m_conv.is_float(args[i]) || m_conv.is_rm(args[i]); if (is_float_uf) { diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index 0fadc62ca..46c9d962d 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -652,10 +652,8 @@ namespace smt { if (fu.is_float(xe) && fu.is_float(ye)) m_converter.mk_eq(xc, yc, c); - else if (fu.is_rm(xe) && fu.is_rm(ye)) + else c = m.mk_eq(xc, yc); - else - UNREACHABLE(); m_th_rw(c); assert_cnstr(m.mk_iff(m.mk_eq(xe, ye), c)); @@ -692,10 +690,8 @@ namespace smt { m_converter.mk_eq(xc, yc, c); c = m.mk_not(c); } - else if (fu.is_rm(xe) && fu.is_rm(ye)) - c = m.mk_not(m.mk_eq(xc, yc)); else - UNREACHABLE(); + c = m.mk_not(m.mk_eq(xc, yc)); m_th_rw(c); assert_cnstr(m.mk_iff(m.mk_not(m.mk_eq(xe, ye)), c)); From c787ea1a3baf001595f533d98f37318778a7adb7 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 8 Oct 2015 12:45:26 +0100 Subject: [PATCH 26/57] Bugfix for FP UFs. --- src/ast/fpa/fpa2bv_converter.h | 2 +- src/ast/fpa/fpa2bv_rewriter.h | 45 +++++++++++++++++----------------- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index 819216bd0..d17a6f770 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -68,7 +68,7 @@ public: bool is_float(sort * s) { return m_util.is_float(s); } bool is_float(expr * e) { return is_app(e) && m_util.is_float(to_app(e)->get_decl()->get_range()); } - bool is_rm(expr * e) { return m_util.is_rm(e); } + bool is_rm(expr * e) { return is_app(e) && m_util.is_rm(e); } bool is_rm(sort * s) { return m_util.is_rm(s); } bool is_float_family(func_decl * f) { return f->get_family_id() == m_util.get_family_id(); } diff --git a/src/ast/fpa/fpa2bv_rewriter.h b/src/ast/fpa/fpa2bv_rewriter.h index 2727a8e73..0fdd50874 100644 --- a/src/ast/fpa/fpa2bv_rewriter.h +++ b/src/ast/fpa/fpa2bv_rewriter.h @@ -79,16 +79,29 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) { TRACE("fpa2bv_rw", tout << "APP: " << f->get_name() << std::endl; ); - if (num == 0 && f->get_family_id() == null_family_id && m_conv.is_float(f->get_range())) { - m_conv.mk_const(f, result); - return BR_DONE; + if (f->get_family_id() == null_family_id) { + if (num == 0) { + if (m_conv.is_float(f->get_range())) + m_conv.mk_const(f, result); + else if (m_conv.is_rm(f->get_range())) + m_conv.mk_rm_const(f, result); + return BR_DONE; + } + else { + bool is_float_uf = m_conv.is_float(f->get_range()) || m_conv.is_rm(f->get_range()); + + for (unsigned i = 0; i < f->get_arity(); i++) { + sort * di = f->get_domain()[i]; + is_float_uf |= m_conv.is_float(di) || m_conv.is_rm(di); + } + + if (is_float_uf) + m_conv.mk_uninterpreted_function(f, num, args, result); + + return BR_DONE; + } } - - if (num == 0 && f->get_family_id() == null_family_id && m_conv.is_rm(f->get_range())) { - m_conv.mk_rm_const(f, result); - return BR_DONE; - } - + if (m().is_eq(f)) { SASSERT(num == 2); TRACE("fpa2bv_rw", tout << "(= " << mk_ismt2_pp(args[0], m()) << " " << @@ -180,20 +193,6 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { } } - if (f->get_family_id() != 0 && f->get_family_id() != m_conv.fu().get_family_id()) - { - bool is_float_uf = m_conv.is_float(f->get_range()) || m_conv.is_rm(f->get_range()); - - for (unsigned i = 0; i < num; i++) - is_float_uf |= m_conv.is_float(args[i]) || m_conv.is_rm(args[i]); - - if (is_float_uf) - { - m_conv.mk_uninterpreted_function(f, num, args, result); - return BR_DONE; - } - } - return BR_FAILED; } From 883514c19577b0f356dfb0c72202de629e1f2ed0 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 8 Oct 2015 14:14:39 +0100 Subject: [PATCH 27/57] Bugfix for FPA UFs --- src/ast/fpa/fpa2bv_rewriter.h | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/ast/fpa/fpa2bv_rewriter.h b/src/ast/fpa/fpa2bv_rewriter.h index 0fdd50874..41b6c0ca9 100644 --- a/src/ast/fpa/fpa2bv_rewriter.h +++ b/src/ast/fpa/fpa2bv_rewriter.h @@ -81,11 +81,16 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { if (f->get_family_id() == null_family_id) { if (num == 0) { - if (m_conv.is_float(f->get_range())) + if (m_conv.is_float(f->get_range())) { m_conv.mk_const(f, result); - else if (m_conv.is_rm(f->get_range())) + return BR_DONE; + } + else if (m_conv.is_rm(f->get_range())) { m_conv.mk_rm_const(f, result); - return BR_DONE; + return BR_DONE; + } + else + return BR_FAILED; } else { bool is_float_uf = m_conv.is_float(f->get_range()) || m_conv.is_rm(f->get_range()); @@ -95,11 +100,13 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { is_float_uf |= m_conv.is_float(di) || m_conv.is_rm(di); } - if (is_float_uf) + if (is_float_uf) { m_conv.mk_uninterpreted_function(f, num, args, result); - - return BR_DONE; - } + return BR_DONE; + } + else + return BR_FAILED; + } } if (m().is_eq(f)) { From a951ff076976587dcadfd863ca779c0c215cc8b7 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 8 Oct 2015 16:04:17 +0100 Subject: [PATCH 28/57] Fix for FP UFs and conversion functions. --- src/ast/fpa/fpa2bv_rewriter.h | 52 ++++++++++++++++------------------- src/smt/theory_fpa.cpp | 22 +++++++++++---- 2 files changed, 40 insertions(+), 34 deletions(-) diff --git a/src/ast/fpa/fpa2bv_rewriter.h b/src/ast/fpa/fpa2bv_rewriter.h index 41b6c0ca9..1b7d55173 100644 --- a/src/ast/fpa/fpa2bv_rewriter.h +++ b/src/ast/fpa/fpa2bv_rewriter.h @@ -79,36 +79,16 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) { TRACE("fpa2bv_rw", tout << "APP: " << f->get_name() << std::endl; ); - if (f->get_family_id() == null_family_id) { - if (num == 0) { - if (m_conv.is_float(f->get_range())) { - m_conv.mk_const(f, result); - return BR_DONE; - } - else if (m_conv.is_rm(f->get_range())) { - m_conv.mk_rm_const(f, result); - return BR_DONE; - } - else - return BR_FAILED; - } - else { - bool is_float_uf = m_conv.is_float(f->get_range()) || m_conv.is_rm(f->get_range()); - - for (unsigned i = 0; i < f->get_arity(); i++) { - sort * di = f->get_domain()[i]; - is_float_uf |= m_conv.is_float(di) || m_conv.is_rm(di); - } - - if (is_float_uf) { - m_conv.mk_uninterpreted_function(f, num, args, result); - return BR_DONE; - } - else - return BR_FAILED; - } + if (num == 0 && f->get_family_id() == null_family_id && m_conv.is_float(f->get_range())) { + m_conv.mk_const(f, result); + return BR_DONE; } - + + if (num == 0 && f->get_family_id() == null_family_id && m_conv.is_rm(f->get_range())) { + m_conv.mk_rm_const(f, result); + return BR_DONE; + } + if (m().is_eq(f)) { SASSERT(num == 2); TRACE("fpa2bv_rw", tout << "(= " << mk_ismt2_pp(args[0], m()) << " " << @@ -199,6 +179,20 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { NOT_IMPLEMENTED_YET(); } } + else { + SASSERT(!m_conv.is_float_family(f)); + bool is_float_uf = m_conv.is_float(f->get_range()) || m_conv.is_rm(f->get_range()); + + for (unsigned i = 0; i < f->get_arity(); i++) { + sort * di = f->get_domain()[i]; + is_float_uf |= m_conv.is_float(di) || m_conv.is_rm(di); + } + + if (is_float_uf) { + m_conv.mk_uninterpreted_function(f, num, args, result); + return BR_DONE; + } + } return BR_FAILED; } diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index 46c9d962d..cf6a367a9 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -331,8 +331,21 @@ namespace smt { proof_ref pr(m); m_rw(e, e_conv); - if (is_app(e_conv) && to_app(e_conv)->get_family_id() != get_family_id()) { - m_th_rw(e_conv, res); + if (is_app(e_conv) && to_app(e_conv)->get_family_id() != get_family_id()) { + if (!m_fpa_util.is_float(e_conv)) + m_th_rw(e_conv, res); + else { + expr_ref bv(m); + bv = wrap(e_conv); + unsigned bv_sz = m_bv_util.get_bv_size(bv); + unsigned ebits = m_fpa_util.get_ebits(m.get_sort(e_conv)); + unsigned sbits = m_fpa_util.get_sbits(m.get_sort(e_conv)); + SASSERT(bv_sz == ebits + sbits); + m_converter.mk_fp(m_bv_util.mk_extract(bv_sz - 1, bv_sz - 1, bv), + m_bv_util.mk_extract(bv_sz - 2, sbits - 1, bv), + m_bv_util.mk_extract(sbits - 2, 0, bv), + res); + } } else if (m_fpa_util.is_rm(e)) { SASSERT(is_sort_of(m.get_sort(e_conv), m_bv_util.get_family_id(), BV_SORT)); @@ -464,7 +477,7 @@ namespace smt { else if (m_fpa_util.is_float(e) || m_fpa_util.is_rm(e)) res = convert_term(e); else if (m_arith_util.is_real(e) || m_bv_util.is_bv(e)) - res = convert_conversion_term(e); + res = convert_conversion_term(e); else UNREACHABLE(); @@ -643,13 +656,12 @@ namespace smt { expr_ref xc(m), yc(m); xc = convert(xe); yc = convert(ye); - TRACE("t_fpa_detail", tout << "xc = " << mk_ismt2_pp(xc, m) << std::endl << "yc = " << mk_ismt2_pp(yc, m) << std::endl;); expr_ref c(m); - + if (fu.is_float(xe) && fu.is_float(ye)) m_converter.mk_eq(xc, yc, c); else From 0e387b2abe65d8ee9d30687474d647fe983d7a2f Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Fri, 9 Oct 2015 18:06:49 +0100 Subject: [PATCH 29/57] use Z3_fallthrough instead of __falthrough directly to avoid messing with reserved identifiers Signed-off-by: Nuno Lopes --- src/ast/ast.cpp | 2 +- src/ast/rewriter/bv_rewriter.cpp | 2 +- src/smt/smt_almost_cg_table.cpp | 2 +- src/smt/smt_cg_table.cpp | 2 +- src/util/hash.cpp | 22 +++++++++++----------- src/util/hash.h | 6 +----- src/util/util.h | 16 ++++++++++++---- 7 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 840222e89..111f1df78 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -516,7 +516,7 @@ inline unsigned ast_array_hash(T * const * array, unsigned size, unsigned init_v switch (size) { case 2: b += array[1]->hash(); - __fallthrough; + Z3_fallthrough; case 1: c += array[0]->hash(); } diff --git a/src/ast/rewriter/bv_rewriter.cpp b/src/ast/rewriter/bv_rewriter.cpp index 1115663d2..fd7c60a57 100644 --- a/src/ast/rewriter/bv_rewriter.cpp +++ b/src/ast/rewriter/bv_rewriter.cpp @@ -1500,7 +1500,7 @@ br_status bv_rewriter::mk_bv_xor(unsigned num, expr * const * args, expr_ref & r result = m_util.mk_bv_not(new_args[1]); return BR_DONE; } - __fallthrough; + Z3_fallthrough; default: if (m_bv_sort_ac) std::sort(new_args.begin(), new_args.end(), ast_to_lt()); diff --git a/src/smt/smt_almost_cg_table.cpp b/src/smt/smt_almost_cg_table.cpp index 93f136aad..66eb8c533 100644 --- a/src/smt/smt_almost_cg_table.cpp +++ b/src/smt/smt_almost_cg_table.cpp @@ -67,7 +67,7 @@ namespace smt { switch (num_args) { case 2: b += arg_hash(n, 1); - __fallthrough; + Z3_fallthrough; case 1: c += arg_hash(n, 0); } diff --git a/src/smt/smt_cg_table.cpp b/src/smt/smt_cg_table.cpp index ed36384c1..83d137ff0 100644 --- a/src/smt/smt_cg_table.cpp +++ b/src/smt/smt_cg_table.cpp @@ -127,7 +127,7 @@ namespace smt { switch (i) { case 2: b += n->get_arg(1)->get_root()->hash(); - __fallthrough; + Z3_fallthrough; case 1: c += n->get_arg(0)->get_root()->hash(); } diff --git a/src/util/hash.cpp b/src/util/hash.cpp index bb5ca0a41..42ba3f4da 100644 --- a/src/util/hash.cpp +++ b/src/util/hash.cpp @@ -52,38 +52,38 @@ unsigned string_hash(const char * str, unsigned length, unsigned init_value) { switch(len) { /* all the case statements fall through */ case 11: c+=((unsigned)str[10]<<24); - __fallthrough; + Z3_fallthrough; case 10: c+=((unsigned)str[9]<<16); - __fallthrough; + Z3_fallthrough; case 9 : c+=((unsigned)str[8]<<8); - __fallthrough; + Z3_fallthrough; /* the first byte of c is reserved for the length */ case 8 : b+=((unsigned)str[7]<<24); - __fallthrough; + Z3_fallthrough; case 7 : b+=((unsigned)str[6]<<16); - __fallthrough; + Z3_fallthrough; case 6 : b+=((unsigned)str[5]<<8); - __fallthrough; + Z3_fallthrough; case 5 : b+=str[4]; - __fallthrough; + Z3_fallthrough; case 4 : a+=((unsigned)str[3]<<24); - __fallthrough; + Z3_fallthrough; case 3 : a+=((unsigned)str[2]<<16); - __fallthrough; + Z3_fallthrough; case 2 : a+=((unsigned)str[1]<<8); - __fallthrough; + Z3_fallthrough; case 1 : a+=str[0]; - __fallthrough; + Z3_fallthrough; /* case 0: nothing left to add */ } mix(a,b,c); diff --git a/src/util/hash.h b/src/util/hash.h index 59bc2cc3b..82d343661 100644 --- a/src/util/hash.h +++ b/src/util/hash.h @@ -22,10 +22,6 @@ Revision History: #include #include"util.h" -#ifndef __fallthrough -#define __fallthrough -#endif - #define mix(a,b,c) \ { \ a -= b; a -= c; a ^= (c>>13); \ @@ -116,7 +112,7 @@ unsigned get_composite_hash(Composite app, unsigned n, GetKindHashProc const & k switch (n) { case 2: b += chasher(app, 1); - __fallthrough; + Z3_fallthrough; case 1: c += chasher(app, 0); } diff --git a/src/util/util.h b/src/util/util.h index 2e7e860d7..f97f5c1f9 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -68,6 +68,18 @@ COMPILE_TIME_ASSERT(sizeof(int64) == 8); #define THREAD_LOCAL #endif +#ifdef __fallthrough +# define Z3_fallthrough __fallthrough +#elif defined(__has_cpp_attribute) +# if __has_cpp_attribute(clang::fallthrough) +# define Z3_fallthrough [[clang::fallthrough]] +# else +# define Z3_fallthrough +# endif +#else +# define Z3_fallthrough +#endif + inline bool is_power_of_two(unsigned v) { return !(v & (v - 1)) && v; } /** @@ -273,10 +285,6 @@ bool has_duplicates(const IT & begin, const IT & end) { return false; } -#ifndef __fallthrough -#define __fallthrough -#endif - #ifndef _WINDOWS #ifndef __declspec #define __declspec(X) From f4954e9d7ff40c2199c18bcf4d9a6bd886fefdf1 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Tue, 13 Oct 2015 09:24:02 -0700 Subject: [PATCH 30/57] fix for fixed size rational difference logic Signed-off-by: Nikolaj Bjorner --- src/smt/theory_diff_logic.h | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/smt/theory_diff_logic.h b/src/smt/theory_diff_logic.h index cb86e6679..ed96d050e 100644 --- a/src/smt/theory_diff_logic.h +++ b/src/smt/theory_diff_logic.h @@ -399,7 +399,6 @@ namespace smt { }; struct sidl_ext { - // TODO: It doesn't need to be a rational, but a bignum integer. static const bool m_int_theory = true; typedef s_integer numeral; typedef s_integer fin_numeral; @@ -415,13 +414,11 @@ namespace smt { rdl_ext() : m_epsilon(rational(), true) {} }; - struct srdl_ext { - static const bool m_int_theory = false; - typedef inf_s_integer numeral; - typedef s_integer fin_numeral; - numeral m_epsilon; - srdl_ext() : m_epsilon(s_integer(0),true) {} - }; + // + // there is no s_rational class, so + // instead we use multi-precision rationals. + // + struct srdl_ext : public rdl_ext {}; typedef theory_diff_logic theory_idl; typedef theory_diff_logic theory_fidl; From 6263252bf5b07e81fe97da378b799a018e5221c8 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 14 Oct 2015 12:42:27 +0100 Subject: [PATCH 31/57] Bugfix for concurrent garbage collection in Java API. Relates to #205 and #245 --- src/api/java/Context.java | 45 +++++++++++++++++++++++++------------- src/api/java/Z3Object.java | 8 +++---- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/src/api/java/Context.java b/src/api/java/Context.java index 0955f79ca..7d4afdf71 100644 --- a/src/api/java/Context.java +++ b/src/api/java/Context.java @@ -18,6 +18,7 @@ Notes: package com.microsoft.z3; import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; import com.microsoft.z3.enumerations.Z3_ast_print_mode; @@ -3761,29 +3762,42 @@ public class Context extends IDisposable return m_Optimize_DRQ; } - protected long m_refCount = 0; + protected AtomicInteger m_refCount = new AtomicInteger(0); /** * Finalizer. + * @throws Throwable **/ - protected void finalize() + protected void finalize() throws Throwable { - dispose(); - - if (m_refCount == 0) - { - try + try { + dispose(); + + if (m_refCount.get() == 0) { - Native.delContext(m_ctx); - } catch (Z3Exception e) + try + { + Native.delContext(m_ctx); + } catch (Z3Exception e) + { + // OK. + } + m_ctx = 0; + System.out.println("> disposed OK."); + } + else if (m_refCount.get() < 0) + System.out.println("XXX negative ref count"); + else { - // OK. + System.out.println("XXX context not disposed"); } - m_ctx = 0; - } - /* - else - CMW: re-queue the finalizer? */ + } + catch (Throwable t) { + throw t; + } + finally { + super.finalize(); + } } /** @@ -3791,6 +3805,7 @@ public class Context extends IDisposable **/ public void dispose() { + System.out.println("> context disposing."); m_AST_DRQ.clear(this); m_ASTMap_DRQ.clear(this); m_ASTVector_DRQ.clear(this); diff --git a/src/api/java/Z3Object.java b/src/api/java/Z3Object.java index 877e22cac..c9ed810fa 100644 --- a/src/api/java/Z3Object.java +++ b/src/api/java/Z3Object.java @@ -43,8 +43,8 @@ public class Z3Object extends IDisposable } if (m_ctx != null) - { - m_ctx.m_refCount--; + { + m_ctx.m_refCount.decrementAndGet(); m_ctx = null; } } @@ -54,13 +54,13 @@ public class Z3Object extends IDisposable Z3Object(Context ctx) { - ctx.m_refCount++; + ctx.m_refCount.incrementAndGet(); m_ctx = ctx; } Z3Object(Context ctx, long obj) { - ctx.m_refCount++; + ctx.m_refCount.incrementAndGet(); m_ctx = ctx; incRef(obj); m_n_obj = obj; From e312b47be6365fd9b193a5a6e0acb4d8d7dde93e Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 14 Oct 2015 12:43:09 +0100 Subject: [PATCH 32/57] Bugfix for object finalization in Java API. Relates to #205 and #245 --- src/api/java/AST.java | 15 +++++++-------- src/api/java/Constructor.java | 13 +++++++++++-- src/api/java/ConstructorList.java | 13 +++++++++++-- src/api/java/Z3Object.java | 13 +++++++++++-- 4 files changed, 40 insertions(+), 14 deletions(-) diff --git a/src/api/java/AST.java b/src/api/java/AST.java index 6b5493bf9..dc73c7ae7 100644 --- a/src/api/java/AST.java +++ b/src/api/java/AST.java @@ -33,7 +33,7 @@ public class AST extends Z3Object implements Comparable { AST casted = null; - try + try { casted = AST.class.cast(o); } catch (ClassCastException e) @@ -41,13 +41,12 @@ public class AST extends Z3Object implements Comparable return false; } - return - (this == casted) || - (this != null) && - (casted != null) && - (getContext().nCtx() == casted.getContext().nCtx()) && - (Native.isEqAst(getContext().nCtx(), getNativeObject(), casted.getNativeObject())); -} + return (this == casted) || + (this != null) && + (casted != null) && + (getContext().nCtx() == casted.getContext().nCtx()) && + (Native.isEqAst(getContext().nCtx(), getNativeObject(), casted.getNativeObject())); + } /** * Object Comparison. diff --git a/src/api/java/Constructor.java b/src/api/java/Constructor.java index 2ceaddcff..26b33ed35 100644 --- a/src/api/java/Constructor.java +++ b/src/api/java/Constructor.java @@ -80,11 +80,20 @@ public class Constructor extends Z3Object /** * Destructor. + * @throws Throwable * @throws Z3Exception on error **/ - protected void finalize() + protected void finalize() throws Throwable { - Native.delConstructor(getContext().nCtx(), getNativeObject()); + try { + Native.delConstructor(getContext().nCtx(), getNativeObject()); + } + catch (Throwable t) { + throw t; + } + finally { + super.finalize(); + } } private int n = 0; diff --git a/src/api/java/ConstructorList.java b/src/api/java/ConstructorList.java index 2b3aa94e2..82b119513 100644 --- a/src/api/java/ConstructorList.java +++ b/src/api/java/ConstructorList.java @@ -24,11 +24,20 @@ public class ConstructorList extends Z3Object { /** * Destructor. + * @throws Throwable * @throws Z3Exception on error **/ - protected void finalize() + protected void finalize() throws Throwable { - Native.delConstructorList(getContext().nCtx(), getNativeObject()); + try { + Native.delConstructorList(getContext().nCtx(), getNativeObject()); + } + catch (Throwable t) { + throw t; + } + finally { + super.finalize(); + } } ConstructorList(Context ctx, long obj) diff --git a/src/api/java/Z3Object.java b/src/api/java/Z3Object.java index c9ed810fa..473cb5403 100644 --- a/src/api/java/Z3Object.java +++ b/src/api/java/Z3Object.java @@ -25,10 +25,19 @@ public class Z3Object extends IDisposable { /** * Finalizer. + * @throws Throwable **/ - protected void finalize() + protected void finalize() throws Throwable { - dispose(); + try { + dispose(); + } + catch (Throwable t) { + throw t; + } + finally { + super.finalize(); + } } /** From bae3a76c8ab73ed7ac9d6255a853e9aa26f15792 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 14 Oct 2015 12:52:16 +0100 Subject: [PATCH 33/57] Removed unnecessary debug output. --- src/api/java/Context.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/api/java/Context.java b/src/api/java/Context.java index 7d4afdf71..3897ec50a 100644 --- a/src/api/java/Context.java +++ b/src/api/java/Context.java @@ -3783,14 +3783,7 @@ public class Context extends IDisposable // OK. } m_ctx = 0; - System.out.println("> disposed OK."); } - else if (m_refCount.get() < 0) - System.out.println("XXX negative ref count"); - else - { - System.out.println("XXX context not disposed"); - } } catch (Throwable t) { throw t; From b66f34f0d265a6c0c186f61671e6ece98280b54d Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 14 Oct 2015 12:53:18 +0100 Subject: [PATCH 34/57] Removed unnecessary debug output. --- src/api/java/Context.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/api/java/Context.java b/src/api/java/Context.java index 3897ec50a..8b7157181 100644 --- a/src/api/java/Context.java +++ b/src/api/java/Context.java @@ -3798,7 +3798,6 @@ public class Context extends IDisposable **/ public void dispose() { - System.out.println("> context disposing."); m_AST_DRQ.clear(this); m_ASTMap_DRQ.clear(this); m_ASTVector_DRQ.clear(this); From 24532474a04ef079ab423efb7e2579990985e538 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 14 Oct 2015 13:58:51 +0100 Subject: [PATCH 35/57] Bugfix for concurrent Context creation in Java and .NET. Relates to #205 #245 --- src/api/dotnet/Context.cs | 23 +++++++++++++++-------- src/api/java/Context.java | 25 +++++++++++++++---------- src/api/java/InterpolationContext.java | 22 ++++++++++++++-------- 3 files changed, 44 insertions(+), 26 deletions(-) diff --git a/src/api/dotnet/Context.cs b/src/api/dotnet/Context.cs index 0aee3f7d8..df502f115 100644 --- a/src/api/dotnet/Context.cs +++ b/src/api/dotnet/Context.cs @@ -37,8 +37,11 @@ namespace Microsoft.Z3 public Context() : base() { - m_ctx = Native.Z3_mk_context_rc(IntPtr.Zero); - InitContext(); + lock (creation_lock) + { + m_ctx = Native.Z3_mk_context_rc(IntPtr.Zero); + InitContext(); + } } /// @@ -64,12 +67,15 @@ namespace Microsoft.Z3 { Contract.Requires(settings != null); - IntPtr cfg = Native.Z3_mk_config(); - foreach (KeyValuePair kv in settings) - Native.Z3_set_param_value(cfg, kv.Key, kv.Value); - m_ctx = Native.Z3_mk_context_rc(cfg); - Native.Z3_del_config(cfg); - InitContext(); + lock (creation_lock) + { + IntPtr cfg = Native.Z3_mk_config(); + foreach (KeyValuePair kv in settings) + Native.Z3_set_param_value(cfg, kv.Key, kv.Value); + m_ctx = Native.Z3_mk_context_rc(cfg); + Native.Z3_del_config(cfg); + InitContext(); + } } #endregion @@ -4381,6 +4387,7 @@ namespace Microsoft.Z3 #region Internal internal IntPtr m_ctx = IntPtr.Zero; internal Native.Z3_error_handler m_n_err_handler = null; + internal static Object creation_lock = new Object(); internal IntPtr nCtx { get { return m_ctx; } } internal void NativeErrorHandler(IntPtr ctx, Z3_error_code errorCode) diff --git a/src/api/java/Context.java b/src/api/java/Context.java index 0955f79ca..9f20f121d 100644 --- a/src/api/java/Context.java +++ b/src/api/java/Context.java @@ -30,10 +30,12 @@ public class Context extends IDisposable * Constructor. **/ public Context() - { + { super(); - m_ctx = Native.mkContextRc(0); - initContext(); + synchronized (creation_lock) { + m_ctx = Native.mkContextRc(0); + initContext(); + } } /** @@ -56,12 +58,14 @@ public class Context extends IDisposable public Context(Map settings) { super(); - long cfg = Native.mkConfig(); - for (Map.Entry kv : settings.entrySet()) - Native.setParamValue(cfg, kv.getKey(), kv.getValue()); - m_ctx = Native.mkContextRc(cfg); - Native.delConfig(cfg); - initContext(); + synchronized (creation_lock) { + long cfg = Native.mkConfig(); + for (Map.Entry kv : settings.entrySet()) + Native.setParamValue(cfg, kv.getKey(), kv.getValue()); + m_ctx = Native.mkContextRc(cfg); + Native.delConfig(cfg); + initContext(); + } } /** @@ -3638,7 +3642,8 @@ public class Context extends IDisposable Native.updateParamValue(nCtx(), id, value); } - long m_ctx = 0; + protected long m_ctx = 0; + protected static Object creation_lock = new Object(); long nCtx() { diff --git a/src/api/java/InterpolationContext.java b/src/api/java/InterpolationContext.java index 05746af5d..47a128643 100644 --- a/src/api/java/InterpolationContext.java +++ b/src/api/java/InterpolationContext.java @@ -35,8 +35,11 @@ public class InterpolationContext extends Context **/ public InterpolationContext() { - m_ctx = Native.mkInterpolationContext(0); - initContext(); + super(); + synchronized(creation_lock) { + m_ctx = Native.mkInterpolationContext(0); + initContext(); + } } /** @@ -48,12 +51,15 @@ public class InterpolationContext extends Context **/ public InterpolationContext(Map settings) { - long cfg = Native.mkConfig(); - for (Map.Entry kv : settings.entrySet()) - Native.setParamValue(cfg, kv.getKey(), kv.getValue()); - m_ctx = Native.mkInterpolationContext(cfg); - Native.delConfig(cfg); - initContext(); + super(); + synchronized(creation_lock) { + long cfg = Native.mkConfig(); + for (Map.Entry kv : settings.entrySet()) + Native.setParamValue(cfg, kv.getKey(), kv.getValue()); + m_ctx = Native.mkInterpolationContext(cfg); + Native.delConfig(cfg); + initContext(); + } } /** From 2d3c12716ac66caffd7144ea4fdcad87830a6d8b Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 14 Oct 2015 21:19:59 +0100 Subject: [PATCH 36/57] Bugfix for Java memory leaks. Relates to #205 #245 --- src/api/java/Context.java | 35 ++++++++++++++++------------------- src/api/java/Z3Object.java | 3 ++- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/api/java/Context.java b/src/api/java/Context.java index 89adaad5d..b733df2fa 100644 --- a/src/api/java/Context.java +++ b/src/api/java/Context.java @@ -370,16 +370,15 @@ public class Context extends IDisposable * Update a datatype field at expression t with value v. * The function performs a record update at t. The field * that is passed in as argument is updated with value v, - * the remainig fields of t are unchanged. + * the remainig fields of t are unchanged. **/ public Expr MkUpdateField(FuncDecl field, Expr t, Expr v) - throws Z3Exception + throws Z3Exception { - return Expr.create - (this, - Native.datatypeUpdateField - (nCtx(), field.getNativeObject(), - t.getNativeObject(), v.getNativeObject())); + return Expr.create (this, + Native.datatypeUpdateField + (nCtx(), field.getNativeObject(), + t.getNativeObject(), v.getNativeObject())); } @@ -3777,18 +3776,6 @@ public class Context extends IDisposable { try { dispose(); - - if (m_refCount.get() == 0) - { - try - { - Native.delContext(m_ctx); - } catch (Z3Exception e) - { - // OK. - } - m_ctx = 0; - } } catch (Throwable t) { throw t; @@ -3821,5 +3808,15 @@ public class Context extends IDisposable m_boolSort = null; m_intSort = null; m_realSort = null; + + if (m_refCount.get() == 0) { + try { + Native.delContext(m_ctx); + } catch (Z3Exception e) { + // OK? + System.out.println("Context deletion failed; memory leak possible."); + } + m_ctx = 0; + } } } diff --git a/src/api/java/Z3Object.java b/src/api/java/Z3Object.java index 473cb5403..574a2820c 100644 --- a/src/api/java/Z3Object.java +++ b/src/api/java/Z3Object.java @@ -53,7 +53,8 @@ public class Z3Object extends IDisposable if (m_ctx != null) { - m_ctx.m_refCount.decrementAndGet(); + if (m_ctx.m_refCount.decrementAndGet() == 0) + m_ctx.dispose(); m_ctx = null; } } From a71a33372200343301c4388e2c52eccfd58fa705 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 14 Oct 2015 21:33:30 +0100 Subject: [PATCH 37/57] Minor Java API fix. --- src/api/java/Context.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/java/Context.java b/src/api/java/Context.java index b733df2fa..56f9e008c 100644 --- a/src/api/java/Context.java +++ b/src/api/java/Context.java @@ -3809,7 +3809,7 @@ public class Context extends IDisposable m_intSort = null; m_realSort = null; - if (m_refCount.get() == 0) { + if (m_refCount.get() == 0 && m_ctx != 0) { try { Native.delContext(m_ctx); } catch (Z3Exception e) { From ef80645a71e2e46190bf631e7f5a345315b132cb Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 14 Oct 2015 22:13:43 +0100 Subject: [PATCH 38/57] Java API context deletion concurrency fix. Relates to #205 #245 --- src/api/java/Context.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/api/java/Context.java b/src/api/java/Context.java index 56f9e008c..1bc01857b 100644 --- a/src/api/java/Context.java +++ b/src/api/java/Context.java @@ -3809,14 +3809,16 @@ public class Context extends IDisposable m_intSort = null; m_realSort = null; - if (m_refCount.get() == 0 && m_ctx != 0) { - try { - Native.delContext(m_ctx); - } catch (Z3Exception e) { - // OK? - System.out.println("Context deletion failed; memory leak possible."); + synchronized (creation_lock) { + if (m_refCount.get() == 0 && m_ctx != 0) { + try { + Native.delContext(m_ctx); + } catch (Z3Exception e) { + // OK? + System.out.println("Context deletion failed; memory leak possible."); + } + m_ctx = 0; } - m_ctx = 0; } } } From a1eee6275f51d00f5d25de2f852f3a2e16e6c243 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 19 Oct 2015 19:03:36 +0100 Subject: [PATCH 39/57] Bugfix for C++ examples. Relates to #26 --- examples/c++/example.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/c++/example.cpp b/examples/c++/example.cpp index 3ef00275e..af972a36b 100644 --- a/examples/c++/example.cpp +++ b/examples/c++/example.cpp @@ -1017,6 +1017,7 @@ void extract_example() { x = c.constant("x", c.bv_sort(32)); expr y = x.extract(21, 10); std::cout << y << " " << y.hi() << " " << y.lo() << "\n"; +} void sudoku_example() { std::cout << "sudoku example\n"; @@ -1059,7 +1060,7 @@ void sudoku_example() { // each 3x3 square contains a digit at most once for (unsigned i0 = 0; i0 < 3; i0++) { - for (uint j0 = 0; j0 < 3; j0++) { + for (unsigned j0 = 0; j0 < 3; j0++) { expr_vector t(c); for (unsigned i = 0; i < 3; i++) for (unsigned j = 0; j < 3; j++) From e2f2708a9c4f09d38ea0cc5fa98c9ad59f2a94ec Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 19 Oct 2015 21:12:43 +0100 Subject: [PATCH 40/57] Fixed array default operator --- src/api/python/z3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/python/z3.py b/src/api/python/z3.py index 3b869d1fd..68f559635 100644 --- a/src/api/python/z3.py +++ b/src/api/python/z3.py @@ -4064,7 +4064,7 @@ def Default(a): """ if __debug__: _z3_assert(is_array(a), "First argument must be a Z3 array expression") - return a.mk_default() + return a.default() def Store(a, i, v): From ffa78b95ab347ce3410ffeba4b5c0d9f828d1917 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Wed, 21 Oct 2015 14:38:47 -0700 Subject: [PATCH 41/57] fix unbounded, issue #252 Signed-off-by: Nikolaj Bjorner --- src/smt/theory_arith_aux.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/smt/theory_arith_aux.h b/src/smt/theory_arith_aux.h index bad141e94..532152100 100644 --- a/src/smt/theory_arith_aux.h +++ b/src/smt/theory_arith_aux.h @@ -1530,6 +1530,7 @@ namespace smt { while (best_efforts < max_efforts && !ctx.get_cancel_flag()) { theory_var x_j = null_theory_var; theory_var x_i = null_theory_var; + unsigned has_bound = false; max_gain.reset(); min_gain.reset(); ++round; @@ -1538,7 +1539,7 @@ namespace smt { typename vector::const_iterator it = r.begin_entries(); typename vector::const_iterator end = r.end_entries(); for (; it != end; ++it) { - if (it->is_dead()) continue; + if (it->is_dead()) continue; theory_var curr_x_j = it->m_var; theory_var curr_x_i = null_theory_var; SASSERT(is_non_base(curr_x_j)); @@ -1546,6 +1547,7 @@ namespace smt { bool curr_inc = curr_coeff.is_pos() ? max : !max; if ((curr_inc && at_upper(curr_x_j)) || (!curr_inc && at_lower(curr_x_j))) { // variable cannot be used for max/min. + has_bound = true; continue; } bool picked_var = pick_var_to_leave(curr_x_j, curr_inc, curr_a_ij, @@ -1593,10 +1595,10 @@ namespace smt { TRACE("opt", tout << "after traversing row:\nx_i: v" << x_i << ", x_j: v" << x_j << ", gain: " << max_gain << "\n"; tout << "best efforts: " << best_efforts << " has shared: " << has_shared << "\n";); - if (x_j == null_theory_var && x_i == null_theory_var) { + if (!has_bound && x_i == null_theory_var && x_j == null_theory_var) { has_shared = false; best_efforts = 0; - result = UNBOUNDED; + result = UNBOUNDED; break; } From ac902dad1a1022a3762320e321c4b2f696a8dbd0 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 22 Oct 2015 08:53:12 -0700 Subject: [PATCH 42/57] fix another regression and missing detection of bounds, Issue #254 Signed-off-by: Nikolaj Bjorner --- src/smt/theory_arith_aux.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/smt/theory_arith_aux.h b/src/smt/theory_arith_aux.h index 532152100..1f729d7b5 100644 --- a/src/smt/theory_arith_aux.h +++ b/src/smt/theory_arith_aux.h @@ -1530,7 +1530,7 @@ namespace smt { while (best_efforts < max_efforts && !ctx.get_cancel_flag()) { theory_var x_j = null_theory_var; theory_var x_i = null_theory_var; - unsigned has_bound = false; + bool has_bound = false; max_gain.reset(); min_gain.reset(); ++round; @@ -1544,10 +1544,12 @@ namespace smt { theory_var curr_x_i = null_theory_var; SASSERT(is_non_base(curr_x_j)); curr_coeff = it->m_coeff; - bool curr_inc = curr_coeff.is_pos() ? max : !max; + bool curr_inc = curr_coeff.is_pos() ? max : !max; + if ((curr_inc && upper(curr_x_j)) || (!curr_inc && lower(curr_x_j))) { + has_bound = true; + } if ((curr_inc && at_upper(curr_x_j)) || (!curr_inc && at_lower(curr_x_j))) { // variable cannot be used for max/min. - has_bound = true; continue; } bool picked_var = pick_var_to_leave(curr_x_j, curr_inc, curr_a_ij, @@ -1557,7 +1559,7 @@ namespace smt { SASSERT(!picked_var || safe_gain(curr_min_gain, curr_max_gain)); - if (!picked_var) { // && (r.size() > 1 || !safe_gain(curr_min_gain, curr_max_gain)) + if (!safe_gain(curr_min_gain, curr_max_gain)) { TRACE("opt", tout << "no variable picked\n";); best_efforts++; } From 05c6ed16982a88d2c87694d8ad709c989248b620 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 22 Oct 2015 09:54:05 -0700 Subject: [PATCH 43/57] fixing issue #254 Signed-off-by: Nikolaj Bjorner --- src/smt/theory_arith_aux.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/smt/theory_arith_aux.h b/src/smt/theory_arith_aux.h index 1f729d7b5..45654310f 100644 --- a/src/smt/theory_arith_aux.h +++ b/src/smt/theory_arith_aux.h @@ -1561,6 +1561,7 @@ namespace smt { if (!safe_gain(curr_min_gain, curr_max_gain)) { TRACE("opt", tout << "no variable picked\n";); + has_bound = true; best_efforts++; } else if (curr_x_i == null_theory_var) { From 21ad1fb623a655362374454a0584d144105fa1d1 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 25 Oct 2015 13:09:18 +0000 Subject: [PATCH 44/57] Bugfix for proof production in asserted_formulas::propagate_values() Fixes #259 --- src/smt/asserted_formulas.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index bd5f53922..0caefd3fe 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -593,7 +593,7 @@ void asserted_formulas::propagate_values() { bool found = false; // Separate the formulas in two sets: C and R // C is a set which contains formulas of the form - // { x = n }, where x is a variable and n a numberal. + // { x = n }, where x is a variable and n a numeral. // R contains the rest. // // - new_exprs1 is the set C @@ -613,15 +613,18 @@ void asserted_formulas::propagate_values() { expr * lhs = to_app(n)->get_arg(0); expr * rhs = to_app(n)->get_arg(1); if (m_manager.is_value(lhs) || m_manager.is_value(rhs)) { - if (m_manager.is_value(lhs)) + if (m_manager.is_value(lhs)) { std::swap(lhs, rhs); + n = m_manager.mk_eq(lhs, rhs); + pr = m_manager.mk_symmetry(pr); + } if (!m_manager.is_value(lhs) && !m_simplifier.is_cached(lhs)) { if (i >= m_asserted_qhead) { new_exprs1.push_back(n); if (m_manager.proofs_enabled()) new_prs1.push_back(pr); } - TRACE("propagate_values", tout << "found:\n" << mk_pp(lhs, m_manager) << "\n->\n" << mk_pp(rhs, m_manager) << "\n";); + TRACE("propagate_values", tout << "found:\n" << mk_pp(lhs, m_manager) << "\n->\n" << mk_pp(rhs, m_manager) << "\nproof: " << mk_pp(pr, m_manager) << "\n";); m_simplifier.cache_result(lhs, rhs, pr); found = true; continue; From 099775947ea59bae07cb9e4305162b218cd20220 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 13 Oct 2015 14:29:08 +0100 Subject: [PATCH 45/57] Partial fix for fp,min/fp.max models --- src/ast/fpa/fpa2bv_converter.cpp | 64 +++++++++++------------ src/ast/fpa/fpa2bv_converter.h | 9 +++- src/ast/fpa/fpa2bv_rewriter.h | 12 +++-- src/ast/fpa_decl_plugin.cpp | 49 ++++------------- src/ast/fpa_decl_plugin.h | 11 ++-- src/ast/rewriter/fpa_rewriter.cpp | 58 +++++++++++--------- src/tactic/fpa/fpa2bv_model_converter.cpp | 42 +++++++-------- src/tactic/fpa/fpa2bv_model_converter.h | 16 ++---- src/tactic/fpa/fpa2bv_tactic.cpp | 2 +- 9 files changed, 115 insertions(+), 148 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 2d6419d69..f5f5b10c0 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -35,7 +35,11 @@ fpa2bv_converter::fpa2bv_converter(ast_manager & m) : m_arith_util(m), m_mpf_manager(m_util.fm()), m_mpz_manager(m_mpf_manager.mpz_manager()), - m_hi_fp_unspecified(true), + m_hi_fp_unspecified(true), + m_min_pn_zeros(0, m), + m_min_np_zeros(0, m), + m_max_pn_zeros(0, m), + m_max_np_zeros(0, m), m_extra_assertions(m) { m_plugin = static_cast(m.get_plugin(m.mk_family_id("fpa"))); } @@ -1064,7 +1068,7 @@ void fpa2bv_converter::mk_abs(func_decl * f, unsigned num, expr * const * args, mk_fp(m_bv_util.mk_numeral(0, 1), e, s, result); } -void fpa2bv_converter::mk_min(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { +void fpa2bv_converter::mk_min_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 2); expr * x = args[0], * y = args[1]; @@ -1086,16 +1090,11 @@ void fpa2bv_converter::mk_min(func_decl * f, unsigned num, expr * const * args, sgn_diff = m.mk_not(m.mk_eq(x_sgn, y_sgn)); expr_ref lt(m); - mk_float_lt(f, num, args, lt); - - expr_ref zz(m); - zz = mk_min_unspecified(f, x, y); - TRACE("fpa2bv", tout << "min = " << mk_ismt2_pp(zz, m) << std::endl;); + mk_float_lt(f, num, args, lt); result = y; mk_ite(lt, x, result, result); mk_ite(both_zero, y, result, result); - mk_ite(m.mk_and(both_zero, sgn_diff), zz, result, result); mk_ite(y_is_nan, x, result, result); mk_ite(x_is_nan, y, result, result); @@ -1111,33 +1110,40 @@ expr_ref fpa2bv_converter::mk_min_unspecified(func_decl * f, expr * x, expr * y) if (m_hi_fp_unspecified) // The hardware interpretation is -0.0. - mk_nzero(f, res); + mk_nzero(f, res); else { - app_ref pn_nondet(m), np_nondet(m); - pn_nondet = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); - np_nondet = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); - m_decls_to_hide.insert(pn_nondet->get_decl()); - m_decls_to_hide.insert(np_nondet->get_decl()); + if (m_min_pn_zeros.get() == 0) m_min_pn_zeros = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); + if (m_min_np_zeros.get() == 0) m_min_np_zeros = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); expr_ref pn(m), np(m); - mk_fp(pn_nondet, + mk_fp(m_min_pn_zeros, m_bv_util.mk_numeral(0, ebits), m_bv_util.mk_numeral(0, sbits - 1), pn); - mk_fp(np_nondet, + mk_fp(m_min_np_zeros, m_bv_util.mk_numeral(0, ebits), m_bv_util.mk_numeral(0, sbits - 1), np); - expr_ref x_is_pzero(m), x_is_nzero(m); + + expr_ref x_is_pzero(m), x_is_nzero(m), ite(m); mk_is_pzero(x, x_is_pzero); mk_is_nzero(y, x_is_nzero); - mk_ite(m.mk_and(x_is_pzero, x_is_nzero), pn, np, res); + mk_ite(m.mk_and(x_is_pzero, x_is_nzero), pn, np, ite); + + expr * args[] = { x, y }; + mk_uninterpreted_function(f, 2, args, res); + + expr_ref pzero(m), nzero(m), extra(m); + mk_pzero(f, pzero); + mk_nzero(f, nzero); + extra = m.mk_or(m.mk_eq(ite, pzero), m.mk_eq(ite, nzero)); + m_extra_assertions.push_back(extra); } return res; } -void fpa2bv_converter::mk_max(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { +void fpa2bv_converter::mk_max_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 2); expr * x = args[0], *y = args[1]; @@ -1160,14 +1166,10 @@ void fpa2bv_converter::mk_max(func_decl * f, unsigned num, expr * const * args, expr_ref gt(m); mk_float_gt(f, num, args, gt); - - expr_ref zz(m); - zz = mk_max_unspecified(f, x, y); - + result = y; mk_ite(gt, x, result, result); - mk_ite(both_zero, y, result, result); - mk_ite(m.mk_and(both_zero, sgn_diff), zz, result, result); + mk_ite(both_zero, y, result, result); mk_ite(y_is_nan, x, result, result); mk_ite(x_is_nan, y, result, result); @@ -1185,21 +1187,19 @@ expr_ref fpa2bv_converter::mk_max_unspecified(func_decl * f, expr * x, expr * y) // The hardware interpretation is +0.0. mk_pzero(f, res); else { - app_ref pn_nondet(m), np_nondet(m); - pn_nondet = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); - np_nondet = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); - m_decls_to_hide.insert(pn_nondet->get_decl()); - m_decls_to_hide.insert(np_nondet->get_decl()); + if (m_max_pn_zeros.get() == 0) m_max_pn_zeros = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); + if (m_max_np_zeros.get() == 0) m_max_np_zeros = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); expr_ref pn(m), np(m); - mk_fp(pn_nondet, + mk_fp(m_max_pn_zeros, m_bv_util.mk_numeral(0, ebits), m_bv_util.mk_numeral(0, sbits - 1), pn); - mk_fp(np_nondet, + mk_fp(m_max_np_zeros, m_bv_util.mk_numeral(0, ebits), m_bv_util.mk_numeral(0, sbits - 1), np); + expr_ref x_is_pzero(m), x_is_nzero(m); mk_is_pzero(x, x_is_pzero); mk_is_nzero(y, x_is_nzero); diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index d17a6f770..6fb905708 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -57,6 +57,11 @@ protected: obj_map m_rm_const2bv; obj_map m_uf2bvuf; obj_hashtable m_decls_to_hide; + + app_ref m_min_pn_zeros; + app_ref m_min_np_zeros; + app_ref m_max_pn_zeros; + app_ref m_max_np_zeros; public: fpa2bv_converter(ast_manager & m); @@ -102,8 +107,8 @@ public: void mk_div(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_rem(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_abs(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - void mk_min(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - void mk_max(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + void mk_min_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + void mk_max_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_fma(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_sqrt(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_round_to_integral(func_decl * f, unsigned num, expr * const * args, expr_ref & result); diff --git a/src/ast/fpa/fpa2bv_rewriter.h b/src/ast/fpa/fpa2bv_rewriter.h index 1b7d55173..054133cc8 100644 --- a/src/ast/fpa/fpa2bv_rewriter.h +++ b/src/ast/fpa/fpa2bv_rewriter.h @@ -141,9 +141,7 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { case OP_FPA_MUL: m_conv.mk_mul(f, num, args, result); return BR_DONE; case OP_FPA_DIV: m_conv.mk_div(f, num, args, result); return BR_DONE; case OP_FPA_REM: m_conv.mk_rem(f, num, args, result); return BR_DONE; - case OP_FPA_ABS: m_conv.mk_abs(f, num, args, result); return BR_DONE; - case OP_FPA_MIN: m_conv.mk_min(f, num, args, result); return BR_DONE; - case OP_FPA_MAX: m_conv.mk_max(f, num, args, result); return BR_DONE; + case OP_FPA_ABS: m_conv.mk_abs(f, num, args, result); return BR_DONE; case OP_FPA_FMA: m_conv.mk_fma(f, num, args, result); return BR_DONE; case OP_FPA_SQRT: m_conv.mk_sqrt(f, num, args, result); return BR_DONE; case OP_FPA_ROUND_TO_INTEGRAL: m_conv.mk_round_to_integral(f, num, args, result); return BR_DONE; @@ -166,8 +164,16 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { case OP_FPA_TO_SBV: m_conv.mk_to_sbv(f, num, args, result); return BR_DONE; case OP_FPA_TO_REAL: m_conv.mk_to_real(f, num, args, result); return BR_DONE; case OP_FPA_TO_IEEE_BV: m_conv.mk_to_ieee_bv(f, num, args, result); return BR_DONE; + + case OP_FPA_MIN: + case OP_FPA_MAX: + throw rewriter_exception("operator is not supported, you must simplify the goal before applying fpa2bv"); + case OP_FPA_INTERNAL_MIN_UNSPECIFIED: result = m_conv.mk_min_unspecified(f, args[0], args[1]); return BR_DONE; case OP_FPA_INTERNAL_MAX_UNSPECIFIED: result = m_conv.mk_max_unspecified(f, args[0], args[1]); return BR_DONE; + case OP_FPA_INTERNAL_MIN_I: m_conv.mk_min_i(f, num, args, result); return BR_DONE; + case OP_FPA_INTERNAL_MAX_I: m_conv.mk_max_i(f, num, args, result); return BR_DONE; + case OP_FPA_INTERNAL_BVWRAP: case OP_FPA_INTERNAL_BVUNWRAP: case OP_FPA_INTERNAL_TO_REAL_UNSPECIFIED: diff --git a/src/ast/fpa_decl_plugin.cpp b/src/ast/fpa_decl_plugin.cpp index ec410fd18..5a8063c37 100644 --- a/src/ast/fpa_decl_plugin.cpp +++ b/src/ast/fpa_decl_plugin.cpp @@ -359,6 +359,10 @@ func_decl * fpa_decl_plugin::mk_binary_decl(decl_kind k, unsigned num_parameters case OP_FPA_REM: name = "fp.rem"; break; case OP_FPA_MIN: name = "fp.min"; break; case OP_FPA_MAX: name = "fp.max"; break; + case OP_FPA_INTERNAL_MIN_I: name = "fp.min_i"; break; + case OP_FPA_INTERNAL_MAX_I: name = "fp.max_i"; break; + case OP_FPA_INTERNAL_MIN_UNSPECIFIED: name = "fp.min_unspecified"; break; + case OP_FPA_INTERNAL_MAX_UNSPECIFIED: name = "fp.max_unspecified"; break; default: UNREACHABLE(); break; @@ -689,32 +693,6 @@ func_decl * fpa_decl_plugin::mk_internal_bv_unwrap(decl_kind k, unsigned num_par return m_manager->mk_func_decl(symbol("bv_unwrap"), 1, domain, range, func_decl_info(m_family_id, k, num_parameters, parameters)); } -func_decl * fpa_decl_plugin::mk_internal_min_unspecified( - decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range) { - if (arity != 2) - m_manager->raise_exception("invalid number of arguments to fp.min_unspecified"); - if (domain[0] != domain[1] || !is_float_sort(domain[0])) - m_manager->raise_exception("sort mismatch, expected arguments of equal FloatingPoint sorts"); - if (!is_float_sort(range)) - m_manager->raise_exception("sort mismatch, expected range of FloatingPoint sort"); - - return m_manager->mk_func_decl(symbol("fp.min_unspecified"), 2, domain, range, func_decl_info(m_family_id, k, num_parameters, parameters)); -} - -func_decl * fpa_decl_plugin::mk_internal_max_unspecified( - decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range) { - if (arity != 2) - m_manager->raise_exception("invalid number of arguments to fp.max_unspecified"); - if (domain[0] != domain[1] || !is_float_sort(domain[0])) - m_manager->raise_exception("sort mismatch, expected arguments of equal FloatingPoint sorts"); - if (!is_float_sort(range)) - m_manager->raise_exception("sort mismatch, expected range of FloatingPoint sort"); - - return m_manager->mk_func_decl(symbol("fp.max_unspecified"), 2, domain, range, func_decl_info(m_family_id, k, num_parameters, parameters)); -} - func_decl * fpa_decl_plugin::mk_internal_to_ubv_unspecified( decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { @@ -822,10 +800,13 @@ func_decl * fpa_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, return mk_internal_bv_wrap(k, num_parameters, parameters, arity, domain, range); case OP_FPA_INTERNAL_BVUNWRAP: return mk_internal_bv_unwrap(k, num_parameters, parameters, arity, domain, range); + + case OP_FPA_INTERNAL_MIN_I: + case OP_FPA_INTERNAL_MAX_I: case OP_FPA_INTERNAL_MIN_UNSPECIFIED: - return mk_internal_min_unspecified(k, num_parameters, parameters, arity, domain, range); case OP_FPA_INTERNAL_MAX_UNSPECIFIED: - return mk_internal_max_unspecified(k, num_parameters, parameters, arity, domain, range); + return mk_binary_decl(k, num_parameters, parameters, arity, domain, range); + case OP_FPA_INTERNAL_TO_UBV_UNSPECIFIED: return mk_internal_to_ubv_unspecified(k, num_parameters, parameters, arity, domain, range); case OP_FPA_INTERNAL_TO_SBV_UNSPECIFIED: @@ -1031,18 +1012,6 @@ app * fpa_util::mk_nzero(unsigned ebits, unsigned sbits) { return mk_value(v); } -app * fpa_util::mk_internal_min_unspecified(expr * x, expr * y) { - SASSERT(m().get_sort(x) == m().get_sort(y)); - expr * args[] = { x, y }; - return m().mk_app(get_family_id(), OP_FPA_INTERNAL_MIN_UNSPECIFIED, 0, 0, 2, args, m().get_sort(x)); -} - -app * fpa_util::mk_internal_max_unspecified(expr * x, expr * y) { - SASSERT(m().get_sort(x) == m().get_sort(y)); - expr * args[] = { x, y }; - return m().mk_app(get_family_id(), OP_FPA_INTERNAL_MAX_UNSPECIFIED, 0, 0, 2, args, m().get_sort(x)); -} - app * fpa_util::mk_internal_to_ubv_unspecified(unsigned width) { parameter ps[] = { parameter(width) }; sort * range = m_bv_util.mk_sort(width); diff --git a/src/ast/fpa_decl_plugin.h b/src/ast/fpa_decl_plugin.h index 50b388047..34a9daa59 100644 --- a/src/ast/fpa_decl_plugin.h +++ b/src/ast/fpa_decl_plugin.h @@ -86,7 +86,10 @@ enum fpa_op_kind { /* Internal use only */ OP_FPA_INTERNAL_BVWRAP, - OP_FPA_INTERNAL_BVUNWRAP, + OP_FPA_INTERNAL_BVUNWRAP, + + OP_FPA_INTERNAL_MIN_I, + OP_FPA_INTERNAL_MAX_I, OP_FPA_INTERNAL_MIN_UNSPECIFIED, OP_FPA_INTERNAL_MAX_UNSPECIFIED, OP_FPA_INTERNAL_TO_UBV_UNSPECIFIED, @@ -162,10 +165,6 @@ class fpa_decl_plugin : public decl_plugin { unsigned arity, sort * const * domain, sort * range); func_decl * mk_internal_bv_unwrap(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); - func_decl * mk_internal_min_unspecified(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); - func_decl * mk_internal_max_unspecified(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); func_decl * mk_internal_to_ubv_unspecified(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); func_decl * mk_internal_to_sbv_unspecified(decl_kind k, unsigned num_parameters, parameter const * parameters, @@ -338,8 +337,6 @@ public: app * mk_to_ieee_bv(expr * arg1) { return m().mk_app(m_fid, OP_FPA_TO_IEEE_BV, arg1); } - app * mk_internal_min_unspecified(expr * x, expr * y); - app * mk_internal_max_unspecified(expr * x, expr * y); app * mk_internal_to_ubv_unspecified(unsigned width); app * mk_internal_to_sbv_unspecified(unsigned width); app * mk_internal_to_ieee_bv_unspecified(unsigned width); diff --git a/src/ast/rewriter/fpa_rewriter.cpp b/src/ast/rewriter/fpa_rewriter.cpp index d336c3a56..2a800f004 100644 --- a/src/ast/rewriter/fpa_rewriter.cpp +++ b/src/ast/rewriter/fpa_rewriter.cpp @@ -93,6 +93,8 @@ br_status fpa_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * con case OP_FPA_TO_IEEE_BV: SASSERT(num_args == 1); st = mk_to_ieee_bv(f, args[0], result); break; case OP_FPA_TO_REAL: SASSERT(num_args == 1); st = mk_to_real(args[0], result); break; + case OP_FPA_INTERNAL_MIN_I: + case OP_FPA_INTERNAL_MAX_I: case OP_FPA_INTERNAL_MIN_UNSPECIFIED: case OP_FPA_INTERNAL_MAX_UNSPECIFIED: SASSERT(num_args == 2); st = BR_FAILED; break; @@ -432,21 +434,23 @@ br_status fpa_rewriter::mk_min(expr * arg1, expr * arg2, expr_ref & result) { } scoped_mpf v1(m_fm), v2(m_fm); - if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2)) { - if (m_fm.is_zero(v1) && m_fm.is_zero(v2) && m_fm.sgn(v1) != m_fm.sgn(v2)) { - // Result could be +zero or -zero. - result = m_util.mk_internal_min_unspecified(arg1, arg2); - return BR_DONE; - } - else { - scoped_mpf r(m_fm); - m_fm.minimum(v1, v2, r); - result = m_util.mk_value(r); - return BR_DONE; - } + if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2) && + !(m_fm.is_zero(v1) && m_fm.is_zero(v2) && m_fm.sgn(v1) != m_fm.sgn(v2))) { + scoped_mpf r(m_fm); + m_fm.minimum(v1, v2, r); + result = m_util.mk_value(r); + return BR_DONE; } + else { + expr_ref c(m()), v(m()); + c = m().mk_and(m().mk_and(m_util.mk_is_zero(arg1), m_util.mk_is_zero(arg2)), + m().mk_or(m().mk_and(m_util.mk_is_positive(arg1), m_util.mk_is_negative(arg2)), + m().mk_and(m_util.mk_is_negative(arg1), m_util.mk_is_positive(arg2)))); + v = m().mk_app(get_fid(), OP_FPA_INTERNAL_MIN_UNSPECIFIED, arg1, arg2); - return BR_FAILED; + result = m().mk_ite(c, v, m().mk_app(get_fid(), OP_FPA_INTERNAL_MIN_I, arg1, arg2)); + return BR_REWRITE_FULL; + } } br_status fpa_rewriter::mk_max(expr * arg1, expr * arg2, expr_ref & result) { @@ -460,21 +464,23 @@ br_status fpa_rewriter::mk_max(expr * arg1, expr * arg2, expr_ref & result) { } scoped_mpf v1(m_fm), v2(m_fm); - if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2)) { - if (m_fm.is_zero(v1) && m_fm.is_zero(v2) && m_fm.sgn(v1) != m_fm.sgn(v2)) { - // Result could be +zero or -zero. - result = m_util.mk_internal_max_unspecified(arg1, arg2); - return BR_REWRITE_FULL; - } - else { - scoped_mpf r(m_fm); - m_fm.maximum(v1, v2, r); - result = m_util.mk_value(r); - return BR_DONE; - } + if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2) && + !(m_fm.is_zero(v1) && m_fm.is_zero(v2) && m_fm.sgn(v1) != m_fm.sgn(v2))) { + scoped_mpf r(m_fm); + m_fm.maximum(v1, v2, r); + result = m_util.mk_value(r); + return BR_DONE; } + else { + expr_ref c(m()), v(m()); + c = m().mk_and(m().mk_and(m_util.mk_is_zero(arg1), m_util.mk_is_zero(arg2)), + m().mk_or(m().mk_and(m_util.mk_is_positive(arg1), m_util.mk_is_negative(arg2)), + m().mk_and(m_util.mk_is_negative(arg1), m_util.mk_is_positive(arg2)))); + v = m().mk_app(get_fid(), OP_FPA_INTERNAL_MAX_UNSPECIFIED, arg1, arg2); - return BR_FAILED; + result = m().mk_ite(c, v, m().mk_app(get_fid(), OP_FPA_INTERNAL_MAX_I, arg1, arg2)); + return BR_REWRITE_FULL; + } } br_status fpa_rewriter::mk_fma(expr * arg1, expr * arg2, expr * arg3, expr * arg4, expr_ref & result) { diff --git a/src/tactic/fpa/fpa2bv_model_converter.cpp b/src/tactic/fpa/fpa2bv_model_converter.cpp index f9d2eeed4..af0d5e5fc 100644 --- a/src/tactic/fpa/fpa2bv_model_converter.cpp +++ b/src/tactic/fpa/fpa2bv_model_converter.cpp @@ -45,11 +45,6 @@ void fpa2bv_model_converter::display(std::ostream & out) { unsigned indent = n.size() + 4; out << mk_ismt2_pp(it->m_value, m, indent) << ")"; } - for (obj_hashtable::iterator it = m_decls_to_hide.begin(); - it != m_decls_to_hide.end(); - it++) { - out << "\n to hide: " << mk_ismt2_pp(*it, m); - } out << ")" << std::endl; } @@ -84,13 +79,6 @@ model_converter * fpa2bv_model_converter::translate(ast_translation & translator translator.to().inc_ref(k); translator.to().inc_ref(v); } - for (obj_hashtable::iterator it = m_decls_to_hide.begin(); - it != m_decls_to_hide.end(); - it++) { - func_decl * k = translator(*it); - res->m_decls_to_hide.insert(k); - translator.to().inc_ref(k); - } return res; } @@ -204,16 +192,23 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) { TRACE("fpa2bv_mc", tout << "BV Model: " << std::endl; for (unsigned i = 0; i < bv_mdl->get_num_constants(); i++) tout << bv_mdl->get_constant(i)->get_name() << " --> " << - mk_ismt2_pp(bv_mdl->get_const_interp(bv_mdl->get_constant(i)), m) << std::endl; - ); + mk_ismt2_pp(bv_mdl->get_const_interp(bv_mdl->get_constant(i)), m) << std::endl; + for (unsigned i = 0; i < bv_mdl->get_num_functions(); i++) { + func_decl * f = bv_mdl->get_function(i); + tout << f->get_name() << "(...) := " << std::endl; + func_interp * fi = bv_mdl->get_func_interp(f); + for (unsigned j = 0; j < fi->num_entries(); j++) { + func_entry const * fe = fi->get_entry(j); + for (unsigned k = 0; k < f->get_arity(); k++) { + tout << mk_ismt2_pp(fe->get_arg(k), m) << " "; + } + tout << "--> " << mk_ismt2_pp(fe->get_result(), m) << std::endl; + } + tout << "else " << mk_ismt2_pp(fi->get_else(), m) << std::endl; + }); obj_hashtable seen; - for (obj_hashtable::iterator it = m_decls_to_hide.begin(); - it != m_decls_to_hide.end(); - it++) - seen.insert(*it); - for (obj_map::iterator it = m_const2bv.begin(); it != m_const2bv.end(); it++) @@ -317,8 +312,8 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) { els = convert_bv2rm(els); flt_fi->set_else(els); - - float_mdl->register_decl(f, flt_fi); + + float_mdl->register_decl(f, flt_fi); } // Keep all the non-float constants. @@ -355,7 +350,6 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) { model_converter * mk_fpa2bv_model_converter(ast_manager & m, obj_map const & const2bv, obj_map const & rm_const2bv, - obj_map const & uf2bvuf, - obj_hashtable const & decls_to_hide) { - return alloc(fpa2bv_model_converter, m, const2bv, rm_const2bv, uf2bvuf, decls_to_hide); + obj_map const & uf2bvuf) { + return alloc(fpa2bv_model_converter, m, const2bv, rm_const2bv, uf2bvuf); } diff --git a/src/tactic/fpa/fpa2bv_model_converter.h b/src/tactic/fpa/fpa2bv_model_converter.h index a6ae73eb8..021538ac1 100644 --- a/src/tactic/fpa/fpa2bv_model_converter.h +++ b/src/tactic/fpa/fpa2bv_model_converter.h @@ -27,13 +27,11 @@ class fpa2bv_model_converter : public model_converter { obj_map m_const2bv; obj_map m_rm_const2bv; obj_map m_uf2bvuf; - obj_hashtable m_decls_to_hide; public: fpa2bv_model_converter(ast_manager & m, obj_map const & const2bv, obj_map const & rm_const2bv, - obj_map const & uf2bvuf, - obj_hashtable const & decls_to_hide) : + obj_map const & uf2bvuf) : m(m) { // Just create a copy? for (obj_map::iterator it = const2bv.begin(); @@ -60,19 +58,12 @@ public: m.inc_ref(it->m_key); m.inc_ref(it->m_value); } - for (obj_hashtable::iterator it = decls_to_hide.begin(); - it != decls_to_hide.end(); - it++) { - m_decls_to_hide.insert(*it); - m.inc_ref(*it); - } } virtual ~fpa2bv_model_converter() { dec_ref_map_key_values(m, m_const2bv); dec_ref_map_key_values(m, m_rm_const2bv); dec_ref_map_key_values(m, m_uf2bvuf); - dec_ref_collection_values(m, m_decls_to_hide); } virtual void operator()(model_ref & md, unsigned goal_idx) { @@ -105,7 +96,6 @@ protected: model_converter * mk_fpa2bv_model_converter(ast_manager & m, obj_map const & const2bv, obj_map const & rm_const2bv, - obj_map const & uf2bvuf, - obj_hashtable const & m_decls_to_hide); + obj_map const & uf2bvuf); -#endif +#endif \ No newline at end of file diff --git a/src/tactic/fpa/fpa2bv_tactic.cpp b/src/tactic/fpa/fpa2bv_tactic.cpp index 158bb935e..07669f513 100644 --- a/src/tactic/fpa/fpa2bv_tactic.cpp +++ b/src/tactic/fpa/fpa2bv_tactic.cpp @@ -107,7 +107,7 @@ class fpa2bv_tactic : public tactic { } if (g->models_enabled()) - mc = mk_fpa2bv_model_converter(m, m_conv.const2bv(), m_conv.rm_const2bv(), m_conv.uf2bvuf(), m_conv.decls_to_hide()); + mc = mk_fpa2bv_model_converter(m, m_conv.const2bv(), m_conv.rm_const2bv(), m_conv.uf2bvuf()); g->inc_depth(); result.push_back(g.get()); From ca496f20cb1d3eacafa1c608e8f0bc78cc23f2f5 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 20 Oct 2015 18:32:31 +0100 Subject: [PATCH 46/57] Partial refactoring of fpa2bv conversion to support proofs. --- src/ast/fpa/fpa2bv_converter.cpp | 169 ++++++++++++---------- src/ast/fpa/fpa2bv_converter.h | 6 +- src/ast/fpa/fpa2bv_rewriter.h | 2 +- src/ast/fpa_decl_plugin.cpp | 21 ++- src/ast/fpa_decl_plugin.h | 7 + src/ast/rewriter/fpa_rewriter.cpp | 23 +++ src/ast/rewriter/fpa_rewriter.h | 2 + src/smt/theory_fpa.cpp | 1 + src/tactic/fpa/fpa2bv_model_converter.cpp | 5 +- 9 files changed, 152 insertions(+), 84 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index f5f5b10c0..cba2b3a7f 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -295,7 +295,8 @@ void fpa2bv_converter::mk_rm_const(func_decl * f, expr_ref & result) { else { SASSERT(is_rm(f->get_range())); - result = m.mk_fresh_const( + expr_ref bv3(m); + bv3 = m.mk_fresh_const( #ifdef Z3DEBUG "fpa2bv_rm" #else @@ -303,12 +304,13 @@ void fpa2bv_converter::mk_rm_const(func_decl * f, expr_ref & result) { #endif , m_bv_util.mk_sort(3)); + mk_rm(bv3, result); m_rm_const2bv.insert(f, result); m.inc_ref(f); m.inc_ref(result); expr_ref rcc(m); - rcc = bu().mk_ule(result, bu().mk_numeral(4, 3)); + rcc = bu().mk_ule(bv3, bu().mk_numeral(4, 3)); m_extra_assertions.push_back(rcc); } } @@ -389,7 +391,7 @@ void fpa2bv_converter::mk_one(func_decl *f, expr_ref sign, expr_ref & result) { result); } -void fpa2bv_converter::add_core(unsigned sbits, unsigned ebits, expr_ref & rm, +void fpa2bv_converter::add_core(unsigned sbits, unsigned ebits, expr_ref & c_sgn, expr_ref & c_sig, expr_ref & c_exp, expr_ref & d_sgn, expr_ref & d_sig, expr_ref & d_exp, expr_ref & res_sgn, expr_ref & res_sig, expr_ref & res_exp) { @@ -496,9 +498,10 @@ void fpa2bv_converter::add_core(unsigned sbits, unsigned ebits, expr_ref & rm, void fpa2bv_converter::mk_add(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 3); - - expr_ref rm(m), x(m), y(m); - rm = args[0]; + SASSERT(is_app_of(args[0], m_util.get_family_id(), OP_FPA_INTERNAL_RM)); + + expr_ref bv_rm(m), x(m), y(m); + bv_rm = to_app(args[0])->get_arg(0); x = args[1]; y = args[2]; @@ -555,7 +558,7 @@ void fpa2bv_converter::mk_add(func_decl * f, unsigned num, expr * const * args, m_simp.mk_and(x_is_zero, y_is_zero, c4); m_simp.mk_and(x_is_neg, y_is_neg, signs_and); m_simp.mk_xor(x_is_neg, y_is_neg, signs_xor); - mk_is_rm(rm, BV_RM_TO_NEGATIVE, rm_is_to_neg); + mk_is_rm(bv_rm, BV_RM_TO_NEGATIVE, rm_is_to_neg); m_simp.mk_and(rm_is_to_neg, signs_xor, rm_and_xor); m_simp.mk_or(signs_and, rm_and_xor, neg_cond); mk_ite(neg_cond, nzero, pzero, v4); @@ -595,7 +598,7 @@ void fpa2bv_converter::mk_add(func_decl * f, unsigned num, expr * const * args, m_simp.mk_ite(swap_cond, a_exp, b_exp, d_exp); // has ebits expr_ref res_sgn(m), res_sig(m), res_exp(m); - add_core(sbits, ebits, rm, + add_core(sbits, ebits, c_sgn, c_sig, c_exp, d_sgn, d_sig, d_exp, res_sgn, res_sig, res_exp); @@ -611,7 +614,7 @@ void fpa2bv_converter::mk_add(func_decl * f, unsigned num, expr * const * args, mk_ite(rm_is_to_neg, nzero, pzero, zero_case); expr_ref rounded(m); - round(f->get_range(), rm, res_sgn, res_sig, res_exp, rounded); + round(f->get_range(), bv_rm, res_sgn, res_sig, res_exp, rounded); mk_ite(is_zero_sig, zero_case, rounded, v7); @@ -649,9 +652,10 @@ void fpa2bv_converter::mk_neg(func_decl * f, unsigned num, expr * const * args, void fpa2bv_converter::mk_mul(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 3); - - expr_ref rm(m), x(m), y(m); - rm = args[0]; + SASSERT(is_app_of(args[0], m_util.get_family_id(), OP_FPA_INTERNAL_RM)); + + expr_ref bv_rm(m), x(m), y(m); + bv_rm = to_app(args[0])->get_arg(0); x = args[1]; y = args[2]; @@ -778,7 +782,7 @@ void fpa2bv_converter::mk_mul(func_decl * f, unsigned num, expr * const * args, SASSERT(m_bv_util.get_bv_size(rbits) == 4); res_sig = m_bv_util.mk_concat(h_p, rbits); - round(f->get_range(), rm, res_sgn, res_sig, res_exp, v7); + round(f->get_range(), bv_rm, res_sgn, res_sig, res_exp, v7); // And finally, we tie them together. mk_ite(c6, v6, v7, result); @@ -795,9 +799,10 @@ void fpa2bv_converter::mk_mul(func_decl * f, unsigned num, expr * const * args, void fpa2bv_converter::mk_div(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 3); + SASSERT(is_app_of(args[0], m_util.get_family_id(), OP_FPA_INTERNAL_RM)); - expr_ref rm(m), x(m), y(m); - rm = args[0]; + expr_ref bv_rm(m), x(m), y(m); + bv_rm = to_app(args[0])->get_arg(0); x = args[1]; y = args[2]; @@ -923,7 +928,7 @@ void fpa2bv_converter::mk_div(func_decl * f, unsigned num, expr * const * args, m_simp.mk_ite(shift_cond, res_sig, m_bv_util.mk_bv_shl(res_sig, res_sig_shift_amount), res_sig); m_simp.mk_ite(shift_cond, res_exp, m_bv_util.mk_bv_sub(res_exp, m_bv_util.mk_extract(ebits+1, 0, res_sig_shift_amount)), res_exp); - round(f->get_range(), rm, res_sgn, res_sig, res_exp, v8); + round(f->get_range(), bv_rm, res_sgn, res_sig, res_exp, v8); // And finally, we tie them together. mk_ite(c7, v7, v8, result); @@ -1039,9 +1044,9 @@ void fpa2bv_converter::mk_rem(func_decl * f, unsigned num, expr * const * args, // CMW: Actual rounding is not necessary here, this is // just convenience to get rid of the extra bits. - expr_ref rm(m); - rm = m_bv_util.mk_numeral(BV_RM_TIES_TO_EVEN, 3); - round(f->get_range(), rm, res_sgn, res_sig, res_exp, v7); + expr_ref bv_rm(m); + m_bv_util.mk_numeral(BV_RM_TIES_TO_EVEN, 3); + round(f->get_range(), bv_rm, res_sgn, res_sig, res_exp, v7); // And finally, we tie them together. mk_ite(c6, v6, v7, result); @@ -1211,10 +1216,11 @@ expr_ref fpa2bv_converter::mk_max_unspecified(func_decl * f, expr * x, expr * y) void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 4); - + SASSERT(is_app_of(args[0], m_util.get_family_id(), OP_FPA_INTERNAL_RM)); + // fusedma means (x * y) + z - expr_ref rm(m), x(m), y(m), z(m); - rm = args[0]; + expr_ref bv_rm(m), x(m), y(m), z(m); + bv_rm = to_app(args[0])->get_arg(0); x = args[1]; y = args[2]; z = args[3]; @@ -1246,7 +1252,7 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, mk_is_inf(z, z_is_inf); expr_ref rm_is_to_neg(m); - mk_is_rm(rm, BV_RM_TO_NEGATIVE, rm_is_to_neg); + mk_is_rm(bv_rm, BV_RM_TO_NEGATIVE, rm_is_to_neg); dbg_decouple("fpa2bv_fma_x_is_nan", x_is_nan); dbg_decouple("fpa2bv_fma_x_is_zero", x_is_zero); @@ -1508,7 +1514,7 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, mk_ite(rm_is_to_neg, nzero, pzero, zero_case); expr_ref rounded(m); - round(f->get_range(), rm, res_sgn, res_sig, res_exp, rounded); + round(f->get_range(), bv_rm, res_sgn, res_sig, res_exp, rounded); mk_ite(is_zero_sig, zero_case, rounded, v8); @@ -1528,9 +1534,10 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, void fpa2bv_converter::mk_sqrt(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 2); - - expr_ref rm(m), x(m); - rm = args[0]; + SASSERT(is_app_of(args[0], m_util.get_family_id(), OP_FPA_INTERNAL_RM)); + + expr_ref bv_rm(m), x(m); + bv_rm = to_app(args[0])->get_arg(0); x = args[1]; expr_ref nan(m), nzero(m), pzero(m), ninf(m), pinf(m); @@ -1661,7 +1668,7 @@ void fpa2bv_converter::mk_sqrt(func_decl * f, unsigned num, expr * const * args, SASSERT(m_bv_util.get_bv_size(res_sig) == sbits + 4); expr_ref rounded(m); - round(f->get_range(), rm, res_sgn, res_sig, res_exp, rounded); + round(f->get_range(), bv_rm, res_sgn, res_sig, res_exp, rounded); v5 = rounded; // And finally, we tie them together. @@ -1675,17 +1682,18 @@ void fpa2bv_converter::mk_sqrt(func_decl * f, unsigned num, expr * const * args, void fpa2bv_converter::mk_round_to_integral(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 2); - - expr_ref rm(m), x(m); - rm = args[0]; + SASSERT(is_app_of(args[0], m_util.get_family_id(), OP_FPA_INTERNAL_RM)); + + expr_ref bv_rm(m), x(m); + bv_rm = to_app(args[0])->get_arg(0); x = args[1]; expr_ref rm_is_rta(m), rm_is_rte(m), rm_is_rtp(m), rm_is_rtn(m), rm_is_rtz(m); - mk_is_rm(rm, BV_RM_TIES_TO_AWAY, rm_is_rta); - mk_is_rm(rm, BV_RM_TIES_TO_EVEN, rm_is_rte); - mk_is_rm(rm, BV_RM_TO_POSITIVE, rm_is_rtp); - mk_is_rm(rm, BV_RM_TO_NEGATIVE, rm_is_rtn); - mk_is_rm(rm, BV_RM_TO_ZERO, rm_is_rtz); + mk_is_rm(bv_rm, BV_RM_TIES_TO_AWAY, rm_is_rta); + mk_is_rm(bv_rm, BV_RM_TIES_TO_EVEN, rm_is_rte); + mk_is_rm(bv_rm, BV_RM_TO_POSITIVE, rm_is_rtp); + mk_is_rm(bv_rm, BV_RM_TO_NEGATIVE, rm_is_rtn); + mk_is_rm(bv_rm, BV_RM_TO_ZERO, rm_is_rtz); expr_ref nan(m), nzero(m), pzero(m), ninf(m), pinf(m); mk_nan(f, nan); @@ -1862,7 +1870,7 @@ void fpa2bv_converter::mk_round_to_integral(func_decl * f, unsigned num, expr * SASSERT(m_bv_util.get_bv_size(res_exp) == ebits + 2); // CMW: We use the rounder for normalization. - round(f->get_range(), rm, res_sgn, res_sig, res_exp, v6); + round(f->get_range(), bv_rm, res_sgn, res_sig, res_exp, v6); // And finally, we tie them together. mk_ite(c5, v5, v6, result); @@ -2436,7 +2444,8 @@ void fpa2bv_converter::mk_to_fp_real_int(func_decl * f, unsigned num, expr * con unsigned ebits = m_util.get_ebits(f->get_range()); unsigned sbits = m_util.get_sbits(f->get_range()); - expr * rm = args[0]; + SASSERT(is_app_of(args[0], m_util.get_family_id(), OP_FPA_INTERNAL_RM)); + expr * bv_rm = to_app(args[0])->get_arg(0); rational q; if (!m_arith_util.is_numeral(args[1], q)) @@ -2474,10 +2483,10 @@ void fpa2bv_converter::mk_to_fp_real_int(func_decl * f, unsigned num, expr * con mk_numeral(a_tz->get_decl(), 0, 0, bv_tz); 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)); - 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)); - c4 = m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TIES_TO_EVEN, 3)); + c1 = m.mk_eq(bv_rm, m_bv_util.mk_numeral(BV_RM_TO_POSITIVE, 3)); + c2 = m.mk_eq(bv_rm, m_bv_util.mk_numeral(BV_RM_TO_POSITIVE, 3)); + c3 = m.mk_eq(bv_rm, m_bv_util.mk_numeral(BV_RM_TIES_TO_AWAY, 3)); + c4 = m.mk_eq(bv_rm, m_bv_util.mk_numeral(BV_RM_TIES_TO_EVEN, 3)); mk_ite(c1, bv_tn, bv_tz, result); mk_ite(c2, bv_tp, result, result); @@ -2586,9 +2595,10 @@ void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const SASSERT(m_util.is_float(f->get_range())); SASSERT(m_bv_util.is_bv(args[0])); SASSERT(m_bv_util.is_bv(args[1])); + SASSERT(is_app_of(args[0], m_util.get_family_id(), OP_FPA_INTERNAL_RM)); - expr_ref rm(m), x(m); - rm = args[0]; + expr_ref bv_rm(m), x(m); + bv_rm = to_app(args[0])->get_arg(0); x = args[1]; dbg_decouple("fpa2bv_to_fp_signed_x", x); @@ -2596,7 +2606,7 @@ void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const unsigned ebits = m_util.get_ebits(f->get_range()); unsigned sbits = m_util.get_sbits(f->get_range()); unsigned bv_sz = m_bv_util.get_bv_size(x); - SASSERT(m_bv_util.get_bv_size(rm) == 3); + SASSERT(m_bv_util.get_bv_size(bv_rm) == 3); expr_ref bv0_1(m), bv1_1(m), bv0_sz(m), bv1_sz(m); bv0_1 = m_bv_util.mk_numeral(0, 1); @@ -2704,7 +2714,7 @@ void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const SASSERT(m_bv_util.get_bv_size(exp) == ebits + 2); expr_ref v2(m); - round(f->get_range(), rm, sgn, sig, exp, v2); + round(f->get_range(), bv_rm, sgn, sig, exp, v2); mk_ite(c1, v1, v2, result); } @@ -2726,9 +2736,10 @@ void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * con SASSERT(m_util.is_float(f->get_range())); SASSERT(m_bv_util.is_bv(args[0])); SASSERT(m_bv_util.is_bv(args[1])); + SASSERT(is_app_of(args[0], m_util.get_family_id(), OP_FPA_INTERNAL_RM)); - expr_ref rm(m), x(m); - rm = args[0]; + expr_ref bv_rm(m), x(m); + bv_rm = to_app(args[0])->get_arg(0); x = args[1]; dbg_decouple("fpa2bv_to_fp_unsigned_x", x); @@ -2736,7 +2747,7 @@ void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * con unsigned ebits = m_util.get_ebits(f->get_range()); unsigned sbits = m_util.get_sbits(f->get_range()); unsigned bv_sz = m_bv_util.get_bv_size(x); - SASSERT(m_bv_util.get_bv_size(rm) == 3); + SASSERT(m_bv_util.get_bv_size(bv_rm) == 3); expr_ref bv0_1(m), bv1_1(m), bv0_sz(m), bv1_sz(m); bv0_1 = m_bv_util.mk_numeral(0, 1); @@ -2836,7 +2847,7 @@ void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * con SASSERT(m_bv_util.get_bv_size(exp) == ebits + 2); expr_ref v2(m); - round(f->get_range(), rm, sgn, sig, exp, v2); + round(f->get_range(), bv_rm, sgn, sig, exp, v2); mk_ite(c1, v1, v2, result); } @@ -2852,13 +2863,11 @@ void fpa2bv_converter::mk_to_bv(func_decl * f, unsigned num, expr * const * args TRACE("fpa2bv_to_bv", for (unsigned i = 0; i < num; i++) tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl;); - SASSERT(f->get_num_parameters() == 1); - SASSERT(f->get_parameter(0).is_int()); SASSERT(num == 2); - SASSERT(m_bv_util.get_bv_size(args[0]) == 3); - SASSERT(m_util.is_float(args[1])); + SASSERT(is_app_of(args[0], m_util.get_family_id(), OP_FPA_INTERNAL_RM)); + SASSERT(m_util.is_float(args[1])); - expr * rm = args[0]; + expr * bv_rm = to_app(args[0])->get_arg(0); expr * x = args[1]; sort * xs = m.get_sort(x); sort * bv_srt = f->get_range(); @@ -2868,7 +2877,6 @@ void fpa2bv_converter::mk_to_bv(func_decl * f, unsigned num, expr * const * args unsigned bv_sz = (unsigned)f->get_parameter(0).get_int(); expr_ref bv0(m), bv1(m); - bv0 = m_bv_util.mk_numeral(0, 1); bv1 = m_bv_util.mk_numeral(1, 1); expr_ref x_is_nan(m), x_is_inf(m), x_is_zero(m), x_is_neg(m), x_is_nzero(m); @@ -2961,7 +2969,7 @@ void fpa2bv_converter::mk_to_bv(func_decl * f, unsigned num, expr * const * args dbg_decouple("fpa2bv_to_bv_sticky", sticky); expr_ref rounding_decision(m); - rounding_decision = mk_rounding_decision(rm, sgn, last, round, sticky); + rounding_decision = mk_rounding_decision(bv_rm, sgn, last, round, sticky); SASSERT(m_bv_util.get_bv_size(rounding_decision) == 1); dbg_decouple("fpa2bv_to_bv_rounding_decision", rounding_decision); @@ -3024,6 +3032,11 @@ expr_ref fpa2bv_converter::mk_to_real_unspecified() { return expr_ref(m_util.mk_internal_to_real_unspecified(), m); } +void fpa2bv_converter::mk_rm(expr * bv3, expr_ref & result) { + SASSERT(m_bv_util.is_bv(bv3) && m_bv_util.get_bv_size(bv3) == 3); + result = m.mk_app(m_util.get_family_id(), OP_FPA_INTERNAL_RM, 0, 0, 1, &bv3, m_util.mk_rm_sort()); +} + void fpa2bv_converter::mk_fp(expr * sign, expr * exponent, expr * significand, expr_ref & result) { SASSERT(m_bv_util.is_bv(sign) && m_bv_util.get_bv_size(sign) == 1); SASSERT(m_bv_util.is_bv(significand)); @@ -3177,18 +3190,18 @@ void fpa2bv_converter::mk_is_normal(expr * e, expr_ref & result) { m_simp.mk_not(or_ex, result); } -void fpa2bv_converter::mk_is_rm(expr * e, BV_RM_VAL rm, expr_ref & result) { - SASSERT(m_bv_util.is_bv(e) && m_bv_util.get_bv_size(e) == 3); +void fpa2bv_converter::mk_is_rm(expr * bv_rm, BV_RM_VAL rm, expr_ref & result) { expr_ref rm_num(m); rm_num = m_bv_util.mk_numeral(rm, 3); + switch(rm) { - case BV_RM_TIES_TO_AWAY: - case BV_RM_TIES_TO_EVEN: + case BV_RM_TIES_TO_AWAY: + case BV_RM_TIES_TO_EVEN: case BV_RM_TO_NEGATIVE: - case BV_RM_TO_POSITIVE: + case BV_RM_TO_POSITIVE: case BV_RM_TO_ZERO: - return m_simp.mk_eq(e, rm_num, result); + return m_simp.mk_eq(bv_rm, rm_num, result); default: UNREACHABLE(); } @@ -3384,6 +3397,8 @@ void fpa2bv_converter::mk_rounding_mode(func_decl * f, expr_ref & result) case OP_FPA_RM_TOWARD_ZERO: result = m_bv_util.mk_numeral(BV_RM_TO_ZERO, 3); break; default: UNREACHABLE(); } + + mk_rm(result, result); } void fpa2bv_converter::dbg_decouple(const char * prefix, expr_ref & e) { @@ -3397,8 +3412,8 @@ void fpa2bv_converter::dbg_decouple(const char * prefix, expr_ref & e) { #endif } -expr_ref fpa2bv_converter::mk_rounding_decision(expr * rm, expr * sgn, expr * last, expr * round, expr * sticky) { - expr_ref rmr(rm, m); +expr_ref fpa2bv_converter::mk_rounding_decision(expr * bv_rm, expr * sgn, expr * last, expr * round, expr * sticky) { + expr_ref rmr(bv_rm, m); expr_ref sgnr(sgn, m); expr_ref lastr(last, m); expr_ref roundr(round, m); @@ -3437,10 +3452,10 @@ expr_ref fpa2bv_converter::mk_rounding_decision(expr * rm, expr * sgn, expr * la expr_ref res(m), inc_c2(m), inc_c3(m), inc_c4(m); expr_ref rm_is_to_neg(m), rm_is_to_pos(m), rm_is_away(m), rm_is_even(m), nil_1(m); nil_1 = m_bv_util.mk_numeral(0, 1); - mk_is_rm(rm, BV_RM_TO_NEGATIVE, rm_is_to_neg); - mk_is_rm(rm, BV_RM_TO_POSITIVE, rm_is_to_pos); - mk_is_rm(rm, BV_RM_TIES_TO_AWAY, rm_is_away); - mk_is_rm(rm, BV_RM_TIES_TO_EVEN, rm_is_even); + mk_is_rm(bv_rm, BV_RM_TO_NEGATIVE, rm_is_to_neg); + mk_is_rm(bv_rm, BV_RM_TO_POSITIVE, rm_is_to_pos); + mk_is_rm(bv_rm, BV_RM_TIES_TO_AWAY, rm_is_away); + mk_is_rm(bv_rm, BV_RM_TIES_TO_EVEN, rm_is_even); m_simp.mk_ite(rm_is_to_neg, inc_neg, nil_1, inc_c4); m_simp.mk_ite(rm_is_to_pos, inc_pos, inc_c4, inc_c3); m_simp.mk_ite(rm_is_away, inc_taway, inc_c3, inc_c2); @@ -3450,16 +3465,16 @@ expr_ref fpa2bv_converter::mk_rounding_decision(expr * rm, expr * sgn, expr * la return res; } -void fpa2bv_converter::round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & sig, expr_ref & exp, expr_ref & result) { +void fpa2bv_converter::round(sort * s, expr_ref & bv_rm, expr_ref & sgn, expr_ref & sig, expr_ref & exp, expr_ref & result) { unsigned ebits = m_util.get_ebits(s); unsigned sbits = m_util.get_sbits(s); - dbg_decouple("fpa2bv_rnd_rm", rm); + dbg_decouple("fpa2bv_rnd_rm", bv_rm); dbg_decouple("fpa2bv_rnd_sgn", sgn); dbg_decouple("fpa2bv_rnd_sig", sig); dbg_decouple("fpa2bv_rnd_exp", exp); - SASSERT(is_well_sorted(m, rm)); + SASSERT(is_well_sorted(m, bv_rm)); SASSERT(is_well_sorted(m, sgn)); SASSERT(is_well_sorted(m, sig)); SASSERT(is_well_sorted(m, exp)); @@ -3475,7 +3490,7 @@ void fpa2bv_converter::round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & // i.e., it has 2 + (sbits-1) + 3 = sbits + 4 bits, where the first one is in sgn. // Furthermore, note that sig is an unsigned bit-vector, while exp is signed. - SASSERT(m_bv_util.is_bv(rm) && m_bv_util.get_bv_size(rm) == 3); + SASSERT(m_bv_util.is_bv(bv_rm) && m_bv_util.get_bv_size(bv_rm) == 3); SASSERT(m_bv_util.is_bv(sgn) && m_bv_util.get_bv_size(sgn) == 1); SASSERT(m_bv_util.is_bv(sig) && m_bv_util.get_bv_size(sig) >= 5); SASSERT(m_bv_util.is_bv(exp) && m_bv_util.get_bv_size(exp) >= 4); @@ -3625,7 +3640,7 @@ void fpa2bv_converter::round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & sig = m_bv_util.mk_extract(sbits+1, 2, sig); expr_ref inc(m); - inc = mk_rounding_decision(rm, sgn, last, round, sticky); + inc = mk_rounding_decision(bv_rm, sgn, last, round, sticky); SASSERT(m_bv_util.get_bv_size(inc) == 1 && is_well_sorted(m, inc)); dbg_decouple("fpa2bv_rnd_inc", inc); @@ -3698,9 +3713,9 @@ void fpa2bv_converter::round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & nil_1 = m_bv_util.mk_numeral(0, 1); expr_ref rm_is_to_zero(m), rm_is_to_neg(m), rm_is_to_pos(m), rm_zero_or_neg(m), rm_zero_or_pos(m); - mk_is_rm(rm, BV_RM_TO_ZERO, rm_is_to_zero); - mk_is_rm(rm, BV_RM_TO_NEGATIVE, rm_is_to_neg); - mk_is_rm(rm, BV_RM_TO_POSITIVE, rm_is_to_pos); + mk_is_rm(bv_rm, BV_RM_TO_ZERO, rm_is_to_zero); + mk_is_rm(bv_rm, BV_RM_TO_NEGATIVE, rm_is_to_neg); + mk_is_rm(bv_rm, BV_RM_TO_POSITIVE, rm_is_to_pos); m_simp.mk_or(rm_is_to_zero, rm_is_to_neg, rm_zero_or_neg); m_simp.mk_or(rm_is_to_zero, rm_is_to_pos, rm_zero_or_pos); dbg_decouple("fpa2bv_rnd_rm_is_to_zero", rm_is_to_zero); diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index 6fb905708..ed59a32d1 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -26,8 +26,6 @@ Notes: #include"bv_decl_plugin.h" #include"basic_simplifier_plugin.h" -typedef enum { BV_RM_TIES_TO_EVEN, BV_RM_TIES_TO_AWAY, BV_RM_TO_POSITIVE, BV_RM_TO_NEGATIVE, BV_RM_TO_ZERO = 4 } BV_RM_VAL; - struct func_decl_triple { func_decl_triple () { f_sgn = 0; f_sig = 0; f_exp = 0; } func_decl_triple (func_decl * sgn, func_decl * sig, func_decl * exp) @@ -77,6 +75,8 @@ public: bool is_rm(sort * s) { return m_util.is_rm(s); } bool is_float_family(func_decl * f) { return f->get_family_id() == m_util.get_family_id(); } + void mk_rm(expr * bv3, expr_ref & result); + void mk_fp(expr * sign, expr * exponent, expr * significand, expr_ref & result); void mk_fp(func_decl * f, unsigned num, expr * const * args, expr_ref & result); @@ -191,7 +191,7 @@ protected: void round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & sig, expr_ref & exp, expr_ref & result); expr_ref mk_rounding_decision(expr * rm, expr * sgn, expr * last, expr * round, expr * sticky); - void add_core(unsigned sbits, unsigned ebits, expr_ref & rm, + void add_core(unsigned sbits, unsigned ebits, expr_ref & c_sgn, expr_ref & c_sig, expr_ref & c_exp, expr_ref & d_sgn, expr_ref & d_sig, expr_ref & d_exp, expr_ref & res_sgn, expr_ref & res_sig, expr_ref & res_exp); diff --git a/src/ast/fpa/fpa2bv_rewriter.h b/src/ast/fpa/fpa2bv_rewriter.h index 054133cc8..e2ecc388a 100644 --- a/src/ast/fpa/fpa2bv_rewriter.h +++ b/src/ast/fpa/fpa2bv_rewriter.h @@ -123,7 +123,7 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { } if (m_conv.is_float_family(f)) { - switch (f->get_decl_kind()) { + switch (f->get_decl_kind()) { case OP_FPA_RM_NEAREST_TIES_TO_AWAY: case OP_FPA_RM_NEAREST_TIES_TO_EVEN: case OP_FPA_RM_TOWARD_NEGATIVE: diff --git a/src/ast/fpa_decl_plugin.cpp b/src/ast/fpa_decl_plugin.cpp index 5a8063c37..d32aa5e6d 100644 --- a/src/ast/fpa_decl_plugin.cpp +++ b/src/ast/fpa_decl_plugin.cpp @@ -647,7 +647,7 @@ func_decl * fpa_decl_plugin::mk_to_real(decl_kind k, unsigned num_parameters, pa } func_decl * fpa_decl_plugin::mk_to_ieee_bv(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range) { + unsigned arity, sort * const * domain, sort * range) { if (arity != 1) m_manager->raise_exception("invalid number of arguments to to_ieee_bv"); if (!is_float_sort(domain[0])) @@ -660,6 +660,20 @@ func_decl * fpa_decl_plugin::mk_to_ieee_bv(decl_kind k, unsigned num_parameters, return m_manager->mk_func_decl(name, 1, domain, bv_srt, func_decl_info(m_family_id, k, num_parameters, parameters)); } +func_decl * fpa_decl_plugin::mk_internal_rm(decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range) { + if (arity != 1) + m_manager->raise_exception("invalid number of arguments to internal_rm"); + if (!is_sort_of(domain[0], m_bv_fid, BV_SORT) || domain[0]->get_parameter(0).get_int() != 3) + m_manager->raise_exception("sort mismatch, expected argument of sort bitvector, size 3"); + if (!is_rm_sort(range)) + m_manager->raise_exception("sort mismatch, expected range of RoundingMode sort"); + + parameter ps[] = { parameter(3) }; + sort * bv_srt = m_bv_plugin->mk_sort(m_bv_fid, 1, ps); + return m_manager->mk_func_decl(symbol("rm"), 1, &bv_srt, range, func_decl_info(m_family_id, k, num_parameters, parameters)); +} + func_decl * fpa_decl_plugin::mk_internal_bv_wrap(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (arity != 1) @@ -688,7 +702,7 @@ func_decl * fpa_decl_plugin::mk_internal_bv_unwrap(decl_kind k, unsigned num_par if (!is_sort_of(domain[0], m_bv_fid, BV_SORT)) m_manager->raise_exception("sort mismatch, expected argument of bitvector sort"); if (!is_float_sort(range) && !is_rm_sort(range)) - m_manager->raise_exception("sort mismatch, expected range of FloatingPoint sort"); + m_manager->raise_exception("sort mismatch, expected range of FloatingPoint or RoundingMode sort"); return m_manager->mk_func_decl(symbol("bv_unwrap"), 1, domain, range, func_decl_info(m_family_id, k, num_parameters, parameters)); } @@ -796,6 +810,9 @@ func_decl * fpa_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, return mk_to_fp_unsigned(k, num_parameters, parameters, arity, domain, range); case OP_FPA_TO_IEEE_BV: return mk_to_ieee_bv(k, num_parameters, parameters, arity, domain, range); + + case OP_FPA_INTERNAL_RM: + return mk_internal_rm(k, num_parameters, parameters, arity, domain, range); case OP_FPA_INTERNAL_BVWRAP: return mk_internal_bv_wrap(k, num_parameters, parameters, arity, domain, range); case OP_FPA_INTERNAL_BVUNWRAP: diff --git a/src/ast/fpa_decl_plugin.h b/src/ast/fpa_decl_plugin.h index 34a9daa59..bf82aa487 100644 --- a/src/ast/fpa_decl_plugin.h +++ b/src/ast/fpa_decl_plugin.h @@ -34,6 +34,8 @@ enum fpa_sort_kind { FLOAT128_SORT }; +typedef enum { BV_RM_TIES_TO_EVEN, BV_RM_TIES_TO_AWAY, BV_RM_TO_POSITIVE, BV_RM_TO_NEGATIVE, BV_RM_TO_ZERO = 4 } BV_RM_VAL; + enum fpa_op_kind { OP_FPA_RM_NEAREST_TIES_TO_EVEN, OP_FPA_RM_NEAREST_TIES_TO_AWAY, @@ -85,6 +87,7 @@ enum fpa_op_kind { OP_FPA_TO_IEEE_BV, /* Internal use only */ + OP_FPA_INTERNAL_RM, // Internal conversion from (_ BitVec 3) to RoundingMode OP_FPA_INTERNAL_BVWRAP, OP_FPA_INTERNAL_BVUNWRAP, @@ -128,6 +131,7 @@ class fpa_decl_plugin : public decl_plugin { sort * mk_float_sort(unsigned ebits, unsigned sbits); sort * mk_rm_sort(); + func_decl * mk_rm_const_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); func_decl * mk_float_const_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, @@ -161,6 +165,8 @@ class fpa_decl_plugin : public decl_plugin { func_decl * mk_to_ieee_bv(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); + func_decl * mk_internal_rm(decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range); func_decl * mk_internal_bv_wrap(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); func_decl * mk_internal_bv_unwrap(decl_kind k, unsigned num_parameters, parameter const * parameters, @@ -175,6 +181,7 @@ class fpa_decl_plugin : public decl_plugin { virtual void set_manager(ast_manager * m, family_id id); unsigned mk_id(mpf const & v); void recycled_id(unsigned id); + public: fpa_decl_plugin(); diff --git a/src/ast/rewriter/fpa_rewriter.cpp b/src/ast/rewriter/fpa_rewriter.cpp index 2a800f004..4da3b3169 100644 --- a/src/ast/rewriter/fpa_rewriter.cpp +++ b/src/ast/rewriter/fpa_rewriter.cpp @@ -99,6 +99,8 @@ br_status fpa_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * con case OP_FPA_INTERNAL_MAX_UNSPECIFIED: SASSERT(num_args == 2); st = BR_FAILED; break; + case OP_FPA_INTERNAL_RM: + SASSERT(num_args == 1); st = mk_rm(args[0], result); break; case OP_FPA_INTERNAL_TO_UBV_UNSPECIFIED: SASSERT(num_args == 0); st = mk_to_ubv_unspecified(f, result); break; case OP_FPA_INTERNAL_TO_SBV_UNSPECIFIED: @@ -719,6 +721,27 @@ br_status fpa_rewriter::mk_eq_core(expr * arg1, expr * arg2, expr_ref & result) return BR_FAILED; } +br_status fpa_rewriter::mk_rm(expr * arg, expr_ref & result) { + bv_util bu(m()); + rational bv_val; + unsigned sz = 0; + if (bu.is_numeral(arg, bv_val, sz)) { + SASSERT(bv_val.is_uint64()); + switch (bv_val.get_uint64()) { + case BV_RM_TIES_TO_AWAY: result = m_util.mk_round_nearest_ties_to_away(); break; + case BV_RM_TIES_TO_EVEN: result = m_util.mk_round_nearest_ties_to_even(); break; + case BV_RM_TO_NEGATIVE: result = m_util.mk_round_toward_negative(); break; + case BV_RM_TO_POSITIVE: result = m_util.mk_round_toward_positive(); break; + case BV_RM_TO_ZERO: + default: result = m_util.mk_round_toward_zero(); + } + + return BR_DONE; + } + + return BR_FAILED; +} + br_status fpa_rewriter::mk_fp(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) { unsynch_mpz_manager & mpzm = m_fm.mpz_manager(); bv_util bu(m()); diff --git a/src/ast/rewriter/fpa_rewriter.h b/src/ast/rewriter/fpa_rewriter.h index 41a929e4b..689ffad3c 100644 --- a/src/ast/rewriter/fpa_rewriter.h +++ b/src/ast/rewriter/fpa_rewriter.h @@ -77,6 +77,8 @@ public: br_status mk_to_fp(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result); br_status mk_to_fp_unsigned(func_decl * f, expr * arg1, expr * arg2, expr_ref & result); + + br_status mk_rm(expr * arg, expr_ref & result); br_status mk_fp(expr * arg1, expr * arg2, expr * arg3, expr_ref & result); br_status mk_to_fp_unsigned(expr * arg1, expr * arg2, expr_ref & result); br_status mk_to_ubv(func_decl * f, expr * arg1, expr * arg2, expr_ref & result); diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index cf6a367a9..66af5c815 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -314,6 +314,7 @@ namespace smt { expr_ref theory_fpa::convert_atom(expr * e) { ast_manager & m = get_manager(); + TRACE("t_fpa_detail", tout << "converting atom: " << mk_ismt2_pp(e, get_manager()) << "\n";); expr_ref res(m); proof_ref pr(m); m_rw(e, res); diff --git a/src/tactic/fpa/fpa2bv_model_converter.cpp b/src/tactic/fpa/fpa2bv_model_converter.cpp index af0d5e5fc..eb6d724c9 100644 --- a/src/tactic/fpa/fpa2bv_model_converter.cpp +++ b/src/tactic/fpa/fpa2bv_model_converter.cpp @@ -157,6 +157,7 @@ expr_ref fpa2bv_model_converter::convert_bv2rm(expr * eval_v) const { rational bv_val(0); unsigned sz = 0; + if (bu.is_numeral(eval_v, bv_val, sz)) { SASSERT(bv_val.is_uint64()); switch (bv_val.get_uint64()) { @@ -255,8 +256,10 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) { func_decl * var = it->m_key; SASSERT(fu.is_rm(var->get_range())); expr * val = it->m_value; + SASSERT(is_app_of(val, fu.get_family_id(), OP_FPA_INTERNAL_RM)); + expr * bvval = to_app(val)->get_arg(0); expr_ref fv(m); - fv = convert_bv2rm(bv_mdl, var, val); + fv = convert_bv2rm(bv_mdl, var, bvval); TRACE("fpa2bv_mc", tout << var->get_name() << " == " << mk_ismt2_pp(fv, m) << std::endl;); float_mdl->register_decl(var, fv); seen.insert(to_app(val)->get_decl()); From 9b5abcd55a641dbe8583cc1740d7161c5c0cf7be Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 21 Oct 2015 20:11:59 +0100 Subject: [PATCH 47/57] Improved support for FPA unspecified min/max values, model validation, and proof generation. --- src/ast/fpa/fpa2bv_converter.cpp | 176 ++++++++++++++-------- src/ast/fpa/fpa2bv_converter.h | 11 +- src/ast/fpa/fpa2bv_rewriter.h | 6 +- src/ast/rewriter/fpa_rewriter.cpp | 38 +++-- src/smt/theory_fpa.cpp | 32 ++-- src/tactic/fpa/fpa2bv_model_converter.cpp | 10 +- src/tactic/fpa/fpa2bv_model_converter.h | 16 +- src/tactic/fpa/fpa2bv_tactic.cpp | 9 +- 8 files changed, 192 insertions(+), 106 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index cba2b3a7f..c3feeb10a 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -42,6 +42,16 @@ fpa2bv_converter::fpa2bv_converter(ast_manager & m) : m_max_np_zeros(0, m), m_extra_assertions(m) { m_plugin = static_cast(m.get_plugin(m.mk_family_id("fpa"))); + + m_min_pn_zeros = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); + m_min_np_zeros = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); + m_decls_to_hide.insert_if_not_there(m_min_pn_zeros->get_decl()); + m_decls_to_hide.insert_if_not_there(m_min_np_zeros->get_decl()); + + m_max_pn_zeros = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); + m_max_np_zeros = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); + m_decls_to_hide.insert_if_not_there(m_max_pn_zeros->get_decl()); + m_decls_to_hide.insert_if_not_there(m_min_np_zeros->get_decl()); } fpa2bv_converter::~fpa2bv_converter() { @@ -49,35 +59,48 @@ fpa2bv_converter::~fpa2bv_converter() { } void fpa2bv_converter::mk_eq(expr * a, expr * b, expr_ref & result) { - SASSERT(is_app_of(a, m_plugin->get_family_id(), OP_FPA_FP)); - SASSERT(is_app_of(b, m_plugin->get_family_id(), OP_FPA_FP)); + if (is_float(a) && is_float(b)) { + SASSERT(is_app_of(a, m_plugin->get_family_id(), OP_FPA_FP)); + SASSERT(is_app_of(b, m_plugin->get_family_id(), OP_FPA_FP)); - TRACE("fpa2bv", tout << "mk_eq a=" << mk_ismt2_pp(a, m) << std::endl; - tout << "mk_eq b=" << mk_ismt2_pp(b, m) << std::endl;); + TRACE("fpa2bv", tout << "mk_eq a=" << mk_ismt2_pp(a, m) << std::endl; + tout << "mk_eq b=" << mk_ismt2_pp(b, m) << std::endl;); - expr_ref eq_sgn(m), eq_exp(m), eq_sig(m); - m_simp.mk_eq(to_app(a)->get_arg(0), to_app(b)->get_arg(0), eq_sgn); - m_simp.mk_eq(to_app(a)->get_arg(1), to_app(b)->get_arg(1), eq_exp); - m_simp.mk_eq(to_app(a)->get_arg(2), to_app(b)->get_arg(2), eq_sig); + expr_ref eq_sgn(m), eq_exp(m), eq_sig(m); + m_simp.mk_eq(to_app(a)->get_arg(0), to_app(b)->get_arg(0), eq_sgn); + m_simp.mk_eq(to_app(a)->get_arg(1), to_app(b)->get_arg(1), eq_exp); + m_simp.mk_eq(to_app(a)->get_arg(2), to_app(b)->get_arg(2), eq_sig); - dbg_decouple("fpa2bv_eq_sgn", eq_sgn); - dbg_decouple("fpa2bv_eq_exp", eq_exp); - dbg_decouple("fpa2bv_eq_sig", eq_sig); + dbg_decouple("fpa2bv_eq_sgn", eq_sgn); + dbg_decouple("fpa2bv_eq_exp", eq_exp); + dbg_decouple("fpa2bv_eq_sig", eq_sig); - expr_ref both_the_same(m); - m_simp.mk_and(eq_sgn, eq_exp, eq_sig, both_the_same); - dbg_decouple("fpa2bv_eq_both_the_same", both_the_same); + expr_ref both_the_same(m); + m_simp.mk_and(eq_sgn, eq_exp, eq_sig, both_the_same); + dbg_decouple("fpa2bv_eq_both_the_same", both_the_same); - // The SMT FPA theory asks for _one_ NaN value, but the bit-blasting - // has many, like IEEE754. This encoding of equality makes it look like - // a single NaN again. - expr_ref a_is_nan(m), b_is_nan(m), both_are_nan(m); - mk_is_nan(a, a_is_nan); - mk_is_nan(b, b_is_nan); - m_simp.mk_and(a_is_nan, b_is_nan, both_are_nan); - dbg_decouple("fpa2bv_eq_both_are_nan", both_are_nan); + // The SMT FPA theory asks for _one_ NaN value, but the bit-blasting + // has many, like IEEE754. This encoding of equality makes it look like + // a single NaN again. + expr_ref a_is_nan(m), b_is_nan(m), both_are_nan(m); + mk_is_nan(a, a_is_nan); + mk_is_nan(b, b_is_nan); + m_simp.mk_and(a_is_nan, b_is_nan, both_are_nan); + dbg_decouple("fpa2bv_eq_both_are_nan", both_are_nan); - m_simp.mk_or(both_are_nan, both_the_same, result); + m_simp.mk_or(both_are_nan, both_the_same, result); + } + else if (is_rm(a) && is_rm(b)) { + SASSERT(is_app_of(a, m_plugin->get_family_id(), OP_FPA_INTERNAL_RM)); + SASSERT(is_app_of(b, m_plugin->get_family_id(), OP_FPA_INTERNAL_RM)); + + TRACE("fpa2bv", tout << "mk_eq_rm a=" << mk_ismt2_pp(a, m) << std::endl; + tout << "mk_eq_rm b=" << mk_ismt2_pp(b, m) << std::endl;); + + m_simp.mk_eq(to_app(a)->get_arg(0), to_app(b)->get_arg(0), result); + } + else + UNREACHABLE(); } void fpa2bv_converter::mk_ite(expr * c, expr * t, expr * f, expr_ref & result) { @@ -224,6 +247,11 @@ void fpa2bv_converter::mk_uninterpreted_output(sort * rng, func_decl * fbv, expr m_bv_util.mk_extract(sbits - 2, 0, na), result); } + else if (m_util.is_rm(rng)) { + app_ref na(m); + na = m.mk_app(fbv, new_args.size(), new_args.c_ptr()); + mk_rm(na, result); + } else result = m.mk_app(fbv, new_args.size(), new_args.c_ptr()); } @@ -242,6 +270,10 @@ void fpa2bv_converter::mk_uninterpreted_function(func_decl * f, unsigned num, ex expr * args[3] = { sgn, exp, sig }; new_args.push_back(m_bv_util.mk_concat(3, args)); } + else if (is_rm(args[i])) { + SASSERT(is_app_of(args[i], m_util.get_family_id(), OP_FPA_INTERNAL_RM)); + new_args.push_back(to_app(args[i])->get_arg(0)); + } else new_args.push_back(args[i]); } @@ -1073,6 +1105,21 @@ void fpa2bv_converter::mk_abs(func_decl * f, unsigned num, expr * const * args, mk_fp(m_bv_util.mk_numeral(0, 1), e, s, result); } +void fpa2bv_converter::mk_min(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { + expr_ref x(m), y(m); + x = args[0]; + y = args[1]; + + expr_ref c(m), v(m); + c = m.mk_and(m.mk_and(m_util.mk_is_zero(x), m_util.mk_is_zero(y)), + m.mk_or(m.mk_and(m_util.mk_is_positive(x), m_util.mk_is_negative(y)), + m.mk_and(m_util.mk_is_negative(x), m_util.mk_is_positive(y)))); + v = m.mk_app(m_util.get_family_id(), OP_FPA_INTERNAL_MIN_UNSPECIFIED, x, y); + + // Note: This requires BR_REWRITE_FULL afterwards. + result = m.mk_ite(c, v, m.mk_app(m_util.get_family_id(), OP_FPA_INTERNAL_MIN_I, x, y)); +} + void fpa2bv_converter::mk_min_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 2); @@ -1117,9 +1164,6 @@ expr_ref fpa2bv_converter::mk_min_unspecified(func_decl * f, expr * x, expr * y) // The hardware interpretation is -0.0. mk_nzero(f, res); else { - if (m_min_pn_zeros.get() == 0) m_min_pn_zeros = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); - if (m_min_np_zeros.get() == 0) m_min_np_zeros = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); - expr_ref pn(m), np(m); mk_fp(m_min_pn_zeros, m_bv_util.mk_numeral(0, ebits), @@ -1130,24 +1174,31 @@ expr_ref fpa2bv_converter::mk_min_unspecified(func_decl * f, expr * x, expr * y) m_bv_util.mk_numeral(0, sbits - 1), np); - expr_ref x_is_pzero(m), x_is_nzero(m), ite(m); + expr_ref x_is_pzero(m), x_is_nzero(m), xyzero(m); mk_is_pzero(x, x_is_pzero); mk_is_nzero(y, x_is_nzero); - mk_ite(m.mk_and(x_is_pzero, x_is_nzero), pn, np, ite); - - expr * args[] = { x, y }; - mk_uninterpreted_function(f, 2, args, res); - - expr_ref pzero(m), nzero(m), extra(m); - mk_pzero(f, pzero); - mk_nzero(f, nzero); - extra = m.mk_or(m.mk_eq(ite, pzero), m.mk_eq(ite, nzero)); - m_extra_assertions.push_back(extra); + m_simp.mk_and(x_is_pzero, x_is_nzero, xyzero); + mk_ite(xyzero, pn, np, res); } return res; } +void fpa2bv_converter::mk_max(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { + expr_ref x(m), y(m); + x = args[0]; + y = args[1]; + + expr_ref c(m), v(m); + c = m.mk_and(m.mk_and(m_util.mk_is_zero(x), m_util.mk_is_zero(y)), + m.mk_or(m.mk_and(m_util.mk_is_positive(x), m_util.mk_is_negative(y)), + m.mk_and(m_util.mk_is_negative(x), m_util.mk_is_positive(y)))); + v = m.mk_app(m_util.get_family_id(), OP_FPA_INTERNAL_MAX_UNSPECIFIED, x, y); + + // Note: This requires BR_REWRITE_FULL afterwards. + result = m.mk_ite(c, v, m.mk_app(m_util.get_family_id(), OP_FPA_INTERNAL_MAX_I, x, y)); +} + void fpa2bv_converter::mk_max_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 2); @@ -1192,9 +1243,6 @@ expr_ref fpa2bv_converter::mk_max_unspecified(func_decl * f, expr * x, expr * y) // The hardware interpretation is +0.0. mk_pzero(f, res); else { - if (m_max_pn_zeros.get() == 0) m_max_pn_zeros = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); - if (m_max_np_zeros.get() == 0) m_max_np_zeros = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); - expr_ref pn(m), np(m); mk_fp(m_max_pn_zeros, m_bv_util.mk_numeral(0, ebits), @@ -1205,10 +1253,11 @@ expr_ref fpa2bv_converter::mk_max_unspecified(func_decl * f, expr * x, expr * y) m_bv_util.mk_numeral(0, sbits - 1), np); - expr_ref x_is_pzero(m), x_is_nzero(m); + expr_ref x_is_pzero(m), x_is_nzero(m), xyzero(m); mk_is_pzero(x, x_is_pzero); mk_is_nzero(y, x_is_nzero); - mk_ite(m.mk_and(x_is_pzero, x_is_nzero), pn, np, res); + m_simp.mk_and(x_is_pzero, x_is_nzero, xyzero); + mk_ite(xyzero, pn, np, res); } return res; @@ -2085,23 +2134,20 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args result); } else if (num == 2 && - m_bv_util.is_bv(args[0]) && - m_bv_util.get_bv_size(args[0]) == 3 && + m_util.is_rm(args[0]) && m_util.is_float(m.get_sort(args[1]))) { // rm + float -> float mk_to_fp_float(f, f->get_range(), args[0], args[1], result); } else if (num == 2 && - m_bv_util.is_bv(args[0]) && - m_bv_util.get_bv_size(args[0]) == 3 && + m_util.is_rm(args[0]) && (m_arith_util.is_int(args[1]) || m_arith_util.is_real(args[1]))) { // rm + real -> float mk_to_fp_real(f, f->get_range(), args[0], args[1], result); } else if (num == 2 && - m_bv_util.is_bv(args[0]) && - m_bv_util.get_bv_size(args[0]) == 3 && + m_util.is_rm(args[0]) && m_bv_util.is_bv(args[1])) { // rm + signed bv -> float mk_to_fp_signed(f, num, args, result); @@ -2117,8 +2163,7 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args mk_fp(args[0], args[1], args[2], result); } else if (num == 3 && - m_bv_util.is_bv(args[0]) && - m_bv_util.get_bv_size(args[0]) == 3 && + m_util.is_rm(args[0]) && m_arith_util.is_numeral(args[1]) && m_arith_util.is_numeral(args[2])) { @@ -2137,6 +2182,9 @@ void fpa2bv_converter::mk_to_fp_float(func_decl * f, sort * s, expr * rm, expr * unsigned to_sbits = m_util.get_sbits(s); unsigned to_ebits = m_util.get_ebits(s); + SASSERT(is_app_of(rm, m_util.get_family_id(), OP_FPA_INTERNAL_RM)); + expr * bv_rm = to_app(rm)->get_arg(0); + if (from_sbits == to_sbits && from_ebits == to_ebits) result = x; else { @@ -2285,7 +2333,7 @@ void fpa2bv_converter::mk_to_fp_float(func_decl * f, sort * s, expr * rm, expr * dbg_decouple("fpa2bv_to_float_res_exp", res_exp); expr_ref rounded(m); - expr_ref rm_e(rm, m); + expr_ref rm_e(bv_rm, m); round(s, rm_e, res_sgn, res_sig, res_exp, rounded); expr_ref is_neg(m), sig_inf(m); @@ -2310,19 +2358,20 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * "x: " << mk_ismt2_pp(x, m) << std::endl;); SASSERT(m_util.is_float(s)); SASSERT(au().is_real(x) || au().is_int(x)); - + SASSERT(is_app_of(rm, m_util.get_family_id(), OP_FPA_INTERNAL_RM)); + + expr * bv_rm = to_app(rm)->get_arg(0); 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)) { + if (m_bv_util.is_numeral(bv_rm) && m_util.au().is_numeral(x)) { rational tmp_rat; unsigned sz; - m_bv_util.is_numeral(to_expr(rm), tmp_rat, sz); + m_bv_util.is_numeral(to_expr(bv_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 mrm; - switch (bv_rm) { + switch ((BV_RM_VAL)tmp_rat.get_unsigned()) { case BV_RM_TIES_TO_AWAY: mrm = MPF_ROUND_NEAREST_TAWAY; break; case BV_RM_TIES_TO_EVEN: mrm = MPF_ROUND_NEAREST_TEVEN; break; case BV_RM_TO_NEGATIVE: mrm = MPF_ROUND_TOWARD_NEGATIVE; break; @@ -2359,11 +2408,11 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * mk_pzero(f, result); else { expr_ref rm_nta(m), rm_nte(m), rm_tp(m), rm_tn(m), rm_tz(m); - mk_is_rm(rm, BV_RM_TIES_TO_AWAY, rm_nta); - 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); + mk_is_rm(bv_rm, BV_RM_TIES_TO_AWAY, rm_nta); + mk_is_rm(bv_rm, BV_RM_TIES_TO_EVEN, rm_nte); + mk_is_rm(bv_rm, BV_RM_TO_POSITIVE, rm_tp); + mk_is_rm(bv_rm, BV_RM_TO_NEGATIVE, rm_tn); + mk_is_rm(bv_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_tn(m_mpf_manager), v_tz(m_mpf_manager); @@ -2428,7 +2477,7 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * sig = mk_fresh_const("fpa2bv_to_fp_real_sig", sbits + 4); exp = mk_fresh_const("fpa2bv_to_fp_real_exp", ebits + 2); - expr_ref rme(rm, m); + expr_ref rme(bv_rm, m); round(s, rme, sgn, sig, exp, result); expr * e = m.mk_eq(m_util.mk_to_real(result), x); @@ -2734,9 +2783,8 @@ void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * con SASSERT(num == 2); SASSERT(m_util.is_float(f->get_range())); - SASSERT(m_bv_util.is_bv(args[0])); - SASSERT(m_bv_util.is_bv(args[1])); SASSERT(is_app_of(args[0], m_util.get_family_id(), OP_FPA_INTERNAL_RM)); + SASSERT(m_bv_util.is_bv(args[1])); expr_ref bv_rm(m), x(m); bv_rm = to_app(args[0])->get_arg(0); diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index ed59a32d1..95f2ca057 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -83,7 +83,7 @@ public: void split_fp(expr * e, expr * & sgn, expr * & exp, expr * & sig) const; void split_fp(expr * e, expr_ref & sgn, expr_ref & exp, expr_ref & sig) const; - void mk_eq(expr * a, expr * b, expr_ref & result); + void mk_eq(expr * a, expr * b, expr_ref & result); void mk_ite(expr * c, expr * t, expr * f, expr_ref & result); void mk_distinct(func_decl * f, unsigned num, expr * const * args, expr_ref & result); @@ -106,9 +106,7 @@ public: void mk_mul(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_div(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_rem(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - void mk_abs(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - void mk_min_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - void mk_max_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + void mk_abs(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_fma(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_sqrt(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_round_to_integral(func_decl * f, unsigned num, expr * const * args, expr_ref & result); @@ -143,7 +141,12 @@ public: void set_unspecified_fp_hi(bool v) { m_hi_fp_unspecified = v; } + void mk_min(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + void mk_min_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result); virtual expr_ref mk_min_unspecified(func_decl * f, expr * x, expr * y); + + void mk_max(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + void mk_max_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result); virtual expr_ref mk_max_unspecified(func_decl * f, expr * x, expr * y); expr_ref mk_to_ubv_unspecified(unsigned width); diff --git a/src/ast/fpa/fpa2bv_rewriter.h b/src/ast/fpa/fpa2bv_rewriter.h index e2ecc388a..c3720421c 100644 --- a/src/ast/fpa/fpa2bv_rewriter.h +++ b/src/ast/fpa/fpa2bv_rewriter.h @@ -165,15 +165,15 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { case OP_FPA_TO_REAL: m_conv.mk_to_real(f, num, args, result); return BR_DONE; case OP_FPA_TO_IEEE_BV: m_conv.mk_to_ieee_bv(f, num, args, result); return BR_DONE; - case OP_FPA_MIN: - case OP_FPA_MAX: - throw rewriter_exception("operator is not supported, you must simplify the goal before applying fpa2bv"); + case OP_FPA_MIN: m_conv.mk_min(f, num, args, result); return BR_REWRITE_FULL; + case OP_FPA_MAX: m_conv.mk_max(f, num, args, result); return BR_REWRITE_FULL; case OP_FPA_INTERNAL_MIN_UNSPECIFIED: result = m_conv.mk_min_unspecified(f, args[0], args[1]); return BR_DONE; case OP_FPA_INTERNAL_MAX_UNSPECIFIED: result = m_conv.mk_max_unspecified(f, args[0], args[1]); return BR_DONE; case OP_FPA_INTERNAL_MIN_I: m_conv.mk_min_i(f, num, args, result); return BR_DONE; case OP_FPA_INTERNAL_MAX_I: m_conv.mk_max_i(f, num, args, result); return BR_DONE; + case OP_FPA_INTERNAL_RM: case OP_FPA_INTERNAL_BVWRAP: case OP_FPA_INTERNAL_BVUNWRAP: case OP_FPA_INTERNAL_TO_REAL_UNSPECIFIED: diff --git a/src/ast/rewriter/fpa_rewriter.cpp b/src/ast/rewriter/fpa_rewriter.cpp index 4da3b3169..062703be0 100644 --- a/src/ast/rewriter/fpa_rewriter.cpp +++ b/src/ast/rewriter/fpa_rewriter.cpp @@ -94,9 +94,9 @@ br_status fpa_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * con case OP_FPA_TO_REAL: SASSERT(num_args == 1); st = mk_to_real(args[0], result); break; case OP_FPA_INTERNAL_MIN_I: - case OP_FPA_INTERNAL_MAX_I: + case OP_FPA_INTERNAL_MAX_I: case OP_FPA_INTERNAL_MIN_UNSPECIFIED: - case OP_FPA_INTERNAL_MAX_UNSPECIFIED: + case OP_FPA_INTERNAL_MAX_UNSPECIFIED: SASSERT(num_args == 2); st = BR_FAILED; break; case OP_FPA_INTERNAL_RM: @@ -436,12 +436,17 @@ br_status fpa_rewriter::mk_min(expr * arg1, expr * arg2, expr_ref & result) { } scoped_mpf v1(m_fm), v2(m_fm); - if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2) && - !(m_fm.is_zero(v1) && m_fm.is_zero(v2) && m_fm.sgn(v1) != m_fm.sgn(v2))) { - scoped_mpf r(m_fm); - m_fm.minimum(v1, v2, r); - result = m_util.mk_value(r); - return BR_DONE; + if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2)) { + if (m_fm.is_zero(v1) && m_fm.is_zero(v2) && m_fm.sgn(v1) != m_fm.sgn(v2)) { + result = m().mk_app(get_fid(), OP_FPA_INTERNAL_MIN_UNSPECIFIED, arg1, arg2); + return BR_DONE; + } + else { + scoped_mpf r(m_fm); + m_fm.minimum(v1, v2, r); + result = m_util.mk_value(r); + return BR_DONE; + } } else { expr_ref c(m()), v(m()); @@ -466,12 +471,17 @@ br_status fpa_rewriter::mk_max(expr * arg1, expr * arg2, expr_ref & result) { } scoped_mpf v1(m_fm), v2(m_fm); - if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2) && - !(m_fm.is_zero(v1) && m_fm.is_zero(v2) && m_fm.sgn(v1) != m_fm.sgn(v2))) { - scoped_mpf r(m_fm); - m_fm.maximum(v1, v2, r); - result = m_util.mk_value(r); - return BR_DONE; + if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2)) { + if (m_fm.is_zero(v1) && m_fm.is_zero(v2) && m_fm.sgn(v1) != m_fm.sgn(v2)) { + result = m().mk_app(get_fid(), OP_FPA_INTERNAL_MAX_UNSPECIFIED, arg1, arg2); + return BR_DONE; + } + else { + scoped_mpf r(m_fm); + m_fm.maximum(v1, v2, r); + result = m_util.mk_value(r); + return BR_DONE; + } } else { expr_ref c(m()), v(m()); diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index 66af5c815..701efb2ba 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -74,7 +74,9 @@ namespace smt { } else { SASSERT(is_rm(f->get_range())); - result = m_th.wrap(m.mk_const(f)); + expr_ref bv(m); + bv = m_th.wrap(m.mk_const(f)); + mk_rm(bv, result); m_rm_const2bv.insert(f, result); m.inc_ref(f); m.inc_ref(result); @@ -83,7 +85,7 @@ namespace smt { void theory_fpa::fpa2bv_converter_wrapped::mk_uninterpreted_function(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { // TODO: This introduces temporary variables/func_decls that should be filtered in the end. - return fpa2bv_converter::mk_uninterpreted_function(f, num, args, result); + fpa2bv_converter::mk_uninterpreted_function(f, num, args, result); } expr_ref theory_fpa::fpa2bv_converter_wrapped::mk_min_unspecified(func_decl * f, expr * x, expr * y) { @@ -106,7 +108,6 @@ namespace smt { expr_ref sc(m); m_th.m_converter.mk_is_zero(res, sc); m_extra_assertions.push_back(sc); - //m_extra_assertions.push_back(m.mk_eq(m_th.unwrap(wrapped, f->get_range()), a)); return res; } @@ -130,7 +131,6 @@ namespace smt { expr_ref sc(m); m_th.m_converter.mk_is_zero(res, sc); m_extra_assertions.push_back(sc); - //m_extra_assertions.push_back(m.mk_eq(m_th.unwrap(wrapped, f->get_range()), a)); return res; } @@ -349,11 +349,14 @@ namespace smt { } } else if (m_fpa_util.is_rm(e)) { - SASSERT(is_sort_of(m.get_sort(e_conv), m_bv_util.get_family_id(), BV_SORT)); - SASSERT(m_bv_util.get_bv_size(e_conv) == 3); - m_th_rw(e_conv, res); + SASSERT(is_app_of(e_conv, get_family_id(), OP_FPA_INTERNAL_RM)); + expr_ref bv_rm(m); + bv_rm = to_app(e_conv)->get_arg(0); + m_th_rw(bv_rm); + m_converter.mk_rm(bv_rm, res); } - else if (m_fpa_util.is_float(e)) { + else if (m_fpa_util.is_float(e)) { + SASSERT(is_app_of(e_conv, get_family_id(), OP_FPA_FP)); expr_ref sgn(m), sig(m), exp(m); m_converter.split_fp(e_conv, sgn, exp, sig); m_th_rw(sgn); @@ -440,7 +443,7 @@ namespace smt { sort * srt = m.get_sort(e); expr_ref res(m); if (m_fpa_util.is_rm(srt)) { - res = to_app(e)->get_arg(0); + m_converter.mk_rm(to_app(e)->get_arg(0), res); } else { SASSERT(m_fpa_util.is_float(srt)); @@ -468,7 +471,6 @@ namespace smt { TRACE("t_fpa_detail", tout << "cached:" << std::endl; tout << mk_ismt2_pp(e, m) << std::endl << " -> " << std::endl << mk_ismt2_pp(res, m) << std::endl;); - return res; } else { if (m_fpa_util.is_unwrap(e)) @@ -490,7 +492,7 @@ namespace smt { m.inc_ref(res); m_trail_stack.push(fpa2bv_conversion_trail_elem(m, m_conversions, e)); } - + return res; } @@ -663,7 +665,8 @@ namespace smt { expr_ref c(m); - if (fu.is_float(xe) && fu.is_float(ye)) + if ((fu.is_float(xe) && fu.is_float(ye)) || + (fu.is_rm(xe) && fu.is_rm(ye))) m_converter.mk_eq(xc, yc, c); else c = m.mk_eq(xc, yc); @@ -682,7 +685,7 @@ namespace smt { TRACE("t_fpa", tout << "new diseq: " << x << " != " << y << std::endl;); TRACE("t_fpa_detail", tout << mk_ismt2_pp(get_enode(x)->get_owner(), m) << " != " << - mk_ismt2_pp(get_enode(y)->get_owner(), m) << std::endl;); + mk_ismt2_pp(get_enode(y)->get_owner(), m) << std::endl;); fpa_util & fu = m_fpa_util; @@ -699,7 +702,8 @@ namespace smt { expr_ref c(m); - if (fu.is_float(xe) && fu.is_float(ye)) { + if ((fu.is_float(xe) && fu.is_float(ye))|| + (fu.is_rm(xe) && fu.is_rm(ye))) { m_converter.mk_eq(xc, yc, c); c = m.mk_not(c); } diff --git a/src/tactic/fpa/fpa2bv_model_converter.cpp b/src/tactic/fpa/fpa2bv_model_converter.cpp index eb6d724c9..6ead927e0 100644 --- a/src/tactic/fpa/fpa2bv_model_converter.cpp +++ b/src/tactic/fpa/fpa2bv_model_converter.cpp @@ -210,6 +210,11 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) { obj_hashtable seen; + for (obj_hashtable::iterator it = m_decls_to_hide.begin(); + it != m_decls_to_hide.end(); + it++) + seen.insert(*it); + for (obj_map::iterator it = m_const2bv.begin(); it != m_const2bv.end(); it++) @@ -353,6 +358,7 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) { model_converter * mk_fpa2bv_model_converter(ast_manager & m, obj_map const & const2bv, obj_map const & rm_const2bv, - obj_map const & uf2bvuf) { - return alloc(fpa2bv_model_converter, m, const2bv, rm_const2bv, uf2bvuf); + obj_map const & uf2bvuf, + obj_hashtable const & decls_to_hide) { + return alloc(fpa2bv_model_converter, m, const2bv, rm_const2bv, uf2bvuf, decls_to_hide); } diff --git a/src/tactic/fpa/fpa2bv_model_converter.h b/src/tactic/fpa/fpa2bv_model_converter.h index 021538ac1..a864f753a 100644 --- a/src/tactic/fpa/fpa2bv_model_converter.h +++ b/src/tactic/fpa/fpa2bv_model_converter.h @@ -27,13 +27,14 @@ class fpa2bv_model_converter : public model_converter { obj_map m_const2bv; obj_map m_rm_const2bv; obj_map m_uf2bvuf; + obj_hashtable m_decls_to_hide; public: fpa2bv_model_converter(ast_manager & m, obj_map const & const2bv, obj_map const & rm_const2bv, - obj_map const & uf2bvuf) : + obj_map const & uf2bvuf, + obj_hashtable const & decls_to_hide) : m(m) { - // Just create a copy? for (obj_map::iterator it = const2bv.begin(); it != const2bv.end(); it++) @@ -58,12 +59,20 @@ public: m.inc_ref(it->m_key); m.inc_ref(it->m_value); } + for (obj_hashtable::iterator it = decls_to_hide.begin(); + it != decls_to_hide.end(); + it++) + { + m_decls_to_hide.insert(*it); + m.inc_ref(*it); + } } virtual ~fpa2bv_model_converter() { dec_ref_map_key_values(m, m_const2bv); dec_ref_map_key_values(m, m_rm_const2bv); dec_ref_map_key_values(m, m_uf2bvuf); + dec_ref_collection_values(m, m_decls_to_hide); } virtual void operator()(model_ref & md, unsigned goal_idx) { @@ -96,6 +105,7 @@ protected: model_converter * mk_fpa2bv_model_converter(ast_manager & m, obj_map const & const2bv, obj_map const & rm_const2bv, - obj_map const & uf2bvuf); + obj_map const & uf2bvuf, + obj_hashtable const & decls_to_hide); #endif \ No newline at end of file diff --git a/src/tactic/fpa/fpa2bv_tactic.cpp b/src/tactic/fpa/fpa2bv_tactic.cpp index 07669f513..4418f0f9f 100644 --- a/src/tactic/fpa/fpa2bv_tactic.cpp +++ b/src/tactic/fpa/fpa2bv_tactic.cpp @@ -107,7 +107,7 @@ class fpa2bv_tactic : public tactic { } if (g->models_enabled()) - mc = mk_fpa2bv_model_converter(m, m_conv.const2bv(), m_conv.rm_const2bv(), m_conv.uf2bvuf()); + mc = mk_fpa2bv_model_converter(m, m_conv.const2bv(), m_conv.rm_const2bv(), m_conv.uf2bvuf(), m_conv.decls_to_hide()); g->inc_depth(); result.push_back(g.get()); @@ -151,7 +151,12 @@ public: model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core) { - (*m_imp)(in, result, mc, pc, core); + try { + (*m_imp)(in, result, mc, pc, core); + } + catch (rewriter_exception & ex) { + throw tactic_exception(ex.msg()); + } } virtual void cleanup() { From ed94bc2f6b31b68f41ce417b83e463bc6540f90e Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 23 Oct 2015 14:58:29 +0100 Subject: [PATCH 48/57] Bugfix for fpa2bv converter. --- src/ast/fpa/fpa2bv_converter.cpp | 2 +- src/tactic/fpa/fpa2bv_model_converter.cpp | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index c3feeb10a..c289d5804 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -51,7 +51,7 @@ fpa2bv_converter::fpa2bv_converter(ast_manager & m) : m_max_pn_zeros = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); m_max_np_zeros = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); m_decls_to_hide.insert_if_not_there(m_max_pn_zeros->get_decl()); - m_decls_to_hide.insert_if_not_there(m_min_np_zeros->get_decl()); + m_decls_to_hide.insert_if_not_there(m_max_np_zeros->get_decl()); } fpa2bv_converter::~fpa2bv_converter() { diff --git a/src/tactic/fpa/fpa2bv_model_converter.cpp b/src/tactic/fpa/fpa2bv_model_converter.cpp index 6ead927e0..53dc071ff 100644 --- a/src/tactic/fpa/fpa2bv_model_converter.cpp +++ b/src/tactic/fpa/fpa2bv_model_converter.cpp @@ -79,6 +79,13 @@ model_converter * fpa2bv_model_converter::translate(ast_translation & translator translator.to().inc_ref(k); translator.to().inc_ref(v); } + for (obj_hashtable::iterator it = m_decls_to_hide.begin(); + it != m_decls_to_hide.end(); + it++) { + func_decl * k = translator(*it); + res->m_decls_to_hide.insert(*it); + translator.to().inc_ref(*it); + } return res; } From cbf8bd8de12c593818d4dcef27cf55865aa6188f Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 25 Oct 2015 15:56:42 +0000 Subject: [PATCH 49/57] Enabled proof & core production in fpa2bv and qffp. --- src/tactic/fpa/fpa2bv_tactic.cpp | 2 -- src/tactic/fpa/qffp_tactic.cpp | 28 +++++++++++++--------------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/tactic/fpa/fpa2bv_tactic.cpp b/src/tactic/fpa/fpa2bv_tactic.cpp index 4418f0f9f..472f6b30c 100644 --- a/src/tactic/fpa/fpa2bv_tactic.cpp +++ b/src/tactic/fpa/fpa2bv_tactic.cpp @@ -56,8 +56,6 @@ class fpa2bv_tactic : public tactic { proof_converter_ref & pc, expr_dependency_ref & core) { SASSERT(g->is_well_sorted()); - fail_if_proof_generation("fpa2bv", g); - fail_if_unsat_core_generation("fpa2bv", g); m_proofs_enabled = g->proofs_enabled(); m_produce_models = g->models_enabled(); m_produce_unsat_cores = g->unsat_core_enabled(); diff --git a/src/tactic/fpa/qffp_tactic.cpp b/src/tactic/fpa/qffp_tactic.cpp index 485e837ee..9c94d6cb2 100644 --- a/src/tactic/fpa/qffp_tactic.cpp +++ b/src/tactic/fpa/qffp_tactic.cpp @@ -71,21 +71,19 @@ tactic * mk_qffp_tactic(ast_manager & m, params_ref const & p) { tactic * st = and_then(mk_simplify_tactic(m, simp_p), mk_propagate_values_tactic(m, p), - cond(mk_or(mk_produce_proofs_probe(), mk_produce_unsat_cores_probe()), - mk_smt_tactic(), - and_then( - mk_fpa2bv_tactic(m, p), - mk_propagate_values_tactic(m, p), - using_params(mk_simplify_tactic(m, p), simp_p), - mk_bit_blaster_tactic(m, p), - using_params(mk_simplify_tactic(m, p), simp_p), - cond(mk_is_propositional_probe(), - mk_sat_tactic(m, p), - cond(mk_has_fp_to_real_probe(), - mk_qfnra_tactic(m, p), - mk_smt_tactic(p)) - ), - mk_fail_if_undecided_tactic()))); + mk_fpa2bv_tactic(m, p), + mk_propagate_values_tactic(m, p), + using_params(mk_simplify_tactic(m, p), simp_p), + mk_bit_blaster_tactic(m, p), + using_params(mk_simplify_tactic(m, p), simp_p), + cond(mk_is_propositional_probe(), + cond(mk_produce_proofs_probe(), + mk_smt_tactic(), // `sat' does not support proofs. + mk_sat_tactic(m, p)), + cond(mk_has_fp_to_real_probe(), + mk_qfnra_tactic(m, p), + mk_smt_tactic(p))), + mk_fail_if_undecided_tactic()); st->updt_params(p); return st; From 64a5247813813a5db6575237cc410cac99ddb48d Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sun, 25 Oct 2015 11:45:46 -0700 Subject: [PATCH 50/57] Changed references to help-tactics to help-tactic. --- src/api/dotnet/Probe.cs | 2 +- src/api/dotnet/Tactic.cs | 2 +- src/api/java/Probe.java | 2 +- src/api/java/Tactic.java | 2 +- src/api/ml/z3.mli | 4 ++-- src/api/z3_api.h | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/api/dotnet/Probe.cs b/src/api/dotnet/Probe.cs index c10755263..3c5e5adc9 100644 --- a/src/api/dotnet/Probe.cs +++ b/src/api/dotnet/Probe.cs @@ -28,7 +28,7 @@ namespace Microsoft.Z3 /// which solver and/or preprocessing step will be used. /// The complete list of probes may be obtained using the procedures Context.NumProbes /// and Context.ProbeNames. - /// It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. + /// It may also be obtained using the command (help-tactic) in the SMT 2.0 front-end. /// [ContractVerification(true)] public class Probe : Z3Object diff --git a/src/api/dotnet/Tactic.cs b/src/api/dotnet/Tactic.cs index 8399490d5..0a6f79494 100644 --- a/src/api/dotnet/Tactic.cs +++ b/src/api/dotnet/Tactic.cs @@ -26,7 +26,7 @@ namespace Microsoft.Z3 /// Tactics are the basic building block for creating custom solvers for specific problem domains. /// The complete list of tactics may be obtained using Context.NumTactics /// and Context.TacticNames. - /// It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. + /// It may also be obtained using the command (help-tactic) in the SMT 2.0 front-end. /// [ContractVerification(true)] public class Tactic : Z3Object diff --git a/src/api/java/Probe.java b/src/api/java/Probe.java index e190229df..625b41e09 100644 --- a/src/api/java/Probe.java +++ b/src/api/java/Probe.java @@ -22,7 +22,7 @@ package com.microsoft.z3; * may be used to decide which solver and/or preprocessing step will be used. * The complete list of probes may be obtained using the procedures * {@code Context.NumProbes} and {@code Context.ProbeNames}. It may - * also be obtained using the command {@code (help-tactics)} in the SMT 2.0 + * also be obtained using the command {@code (help-tactic)} in the SMT 2.0 * front-end. **/ public class Probe extends Z3Object diff --git a/src/api/java/Tactic.java b/src/api/java/Tactic.java index 81d886537..786f8a6ec 100644 --- a/src/api/java/Tactic.java +++ b/src/api/java/Tactic.java @@ -21,7 +21,7 @@ package com.microsoft.z3; * Tactics are the basic building block for creating custom solvers for specific * problem domains. The complete list of tactics may be obtained using * {@code Context.NumTactics} and {@code Context.TacticNames}. It may - * also be obtained using the command {@code (help-tactics)} in the SMT 2.0 + * also be obtained using the command {@code (help-tactic)} in the SMT 2.0 * front-end. **/ public class Tactic extends Z3Object diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index dba15c85d..02f29d080 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -2779,7 +2779,7 @@ end which solver and/or preprocessing step will be used. The complete list of probes may be obtained using the procedures [Context.NumProbes] and [Context.ProbeNames]. - It may also be obtained using the command [(help-tactics)] in the SMT 2.0 front-end. + It may also be obtained using the command [(help-tactic)] in the SMT 2.0 front-end. *) module Probe : sig @@ -2841,7 +2841,7 @@ end Tactics are the basic building block for creating custom solvers for specific problem domains. The complete list of tactics may be obtained using [Context.get_num_tactics] and [Context.get_tactic_names]. - It may also be obtained using the command [(help-tactics)] in the SMT 2.0 front-end. + It may also be obtained using the command [(help-tactic)] in the SMT 2.0 front-end. *) module Tactic : sig diff --git a/src/api/z3_api.h b/src/api/z3_api.h index 2312f4389..d0bf20188 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -6650,7 +6650,7 @@ END_MLAPI_EXCLUDE /** \brief Return a tactic associated with the given name. The complete list of tactics may be obtained using the procedures #Z3_get_num_tactics and #Z3_get_tactic_name. - It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. + It may also be obtained using the command (help-tactic) in the SMT 2.0 front-end. Tactics are the basic building block for creating custom solvers for specific problem domains. @@ -6677,7 +6677,7 @@ END_MLAPI_EXCLUDE /** \brief Return a probe associated with the given name. The complete list of probes may be obtained using the procedures #Z3_get_num_probes and #Z3_get_probe_name. - It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. + It may also be obtained using the command (help-tactic) in the SMT 2.0 front-end. Probes are used to inspect a goal (aka problem) and collect information that may be used to decide which solver and/or preprocessing step will be used. From d558eaa321930056287b7e80a20158b8507fd739 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 26 Oct 2015 15:45:21 +0000 Subject: [PATCH 51/57] Eliminated unused variable in fpa2bv model converter. --- src/tactic/fpa/fpa2bv_model_converter.cpp | 32 +++++++++++------------ 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/tactic/fpa/fpa2bv_model_converter.cpp b/src/tactic/fpa/fpa2bv_model_converter.cpp index 53dc071ff..78c79dd11 100644 --- a/src/tactic/fpa/fpa2bv_model_converter.cpp +++ b/src/tactic/fpa/fpa2bv_model_converter.cpp @@ -83,8 +83,8 @@ model_converter * fpa2bv_model_converter::translate(ast_translation & translator it != m_decls_to_hide.end(); it++) { func_decl * k = translator(*it); - res->m_decls_to_hide.insert(*it); - translator.to().inc_ref(*it); + res->m_decls_to_hide.insert(k); + translator.to().inc_ref(k); } return res; } @@ -125,16 +125,16 @@ expr_ref fpa2bv_model_converter::convert_bv2fp(sort * s, expr * sgn, expr * exp, res = fu.mk_value(fp_val); - TRACE("fpa2bv_mc", tout << "[" << mk_ismt2_pp(sgn, m) << - " " << mk_ismt2_pp(exp, m) << - " " << mk_ismt2_pp(sig, m) << "] == " << + TRACE("fpa2bv_mc", tout << "[" << mk_ismt2_pp(sgn, m) << + " " << mk_ismt2_pp(exp, m) << + " " << mk_ismt2_pp(sig, m) << "] == " << mk_ismt2_pp(res, m) << std::endl;); fu.fm().del(fp_val); return res; } -expr_ref fpa2bv_model_converter::convert_bv2fp(model * bv_mdl, sort * s, expr * bv) const { +expr_ref fpa2bv_model_converter::convert_bv2fp(model * bv_mdl, sort * s, expr * bv) const { fpa_util fu(m); bv_util bu(m); @@ -160,11 +160,11 @@ expr_ref fpa2bv_model_converter::convert_bv2fp(model * bv_mdl, sort * s, expr * expr_ref fpa2bv_model_converter::convert_bv2rm(expr * eval_v) const { fpa_util fu(m); bv_util bu(m); - expr_ref res(m); + expr_ref res(m); rational bv_val(0); unsigned sz = 0; - + if (bu.is_numeral(eval_v, bv_val, sz)) { SASSERT(bv_val.is_uint64()); switch (bv_val.get_uint64()) { @@ -185,7 +185,7 @@ expr_ref fpa2bv_model_converter::convert_bv2rm(model * bv_mdl, func_decl * var, bv_util bu(m); expr_ref res(m); - expr_ref eval_v(m); + expr_ref eval_v(m); if (val && bv_mdl->eval(val, eval_v, true)) res = convert_bv2rm(eval_v); @@ -200,7 +200,7 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) { TRACE("fpa2bv_mc", tout << "BV Model: " << std::endl; for (unsigned i = 0; i < bv_mdl->get_num_constants(); i++) tout << bv_mdl->get_constant(i)->get_name() << " --> " << - mk_ismt2_pp(bv_mdl->get_const_interp(bv_mdl->get_constant(i)), m) << std::endl; + mk_ismt2_pp(bv_mdl->get_const_interp(bv_mdl->get_constant(i)), m) << std::endl; for (unsigned i = 0; i < bv_mdl->get_num_functions(); i++) { func_decl * f = bv_mdl->get_function(i); tout << f->get_name() << "(...) := " << std::endl; @@ -210,7 +210,7 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) { for (unsigned k = 0; k < f->get_arity(); k++) { tout << mk_ismt2_pp(fe->get_arg(k), m) << " "; } - tout << "--> " << mk_ismt2_pp(fe->get_result(), m) << std::endl; + tout << "--> " << mk_ismt2_pp(fe->get_result(), m) << std::endl; } tout << "else " << mk_ismt2_pp(fi->get_else(), m) << std::endl; }); @@ -231,7 +231,7 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) { SASSERT(fu.is_float(var->get_range())); SASSERT(var->get_range()->get_num_parameters() == 2); - expr_ref sgn(m), sig(m), exp(m); + expr_ref sgn(m), sig(m), exp(m); bv_mdl->eval(val->get_arg(0), sgn, true); bv_mdl->eval(val->get_arg(1), exp, true); bv_mdl->eval(val->get_arg(2), sig, true); @@ -245,7 +245,7 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) { seen.insert(to_app(val->get_arg(0))->get_decl()); seen.insert(to_app(val->get_arg(1))->get_decl()); seen.insert(to_app(val->get_arg(2))->get_decl()); -#else +#else SASSERT(a->get_arg(0)->get_kind() == OP_EXTRACT); SASSERT(to_app(a->get_arg(0))->get_arg(0)->get_kind() == OP_EXTRACT); seen.insert(to_app(to_app(val->get_arg(0))->get_arg(0))->get_decl()); @@ -308,7 +308,7 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) { else new_args.push_back(aj); } - + expr_ref ret(m); ret = bv_fe->get_result(); if (fu.is_float(rng)) @@ -316,7 +316,7 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) { else if (fu.is_rm(rng)) ret = convert_bv2rm(ret); - flt_fi->insert_new_entry(new_args.c_ptr(), ret); + flt_fi->insert_new_entry(new_args.c_ptr(), ret); } expr_ref els(m); @@ -327,7 +327,7 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) { els = convert_bv2rm(els); flt_fi->set_else(els); - + float_mdl->register_decl(f, flt_fi); } From 5b39d8fa0de77b74da89912ebfd7e036d18f01d3 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 26 Oct 2015 15:59:00 +0000 Subject: [PATCH 52/57] bugfix for fpa2bv converter --- src/ast/fpa/fpa2bv_converter.cpp | 578 +++++++++++++++---------------- 1 file changed, 289 insertions(+), 289 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index c289d5804..f2ab3a802 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -27,15 +27,15 @@ Notes: #define BVULT(X,Y,R) { expr_ref bvult_eq(m), bvult_not(m); m_simp.mk_eq(X, Y, bvult_eq); m_simp.mk_not(bvult_eq, bvult_not); expr_ref t(m); t = m_bv_util.mk_ule(X,Y); m_simp.mk_and(t, bvult_not, R); } #define BVSLT(X,Y,R) { expr_ref bvslt_eq(m), bvslt_not(m); m_simp.mk_eq(X, Y, bvslt_eq); m_simp.mk_not(bvslt_eq, bvslt_not); expr_ref t(m); t = m_bv_util.mk_sle(X,Y); m_simp.mk_and(t, bvslt_not, R); } -fpa2bv_converter::fpa2bv_converter(ast_manager & m) : +fpa2bv_converter::fpa2bv_converter(ast_manager & m) : m(m), m_simp(m), m_util(m), m_bv_util(m), m_arith_util(m), m_mpf_manager(m_util.fm()), - m_mpz_manager(m_mpf_manager.mpz_manager()), - m_hi_fp_unspecified(true), + m_mpz_manager(m_mpf_manager.mpz_manager()), + m_hi_fp_unspecified(true), m_min_pn_zeros(0, m), m_min_np_zeros(0, m), m_max_pn_zeros(0, m), @@ -81,7 +81,7 @@ void fpa2bv_converter::mk_eq(expr * a, expr * b, expr_ref & result) { // The SMT FPA theory asks for _one_ NaN value, but the bit-blasting // has many, like IEEE754. This encoding of equality makes it look like - // a single NaN again. + // a single NaN again. expr_ref a_is_nan(m), b_is_nan(m), both_are_nan(m); mk_is_nan(a, a_is_nan); mk_is_nan(b, b_is_nan); @@ -121,8 +121,8 @@ void fpa2bv_converter::mk_ite(expr * c, expr * t, expr * f, expr_ref & result) { } void fpa2bv_converter::mk_distinct(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { - // Note: in SMT there is only one NaN, so multiple of them are considered - // equal, thus (distinct NaN NaN) is false, even if the two NaNs have + // Note: in SMT there is only one NaN, so multiple of them are considered + // equal, thus (distinct NaN NaN) is false, even if the two NaNs have // different bitwise representations (see also mk_eq). result = m.mk_true(); for (unsigned i = 0; i < num; i++) { @@ -131,10 +131,10 @@ void fpa2bv_converter::mk_distinct(func_decl * f, unsigned num, expr * const * a mk_eq(args[i], args[j], eq); m_simp.mk_and(result, m.mk_not(eq), result); } - } + } } -void fpa2bv_converter::mk_numeral(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { +void fpa2bv_converter::mk_numeral(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 0); SASSERT(f->get_num_parameters() == 1); SASSERT(f->get_parameter(0).is_external()); @@ -166,9 +166,9 @@ void fpa2bv_converter::mk_numeral(func_decl * f, unsigned num, expr * const * ar mk_bias(e, biased_exp); mk_fp(bv_sgn, biased_exp, bv_sig, result); - TRACE("fpa2bv_dbg", tout << "value of [" << sign << " " << m_mpz_manager.to_string(sig) << " " << exp << "] is " + TRACE("fpa2bv_dbg", tout << "value of [" << sign << " " << m_mpz_manager.to_string(sig) << " " << exp << "] is " << mk_ismt2_pp(result, m) << std::endl;); - + } } @@ -197,7 +197,7 @@ void fpa2bv_converter::mk_const(func_decl * f, expr_ref & result) { sgn = mk_fresh_const((p + "_sgn_" + name).c_str(), 1); s = mk_fresh_const((p + "_sig_" + name).c_str(), sbits - 1); - e = mk_fresh_const((p + "_exp_" + name).c_str(), ebits); + e = mk_fresh_const((p + "_exp_" + name).c_str(), ebits); #else app_ref bv(m); unsigned bv_sz = 1 + ebits + (sbits - 1); @@ -211,12 +211,12 @@ void fpa2bv_converter::mk_const(func_decl * f, expr_ref & result) { SASSERT(m_bv_util.get_bv_size(s) == sbits-1); SASSERT(m_bv_util.get_bv_size(e) == ebits); #endif - + mk_fp(sgn, e, s, result); m_const2bv.insert(f, result); m.inc_ref(f); - m.inc_ref(result); + m.inc_ref(result); } } @@ -224,8 +224,8 @@ void fpa2bv_converter::mk_var(unsigned base_inx, sort * srt, expr_ref & result) SASSERT(is_float(srt)); unsigned ebits = m_util.get_ebits(srt); unsigned sbits = m_util.get_sbits(srt); - - expr_ref sgn(m), s(m), e(m); + + expr_ref sgn(m), s(m), e(m); sgn = m.mk_var(base_inx, m_bv_util.mk_sort(1)); s = m.mk_var(base_inx + 1, m_bv_util.mk_sort(sbits-1)); @@ -278,7 +278,7 @@ void fpa2bv_converter::mk_uninterpreted_function(func_decl * f, unsigned num, ex new_args.push_back(args[i]); } - func_decl * fd; + func_decl * fd; if (m_uf2bvuf.find(f, fd)) mk_uninterpreted_output(f->get_range(), fd, new_args, result); else { @@ -309,7 +309,7 @@ void fpa2bv_converter::mk_uninterpreted_function(func_decl * f, unsigned num, ex m.inc_ref(f); m.inc_ref(fbv); - mk_uninterpreted_output(f->get_range(), fbv, new_args, result); + mk_uninterpreted_output(f->get_range(), fbv, new_args, result); } TRACE("fpa2bv", tout << "UF result: " << mk_ismt2_pp(result, m) << std::endl; ); @@ -382,7 +382,7 @@ void fpa2bv_converter::mk_nan(func_decl * f, expr_ref & result) { mk_top_exp(ebits, top_exp); mk_fp(m_bv_util.mk_numeral(0, 1), top_exp, - m_bv_util.mk_numeral(1, sbits-1), + m_bv_util.mk_numeral(1, sbits-1), result); } @@ -423,17 +423,17 @@ void fpa2bv_converter::mk_one(func_decl *f, expr_ref sign, expr_ref & result) { result); } -void fpa2bv_converter::add_core(unsigned sbits, unsigned ebits, +void fpa2bv_converter::add_core(unsigned sbits, unsigned ebits, expr_ref & c_sgn, expr_ref & c_sig, expr_ref & c_exp, expr_ref & d_sgn, expr_ref & d_sig, expr_ref & d_exp, expr_ref & res_sgn, expr_ref & res_sig, expr_ref & res_exp) -{ +{ // c/d are now such that c_exp >= d_exp. expr_ref exp_delta(m); exp_delta = m_bv_util.mk_bv_sub(c_exp, d_exp); dbg_decouple("fpa2bv_add_exp_delta", exp_delta); - // cap the delta + // cap the delta expr_ref cap(m), cap_le_delta(m); cap = m_bv_util.mk_numeral(sbits+2, ebits); cap_le_delta = m_bv_util.mk_ule(cap, exp_delta); @@ -451,7 +451,7 @@ void fpa2bv_converter::add_core(unsigned sbits, unsigned ebits, // Alignment shift with sticky bit computation. expr_ref big_d_sig(m); big_d_sig = m_bv_util.mk_concat(d_sig, m_bv_util.mk_numeral(0, sbits+3)); - + SASSERT(is_well_sorted(m, big_d_sig)); expr_ref shifted_big(m), shifted_d_sig(m), sticky_raw(m), sticky(m); @@ -459,14 +459,14 @@ void fpa2bv_converter::add_core(unsigned sbits, unsigned ebits, shifted_d_sig = m_bv_util.mk_extract((2*(sbits+3)-1), (sbits+3), shifted_big); SASSERT(is_well_sorted(m, shifted_d_sig)); - sticky_raw = m_bv_util.mk_extract(sbits+2, 0, shifted_big); - expr_ref sticky_eq(m), nil_sbit3(m), one_sbit3(m); + sticky_raw = m_bv_util.mk_extract(sbits+2, 0, shifted_big); + expr_ref sticky_eq(m), nil_sbit3(m), one_sbit3(m); nil_sbit3 = m_bv_util.mk_numeral(0, sbits+3); one_sbit3 = m_bv_util.mk_numeral(1, sbits+3); m_simp.mk_eq(sticky_raw, nil_sbit3, sticky_eq); m_simp.mk_ite(sticky_eq, nil_sbit3, one_sbit3, sticky); SASSERT(is_well_sorted(m, sticky)); - + expr * or_args[2] = { shifted_d_sig, sticky }; shifted_d_sig = m_bv_util.mk_bv_or(2, or_args); SASSERT(is_well_sorted(m, shifted_d_sig)); @@ -475,8 +475,8 @@ void fpa2bv_converter::add_core(unsigned sbits, unsigned ebits, m_simp.mk_eq(c_sgn, d_sgn, eq_sgn); // dbg_decouple("fpa2bv_add_eq_sgn", eq_sgn); - TRACE("fpa2bv_add_core", tout << "EQ_SGN = " << mk_ismt2_pp(eq_sgn, m) << std::endl; ); - + TRACE("fpa2bv_add_core", tout << "EQ_SGN = " << mk_ismt2_pp(eq_sgn, m) << std::endl; ); + // two extra bits for catching the overflow. c_sig = m_bv_util.mk_zero_extend(2, c_sig); shifted_d_sig = m_bv_util.mk_zero_extend(2, shifted_d_sig); @@ -488,22 +488,22 @@ void fpa2bv_converter::add_core(unsigned sbits, unsigned ebits, dbg_decouple("fpa2bv_add_shifted_d_sig", shifted_d_sig); expr_ref sum(m); - m_simp.mk_ite(eq_sgn, + m_simp.mk_ite(eq_sgn, m_bv_util.mk_bv_add(c_sig, shifted_d_sig), - m_bv_util.mk_bv_sub(c_sig, shifted_d_sig), + m_bv_util.mk_bv_sub(c_sig, shifted_d_sig), sum); SASSERT(is_well_sorted(m, sum)); - dbg_decouple("fpa2bv_add_sum", sum); + dbg_decouple("fpa2bv_add_sum", sum); expr_ref sign_bv(m), n_sum(m); - sign_bv = m_bv_util.mk_extract(sbits+4, sbits+4, sum); + sign_bv = m_bv_util.mk_extract(sbits+4, sbits+4, sum); n_sum = m_bv_util.mk_bv_neg(sum); - dbg_decouple("fpa2bv_add_sign_bv", sign_bv); - dbg_decouple("fpa2bv_add_n_sum", n_sum); - + dbg_decouple("fpa2bv_add_sign_bv", sign_bv); + dbg_decouple("fpa2bv_add_n_sum", n_sum); + family_id bvfid = m_bv_util.get_fid(); expr_ref res_sgn_c1(m), res_sgn_c2(m), res_sgn_c3(m); @@ -514,7 +514,7 @@ void fpa2bv_converter::add_core(unsigned sbits, unsigned ebits, res_sgn_c1 = m.mk_app(bvfid, OP_BAND, not_c_sgn, d_sgn, sign_bv); res_sgn_c2 = m.mk_app(bvfid, OP_BAND, c_sgn, not_d_sgn, not_sign_bv); res_sgn_c3 = m.mk_app(bvfid, OP_BAND, c_sgn, d_sgn); - expr * res_sgn_or_args[3] = { res_sgn_c1, res_sgn_c2, res_sgn_c3 }; + expr * res_sgn_or_args[3] = { res_sgn_c1, res_sgn_c2, res_sgn_c3 }; res_sgn = m_bv_util.mk_bv_or(3, res_sgn_or_args); expr_ref res_sig_eq(m), sig_abs(m), one_1(m); @@ -532,14 +532,14 @@ void fpa2bv_converter::mk_add(func_decl * f, unsigned num, expr * const * args, SASSERT(num == 3); SASSERT(is_app_of(args[0], m_util.get_family_id(), OP_FPA_INTERNAL_RM)); - expr_ref bv_rm(m), x(m), y(m); + expr_ref bv_rm(m), x(m), y(m); bv_rm = to_app(args[0])->get_arg(0); x = args[1]; y = args[2]; expr_ref nan(m), nzero(m), pzero(m); mk_nan(f, nan); - mk_nzero(f, nzero); + mk_nzero(f, nzero); mk_pzero(f, pzero); expr_ref x_is_nan(m), x_is_zero(m), x_is_pos(m), x_is_neg(m), x_is_inf(m); @@ -568,24 +568,24 @@ void fpa2bv_converter::mk_add(func_decl * f, unsigned num, expr * const * args, expr_ref c1(m), c2(m), c3(m), c4(m), c5(m), c6(m); expr_ref v1(m), v2(m), v3(m), v4(m), v5(m), v6(m), v7(m); - + m_simp.mk_or(x_is_nan, y_is_nan, c1); v1 = nan; - + mk_is_inf(x, c2); - expr_ref nx(m), ny(m), nx_xor_ny(m), inf_xor(m); + expr_ref nx(m), ny(m), nx_xor_ny(m), inf_xor(m); mk_is_neg(x, nx); mk_is_neg(y, ny); m_simp.mk_xor(nx, ny, nx_xor_ny); m_simp.mk_and(y_is_inf, nx_xor_ny, inf_xor); mk_ite(inf_xor, nan, x, v2); - + mk_is_inf(y, c3); - expr_ref xy_is_neg(m), v3_and(m); + expr_ref xy_is_neg(m), v3_and(m); m_simp.mk_xor(x_is_neg, y_is_neg, xy_is_neg); m_simp.mk_and(x_is_inf, xy_is_neg, v3_and); mk_ite(v3_and, nan, y, v3); - + expr_ref rm_is_to_neg(m), signs_and(m), signs_xor(m), v4_and(m), rm_and_xor(m), neg_cond(m); m_simp.mk_and(x_is_zero, y_is_zero, c4); m_simp.mk_and(x_is_neg, y_is_neg, signs_and); @@ -605,7 +605,7 @@ void fpa2bv_converter::mk_add(func_decl * f, unsigned num, expr * const * args, // Actual addition. unsigned ebits = m_util.get_ebits(f->get_range()); - unsigned sbits = m_util.get_sbits(f->get_range()); + unsigned sbits = m_util.get_sbits(f->get_range()); expr_ref a_sgn(m), a_sig(m), a_exp(m), a_lz(m), b_sgn(m), b_sig(m), b_exp(m), b_lz(m); unpack(x, a_sgn, a_sig, a_exp, a_lz, false); @@ -627,11 +627,11 @@ void fpa2bv_converter::mk_add(func_decl * f, unsigned num, expr * const * args, m_simp.mk_ite(swap_cond, b_exp, a_exp, c_exp); // has ebits m_simp.mk_ite(swap_cond, a_sgn, b_sgn, d_sgn); m_simp.mk_ite(swap_cond, a_sig, b_sig, d_sig); // has sbits - m_simp.mk_ite(swap_cond, a_exp, b_exp, d_exp); // has ebits + m_simp.mk_ite(swap_cond, a_exp, b_exp, d_exp); // has ebits expr_ref res_sgn(m), res_sig(m), res_exp(m); add_core(sbits, ebits, - c_sgn, c_sig, c_exp, d_sgn, d_sig, d_exp, + c_sgn, c_sig, c_exp, d_sgn, d_sig, d_exp, res_sgn, res_sig, res_exp); expr_ref is_zero_sig(m), nil_sbit4(m); @@ -641,7 +641,7 @@ void fpa2bv_converter::mk_add(func_decl * f, unsigned num, expr * const * args, SASSERT(is_well_sorted(m, is_zero_sig)); dbg_decouple("fpa2bv_add_is_zero_sig", is_zero_sig); - + expr_ref zero_case(m); mk_ite(rm_is_to_neg, nzero, pzero, zero_case); @@ -649,7 +649,7 @@ void fpa2bv_converter::mk_add(func_decl * f, unsigned num, expr * const * args, round(f->get_range(), bv_rm, res_sgn, res_sig, res_exp, rounded); mk_ite(is_zero_sig, zero_case, rounded, v7); - + mk_ite(c6, v6, v7, result); mk_ite(c5, v5, result, result); mk_ite(c4, v4, result, result); @@ -675,8 +675,8 @@ void fpa2bv_converter::mk_neg(func_decl * f, unsigned num, expr * const * args, expr * sgn, * s, * e; split_fp(args[0], sgn, e, s); expr_ref c(m), nsgn(m); - mk_is_nan(args[0], c); - nsgn = m_bv_util.mk_bv_not(sgn); + mk_is_nan(args[0], c); + nsgn = m_bv_util.mk_bv_not(sgn); expr_ref r_sgn(m); m_simp.mk_ite(c, sgn, nsgn, r_sgn); mk_fp(r_sgn, e, s, result); @@ -693,7 +693,7 @@ void fpa2bv_converter::mk_mul(func_decl * f, unsigned num, expr * const * args, expr_ref nan(m), nzero(m), pzero(m), ninf(m), pinf(m); mk_nan(f, nan); - mk_nzero(f, nzero); + mk_nzero(f, nzero); mk_pzero(f, pzero); mk_ninf(f, ninf); mk_pinf(f, pinf); @@ -724,26 +724,26 @@ void fpa2bv_converter::mk_mul(func_decl * f, unsigned num, expr * const * args, // (x is NaN) || (y is NaN) -> NaN m_simp.mk_or(x_is_nan, y_is_nan, c1); v1 = nan; - + // (x is +oo) -> if (y is 0) then NaN else inf with y's sign. mk_is_pinf(x, c2); expr_ref y_sgn_inf(m); mk_ite(y_is_pos, pinf, ninf, y_sgn_inf); mk_ite(y_is_zero, nan, y_sgn_inf, v2); - + // (y is +oo) -> if (x is 0) then NaN else inf with x's sign. mk_is_pinf(y, c3); expr_ref x_sgn_inf(m); mk_ite(x_is_pos, pinf, ninf, x_sgn_inf); mk_ite(x_is_zero, nan, x_sgn_inf, v3); - - // (x is -oo) -> if (y is 0) then NaN else inf with -y's sign. + + // (x is -oo) -> if (y is 0) then NaN else inf with -y's sign. mk_is_ninf(x, c4); expr_ref neg_y_sgn_inf(m); mk_ite(y_is_pos, ninf, pinf, neg_y_sgn_inf); mk_ite(y_is_zero, nan, neg_y_sgn_inf, v4); - // (y is -oo) -> if (x is 0) then NaN else inf with -x's sign. + // (y is -oo) -> if (x is 0) then NaN else inf with -x's sign. mk_is_ninf(y, c5); expr_ref neg_x_sgn_inf(m); mk_ite(x_is_pos, ninf, pinf, neg_x_sgn_inf); @@ -754,9 +754,9 @@ void fpa2bv_converter::mk_mul(func_decl * f, unsigned num, expr * const * args, expr_ref sign_xor(m); m_simp.mk_xor(x_is_pos, y_is_pos, sign_xor); mk_ite(sign_xor, nzero, pzero, v6); - - // else comes the actual multiplication. - unsigned sbits = m_util.get_sbits(f->get_range()); + + // else comes the actual multiplication. + unsigned sbits = m_util.get_sbits(f->get_range()); expr_ref a_sgn(m), a_sig(m), a_exp(m), a_lz(m), b_sgn(m), b_sig(m), b_exp(m), b_lz(m); unpack(x, a_sgn, a_sig, a_exp, a_lz, true); @@ -772,7 +772,7 @@ void fpa2bv_converter::mk_mul(func_decl * f, unsigned num, expr * const * args, b_lz_ext = m_bv_util.mk_zero_extend(2, b_lz); dbg_decouple("fpa2bv_mul_lz_a", a_lz); - dbg_decouple("fpa2bv_mul_lz_b", b_lz); + dbg_decouple("fpa2bv_mul_lz_b", b_lz); expr_ref a_sig_ext(m), b_sig_ext(m); a_sig_ext = m_bv_util.mk_zero_extend(sbits, a_sig); @@ -802,21 +802,21 @@ void fpa2bv_converter::mk_mul(func_decl * f, unsigned num, expr * const * args, expr_ref h_p(m), l_p(m), rbits(m); h_p = m_bv_util.mk_extract(2*sbits-1, sbits, product); l_p = m_bv_util.mk_extract(sbits-1, 0, product); - + if (sbits >= 4) { expr_ref sticky(m); - sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, m_bv_util.mk_extract(sbits-4, 0, product)); + sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, m_bv_util.mk_extract(sbits-4, 0, product)); rbits = m_bv_util.mk_concat(m_bv_util.mk_extract(sbits-1, sbits-3, product), sticky); } else rbits = m_bv_util.mk_concat(l_p, m_bv_util.mk_numeral(0, 4 - sbits)); - + SASSERT(m_bv_util.get_bv_size(rbits) == 4); res_sig = m_bv_util.mk_concat(h_p, rbits); round(f->get_range(), bv_rm, res_sgn, res_sig, res_exp, v7); - // And finally, we tie them together. + // And finally, we tie them together. mk_ite(c6, v6, v7, result); mk_ite(c5, v5, result, result); mk_ite(c4, v4, result, result); @@ -832,7 +832,7 @@ void fpa2bv_converter::mk_mul(func_decl * f, unsigned num, expr * const * args, void fpa2bv_converter::mk_div(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 3); SASSERT(is_app_of(args[0], m_util.get_family_id(), OP_FPA_INTERNAL_RM)); - + expr_ref bv_rm(m), x(m), y(m); bv_rm = to_app(args[0])->get_arg(0); x = args[1]; @@ -840,21 +840,21 @@ void fpa2bv_converter::mk_div(func_decl * f, unsigned num, expr * const * args, expr_ref nan(m), nzero(m), pzero(m), ninf(m), pinf(m); mk_nan(f, nan); - mk_nzero(f, nzero); + mk_nzero(f, nzero); mk_pzero(f, pzero); mk_ninf(f, ninf); - mk_pinf(f, pinf); + 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); mk_is_nan(x, x_is_nan); mk_is_zero(x, x_is_zero); mk_is_pos(x, x_is_pos); - mk_is_inf(x, x_is_inf); + mk_is_inf(x, x_is_inf); mk_is_nan(y, y_is_nan); mk_is_zero(y, y_is_zero); mk_is_pos(y, y_is_pos); - mk_is_inf(y, y_is_inf); + mk_is_inf(y, y_is_inf); dbg_decouple("fpa2bv_div_x_is_nan", x_is_nan); dbg_decouple("fpa2bv_div_x_is_zero", x_is_zero); @@ -863,7 +863,7 @@ void fpa2bv_converter::mk_div(func_decl * f, unsigned num, expr * const * args, dbg_decouple("fpa2bv_div_y_is_nan", y_is_nan); dbg_decouple("fpa2bv_div_y_is_zero", y_is_zero); dbg_decouple("fpa2bv_div_y_is_pos", y_is_pos); - dbg_decouple("fpa2bv_div_y_is_inf", y_is_inf); + dbg_decouple("fpa2bv_div_y_is_inf", y_is_inf); expr_ref c1(m), c2(m), c3(m), c4(m), c5(m), c6(m), c7(m); expr_ref v1(m), v2(m), v3(m), v4(m), v5(m), v6(m), v7(m), v8(m); @@ -871,21 +871,21 @@ void fpa2bv_converter::mk_div(func_decl * f, unsigned num, expr * const * args, // (x is NaN) || (y is NaN) -> NaN m_simp.mk_or(x_is_nan, y_is_nan, c1); v1 = nan; - + // (x is +oo) -> if (y is oo) then NaN else inf with y's sign. mk_is_pinf(x, c2); expr_ref y_sgn_inf(m); mk_ite(y_is_pos, pinf, ninf, y_sgn_inf); mk_ite(y_is_inf, nan, y_sgn_inf, v2); - + // (y is +oo) -> if (x is oo) then NaN else 0 with sign x.sgn ^ y.sgn mk_is_pinf(y, c3); expr_ref xy_zero(m), signs_xor(m); m_simp.mk_xor(x_is_pos, y_is_pos, signs_xor); mk_ite(signs_xor, nzero, pzero, xy_zero); mk_ite(x_is_inf, nan, xy_zero, v3); - - // (x is -oo) -> if (y is oo) then NaN else inf with -y's sign. + + // (x is -oo) -> if (y is oo) then NaN else inf with -y's sign. mk_is_ninf(x, c4); expr_ref neg_y_sgn_inf(m); mk_ite(y_is_pos, ninf, pinf, neg_y_sgn_inf); @@ -895,15 +895,15 @@ void fpa2bv_converter::mk_div(func_decl * f, unsigned num, expr * const * args, mk_is_ninf(y, c5); mk_ite(x_is_inf, nan, xy_zero, v5); - // (y is 0) -> if (x is 0) then NaN else inf with xor sign. - c6 = y_is_zero; + // (y is 0) -> if (x is 0) then NaN else inf with xor sign. + c6 = y_is_zero; expr_ref sgn_inf(m); mk_ite(signs_xor, ninf, pinf, sgn_inf); mk_ite(x_is_zero, nan, sgn_inf, v6); // (x is 0) -> result is zero with sgn = x.sgn^y.sgn // This is a special case to avoid problems with the unpacking of zero. - c7 = x_is_zero; + c7 = x_is_zero; mk_ite(signs_xor, nzero, pzero, v7); // else comes the actual division. @@ -914,7 +914,7 @@ void fpa2bv_converter::mk_div(func_decl * f, unsigned num, expr * const * args, expr_ref a_sgn(m), a_sig(m), a_exp(m), a_lz(m), b_sgn(m), b_sig(m), b_exp(m), b_lz(m); unpack(x, a_sgn, a_sig, a_exp, a_lz, true); unpack(y, b_sgn, b_sig, b_exp, b_lz, true); - + unsigned extra_bits = sbits+2; expr_ref a_sig_ext(m), b_sig_ext(m); a_sig_ext = m_bv_util.mk_concat(a_sig, m_bv_util.mk_numeral(0, sbits + extra_bits)); @@ -941,7 +941,7 @@ void fpa2bv_converter::mk_div(func_decl * f, unsigned num, expr * const * args, dbg_decouple("fpa2bv_div_quotient", quotient); - SASSERT(m_bv_util.get_bv_size(quotient) == (sbits + sbits + extra_bits)); + SASSERT(m_bv_util.get_bv_size(quotient) == (sbits + sbits + extra_bits)); expr_ref sticky(m); sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, m_bv_util.mk_extract(extra_bits-2, 0, quotient)); @@ -951,7 +951,7 @@ void fpa2bv_converter::mk_div(func_decl * f, unsigned num, expr * const * args, expr_ref res_sig_lz(m); mk_leading_zeros(res_sig, sbits + 4, res_sig_lz); - dbg_decouple("fpa2bv_div_res_sig_lz", res_sig_lz); + dbg_decouple("fpa2bv_div_res_sig_lz", res_sig_lz); expr_ref res_sig_shift_amount(m); res_sig_shift_amount = m_bv_util.mk_bv_sub(res_sig_lz, m_bv_util.mk_numeral(1, sbits + 4)); dbg_decouple("fpa2bv_div_res_sig_shift_amount", res_sig_shift_amount); @@ -959,10 +959,10 @@ void fpa2bv_converter::mk_div(func_decl * f, unsigned num, expr * const * args, shift_cond = m_bv_util.mk_ule(res_sig_lz, m_bv_util.mk_numeral(1, sbits + 4)); m_simp.mk_ite(shift_cond, res_sig, m_bv_util.mk_bv_shl(res_sig, res_sig_shift_amount), res_sig); m_simp.mk_ite(shift_cond, res_exp, m_bv_util.mk_bv_sub(res_exp, m_bv_util.mk_extract(ebits+1, 0, res_sig_shift_amount)), res_exp); - + round(f->get_range(), bv_rm, res_sgn, res_sig, res_exp, v8); - // And finally, we tie them together. + // And finally, we tie them together. mk_ite(c7, v7, v8, result); mk_ite(c6, v6, result, result); mk_ite(c5, v5, result, result); @@ -978,7 +978,7 @@ void fpa2bv_converter::mk_div(func_decl * f, unsigned num, expr * const * args, void fpa2bv_converter::mk_rem(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 2); - + // Remainder is always exact, so there is no rounding mode. expr_ref x(m), y(m); x = args[0]; @@ -986,21 +986,21 @@ void fpa2bv_converter::mk_rem(func_decl * f, unsigned num, expr * const * args, expr_ref nan(m), nzero(m), pzero(m), ninf(m), pinf(m); mk_nan(f, nan); - mk_nzero(f, nzero); + mk_nzero(f, nzero); mk_pzero(f, pzero); mk_ninf(f, ninf); - mk_pinf(f, pinf); + 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); mk_is_nan(x, x_is_nan); mk_is_zero(x, x_is_zero); mk_is_pos(x, x_is_pos); - mk_is_inf(x, x_is_inf); + mk_is_inf(x, x_is_inf); mk_is_nan(y, y_is_nan); mk_is_zero(y, y_is_zero); mk_is_pos(y, y_is_pos); - mk_is_inf(y, y_is_inf); + mk_is_inf(y, y_is_inf); dbg_decouple("fpa2bv_rem_x_is_nan", x_is_nan); dbg_decouple("fpa2bv_rem_x_is_zero", x_is_zero); @@ -1009,7 +1009,7 @@ void fpa2bv_converter::mk_rem(func_decl * f, unsigned num, expr * const * args, dbg_decouple("fpa2bv_rem_y_is_nan", y_is_nan); dbg_decouple("fpa2bv_rem_y_is_zero", y_is_zero); dbg_decouple("fpa2bv_rem_y_is_pos", y_is_pos); - dbg_decouple("fpa2bv_rem_y_is_inf", y_is_inf); + dbg_decouple("fpa2bv_rem_y_is_inf", y_is_inf); expr_ref c1(m), c2(m), c3(m), c4(m), c5(m), c6(m); expr_ref v1(m), v2(m), v3(m), v4(m), v5(m), v6(m), v7(m); @@ -1021,7 +1021,7 @@ void fpa2bv_converter::mk_rem(func_decl * f, unsigned num, expr * const * args, // (x is +-oo) -> NaN c2 = x_is_inf; v2 = nan; - + // (y is +-oo) -> x c3 = y_is_inf; v3 = x; @@ -1033,16 +1033,16 @@ void fpa2bv_converter::mk_rem(func_decl * f, unsigned num, expr * const * args, // (x is 0) -> x c5 = x_is_zero; v5 = pzero; - + // else the actual remainder. unsigned ebits = m_util.get_ebits(f->get_range()); - unsigned sbits = m_util.get_sbits(f->get_range()); + unsigned sbits = m_util.get_sbits(f->get_range()); expr_ref a_sgn(m), a_sig(m), a_exp(m), a_lz(m); expr_ref b_sgn(m), b_sig(m), b_exp(m), b_lz(m); unpack(x, a_sgn, a_sig, a_exp, a_lz, true); unpack(y, b_sgn, b_sig, b_exp, b_lz, true); - + BVSLT(a_exp, b_exp, c6); v6 = x; @@ -1073,14 +1073,14 @@ void fpa2bv_converter::mk_rem(func_decl * f, unsigned num, expr * const * args, res_sig = m_bv_util.mk_concat(m_bv_util.mk_extract(sbits, 0, huge_rem), m_bv_util.mk_numeral(0, 3)); res_exp = m_bv_util.mk_sign_extend(2, b_exp); - - // CMW: Actual rounding is not necessary here, this is + + // CMW: Actual rounding is not necessary here, this is // just convenience to get rid of the extra bits. expr_ref bv_rm(m); - m_bv_util.mk_numeral(BV_RM_TIES_TO_EVEN, 3); - round(f->get_range(), bv_rm, res_sgn, res_sig, res_exp, v7); + bv_rm = m_bv_util.mk_numeral(BV_RM_TIES_TO_EVEN, 3); + round(f->get_range(), bv_rm, res_sgn, res_sig, res_exp, v7); - // And finally, we tie them together. + // And finally, we tie them together. mk_ite(c6, v6, v7, result); mk_ite(c5, v5, result, result); mk_ite(c4, v4, result, result); @@ -1122,7 +1122,7 @@ void fpa2bv_converter::mk_min(func_decl * f, unsigned num, expr * const * args, void fpa2bv_converter::mk_min_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 2); - + expr * x = args[0], * y = args[1]; expr * x_sgn, * x_sig, * x_exp; @@ -1134,7 +1134,7 @@ void fpa2bv_converter::mk_min_i(func_decl * f, unsigned num, expr * const * args mk_is_zero(x, x_is_zero); mk_is_zero(y, y_is_zero); 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); mk_is_nan(y, y_is_nan); mk_pzero(f, pzero); @@ -1142,7 +1142,7 @@ void fpa2bv_converter::mk_min_i(func_decl * f, unsigned num, expr * const * args sgn_diff = m.mk_not(m.mk_eq(x_sgn, y_sgn)); expr_ref lt(m); - mk_float_lt(f, num, args, lt); + mk_float_lt(f, num, args, lt); result = y; mk_ite(lt, x, result, result); @@ -1153,13 +1153,13 @@ void fpa2bv_converter::mk_min_i(func_decl * f, unsigned num, expr * const * args SASSERT(is_well_sorted(m, result)); } -expr_ref fpa2bv_converter::mk_min_unspecified(func_decl * f, expr * x, expr * y) { +expr_ref fpa2bv_converter::mk_min_unspecified(func_decl * f, expr * x, expr * y) { unsigned ebits = m_util.get_ebits(f->get_range()); unsigned sbits = m_util.get_sbits(f->get_range()); expr_ref res(m); // The only cases in which min is unspecified for is when the arguments are +0.0 and -0.0. - + if (m_hi_fp_unspecified) // The hardware interpretation is -0.0. mk_nzero(f, res); @@ -1209,7 +1209,7 @@ void fpa2bv_converter::mk_max_i(func_decl * f, unsigned num, expr * const * args split_fp(x, x_sgn, x_exp, x_sig); split_fp(y, y_sgn, y_exp, y_sig); - expr_ref x_is_nan(m), y_is_nan(m), x_is_zero(m), y_is_zero(m), both_zero(m), pzero(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(y, y_is_zero); m_simp.mk_and(x_is_zero, y_is_zero, both_zero); @@ -1222,10 +1222,10 @@ void fpa2bv_converter::mk_max_i(func_decl * f, unsigned num, expr * const * args expr_ref gt(m); mk_float_gt(f, num, args, gt); - + result = y; mk_ite(gt, x, result, result); - mk_ite(both_zero, y, result, result); + mk_ite(both_zero, y, result, result); mk_ite(y_is_nan, x, result, result); mk_ite(x_is_nan, y, result, result); @@ -1240,7 +1240,7 @@ expr_ref fpa2bv_converter::mk_max_unspecified(func_decl * f, expr * x, expr * y) // The only cases in which max is unspecified for is when the arguments are +0.0 and -0.0. if (m_hi_fp_unspecified) - // The hardware interpretation is +0.0. + // The hardware interpretation is +0.0. mk_pzero(f, res); else { expr_ref pn(m), np(m); @@ -1259,7 +1259,7 @@ expr_ref fpa2bv_converter::mk_max_unspecified(func_decl * f, expr * x, expr * y) m_simp.mk_and(x_is_pzero, x_is_nzero, xyzero); mk_ite(xyzero, pn, np, res); } - + return res; } @@ -1276,7 +1276,7 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, expr_ref nan(m), nzero(m), pzero(m), ninf(m), pinf(m); mk_nan(f, nan); - mk_nzero(f, nzero); + mk_nzero(f, nzero); mk_pzero(f, pzero); mk_ninf(f, ninf); mk_pinf(f, pinf); @@ -1327,29 +1327,29 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, // (x is NaN) || (y is NaN) || (z is Nan) -> NaN m_simp.mk_or(x_is_nan, y_is_nan, z_is_nan, c1); v1 = nan; - + // (x is +oo) -> if (y is 0) then NaN else inf with y's sign. mk_is_pinf(x, c2); expr_ref y_sgn_inf(m), inf_or(m); mk_ite(y_is_pos, pinf, ninf, y_sgn_inf); m_simp.mk_or(y_is_zero, inf_cond, inf_or); mk_ite(inf_or, nan, y_sgn_inf, v2); - + // (y is +oo) -> if (x is 0) then NaN else inf with x's sign. mk_is_pinf(y, c3); expr_ref x_sgn_inf(m); mk_ite(x_is_pos, pinf, ninf, x_sgn_inf); m_simp.mk_or(x_is_zero, inf_cond, inf_or); mk_ite(inf_or, nan, x_sgn_inf, v3); - - // (x is -oo) -> if (y is 0) then NaN else inf with -y's sign. + + // (x is -oo) -> if (y is 0) then NaN else inf with -y's sign. mk_is_ninf(x, c4); expr_ref neg_y_sgn_inf(m); mk_ite(y_is_pos, ninf, pinf, neg_y_sgn_inf); m_simp.mk_or(y_is_zero, inf_cond, inf_or); mk_ite(inf_or, nan, neg_y_sgn_inf, v4); - // (y is -oo) -> if (x is 0) then NaN else inf with -x's sign. + // (y is -oo) -> if (x is 0) then NaN else inf with -x's sign. mk_is_ninf(y, c5); expr_ref neg_x_sgn_inf(m); mk_ite(x_is_pos, ninf, pinf, neg_x_sgn_inf); @@ -1365,7 +1365,7 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, expr_ref ite_c(m); m_simp.mk_and(z_is_zero, m.mk_not(rm_is_to_neg), ite_c); mk_ite(ite_c, pzero, z, v7); - + // else comes the fused multiplication. unsigned ebits = m_util.get_ebits(f->get_range()); unsigned sbits = m_util.get_sbits(f->get_range()); @@ -1375,7 +1375,7 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, expr_ref c_sgn(m), c_sig(m), c_exp(m), c_lz(m); unpack(x, a_sgn, a_sig, a_exp, a_lz, true); unpack(y, b_sgn, b_sig, b_exp, b_lz, true); - unpack(z, c_sgn, c_sig, c_exp, c_lz, true); + unpack(z, c_sgn, c_sig, c_exp, c_lz, true); expr_ref a_lz_ext(m), b_lz_ext(m), c_lz_ext(m); a_lz_ext = m_bv_util.mk_zero_extend(2, a_lz); @@ -1384,12 +1384,12 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, expr_ref a_sig_ext(m), b_sig_ext(m); a_sig_ext = m_bv_util.mk_zero_extend(sbits, a_sig); - b_sig_ext = m_bv_util.mk_zero_extend(sbits, b_sig); + b_sig_ext = m_bv_util.mk_zero_extend(sbits, b_sig); expr_ref a_exp_ext(m), b_exp_ext(m), c_exp_ext(m); a_exp_ext = m_bv_util.mk_sign_extend(2, a_exp); b_exp_ext = m_bv_util.mk_sign_extend(2, b_exp); - c_exp_ext = m_bv_util.mk_sign_extend(2, c_exp); + c_exp_ext = m_bv_util.mk_sign_extend(2, c_exp); dbg_decouple("fpa2bv_fma_a_sig", a_sig_ext); dbg_decouple("fpa2bv_fma_b_sig", b_sig_ext); @@ -1410,7 +1410,7 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, mul_exp = m_bv_util.mk_bv_add(m_bv_util.mk_bv_sub(a_exp_ext, a_lz_ext), m_bv_util.mk_bv_sub(b_exp_ext, b_lz_ext)); dbg_decouple("fpa2bv_fma_mul_exp", mul_exp); - + mul_sig = m_bv_util.mk_bv_mul(a_sig_ext, b_sig_ext); dbg_decouple("fpa2bv_fma_mul_sig", mul_sig); @@ -1418,7 +1418,7 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, SASSERT(m_bv_util.get_bv_size(mul_exp) == ebits + 2); // The product has the form [-1][0].[2*sbits - 2]. - + // Extend c c_sig = m_bv_util.mk_zero_extend(1, m_bv_util.mk_concat(c_sig, m_bv_util.mk_numeral(0, sbits-1))); c_exp_ext = m_bv_util.mk_bv_sub(c_exp_ext, c_lz_ext); @@ -1437,7 +1437,7 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, m_simp.mk_ite(swap_cond, c_exp_ext, mul_exp, e_exp); // has ebits + 2 m_simp.mk_ite(swap_cond, mul_sgn, c_sgn, f_sgn); m_simp.mk_ite(swap_cond, mul_sig, c_sig, f_sig); // has 2 * sbits - m_simp.mk_ite(swap_cond, mul_exp, c_exp_ext, f_exp); // has ebits + 2 + m_simp.mk_ite(swap_cond, mul_exp, c_exp_ext, f_exp); // has ebits + 2 SASSERT(is_well_sorted(m, e_sgn)); SASSERT(is_well_sorted(m, e_sig)); @@ -1452,12 +1452,12 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, SASSERT(m_bv_util.get_bv_size(f_exp) == ebits + 2); expr_ref res_sgn(m), res_sig(m), res_exp(m); - + expr_ref exp_delta(m); exp_delta = m_bv_util.mk_bv_sub(e_exp, f_exp); dbg_decouple("fpa2bv_fma_add_exp_delta", exp_delta); - // cap the delta + // cap the delta expr_ref cap(m), cap_le_delta(m); cap = m_bv_util.mk_numeral(2*sbits, ebits+2); cap_le_delta = m_bv_util.mk_ule(cap, exp_delta); @@ -1465,23 +1465,23 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, SASSERT(m_bv_util.get_bv_size(exp_delta) == ebits+2); SASSERT(is_well_sorted(m, exp_delta)); dbg_decouple("fpa2bv_fma_add_exp_delta_capped", exp_delta); - + // Alignment shift with sticky bit computation. expr_ref shifted_big(m), shifted_f_sig(m), sticky_raw(m); shifted_big = m_bv_util.mk_bv_lshr( - m_bv_util.mk_concat(f_sig, m_bv_util.mk_numeral(0, sbits)), + m_bv_util.mk_concat(f_sig, m_bv_util.mk_numeral(0, sbits)), m_bv_util.mk_zero_extend((3*sbits)-(ebits+2), exp_delta)); shifted_f_sig = m_bv_util.mk_extract(3*sbits-1, sbits, shifted_big); - sticky_raw = m_bv_util.mk_extract(sbits-1, 0, shifted_big); + sticky_raw = m_bv_util.mk_extract(sbits-1, 0, shifted_big); SASSERT(m_bv_util.get_bv_size(shifted_f_sig) == 2 * sbits); - SASSERT(is_well_sorted(m, shifted_f_sig)); - - expr_ref sticky(m); + SASSERT(is_well_sorted(m, shifted_f_sig)); + + expr_ref sticky(m); sticky = m_bv_util.mk_zero_extend(2*sbits-1, m.mk_app(m_bv_util.get_fid(), OP_BREDOR, sticky_raw.get())); SASSERT(is_well_sorted(m, sticky)); dbg_decouple("fpa2bv_fma_f_sig_sticky_raw", sticky_raw); dbg_decouple("fpa2bv_fma_f_sig_sticky", sticky); - + expr * or_args[2] = { shifted_f_sig, sticky }; shifted_f_sig = m_bv_util.mk_bv_or(2, or_args); SASSERT(is_well_sorted(m, shifted_f_sig)); @@ -1501,9 +1501,9 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, dbg_decouple("fpa2bv_fma_add_shifted_f_sig", shifted_f_sig); expr_ref sum(m); - m_simp.mk_ite(eq_sgn, + m_simp.mk_ite(eq_sgn, m_bv_util.mk_bv_add(e_sig, shifted_f_sig), - m_bv_util.mk_bv_sub(e_sig, shifted_f_sig), + m_bv_util.mk_bv_sub(e_sig, shifted_f_sig), sum); SASSERT(is_well_sorted(m, sum)); @@ -1511,19 +1511,19 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, dbg_decouple("fpa2bv_fma_add_sum", sum); expr_ref sign_bv(m), n_sum(m); - sign_bv = m_bv_util.mk_extract(2*sbits+1, 2*sbits+1, sum); + sign_bv = m_bv_util.mk_extract(2*sbits+1, 2*sbits+1, sum); n_sum = m_bv_util.mk_bv_neg(sum); expr_ref res_sig_eq(m), sig_abs(m), one_1(m); one_1 = m_bv_util.mk_numeral(1, 1); m_simp.mk_eq(sign_bv, one_1, res_sig_eq); m_simp.mk_ite(res_sig_eq, n_sum, sum, sig_abs); - dbg_decouple("fpa2bv_fma_add_sign_bv", sign_bv); - dbg_decouple("fpa2bv_fma_add_n_sum", n_sum); + dbg_decouple("fpa2bv_fma_add_sign_bv", sign_bv); + dbg_decouple("fpa2bv_fma_add_n_sum", n_sum); dbg_decouple("fpa2bv_fma_add_sig_abs", sig_abs); res_exp = e_exp; - + // Result could overflow into 4.xxx ... family_id bvfid = m_bv_util.get_fid(); @@ -1535,7 +1535,7 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, res_sgn_c1 = m.mk_app(bvfid, OP_BAND, not_e_sgn, f_sgn, sign_bv); res_sgn_c2 = m.mk_app(bvfid, OP_BAND, e_sgn, not_f_sgn, not_sign_bv); res_sgn_c3 = m.mk_app(bvfid, OP_BAND, e_sgn, f_sgn); - expr * res_sgn_or_args[3] = { res_sgn_c1, res_sgn_c2, res_sgn_c3 }; + expr * res_sgn_or_args[3] = { res_sgn_c1, res_sgn_c2, res_sgn_c3 }; res_sgn = m_bv_util.mk_bv_or(3, res_sgn_or_args); if (sbits > 5) { @@ -1558,7 +1558,7 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, SASSERT(is_well_sorted(m, is_zero_sig)); dbg_decouple("fpa2bv_fma_is_zero_sig", is_zero_sig); - + expr_ref zero_case(m); mk_ite(rm_is_to_neg, nzero, pzero, zero_case); @@ -1587,40 +1587,40 @@ void fpa2bv_converter::mk_sqrt(func_decl * f, unsigned num, expr * const * args, expr_ref bv_rm(m), x(m); bv_rm = to_app(args[0])->get_arg(0); - x = args[1]; + x = args[1]; expr_ref nan(m), nzero(m), pzero(m), ninf(m), pinf(m); mk_nan(f, nan); - mk_nzero(f, nzero); + mk_nzero(f, nzero); mk_pzero(f, pzero); 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 x_is_nan(m), x_is_zero(m), x_is_pos(m), x_is_inf(m); mk_is_nan(x, x_is_nan); mk_is_zero(x, x_is_zero); mk_is_pos(x, x_is_pos); mk_is_inf(x, x_is_inf); - + expr_ref zero1(m), one1(m); zero1 = m_bv_util.mk_numeral(0, 1); one1 = m_bv_util.mk_numeral(1, 1); - + expr_ref c1(m), c2(m), c3(m), c4(m), c5(m), c6(m); expr_ref v1(m), v2(m), v3(m), v4(m), v5(m), v6(m), v7(m); // (x is NaN) -> NaN c1 = x_is_nan; v1 = x; - + // (x is +oo) -> +oo mk_is_pinf(x, c2); v2 = x; - + // (x is +-0) -> +-0 mk_is_zero(x, c3); v3 = x; - + // (x < 0) -> NaN mk_is_neg(x, c4); v4 = nan; @@ -1652,11 +1652,11 @@ void fpa2bv_converter::mk_sqrt(func_decl * f, unsigned num, expr * const * args, dbg_decouple("fpa2bv_sqrt_e_is_odd", e_is_odd); dbg_decouple("fpa2bv_sqrt_real_exp", real_exp); - expr_ref sig_prime(m); + expr_ref sig_prime(m); m_simp.mk_ite(e_is_odd, m_bv_util.mk_concat(a_sig, zero1), - m_bv_util.mk_concat(zero1, a_sig), + m_bv_util.mk_concat(zero1, a_sig), sig_prime); - SASSERT(m_bv_util.get_bv_size(sig_prime) == sbits+1); + SASSERT(m_bv_util.get_bv_size(sig_prime) == sbits+1); dbg_decouple("fpa2bv_sqrt_sig_prime", sig_prime); // This is algorithm 10.2 in the Handbook of Floating-Point Arithmetic @@ -1672,7 +1672,7 @@ void fpa2bv_converter::mk_sqrt(func_decl * f, unsigned num, expr * const * args, dbg_decouple("fpa2bv_sqrt_R", R); S = m_bv_util.mk_concat(zero1, m_bv_util.mk_extract(sbits+4, 1, S)); - + expr_ref twoQ_plus_S(m); twoQ_plus_S = m_bv_util.mk_bv_add(m_bv_util.mk_concat(Q, zero1), m_bv_util.mk_concat(zero1, S)); T = m_bv_util.mk_bv_sub(m_bv_util.mk_concat(R, zero1), twoQ_plus_S); @@ -1685,21 +1685,21 @@ void fpa2bv_converter::mk_sqrt(func_decl * f, unsigned num, expr * const * args, SASSERT(m_bv_util.get_bv_size(T) == sbits + 6); expr_ref t_lt_0(m); - m_simp.mk_eq(m_bv_util.mk_extract(sbits+5, sbits+5, T), one1, t_lt_0); - + m_simp.mk_eq(m_bv_util.mk_extract(sbits+5, sbits+5, T), one1, t_lt_0); + expr * or_args[2] = { Q, S }; m_simp.mk_ite(t_lt_0, Q, m_bv_util.mk_bv_or(2, or_args), Q); - m_simp.mk_ite(t_lt_0, m_bv_util.mk_concat(m_bv_util.mk_extract(sbits+3, 0, R), zero1), - m_bv_util.mk_extract(sbits+4, 0, T), + m_simp.mk_ite(t_lt_0, m_bv_util.mk_concat(m_bv_util.mk_extract(sbits+3, 0, R), zero1), + m_bv_util.mk_extract(sbits+4, 0, T), R); } expr_ref is_exact(m); m_simp.mk_eq(R, m_bv_util.mk_numeral(0, sbits+5), is_exact); - dbg_decouple("fpa2bv_sqrt_is_exact", is_exact); + dbg_decouple("fpa2bv_sqrt_is_exact", is_exact); expr_ref rest(m), last(m), q_is_odd(m), rest_ext(m); last = m_bv_util.mk_extract(0, 0, Q); @@ -1717,7 +1717,7 @@ void fpa2bv_converter::mk_sqrt(func_decl * f, unsigned num, expr * const * args, SASSERT(m_bv_util.get_bv_size(res_sig) == sbits + 4); expr_ref rounded(m); - round(f->get_range(), bv_rm, res_sgn, res_sig, res_exp, rounded); + round(f->get_range(), bv_rm, res_sgn, res_sig, res_exp, rounded); v5 = rounded; // And finally, we tie them together. @@ -1746,16 +1746,16 @@ void fpa2bv_converter::mk_round_to_integral(func_decl * f, unsigned num, expr * expr_ref nan(m), nzero(m), pzero(m), ninf(m), pinf(m); mk_nan(f, nan); - mk_nzero(f, nzero); + mk_nzero(f, nzero); mk_pzero(f, pzero); expr_ref x_is_zero(m), x_is_pos(m), x_is_neg(m); mk_is_zero(x, x_is_zero); mk_is_pos(x, x_is_pos); mk_is_neg(x, x_is_neg); - + dbg_decouple("fpa2bv_r2i_x_is_zero", x_is_zero); - dbg_decouple("fpa2bv_r2i_x_is_pos", x_is_pos); + dbg_decouple("fpa2bv_r2i_x_is_pos", x_is_pos); expr_ref c1(m), c2(m), c3(m), c4(m), c5(m); expr_ref v1(m), v2(m), v3(m), v4(m), v5(m), v6(m); @@ -1771,18 +1771,18 @@ void fpa2bv_converter::mk_round_to_integral(func_decl * f, unsigned num, expr * // (x is +-0) -> x ; -0.0 -> -0.0, says IEEE754, Sec 5.9. mk_is_zero(x, c3); v3 = x; - + expr_ref one_1(m), zero_1(m); one_1 = m_bv_util.mk_numeral(1, 1); zero_1 = m_bv_util.mk_numeral(0, 1); - + unsigned ebits = m_util.get_ebits(f->get_range()); - unsigned sbits = m_util.get_sbits(f->get_range()); + unsigned sbits = m_util.get_sbits(f->get_range()); expr_ref a_sgn(m), a_sig(m), a_exp(m), a_lz(m); unpack(x, a_sgn, a_sig, a_exp, a_lz, true); - + dbg_decouple("fpa2bv_r2i_unpacked_sig", a_sig); dbg_decouple("fpa2bv_r2i_unpacked_exp", a_exp); @@ -1791,7 +1791,7 @@ void fpa2bv_converter::mk_round_to_integral(func_decl * f, unsigned num, expr * // exponent < 0 -> 0/1 expr_ref exp_lt_zero(m), exp_h(m); - exp_h = m_bv_util.mk_extract(ebits-1, ebits-1, a_exp); + exp_h = m_bv_util.mk_extract(ebits-1, ebits-1, a_exp); m_simp.mk_eq(exp_h, one_1, exp_lt_zero); dbg_decouple("fpa2bv_r2i_exp_lt_zero", exp_lt_zero); c4 = exp_lt_zero; @@ -1800,10 +1800,10 @@ void fpa2bv_converter::mk_round_to_integral(func_decl * f, unsigned num, expr * mk_one(f, zero_1, pone); mk_one(f, one_1, none); mk_ite(m.mk_eq(a_sgn, one_1), none, pone, xone); - + m_simp.mk_eq(a_sig, m_bv_util.mk_numeral(fu().fm().m_powers2(sbits-1), sbits), t1); m_simp.mk_eq(a_exp, m_bv_util.mk_numeral(-1, ebits), t2); - m_simp.mk_and(t1, t2, tie); + m_simp.mk_and(t1, t2, tie); dbg_decouple("fpa2bv_r2i_c42_tie", tie); m_simp.mk_and(tie, rm_is_rte, c421); @@ -1818,7 +1818,7 @@ void fpa2bv_converter::mk_round_to_integral(func_decl * f, unsigned num, expr * mk_ite(c423, xzero, v42, v42); mk_ite(c422, xone, v42, v42); mk_ite(c421, xzero, v42, v42); - + expr_ref v4_rtn(m), v4_rtp(m); mk_ite(x_is_neg, nzero, pone, v4_rtp); mk_ite(x_is_neg, none, pzero, v4_rtn); @@ -1828,7 +1828,7 @@ void fpa2bv_converter::mk_round_to_integral(func_decl * f, unsigned num, expr * mk_ite(rm_is_rtz, xzero, v4, v4); SASSERT(is_well_sorted(m, v4)); - + // exponent >= sbits-1 expr_ref exp_is_large(m); exp_is_large = m_bv_util.mk_sle(m_bv_util.mk_numeral(sbits-1, ebits), a_exp); @@ -1836,7 +1836,7 @@ void fpa2bv_converter::mk_round_to_integral(func_decl * f, unsigned num, expr * c5 = exp_is_large; v5 = x; - // Actual conversion with rounding. + // Actual conversion with rounding. // x.exponent >= 0 && x.exponent < x.sbits - 1 expr_ref res_sgn(m), res_sig(m), res_exp(m); @@ -1867,7 +1867,7 @@ void fpa2bv_converter::mk_round_to_integral(func_decl * f, unsigned num, expr * rem_shl = m_bv_util.mk_concat(m_bv_util.mk_extract(sbits - 1, 0, rem), zero_1); m_simp.mk_eq(rem_shl, m_bv_util.mk_bv_shl(m_bv_util.mk_numeral(1, sbits+1), shift), - tie2); + tie2); div_last = m_bv_util.mk_extract(0, 0, div); tie2_c = m.mk_or(m.mk_and(tie2, m.mk_or(m.mk_and(rm_is_rte, m.mk_eq(div_last, one_1)), @@ -1898,13 +1898,13 @@ void fpa2bv_converter::mk_round_to_integral(func_decl * f, unsigned num, expr * c51 = m.mk_or(rm_is_rte, rm_is_rta); c52 = rm_is_rtp; c53 = rm_is_rtn; - + res_sig = div; m_simp.mk_ite(c53, v53, res_sig, res_sig); m_simp.mk_ite(c52, v52, res_sig, res_sig); m_simp.mk_ite(c51, v51, res_sig, res_sig); res_sig = m_bv_util.mk_concat(res_sig, m_bv_util.mk_numeral(0, 3)); // rounding bits are all 0. - + SASSERT(m_bv_util.get_bv_size(res_exp) == ebits); SASSERT(m_bv_util.get_bv_size(shift) == sbits + 1); @@ -1919,7 +1919,7 @@ void fpa2bv_converter::mk_round_to_integral(func_decl * f, unsigned num, expr * SASSERT(m_bv_util.get_bv_size(res_exp) == ebits + 2); // CMW: We use the rounder for normalization. - round(f->get_range(), bv_rm, res_sgn, res_sig, res_exp, v6); + round(f->get_range(), bv_rm, res_sgn, res_sig, res_exp, v6); // And finally, we tie them together. mk_ite(c5, v5, v6, result); @@ -1938,7 +1938,7 @@ void fpa2bv_converter::mk_float_eq(func_decl * f, unsigned num, expr * const * a expr * x = args[0], * y = args[1]; - TRACE("fpa2bv_float_eq", tout << "X = " << mk_ismt2_pp(x, m) << std::endl; + TRACE("fpa2bv_float_eq", tout << "X = " << mk_ismt2_pp(x, m) << std::endl; tout << "Y = " << mk_ismt2_pp(y, m) << std::endl;); expr_ref c1(m), c2(m), x_is_nan(m), y_is_nan(m), x_is_zero(m), y_is_zero(m); @@ -1953,7 +1953,7 @@ void fpa2bv_converter::mk_float_eq(func_decl * f, unsigned num, expr * const * a expr * y_sgn, * y_sig, * y_exp; split_fp(x, x_sgn, x_exp, x_sig); split_fp(y, y_sgn, y_exp, y_sig); - + expr_ref x_eq_y_sgn(m), x_eq_y_exp(m), x_eq_y_sig(m); m_simp.mk_eq(x_sgn, y_sgn, x_eq_y_sgn); m_simp.mk_eq(x_exp, y_exp, x_eq_y_exp); @@ -1976,7 +1976,7 @@ void fpa2bv_converter::mk_float_lt(func_decl * f, unsigned num, expr * const * a SASSERT(num == 2); expr * x = args[0], * y = args[1]; - + expr_ref c1(m), c2(m), x_is_nan(m), y_is_nan(m), x_is_zero(m), y_is_zero(m); mk_is_nan(x, x_is_nan); mk_is_nan(y, y_is_nan); @@ -2111,14 +2111,14 @@ void fpa2bv_converter::mk_is_positive(func_decl * f, unsigned num, expr * const expr_ref t1(m), t2(m); mk_is_nan(args[0], t1); mk_is_pos(args[0], t2); - result = m.mk_and(m.mk_not(t1), t2); + result = m.mk_and(m.mk_not(t1), t2); } void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { TRACE("fpa2bv_to_fp", for (unsigned i=0; i < num; i++) tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl; ); - if (num == 1 && + if (num == 1 && m_bv_util.is_bv(args[0])) { sort * s = f->get_range(); unsigned to_sbits = m_util.get_sbits(s); @@ -2141,7 +2141,7 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args } else if (num == 2 && m_util.is_rm(args[0]) && - (m_arith_util.is_int(args[1]) || + (m_arith_util.is_int(args[1]) || m_arith_util.is_real(args[1]))) { // rm + real -> float mk_to_fp_real(f, f->get_range(), args[0], args[1], result); @@ -2152,14 +2152,14 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args // rm + signed bv -> float mk_to_fp_signed(f, num, args, result); } - else if (num == 3 && - m_bv_util.is_bv(args[0]) && - m_bv_util.is_bv(args[1]) && - m_bv_util.is_bv(args[2])) { + else if (num == 3 && + m_bv_util.is_bv(args[0]) && + m_bv_util.is_bv(args[1]) && + m_bv_util.is_bv(args[2])) { // 3 BV -> float SASSERT(m_bv_util.get_bv_size(args[0]) == 1); SASSERT(m_util.get_ebits(f->get_range()) == m_bv_util.get_bv_size(args[1])); - SASSERT(m_util.get_sbits(f->get_range()) == m_bv_util.get_bv_size(args[2])+1); + SASSERT(m_util.get_sbits(f->get_range()) == m_bv_util.get_bv_size(args[2])+1); mk_fp(args[0], args[1], args[2], result); } else if (num == 3 && @@ -2169,11 +2169,11 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args { // rm + real + int -> float mk_to_fp_real_int(f, num, args, result); - } + } else UNREACHABLE(); - SASSERT(is_well_sorted(m, result)); + 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) { @@ -2217,7 +2217,7 @@ void fpa2bv_converter::mk_to_fp_float(func_decl * f, sort * s, expr * rm, expr * mk_is_ninf(x, c5); v5 = ninf; - // otherwise: the actual conversion with rounding. + // otherwise: the actual conversion with rounding. expr_ref sgn(m), sig(m), exp(m), lz(m); unpack(x, sgn, sig, exp, lz, true); @@ -2244,11 +2244,11 @@ void fpa2bv_converter::mk_to_fp_float(func_decl * f, sort * s, expr * rm, expr * expr_ref sticky(m), low(m), high(m); high = m_bv_util.mk_extract(from_sbits - 1, from_sbits - to_sbits - 2, sig); SASSERT(m_bv_util.get_bv_size(high) == to_sbits + 2); - low = m_bv_util.mk_extract(from_sbits - to_sbits - 3, 0, sig); + low = m_bv_util.mk_extract(from_sbits - to_sbits - 3, 0, sig); sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, low.get()); SASSERT(m_bv_util.get_bv_size(sticky) == 1); dbg_decouple("fpa2bv_to_float_sticky", sticky); - res_sig = m_bv_util.mk_concat(high, sticky); + res_sig = m_bv_util.mk_concat(high, sticky); SASSERT(m_bv_util.get_bv_size(res_sig) == to_sbits + 3); } else @@ -2270,8 +2270,8 @@ void fpa2bv_converter::mk_to_fp_float(func_decl * f, sort * s, expr * rm, expr * 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)) { - expr_ref lz_rest(m), lz_redor(m), lz_redor_bool(m); + else if (from_ebits > (to_ebits + 2)) { + expr_ref lz_rest(m), lz_redor(m), lz_redor_bool(m); lz_rest = m_bv_util.mk_extract(from_ebits - 1, to_ebits + 2, lz); lz_redor = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, lz_rest.get()); m_simp.mk_eq(lz_redor, one1, lz_redor_bool); @@ -2290,7 +2290,7 @@ void fpa2bv_converter::mk_to_fp_float(func_decl * f, sort * s, expr * rm, expr * dbg_decouple("fpa2bv_to_float_exp_high", high); dbg_decouple("fpa2bv_to_float_exp_low", low); dbg_decouple("fpa2bv_to_float_exp_low_msb", low_msb); - + res_exp = low; expr_ref high_red_or(m), high_red_and(m); @@ -2307,19 +2307,19 @@ void fpa2bv_converter::mk_to_fp_float(func_decl * f, sort * s, expr * rm, expr * dbg_decouple("fpa2bv_to_float_exp_h_or_eq_0", h_or_eq_0); dbg_decouple("fpa2bv_to_float_exp_s_is_zero", low_msb_is_zero); dbg_decouple("fpa2bv_to_float_exp_s_is_one", low_msb_is_one); - + m_simp.mk_and(h_or_eq_0, low_msb_is_one, exponent_underflow); m_simp.mk_and(h_and_eq_1, low_msb_is_zero, exponent_overflow); m_simp.mk_or(exponent_overflow, lz_redor_bool, exponent_overflow); dbg_decouple("fpa2bv_to_float_exp_ovf", exponent_overflow); dbg_decouple("fpa2bv_to_float_exp_udf", exponent_underflow); - // exponent underflow means that the result is the smallest - // representable float, rounded according to rm. - m_simp.mk_ite(exponent_underflow, + // exponent underflow means that the result is the smallest + // representable float, rounded according to rm. + m_simp.mk_ite(exponent_underflow, m_bv_util.mk_concat(m_bv_util.mk_numeral(1, 1), - m_bv_util.mk_numeral(1, to_ebits+1)), - res_exp, + m_bv_util.mk_numeral(1, to_ebits+1)), + res_exp, res_exp); m_simp.mk_ite(exponent_underflow, m_bv_util.mk_numeral(1, to_sbits+4), res_sig, res_sig); } @@ -2340,7 +2340,7 @@ void fpa2bv_converter::mk_to_fp_float(func_decl * f, sort * s, expr * rm, expr * m_simp.mk_eq(sgn, one1, is_neg); mk_ite(is_neg, ninf, pinf, sig_inf); - mk_ite(exponent_overflow, sig_inf, rounded, v6); + mk_ite(exponent_overflow, sig_inf, rounded, v6); // And finally, we tie them together. mk_ite(c5, v5, v6, result); @@ -2354,12 +2354,12 @@ void fpa2bv_converter::mk_to_fp_float(func_decl * f, sort * s, expr * rm, expr * } void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * x, expr_ref & result) { - TRACE("fpa2bv_to_fp_real", tout << "rm: " << mk_ismt2_pp(rm, m) << std::endl << + TRACE("fpa2bv_to_fp_real", tout << "rm: " << mk_ismt2_pp(rm, m) << std::endl << "x: " << mk_ismt2_pp(x, m) << std::endl;); SASSERT(m_util.is_float(s)); SASSERT(au().is_real(x) || au().is_int(x)); SASSERT(is_app_of(rm, m_util.get_family_id(), OP_FPA_INTERNAL_RM)); - + expr * bv_rm = to_app(rm)->get_arg(0); unsigned ebits = m_util.get_ebits(s); unsigned sbits = m_util.get_sbits(s); @@ -2473,13 +2473,13 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * two = au.mk_numeral(rational(2), false); expr_ref sgn(m), sig(m), exp(m); - sgn = mk_fresh_const("fpa2bv_to_fp_real_sgn", 1); + sgn = mk_fresh_const("fpa2bv_to_fp_real_sgn", 1); sig = mk_fresh_const("fpa2bv_to_fp_real_sig", sbits + 4); exp = mk_fresh_const("fpa2bv_to_fp_real_exp", ebits + 2); expr_ref rme(bv_rm, m); round(s, rme, sgn, sig, exp, result); - + expr * e = m.mk_eq(m_util.mk_to_real(result), x); m_extra_assertions.push_back(e); } @@ -2634,11 +2634,11 @@ void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const // 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: + // 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. + // [[(_ 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. SASSERT(num == 2); SASSERT(m_util.is_float(f->get_range())); @@ -2672,7 +2672,7 @@ void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const // Special case: x == 0 -> p/n zero expr_ref c1(m), v1(m); - c1 = is_zero; + c1 = is_zero; v1 = pzero; // Special case: x != 0 @@ -2710,13 +2710,13 @@ void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const 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), + 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 @@ -2724,13 +2724,13 @@ void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const 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. + // the remaining bits are 0 if ebits is large enough. exp_too_large = m.mk_false(); // The exponent is at most bv_sz, i.e., we need ld(bv_sz)+1 ebits. - // exp < bv_sz (+sign bit which is [0]) + // exp < bv_sz (+sign bit which is [0]) unsigned exp_worst_case_sz = (unsigned)((log((double)bv_sz) / log((double)2)) + 1.0); - + TRACE("fpa2bv_to_fp_signed", tout << "exp worst case sz: " << exp_worst_case_sz << std::endl;); if (exp_sz < exp_worst_case_sz) { @@ -2742,13 +2742,13 @@ void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const 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)), + 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); + dbg_decouple("fpa2bv_to_fp_signed_exp_too_large", exp_too_large); expr_ref sgn(m), sig(m), exp(m); sgn = is_neg_bit; @@ -2761,10 +2761,10 @@ void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const 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(), bv_rm, sgn, sig, exp, v2); - + mk_ite(c1, v1, v2, result); } @@ -2784,7 +2784,7 @@ void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * con SASSERT(num == 2); SASSERT(m_util.is_float(f->get_range())); SASSERT(is_app_of(args[0], m_util.get_family_id(), OP_FPA_INTERNAL_RM)); - SASSERT(m_bv_util.is_bv(args[1])); + SASSERT(m_bv_util.is_bv(args[1])); expr_ref bv_rm(m), x(m); bv_rm = to_app(args[0])->get_arg(0); @@ -2795,7 +2795,7 @@ void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * con unsigned ebits = m_util.get_ebits(f->get_range()); unsigned sbits = m_util.get_sbits(f->get_range()); unsigned bv_sz = m_bv_util.get_bv_size(x); - SASSERT(m_bv_util.get_bv_size(bv_rm) == 3); + SASSERT(m_bv_util.get_bv_size(bv_rm) == 3); expr_ref bv0_1(m), bv1_1(m), bv0_sz(m), bv1_sz(m); bv0_1 = m_bv_util.mk_numeral(0, 1); @@ -2816,7 +2816,7 @@ void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * con v1 = pzero; // 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); // x is [bv_sz-1] . [bv_sz-2 ... 0] * 2^(bv_sz-1) // bv_sz-1 is the "1.0" bit for the rounder. @@ -2858,12 +2858,12 @@ void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * con 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 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((double)bv_sz) / log((double)2)) + 1.0); + // exp < bv_sz (+sign bit which is [0]) + unsigned exp_worst_case_sz = (unsigned)((log((double)bv_sz) / log((double)2)) + 1.0); if (exp_sz < exp_worst_case_sz) { // exp_sz < exp_worst_case_sz and exp >= 0. @@ -2910,10 +2910,10 @@ void fpa2bv_converter::mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * void fpa2bv_converter::mk_to_bv(func_decl * f, unsigned num, expr * const * args, bool is_signed, expr_ref & result) { TRACE("fpa2bv_to_bv", for (unsigned i = 0; i < num; i++) tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl;); - + SASSERT(num == 2); SASSERT(is_app_of(args[0], m_util.get_family_id(), OP_FPA_INTERNAL_RM)); - SASSERT(m_util.is_float(args[1])); + SASSERT(m_util.is_float(args[1])); expr * bv_rm = to_app(args[0])->get_arg(0); expr * x = args[1]; @@ -2923,7 +2923,7 @@ void fpa2bv_converter::mk_to_bv(func_decl * f, unsigned num, expr * const * args unsigned ebits = m_util.get_ebits(xs); unsigned sbits = m_util.get_sbits(xs); unsigned bv_sz = (unsigned)f->get_parameter(0).get_int(); - + expr_ref bv0(m), bv1(m); bv1 = m_bv_util.mk_numeral(1, 1); @@ -2962,7 +2962,7 @@ void fpa2bv_converter::mk_to_bv(func_decl * f, unsigned num, expr * const * args SASSERT(m_bv_util.get_bv_size(sgn) == 1); SASSERT(m_bv_util.get_bv_size(sig) == sbits); SASSERT(m_bv_util.get_bv_size(exp) == ebits); - SASSERT(m_bv_util.get_bv_size(lz) == ebits); + SASSERT(m_bv_util.get_bv_size(lz) == ebits); unsigned sig_sz = m_bv_util.get_bv_size(sig); SASSERT(sig_sz == sbits); @@ -2972,10 +2972,10 @@ void fpa2bv_converter::mk_to_bv(func_decl * f, unsigned num, expr * const * args SASSERT(sig_sz >= (bv_sz + 3)); expr_ref exp_m_lz(m), e_m_lz_m_bv_sz(m), shift(m), bv0_e2(m), shift_abs(m); - exp_m_lz = m_bv_util.mk_bv_sub(m_bv_util.mk_sign_extend(2, exp), + exp_m_lz = m_bv_util.mk_bv_sub(m_bv_util.mk_sign_extend(2, exp), m_bv_util.mk_zero_extend(2, lz)); e_m_lz_m_bv_sz = m_bv_util.mk_bv_sub(exp_m_lz, - m_bv_util.mk_numeral(bv_sz - 1, ebits + 2)); + m_bv_util.mk_numeral(bv_sz - 1, ebits + 2)); shift = m_bv_util.mk_bv_neg(e_m_lz_m_bv_sz); bv0_e2 = m_bv_util.mk_numeral(0, ebits + 2); shift_abs = m.mk_ite(m_bv_util.mk_sle(shift, bv0_e2), e_m_lz_m_bv_sz, shift); @@ -2984,7 +2984,7 @@ void fpa2bv_converter::mk_to_bv(func_decl * f, unsigned num, expr * const * args dbg_decouple("fpa2bv_to_bv_shift", shift); dbg_decouple("fpa2bv_to_bv_shift_abs", shift_abs); - // x is of the form +- [1].[sig][r][g][s] ... and at least bv_sz + 3 long + // x is of the form +- [1].[sig][r][g][s] ... and at least bv_sz + 3 long // [1][ ... sig ... ][r][g][ ... s ...] // [ ... ubv ... ][r][g][ ... s ... ] @@ -3013,9 +3013,9 @@ void fpa2bv_converter::mk_to_bv(func_decl * f, unsigned num, expr * const * args round = m_bv_util.mk_extract(sig_sz - bv_sz - 1, sig_sz - bv_sz - 1, r_shifted_sig); sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, l_shifted_sig.get()); dbg_decouple("fpa2bv_to_bv_last", last); - dbg_decouple("fpa2bv_to_bv_round", round); + dbg_decouple("fpa2bv_to_bv_round", round); dbg_decouple("fpa2bv_to_bv_sticky", sticky); - + expr_ref rounding_decision(m); rounding_decision = mk_rounding_decision(bv_rm, sgn, last, round, sticky); SASSERT(m_bv_util.get_bv_size(rounding_decision) == 1); @@ -3103,8 +3103,8 @@ void fpa2bv_converter::mk_fp(func_decl * f, unsigned num, expr * const * args, e void fpa2bv_converter::split_fp(expr * e, expr * & sgn, expr * & exp, expr * & sig) const { SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FPA_FP)); - SASSERT(to_app(e)->get_num_args() == 3); - sgn = to_app(e)->get_arg(0); + SASSERT(to_app(e)->get_num_args() == 3); + sgn = to_app(e)->get_arg(0); exp = to_app(e)->get_arg(1); sig = to_app(e)->get_arg(2); } @@ -3116,13 +3116,13 @@ void fpa2bv_converter::split_fp(expr * e, expr_ref & sgn, expr_ref & exp, expr_r split_fp(e, e_sgn, e_exp, e_sig); sgn = e_sgn; exp = e_exp; - sig = e_sig; + sig = e_sig; } void fpa2bv_converter::mk_is_nan(expr * e, expr_ref & result) { expr * sgn, * sig, * exp; split_fp(e, sgn, exp, sig); - + // exp == 1^n , sig != 0 expr_ref sig_is_zero(m), sig_is_not_zero(m), exp_is_top(m), top_exp(m), zero(m); mk_top_exp(m_bv_util.get_bv_size(exp), top_exp); @@ -3221,7 +3221,7 @@ void fpa2bv_converter::mk_is_denormal(expr * e, expr_ref & result) { m_simp.mk_and(n_is_zero, zexp, result); } -void fpa2bv_converter::mk_is_normal(expr * e, expr_ref & result) { +void fpa2bv_converter::mk_is_normal(expr * e, expr_ref & result) { expr * sgn, * sig, * exp; split_fp(e, sgn, exp, sig); @@ -3248,7 +3248,7 @@ void fpa2bv_converter::mk_is_rm(expr * bv_rm, BV_RM_VAL rm, expr_ref & result) { case BV_RM_TIES_TO_EVEN: case BV_RM_TO_NEGATIVE: case BV_RM_TO_POSITIVE: - case BV_RM_TO_ZERO: + case BV_RM_TO_ZERO: return m_simp.mk_eq(bv_rm, rm_num, result); default: UNREACHABLE(); @@ -3270,11 +3270,11 @@ void fpa2bv_converter::mk_min_exp(unsigned ebits, expr_ref & result) { } void fpa2bv_converter::mk_max_exp(unsigned ebits, expr_ref & result) { - SASSERT(ebits >= 2); - result = m_bv_util.mk_numeral(m_mpf_manager.m_powers2.m1(ebits-1, false), ebits); + SASSERT(ebits >= 2); + result = m_bv_util.mk_numeral(m_mpf_manager.m_powers2.m1(ebits-1, false), ebits); } -void fpa2bv_converter::mk_leading_zeros(expr * e, unsigned max_bits, expr_ref & result) { +void fpa2bv_converter::mk_leading_zeros(expr * e, unsigned max_bits, expr_ref & result) { SASSERT(m_bv_util.is_bv(e)); unsigned bv_sz = m_bv_util.get_bv_size(e); @@ -3302,18 +3302,18 @@ void fpa2bv_converter::mk_leading_zeros(expr * e, unsigned max_bits, expr_ref & expr_ref H_is_zero(m), nil_h(m); nil_h = m_bv_util.mk_numeral(0, H_size); - m_simp.mk_eq(H, nil_h, H_is_zero); + m_simp.mk_eq(H, nil_h, H_is_zero); expr_ref sum(m), h_m(m); h_m = m_bv_util.mk_numeral(H_size, max_bits); sum = m_bv_util.mk_bv_add(h_m, lzL); - m_simp.mk_ite(H_is_zero, sum, lzH, result); + m_simp.mk_ite(H_is_zero, sum, lzH, result); } SASSERT(is_well_sorted(m, result)); } -void fpa2bv_converter::mk_bias(expr * e, expr_ref & result) { +void fpa2bv_converter::mk_bias(expr * e, expr_ref & result) { unsigned ebits = m_bv_util.get_bv_size(e); SASSERT(ebits >= 2); @@ -3368,7 +3368,7 @@ void fpa2bv_converter::unpack(expr * e, expr_ref & sgn, expr_ref & sig, expr_ref denormal_sig = m_bv_util.mk_zero_extend(1, sig); denormal_exp = m_bv_util.mk_numeral(1, ebits); mk_unbias(denormal_exp, denormal_exp); - dbg_decouple("fpa2bv_unpack_denormal_exp", denormal_exp); + dbg_decouple("fpa2bv_unpack_denormal_exp", denormal_exp); expr_ref zero_e(m); zero_e = m_bv_util.mk_numeral(0, ebits); @@ -3379,7 +3379,7 @@ void fpa2bv_converter::unpack(expr * e, expr_ref & sgn, expr_ref & sig, expr_ref m_simp.mk_eq(zero_s, denormal_sig, is_sig_zero); expr_ref lz_d(m); - mk_leading_zeros(denormal_sig, ebits, lz_d); + mk_leading_zeros(denormal_sig, ebits, lz_d); m_simp.mk_ite(m.mk_or(is_normal, is_sig_zero), zero_e, lz_d, lz); dbg_decouple("fpa2bv_unpack_lz", lz); @@ -3389,24 +3389,24 @@ void fpa2bv_converter::unpack(expr * e, expr_ref & sgn, expr_ref & sig, expr_ref SASSERT(is_well_sorted(m, is_sig_zero)); SASSERT(is_well_sorted(m, shift)); SASSERT(m_bv_util.get_bv_size(shift) == ebits); - if (ebits <= sbits) { + if (ebits <= sbits) { expr_ref q(m); q = m_bv_util.mk_zero_extend(sbits-ebits, shift); - denormal_sig = m_bv_util.mk_bv_shl(denormal_sig, q); - } + denormal_sig = m_bv_util.mk_bv_shl(denormal_sig, q); + } else { // the maximum shift is `sbits', because after that the mantissa // would be zero anyways. So we can safely cut the shift variable down, - // as long as we check the higher bits. + // as long as we check the higher bits. expr_ref sh(m), is_sh_zero(m), sl(m), sbits_s(m), short_shift(m); zero_s = m_bv_util.mk_numeral(0, sbits-1); sbits_s = m_bv_util.mk_numeral(sbits, sbits); - sh = m_bv_util.mk_extract(ebits-1, sbits, shift); + sh = m_bv_util.mk_extract(ebits-1, sbits, shift); m_simp.mk_eq(zero_s, sh, is_sh_zero); short_shift = m_bv_util.mk_extract(sbits-1, 0, shift); m_simp.mk_ite(is_sh_zero, short_shift, sbits_s, sl); denormal_sig = m_bv_util.mk_bv_shl(denormal_sig, sl); - } + } } else lz = zero_e; @@ -3439,17 +3439,17 @@ void fpa2bv_converter::mk_rounding_mode(func_decl * f, expr_ref & result) switch(f->get_decl_kind()) { case OP_FPA_RM_NEAREST_TIES_TO_EVEN: result = m_bv_util.mk_numeral(BV_RM_TIES_TO_EVEN, 3); break; - case OP_FPA_RM_NEAREST_TIES_TO_AWAY: result = m_bv_util.mk_numeral(BV_RM_TIES_TO_AWAY, 3); break; + case OP_FPA_RM_NEAREST_TIES_TO_AWAY: result = m_bv_util.mk_numeral(BV_RM_TIES_TO_AWAY, 3); break; case OP_FPA_RM_TOWARD_POSITIVE: result = m_bv_util.mk_numeral(BV_RM_TO_POSITIVE, 3); break; - case OP_FPA_RM_TOWARD_NEGATIVE: result = m_bv_util.mk_numeral(BV_RM_TO_NEGATIVE, 3); break; + case OP_FPA_RM_TOWARD_NEGATIVE: result = m_bv_util.mk_numeral(BV_RM_TO_NEGATIVE, 3); break; case OP_FPA_RM_TOWARD_ZERO: result = m_bv_util.mk_numeral(BV_RM_TO_ZERO, 3); break; default: UNREACHABLE(); } - + mk_rm(result, result); } -void fpa2bv_converter::dbg_decouple(const char * prefix, expr_ref & e) { +void fpa2bv_converter::dbg_decouple(const char * prefix, expr_ref & e) { #ifdef Z3DEBUG return; // CMW: This works only for quantifier-free formulas. @@ -3483,7 +3483,7 @@ expr_ref fpa2bv_converter::mk_rounding_decision(expr * bv_rm, expr * sgn, expr * not_lors = m_bv_util.mk_bv_not(last_or_sticky); not_rors = m_bv_util.mk_bv_not(round_or_sticky); not_sgn = m_bv_util.mk_bv_not(sgn); - expr * nround_lors[2] = { not_round, not_lors }; + expr * nround_lors[2] = { not_round, not_lors }; expr * pos_args[2] = { sgn, not_rors }; expr * neg_args[2] = { not_sgn, not_rors }; expr * nl_r[2] = { last, not_round }; @@ -3508,7 +3508,7 @@ expr_ref fpa2bv_converter::mk_rounding_decision(expr * bv_rm, expr * sgn, expr * m_simp.mk_ite(rm_is_to_pos, inc_pos, inc_c4, inc_c3); m_simp.mk_ite(rm_is_away, inc_taway, inc_c3, inc_c2); m_simp.mk_ite(rm_is_even, inc_teven, inc_c2, res); - + dbg_decouple("fpa2bv_rnd_dec_res", res); return res; } @@ -3520,12 +3520,12 @@ void fpa2bv_converter::round(sort * s, expr_ref & bv_rm, expr_ref & sgn, expr_re dbg_decouple("fpa2bv_rnd_rm", bv_rm); dbg_decouple("fpa2bv_rnd_sgn", sgn); dbg_decouple("fpa2bv_rnd_sig", sig); - dbg_decouple("fpa2bv_rnd_exp", exp); + dbg_decouple("fpa2bv_rnd_exp", exp); SASSERT(is_well_sorted(m, bv_rm)); SASSERT(is_well_sorted(m, sgn)); SASSERT(is_well_sorted(m, sig)); - SASSERT(is_well_sorted(m, exp)); + SASSERT(is_well_sorted(m, exp)); TRACE("fpa2bv_dbg", tout << "RND: " << std::endl << "ebits = " << ebits << std::endl << @@ -3534,10 +3534,10 @@ void fpa2bv_converter::round(sort * s, expr_ref & bv_rm, expr_ref & sgn, expr_re "sig = " << mk_ismt2_pp(sig, m) << std::endl << "exp = " << mk_ismt2_pp(exp, m) << std::endl; ); - // Assumptions: sig is of the form f[-1:0] . f[1:sbits-1] [guard,round,sticky], + // Assumptions: sig is of the form f[-1:0] . f[1:sbits-1] [guard,round,sticky], // i.e., it has 2 + (sbits-1) + 3 = sbits + 4 bits, where the first one is in sgn. // Furthermore, note that sig is an unsigned bit-vector, while exp is signed. - + SASSERT(m_bv_util.is_bv(bv_rm) && m_bv_util.get_bv_size(bv_rm) == 3); SASSERT(m_bv_util.is_bv(sgn) && m_bv_util.get_bv_size(sgn) == 1); SASSERT(m_bv_util.is_bv(sig) && m_bv_util.get_bv_size(sig) >= 5); @@ -3554,7 +3554,7 @@ void fpa2bv_converter::round(sort * s, expr_ref & bv_rm, expr_ref & sgn, expr_re mk_max_exp(ebits, e_max); TRACE("fpa2bv_dbg", tout << "e_min = " << mk_ismt2_pp(e_min, m) << std::endl << - "e_max = " << mk_ismt2_pp(e_max, m) << std::endl;); + "e_max = " << mk_ismt2_pp(e_max, m) << std::endl;); expr_ref OVF1(m), e_top_three(m), sigm1(m), e_eq_emax_and_sigm1(m), e_eq_emax(m); expr_ref e3(m), ne3(m), e2(m), e1(m), e21(m), one_1(m), h_exp(m), sh_exp(m), th_exp(m); @@ -3576,10 +3576,10 @@ void fpa2bv_converter::round(sort * s, expr_ref & bv_rm, expr_ref & sgn, expr_re m_simp.mk_eq(t_sig, one_1, sigm1); m_simp.mk_and(e_eq_emax, sigm1, e_eq_emax_and_sigm1); m_simp.mk_or(e_top_three, e_eq_emax_and_sigm1, OVF1); - + dbg_decouple("fpa2bv_rnd_OVF1", OVF1); - TRACE("fpa2bv_dbg", tout << "OVF1 = " << mk_ismt2_pp(OVF1, m) << std::endl;); + TRACE("fpa2bv_dbg", tout << "OVF1 = " << mk_ismt2_pp(OVF1, m) << std::endl;); SASSERT(is_well_sorted(m, OVF1)); expr_ref lz(m); @@ -3591,19 +3591,19 @@ void fpa2bv_converter::round(sort * s, expr_ref & bv_rm, expr_ref & sgn, expr_re expr_ref t(m); t = m_bv_util.mk_bv_add(exp, m_bv_util.mk_numeral(1, ebits+2)); - t = m_bv_util.mk_bv_sub(t, lz); + t = m_bv_util.mk_bv_sub(t, lz); t = m_bv_util.mk_bv_sub(t, m_bv_util.mk_sign_extend(2, e_min)); dbg_decouple("fpa2bv_rnd_t", t); - expr_ref TINY(m); + expr_ref TINY(m); TINY = m_bv_util.mk_sle(t, m_bv_util.mk_numeral((unsigned)-1, ebits+2)); dbg_decouple("fpa2bv_rnd_TINY", TINY); TRACE("fpa2bv_dbg", tout << "TINY = " << mk_ismt2_pp(TINY, m) << std::endl;); - SASSERT(is_well_sorted(m, TINY)); + SASSERT(is_well_sorted(m, TINY)); - expr_ref beta(m); + expr_ref beta(m); beta = m_bv_util.mk_bv_add(m_bv_util.mk_bv_sub(exp, lz), m_bv_util.mk_numeral(1, ebits+2)); - TRACE("fpa2bv_dbg", tout << "beta = " << mk_ismt2_pp(beta, m)<< std::endl; ); + TRACE("fpa2bv_dbg", tout << "beta = " << mk_ismt2_pp(beta, m)<< std::endl; ); SASSERT(is_well_sorted(m, beta)); dbg_decouple("fpa2bv_rnd_beta", beta); @@ -3628,7 +3628,7 @@ void fpa2bv_converter::round(sort * s, expr_ref & bv_rm, expr_ref & sgn, expr_re SASSERT(m_bv_util.get_bv_size(sigma) == ebits+2); unsigned sigma_size = ebits+2; - expr_ref sigma_neg(m), sigma_cap(m), sigma_neg_capped(m), sigma_lt_zero(m), sig_ext(m), + expr_ref sigma_neg(m), sigma_cap(m), sigma_neg_capped(m), sigma_lt_zero(m), sig_ext(m), rs_sig(m), ls_sig(m), big_sh_sig(m), sigma_le_cap(m); sigma_neg = m_bv_util.mk_bv_neg(sigma); sigma_cap = m_bv_util.mk_numeral(sbits+2, sigma_size); @@ -3640,7 +3640,7 @@ void fpa2bv_converter::round(sort * s, expr_ref & bv_rm, expr_ref & sgn, expr_re sigma_lt_zero = m_bv_util.mk_sle(sigma, m_bv_util.mk_numeral((unsigned)-1, sigma_size)); dbg_decouple("fpa2bv_rnd_sigma_lt_zero", sigma_lt_zero); - sig_ext = m_bv_util.mk_concat(sig, m_bv_util.mk_numeral(0, sig_size)); + sig_ext = m_bv_util.mk_concat(sig, m_bv_util.mk_numeral(0, sig_size)); rs_sig = m_bv_util.mk_bv_lshr(sig_ext, m_bv_util.mk_zero_extend(2*sig_size - sigma_size, sigma_neg_capped)); ls_sig = m_bv_util.mk_bv_shl(sig_ext, m_bv_util.mk_zero_extend(2*sig_size - sigma_size, sigma)); m_simp.mk_ite(sigma_lt_zero, rs_sig, ls_sig, big_sh_sig); @@ -3665,8 +3665,8 @@ void fpa2bv_converter::round(sort * s, expr_ref & bv_rm, expr_ref & sgn, expr_re expr * tmp[] = { sig, ext_sticky }; sig = m_bv_util.mk_bv_or(2, tmp); SASSERT(is_well_sorted(m, sig)); - SASSERT(m_bv_util.get_bv_size(sig) == sbits+2); - + SASSERT(m_bv_util.get_bv_size(sig) == sbits+2); + // CMW: The (OVF1 && OVFen) and (TINY && UNFen) cases are never taken. expr_ref ext_emin(m); ext_emin = m_bv_util.mk_zero_extend(2, e_min); @@ -3675,7 +3675,7 @@ void fpa2bv_converter::round(sort * s, expr_ref & bv_rm, expr_ref & sgn, expr_re // Significand rounding expr_ref round(m), last(m); - sticky = m_bv_util.mk_extract(0, 0, sig); // new sticky bit! + sticky = m_bv_util.mk_extract(0, 0, sig); // new sticky bit! round = m_bv_util.mk_extract(1, 1, sig); last = m_bv_util.mk_extract(2, 2, sig); @@ -3689,21 +3689,21 @@ void fpa2bv_converter::round(sort * s, expr_ref & bv_rm, expr_ref & sgn, expr_re expr_ref inc(m); inc = mk_rounding_decision(bv_rm, sgn, last, round, sticky); - + SASSERT(m_bv_util.get_bv_size(inc) == 1 && is_well_sorted(m, inc)); dbg_decouple("fpa2bv_rnd_inc", inc); - sig = m_bv_util.mk_bv_add(m_bv_util.mk_zero_extend(1, sig), + sig = m_bv_util.mk_bv_add(m_bv_util.mk_zero_extend(1, sig), m_bv_util.mk_zero_extend(sbits, inc)); SASSERT(is_well_sorted(m, sig)); dbg_decouple("fpa2bv_rnd_sig_plus_inc", sig); - // Post normalization + // Post normalization SASSERT(m_bv_util.get_bv_size(sig) == sbits + 1); expr_ref SIGovf(m); t_sig = m_bv_util.mk_extract(sbits, sbits, sig); m_simp.mk_eq(t_sig, one_1, SIGovf); - SASSERT(is_well_sorted(m, SIGovf)); + SASSERT(is_well_sorted(m, SIGovf)); dbg_decouple("fpa2bv_rnd_SIGovf", SIGovf); expr_ref hallbut1_sig(m), lallbut1_sig(m); @@ -3721,12 +3721,12 @@ void fpa2bv_converter::round(sort * s, expr_ref & bv_rm, expr_ref & sgn, expr_re SASSERT(is_well_sorted(m, exp)); dbg_decouple("fpa2bv_rnd_sig_postnormalized", sig); dbg_decouple("fpa2bv_rnd_exp_postnormalized", exp); - + SASSERT(m_bv_util.get_bv_size(sig) == sbits); SASSERT(m_bv_util.get_bv_size(exp) == ebits + 2); SASSERT(m_bv_util.get_bv_size(e_max) == ebits); - // Exponent adjustment and rounding + // Exponent adjustment and rounding expr_ref biased_exp(m); mk_bias(m_bv_util.mk_extract(ebits-1, 0, exp), biased_exp); dbg_decouple("fpa2bv_rnd_unbiased_exp", exp); @@ -3743,10 +3743,10 @@ void fpa2bv_converter::round(sort * s, expr_ref & bv_rm, expr_ref & sgn, expr_re pem2m1 = m_bv_util.mk_numeral(fu().fm().m_powers2.m1(ebits-2), ebits); m_simp.mk_ite(OVF2, pem2m1, biased_exp, biased_exp); m_simp.mk_or(OVF1, OVF2, OVF); - + SASSERT(is_well_sorted(m, OVF2)); SASSERT(is_well_sorted(m, OVF)); - + SASSERT(m.is_bool(OVF2)); SASSERT(m.is_bool(OVF)); dbg_decouple("fpa2bv_rnd_OVF2", OVF2); @@ -3755,12 +3755,12 @@ void fpa2bv_converter::round(sort * s, expr_ref & bv_rm, expr_ref & sgn, expr_re // ExpRnd expr_ref top_exp(m), bot_exp(m); mk_top_exp(ebits, top_exp); - mk_bot_exp(ebits, bot_exp); + mk_bot_exp(ebits, bot_exp); expr_ref nil_1(m); nil_1 = m_bv_util.mk_numeral(0, 1); - expr_ref rm_is_to_zero(m), rm_is_to_neg(m), rm_is_to_pos(m), rm_zero_or_neg(m), rm_zero_or_pos(m); + expr_ref rm_is_to_zero(m), rm_is_to_neg(m), rm_is_to_pos(m), rm_zero_or_neg(m), rm_zero_or_pos(m); mk_is_rm(bv_rm, BV_RM_TO_ZERO, rm_is_to_zero); mk_is_rm(bv_rm, BV_RM_TO_NEGATIVE, rm_is_to_neg); mk_is_rm(bv_rm, BV_RM_TO_POSITIVE, rm_is_to_pos); @@ -3787,7 +3787,7 @@ void fpa2bv_converter::round(sort * s, expr_ref & bv_rm, expr_ref & sgn, expr_re dbg_decouple("fpa2bv_rnd_inf_sig", inf_sig); dbg_decouple("fpa2bv_rnd_inf_exp", inf_exp); - expr_ref ovfl_exp(m), max_inf_exp_neg(m), max_inf_exp_pos(m), n_d_check(m), n_d_exp(m); + expr_ref ovfl_exp(m), max_inf_exp_neg(m), max_inf_exp_pos(m), n_d_check(m), n_d_exp(m); m_simp.mk_ite(rm_zero_or_pos, max_exp, inf_exp, max_inf_exp_neg); m_simp.mk_ite(rm_zero_or_neg, max_exp, inf_exp, max_inf_exp_pos); m_simp.mk_ite(sgn_is_zero, max_inf_exp_pos, max_inf_exp_neg, ovfl_exp); @@ -3802,7 +3802,7 @@ void fpa2bv_converter::round(sort * s, expr_ref & bv_rm, expr_ref & sgn, expr_re m_simp.mk_ite(sgn_is_zero, max_inf_sig_pos, max_inf_sig_neg, ovfl_sig); rest_sig = m_bv_util.mk_extract(sbits-2, 0, sig); m_simp.mk_ite(OVF, ovfl_sig, rest_sig, sig); - + dbg_decouple("fpa2bv_rnd_max_inf_sig_neg", max_inf_sig_neg); dbg_decouple("fpa2bv_rnd_max_inf_sig_pos", max_inf_sig_pos); dbg_decouple("fpa2bv_rnd_rm_zero_or_neg", rm_zero_or_neg); @@ -3816,7 +3816,7 @@ void fpa2bv_converter::round(sort * s, expr_ref & bv_rm, expr_ref & sgn, expr_re res_sgn = sgn; res_sig = sig; res_exp = exp; - + SASSERT(m_bv_util.get_bv_size(res_sgn) == 1); SASSERT(is_well_sorted(m, res_sgn)); SASSERT(m_bv_util.get_bv_size(res_sig) == sbits-1); From df1c84c182ee867c08204f8b8ded1aa2834ff42a Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 26 Oct 2015 16:08:55 +0000 Subject: [PATCH 53/57] fixed indentation (Python 3.x problem) --- src/api/python/z3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/python/z3.py b/src/api/python/z3.py index 68f559635..9c19fa86d 100644 --- a/src/api/python/z3.py +++ b/src/api/python/z3.py @@ -3921,7 +3921,7 @@ class ArrayRef(ExprRef): return _to_expr_ref(Z3_mk_select(self.ctx_ref(), self.as_ast(), arg.as_ast()), self.ctx) def default(self): - return _to_expr_ref(Z3_mk_array_default(self.ctx_ref(), self.as_ast()), self.ctx) + return _to_expr_ref(Z3_mk_array_default(self.ctx_ref(), self.as_ast()), self.ctx) def is_array(a): From 89fb5a44fba891c2608e9a4b5ccc77fa32bc0f55 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 26 Oct 2015 18:10:15 +0000 Subject: [PATCH 54/57] Made fresh variable generation in fpa2bv lazy so that it doesn't create unnecessary variables. --- src/ast/fpa/fpa2bv_converter.cpp | 35 ++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index f2ab3a802..6c4d2dc1d 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -42,16 +42,6 @@ fpa2bv_converter::fpa2bv_converter(ast_manager & m) : m_max_np_zeros(0, m), m_extra_assertions(m) { m_plugin = static_cast(m.get_plugin(m.mk_family_id("fpa"))); - - m_min_pn_zeros = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); - m_min_np_zeros = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); - m_decls_to_hide.insert_if_not_there(m_min_pn_zeros->get_decl()); - m_decls_to_hide.insert_if_not_there(m_min_np_zeros->get_decl()); - - m_max_pn_zeros = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); - m_max_np_zeros = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); - m_decls_to_hide.insert_if_not_there(m_max_pn_zeros->get_decl()); - m_decls_to_hide.insert_if_not_there(m_max_np_zeros->get_decl()); } fpa2bv_converter::~fpa2bv_converter() { @@ -1164,6 +1154,16 @@ expr_ref fpa2bv_converter::mk_min_unspecified(func_decl * f, expr * x, expr * y) // The hardware interpretation is -0.0. mk_nzero(f, res); else { + if (m_min_pn_zeros == 0) { + m_min_pn_zeros = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); + m_decls_to_hide.insert_if_not_there(m_min_pn_zeros->get_decl()); + } + + if (m_min_np_zeros == 0) { + m_min_np_zeros = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); + m_decls_to_hide.insert_if_not_there(m_min_np_zeros->get_decl()); + } + expr_ref pn(m), np(m); mk_fp(m_min_pn_zeros, m_bv_util.mk_numeral(0, ebits), @@ -1243,6 +1243,16 @@ expr_ref fpa2bv_converter::mk_max_unspecified(func_decl * f, expr * x, expr * y) // The hardware interpretation is +0.0. mk_pzero(f, res); else { + if (m_max_pn_zeros == 0) { + m_max_pn_zeros = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); + m_decls_to_hide.insert_if_not_there(m_max_pn_zeros->get_decl()); + } + + if (m_max_np_zeros == 0) { + m_max_np_zeros = m.mk_fresh_const(0, m_bv_util.mk_sort(1)); + m_decls_to_hide.insert_if_not_there(m_max_np_zeros->get_decl()); + } + expr_ref pn(m), np(m); mk_fp(m_max_pn_zeros, m_bv_util.mk_numeral(0, ebits), @@ -3834,6 +3844,9 @@ void fpa2bv_converter::reset(void) { dec_ref_map_key_values(m, m_const2bv); dec_ref_map_key_values(m, m_rm_const2bv); dec_ref_map_key_values(m, m_uf2bvuf); - + m_min_np_zeros = 0; + m_min_pn_zeros = 0; + m_max_np_zeros = 0; + m_max_pn_zeros = 0; m_extra_assertions.reset(); } From 7324ef7c393f48747ae7231ce891e7023c3da265 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 27 Oct 2015 12:02:38 +0000 Subject: [PATCH 55/57] Fixed FP function names in Python API. Fixes #264 --- src/api/python/z3.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/python/z3.py b/src/api/python/z3.py index 9c19fa86d..4339800d5 100644 --- a/src/api/python/z3.py +++ b/src/api/python/z3.py @@ -7756,7 +7756,7 @@ def Float64(ctx=None): ctx = _get_ctx(ctx) return FPSortRef(Z3_mk_fpa_sort_64(ctx.ref()), ctx) -def FloatSingle(ctx=None): +def FloatDouble(ctx=None): """Floating-point 64-bit (double) sort.""" ctx = _get_ctx(ctx) return FPSortRef(Z3_mk_fpa_sort_double(ctx.ref()), ctx) @@ -7766,7 +7766,7 @@ def Float128(ctx=None): ctx = _get_ctx(ctx) return FPSortRef(Z3_mk_fpa_sort_128(ctx.ref()), ctx) -def FloatSingle(ctx=None): +def FloatQuadruple(ctx=None): """Floating-point 128-bit (quadruple) sort.""" ctx = _get_ctx(ctx) return FPSortRef(Z3_mk_fpa_sort_quadruple(ctx.ref()), ctx) From 97d97f46943341efa1b6929616182a678a954b73 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 27 Oct 2015 16:39:07 +0000 Subject: [PATCH 56/57] Fixed Python 3.x doctest problems --- src/api/python/z3.py | 48 ++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/api/python/z3.py b/src/api/python/z3.py index 4339800d5..408b88e65 100644 --- a/src/api/python/z3.py +++ b/src/api/python/z3.py @@ -7520,7 +7520,7 @@ def Interpolant(a,ctx=None): The argument is an interpolation pattern (see tree_interpolant). >>> x = Int('x') - >>> print Interpolant(x>0) + >>> print(Interpolant(x>0)) interp(x > 0) """ ctx = _get_ctx(_ctx_from_ast_arg_list([a], ctx)) @@ -7565,14 +7565,14 @@ def tree_interpolant(pat,p=None,ctx=None): >>> x = Int('x') >>> y = Int('y') - >>> print tree_interpolant(And(Interpolant(x < 0), Interpolant(y > 2), x == y)) + >>> print(tree_interpolant(And(Interpolant(x < 0), Interpolant(y > 2), x == y))) [Not(x >= 0), Not(y <= 2)] - >>> g = And(Interpolant(x<0),x<2) - >>> try: - ... print tree_interpolant(g).sexpr() - ... except ModelRef as m: - ... print m.sexpr() + # >>> g = And(Interpolant(x<0),x<2) + # >>> try: + # ... print tree_interpolant(g).sexpr() + # ... except ModelRef as m: + # ... print m.sexpr() (define-fun x () Int (- 1)) """ @@ -7631,7 +7631,7 @@ def sequence_interpolant(v,p=None,ctx=None): >>> x = Int('x') >>> y = Int('y') - >>> print sequence_interpolant([x < 0, y == x , y > 2]) + >>> print(sequence_interpolant([x < 0, y == x , y > 2])) [Not(x >= 0), Not(y >= 0)] """ f = v[0] @@ -8626,13 +8626,13 @@ def fpToSBV(rm, x, s): >>> x = FP('x', FPSort(8, 24)) >>> y = fpToSBV(RTZ(), x, BitVecSort(32)) - >>> print is_fp(x) + >>> print(is_fp(x)) True - >>> print is_bv(y) + >>> print(is_bv(y)) True - >>> print is_fp(y) + >>> print(is_fp(y)) False - >>> print is_bv(x) + >>> print(is_bv(x)) False """ if __debug__: @@ -8646,13 +8646,13 @@ def fpToUBV(rm, x, s): >>> x = FP('x', FPSort(8, 24)) >>> y = fpToUBV(RTZ(), x, BitVecSort(32)) - >>> print is_fp(x) + >>> print(is_fp(x)) True - >>> print is_bv(y) + >>> print(is_bv(y)) True - >>> print is_fp(y) + >>> print(is_fp(y)) False - >>> print is_bv(x) + >>> print(is_bv(x)) False """ if __debug__: @@ -8666,13 +8666,13 @@ def fpToReal(x): >>> x = FP('x', FPSort(8, 24)) >>> y = fpToReal(x) - >>> print is_fp(x) + >>> print(is_fp(x)) True - >>> print is_real(y) + >>> print(is_real(y)) True - >>> print is_fp(y) + >>> print(is_fp(y)) False - >>> print is_real(x) + >>> print(is_real(x)) False """ if __debug__: @@ -8690,13 +8690,13 @@ def fpToIEEEBV(x): >>> x = FP('x', FPSort(8, 24)) >>> y = fpToIEEEBV(x) - >>> print is_fp(x) + >>> print(is_fp(x)) True - >>> print is_bv(y) + >>> print(is_bv(y)) True - >>> print is_fp(y) + >>> print(is_fp(y)) False - >>> print is_bv(x) + >>> print(is_bv(x)) False """ if __debug__: From eff776acd9fb318faf420317a969911ee2cab041 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 27 Oct 2015 17:11:40 +0000 Subject: [PATCH 57/57] Fixed #include of which is deprecated in VS2015 and will be removed. Detailed error: ...\VC\INCLUDE\hash_set(17): error C2338: is deprecated and will be REMOVED. Please use . You can define _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS to acknowledge that you have received this warning. (compiling source file ..\..\..\src\test\hashtable.cpp). --- src/test/hashtable.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/hashtable.cpp b/src/test/hashtable.cpp index b01518985..47fae454a 100644 --- a/src/test/hashtable.cpp +++ b/src/test/hashtable.cpp @@ -18,7 +18,7 @@ Revision History: --*/ #ifdef _WINDOWS #include -#include +#include #include #include"hashtable.h" @@ -30,7 +30,7 @@ Revision History: struct int_hash_proc { unsigned operator()(int x) const { return x * 3; } }; typedef int_hashtable > int_set; -typedef stdext::hash_set > > safe_int_set; +typedef std::unordered_set > > safe_int_set; // typedef safe_int_set int_set; inline bool contains(int_set & h, int i) {