3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-08-02 01:13:18 +00:00
This commit is contained in:
Nikolaj Bjorner 2015-10-27 18:11:35 -07:00
commit 47cb1058b2
68 changed files with 1281 additions and 882 deletions

View file

@ -1019,6 +1019,83 @@ void extract_example() {
std::cout << y << " " << y.hi() << " " << y.lo() << "\n"; std::cout << y << " " << y.hi() << " " << y.lo() << "\n";
} }
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()));
}
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);
}
// 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 (unsigned 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() { int main() {
try { try {
@ -1060,6 +1137,7 @@ int main() {
substitute_example(); std::cout << "\n"; substitute_example(); std::cout << "\n";
opt_example(); std::cout << "\n"; opt_example(); std::cout << "\n";
extract_example(); std::cout << "\n"; extract_example(); std::cout << "\n";
sudoku_example(); std::cout << "\n";
std::cout << "done\n"; std::cout << "done\n";
} }
catch (exception & ex) { catch (exception & ex) {

View file

@ -8,7 +8,6 @@
############################################ ############################################
import sys import sys
import os import os
import glob
import re import re
import getopt import getopt
import shutil import shutil
@ -17,7 +16,6 @@ from fnmatch import fnmatch
import distutils.sysconfig import distutils.sysconfig
import compileall import compileall
import subprocess import subprocess
import string
def getenv(name, default): def getenv(name, default):
try: try:
@ -182,6 +180,8 @@ def exec_cmd(cmd):
except: except:
# Failed to create process # Failed to create process
return 1 return 1
finally:
null.close()
# rm -f fname # rm -f fname
def rmf(fname): def rmf(fname):
@ -282,7 +282,7 @@ def check_java():
if is_verbose(): if is_verbose():
print("Finding javac ...") print("Finding javac ...")
if JDK_HOME != None: if JDK_HOME is not None:
if IS_WINDOWS: if IS_WINDOWS:
JAVAC = os.path.join(JDK_HOME, 'bin', 'javac.exe') JAVAC = os.path.join(JDK_HOME, 'bin', 'javac.exe')
else: else:
@ -292,7 +292,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)) 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: else:
# Search for javac in the path. # Search for javac in the path.
ind = 'javac'; ind = 'javac'
if IS_WINDOWS: if IS_WINDOWS:
ind = ind + '.exe' ind = ind + '.exe'
paths = os.getenv('PATH', None) paths = os.getenv('PATH', None)
@ -304,7 +304,7 @@ def check_java():
JAVAC = cmb JAVAC = cmb
break 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.') 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(): if is_verbose():
@ -339,7 +339,7 @@ def check_java():
if is_verbose(): if is_verbose():
print("Finding jni.h...") 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')): 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)) 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: else:
@ -355,6 +355,7 @@ def check_java():
q = os.path.dirname(libdir) q = os.path.dirname(libdir)
if cdirs.count(q) == 0: if cdirs.count(q) == 0:
cdirs.append(q) cdirs.append(q)
t.close()
# ... plus some heuristic ones. # ... plus some heuristic ones.
extra_dirs = [] extra_dirs = []
@ -371,10 +372,10 @@ def check_java():
for dir in cdirs: for dir in cdirs:
q = find_jni_h(dir) q = find_jni_h(dir)
if q != False: if q is not False:
JNI_HOME = q 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.") raise MKException("Failed to detect jni.h. Possible solution: set JNI_HOME with the path to JDK.")
def check_ml(): def check_ml():
@ -416,11 +417,14 @@ def find_ml_lib():
print ('Finding OCAML_LIB...') print ('Finding OCAML_LIB...')
t = TempFile('output') t = TempFile('output')
null = open(os.devnull, 'wb') null = open(os.devnull, 'wb')
try: try:
subprocess.call([OCAMLC, '-where'], stdout=t.fname, stderr=null) subprocess.call([OCAMLC, '-where'], stdout=t.fname, stderr=null)
t.commit() t.commit()
except: except:
raise MKException('Failed to find Ocaml library; please set OCAML_LIB') raise MKException('Failed to find Ocaml library; please set OCAML_LIB')
finally:
null.close()
t = open('output', 'r') t = open('output', 'r')
for line in t: for line in t:
OCAML_LIB = line[:-1] OCAML_LIB = line[:-1]
@ -437,12 +441,12 @@ def is64():
def check_ar(): def check_ar():
if is_verbose(): if is_verbose():
print("Testing ar...") print("Testing ar...")
if which('ar')== None: if which('ar') is None:
raise MKException('ar (archive tool) was not found') raise MKException('ar (archive tool) was not found')
def find_cxx_compiler(): def find_cxx_compiler():
global CXX, CXX_COMPILERS global CXX, CXX_COMPILERS
if CXX != None: if CXX is not None:
if test_cxx_compiler(CXX): if test_cxx_compiler(CXX):
return CXX return CXX
for cxx in CXX_COMPILERS: for cxx in CXX_COMPILERS:
@ -453,7 +457,7 @@ def find_cxx_compiler():
def find_c_compiler(): def find_c_compiler():
global CC, C_COMPILERS global CC, C_COMPILERS
if CC != None: if CC is not None:
if test_c_compiler(CC): if test_c_compiler(CC):
return CC return CC
for c in C_COMPILERS: for c in C_COMPILERS:
@ -479,6 +483,7 @@ def is_cr_lf(fname):
# Check whether text files use cr/lf # Check whether text files use cr/lf
f = open(fname, 'r') f = open(fname, 'r')
line = f.readline() line = f.readline()
f.close()
sz = len(line) sz = len(line)
return sz >= 2 and line[sz-2] == '\r' and line[sz-1] == '\n' return sz >= 2 and line[sz-2] == '\r' and line[sz-1] == '\n'
@ -559,7 +564,7 @@ def display_help(exit_code):
print(" --optimize generate optimized code during linking.") print(" --optimize generate optimized code during linking.")
print(" -j, --java generate Java bindings.") print(" -j, --java generate Java bindings.")
print(" --ml generate OCaml bindings.") print(" --ml generate OCaml bindings.")
print(" --staticlib build Z3 static library.") print(" --staticlib build Z3 static library.")
if not IS_WINDOWS: if not IS_WINDOWS:
print(" -g, --gmp use GMP.") print(" -g, --gmp use GMP.")
print(" --gprof enable gprof") print(" --gprof enable gprof")
@ -674,6 +679,7 @@ def extract_c_includes(fname):
elif not system_inc_pat.match(line) and non_std_inc_pat.match(line): elif not system_inc_pat.match(line) and non_std_inc_pat.match(line):
raise MKException("Invalid #include directive at '%s':%s" % (fname, line)) raise MKException("Invalid #include directive at '%s':%s" % (fname, line))
linenum = linenum + 1 linenum = linenum + 1
f.close()
return result return result
@ -805,7 +811,7 @@ class Component:
global BUILD_DIR, SRC_DIR, REV_BUILD_DIR global BUILD_DIR, SRC_DIR, REV_BUILD_DIR
if name in _ComponentNames: if name in _ComponentNames:
raise MKException("Component '%s' was already defined." % name) raise MKException("Component '%s' was already defined." % name)
if path == None: if path is None:
path = name path = name
self.name = name self.name = name
path = norm_path(path) path = norm_path(path)
@ -1019,7 +1025,7 @@ def sort_components(cnames):
class ExeComponent(Component): class ExeComponent(Component):
def __init__(self, name, exe_name, path, deps, install): def __init__(self, name, exe_name, path, deps, install):
Component.__init__(self, name, path, deps) Component.__init__(self, name, path, deps)
if exe_name == None: if exe_name is None:
exe_name = name exe_name = name
self.exe_name = exe_name self.exe_name = exe_name
self.install = install self.install = install
@ -1113,7 +1119,7 @@ def get_so_ext():
class DLLComponent(Component): class DLLComponent(Component):
def __init__(self, name, dll_name, path, deps, export_files, reexports, install, static): def __init__(self, name, dll_name, path, deps, export_files, reexports, install, static):
Component.__init__(self, name, path, deps) Component.__init__(self, name, path, deps)
if dll_name == None: if dll_name is None:
dll_name = name dll_name = name
self.dll_name = dll_name self.dll_name = dll_name
self.export_files = export_files self.export_files = export_files
@ -1147,7 +1153,7 @@ class DLLComponent(Component):
out.write(' ') out.write(' ')
out.write(obj) out.write(obj)
for dep in deps: for dep in deps:
if not dep in self.reexports: if dep not in self.reexports:
c_dep = get_component(dep) c_dep = get_component(dep)
out.write(' ' + c_dep.get_link_name()) out.write(' ' + c_dep.get_link_name())
out.write('\n') out.write('\n')
@ -1156,7 +1162,7 @@ class DLLComponent(Component):
out.write(' ') out.write(' ')
out.write(obj) out.write(obj)
for dep in deps: for dep in deps:
if not dep in self.reexports: if dep not in self.reexports:
c_dep = get_component(dep) c_dep = get_component(dep)
out.write(' ' + c_dep.get_link_name()) out.write(' ' + c_dep.get_link_name())
out.write(' ' + FOCI2LIB) out.write(' ' + FOCI2LIB)
@ -1249,9 +1255,9 @@ class DLLComponent(Component):
class DotNetDLLComponent(Component): class DotNetDLLComponent(Component):
def __init__(self, name, dll_name, path, deps, assembly_info_dir): def __init__(self, name, dll_name, path, deps, assembly_info_dir):
Component.__init__(self, name, path, deps) Component.__init__(self, name, path, deps)
if dll_name == None: if dll_name is None:
dll_name = name dll_name = name
if assembly_info_dir == None: if assembly_info_dir is None:
assembly_info_dir = "." assembly_info_dir = "."
self.dll_name = dll_name self.dll_name = dll_name
self.assembly_info_dir = assembly_info_dir self.assembly_info_dir = assembly_info_dir
@ -1315,7 +1321,7 @@ class DotNetDLLComponent(Component):
class JavaDLLComponent(Component): class JavaDLLComponent(Component):
def __init__(self, name, dll_name, package_name, manifest_file, path, deps): def __init__(self, name, dll_name, package_name, manifest_file, path, deps):
Component.__init__(self, name, path, deps) Component.__init__(self, name, path, deps)
if dll_name == None: if dll_name is None:
dll_name = name dll_name = name
self.dll_name = dll_name self.dll_name = dll_name
self.package_name = package_name self.package_name = package_name
@ -1406,7 +1412,7 @@ class JavaDLLComponent(Component):
class MLComponent(Component): class MLComponent(Component):
def __init__(self, name, lib_name, path, deps): def __init__(self, name, lib_name, path, deps):
Component.__init__(self, name, path, deps) Component.__init__(self, name, path, deps)
if lib_name == None: if lib_name is None:
lib_name = name lib_name = name
self.lib_name = lib_name self.lib_name = lib_name
@ -1426,7 +1432,7 @@ class MLComponent(Component):
fout.close() fout.close()
if VERBOSE: if VERBOSE:
print("Updated '%s'" % ml_meta_out) print("Updated '%s'" % ml_meta_out)
def mk_makefile(self, out): def mk_makefile(self, out):
if is_ml_enabled(): if is_ml_enabled():
@ -1470,20 +1476,47 @@ class MLComponent(Component):
archives = archives + ' ' + os.path.join(sub_dir,m) + '.cma' archives = archives + ' ' + os.path.join(sub_dir,m) + '.cma'
mls = mls + ' ' + os.path.join(sub_dir, m) + '.ml' mls = mls + ' ' + os.path.join(sub_dir, m) + '.ml'
out.write('%s: %s %s\n' % out.write('%s: %s %s\n' %
(os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'), (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'),
os.path.join(sub_dir, 'z3native_stubs.c'), 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' % 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'))) (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)' % ( out.write('%s: %s %s %s$(SO_EXT)' % (
os.path.join(sub_dir, "z3ml.cmxa"), os.path.join(sub_dir, "z3ml.cmxa"),
cmis, cmis,
archives, archives,
get_component(Z3_DLL_COMPONENT).dll_name)) get_component(Z3_DLL_COMPONENT).dll_name))
out.write(' %s\n' % (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'))) 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)) 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')
# 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: for m in modules:
out.write(' %s' % (os.path.join(sub_dir, m+'.ml'))) out.write(' %s' % (os.path.join(sub_dir, m+'.ml')))
out.write(' %s\n' % (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'))) out.write(' %s\n' % (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)')))
@ -1518,7 +1551,7 @@ class MLComponent(Component):
out.write(' ' + get_component(Z3_DLL_COMPONENT).dll_name + '$(LIB_EXT)') out.write(' ' + get_component(Z3_DLL_COMPONENT).dll_name + '$(LIB_EXT)')
out.write('\n\n') out.write('\n\n')
def main_component(self): def main_component(self):
return is_ml_enabled() return is_ml_enabled()
@ -1642,7 +1675,7 @@ class MLExampleComponent(ExampleComponent):
if ML_ENABLED: if ML_ENABLED:
out.write('ml_example.byte: api/ml/z3ml.cmxa ') out.write('ml_example.byte: api/ml/z3ml.cmxa ')
for mlfile in get_ml_files(self.ex_dir): 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('\n')
out.write('\t%s ' % OCAMLC) out.write('\t%s ' % OCAMLC)
if DEBUG_MODE: if DEBUG_MODE:
@ -1653,7 +1686,7 @@ class MLExampleComponent(ExampleComponent):
out.write('\n') out.write('\n')
out.write('ml_example$(EXE_EXT): api/ml/z3ml.cmxa ml_example.byte') out.write('ml_example$(EXE_EXT): api/ml/z3ml.cmxa ml_example.byte')
for mlfile in get_ml_files(self.ex_dir): 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('\n')
out.write('\t%s ' % OCAMLOPT) out.write('\t%s ' % OCAMLOPT)
if DEBUG_MODE: if DEBUG_MODE:
@ -1818,7 +1851,7 @@ def mk_config():
if is_verbose(): if is_verbose():
print('64-bit: %s' % is64()) print('64-bit: %s' % is64())
print('OpenMP: %s' % HAS_OMP) print('OpenMP: %s' % HAS_OMP)
if is_java_enabled(): if is_java_enabled():
print('JNI Bindings: %s' % JNI_HOME) print('JNI Bindings: %s' % JNI_HOME)
print('Java Compiler: %s' % JAVAC) print('Java Compiler: %s' % JAVAC)
if is_ml_enabled(): if is_ml_enabled():
@ -1892,6 +1925,11 @@ def mk_config():
LDFLAGS = '%s -lrt' % LDFLAGS LDFLAGS = '%s -lrt' % LDFLAGS
SLIBFLAGS = '-shared' SLIBFLAGS = '-shared'
SLIBEXTRAFLAGS = '%s -lrt' % SLIBEXTRAFLAGS 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': elif sysname[:6] == 'CYGWIN':
CXXFLAGS = '%s -D_CYGWIN -fno-strict-aliasing' % CXXFLAGS CXXFLAGS = '%s -D_CYGWIN -fno-strict-aliasing' % CXXFLAGS
OS_DEFINES = '-D_CYGWIN' OS_DEFINES = '-D_CYGWIN'
@ -1943,10 +1981,10 @@ def mk_config():
print('OpenMP: %s' % HAS_OMP) print('OpenMP: %s' % HAS_OMP)
print('Prefix: %s' % PREFIX) print('Prefix: %s' % PREFIX)
print('64-bit: %s' % is64()) print('64-bit: %s' % is64())
print('FP math: %s' % FPMATH) print('FP math: %s' % FPMATH)
if GPROF: if GPROF:
print('gprof: enabled') print('gprof: enabled')
print('Python version: %s' % distutils.sysconfig.get_python_version()) print('Python version: %s' % distutils.sysconfig.get_python_version())
if is_java_enabled(): if is_java_enabled():
print('JNI Bindings: %s' % JNI_HOME) print('JNI Bindings: %s' % JNI_HOME)
print('Java Compiler: %s' % JAVAC) print('Java Compiler: %s' % JAVAC)
@ -1955,6 +1993,8 @@ def mk_config():
print('OCaml Native: %s' % OCAMLOPT) print('OCaml Native: %s' % OCAMLOPT)
print('OCaml Library: %s' % OCAML_LIB) print('OCaml Library: %s' % OCAML_LIB)
config.close()
def mk_install(out): def mk_install(out):
out.write('install: ') out.write('install: ')
for c in get_components(): for c in get_components():
@ -2028,6 +2068,7 @@ def mk_makefile():
if not IS_WINDOWS: if not IS_WINDOWS:
mk_install(out) mk_install(out)
mk_uninstall(out) mk_uninstall(out)
out.close()
# Finalize # Finalize
if VERBOSE: if VERBOSE:
print("Makefile was successfully generated.") print("Makefile was successfully generated.")
@ -2102,7 +2143,7 @@ def to_c_method(s):
def def_module_params(module_name, export, params, class_name=None, description=None): def def_module_params(module_name, export, params, class_name=None, description=None):
pyg = get_curr_pyg() pyg = get_curr_pyg()
dirname = os.path.split(get_curr_pyg())[0] dirname = os.path.split(get_curr_pyg())[0]
if class_name == None: if class_name is None:
class_name = '%s_params' % module_name class_name = '%s_params' % module_name
hpp = os.path.join(dirname, '%s.hpp' % class_name) hpp = os.path.join(dirname, '%s.hpp' % class_name)
out = open(hpp, 'w') out = open(hpp, 'w')
@ -2128,7 +2169,7 @@ def def_module_params(module_name, export, params, class_name=None, description=
if export: if export:
out.write(' /*\n') out.write(' /*\n')
out.write(" REG_MODULE_PARAMS('%s', '%s::collect_param_descrs')\n" % (module_name, class_name)) 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(" REG_MODULE_DESCRIPTION('%s', '%s')\n" % (module_name, description))
out.write(' */\n') out.write(' */\n')
# Generated accessors # Generated accessors
@ -2141,6 +2182,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))) (TYPE2CTYPE[param[1]], to_c_method(param[0]), TYPE2GETTER[param[1]], param[0], pyg_default_as_c_literal(param)))
out.write('};\n') out.write('};\n')
out.write('#endif\n') out.write('#endif\n')
out.close()
if is_verbose(): if is_verbose():
print("Generated '%s'" % hpp) print("Generated '%s'" % hpp)
@ -2183,6 +2225,8 @@ def mk_pat_db():
for line in fin: for line in fin:
fout.write('"%s\\n"\n' % line.strip('\n')) fout.write('"%s\\n"\n' % line.strip('\n'))
fout.write(';\n') fout.write(';\n')
fin.close()
fout.close()
if VERBOSE: if VERBOSE:
print("Generated '%s'" % os.path.join(c.src_dir, 'database.h')) print("Generated '%s'" % os.path.join(c.src_dir, 'database.h'))
@ -2192,7 +2236,7 @@ def update_version():
minor = VER_MINOR minor = VER_MINOR
build = VER_BUILD build = VER_BUILD
revision = VER_REVISION 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()") raise MKException("set_version(major, minor, build, revision) must be used before invoking update_version()")
if not ONLY_MAKEFILES: if not ONLY_MAKEFILES:
mk_version_dot_h(major, minor, build, revision) mk_version_dot_h(major, minor, build, revision)
@ -2208,6 +2252,7 @@ def mk_version_dot_h(major, minor, build, revision):
fout.write('#define Z3_MINOR_VERSION %s\n' % minor) fout.write('#define Z3_MINOR_VERSION %s\n' % minor)
fout.write('#define Z3_BUILD_NUMBER %s\n' % build) fout.write('#define Z3_BUILD_NUMBER %s\n' % build)
fout.write('#define Z3_REVISION_NUMBER %s\n' % revision) fout.write('#define Z3_REVISION_NUMBER %s\n' % revision)
fout.close()
if VERBOSE: if VERBOSE:
print("Generated '%s'" % os.path.join(c.src_dir, 'version.h')) print("Generated '%s'" % os.path.join(c.src_dir, 'version.h'))
@ -2299,6 +2344,7 @@ def mk_install_tactic_cpp(cnames, path):
exec(line.strip('\n '), globals()) exec(line.strip('\n '), globals())
except: except:
raise MKException("Failed processing ADD_PROBE command at '%s'\n%s" % (fullname, line)) raise MKException("Failed processing ADD_PROBE command at '%s'\n%s" % (fullname, line))
fin.close()
# First pass will just generate the tactic factories # First pass will just generate the tactic factories
idx = 0 idx = 0
for data in ADD_TACTIC_DATA: for data in ADD_TACTIC_DATA:
@ -2314,6 +2360,7 @@ def mk_install_tactic_cpp(cnames, path):
for data in ADD_PROBE_DATA: for data in ADD_PROBE_DATA:
fout.write(' ADD_PROBE("%s", "%s", %s);\n' % data) fout.write(' ADD_PROBE("%s", "%s", %s);\n' % data)
fout.write('}\n') fout.write('}\n')
fout.close()
if VERBOSE: if VERBOSE:
print("Generated '%s'" % fullname) print("Generated '%s'" % fullname)
@ -2366,6 +2413,7 @@ def mk_mem_initializer_cpp(cnames, path):
added_include = True added_include = True
fout.write('#include"%s"\n' % h_file) fout.write('#include"%s"\n' % h_file)
finalizer_cmds.append(m.group(1)) finalizer_cmds.append(m.group(1))
fin.close()
initializer_cmds.sort(key=lambda tup: tup[1]) initializer_cmds.sort(key=lambda tup: tup[1])
fout.write('void mem_initialize() {\n') fout.write('void mem_initialize() {\n')
for (cmd, prio) in initializer_cmds: for (cmd, prio) in initializer_cmds:
@ -2377,6 +2425,7 @@ def mk_mem_initializer_cpp(cnames, path):
fout.write(cmd) fout.write(cmd)
fout.write('\n') fout.write('\n')
fout.write('}\n') fout.write('}\n')
fout.close()
if VERBOSE: if VERBOSE:
print("Generated '%s'" % fullname) print("Generated '%s'" % fullname)
@ -2426,6 +2475,7 @@ def mk_gparams_register_modules(cnames, path):
m = reg_mod_descr_pat.match(line) m = reg_mod_descr_pat.match(line)
if m: if m:
mod_descrs.append((m.group(1), m.group(2))) mod_descrs.append((m.group(1), m.group(2)))
fin.close()
fout.write('void gparams_register_modules() {\n') fout.write('void gparams_register_modules() {\n')
for code in cmds: for code in cmds:
fout.write('{ param_descrs d; %s(d); gparams::register_global(d); }\n' % code) fout.write('{ param_descrs d; %s(d); gparams::register_global(d); }\n' % code)
@ -2434,6 +2484,7 @@ def mk_gparams_register_modules(cnames, path):
for (mod, descr) in mod_descrs: for (mod, descr) in mod_descrs:
fout.write('gparams::register_module_descr("%s", "%s");\n' % (mod, descr)) fout.write('gparams::register_module_descr("%s", "%s");\n' % (mod, descr))
fout.write('}\n') fout.write('}\n')
fout.close()
if VERBOSE: if VERBOSE:
print("Generated '%s'" % fullname) print("Generated '%s'" % fullname)
@ -2467,6 +2518,8 @@ def mk_def_file(c):
fout.write('\t%s @%s\n' % (f, num)) fout.write('\t%s @%s\n' % (f, num))
i = i + 1 i = i + 1
num = num + 1 num = num + 1
api.close()
fout.close()
if VERBOSE: if VERBOSE:
print("Generated '%s'" % defname) print("Generated '%s'" % defname)
@ -2528,7 +2581,7 @@ def mk_bindings(api_files):
# Extract enumeration types from API files, and add python definitions. # Extract enumeration types from API files, and add python definitions.
def mk_z3consts_py(api_files): 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):") raise MKException("You must invoke set_z3py_dir(path):")
blank_pat = re.compile("^ *$") blank_pat = re.compile("^ *$")
@ -2601,6 +2654,8 @@ def mk_z3consts_py(api_files):
decls[words[1]] = idx decls[words[1]] = idx
idx = idx + 1 idx = idx + 1
linenum = linenum + 1 linenum = linenum + 1
api.close()
z3consts.close()
if VERBOSE: if VERBOSE:
print("Generated '%s'" % os.path.join(Z3PY_SRC_DIR, 'z3consts.py')) print("Generated '%s'" % os.path.join(Z3PY_SRC_DIR, 'z3consts.py'))
@ -2622,7 +2677,7 @@ def mk_z3consts_dotnet(api_files):
z3consts.write('using System;\n\n' z3consts.write('using System;\n\n'
'#pragma warning disable 1591\n\n' '#pragma warning disable 1591\n\n'
'namespace Microsoft.Z3\n' 'namespace Microsoft.Z3\n'
'{\n'); '{\n')
for api_file in api_files: for api_file in api_files:
api_file_c = dotnet.find_file(api_file, dotnet.name) api_file_c = dotnet.find_file(api_file, dotnet.name)
@ -2686,7 +2741,9 @@ def mk_z3consts_dotnet(api_files):
decls[words[1]] = idx decls[words[1]] = idx
idx = idx + 1 idx = idx + 1
linenum = linenum + 1 linenum = linenum + 1
api.close()
z3consts.write('}\n'); z3consts.write('}\n');
z3consts.close()
if VERBOSE: if VERBOSE:
print("Generated '%s'" % os.path.join(dotnet.src_dir, 'Enumerations.cs')) print("Generated '%s'" % os.path.join(dotnet.src_dir, 'Enumerations.cs'))
@ -2754,7 +2811,7 @@ def mk_z3consts_java(api_files):
if name not in DeprecatedEnums: if name not in DeprecatedEnums:
efile = open('%s.java' % os.path.join(gendir, name), 'w') efile = open('%s.java' % os.path.join(gendir, name), 'w')
efile.write('/**\n * Automatically generated file\n **/\n\n') 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('/**\n')
efile.write(' * %s\n' % name) efile.write(' * %s\n' % name)
@ -2765,7 +2822,7 @@ def mk_z3consts_java(api_files):
for k in decls: for k in decls:
i = decls[k] i = decls[k]
if first: if first:
first = False first = False
else: else:
efile.write(',\n') efile.write(',\n')
efile.write(' %s (%s)' % (k, i)) efile.write(' %s (%s)' % (k, i))
@ -2793,6 +2850,7 @@ def mk_z3consts_java(api_files):
decls[words[1]] = idx decls[words[1]] = idx
idx = idx + 1 idx = idx + 1
linenum = linenum + 1 linenum = linenum + 1
api.close()
if VERBOSE: if VERBOSE:
print("Generated '%s'" % ('%s' % gendir)) print("Generated '%s'" % ('%s' % gendir))
@ -2835,7 +2893,7 @@ def mk_z3consts_ml(api_files):
m2 = comment_pat.match(line) m2 = comment_pat.match(line)
if m1 or m2: if m1 or m2:
# skip blank lines and comments # skip blank lines and comments
linenum = linenum + 1 linenum = linenum + 1
elif mode == SEARCHING: elif mode == SEARCHING:
m = typedef_pat.match(line) m = typedef_pat.match(line)
if m: if m:
@ -2888,6 +2946,8 @@ def mk_z3consts_ml(api_files):
decls[words[1]] = idx decls[words[1]] = idx
idx = idx + 1 idx = idx + 1
linenum = linenum + 1 linenum = linenum + 1
api.close()
efile.close()
if VERBOSE: if VERBOSE:
print ('Generated "%s/z3enums.ml"' % ('%s' % gendir)) print ('Generated "%s/z3enums.ml"' % ('%s' % gendir))
efile = open('%s.mli' % os.path.join(gendir, "z3enums"), 'w') efile = open('%s.mli' % os.path.join(gendir, "z3enums"), 'w')
@ -2913,7 +2973,7 @@ def mk_z3consts_ml(api_files):
m2 = comment_pat.match(line) m2 = comment_pat.match(line)
if m1 or m2: if m1 or m2:
# skip blank lines and comments # skip blank lines and comments
linenum = linenum + 1 linenum = linenum + 1
elif mode == SEARCHING: elif mode == SEARCHING:
m = typedef_pat.match(line) m = typedef_pat.match(line)
if m: if m:
@ -2958,6 +3018,8 @@ def mk_z3consts_ml(api_files):
decls[words[1]] = idx decls[words[1]] = idx
idx = idx + 1 idx = idx + 1
linenum = linenum + 1 linenum = linenum + 1
api.close()
efile.close()
if VERBOSE: if VERBOSE:
print ('Generated "%s/z3enums.mli"' % ('%s' % gendir)) print ('Generated "%s/z3enums.mli"' % ('%s' % gendir))
@ -3094,6 +3156,7 @@ def mk_vs_proj(name, components):
f.write(' <ImportGroup Label="ExtensionTargets">\n') f.write(' <ImportGroup Label="ExtensionTargets">\n')
f.write(' </ImportGroup>\n') f.write(' </ImportGroup>\n')
f.write('</Project>\n') f.write('</Project>\n')
f.close()
if is_verbose(): if is_verbose():
print("Generated '%s'" % proj_name) print("Generated '%s'" % proj_name)

View file

@ -217,16 +217,16 @@ def type2ml(ty):
return Type2ML[ty] return Type2ML[ty]
def _in(ty): def _in(ty):
return (IN, ty); return (IN, ty)
def _in_array(sz, ty): def _in_array(sz, ty):
return (IN_ARRAY, ty, sz); return (IN_ARRAY, ty, sz)
def _out(ty): def _out(ty):
return (OUT, ty); return (OUT, ty)
def _out_array(sz, 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 # 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 # 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) return (OUT_ARRAY, ty, cap, sz)
def _inout_array(sz, ty): def _inout_array(sz, ty):
return (INOUT_ARRAY, ty, sz, sz); return (INOUT_ARRAY, ty, sz, sz)
def _out_managed_array(sz,ty): def _out_managed_array(sz,ty):
return (OUT_MANAGED_ARRAY, ty, 0, sz) return (OUT_MANAGED_ARRAY, ty, 0, sz)
@ -314,7 +314,7 @@ def param2javaw(p):
else: else:
return "jlongArray" return "jlongArray"
elif k == OUT_MANAGED_ARRAY: elif k == OUT_MANAGED_ARRAY:
return "jlong"; return "jlong"
else: else:
return type2javaw(param_type(p)) return type2javaw(param_type(p))
@ -336,7 +336,7 @@ def param2ml(p):
elif k == IN_ARRAY or k == INOUT_ARRAY or k == OUT_ARRAY: elif k == IN_ARRAY or k == INOUT_ARRAY or k == OUT_ARRAY:
return "%s array" % type2ml(param_type(p)) return "%s array" % type2ml(param_type(p))
elif k == OUT_MANAGED_ARRAY: elif k == OUT_MANAGED_ARRAY:
return "%s array" % type2ml(param_type(p)); return "%s array" % type2ml(param_type(p))
else: else:
return type2ml(param_type(p)) return type2ml(param_type(p))
@ -422,14 +422,14 @@ def mk_dotnet():
dotnet.write('using System.Collections.Generic;\n') dotnet.write('using System.Collections.Generic;\n')
dotnet.write('using System.Text;\n') dotnet.write('using System.Text;\n')
dotnet.write('using System.Runtime.InteropServices;\n\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('namespace Microsoft.Z3\n')
dotnet.write('{\n') dotnet.write('{\n')
for k in Type2Str: for k in Type2Str:
v = Type2Str[k] v = Type2Str[k]
if is_obj(k): if is_obj(k):
dotnet.write(' using %s = System.IntPtr;\n' % v) dotnet.write(' using %s = System.IntPtr;\n' % v)
dotnet.write('\n'); dotnet.write('\n')
dotnet.write(' public class Native\n') dotnet.write(' public class Native\n')
dotnet.write(' {\n\n') dotnet.write(' {\n\n')
dotnet.write(' [UnmanagedFunctionPointer(CallingConvention.Cdecl)]\n') dotnet.write(' [UnmanagedFunctionPointer(CallingConvention.Cdecl)]\n')
@ -437,7 +437,7 @@ def mk_dotnet():
dotnet.write(' public unsafe class LIB\n') dotnet.write(' public unsafe class LIB\n')
dotnet.write(' {\n') dotnet.write(' {\n')
dotnet.write(' const string Z3_DLL_NAME = \"libz3.dll\";\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(' [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') 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: for name, result, params in _dotnet_decls:
@ -448,7 +448,7 @@ def mk_dotnet():
else: else:
dotnet.write('public extern static %s %s(' % (type2dotnet(result), name)) dotnet.write('public extern static %s %s(' % (type2dotnet(result), name))
first = True first = True
i = 0; i = 0
for param in params: for param in params:
if first: if first:
first = False first = False
@ -480,7 +480,7 @@ def mk_dotnet_wrappers():
else: else:
dotnet.write(' public static %s %s(' % (type2dotnet(result), name)) dotnet.write(' public static %s %s(' % (type2dotnet(result), name))
first = True first = True
i = 0; i = 0
for param in params: for param in params:
if first: if first:
first = False first = False
@ -491,9 +491,9 @@ def mk_dotnet_wrappers():
dotnet.write(') {\n') dotnet.write(') {\n')
dotnet.write(' ') dotnet.write(' ')
if result == STRING: if result == STRING:
dotnet.write('IntPtr r = '); dotnet.write('IntPtr r = ')
elif result != VOID: elif result != VOID:
dotnet.write('%s r = ' % type2dotnet(result)); dotnet.write('%s r = ' % type2dotnet(result))
dotnet.write('LIB.%s(' % (name)) dotnet.write('LIB.%s(' % (name))
first = True first = True
i = 0 i = 0
@ -504,14 +504,14 @@ def mk_dotnet_wrappers():
dotnet.write(', ') dotnet.write(', ')
if param_kind(param) == OUT: if param_kind(param) == OUT:
if param_type(param) == STRING: if param_type(param) == STRING:
dotnet.write('out '); dotnet.write('out ')
else: else:
dotnet.write('ref ') dotnet.write('ref ')
elif param_kind(param) == OUT_MANAGED_ARRAY: elif param_kind(param) == OUT_MANAGED_ARRAY:
dotnet.write('out '); dotnet.write('out ')
dotnet.write('a%d' % i) dotnet.write('a%d' % i)
i = i + 1 i = i + 1
dotnet.write(');\n'); dotnet.write(');\n')
if name not in Unwrapped: if name not in Unwrapped:
if name in NULLWrapped: if name in NULLWrapped:
dotnet.write(" if (r == IntPtr.Zero)\n") dotnet.write(" if (r == IntPtr.Zero)\n")
@ -578,7 +578,7 @@ def mk_java():
for name, result, params in _dotnet_decls: for name, result, params in _dotnet_decls:
java_native.write(' protected static native %s INTERNAL%s(' % (type2java(result), java_method_name(name))) java_native.write(' protected static native %s INTERNAL%s(' % (type2java(result), java_method_name(name)))
first = True first = True
i = 0; i = 0
for param in params: for param in params:
if first: if first:
first = False first = False
@ -592,7 +592,7 @@ def mk_java():
for name, result, params in _dotnet_decls: for name, result, params in _dotnet_decls:
java_native.write(' public static %s %s(' % (type2java(result), java_method_name(name))) java_native.write(' public static %s %s(' % (type2java(result), java_method_name(name)))
first = True first = True
i = 0; i = 0
for param in params: for param in params:
if first: if first:
first = False first = False
@ -610,7 +610,7 @@ def mk_java():
java_native.write('%s res = ' % type2java(result)) java_native.write('%s res = ' % type2java(result))
java_native.write('INTERNAL%s(' % (java_method_name(name))) java_native.write('INTERNAL%s(' % (java_method_name(name)))
first = True first = True
i = 0; i = 0
for param in params: for param in params:
if first: if first:
first = False first = False
@ -698,7 +698,7 @@ def mk_java():
java_wrapper.write('') java_wrapper.write('')
for name, result, params in _dotnet_decls: 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))) 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: for param in params:
java_wrapper.write(', ') java_wrapper.write(', ')
java_wrapper.write('%s a%d' % (param2javaw(param), i)) java_wrapper.write('%s a%d' % (param2javaw(param), i))
@ -804,10 +804,10 @@ def mk_log_header(file, name, params):
i = 0 i = 0
for p in params: for p in params:
if i > 0: if i > 0:
file.write(", "); file.write(", ")
file.write("%s a%s" % (param2str(p), i)) file.write("%s a%s" % (param2str(p), i))
i = i + 1 i = i + 1
file.write(")"); file.write(")")
def log_param(p): def log_param(p):
kind = param_kind(p) kind = param_kind(p)
@ -964,7 +964,7 @@ def def_API(name, result, params):
log_c.write(" I(a%s);\n" % i) log_c.write(" I(a%s);\n" % i)
exe_c.write("in.get_bool(%s)" % i) exe_c.write("in.get_bool(%s)" % i)
elif ty == PRINT_MODE or ty == ERROR_CODE: elif ty == PRINT_MODE or ty == ERROR_CODE:
log_c.write(" U(static_cast<unsigned>(a%s));\n" % i); log_c.write(" U(static_cast<unsigned>(a%s));\n" % i)
exe_c.write("static_cast<%s>(in.get_uint(%s))" % (type2str(ty), i)) exe_c.write("static_cast<%s>(in.get_uint(%s))" % (type2str(ty), i))
else: else:
error("unsupported parameter for %s, %s" % (name, p)) error("unsupported parameter for %s, %s" % (name, p))
@ -1081,10 +1081,10 @@ def ml_method_name(name):
return name[3:] # Remove Z3_ return name[3:] # Remove Z3_
def is_out_param(p): 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: 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 return True
else: else:
return False return False
def outparams(params): def outparams(params):
op = [] op = []
@ -1169,7 +1169,7 @@ def mk_ml():
ml_native.write('(** The native (raw) interface to the dynamic Z3 library. *)\n\n') 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('(* Automatically generated file *)\n\n')
ml_i.write('(** The native (raw) interface to the dynamic Z3 library. *)\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('open Z3enums\n\n')
ml_native.write('(**/**)\n') ml_native.write('(**/**)\n')
ml_native.write('type ptr\n') ml_native.write('type ptr\n')
@ -1232,7 +1232,7 @@ def mk_ml():
ml_native.write(' = "n_%s"\n' % ml_method_name(name)) ml_native.write(' = "n_%s"\n' % ml_method_name(name))
ml_native.write('\n') ml_native.write('\n')
ml_native.write(' end\n\n') ml_native.write(' end\n\n')
ml_i.write('\n(**/**)\n'); ml_i.write('\n(**/**)\n')
# Exception wrappers # Exception wrappers
for name, result, params in _dotnet_decls: for name, result, params in _dotnet_decls:
@ -1241,11 +1241,11 @@ def mk_ml():
ml_native.write(' let %s ' % ml_method_name(name)) ml_native.write(' let %s ' % ml_method_name(name))
first = True first = True
i = 0; i = 0
for p in params: for p in params:
if is_in_param(p): if is_in_param(p):
if first: if first:
first = False; first = False
else: else:
ml_native.write(' ') ml_native.write(' ')
ml_native.write('a%d' % i) ml_native.write('a%d' % i)
@ -1262,7 +1262,7 @@ def mk_ml():
if len(ip) == 0: if len(ip) == 0:
ml_native.write(' ()') ml_native.write(' ()')
first = True first = True
i = 0; i = 0
for p in params: for p in params:
if is_in_param(p): if is_in_param(p):
ml_native.write(' a%d' % i) ml_native.write(' a%d' % i)
@ -1476,7 +1476,7 @@ def mk_ml():
if len(op) > 0: if len(op) > 0:
if result != VOID: if result != VOID:
ml_wrapper.write(' %s\n' % ml_set_wrap(result, "res_val", "z3_result")) ml_wrapper.write(' %s\n' % ml_set_wrap(result, "res_val", "z3_result"))
i = 0; i = 0
for p in params: for p in params:
if param_kind(p) == OUT_ARRAY or param_kind(p) == INOUT_ARRAY: 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))) ml_wrapper.write(' _a%s_val = caml_alloc(_a%s, 0);\n' % (i, param_array_capacity_pos(p)))
@ -1499,7 +1499,7 @@ def mk_ml():
for p in params: for p in params:
if is_out_param(p): if is_out_param(p):
ml_wrapper.write(' Store_field(result, %s, _a%s_val);\n' % (j, i)) ml_wrapper.write(' Store_field(result, %s, _a%s_val);\n' % (j, i))
j = j + 1; j = j + 1
i = i + 1 i = i + 1
# local array cleanup # local array cleanup

View file

@ -647,13 +647,7 @@ namespace z3 {
*/ */
friend expr operator||(bool a, expr const & b) { return b.ctx().bool_val(a) || b; } friend expr operator||(bool a, expr const & b) { return b.ctx().bool_val(a) || b; }
friend expr implies(expr const & a, expr const & 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, bool b); friend expr implies(expr const & a, bool b);
friend expr implies(bool a, expr const & b); friend expr implies(bool a, expr const & b);
@ -897,6 +891,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(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); } inline expr implies(bool a, expr const & b) { return implies(b.ctx().bool_val(a), b); }
@ -1911,7 +1912,7 @@ namespace z3 {
}; }
/*@}*/ /*@}*/
/*@}*/ /*@}*/

View file

@ -37,8 +37,11 @@ namespace Microsoft.Z3
public Context() public Context()
: base() : base()
{ {
m_ctx = Native.Z3_mk_context_rc(IntPtr.Zero); lock (creation_lock)
InitContext(); {
m_ctx = Native.Z3_mk_context_rc(IntPtr.Zero);
InitContext();
}
} }
/// <summary> /// <summary>
@ -64,12 +67,15 @@ namespace Microsoft.Z3
{ {
Contract.Requires(settings != null); Contract.Requires(settings != null);
IntPtr cfg = Native.Z3_mk_config(); lock (creation_lock)
foreach (KeyValuePair<string, string> kv in settings) {
Native.Z3_set_param_value(cfg, kv.Key, kv.Value); IntPtr cfg = Native.Z3_mk_config();
m_ctx = Native.Z3_mk_context_rc(cfg); foreach (KeyValuePair<string, string> kv in settings)
Native.Z3_del_config(cfg); Native.Z3_set_param_value(cfg, kv.Key, kv.Value);
InitContext(); m_ctx = Native.Z3_mk_context_rc(cfg);
Native.Z3_del_config(cfg);
InitContext();
}
} }
#endregion #endregion
@ -4381,6 +4387,7 @@ namespace Microsoft.Z3
#region Internal #region Internal
internal IntPtr m_ctx = IntPtr.Zero; internal IntPtr m_ctx = IntPtr.Zero;
internal Native.Z3_error_handler m_n_err_handler = null; 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 IntPtr nCtx { get { return m_ctx; } }
internal void NativeErrorHandler(IntPtr ctx, Z3_error_code errorCode) internal void NativeErrorHandler(IntPtr ctx, Z3_error_code errorCode)

View file

@ -28,7 +28,7 @@ namespace Microsoft.Z3
/// which solver and/or preprocessing step will be used. /// which solver and/or preprocessing step will be used.
/// The complete list of probes may be obtained using the procedures <c>Context.NumProbes</c> /// The complete list of probes may be obtained using the procedures <c>Context.NumProbes</c>
/// and <c>Context.ProbeNames</c>. /// and <c>Context.ProbeNames</c>.
/// It may also be obtained using the command <c>(help-tactics)</c> in the SMT 2.0 front-end. /// It may also be obtained using the command <c>(help-tactic)</c> in the SMT 2.0 front-end.
/// </summary> /// </summary>
[ContractVerification(true)] [ContractVerification(true)]
public class Probe : Z3Object public class Probe : Z3Object

View file

@ -26,7 +26,7 @@ namespace Microsoft.Z3
/// Tactics are the basic building block for creating custom solvers for specific problem domains. /// Tactics are the basic building block for creating custom solvers for specific problem domains.
/// The complete list of tactics may be obtained using <c>Context.NumTactics</c> /// The complete list of tactics may be obtained using <c>Context.NumTactics</c>
/// and <c>Context.TacticNames</c>. /// and <c>Context.TacticNames</c>.
/// It may also be obtained using the command <c>(help-tactics)</c> in the SMT 2.0 front-end. /// It may also be obtained using the command <c>(help-tactic)</c> in the SMT 2.0 front-end.
/// </summary> /// </summary>
[ContractVerification(true)] [ContractVerification(true)]
public class Tactic : Z3Object public class Tactic : Z3Object

View file

@ -33,7 +33,7 @@ public class AST extends Z3Object implements Comparable
{ {
AST casted = null; AST casted = null;
try try
{ {
casted = AST.class.cast(o); casted = AST.class.cast(o);
} catch (ClassCastException e) } catch (ClassCastException e)
@ -41,13 +41,12 @@ public class AST extends Z3Object implements Comparable
return false; return false;
} }
return return (this == casted) ||
(this == casted) || (this != null) &&
(this != null) && (casted != null) &&
(casted != null) && (getContext().nCtx() == casted.getContext().nCtx()) &&
(getContext().nCtx() == casted.getContext().nCtx()) && (Native.isEqAst(getContext().nCtx(), getNativeObject(), casted.getNativeObject()));
(Native.isEqAst(getContext().nCtx(), getNativeObject(), casted.getNativeObject())); }
}
/** /**
* Object Comparison. * Object Comparison.

View file

@ -80,11 +80,20 @@ public class Constructor extends Z3Object
/** /**
* Destructor. * Destructor.
* @throws Throwable
* @throws Z3Exception on error * @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; private int n = 0;

View file

@ -24,11 +24,20 @@ public class ConstructorList extends Z3Object
{ {
/** /**
* Destructor. * Destructor.
* @throws Throwable
* @throws Z3Exception on error * @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) ConstructorList(Context ctx, long obj)

View file

@ -18,6 +18,7 @@ Notes:
package com.microsoft.z3; package com.microsoft.z3;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import com.microsoft.z3.enumerations.Z3_ast_print_mode; import com.microsoft.z3.enumerations.Z3_ast_print_mode;
@ -30,10 +31,12 @@ public class Context extends IDisposable
* Constructor. * Constructor.
**/ **/
public Context() public Context()
{ {
super(); super();
m_ctx = Native.mkContextRc(0); synchronized (creation_lock) {
initContext(); m_ctx = Native.mkContextRc(0);
initContext();
}
} }
/** /**
@ -56,12 +59,14 @@ public class Context extends IDisposable
public Context(Map<String, String> settings) public Context(Map<String, String> settings)
{ {
super(); super();
long cfg = Native.mkConfig(); synchronized (creation_lock) {
for (Map.Entry<String, String> kv : settings.entrySet()) long cfg = Native.mkConfig();
Native.setParamValue(cfg, kv.getKey(), kv.getValue()); for (Map.Entry<String, String> kv : settings.entrySet())
m_ctx = Native.mkContextRc(cfg); Native.setParamValue(cfg, kv.getKey(), kv.getValue());
Native.delConfig(cfg); m_ctx = Native.mkContextRc(cfg);
initContext(); Native.delConfig(cfg);
initContext();
}
} }
/** /**
@ -365,16 +370,15 @@ public class Context extends IDisposable
* Update a datatype field at expression t with value v. * Update a datatype field at expression t with value v.
* The function performs a record update at t. The field * The function performs a record update at t. The field
* that is passed in as argument is updated with value v, * 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) public Expr MkUpdateField(FuncDecl field, Expr t, Expr v)
throws Z3Exception throws Z3Exception
{ {
return Expr.create return Expr.create (this,
(this, Native.datatypeUpdateField
Native.datatypeUpdateField (nCtx(), field.getNativeObject(),
(nCtx(), field.getNativeObject(), t.getNativeObject(), v.getNativeObject()));
t.getNativeObject(), v.getNativeObject()));
} }
@ -3638,7 +3642,8 @@ public class Context extends IDisposable
Native.updateParamValue(nCtx(), id, value); Native.updateParamValue(nCtx(), id, value);
} }
long m_ctx = 0; protected long m_ctx = 0;
protected static Object creation_lock = new Object();
long nCtx() long nCtx()
{ {
@ -3761,29 +3766,23 @@ public class Context extends IDisposable
return m_Optimize_DRQ; return m_Optimize_DRQ;
} }
protected long m_refCount = 0; protected AtomicInteger m_refCount = new AtomicInteger(0);
/** /**
* Finalizer. * Finalizer.
* @throws Throwable
**/ **/
protected void finalize() protected void finalize() throws Throwable
{ {
dispose(); try {
dispose();
if (m_refCount == 0) }
{ catch (Throwable t) {
try throw t;
{ }
Native.delContext(m_ctx); finally {
} catch (Z3Exception e) super.finalize();
{ }
// OK.
}
m_ctx = 0;
}
/*
else
CMW: re-queue the finalizer? */
} }
/** /**
@ -3809,5 +3808,17 @@ public class Context extends IDisposable
m_boolSort = null; m_boolSort = null;
m_intSort = null; m_intSort = null;
m_realSort = null; m_realSort = null;
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;
}
}
} }
} }

View file

@ -35,8 +35,11 @@ public class InterpolationContext extends Context
**/ **/
public InterpolationContext() public InterpolationContext()
{ {
m_ctx = Native.mkInterpolationContext(0); super();
initContext(); synchronized(creation_lock) {
m_ctx = Native.mkInterpolationContext(0);
initContext();
}
} }
/** /**
@ -48,12 +51,15 @@ public class InterpolationContext extends Context
**/ **/
public InterpolationContext(Map<String, String> settings) public InterpolationContext(Map<String, String> settings)
{ {
long cfg = Native.mkConfig(); super();
for (Map.Entry<String, String> kv : settings.entrySet()) synchronized(creation_lock) {
Native.setParamValue(cfg, kv.getKey(), kv.getValue()); long cfg = Native.mkConfig();
m_ctx = Native.mkInterpolationContext(cfg); for (Map.Entry<String, String> kv : settings.entrySet())
Native.delConfig(cfg); Native.setParamValue(cfg, kv.getKey(), kv.getValue());
initContext(); m_ctx = Native.mkInterpolationContext(cfg);
Native.delConfig(cfg);
initContext();
}
} }
/** /**

View file

@ -22,7 +22,7 @@ package com.microsoft.z3;
* may be used to decide which solver and/or preprocessing step will be used. * 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 * The complete list of probes may be obtained using the procedures
* {@code Context.NumProbes} and {@code Context.ProbeNames}. It may * {@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. * front-end.
**/ **/
public class Probe extends Z3Object public class Probe extends Z3Object

View file

@ -21,7 +21,7 @@ package com.microsoft.z3;
* Tactics are the basic building block for creating custom solvers for specific * Tactics are the basic building block for creating custom solvers for specific
* problem domains. The complete list of tactics may be obtained using * problem domains. The complete list of tactics may be obtained using
* {@code Context.NumTactics} and {@code Context.TacticNames}. It may * {@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. * front-end.
**/ **/
public class Tactic extends Z3Object public class Tactic extends Z3Object

View file

@ -25,10 +25,19 @@ public class Z3Object extends IDisposable
{ {
/** /**
* Finalizer. * Finalizer.
* @throws Throwable
**/ **/
protected void finalize() protected void finalize() throws Throwable
{ {
dispose(); try {
dispose();
}
catch (Throwable t) {
throw t;
}
finally {
super.finalize();
}
} }
/** /**
@ -43,8 +52,9 @@ public class Z3Object extends IDisposable
} }
if (m_ctx != null) if (m_ctx != null)
{ {
m_ctx.m_refCount--; if (m_ctx.m_refCount.decrementAndGet() == 0)
m_ctx.dispose();
m_ctx = null; m_ctx = null;
} }
} }
@ -54,13 +64,13 @@ public class Z3Object extends IDisposable
Z3Object(Context ctx) Z3Object(Context ctx)
{ {
ctx.m_refCount++; ctx.m_refCount.incrementAndGet();
m_ctx = ctx; m_ctx = ctx;
} }
Z3Object(Context ctx, long obj) Z3Object(Context ctx, long obj)
{ {
ctx.m_refCount++; ctx.m_refCount.incrementAndGet();
m_ctx = ctx; m_ctx = ctx;
incRef(obj); incRef(obj);
m_n_obj = obj; m_n_obj = obj;

View file

@ -2779,7 +2779,7 @@ end
which solver and/or preprocessing step will be used. which solver and/or preprocessing step will be used.
The complete list of probes may be obtained using the procedures [Context.NumProbes] The complete list of probes may be obtained using the procedures [Context.NumProbes]
and [Context.ProbeNames]. 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 : module Probe :
sig sig
@ -2841,7 +2841,7 @@ end
Tactics are the basic building block for creating custom solvers for specific problem domains. 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] The complete list of tactics may be obtained using [Context.get_num_tactics]
and [Context.get_tactic_names]. 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 : module Tactic :
sig sig

View file

@ -2637,7 +2637,7 @@ def _py2expr(a, ctx=None):
_z3_assert(False, "Python bool, int, long or float expected") _z3_assert(False, "Python bool, int, long or float expected")
def IntSort(ctx=None): 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() >>> IntSort()
Int Int
@ -3920,8 +3920,8 @@ class ArrayRef(ExprRef):
arg = self.domain().cast(arg) arg = self.domain().cast(arg)
return _to_expr_ref(Z3_mk_select(self.ctx_ref(), self.as_ast(), arg.as_ast()), self.ctx) return _to_expr_ref(Z3_mk_select(self.ctx_ref(), self.as_ast(), arg.as_ast()), self.ctx)
def mk_default(self): 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): def is_array(a):
@ -4064,7 +4064,7 @@ def Default(a):
""" """
if __debug__: if __debug__:
_z3_assert(is_array(a), "First argument must be a Z3 array expression") _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): def Store(a, i, v):
@ -7520,7 +7520,7 @@ def Interpolant(a,ctx=None):
The argument is an interpolation pattern (see tree_interpolant). The argument is an interpolation pattern (see tree_interpolant).
>>> x = Int('x') >>> x = Int('x')
>>> print Interpolant(x>0) >>> print(Interpolant(x>0))
interp(x > 0) interp(x > 0)
""" """
ctx = _get_ctx(_ctx_from_ast_arg_list([a], ctx)) 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') >>> x = Int('x')
>>> y = Int('y') >>> 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)] [Not(x >= 0), Not(y <= 2)]
>>> g = And(Interpolant(x<0),x<2) # >>> g = And(Interpolant(x<0),x<2)
>>> try: # >>> try:
... print tree_interpolant(g).sexpr() # ... print tree_interpolant(g).sexpr()
... except ModelRef as m: # ... except ModelRef as m:
... print m.sexpr() # ... print m.sexpr()
(define-fun x () Int (define-fun x () Int
(- 1)) (- 1))
""" """
@ -7631,7 +7631,7 @@ def sequence_interpolant(v,p=None,ctx=None):
>>> x = Int('x') >>> x = Int('x')
>>> y = Int('y') >>> 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)] [Not(x >= 0), Not(y >= 0)]
""" """
f = v[0] f = v[0]
@ -7756,7 +7756,7 @@ def Float64(ctx=None):
ctx = _get_ctx(ctx) ctx = _get_ctx(ctx)
return FPSortRef(Z3_mk_fpa_sort_64(ctx.ref()), 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.""" """Floating-point 64-bit (double) sort."""
ctx = _get_ctx(ctx) ctx = _get_ctx(ctx)
return FPSortRef(Z3_mk_fpa_sort_double(ctx.ref()), ctx) return FPSortRef(Z3_mk_fpa_sort_double(ctx.ref()), ctx)
@ -7766,7 +7766,7 @@ def Float128(ctx=None):
ctx = _get_ctx(ctx) ctx = _get_ctx(ctx)
return FPSortRef(Z3_mk_fpa_sort_128(ctx.ref()), 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.""" """Floating-point 128-bit (quadruple) sort."""
ctx = _get_ctx(ctx) ctx = _get_ctx(ctx)
return FPSortRef(Z3_mk_fpa_sort_quadruple(ctx.ref()), ctx) return FPSortRef(Z3_mk_fpa_sort_quadruple(ctx.ref()), ctx)
@ -7835,7 +7835,7 @@ class FPRef(ExprRef):
return fpLEQ(self, other) return fpLEQ(self, other)
def __lt__(self, other): def __lt__(self, other):
return fpLEQ(self, other) return fpLT(self, other)
def __ge__(self, other): def __ge__(self, other):
return fpGEQ(self, other) return fpGEQ(self, other)
@ -8626,13 +8626,13 @@ def fpToSBV(rm, x, s):
>>> x = FP('x', FPSort(8, 24)) >>> x = FP('x', FPSort(8, 24))
>>> y = fpToSBV(RTZ(), x, BitVecSort(32)) >>> y = fpToSBV(RTZ(), x, BitVecSort(32))
>>> print is_fp(x) >>> print(is_fp(x))
True True
>>> print is_bv(y) >>> print(is_bv(y))
True True
>>> print is_fp(y) >>> print(is_fp(y))
False False
>>> print is_bv(x) >>> print(is_bv(x))
False False
""" """
if __debug__: if __debug__:
@ -8646,13 +8646,13 @@ def fpToUBV(rm, x, s):
>>> x = FP('x', FPSort(8, 24)) >>> x = FP('x', FPSort(8, 24))
>>> y = fpToUBV(RTZ(), x, BitVecSort(32)) >>> y = fpToUBV(RTZ(), x, BitVecSort(32))
>>> print is_fp(x) >>> print(is_fp(x))
True True
>>> print is_bv(y) >>> print(is_bv(y))
True True
>>> print is_fp(y) >>> print(is_fp(y))
False False
>>> print is_bv(x) >>> print(is_bv(x))
False False
""" """
if __debug__: if __debug__:
@ -8666,13 +8666,13 @@ def fpToReal(x):
>>> x = FP('x', FPSort(8, 24)) >>> x = FP('x', FPSort(8, 24))
>>> y = fpToReal(x) >>> y = fpToReal(x)
>>> print is_fp(x) >>> print(is_fp(x))
True True
>>> print is_real(y) >>> print(is_real(y))
True True
>>> print is_fp(y) >>> print(is_fp(y))
False False
>>> print is_real(x) >>> print(is_real(x))
False False
""" """
if __debug__: if __debug__:
@ -8690,13 +8690,13 @@ def fpToIEEEBV(x):
>>> x = FP('x', FPSort(8, 24)) >>> x = FP('x', FPSort(8, 24))
>>> y = fpToIEEEBV(x) >>> y = fpToIEEEBV(x)
>>> print is_fp(x) >>> print(is_fp(x))
True True
>>> print is_bv(y) >>> print(is_bv(y))
True True
>>> print is_fp(y) >>> print(is_fp(y))
False False
>>> print is_bv(x) >>> print(is_bv(x))
False False
""" """
if __debug__: if __debug__:

View file

@ -234,7 +234,7 @@ extern "C" {
/*@}*/ /*@}*/
#ifdef __cplusplus #ifdef __cplusplus
}; }
#endif // __cplusplus #endif // __cplusplus
#endif #endif

View file

@ -184,7 +184,7 @@ typedef enum
Z3_PARAMETER_SYMBOL, Z3_PARAMETER_SYMBOL,
Z3_PARAMETER_SORT, Z3_PARAMETER_SORT,
Z3_PARAMETER_AST, Z3_PARAMETER_AST,
Z3_PARAMETER_FUNC_DECL, Z3_PARAMETER_FUNC_DECL
} Z3_parameter_kind; } Z3_parameter_kind;
/** /**
@ -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. \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); Z3_lbool Z3_API Z3_get_bool_value(Z3_context c, Z3_ast a);
@ -6650,7 +6650,7 @@ END_MLAPI_EXCLUDE
/** /**
\brief Return a tactic associated with the given name. \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. 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 <tt>(help-tactics)</tt> in the SMT 2.0 front-end. It may also be obtained using the command <tt>(help-tactic)</tt> in the SMT 2.0 front-end.
Tactics are the basic building block for creating custom solvers for specific problem domains. 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. \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. 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 <tt>(help-tactics)</tt> in the SMT 2.0 front-end. It may also be obtained using the command <tt>(help-tactic)</tt> 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 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. which solver and/or preprocessing step will be used.
@ -7587,7 +7587,7 @@ END_MLAPI_EXCLUDE
\deprecated To be moved outside of API. \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_lbool Z3_API Z3_get_implied_equalities(
Z3_context c, Z3_context c,
@ -8116,7 +8116,7 @@ END_MLAPI_EXCLUDE
#ifndef CAMLIDL #ifndef CAMLIDL
#ifdef __cplusplus #ifdef __cplusplus
}; }
#endif // __cplusplus #endif // __cplusplus
#else #else
} }

View file

@ -935,7 +935,7 @@ extern "C" {
/*@}*/ /*@}*/
#ifdef __cplusplus #ifdef __cplusplus
}; }
#endif // __cplusplus #endif // __cplusplus
#endif #endif

View file

@ -287,7 +287,7 @@ extern "C" {
/*@}*/ /*@}*/
#ifdef __cplusplus #ifdef __cplusplus
}; }
#endif // __cplusplus #endif // __cplusplus
#endif #endif

View file

@ -55,7 +55,7 @@ extern "C" {
/*@}*/ /*@}*/
#ifdef __cplusplus #ifdef __cplusplus
}; }
#endif // __cplusplus #endif // __cplusplus
#endif #endif

View file

@ -208,7 +208,7 @@ extern "C" {
/*@}*/ /*@}*/
#ifdef __cplusplus #ifdef __cplusplus
}; }
#endif // __cplusplus #endif // __cplusplus
#endif #endif

View file

@ -516,7 +516,7 @@ inline unsigned ast_array_hash(T * const * array, unsigned size, unsigned init_v
switch (size) { switch (size) {
case 2: case 2:
b += array[1]->hash(); b += array[1]->hash();
__fallthrough; Z3_fallthrough;
case 1: case 1:
c += array[0]->hash(); c += array[0]->hash();
} }

View file

@ -1146,7 +1146,7 @@ typedef app proof; /* a proof is just an applicaton */
enum label_op_kind { enum label_op_kind {
OP_LABEL, OP_LABEL,
OP_LABEL_LIT, OP_LABEL_LIT
}; };
/** /**

File diff suppressed because it is too large Load diff

View file

@ -26,8 +26,6 @@ Notes:
#include"bv_decl_plugin.h" #include"bv_decl_plugin.h"
#include"basic_simplifier_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 { struct func_decl_triple {
func_decl_triple () { f_sgn = 0; f_sig = 0; f_exp = 0; } func_decl_triple () { f_sgn = 0; f_sig = 0; f_exp = 0; }
func_decl_triple (func_decl * sgn, func_decl * sig, func_decl * exp) func_decl_triple (func_decl * sgn, func_decl * sig, func_decl * exp)
@ -57,6 +55,11 @@ protected:
obj_map<func_decl, expr*> m_rm_const2bv; obj_map<func_decl, expr*> m_rm_const2bv;
obj_map<func_decl, func_decl*> m_uf2bvuf; obj_map<func_decl, func_decl*> m_uf2bvuf;
obj_hashtable<func_decl> m_decls_to_hide; obj_hashtable<func_decl> 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: public:
fpa2bv_converter(ast_manager & m); fpa2bv_converter(ast_manager & m);
@ -68,17 +71,19 @@ public:
bool is_float(sort * s) { return m_util.is_float(s); } 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_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_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(); } 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(expr * sign, expr * exponent, expr * significand, expr_ref & result);
void mk_fp(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_fp(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
void split_fp(expr * e, expr * & sgn, expr * & exp, expr * & sig) const; 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 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_ite(expr * c, expr * t, expr * f, expr_ref & result);
void mk_distinct(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_distinct(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
@ -101,9 +106,7 @@ public:
void mk_mul(func_decl * f, unsigned num, expr * const * args, expr_ref & result); 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_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_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_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_fma(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_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); void mk_round_to_integral(func_decl * f, unsigned num, expr * const * args, expr_ref & result);
@ -138,7 +141,12 @@ public:
void set_unspecified_fp_hi(bool v) { m_hi_fp_unspecified = v; } 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); 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); virtual expr_ref mk_max_unspecified(func_decl * f, expr * x, expr * y);
expr_ref mk_to_ubv_unspecified(unsigned width); expr_ref mk_to_ubv_unspecified(unsigned width);
@ -186,7 +194,7 @@ protected:
void round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & sig, expr_ref & exp, expr_ref & result); 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); 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 & 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); expr_ref & res_sgn, expr_ref & res_sig, expr_ref & res_exp);

View file

@ -123,7 +123,7 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg {
} }
if (m_conv.is_float_family(f)) { 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_AWAY:
case OP_FPA_RM_NEAREST_TIES_TO_EVEN: case OP_FPA_RM_NEAREST_TIES_TO_EVEN:
case OP_FPA_RM_TOWARD_NEGATIVE: case OP_FPA_RM_TOWARD_NEGATIVE:
@ -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_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_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_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_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_FMA: m_conv.mk_fma(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_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; 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_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_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_TO_IEEE_BV: m_conv.mk_to_ieee_bv(f, num, args, result); return BR_DONE;
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_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_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_BVWRAP:
case OP_FPA_INTERNAL_BVUNWRAP: case OP_FPA_INTERNAL_BVUNWRAP:
case OP_FPA_INTERNAL_TO_REAL_UNSPECIFIED: case OP_FPA_INTERNAL_TO_REAL_UNSPECIFIED:
@ -179,21 +185,21 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg {
NOT_IMPLEMENTED_YET(); NOT_IMPLEMENTED_YET();
} }
} }
else {
if (f->get_family_id() != 0 && f->get_family_id() != m_conv.fu().get_family_id()) 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()); 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]);
if (is_float_uf) 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); m_conv.mk_uninterpreted_function(f, num, args, result);
return BR_DONE; return BR_DONE;
} }
} }
return BR_FAILED; return BR_FAILED;
} }

View file

@ -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_REM: name = "fp.rem"; break;
case OP_FPA_MIN: name = "fp.min"; break; case OP_FPA_MIN: name = "fp.min"; break;
case OP_FPA_MAX: name = "fp.max"; 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: default:
UNREACHABLE(); UNREACHABLE();
break; break;
@ -643,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, 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) if (arity != 1)
m_manager->raise_exception("invalid number of arguments to to_ieee_bv"); m_manager->raise_exception("invalid number of arguments to to_ieee_bv");
if (!is_float_sort(domain[0])) if (!is_float_sort(domain[0]))
@ -656,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)); 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, 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) { unsigned arity, sort * const * domain, sort * range) {
if (arity != 1) if (arity != 1)
@ -684,37 +702,11 @@ 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)) if (!is_sort_of(domain[0], m_bv_fid, BV_SORT))
m_manager->raise_exception("sort mismatch, expected argument of bitvector sort"); m_manager->raise_exception("sort mismatch, expected argument of bitvector sort");
if (!is_float_sort(range) && !is_rm_sort(range)) 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)); 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( func_decl * fpa_decl_plugin::mk_internal_to_ubv_unspecified(
decl_kind k, unsigned num_parameters, parameter const * parameters, decl_kind k, unsigned num_parameters, parameter const * parameters,
unsigned arity, sort * const * domain, sort * range) { unsigned arity, sort * const * domain, sort * range) {
@ -818,14 +810,20 @@ 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); return mk_to_fp_unsigned(k, num_parameters, parameters, arity, domain, range);
case OP_FPA_TO_IEEE_BV: case OP_FPA_TO_IEEE_BV:
return mk_to_ieee_bv(k, num_parameters, parameters, arity, domain, range); 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: case OP_FPA_INTERNAL_BVWRAP:
return mk_internal_bv_wrap(k, num_parameters, parameters, arity, domain, range); return mk_internal_bv_wrap(k, num_parameters, parameters, arity, domain, range);
case OP_FPA_INTERNAL_BVUNWRAP: case OP_FPA_INTERNAL_BVUNWRAP:
return mk_internal_bv_unwrap(k, num_parameters, parameters, arity, domain, range); 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: case OP_FPA_INTERNAL_MIN_UNSPECIFIED:
return mk_internal_min_unspecified(k, num_parameters, parameters, arity, domain, range);
case OP_FPA_INTERNAL_MAX_UNSPECIFIED: 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: case OP_FPA_INTERNAL_TO_UBV_UNSPECIFIED:
return mk_internal_to_ubv_unspecified(k, num_parameters, parameters, arity, domain, range); return mk_internal_to_ubv_unspecified(k, num_parameters, parameters, arity, domain, range);
case OP_FPA_INTERNAL_TO_SBV_UNSPECIFIED: case OP_FPA_INTERNAL_TO_SBV_UNSPECIFIED:
@ -1031,18 +1029,6 @@ app * fpa_util::mk_nzero(unsigned ebits, unsigned sbits) {
return mk_value(v); 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) { app * fpa_util::mk_internal_to_ubv_unspecified(unsigned width) {
parameter ps[] = { parameter(width) }; parameter ps[] = { parameter(width) };
sort * range = m_bv_util.mk_sort(width); sort * range = m_bv_util.mk_sort(width);

View file

@ -34,6 +34,8 @@ enum fpa_sort_kind {
FLOAT128_SORT 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 { enum fpa_op_kind {
OP_FPA_RM_NEAREST_TIES_TO_EVEN, OP_FPA_RM_NEAREST_TIES_TO_EVEN,
OP_FPA_RM_NEAREST_TIES_TO_AWAY, OP_FPA_RM_NEAREST_TIES_TO_AWAY,
@ -85,8 +87,12 @@ enum fpa_op_kind {
OP_FPA_TO_IEEE_BV, OP_FPA_TO_IEEE_BV,
/* Internal use only */ /* Internal use only */
OP_FPA_INTERNAL_RM, // Internal conversion from (_ BitVec 3) to RoundingMode
OP_FPA_INTERNAL_BVWRAP, 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_MIN_UNSPECIFIED,
OP_FPA_INTERNAL_MAX_UNSPECIFIED, OP_FPA_INTERNAL_MAX_UNSPECIFIED,
OP_FPA_INTERNAL_TO_UBV_UNSPECIFIED, OP_FPA_INTERNAL_TO_UBV_UNSPECIFIED,
@ -125,6 +131,7 @@ class fpa_decl_plugin : public decl_plugin {
sort * mk_float_sort(unsigned ebits, unsigned sbits); sort * mk_float_sort(unsigned ebits, unsigned sbits);
sort * mk_rm_sort(); sort * mk_rm_sort();
func_decl * mk_rm_const_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, func_decl * mk_rm_const_decl(decl_kind k, unsigned num_parameters, parameter const * parameters,
unsigned arity, sort * const * domain, sort * range); unsigned arity, sort * const * domain, sort * range);
func_decl * mk_float_const_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, func_decl * mk_float_const_decl(decl_kind k, unsigned num_parameters, parameter const * parameters,
@ -158,14 +165,12 @@ class fpa_decl_plugin : public decl_plugin {
func_decl * mk_to_ieee_bv(decl_kind k, unsigned num_parameters, parameter const * parameters, func_decl * 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);
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, func_decl * mk_internal_bv_wrap(decl_kind k, unsigned num_parameters, parameter const * parameters,
unsigned arity, sort * const * domain, sort * range); unsigned arity, sort * const * domain, sort * range);
func_decl * mk_internal_bv_unwrap(decl_kind k, unsigned num_parameters, parameter const * parameters, func_decl * mk_internal_bv_unwrap(decl_kind k, unsigned num_parameters, parameter const * parameters,
unsigned arity, sort * const * domain, sort * range); 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, func_decl * mk_internal_to_ubv_unspecified(decl_kind k, unsigned num_parameters, parameter const * parameters,
unsigned arity, sort * const * domain, sort * range); unsigned arity, sort * const * domain, sort * range);
func_decl * mk_internal_to_sbv_unspecified(decl_kind k, unsigned num_parameters, parameter const * parameters, func_decl * mk_internal_to_sbv_unspecified(decl_kind k, unsigned num_parameters, parameter const * parameters,
@ -176,6 +181,7 @@ class fpa_decl_plugin : public decl_plugin {
virtual void set_manager(ast_manager * m, family_id id); virtual void set_manager(ast_manager * m, family_id id);
unsigned mk_id(mpf const & v); unsigned mk_id(mpf const & v);
void recycled_id(unsigned id); void recycled_id(unsigned id);
public: public:
fpa_decl_plugin(); fpa_decl_plugin();
@ -338,8 +344,6 @@ public:
app * mk_to_ieee_bv(expr * arg1) { return m().mk_app(m_fid, OP_FPA_TO_IEEE_BV, arg1); } 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_ubv_unspecified(unsigned width);
app * mk_internal_to_sbv_unspecified(unsigned width); app * mk_internal_to_sbv_unspecified(unsigned width);
app * mk_internal_to_ieee_bv_unspecified(unsigned width); app * mk_internal_to_ieee_bv_unspecified(unsigned width);

View file

@ -37,7 +37,7 @@ class expr_pattern_match {
CHECK_TERM, CHECK_TERM,
SET_BOUND, SET_BOUND,
CHECK_BOUND, CHECK_BOUND,
YIELD, YIELD
}; };
struct instr { struct instr {

View file

@ -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]); result = m_util.mk_bv_not(new_args[1]);
return BR_DONE; return BR_DONE;
} }
__fallthrough; Z3_fallthrough;
default: default:
if (m_bv_sort_ac) if (m_bv_sort_ac)
std::sort(new_args.begin(), new_args.end(), ast_to_lt()); std::sort(new_args.begin(), new_args.end(), ast_to_lt());

View file

@ -93,10 +93,14 @@ 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_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_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_MIN_UNSPECIFIED:
case OP_FPA_INTERNAL_MAX_UNSPECIFIED: case OP_FPA_INTERNAL_MAX_UNSPECIFIED:
SASSERT(num_args == 2); st = BR_FAILED; break; 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: case OP_FPA_INTERNAL_TO_UBV_UNSPECIFIED:
SASSERT(num_args == 0); st = mk_to_ubv_unspecified(f, result); break; SASSERT(num_args == 0); st = mk_to_ubv_unspecified(f, result); break;
case OP_FPA_INTERNAL_TO_SBV_UNSPECIFIED: case OP_FPA_INTERNAL_TO_SBV_UNSPECIFIED:
@ -434,19 +438,26 @@ br_status fpa_rewriter::mk_min(expr * arg1, expr * arg2, expr_ref & result) {
scoped_mpf v1(m_fm), v2(m_fm); scoped_mpf v1(m_fm), v2(m_fm);
if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2)) { 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)) { 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().mk_app(get_fid(), OP_FPA_INTERNAL_MIN_UNSPECIFIED, arg1, arg2);
result = m_util.mk_internal_min_unspecified(arg1, arg2);
return BR_DONE; return BR_DONE;
} }
else { else {
scoped_mpf r(m_fm); scoped_mpf r(m_fm);
m_fm.minimum(v1, v2, r); m_fm.minimum(v1, v2, r);
result = m_util.mk_value(r); result = m_util.mk_value(r);
return BR_DONE; 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) { br_status fpa_rewriter::mk_max(expr * arg1, expr * arg2, expr_ref & result) {
@ -462,9 +473,8 @@ br_status fpa_rewriter::mk_max(expr * arg1, expr * arg2, expr_ref & result) {
scoped_mpf v1(m_fm), v2(m_fm); scoped_mpf v1(m_fm), v2(m_fm);
if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2)) { 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)) { 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().mk_app(get_fid(), OP_FPA_INTERNAL_MAX_UNSPECIFIED, arg1, arg2);
result = m_util.mk_internal_max_unspecified(arg1, arg2); return BR_DONE;
return BR_REWRITE_FULL;
} }
else { else {
scoped_mpf r(m_fm); scoped_mpf r(m_fm);
@ -473,8 +483,16 @@ br_status fpa_rewriter::mk_max(expr * arg1, expr * arg2, expr_ref & result) {
return BR_DONE; 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) { br_status fpa_rewriter::mk_fma(expr * arg1, expr * arg2, expr * arg3, expr * arg4, expr_ref & result) {
@ -713,6 +731,27 @@ br_status fpa_rewriter::mk_eq_core(expr * arg1, expr * arg2, expr_ref & result)
return BR_FAILED; 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) { br_status fpa_rewriter::mk_fp(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) {
unsynch_mpz_manager & mpzm = m_fm.mpz_manager(); unsynch_mpz_manager & mpzm = m_fm.mpz_manager();
bv_util bu(m()); bv_util bu(m());

View file

@ -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(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_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_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_fp_unsigned(expr * arg1, expr * arg2, expr_ref & result);
br_status mk_to_ubv(func_decl * f, expr * arg1, expr * arg2, expr_ref & result); br_status mk_to_ubv(func_decl * f, expr * arg1, expr * arg2, expr_ref & result);

View file

@ -66,7 +66,7 @@ void context_params::set(char const * param, char const * value) {
long val = strtol(value, 0, 10); long val = strtol(value, 0, 10);
m_timeout = static_cast<unsigned>(val); m_timeout = static_cast<unsigned>(val);
} }
if (p == "rlimit") { else if (p == "rlimit") {
long val = strtol(value, 0, 10); long val = strtol(value, 0, 10);
m_rlimit = static_cast<unsigned>(val); m_rlimit = static_cast<unsigned>(val);
} }

View file

@ -117,7 +117,7 @@ class iz3base : public iz3mgr, public scopes {
/** Interpolator for clauses, to be implemented */ /** Interpolator for clauses, to be implemented */
virtual void interpolate_clause(std::vector<ast> &lits, std::vector<ast> &itps){ virtual void interpolate_clause(std::vector<ast> &lits, std::vector<ast> &itps){
throw "no interpolator"; throw iz3_exception("no interpolator");
} }
ast get_proof_check_assump(range &rng){ ast get_proof_check_assump(range &rng){
@ -129,7 +129,7 @@ class iz3base : public iz3mgr, public scopes {
int frame_of_assertion(const ast &ass){ int frame_of_assertion(const ast &ass){
stl_ext::hash_map<ast,int>::iterator it = frame_map.find(ass); stl_ext::hash_map<ast,int>::iterator it = frame_map.find(ass);
if(it == frame_map.end()) if(it == frame_map.end())
throw "unknown assertion"; throw iz3_exception("unknown assertion");
return it->second; return it->second;
} }

28
src/interp/iz3exception.h Normal file
View file

@ -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

View file

@ -218,7 +218,7 @@ public:
iz3secondary *sp = iz3foci::create(this,num,(int *)(parents.empty()?0:&parents[0])); iz3secondary *sp = iz3foci::create(this,num,(int *)(parents.empty()?0:&parents[0]));
int res = sp->interpolate(cnsts, interps); int res = sp->interpolate(cnsts, interps);
if(res != 0) if(res != 0)
throw "secondary failed"; throw iz3_exception("secondary failed");
} }
void proof_to_interpolant(z3pf proof, void proof_to_interpolant(z3pf proof,

View file

@ -21,6 +21,7 @@
#define IZ3_INTERP_H #define IZ3_INTERP_H
#include "iz3hash.h" #include "iz3hash.h"
#include "iz3exception.h"
#include "solver.h" #include "solver.h"
class iz3base; class iz3base;
@ -35,12 +36,14 @@ public:
}; };
/** This object is thrown if a tree interpolation problem is mal-formed */ /** 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 /** This object is thrown when iz3 fails due to an incompleteness in
the secondary solver. */ the secondary solver. */
struct iz3_incompleteness { struct iz3_incompleteness: public iz3_exception {
iz3_incompleteness(): iz3_exception("iz3_incompleteness") {}
}; };
// This is thrown if there is some bug in the // This is thrown if there is some bug in the

View file

@ -515,7 +515,7 @@ bool iz3mgr::is_farkas_coefficient_negative(const ast &proof, int n){
symb s = sym(proof); symb s = sym(proof);
bool ok = s->get_parameter(n+2).is_rational(r); bool ok = s->get_parameter(n+2).is_rational(r);
if(!ok) if(!ok)
throw "Bad Farkas coefficient"; throw iz3_exception("Bad Farkas coefficient");
return r.is_neg(); return r.is_neg();
} }
@ -532,7 +532,7 @@ void iz3mgr::get_farkas_coeffs(const ast &proof, std::vector<rational>& rats){
rational r; rational r;
bool ok = s->get_parameter(i).is_rational(r); bool ok = s->get_parameter(i).is_rational(r);
if(!ok) if(!ok)
throw "Bad Farkas coefficient"; throw iz3_exception("Bad Farkas coefficient");
#if 0 #if 0
{ {
ast con = conc(prem(proof,i-2)); ast con = conc(prem(proof,i-2));
@ -591,7 +591,7 @@ void iz3mgr::get_assign_bounds_coeffs(const ast &proof, std::vector<rational>& r
rational r; rational r;
bool ok = s->get_parameter(i).is_rational(r); bool ok = s->get_parameter(i).is_rational(r);
if(!ok) if(!ok)
throw "Bad Farkas coefficient"; throw iz3_exception("Bad Farkas coefficient");
{ {
ast con = arg(conc(proof),i-1); ast con = arg(conc(proof),i-1);
ast temp = make_real(r); // for debugging ast temp = make_real(r); // for debugging
@ -607,7 +607,7 @@ void iz3mgr::get_assign_bounds_coeffs(const ast &proof, std::vector<rational>& r
if(rats[1].is_neg()){ // work around bug -- if all coeffs negative, negate them if(rats[1].is_neg()){ // work around bug -- if all coeffs negative, negate them
for(unsigned i = 1; i < rats.size(); i++){ for(unsigned i = 1; i < rats.size(); i++){
if(!rats[i].is_neg()) if(!rats[i].is_neg())
throw "Bad Farkas coefficients"; throw iz3_exception("Bad Farkas coefficients");
rats[i] = -rats[i]; rats[i] = -rats[i];
} }
} }
@ -661,7 +661,7 @@ void iz3mgr::get_assign_bounds_rule_coeffs(const ast &proof, std::vector<rationa
rational r; rational r;
bool ok = s->get_parameter(i).is_rational(r); bool ok = s->get_parameter(i).is_rational(r);
if(!ok) if(!ok)
throw "Bad Farkas coefficient"; throw iz3_exception("Bad Farkas coefficient");
{ {
ast con = conc(prem(proof,i-2)); ast con = conc(prem(proof,i-2));
ast temp = make_real(r); // for debugging ast temp = make_real(r); // for debugging
@ -677,7 +677,7 @@ void iz3mgr::get_assign_bounds_rule_coeffs(const ast &proof, std::vector<rationa
if(rats[1].is_neg()){ // work around bug -- if all coeffs negative, negate them if(rats[1].is_neg()){ // work around bug -- if all coeffs negative, negate them
for(unsigned i = 1; i < rats.size(); i++){ for(unsigned i = 1; i < rats.size(); i++){
if(!rats[i].is_neg()) if(!rats[i].is_neg())
throw "Bad Farkas coefficients"; throw iz3_exception("Bad Farkas coefficients");
rats[i] = -rats[i]; rats[i] = -rats[i];
} }
} }
@ -709,7 +709,7 @@ void iz3mgr::linear_comb(ast &P, const ast &c, const ast &Q, bool round_off){
qstrict = true; qstrict = true;
break; break;
default: default:
throw "not an inequality"; throw iz3_exception("not an inequality");
} }
} }
else { else {
@ -729,7 +729,7 @@ void iz3mgr::linear_comb(ast &P, const ast &c, const ast &Q, bool round_off){
qstrict = true; qstrict = true;
break; break;
default: default:
throw "not an inequality"; throw iz3_exception("not an inequality");
} }
} }
bool pstrict = op(P) == Lt; bool pstrict = op(P) == Lt;

View file

@ -26,6 +26,7 @@
#include <functional> #include <functional>
#include "iz3hash.h" #include "iz3hash.h"
#include "iz3exception.h"
#include"well_sorted.h" #include"well_sorted.h"
#include"arith_decl_plugin.h" #include"arith_decl_plugin.h"

View file

@ -25,7 +25,8 @@
/** Exception thrown in case of mal-formed tree interpoloation /** Exception thrown in case of mal-formed tree interpoloation
specification */ 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, void iz3pp(ast_manager &m,

View file

@ -57,7 +57,9 @@ class iz3proof {
typedef prover::ast ast; typedef prover::ast ast;
/** Object thrown in case of a proof error. */ /** 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 */ /* Null proof node */
static const node null = -1; static const node null = -1;

View file

@ -250,7 +250,7 @@ class iz3proof_itp_impl : public iz3proof_itp {
#if 0 #if 0
rational r; rational r;
if(!is_integer(coeff,r)) if(!is_integer(coeff,r))
throw "ack!"; throw iz3_exception("ack!");
ast n = make_int(r.numerator()); ast n = make_int(r.numerator());
ast res = make(Times,n,t); ast res = make(Times,n,t);
if(!r.is_int()) { if(!r.is_int()) {
@ -433,7 +433,7 @@ class iz3proof_itp_impl : public iz3proof_itp {
if(op(foo) == Uninterpreted && sym(foo) == contra){ if(op(foo) == Uninterpreted && sym(foo) == contra){
ast neg_lit = arg(foo,1); ast neg_lit = arg(foo,1);
if(!is_false(neg_lit) && neg_lits.find(neg_lit) == neg_lits.end()) if(!is_false(neg_lit) && neg_lits.find(neg_lit) == neg_lits.end())
throw "lost a literal"; throw iz3_exception("lost a literal");
return; return;
} }
else { else {
@ -506,7 +506,9 @@ class iz3proof_itp_impl : public iz3proof_itp {
/* This is where the real work happens. Here, we simplify the /* This is where the real work happens. Here, we simplify the
proof obtained by cut elimination, obtaining an interpolant. */ 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<ast,ast> simplify_memo; hash_map<ast,ast> simplify_memo;
ast simplify(const ast &t){ 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(g == symm) return simplify_rotate_symm(pl,args[0],pf);
} }
if(op(pf) == Leq) if(op(pf) == Leq)
throw "foo!"; throw iz3_exception("foo!");
throw cannot_simplify(); throw cannot_simplify();
} }
@ -831,7 +833,7 @@ class iz3proof_itp_impl : public iz3proof_itp {
return my_implies(cond,ineqs); return my_implies(cond,ineqs);
if(op(ineqs) != And) if(op(ineqs) != And)
return my_and(Bconds,my_implies(cond,ineqs)); 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){ 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<ast> &args){ void reverse_modpon(std::vector<ast> &args){
@ -980,7 +982,9 @@ class iz3proof_itp_impl : public iz3proof_itp {
return chain; 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, void get_subterm_normals(const ast &ineq1, const ast &ineq2, const ast &chain, ast &normals,
const ast &pos, hash_set<ast> &memo, ast &Aproves, ast &Bproves){ const ast &pos, hash_set<ast> &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){ if(o1 == Not || o1 == Leq || o1 == Lt || o1 == Geq || o1 == Gt || o1 == Plus || o1 == Times){
int n = num_args(ineq1); int n = num_args(ineq1);
if(o2 != o1 || num_args(ineq2) != n) if(o2 != o1 || num_args(ineq2) != n)
throw "bad inequality rewriting"; throw iz3_exception("bad inequality rewriting");
for(int i = 0; i < n; i++){ for(int i = 0; i < n; i++){
ast new_pos = add_pos_to_end(pos,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); 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); memo.insert(ineq2);
ast sub_chain = extract_rewrites(chain,pos); ast sub_chain = extract_rewrites(chain,pos);
if(is_true(sub_chain)) 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)); 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); 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); ast interp = contra_chain(Q2,chain);
return my_and(Aproves,my_implies(Bproves,interp)); return my_and(Aproves,my_implies(Bproves,interp));
} }
throw "bad exmid"; throw iz3_exception("bad exmid");
} }
ast simplify_cong(const std::vector<ast> &args){ ast simplify_cong(const std::vector<ast> &args){
@ -1163,7 +1167,7 @@ class iz3proof_itp_impl : public iz3proof_itp {
ast interp = contra_chain(Q2,chain); ast interp = contra_chain(Q2,chain);
return my_and(Aproves,my_implies(Bproves,interp)); return my_and(Aproves,my_implies(Bproves,interp));
} }
throw "bad cong"; throw iz3_exception("bad cong");
} }
bool is_equivrel(const ast &p){ bool is_equivrel(const ast &p){
@ -1171,7 +1175,9 @@ class iz3proof_itp_impl : public iz3proof_itp {
return o == Equal || o == Iff; 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 /* 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". */ 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; rational r;
if(is_numeral(arg(pos,0),r)) if(is_numeral(arg(pos,0),r))
return r.get_unsigned(); return r.get_unsigned();
throw "bad position!"; throw iz3_exception("bad position!");
} }
/* substitute y into position pos in x */ /* 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); args[i] = i == p ? subst_in_pos(arg(x,i),arg(pos,1),y) : arg(x,i);
return clone(x,args); 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){ 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){ ast make_rewrite(LitType t, const ast &pos, const ast &cond, const ast &equality){
#if 0 #if 0
if(pos == top_pos && op(equality) == Iff && !is_true(arg(equality,0))) if(pos == top_pos && op(equality) == Iff && !is_true(arg(equality,0)))
throw "bad rewrite"; throw iz3_exception("bad rewrite");
#endif #endif
if(!is_equivrel(equality)) if(!is_equivrel(equality))
throw "bad rewrite"; throw iz3_exception("bad rewrite");
return make(t == LitA ? rewrite_A : rewrite_B, pos, cond, equality); 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)){ if(is_true(rest)){
ast old = rewrite_rhs(last); ast old = rewrite_rhs(last);
if(!(op(old) == Not)) if(!(op(old) == Not))
throw "bad negative equality chain"; throw iz3_exception("bad negative equality chain");
ast equ = arg(old,0); ast equ = arg(old,0);
if(!is_equivrel(equ)) 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)); 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); return chain_cons(rest,last);
} }
ast pos = rewrite_pos(last); ast pos = rewrite_pos(last);
if(pos == top_pos) if(pos == top_pos)
throw "bad negative equality chain"; throw iz3_exception("bad negative equality chain");
int idx = pos_arg(pos); int idx = pos_arg(pos);
if(idx != 0) if(idx != 0)
throw "bad negative equality chain"; throw iz3_exception("bad negative equality chain");
pos = arg(pos,1); pos = arg(pos,1);
if(pos == top_pos){ if(pos == top_pos){
ast lhs = rewrite_lhs(last); ast lhs = rewrite_lhs(last);
ast rhs = rewrite_rhs(last); ast rhs = rewrite_rhs(last);
if(op(lhs) != Equal || op(rhs) != Equal) 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), 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)))); 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) else if(idx == 1)
idx = 0; idx = 0;
else else
throw "bad negative equality chain"; throw iz3_exception("bad negative equality chain");
pos = pos_add(0,pos_add(idx,arg(pos,1))); pos = pos_add(0,pos_add(idx,arg(pos,1)));
last = make_rewrite(rewrite_side(last),pos,rewrite_cond(last),rewrite_equ(last)); 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; return chain;
} }
if(is_true(rest)) if(is_true(rest))
throw "bad rewrite chain"; throw iz3_exception("bad rewrite chain");
ast head = get_head_chain(rest,tail,is_not); ast head = get_head_chain(rest,tail,is_not);
tail = chain_cons(tail,last); tail = chain_cons(tail,last);
return head; 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. /** Split a chain of rewrites two chains, operating on positions 0 and 1.
Fail if any rewrite in the chain operates on top position. */ Fail if any rewrite in the chain operates on top position. */
@ -1808,7 +1816,7 @@ class iz3proof_itp_impl : public iz3proof_itp {
} }
case 1: case 1:
if(rewrite_lhs(last) != rewrite_rhs(last)) if(rewrite_lhs(last) != rewrite_rhs(last))
throw "bad rewrite chain"; throw iz3_exception("bad rewrite chain");
break; break;
default:; default:;
} }
@ -1853,7 +1861,9 @@ class iz3proof_itp_impl : public iz3proof_itp {
return rewrites_from_to(rest,lhs,mid); 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){ ast chain_ineqs(opr comp_op, LitType t, const ast &chain, const ast &lhs, const ast &rhs){
if(is_true(chain)){ if(is_true(chain)){
@ -1907,7 +1917,7 @@ class iz3proof_itp_impl : public iz3proof_itp {
rhs = arg(ineq,1); rhs = arg(ineq,1);
return; return;
} }
throw "bad ineq"; throw iz3_exception("bad ineq");
} }
ast chain_pos_add(int arg, const ast &chain){ 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){ ast make_normal(const ast &ineq, const ast &nrml){
if(!is_ineq(ineq)) if(!is_ineq(ineq))
throw "what?"; throw iz3_exception("what?");
return make(normal,ineq,nrml); return make(normal,ineq,nrml);
} }
@ -1985,7 +1995,7 @@ class iz3proof_itp_impl : public iz3proof_itp {
return make_normal_step(lhs,rhs,proof); return make_normal_step(lhs,rhs,proof);
if(rhst == LitMixed && (lhst != LitMixed || ast_id(rhs) < ast_id(lhs))) if(rhst == LitMixed && (lhst != LitMixed || ast_id(rhs) < ast_id(lhs)))
return make_normal_step(rhs,lhs,reverse_chain(proof)); return make_normal_step(rhs,lhs,reverse_chain(proof));
throw "help!"; throw iz3_exception("help!");
} }
ast chain_side_proves(LitType side, const ast &chain){ ast chain_side_proves(LitType side, const ast &chain){

View file

@ -50,7 +50,9 @@ class iz3proof_itp : public iz3mgr {
typedef ast node; typedef ast node;
/** Object thrown in case of a proof error. */ /** 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. /** Make a resolution node with given pivot literal and premises.

View file

@ -132,7 +132,7 @@ public:
// if(range_is_empty(r)) // if(range_is_empty(r))
range r = ast_scope(quanted); range r = ast_scope(quanted);
if(range_is_empty(r)) if(range_is_empty(r))
throw "can't skolemize"; throw iz3_exception("can't skolemize");
if(frame == INT_MAX || !in_range(frame,r)) if(frame == INT_MAX || !in_range(frame,r))
frame = range_max(r); // this is desperation -- may fail frame = range_max(r); // this is desperation -- may fail
if(frame >= frames) frame = frames - 1; if(frame >= frames) frame = frames - 1;
@ -1092,10 +1092,10 @@ public:
rational xcoeff = get_first_coefficient(arg(x,0),xvar); rational xcoeff = get_first_coefficient(arg(x,0),xvar);
rational ycoeff = get_first_coefficient(arg(y,0),yvar); rational ycoeff = get_first_coefficient(arg(y,0),yvar);
if(xcoeff == rational(0) || ycoeff == rational(0) || xvar != 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; rational ratio = xcoeff/ycoeff;
if(denominator(ratio) != rational(1)) if(denominator(ratio) != rational(1))
throw "bad assign-bounds lemma"; throw iz3_exception("bad assign-bounds lemma");
return make_int(ratio); // better be integer! return make_int(ratio); // better be integer!
} }
@ -1104,7 +1104,7 @@ public:
get_assign_bounds_coeffs(proof,farkas_coeffs); get_assign_bounds_coeffs(proof,farkas_coeffs);
int nargs = num_args(con); int nargs = num_args(con);
if(nargs != (int)(farkas_coeffs.size())) if(nargs != (int)(farkas_coeffs.size()))
throw "bad assign-bounds theory lemma"; throw iz3_exception("bad assign-bounds theory lemma");
#if 0 #if 0
if(farkas_coeffs[0] != make_int(rational(1))) if(farkas_coeffs[0] != make_int(rational(1)))
farkas_coeffs[0] = make_int(rational(1)); farkas_coeffs[0] = make_int(rational(1));
@ -1145,7 +1145,7 @@ public:
get_assign_bounds_rule_coeffs(proof,farkas_coeffs); get_assign_bounds_rule_coeffs(proof,farkas_coeffs);
int nargs = num_prems(proof)+1; int nargs = num_prems(proof)+1;
if(nargs != (int)(farkas_coeffs.size())) if(nargs != (int)(farkas_coeffs.size()))
throw "bad assign-bounds theory lemma"; throw iz3_exception("bad assign-bounds theory lemma");
#if 0 #if 0
if(farkas_coeffs[0] != make_int(rational(1))) if(farkas_coeffs[0] != make_int(rational(1)))
farkas_coeffs[0] = make_int(rational(1)); farkas_coeffs[0] = make_int(rational(1));
@ -1447,7 +1447,7 @@ public:
std::vector<ast> vals = cvec; std::vector<ast> vals = cvec;
if(!is_sat(cnstrs,new_proof,vals)) if(!is_sat(cnstrs,new_proof,vals))
throw "Proof error!"; throw iz3_exception("Proof error!");
std::vector<rational> rat_farkas_coeffs; std::vector<rational> rat_farkas_coeffs;
for(unsigned i = 0; i < cvec.size(); i++){ for(unsigned i = 0; i < cvec.size(); i++){
ast bar = vals[i]; ast bar = vals[i];
@ -1455,7 +1455,7 @@ public:
if(is_numeral(bar,r)) if(is_numeral(bar,r))
rat_farkas_coeffs.push_back(r); rat_farkas_coeffs.push_back(r);
else else
throw "Proof error!"; throw iz3_exception("Proof error!");
} }
rational the_lcd = lcd(rat_farkas_coeffs); rational the_lcd = lcd(rat_farkas_coeffs);
std::vector<ast> farkas_coeffs; std::vector<ast> farkas_coeffs;
@ -1503,7 +1503,7 @@ public:
ast new_proof; ast new_proof;
std::vector<ast> dummy; std::vector<ast> dummy;
if(is_sat(npcons,new_proof,dummy)) if(is_sat(npcons,new_proof,dummy))
throw "Proof error!"; throw iz3_exception("Proof error!");
pfrule dk = pr(new_proof); pfrule dk = pr(new_proof);
int nnp = num_prems(new_proof); int nnp = num_prems(new_proof);
std::vector<Iproof::node> my_prems; std::vector<Iproof::node> my_prems;
@ -1564,7 +1564,7 @@ public:
ast new_proof; ast new_proof;
std::vector<ast> dummy; std::vector<ast> dummy;
if(is_sat(npcons,new_proof,dummy)) if(is_sat(npcons,new_proof,dummy))
throw "Proof error!"; throw iz3_exception("Proof error!");
pfrule dk = pr(new_proof); pfrule dk = pr(new_proof);
int nnp = num_prems(new_proof); int nnp = num_prems(new_proof);
std::vector<Iproof::node> my_prems; std::vector<Iproof::node> my_prems;

View file

@ -35,7 +35,8 @@ class iz3translation : public iz3base {
virtual ~iz3translation(){} virtual ~iz3translation(){}
/** This is thrown when the proof cannot be translated. */ /** 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, static iz3translation *create(iz3mgr &mgr,

View file

@ -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; 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; bool local_antes_simple;

View file

@ -593,7 +593,7 @@ void asserted_formulas::propagate_values() {
bool found = false; bool found = false;
// Separate the formulas in two sets: C and R // Separate the formulas in two sets: C and R
// C is a set which contains formulas of the form // 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. // R contains the rest.
// //
// - new_exprs1 is the set C // - new_exprs1 is the set C
@ -613,15 +613,18 @@ void asserted_formulas::propagate_values() {
expr * lhs = to_app(n)->get_arg(0); expr * lhs = to_app(n)->get_arg(0);
expr * rhs = to_app(n)->get_arg(1); 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) || m_manager.is_value(rhs)) {
if (m_manager.is_value(lhs)) if (m_manager.is_value(lhs)) {
std::swap(lhs, rhs); 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 (!m_manager.is_value(lhs) && !m_simplifier.is_cached(lhs)) {
if (i >= m_asserted_qhead) { if (i >= m_asserted_qhead) {
new_exprs1.push_back(n); new_exprs1.push_back(n);
if (m_manager.proofs_enabled()) if (m_manager.proofs_enabled())
new_prs1.push_back(pr); 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); m_simplifier.cache_result(lhs, rhs, pr);
found = true; found = true;
continue; continue;

View file

@ -27,4 +27,4 @@ void dyn_ack_params::updt_params(params_ref const & _p) {
m_dack_threshold = p.dack_threshold(); m_dack_threshold = p.dack_threshold();
m_dack_gc = p.dack_gc(); m_dack_gc = p.dack_gc();
m_dack_gc_inv_decay = p.dack_gc_inv_decay(); m_dack_gc_inv_decay = p.dack_gc_inv_decay();
} }

View file

@ -66,7 +66,7 @@ enum case_split_strategy {
CS_ACTIVITY_WITH_CACHE, // case split based on activity and cache the activity CS_ACTIVITY_WITH_CACHE, // case split based on activity and cache the activity
CS_RELEVANCY, // case split based on relevancy CS_RELEVANCY, // case split based on relevancy
CS_RELEVANCY_ACTIVITY, // case split based on relevancy and activity 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, struct smt_params : public preprocessor_params,

View file

@ -67,7 +67,7 @@ namespace smt {
switch (num_args) { switch (num_args) {
case 2: case 2:
b += arg_hash(n, 1); b += arg_hash(n, 1);
__fallthrough; Z3_fallthrough;
case 1: case 1:
c += arg_hash(n, 0); c += arg_hash(n, 0);
} }

View file

@ -127,7 +127,7 @@ namespace smt {
switch (i) { switch (i) {
case 2: case 2:
b += n->get_arg(1)->get_root()->hash(); b += n->get_arg(1)->get_root()->hash();
__fallthrough; Z3_fallthrough;
case 1: case 1:
c += n->get_arg(0)->get_root()->hash(); c += n->get_arg(0)->get_root()->hash();
} }

View file

@ -28,7 +28,7 @@ namespace smt {
enum config_mode { enum config_mode {
CFG_BASIC, // install theories based on user options 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_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; class context;

View file

@ -1535,6 +1535,7 @@ namespace smt {
while (best_efforts < max_efforts && !ctx.get_cancel_flag()) { while (best_efforts < max_efforts && !ctx.get_cancel_flag()) {
theory_var x_j = null_theory_var; theory_var x_j = null_theory_var;
theory_var x_i = null_theory_var; theory_var x_i = null_theory_var;
bool has_bound = false;
max_gain.reset(); max_gain.reset();
min_gain.reset(); min_gain.reset();
++round; ++round;
@ -1543,12 +1544,15 @@ namespace smt {
typename vector<row_entry>::const_iterator it = r.begin_entries(); typename vector<row_entry>::const_iterator it = r.begin_entries();
typename vector<row_entry>::const_iterator end = r.end_entries(); typename vector<row_entry>::const_iterator end = r.end_entries();
for (; it != end; ++it) { 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_j = it->m_var;
theory_var curr_x_i = null_theory_var; theory_var curr_x_i = null_theory_var;
SASSERT(is_non_base(curr_x_j)); SASSERT(is_non_base(curr_x_j));
curr_coeff = it->m_coeff; 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))) { if ((curr_inc && at_upper(curr_x_j)) || (!curr_inc && at_lower(curr_x_j))) {
// variable cannot be used for max/min. // variable cannot be used for max/min.
continue; continue;
@ -1560,8 +1564,9 @@ namespace smt {
SASSERT(!picked_var || safe_gain(curr_min_gain, curr_max_gain)); 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";); TRACE("opt", tout << "no variable picked\n";);
has_bound = true;
best_efforts++; best_efforts++;
} }
else if (curr_x_i == null_theory_var) { else if (curr_x_i == null_theory_var) {
@ -1598,10 +1603,10 @@ namespace smt {
TRACE("opt", tout << "after traversing row:\nx_i: v" << x_i << ", x_j: v" << x_j << ", gain: " << max_gain << "\n"; 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";); 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; has_shared = false;
best_efforts = 0; best_efforts = 0;
result = UNBOUNDED; result = UNBOUNDED;
break; break;
} }

View file

@ -399,7 +399,6 @@ namespace smt {
}; };
struct sidl_ext { struct sidl_ext {
// TODO: It doesn't need to be a rational, but a bignum integer.
static const bool m_int_theory = true; static const bool m_int_theory = true;
typedef s_integer numeral; typedef s_integer numeral;
typedef s_integer fin_numeral; typedef s_integer fin_numeral;
@ -415,13 +414,11 @@ namespace smt {
rdl_ext() : m_epsilon(rational(), true) {} rdl_ext() : m_epsilon(rational(), true) {}
}; };
struct srdl_ext { //
static const bool m_int_theory = false; // there is no s_rational class, so
typedef inf_s_integer numeral; // instead we use multi-precision rationals.
typedef s_integer fin_numeral; //
numeral m_epsilon; struct srdl_ext : public rdl_ext {};
srdl_ext() : m_epsilon(s_integer(0),true) {}
};
typedef theory_diff_logic<idl_ext> theory_idl; typedef theory_diff_logic<idl_ext> theory_idl;
typedef theory_diff_logic<sidl_ext> theory_fidl; typedef theory_diff_logic<sidl_ext> theory_fidl;

View file

@ -74,7 +74,9 @@ namespace smt {
} }
else { else {
SASSERT(is_rm(f->get_range())); 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_rm_const2bv.insert(f, result);
m.inc_ref(f); m.inc_ref(f);
m.inc_ref(result); 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) { 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. // 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) { 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); expr_ref sc(m);
m_th.m_converter.mk_is_zero(res, sc); m_th.m_converter.mk_is_zero(res, sc);
m_extra_assertions.push_back(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; return res;
} }
@ -130,7 +131,6 @@ namespace smt {
expr_ref sc(m); expr_ref sc(m);
m_th.m_converter.mk_is_zero(res, sc); m_th.m_converter.mk_is_zero(res, sc);
m_extra_assertions.push_back(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; return res;
} }
@ -314,6 +314,7 @@ namespace smt {
expr_ref theory_fpa::convert_atom(expr * e) { expr_ref theory_fpa::convert_atom(expr * e) {
ast_manager & m = get_manager(); ast_manager & m = get_manager();
TRACE("t_fpa_detail", tout << "converting atom: " << mk_ismt2_pp(e, get_manager()) << "\n";);
expr_ref res(m); expr_ref res(m);
proof_ref pr(m); proof_ref pr(m);
m_rw(e, res); m_rw(e, res);
@ -331,15 +332,31 @@ namespace smt {
proof_ref pr(m); proof_ref pr(m);
m_rw(e, e_conv); m_rw(e, e_conv);
if (is_app(e_conv) && to_app(e_conv)->get_family_id() != get_family_id()) { if (is_app(e_conv) && to_app(e_conv)->get_family_id() != get_family_id()) {
m_th_rw(e_conv, res); 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)) { 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(is_app_of(e_conv, get_family_id(), OP_FPA_INTERNAL_RM));
SASSERT(m_bv_util.get_bv_size(e_conv) == 3); expr_ref bv_rm(m);
m_th_rw(e_conv, res); 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); expr_ref sgn(m), sig(m), exp(m);
m_converter.split_fp(e_conv, sgn, exp, sig); m_converter.split_fp(e_conv, sgn, exp, sig);
m_th_rw(sgn); m_th_rw(sgn);
@ -426,7 +443,7 @@ namespace smt {
sort * srt = m.get_sort(e); sort * srt = m.get_sort(e);
expr_ref res(m); expr_ref res(m);
if (m_fpa_util.is_rm(srt)) { 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 { else {
SASSERT(m_fpa_util.is_float(srt)); SASSERT(m_fpa_util.is_float(srt));
@ -454,7 +471,6 @@ namespace smt {
TRACE("t_fpa_detail", tout << "cached:" << std::endl; TRACE("t_fpa_detail", tout << "cached:" << std::endl;
tout << mk_ismt2_pp(e, m) << std::endl << " -> " << std::endl << tout << mk_ismt2_pp(e, m) << std::endl << " -> " << std::endl <<
mk_ismt2_pp(res, m) << std::endl;); mk_ismt2_pp(res, m) << std::endl;);
return res;
} }
else { else {
if (m_fpa_util.is_unwrap(e)) if (m_fpa_util.is_unwrap(e))
@ -464,7 +480,7 @@ namespace smt {
else if (m_fpa_util.is_float(e) || m_fpa_util.is_rm(e)) else if (m_fpa_util.is_float(e) || m_fpa_util.is_rm(e))
res = convert_term(e); res = convert_term(e);
else if (m_arith_util.is_real(e) || m_bv_util.is_bv(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 else
UNREACHABLE(); UNREACHABLE();
@ -476,7 +492,7 @@ namespace smt {
m.inc_ref(res); m.inc_ref(res);
m_trail_stack.push(fpa2bv_conversion_trail_elem(m, m_conversions, e)); m_trail_stack.push(fpa2bv_conversion_trail_elem(m, m_conversions, e));
} }
return res; return res;
} }
@ -643,19 +659,17 @@ namespace smt {
expr_ref xc(m), yc(m); expr_ref xc(m), yc(m);
xc = convert(xe); xc = convert(xe);
yc = convert(ye); yc = convert(ye);
TRACE("t_fpa_detail", tout << "xc = " << mk_ismt2_pp(xc, m) << std::endl << TRACE("t_fpa_detail", tout << "xc = " << mk_ismt2_pp(xc, m) << std::endl <<
"yc = " << mk_ismt2_pp(yc, m) << std::endl;); "yc = " << mk_ismt2_pp(yc, m) << std::endl;);
expr_ref c(m); 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); m_converter.mk_eq(xc, yc, c);
else if (fu.is_rm(xe) && fu.is_rm(ye)) else
c = m.mk_eq(xc, yc); c = m.mk_eq(xc, yc);
else
UNREACHABLE();
m_th_rw(c); m_th_rw(c);
assert_cnstr(m.mk_iff(m.mk_eq(xe, ye), c)); assert_cnstr(m.mk_iff(m.mk_eq(xe, ye), c));
@ -671,7 +685,7 @@ namespace smt {
TRACE("t_fpa", tout << "new diseq: " << x << " != " << y << std::endl;); TRACE("t_fpa", tout << "new diseq: " << x << " != " << y << std::endl;);
TRACE("t_fpa_detail", tout << mk_ismt2_pp(get_enode(x)->get_owner(), m) << " != " << 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; fpa_util & fu = m_fpa_util;
@ -688,14 +702,13 @@ namespace smt {
expr_ref c(m); 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); m_converter.mk_eq(xc, yc, c);
c = m.mk_not(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 else
UNREACHABLE(); c = m.mk_not(m.mk_eq(xc, yc));
m_th_rw(c); m_th_rw(c);
assert_cnstr(m.mk_iff(m.mk_not(m.mk_eq(xe, ye)), c)); assert_cnstr(m.mk_iff(m.mk_not(m.mk_eq(xe, ye)), c));

View file

@ -45,11 +45,6 @@ void fpa2bv_model_converter::display(std::ostream & out) {
unsigned indent = n.size() + 4; unsigned indent = n.size() + 4;
out << mk_ismt2_pp(it->m_value, m, indent) << ")"; out << mk_ismt2_pp(it->m_value, m, indent) << ")";
} }
for (obj_hashtable<func_decl>::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; out << ")" << std::endl;
} }
@ -130,16 +125,16 @@ expr_ref fpa2bv_model_converter::convert_bv2fp(sort * s, expr * sgn, expr * exp,
res = fu.mk_value(fp_val); res = fu.mk_value(fp_val);
TRACE("fpa2bv_mc", tout << "[" << mk_ismt2_pp(sgn, m) << TRACE("fpa2bv_mc", tout << "[" << mk_ismt2_pp(sgn, m) <<
" " << mk_ismt2_pp(exp, m) << " " << mk_ismt2_pp(exp, m) <<
" " << mk_ismt2_pp(sig, m) << "] == " << " " << mk_ismt2_pp(sig, m) << "] == " <<
mk_ismt2_pp(res, m) << std::endl;); mk_ismt2_pp(res, m) << std::endl;);
fu.fm().del(fp_val); fu.fm().del(fp_val);
return res; 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); fpa_util fu(m);
bv_util bu(m); bv_util bu(m);
@ -165,10 +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 { expr_ref fpa2bv_model_converter::convert_bv2rm(expr * eval_v) const {
fpa_util fu(m); fpa_util fu(m);
bv_util bu(m); bv_util bu(m);
expr_ref res(m); expr_ref res(m);
rational bv_val(0); rational bv_val(0);
unsigned sz = 0; unsigned sz = 0;
if (bu.is_numeral(eval_v, bv_val, sz)) { if (bu.is_numeral(eval_v, bv_val, sz)) {
SASSERT(bv_val.is_uint64()); SASSERT(bv_val.is_uint64());
switch (bv_val.get_uint64()) { switch (bv_val.get_uint64()) {
@ -189,7 +185,7 @@ expr_ref fpa2bv_model_converter::convert_bv2rm(model * bv_mdl, func_decl * var,
bv_util bu(m); bv_util bu(m);
expr_ref res(m); expr_ref res(m);
expr_ref eval_v(m); expr_ref eval_v(m);
if (val && bv_mdl->eval(val, eval_v, true)) if (val && bv_mdl->eval(val, eval_v, true))
res = convert_bv2rm(eval_v); res = convert_bv2rm(eval_v);
@ -205,14 +201,26 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) {
for (unsigned i = 0; i < bv_mdl->get_num_constants(); i++) for (unsigned i = 0; i < bv_mdl->get_num_constants(); i++)
tout << bv_mdl->get_constant(i)->get_name() << " --> " << 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<func_decl> seen; obj_hashtable<func_decl> seen;
for (obj_hashtable<func_decl>::iterator it = m_decls_to_hide.begin(); for (obj_hashtable<func_decl>::iterator it = m_decls_to_hide.begin();
it != m_decls_to_hide.end(); it != m_decls_to_hide.end();
it++) it++)
seen.insert(*it); seen.insert(*it);
for (obj_map<func_decl, expr*>::iterator it = m_const2bv.begin(); for (obj_map<func_decl, expr*>::iterator it = m_const2bv.begin();
it != m_const2bv.end(); it != m_const2bv.end();
@ -223,7 +231,7 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) {
SASSERT(fu.is_float(var->get_range())); SASSERT(fu.is_float(var->get_range()));
SASSERT(var->get_range()->get_num_parameters() == 2); 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(0), sgn, true);
bv_mdl->eval(val->get_arg(1), exp, true); bv_mdl->eval(val->get_arg(1), exp, true);
bv_mdl->eval(val->get_arg(2), sig, true); bv_mdl->eval(val->get_arg(2), sig, true);
@ -237,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(0))->get_decl());
seen.insert(to_app(val->get_arg(1))->get_decl()); seen.insert(to_app(val->get_arg(1))->get_decl());
seen.insert(to_app(val->get_arg(2))->get_decl()); seen.insert(to_app(val->get_arg(2))->get_decl());
#else #else
SASSERT(a->get_arg(0)->get_kind() == OP_EXTRACT); SASSERT(a->get_arg(0)->get_kind() == OP_EXTRACT);
SASSERT(to_app(a->get_arg(0))->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()); seen.insert(to_app(to_app(val->get_arg(0))->get_arg(0))->get_decl());
@ -260,8 +268,10 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) {
func_decl * var = it->m_key; func_decl * var = it->m_key;
SASSERT(fu.is_rm(var->get_range())); SASSERT(fu.is_rm(var->get_range()));
expr * val = it->m_value; 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); 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;); TRACE("fpa2bv_mc", tout << var->get_name() << " == " << mk_ismt2_pp(fv, m) << std::endl;);
float_mdl->register_decl(var, fv); float_mdl->register_decl(var, fv);
seen.insert(to_app(val)->get_decl()); seen.insert(to_app(val)->get_decl());
@ -298,7 +308,7 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) {
else else
new_args.push_back(aj); new_args.push_back(aj);
} }
expr_ref ret(m); expr_ref ret(m);
ret = bv_fe->get_result(); ret = bv_fe->get_result();
if (fu.is_float(rng)) if (fu.is_float(rng))
@ -306,7 +316,7 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) {
else if (fu.is_rm(rng)) else if (fu.is_rm(rng))
ret = convert_bv2rm(ret); 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); expr_ref els(m);
@ -318,7 +328,7 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) {
flt_fi->set_else(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. // Keep all the non-float constants.

View file

@ -35,7 +35,6 @@ public:
obj_map<func_decl, func_decl*> const & uf2bvuf, obj_map<func_decl, func_decl*> const & uf2bvuf,
obj_hashtable<func_decl> const & decls_to_hide) : obj_hashtable<func_decl> const & decls_to_hide) :
m(m) { m(m) {
// Just create a copy?
for (obj_map<func_decl, expr*>::iterator it = const2bv.begin(); for (obj_map<func_decl, expr*>::iterator it = const2bv.begin();
it != const2bv.end(); it != const2bv.end();
it++) it++)
@ -62,7 +61,8 @@ public:
} }
for (obj_hashtable<func_decl>::iterator it = decls_to_hide.begin(); for (obj_hashtable<func_decl>::iterator it = decls_to_hide.begin();
it != decls_to_hide.end(); it != decls_to_hide.end();
it++) { it++)
{
m_decls_to_hide.insert(*it); m_decls_to_hide.insert(*it);
m.inc_ref(*it); m.inc_ref(*it);
} }
@ -106,6 +106,6 @@ model_converter * mk_fpa2bv_model_converter(ast_manager & m,
obj_map<func_decl, expr*> const & const2bv, obj_map<func_decl, expr*> const & const2bv,
obj_map<func_decl, expr*> const & rm_const2bv, obj_map<func_decl, expr*> const & rm_const2bv,
obj_map<func_decl, func_decl*> const & uf2bvuf, obj_map<func_decl, func_decl*> const & uf2bvuf,
obj_hashtable<func_decl> const & m_decls_to_hide); obj_hashtable<func_decl> const & decls_to_hide);
#endif #endif

View file

@ -56,8 +56,6 @@ class fpa2bv_tactic : public tactic {
proof_converter_ref & pc, proof_converter_ref & pc,
expr_dependency_ref & core) { expr_dependency_ref & core) {
SASSERT(g->is_well_sorted()); 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_proofs_enabled = g->proofs_enabled();
m_produce_models = g->models_enabled(); m_produce_models = g->models_enabled();
m_produce_unsat_cores = g->unsat_core_enabled(); m_produce_unsat_cores = g->unsat_core_enabled();
@ -151,7 +149,12 @@ public:
model_converter_ref & mc, model_converter_ref & mc,
proof_converter_ref & pc, proof_converter_ref & pc,
expr_dependency_ref & core) { 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() { virtual void cleanup() {

View file

@ -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), tactic * st = and_then(mk_simplify_tactic(m, simp_p),
mk_propagate_values_tactic(m, p), mk_propagate_values_tactic(m, p),
cond(mk_or(mk_produce_proofs_probe(), mk_produce_unsat_cores_probe()), mk_fpa2bv_tactic(m, p),
mk_smt_tactic(), mk_propagate_values_tactic(m, p),
and_then( using_params(mk_simplify_tactic(m, p), simp_p),
mk_fpa2bv_tactic(m, p), mk_bit_blaster_tactic(m, p),
mk_propagate_values_tactic(m, p), using_params(mk_simplify_tactic(m, p), simp_p),
using_params(mk_simplify_tactic(m, p), simp_p), cond(mk_is_propositional_probe(),
mk_bit_blaster_tactic(m, p), cond(mk_produce_proofs_probe(),
using_params(mk_simplify_tactic(m, p), simp_p), mk_smt_tactic(), // `sat' does not support proofs.
cond(mk_is_propositional_probe(), mk_sat_tactic(m, p)),
mk_sat_tactic(m, p), cond(mk_has_fp_to_real_probe(),
cond(mk_has_fp_to_real_probe(), mk_qfnra_tactic(m, p),
mk_qfnra_tactic(m, p), mk_smt_tactic(p))),
mk_smt_tactic(p)) mk_fail_if_undecided_tactic());
),
mk_fail_if_undecided_tactic())));
st->updt_params(p); st->updt_params(p);
return st; return st;

View file

@ -820,4 +820,4 @@ public:
} }
}; };
#endif #endif

View file

@ -46,4 +46,4 @@ public:
} }
}; };
#endif #endif

View file

@ -18,7 +18,7 @@ Revision History:
--*/ --*/
#ifdef _WINDOWS #ifdef _WINDOWS
#include<iostream> #include<iostream>
#include<hash_set> #include<unordered_set>
#include<stdlib.h> #include<stdlib.h>
#include"hashtable.h" #include"hashtable.h"
@ -30,7 +30,7 @@ Revision History:
struct int_hash_proc { unsigned operator()(int x) const { return x * 3; } }; struct int_hash_proc { unsigned operator()(int x) const { return x * 3; } };
typedef int_hashtable<int_hash_proc, default_eq<int> > int_set; typedef int_hashtable<int_hash_proc, default_eq<int> > int_set;
typedef stdext::hash_set<int, stdext::hash_compare<int, std::less<int> > > safe_int_set; typedef std::unordered_set<int, std::hash_compare<int, std::less<int> > > safe_int_set;
// typedef safe_int_set int_set; // typedef safe_int_set int_set;
inline bool contains(int_set & h, int i) { inline bool contains(int_set & h, int i) {

View file

@ -52,38 +52,38 @@ unsigned string_hash(const char * str, unsigned length, unsigned init_value) {
switch(len) { /* all the case statements fall through */ switch(len) { /* all the case statements fall through */
case 11: case 11:
c+=((unsigned)str[10]<<24); c+=((unsigned)str[10]<<24);
__fallthrough; Z3_fallthrough;
case 10: case 10:
c+=((unsigned)str[9]<<16); c+=((unsigned)str[9]<<16);
__fallthrough; Z3_fallthrough;
case 9 : case 9 :
c+=((unsigned)str[8]<<8); c+=((unsigned)str[8]<<8);
__fallthrough; Z3_fallthrough;
/* the first byte of c is reserved for the length */ /* the first byte of c is reserved for the length */
case 8 : case 8 :
b+=((unsigned)str[7]<<24); b+=((unsigned)str[7]<<24);
__fallthrough; Z3_fallthrough;
case 7 : case 7 :
b+=((unsigned)str[6]<<16); b+=((unsigned)str[6]<<16);
__fallthrough; Z3_fallthrough;
case 6 : case 6 :
b+=((unsigned)str[5]<<8); b+=((unsigned)str[5]<<8);
__fallthrough; Z3_fallthrough;
case 5 : case 5 :
b+=str[4]; b+=str[4];
__fallthrough; Z3_fallthrough;
case 4 : case 4 :
a+=((unsigned)str[3]<<24); a+=((unsigned)str[3]<<24);
__fallthrough; Z3_fallthrough;
case 3 : case 3 :
a+=((unsigned)str[2]<<16); a+=((unsigned)str[2]<<16);
__fallthrough; Z3_fallthrough;
case 2 : case 2 :
a+=((unsigned)str[1]<<8); a+=((unsigned)str[1]<<8);
__fallthrough; Z3_fallthrough;
case 1 : case 1 :
a+=str[0]; a+=str[0];
__fallthrough; Z3_fallthrough;
/* case 0: nothing left to add */ /* case 0: nothing left to add */
} }
mix(a,b,c); mix(a,b,c);

View file

@ -22,10 +22,6 @@ Revision History:
#include<algorithm> #include<algorithm>
#include"util.h" #include"util.h"
#ifndef __fallthrough
#define __fallthrough
#endif
#define mix(a,b,c) \ #define mix(a,b,c) \
{ \ { \
a -= b; a -= c; a ^= (c>>13); \ a -= b; a -= c; a ^= (c>>13); \
@ -116,7 +112,7 @@ unsigned get_composite_hash(Composite app, unsigned n, GetKindHashProc const & k
switch (n) { switch (n) {
case 2: case 2:
b += chasher(app, 1); b += chasher(app, 1);
__fallthrough; Z3_fallthrough;
case 1: case 1:
c += chasher(app, 0); c += chasher(app, 0);
} }

View file

@ -127,15 +127,15 @@ public:
void to_rational(hwf const & x, scoped_mpq & o) { to_rational(x, o.m(), o); } 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; return (x.get_raw() & 0x8000000000000000ull) != 0;
} }
uint64 sig(hwf const & x) const { uint64 sig(hwf const & x) const {
return x.get_raw() & 0x000FFFFFFFFFFFFFull; return x.get_raw() & 0x000FFFFFFFFFFFFFull;
} }
int exp(hwf const & x) const { int exp(hwf const & x) const {
return ((x.get_raw() & 0x7FF0000000000000ull) >> 52) - 1023; return ((x.get_raw() & 0x7FF0000000000000ull) >> 52) - 1023;
} }

View file

@ -68,6 +68,18 @@ COMPILE_TIME_ASSERT(sizeof(int64) == 8);
#define THREAD_LOCAL #define THREAD_LOCAL
#endif #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; } 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; return false;
} }
#ifndef __fallthrough
#define __fallthrough
#endif
#ifndef _WINDOWS #ifndef _WINDOWS
#ifndef __declspec #ifndef __declspec
#define __declspec(X) #define __declspec(X)