mirror of
https://github.com/Z3Prover/z3
synced 2025-04-15 21:38:44 +00:00
Merge branch 'master' of https://github.com/Z3Prover/z3
This commit is contained in:
commit
865c0c0109
|
@ -32,9 +32,9 @@ project(Z3 C CXX)
|
||||||
# Project version
|
# Project version
|
||||||
################################################################################
|
################################################################################
|
||||||
set(Z3_VERSION_MAJOR 4)
|
set(Z3_VERSION_MAJOR 4)
|
||||||
set(Z3_VERSION_MINOR 4)
|
set(Z3_VERSION_MINOR 5)
|
||||||
set(Z3_VERSION_PATCH 2)
|
set(Z3_VERSION_PATCH 1)
|
||||||
set(Z3_VERSION_TWEAK 1)
|
set(Z3_VERSION_TWEAK 0)
|
||||||
set(Z3_FULL_VERSION 0)
|
set(Z3_FULL_VERSION 0)
|
||||||
set(Z3_VERSION "${Z3_VERSION_MAJOR}.${Z3_VERSION_MINOR}.${Z3_VERSION_PATCH}.${Z3_VERSION_TWEAK}")
|
set(Z3_VERSION "${Z3_VERSION_MAJOR}.${Z3_VERSION_MINOR}.${Z3_VERSION_PATCH}.${Z3_VERSION_TWEAK}")
|
||||||
message(STATUS "Z3 version ${Z3_VERSION}")
|
message(STATUS "Z3 version ${Z3_VERSION}")
|
||||||
|
|
|
@ -1,4 +1,30 @@
|
||||||
# Copyright (c) Microsoft Corporation 2015
|
# Copyright (c) Microsoft Corporation 2015, 2016
|
||||||
|
|
||||||
|
# The Z3 Python API requires libz3.dll/.so/.dylib in the
|
||||||
|
# PATH/LD_LIBRARY_PATH/DYLD_LIBRARY_PATH
|
||||||
|
# environment variable and the PYTHON_PATH environment variable
|
||||||
|
# needs to point to the `python' directory that contains `z3/z3.py'
|
||||||
|
# (which is at bin/python in our binary releases).
|
||||||
|
|
||||||
|
# If you obtained example.py as part of our binary release zip files,
|
||||||
|
# which you unzipped into a directory called `MYZ3', then follow these
|
||||||
|
# instructions to run the example:
|
||||||
|
|
||||||
|
# Running this example on Windows:
|
||||||
|
# set PATH=%PATH%;MYZ3\bin
|
||||||
|
# set PYTHONPATH=MYZ3\bin\python
|
||||||
|
# python example.py
|
||||||
|
|
||||||
|
# Running this example on Linux:
|
||||||
|
# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:MYZ3/bin
|
||||||
|
# export PYTHONPATH=MYZ3/bin/python
|
||||||
|
# python example.py
|
||||||
|
|
||||||
|
# Running this example on OSX:
|
||||||
|
# export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:MYZ3/bin
|
||||||
|
# export PYTHONPATH=MYZ3/bin/python
|
||||||
|
# python example.py
|
||||||
|
|
||||||
|
|
||||||
from z3 import *
|
from z3 import *
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ from mk_util import *
|
||||||
|
|
||||||
# Z3 Project definition
|
# Z3 Project definition
|
||||||
def init_project_def():
|
def init_project_def():
|
||||||
set_version(4, 4, 2, 1)
|
set_version(4, 5, 1, 0)
|
||||||
add_lib('util', [])
|
add_lib('util', [])
|
||||||
add_lib('polynomial', ['util'], 'math/polynomial')
|
add_lib('polynomial', ['util'], 'math/polynomial')
|
||||||
add_lib('sat', ['util'])
|
add_lib('sat', ['util'])
|
||||||
|
@ -94,6 +94,7 @@ def init_project_def():
|
||||||
add_ml_lib('ml', ['api_dll'], 'api/ml', lib_name='libz3ml')
|
add_ml_lib('ml', ['api_dll'], 'api/ml', lib_name='libz3ml')
|
||||||
add_hlib('cpp', 'api/c++', includes2install=['z3++.h'])
|
add_hlib('cpp', 'api/c++', includes2install=['z3++.h'])
|
||||||
set_z3py_dir('api/python')
|
set_z3py_dir('api/python')
|
||||||
|
add_python(_libz3Component)
|
||||||
add_python_install(_libz3Component)
|
add_python_install(_libz3Component)
|
||||||
# Examples
|
# Examples
|
||||||
add_cpp_example('cpp_example', 'c++')
|
add_cpp_example('cpp_example', 'c++')
|
||||||
|
|
|
@ -26,6 +26,7 @@ DOTNET_ENABLED=True
|
||||||
DOTNET_KEY_FILE=None
|
DOTNET_KEY_FILE=None
|
||||||
JAVA_ENABLED=True
|
JAVA_ENABLED=True
|
||||||
GIT_HASH=False
|
GIT_HASH=False
|
||||||
|
PYTHON_ENABLED=True
|
||||||
|
|
||||||
def set_verbose(flag):
|
def set_verbose(flag):
|
||||||
global VERBOSE
|
global VERBOSE
|
||||||
|
@ -55,6 +56,7 @@ def display_help():
|
||||||
print(" --nodotnet do not include .NET bindings in the binary distribution files.")
|
print(" --nodotnet do not include .NET bindings in the binary distribution files.")
|
||||||
print(" --dotnet-key=<file> sign the .NET assembly with the private key in <file>.")
|
print(" --dotnet-key=<file> sign the .NET assembly with the private key in <file>.")
|
||||||
print(" --nojava do not include Java bindings in the binary distribution files.")
|
print(" --nojava do not include Java bindings in the binary distribution files.")
|
||||||
|
print(" --nopython do not include Python bindings in the binary distribution files.")
|
||||||
print(" --githash include git hash in the Zip file.")
|
print(" --githash include git hash in the Zip file.")
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
|
@ -69,7 +71,8 @@ def parse_options():
|
||||||
'nojava',
|
'nojava',
|
||||||
'nodotnet',
|
'nodotnet',
|
||||||
'dotnet-key=',
|
'dotnet-key=',
|
||||||
'githash'
|
'githash',
|
||||||
|
'nopython'
|
||||||
])
|
])
|
||||||
for opt, arg in options:
|
for opt, arg in options:
|
||||||
if opt in ('-b', '--build'):
|
if opt in ('-b', '--build'):
|
||||||
|
@ -84,6 +87,8 @@ def parse_options():
|
||||||
FORCE_MK = True
|
FORCE_MK = True
|
||||||
elif opt == '--nodotnet':
|
elif opt == '--nodotnet':
|
||||||
DOTNET_ENABLED = False
|
DOTNET_ENABLED = False
|
||||||
|
elif opt == '--nopython':
|
||||||
|
PYTHON_ENABLED = False
|
||||||
elif opt == '--dotnet-key':
|
elif opt == '--dotnet-key':
|
||||||
DOTNET_KEY_FILE = arg
|
DOTNET_KEY_FILE = arg
|
||||||
elif opt == '--nojava':
|
elif opt == '--nojava':
|
||||||
|
@ -111,6 +116,8 @@ def mk_build_dir(path):
|
||||||
if GIT_HASH:
|
if GIT_HASH:
|
||||||
opts.append('--githash=%s' % mk_util.git_hash())
|
opts.append('--githash=%s' % mk_util.git_hash())
|
||||||
opts.append('--git-describe')
|
opts.append('--git-describe')
|
||||||
|
if PYTHON_ENABLED:
|
||||||
|
opts.append('--python')
|
||||||
if subprocess.call(opts) != 0:
|
if subprocess.call(opts) != 0:
|
||||||
raise MKException("Failed to generate build directory at '%s'" % path)
|
raise MKException("Failed to generate build directory at '%s'" % path)
|
||||||
|
|
||||||
|
@ -181,6 +188,7 @@ def mk_dist_dir():
|
||||||
mk_util.DOTNET_ENABLED = DOTNET_ENABLED
|
mk_util.DOTNET_ENABLED = DOTNET_ENABLED
|
||||||
mk_util.DOTNET_KEY_FILE = DOTNET_KEY_FILE
|
mk_util.DOTNET_KEY_FILE = DOTNET_KEY_FILE
|
||||||
mk_util.JAVA_ENABLED = JAVA_ENABLED
|
mk_util.JAVA_ENABLED = JAVA_ENABLED
|
||||||
|
mk_util.PYTHON_ENABLED = PYTHON_ENABLED
|
||||||
mk_unix_dist(build_path, dist_path)
|
mk_unix_dist(build_path, dist_path)
|
||||||
if is_verbose():
|
if is_verbose():
|
||||||
print("Generated distribution folder at '%s'" % dist_path)
|
print("Generated distribution folder at '%s'" % dist_path)
|
||||||
|
|
|
@ -63,6 +63,7 @@ DOTNET_COMPONENT='dotnet'
|
||||||
JAVA_COMPONENT='java'
|
JAVA_COMPONENT='java'
|
||||||
ML_COMPONENT='ml'
|
ML_COMPONENT='ml'
|
||||||
CPP_COMPONENT='cpp'
|
CPP_COMPONENT='cpp'
|
||||||
|
PYTHON_COMPONENT='python'
|
||||||
#####################
|
#####################
|
||||||
IS_WINDOWS=False
|
IS_WINDOWS=False
|
||||||
IS_LINUX=False
|
IS_LINUX=False
|
||||||
|
@ -81,6 +82,7 @@ ONLY_MAKEFILES = False
|
||||||
Z3PY_SRC_DIR=None
|
Z3PY_SRC_DIR=None
|
||||||
VS_PROJ = False
|
VS_PROJ = False
|
||||||
TRACE = False
|
TRACE = False
|
||||||
|
PYTHON_ENABLED=False
|
||||||
DOTNET_ENABLED=False
|
DOTNET_ENABLED=False
|
||||||
DOTNET_KEY_FILE=getenv("Z3_DOTNET_KEY_FILE", None)
|
DOTNET_KEY_FILE=getenv("Z3_DOTNET_KEY_FILE", None)
|
||||||
JAVA_ENABLED=False
|
JAVA_ENABLED=False
|
||||||
|
@ -675,7 +677,7 @@ def display_help(exit_code):
|
||||||
# Parse configuration option for mk_make script
|
# Parse configuration option for mk_make script
|
||||||
def parse_options():
|
def parse_options():
|
||||||
global VERBOSE, DEBUG_MODE, IS_WINDOWS, VS_X64, ONLY_MAKEFILES, SHOW_CPPS, VS_PROJ, TRACE, VS_PAR, VS_PAR_NUM
|
global VERBOSE, DEBUG_MODE, IS_WINDOWS, VS_X64, ONLY_MAKEFILES, SHOW_CPPS, VS_PROJ, TRACE, VS_PAR, VS_PAR_NUM
|
||||||
global DOTNET_ENABLED, DOTNET_KEY_FILE, JAVA_ENABLED, ML_ENABLED, STATIC_LIB, STATIC_BIN, PREFIX, GMP, FOCI2, FOCI2LIB, PYTHON_PACKAGE_DIR, GPROF, GIT_HASH, GIT_DESCRIBE, PYTHON_INSTALL_ENABLED
|
global DOTNET_ENABLED, DOTNET_KEY_FILE, JAVA_ENABLED, ML_ENABLED, STATIC_LIB, STATIC_BIN, PREFIX, GMP, FOCI2, FOCI2LIB, PYTHON_PACKAGE_DIR, GPROF, GIT_HASH, GIT_DESCRIBE, PYTHON_INSTALL_ENABLED, PYTHON_ENABLED
|
||||||
global LINUX_X64, SLOW_OPTIMIZE, USE_OMP
|
global LINUX_X64, SLOW_OPTIMIZE, USE_OMP
|
||||||
try:
|
try:
|
||||||
options, remainder = getopt.gnu_getopt(sys.argv[1:],
|
options, remainder = getopt.gnu_getopt(sys.argv[1:],
|
||||||
|
@ -748,6 +750,7 @@ def parse_options():
|
||||||
elif opt in ('', '--noomp'):
|
elif opt in ('', '--noomp'):
|
||||||
USE_OMP = False
|
USE_OMP = False
|
||||||
elif opt in ('--python'):
|
elif opt in ('--python'):
|
||||||
|
PYTHON_ENABLED = True
|
||||||
PYTHON_INSTALL_ENABLED = True
|
PYTHON_INSTALL_ENABLED = True
|
||||||
else:
|
else:
|
||||||
print("ERROR: Invalid command line option '%s'" % opt)
|
print("ERROR: Invalid command line option '%s'" % opt)
|
||||||
|
@ -844,6 +847,9 @@ def is_ml_enabled():
|
||||||
def is_dotnet_enabled():
|
def is_dotnet_enabled():
|
||||||
return DOTNET_ENABLED
|
return DOTNET_ENABLED
|
||||||
|
|
||||||
|
def is_python_enabled():
|
||||||
|
return PYTHON_ENABLED
|
||||||
|
|
||||||
def is_python_install_enabled():
|
def is_python_install_enabled():
|
||||||
return PYTHON_INSTALL_ENABLED
|
return PYTHON_INSTALL_ENABLED
|
||||||
|
|
||||||
|
@ -1382,6 +1388,32 @@ class DLLComponent(Component):
|
||||||
shutil.copy('%s.a' % os.path.join(build_path, self.dll_name),
|
shutil.copy('%s.a' % os.path.join(build_path, self.dll_name),
|
||||||
'%s.a' % os.path.join(dist_path, INSTALL_BIN_DIR, self.dll_name))
|
'%s.a' % os.path.join(dist_path, INSTALL_BIN_DIR, self.dll_name))
|
||||||
|
|
||||||
|
class PythonComponent(Component):
|
||||||
|
def __init__(self, name, libz3Component):
|
||||||
|
assert isinstance(libz3Component, DLLComponent)
|
||||||
|
global PYTHON_ENABLED
|
||||||
|
Component.__init__(self, name, None, [])
|
||||||
|
self.libz3Component = libz3Component
|
||||||
|
|
||||||
|
def main_component(self):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def mk_win_dist(self, build_path, dist_path):
|
||||||
|
if not is_python_enabled():
|
||||||
|
return
|
||||||
|
|
||||||
|
src = os.path.join(build_path, 'python', 'z3')
|
||||||
|
dst = os.path.join(dist_path, INSTALL_BIN_DIR, 'python', 'z3')
|
||||||
|
if os.path.exists(dst):
|
||||||
|
shutil.rmtree(dst)
|
||||||
|
shutil.copytree(src, dst)
|
||||||
|
|
||||||
|
def mk_unix_dist(self, build_path, dist_path):
|
||||||
|
self.mk_win_dist(build_path, dist_path)
|
||||||
|
|
||||||
|
def mk_makefile(self, out):
|
||||||
|
return
|
||||||
|
|
||||||
class PythonInstallComponent(Component):
|
class PythonInstallComponent(Component):
|
||||||
def __init__(self, name, libz3Component):
|
def __init__(self, name, libz3Component):
|
||||||
assert isinstance(libz3Component, DLLComponent)
|
assert isinstance(libz3Component, DLLComponent)
|
||||||
|
@ -1484,6 +1516,7 @@ class PythonInstallComponent(Component):
|
||||||
os.path.join('python', 'z3', '*.pyc'),
|
os.path.join('python', 'z3', '*.pyc'),
|
||||||
os.path.join(self.pythonPkgDir,'z3'),
|
os.path.join(self.pythonPkgDir,'z3'),
|
||||||
in_prefix=self.in_prefix_install)
|
in_prefix=self.in_prefix_install)
|
||||||
|
|
||||||
if PYTHON_PACKAGE_DIR != distutils.sysconfig.get_python_lib():
|
if PYTHON_PACKAGE_DIR != distutils.sysconfig.get_python_lib():
|
||||||
out.write('\t@echo Z3Py was installed at \'%s\', make sure this directory is in your PYTHONPATH environment variable.' % PYTHON_PACKAGE_DIR)
|
out.write('\t@echo Z3Py was installed at \'%s\', make sure this directory is in your PYTHONPATH environment variable.' % PYTHON_PACKAGE_DIR)
|
||||||
|
|
||||||
|
@ -2173,6 +2206,15 @@ class PythonExampleComponent(ExampleComponent):
|
||||||
print("Copied Z3Py example '%s' to '%s'" % (py, os.path.join(BUILD_DIR, 'python')))
|
print("Copied Z3Py example '%s' to '%s'" % (py, os.path.join(BUILD_DIR, 'python')))
|
||||||
out.write('_ex_%s: \n\n' % self.name)
|
out.write('_ex_%s: \n\n' % self.name)
|
||||||
|
|
||||||
|
def mk_win_dist(self, build_path, dist_path):
|
||||||
|
full = os.path.join(EXAMPLE_DIR, self.path)
|
||||||
|
py = 'example.py'
|
||||||
|
shutil.copyfile(os.path.join(full, py),
|
||||||
|
os.path.join(dist_path, INSTALL_BIN_DIR, 'python', py))
|
||||||
|
|
||||||
|
def mk_unix_dist(self, build_path, dist_path):
|
||||||
|
self.mk_win_dist(build_path, dist_path)
|
||||||
|
|
||||||
|
|
||||||
def reg_component(name, c):
|
def reg_component(name, c):
|
||||||
global _Id, _Components, _ComponentNames, _Name2Component
|
global _Id, _Components, _ComponentNames, _Name2Component
|
||||||
|
@ -2213,6 +2255,10 @@ def add_java_dll(name, deps=[], path=None, dll_name=None, package_name=None, man
|
||||||
c = JavaDLLComponent(name, dll_name, package_name, manifest_file, path, deps)
|
c = JavaDLLComponent(name, dll_name, package_name, manifest_file, path, deps)
|
||||||
reg_component(name, c)
|
reg_component(name, c)
|
||||||
|
|
||||||
|
def add_python(libz3Component):
|
||||||
|
name = 'python'
|
||||||
|
reg_component(name, PythonComponent(name, libz3Component))
|
||||||
|
|
||||||
def add_python_install(libz3Component):
|
def add_python_install(libz3Component):
|
||||||
name = 'python_install'
|
name = 'python_install'
|
||||||
reg_component(name, PythonInstallComponent(name, libz3Component))
|
reg_component(name, PythonInstallComponent(name, libz3Component))
|
||||||
|
@ -3230,11 +3276,6 @@ def mk_vs_proj_dll(name, components):
|
||||||
def mk_win_dist(build_path, dist_path):
|
def mk_win_dist(build_path, dist_path):
|
||||||
for c in get_components():
|
for c in get_components():
|
||||||
c.mk_win_dist(build_path, dist_path)
|
c.mk_win_dist(build_path, dist_path)
|
||||||
# Add Z3Py to bin directory
|
|
||||||
print("Adding to %s\n" % dist_path)
|
|
||||||
for pyc in filter(lambda f: f.endswith('.pyc') or f.endswith('.py'), os.listdir(build_path)):
|
|
||||||
shutil.copy(os.path.join(build_path, pyc),
|
|
||||||
os.path.join(dist_path, INSTALL_BIN_DIR, pyc))
|
|
||||||
|
|
||||||
def mk_unix_dist(build_path, dist_path):
|
def mk_unix_dist(build_path, dist_path):
|
||||||
for c in get_components():
|
for c in get_components():
|
||||||
|
|
|
@ -28,6 +28,7 @@ DOTNET_ENABLED=True
|
||||||
DOTNET_KEY_FILE=None
|
DOTNET_KEY_FILE=None
|
||||||
JAVA_ENABLED=True
|
JAVA_ENABLED=True
|
||||||
GIT_HASH=False
|
GIT_HASH=False
|
||||||
|
PYTHON_ENABLED=True
|
||||||
|
|
||||||
def set_verbose(flag):
|
def set_verbose(flag):
|
||||||
global VERBOSE
|
global VERBOSE
|
||||||
|
@ -60,12 +61,13 @@ def display_help():
|
||||||
print(" --nodotnet do not include .NET bindings in the binary distribution files.")
|
print(" --nodotnet do not include .NET bindings in the binary distribution files.")
|
||||||
print(" --dotnet-key=<file> sign the .NET assembly with the private key in <file>.")
|
print(" --dotnet-key=<file> sign the .NET assembly with the private key in <file>.")
|
||||||
print(" --nojava do not include Java bindings in the binary distribution files.")
|
print(" --nojava do not include Java bindings in the binary distribution files.")
|
||||||
|
print(" --nopython do not include Python bindings in the binary distribution files.")
|
||||||
print(" --githash include git hash in the Zip file.")
|
print(" --githash include git hash in the Zip file.")
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
# Parse configuration option for mk_make script
|
# Parse configuration option for mk_make script
|
||||||
def parse_options():
|
def parse_options():
|
||||||
global FORCE_MK, JAVA_ENABLED, GIT_HASH, DOTNET_ENABLED, DOTNET_KEY_FILE
|
global FORCE_MK, JAVA_ENABLED, GIT_HASH, DOTNET_ENABLED, DOTNET_KEY_FILE, PYTHON_ENABLED
|
||||||
path = BUILD_DIR
|
path = BUILD_DIR
|
||||||
options, remainder = getopt.gnu_getopt(sys.argv[1:], 'b:hsf', ['build=',
|
options, remainder = getopt.gnu_getopt(sys.argv[1:], 'b:hsf', ['build=',
|
||||||
'help',
|
'help',
|
||||||
|
@ -74,7 +76,8 @@ def parse_options():
|
||||||
'nojava',
|
'nojava',
|
||||||
'nodotnet',
|
'nodotnet',
|
||||||
'dotnet-key=',
|
'dotnet-key=',
|
||||||
'githash'
|
'githash',
|
||||||
|
'nopython'
|
||||||
])
|
])
|
||||||
for opt, arg in options:
|
for opt, arg in options:
|
||||||
if opt in ('-b', '--build'):
|
if opt in ('-b', '--build'):
|
||||||
|
@ -89,6 +92,8 @@ def parse_options():
|
||||||
FORCE_MK = True
|
FORCE_MK = True
|
||||||
elif opt == '--nodotnet':
|
elif opt == '--nodotnet':
|
||||||
DOTNET_ENABLED = False
|
DOTNET_ENABLED = False
|
||||||
|
elif opt == '--nopython':
|
||||||
|
PYTHON_ENABLED = False
|
||||||
elif opt == '--dotnet-key':
|
elif opt == '--dotnet-key':
|
||||||
DOTNET_KEY_FILE = arg
|
DOTNET_KEY_FILE = arg
|
||||||
elif opt == '--nojava':
|
elif opt == '--nojava':
|
||||||
|
@ -118,6 +123,8 @@ def mk_build_dir(path, x64):
|
||||||
if GIT_HASH:
|
if GIT_HASH:
|
||||||
opts.append('--githash=%s' % mk_util.git_hash())
|
opts.append('--githash=%s' % mk_util.git_hash())
|
||||||
opts.append('--git-describe')
|
opts.append('--git-describe')
|
||||||
|
if PYTHON_ENABLED:
|
||||||
|
opts.append('--python')
|
||||||
if subprocess.call(opts) != 0:
|
if subprocess.call(opts) != 0:
|
||||||
raise MKException("Failed to generate build directory at '%s'" % path)
|
raise MKException("Failed to generate build directory at '%s'" % path)
|
||||||
|
|
||||||
|
@ -192,6 +199,7 @@ def mk_dist_dir_core(x64):
|
||||||
mk_util.DOTNET_ENABLED = DOTNET_ENABLED
|
mk_util.DOTNET_ENABLED = DOTNET_ENABLED
|
||||||
mk_util.DOTNET_KEY_FILE = DOTNET_KEY_FILE
|
mk_util.DOTNET_KEY_FILE = DOTNET_KEY_FILE
|
||||||
mk_util.JAVA_ENABLED = JAVA_ENABLED
|
mk_util.JAVA_ENABLED = JAVA_ENABLED
|
||||||
|
mk_util.PYTHON_ENABLED = PYTHON_ENABLED
|
||||||
mk_win_dist(build_path, dist_path)
|
mk_win_dist(build_path, dist_path)
|
||||||
if is_verbose():
|
if is_verbose():
|
||||||
print("Generated %s distribution folder at '%s'" % (platform, dist_path))
|
print("Generated %s distribution folder at '%s'" % (platform, dist_path))
|
||||||
|
|
|
@ -189,7 +189,7 @@ extern "C" {
|
||||||
Z3_CATCH_RETURN(0);
|
Z3_CATCH_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Z3_sort Z3_API Z3_mk_finite_domain_sort(Z3_context c, Z3_symbol name, unsigned __int64 size) {
|
Z3_sort Z3_API Z3_mk_finite_domain_sort(Z3_context c, Z3_symbol name, __uint64 size) {
|
||||||
Z3_TRY;
|
Z3_TRY;
|
||||||
LOG_Z3_mk_finite_domain_sort(c, name, size);
|
LOG_Z3_mk_finite_domain_sort(c, name, size);
|
||||||
RESET_ERROR_CODE();
|
RESET_ERROR_CODE();
|
||||||
|
@ -199,7 +199,7 @@ extern "C" {
|
||||||
Z3_CATCH_RETURN(0);
|
Z3_CATCH_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Z3_bool Z3_API Z3_get_finite_domain_sort_size(Z3_context c, Z3_sort s, unsigned __int64 * out) {
|
Z3_bool Z3_API Z3_get_finite_domain_sort_size(Z3_context c, Z3_sort s, __uint64 * out) {
|
||||||
Z3_TRY;
|
Z3_TRY;
|
||||||
if (out) {
|
if (out) {
|
||||||
*out = 0;
|
*out = 0;
|
||||||
|
|
|
@ -4,6 +4,7 @@ import shutil
|
||||||
import platform
|
import platform
|
||||||
import subprocess
|
import subprocess
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
|
import re
|
||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
from distutils.errors import LibError
|
from distutils.errors import LibError
|
||||||
from distutils.command.build import build as _build
|
from distutils.command.build import build as _build
|
||||||
|
@ -43,6 +44,16 @@ def _clean_bins():
|
||||||
shutil.rmtree(BINS_DIR, ignore_errors=True)
|
shutil.rmtree(BINS_DIR, ignore_errors=True)
|
||||||
shutil.rmtree(HEADERS_DIR, ignore_errors=True)
|
shutil.rmtree(HEADERS_DIR, ignore_errors=True)
|
||||||
|
|
||||||
|
def _z3_version():
|
||||||
|
fn = os.path.join(SRC_DIR, 'scripts', 'mk_project.py')
|
||||||
|
if os.path.exists(fn):
|
||||||
|
with open(fn) as f:
|
||||||
|
for line in f:
|
||||||
|
n = re.match(".*set_version\((.*), (.*), (.*), (.*)\).*", line)
|
||||||
|
if not n is None:
|
||||||
|
return n.group(1) + '.' + n.group(2) + '.' + n.group(3) + '.' + n.group(4)
|
||||||
|
return "?.?.?.?"
|
||||||
|
|
||||||
def _configure_z3():
|
def _configure_z3():
|
||||||
# bail out early if we don't need to do this - it forces a rebuild every time otherwise
|
# bail out early if we don't need to do this - it forces a rebuild every time otherwise
|
||||||
if os.path.exists(BUILD_DIR):
|
if os.path.exists(BUILD_DIR):
|
||||||
|
@ -139,7 +150,7 @@ class sdist(_sdist):
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='z3-solver',
|
name='z3-solver',
|
||||||
version='4.4.2.1',
|
version=_z3_version(),
|
||||||
description='an efficient SMT solver library',
|
description='an efficient SMT solver library',
|
||||||
long_description='Z3 is a theorem prover from Microsoft Research with support for bitvectors, booleans, arrays, floating point numbers, strings, and other data types.\n\nFor documentation, please read http://z3prover.github.io/api/html/z3.html\n\nIn the event of technical difficulties related to configuration, compiliation, or installation, please submit issues to https://github.com/angr/angr-z3',
|
long_description='Z3 is a theorem prover from Microsoft Research with support for bitvectors, booleans, arrays, floating point numbers, strings, and other data types.\n\nFor documentation, please read http://z3prover.github.io/api/html/z3.html\n\nIn the event of technical difficulties related to configuration, compiliation, or installation, please submit issues to https://github.com/angr/angr-z3',
|
||||||
author="The Z3 Theorem Prover Project",
|
author="The Z3 Theorem Prover Project",
|
||||||
|
|
|
@ -1807,7 +1807,7 @@ extern "C" {
|
||||||
|
|
||||||
def_API('Z3_mk_finite_domain_sort', SORT, (_in(CONTEXT), _in(SYMBOL), _in(UINT64)))
|
def_API('Z3_mk_finite_domain_sort', SORT, (_in(CONTEXT), _in(SYMBOL), _in(UINT64)))
|
||||||
*/
|
*/
|
||||||
Z3_sort Z3_API Z3_mk_finite_domain_sort(Z3_context c, Z3_symbol name, unsigned __int64 size);
|
Z3_sort Z3_API Z3_mk_finite_domain_sort(Z3_context c, Z3_symbol name, __uint64 size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Create an array type.
|
\brief Create an array type.
|
||||||
|
@ -3143,14 +3143,14 @@ extern "C" {
|
||||||
/**
|
/**
|
||||||
\brief Create a numeral of a int, bit-vector, or finite-domain sort.
|
\brief Create a numeral of a int, bit-vector, or finite-domain sort.
|
||||||
|
|
||||||
This function can be use to create numerals that fit in a machine unsigned __int64 integer.
|
This function can be use to create numerals that fit in a machine __uint64 integer.
|
||||||
It is slightly faster than #Z3_mk_numeral since it is not necessary to parse a string.
|
It is slightly faster than #Z3_mk_numeral since it is not necessary to parse a string.
|
||||||
|
|
||||||
\sa Z3_mk_numeral
|
\sa Z3_mk_numeral
|
||||||
|
|
||||||
def_API('Z3_mk_unsigned_int64', AST, (_in(CONTEXT), _in(UINT64), _in(SORT)))
|
def_API('Z3_mk_unsigned_int64', AST, (_in(CONTEXT), _in(UINT64), _in(SORT)))
|
||||||
*/
|
*/
|
||||||
Z3_ast Z3_API Z3_mk_unsigned_int64(Z3_context c, unsigned __int64 v, Z3_sort ty);
|
Z3_ast Z3_API Z3_mk_unsigned_int64(Z3_context c, __uint64 v, Z3_sort ty);
|
||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
|
@ -3722,7 +3722,7 @@ extern "C" {
|
||||||
|
|
||||||
def_API('Z3_get_finite_domain_sort_size', BOOL, (_in(CONTEXT), _in(SORT), _out(UINT64)))
|
def_API('Z3_get_finite_domain_sort_size', BOOL, (_in(CONTEXT), _in(SORT), _out(UINT64)))
|
||||||
*/
|
*/
|
||||||
Z3_bool_opt Z3_API Z3_get_finite_domain_sort_size(Z3_context c, Z3_sort s, unsigned __int64* r);
|
Z3_bool_opt Z3_API Z3_get_finite_domain_sort_size(Z3_context c, Z3_sort s, __uint64* r);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Return the domain of the given array sort.
|
\brief Return the domain of the given array sort.
|
||||||
|
@ -4288,7 +4288,7 @@ extern "C" {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Similar to #Z3_get_numeral_string, but only succeeds if
|
\brief Similar to #Z3_get_numeral_string, but only succeeds if
|
||||||
the value can fit in a machine unsigned __int64 int. Return Z3_TRUE if the call succeeded.
|
the value can fit in a machine __uint64 int. Return Z3_TRUE if the call succeeded.
|
||||||
|
|
||||||
\pre Z3_get_ast_kind(c, v) == Z3_NUMERAL_AST
|
\pre Z3_get_ast_kind(c, v) == Z3_NUMERAL_AST
|
||||||
|
|
||||||
|
@ -4296,7 +4296,7 @@ extern "C" {
|
||||||
|
|
||||||
def_API('Z3_get_numeral_uint64', BOOL, (_in(CONTEXT), _in(AST), _out(UINT64)))
|
def_API('Z3_get_numeral_uint64', BOOL, (_in(CONTEXT), _in(AST), _out(UINT64)))
|
||||||
*/
|
*/
|
||||||
Z3_bool Z3_API Z3_get_numeral_uint64(Z3_context c, Z3_ast v, unsigned __int64* u);
|
Z3_bool Z3_API Z3_get_numeral_uint64(Z3_context c, Z3_ast v, __uint64* u);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Similar to #Z3_get_numeral_string, but only succeeds if
|
\brief Similar to #Z3_get_numeral_string, but only succeeds if
|
||||||
|
|
|
@ -34,7 +34,7 @@ macro_util::macro_util(ast_manager & m, simplifier & s):
|
||||||
m_simplifier(s),
|
m_simplifier(s),
|
||||||
m_arith_simp(0),
|
m_arith_simp(0),
|
||||||
m_bv_simp(0),
|
m_bv_simp(0),
|
||||||
m_basic_simp(0),
|
m_basic_simp(0),
|
||||||
m_forbidden_set(0),
|
m_forbidden_set(0),
|
||||||
m_curr_clause(0) {
|
m_curr_clause(0) {
|
||||||
}
|
}
|
||||||
|
@ -64,23 +64,23 @@ basic_simplifier_plugin * macro_util::get_basic_simp() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool macro_util::is_bv(expr * n) const {
|
bool macro_util::is_bv(expr * n) const {
|
||||||
return get_bv_simp()->is_bv(n);
|
return get_bv_simp()->is_bv(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool macro_util::is_bv_sort(sort * s) const {
|
bool macro_util::is_bv_sort(sort * s) const {
|
||||||
return get_bv_simp()->is_bv_sort(s);
|
return get_bv_simp()->is_bv_sort(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool macro_util::is_add(expr * n) const {
|
bool macro_util::is_add(expr * n) const {
|
||||||
return get_arith_simp()->is_add(n) || get_bv_simp()->is_add(n);
|
return get_arith_simp()->is_add(n) || get_bv_simp()->is_add(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool macro_util::is_times_minus_one(expr * n, expr * & arg) const {
|
bool macro_util::is_times_minus_one(expr * n, expr * & arg) const {
|
||||||
return get_arith_simp()->is_times_minus_one(n, arg) || get_bv_simp()->is_times_minus_one(n, arg);
|
return get_arith_simp()->is_times_minus_one(n, arg) || get_bv_simp()->is_times_minus_one(n, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool macro_util::is_le(expr * n) const {
|
bool macro_util::is_le(expr * n) const {
|
||||||
return get_arith_simp()->is_le(n) || get_bv_simp()->is_le(n);
|
return get_arith_simp()->is_le(n) || get_bv_simp()->is_le(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool macro_util::is_le_ge(expr * n) const {
|
bool macro_util::is_le_ge(expr * n) const {
|
||||||
|
@ -130,7 +130,7 @@ void macro_util::mk_add(unsigned num_args, expr * const * args, sort * s, expr_r
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Return true if \c n is an application of the form
|
\brief Return true if \c n is an application of the form
|
||||||
|
|
||||||
(f x_{k_1}, ..., x_{k_n})
|
(f x_{k_1}, ..., x_{k_n})
|
||||||
|
|
||||||
where f is uninterpreted
|
where f is uninterpreted
|
||||||
|
@ -147,7 +147,7 @@ bool macro_util::is_macro_head(expr * n, unsigned num_decls) const {
|
||||||
var2pos.resize(num_decls, -1);
|
var2pos.resize(num_decls, -1);
|
||||||
for (unsigned i = 0; i < num_decls; i++) {
|
for (unsigned i = 0; i < num_decls; i++) {
|
||||||
expr * c = to_app(n)->get_arg(i);
|
expr * c = to_app(n)->get_arg(i);
|
||||||
if (!is_var(c))
|
if (!is_var(c))
|
||||||
return false;
|
return false;
|
||||||
unsigned idx = to_var(c)->get_idx();
|
unsigned idx = to_var(c)->get_idx();
|
||||||
if (idx >= num_decls || var2pos[idx] != -1)
|
if (idx >= num_decls || var2pos[idx] != -1)
|
||||||
|
@ -161,12 +161,12 @@ bool macro_util::is_macro_head(expr * n, unsigned num_decls) const {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Return true if n is of the form
|
\brief Return true if n is of the form
|
||||||
|
|
||||||
(= (f x_{k_1}, ..., x_{k_n}) t) OR
|
(= (f x_{k_1}, ..., x_{k_n}) t) OR
|
||||||
(iff (f x_{k_1}, ..., x_{k_n}) t)
|
(iff (f x_{k_1}, ..., x_{k_n}) t)
|
||||||
|
|
||||||
where
|
where
|
||||||
|
|
||||||
is_macro_head((f x_{k_1}, ..., x_{k_n})) returns true AND
|
is_macro_head((f x_{k_1}, ..., x_{k_n})) returns true AND
|
||||||
t does not contain f AND
|
t does not contain f AND
|
||||||
f is not in forbidden_set
|
f is not in forbidden_set
|
||||||
|
@ -180,7 +180,8 @@ bool macro_util::is_left_simple_macro(expr * n, unsigned num_decls, app_ref & he
|
||||||
if (m_manager.is_eq(n) || m_manager.is_iff(n)) {
|
if (m_manager.is_eq(n) || m_manager.is_iff(n)) {
|
||||||
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 (is_macro_head(lhs, num_decls) && !is_forbidden(to_app(lhs)->get_decl()) && !occurs(to_app(lhs)->get_decl(), rhs)) {
|
if (is_macro_head(lhs, num_decls) && !is_forbidden(to_app(lhs)->get_decl()) &&
|
||||||
|
!occurs(to_app(lhs)->get_decl(), rhs)) {
|
||||||
head = to_app(lhs);
|
head = to_app(lhs);
|
||||||
def = rhs;
|
def = rhs;
|
||||||
return true;
|
return true;
|
||||||
|
@ -192,12 +193,12 @@ bool macro_util::is_left_simple_macro(expr * n, unsigned num_decls, app_ref & he
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Return true if n is of the form
|
\brief Return true if n is of the form
|
||||||
|
|
||||||
(= t (f x_{k_1}, ..., x_{k_n})) OR
|
(= t (f x_{k_1}, ..., x_{k_n})) OR
|
||||||
(iff t (f x_{k_1}, ..., x_{k_n}))
|
(iff t (f x_{k_1}, ..., x_{k_n}))
|
||||||
|
|
||||||
where
|
where
|
||||||
|
|
||||||
is_macro_head((f x_{k_1}, ..., x_{k_n})) returns true AND
|
is_macro_head((f x_{k_1}, ..., x_{k_n})) returns true AND
|
||||||
t does not contain f AND
|
t does not contain f AND
|
||||||
f is not in forbidden_set
|
f is not in forbidden_set
|
||||||
|
@ -211,7 +212,8 @@ bool macro_util::is_right_simple_macro(expr * n, unsigned num_decls, app_ref & h
|
||||||
if (m_manager.is_eq(n) || m_manager.is_iff(n)) {
|
if (m_manager.is_eq(n) || m_manager.is_iff(n)) {
|
||||||
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 (is_macro_head(rhs, num_decls) && !is_forbidden(to_app(rhs)->get_decl()) && !occurs(to_app(rhs)->get_decl(), lhs)) {
|
if (is_macro_head(rhs, num_decls) && !is_forbidden(to_app(rhs)->get_decl()) &&
|
||||||
|
!occurs(to_app(rhs)->get_decl(), lhs)) {
|
||||||
head = to_app(rhs);
|
head = to_app(rhs);
|
||||||
def = lhs;
|
def = lhs;
|
||||||
return true;
|
return true;
|
||||||
|
@ -254,7 +256,7 @@ bool macro_util::is_arith_macro(expr * n, unsigned num_decls, app_ref & head, ex
|
||||||
|
|
||||||
if (!as->is_numeral(rhs))
|
if (!as->is_numeral(rhs))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
inv = false;
|
inv = false;
|
||||||
ptr_buffer<expr> args;
|
ptr_buffer<expr> args;
|
||||||
expr * h = 0;
|
expr * h = 0;
|
||||||
|
@ -271,15 +273,15 @@ bool macro_util::is_arith_macro(expr * n, unsigned num_decls, app_ref & head, ex
|
||||||
for (unsigned i = 0; i < lhs_num_args; i++) {
|
for (unsigned i = 0; i < lhs_num_args; i++) {
|
||||||
expr * arg = lhs_args[i];
|
expr * arg = lhs_args[i];
|
||||||
expr * neg_arg;
|
expr * neg_arg;
|
||||||
if (h == 0 &&
|
if (h == 0 &&
|
||||||
is_macro_head(arg, num_decls) &&
|
is_macro_head(arg, num_decls) &&
|
||||||
!is_forbidden(to_app(arg)->get_decl()) &&
|
!is_forbidden(to_app(arg)->get_decl()) &&
|
||||||
!poly_contains_head(lhs, to_app(arg)->get_decl(), arg)) {
|
!poly_contains_head(lhs, to_app(arg)->get_decl(), arg)) {
|
||||||
h = arg;
|
h = arg;
|
||||||
}
|
}
|
||||||
else if (h == 0 && as->is_times_minus_one(arg, neg_arg) &&
|
else if (h == 0 && as->is_times_minus_one(arg, neg_arg) &&
|
||||||
is_macro_head(neg_arg, num_decls) &&
|
is_macro_head(neg_arg, num_decls) &&
|
||||||
!is_forbidden(to_app(neg_arg)->get_decl()) &&
|
!is_forbidden(to_app(neg_arg)->get_decl()) &&
|
||||||
!poly_contains_head(lhs, to_app(neg_arg)->get_decl(), arg)) {
|
!poly_contains_head(lhs, to_app(neg_arg)->get_decl(), arg)) {
|
||||||
h = neg_arg;
|
h = neg_arg;
|
||||||
inv = true;
|
inv = true;
|
||||||
|
@ -304,7 +306,7 @@ bool macro_util::is_arith_macro(expr * n, unsigned num_decls, app_ref & head, ex
|
||||||
\brief Auxiliary function for is_pseudo_predicate_macro. It detects the pattern (= (f X) t)
|
\brief Auxiliary function for is_pseudo_predicate_macro. It detects the pattern (= (f X) t)
|
||||||
*/
|
*/
|
||||||
bool macro_util::is_pseudo_head(expr * n, unsigned num_decls, app_ref & head, app_ref & t) {
|
bool macro_util::is_pseudo_head(expr * n, unsigned num_decls, app_ref & head, app_ref & t) {
|
||||||
if (!m_manager.is_eq(n))
|
if (!m_manager.is_eq(n))
|
||||||
return false;
|
return false;
|
||||||
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);
|
||||||
|
@ -331,7 +333,7 @@ bool macro_util::is_pseudo_head(expr * n, unsigned num_decls, app_ref & head, ap
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Returns true if n if of the form (forall (X) (iff (= (f X) t) def[X]))
|
\brief Returns true if n if of the form (forall (X) (iff (= (f X) t) def[X]))
|
||||||
where t is a ground term, (f X) is the head.
|
where t is a ground term, (f X) is the head.
|
||||||
*/
|
*/
|
||||||
bool macro_util::is_pseudo_predicate_macro(expr * n, app_ref & head, app_ref & t, expr_ref & def) {
|
bool macro_util::is_pseudo_predicate_macro(expr * n, app_ref & head, app_ref & t, expr_ref & def) {
|
||||||
if (!is_quantifier(n) || !to_quantifier(n)->is_forall())
|
if (!is_quantifier(n) || !to_quantifier(n)->is_forall())
|
||||||
|
@ -343,14 +345,14 @@ bool macro_util::is_pseudo_predicate_macro(expr * n, app_ref & head, app_ref & t
|
||||||
return false;
|
return false;
|
||||||
expr * lhs = to_app(body)->get_arg(0);
|
expr * lhs = to_app(body)->get_arg(0);
|
||||||
expr * rhs = to_app(body)->get_arg(1);
|
expr * rhs = to_app(body)->get_arg(1);
|
||||||
if (is_pseudo_head(lhs, num_decls, head, t) &&
|
if (is_pseudo_head(lhs, num_decls, head, t) &&
|
||||||
!is_forbidden(head->get_decl()) &&
|
!is_forbidden(head->get_decl()) &&
|
||||||
!occurs(head->get_decl(), rhs)) {
|
!occurs(head->get_decl(), rhs)) {
|
||||||
def = rhs;
|
def = rhs;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (is_pseudo_head(rhs, num_decls, head, t) &&
|
if (is_pseudo_head(rhs, num_decls, head, t) &&
|
||||||
!is_forbidden(head->get_decl()) &&
|
!is_forbidden(head->get_decl()) &&
|
||||||
!occurs(head->get_decl(), lhs)) {
|
!occurs(head->get_decl(), lhs)) {
|
||||||
def = lhs;
|
def = lhs;
|
||||||
return true;
|
return true;
|
||||||
|
@ -361,7 +363,7 @@ bool macro_util::is_pseudo_predicate_macro(expr * n, app_ref & head, app_ref & t
|
||||||
/**
|
/**
|
||||||
\brief A quasi-macro head is of the form f[X_1, ..., X_n],
|
\brief A quasi-macro head is of the form f[X_1, ..., X_n],
|
||||||
where n == num_decls, f[X_1, ..., X_n] is a term starting with symbol f, f is uninterpreted,
|
where n == num_decls, f[X_1, ..., X_n] is a term starting with symbol f, f is uninterpreted,
|
||||||
contains all universally quantified variables as arguments.
|
contains all universally quantified variables as arguments.
|
||||||
Note that, some arguments of f[X_1, ..., X_n] may not be variables.
|
Note that, some arguments of f[X_1, ..., X_n] may not be variables.
|
||||||
|
|
||||||
Examples of quasi-macros:
|
Examples of quasi-macros:
|
||||||
|
@ -477,16 +479,16 @@ void macro_util::normalize_expr(app * head, expr * t, expr_ref & norm_t) const {
|
||||||
else
|
else
|
||||||
var_mapping.setx(max_var_idx - i, v);
|
var_mapping.setx(max_var_idx - i, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = num_args; i <= max_var_idx; i++)
|
for (unsigned i = num_args; i <= max_var_idx; i++)
|
||||||
// CMW: Won't be used, but dictates a larger binding size,
|
// CMW: Won't be used, but dictates a larger binding size,
|
||||||
// so that the indexes between here and in the rewriter match.
|
// so that the indexes between here and in the rewriter match.
|
||||||
// It's possible that we don't see the true max idx of all vars here.
|
// It's possible that we don't see the true max idx of all vars here.
|
||||||
var_mapping.setx(max_var_idx - i, 0);
|
var_mapping.setx(max_var_idx - i, 0);
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
// REMARK: t may have nested quantifiers... So, I must use the std order for variable substitution.
|
// REMARK: t may have nested quantifiers... So, I must use the std order for variable substitution.
|
||||||
var_subst subst(m_manager, true);
|
var_subst subst(m_manager, true);
|
||||||
TRACE("macro_util_bug",
|
TRACE("macro_util_bug",
|
||||||
tout << "head: " << mk_pp(head, m_manager) << "\n";
|
tout << "head: " << mk_pp(head, m_manager) << "\n";
|
||||||
tout << "applying substitution to:\n" << mk_ll_pp(t, m_manager) << "\nsubstitution:\n";
|
tout << "applying substitution to:\n" << mk_ll_pp(t, m_manager) << "\nsubstitution:\n";
|
||||||
|
@ -503,8 +505,8 @@ void macro_util::normalize_expr(app * head, expr * t, expr_ref & norm_t) const {
|
||||||
|
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
//
|
//
|
||||||
// "Hint" support
|
// "Hint" support
|
||||||
// See comment at is_hint_atom
|
// See comment at is_hint_atom
|
||||||
// for a definition of what a hint is.
|
// for a definition of what a hint is.
|
||||||
//
|
//
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
|
@ -516,7 +518,7 @@ bool is_hint_head(expr * n, ptr_buffer<var> & vars) {
|
||||||
return false;
|
return false;
|
||||||
unsigned num_args = to_app(n)->get_num_args();
|
unsigned num_args = to_app(n)->get_num_args();
|
||||||
for (unsigned i = 0; i < num_args; i++) {
|
for (unsigned i = 0; i < num_args; i++) {
|
||||||
expr * arg = to_app(n)->get_arg(i);
|
expr * arg = to_app(n)->get_arg(i);
|
||||||
if (is_var(arg))
|
if (is_var(arg))
|
||||||
vars.push_back(to_var(arg));
|
vars.push_back(to_var(arg));
|
||||||
}
|
}
|
||||||
|
@ -552,7 +554,7 @@ bool vars_of_is_subset(expr * n, ptr_buffer<var> const & vars) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SASSERT(is_quantifier(curr));
|
SASSERT(is_quantifier(curr));
|
||||||
return false; // do no support nested quantifier... being conservative.
|
return false; // do no support nested quantifier... being conservative.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -560,7 +562,7 @@ bool vars_of_is_subset(expr * n, ptr_buffer<var> const & vars) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief (= lhs rhs) is a hint atom if
|
\brief (= lhs rhs) is a hint atom if
|
||||||
lhs is of the form (f t_1 ... t_n)
|
lhs is of the form (f t_1 ... t_n)
|
||||||
and all variables occurring in rhs are direct arguments of lhs.
|
and all variables occurring in rhs are direct arguments of lhs.
|
||||||
*/
|
*/
|
||||||
|
@ -598,7 +600,7 @@ void hint_to_macro_head(ast_manager & m, app * head, unsigned num_decls, app_ref
|
||||||
/**
|
/**
|
||||||
\brief Return true if n can be viewed as a polynomial "hint" based on head.
|
\brief Return true if n can be viewed as a polynomial "hint" based on head.
|
||||||
That is, n (but the monomial exception) only uses the variables in head, and does not use
|
That is, n (but the monomial exception) only uses the variables in head, and does not use
|
||||||
head->get_decl().
|
head->get_decl().
|
||||||
is_hint_head(head, vars) must also return true
|
is_hint_head(head, vars) must also return true
|
||||||
*/
|
*/
|
||||||
bool macro_util::is_poly_hint(expr * n, app * head, expr * exception) {
|
bool macro_util::is_poly_hint(expr * n, app * head, expr * exception) {
|
||||||
|
@ -630,7 +632,7 @@ bool macro_util::is_poly_hint(expr * n, app * head, expr * exception) {
|
||||||
}
|
}
|
||||||
TRACE("macro_util_hint", tout << "succeeded\n";);
|
TRACE("macro_util_hint", tout << "succeeded\n";);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
|
@ -681,7 +683,7 @@ void macro_util::insert_macro(app * head, expr * def, expr * cond, bool ineq, bo
|
||||||
r.insert(head->get_decl(), norm_def.get(), norm_cond.get(), ineq, satisfy_atom, hint);
|
r.insert(head->get_decl(), norm_def.get(), norm_cond.get(), ineq, satisfy_atom, hint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void macro_util::insert_quasi_macro(app * head, unsigned num_decls, expr * def, expr * cond, bool ineq, bool satisfy_atom,
|
void macro_util::insert_quasi_macro(app * head, unsigned num_decls, expr * def, expr * cond, bool ineq, bool satisfy_atom,
|
||||||
bool hint, macro_candidates & r) {
|
bool hint, macro_candidates & r) {
|
||||||
if (!is_macro_head(head, head->get_num_args())) {
|
if (!is_macro_head(head, head->get_num_args())) {
|
||||||
app_ref new_head(m_manager);
|
app_ref new_head(m_manager);
|
||||||
|
@ -783,8 +785,8 @@ void macro_util::collect_arith_macro_candidates(expr * lhs, expr * rhs, expr * a
|
||||||
if (!is_app(arg))
|
if (!is_app(arg))
|
||||||
continue;
|
continue;
|
||||||
func_decl * f = to_app(arg)->get_decl();
|
func_decl * f = to_app(arg)->get_decl();
|
||||||
|
|
||||||
bool _is_arith_macro =
|
bool _is_arith_macro =
|
||||||
is_quasi_macro_head(arg, num_decls) &&
|
is_quasi_macro_head(arg, num_decls) &&
|
||||||
!is_forbidden(f) &&
|
!is_forbidden(f) &&
|
||||||
!poly_contains_head(lhs, f, arg) &&
|
!poly_contains_head(lhs, f, arg) &&
|
||||||
|
@ -805,14 +807,14 @@ void macro_util::collect_arith_macro_candidates(expr * lhs, expr * rhs, expr * a
|
||||||
}
|
}
|
||||||
else if (is_times_minus_one(arg, neg_arg) && is_app(neg_arg)) {
|
else if (is_times_minus_one(arg, neg_arg) && is_app(neg_arg)) {
|
||||||
f = to_app(neg_arg)->get_decl();
|
f = to_app(neg_arg)->get_decl();
|
||||||
bool _is_arith_macro =
|
bool _is_arith_macro =
|
||||||
is_quasi_macro_head(neg_arg, num_decls) &&
|
is_quasi_macro_head(neg_arg, num_decls) &&
|
||||||
!is_forbidden(f) &&
|
!is_forbidden(f) &&
|
||||||
!poly_contains_head(lhs, f, arg) &&
|
!poly_contains_head(lhs, f, arg) &&
|
||||||
!occurs(f, rhs) &&
|
!occurs(f, rhs) &&
|
||||||
!rest_contains_decl(f, atom);
|
!rest_contains_decl(f, atom);
|
||||||
bool _is_poly_hint = !_is_arith_macro && is_poly_hint(lhs, to_app(neg_arg), arg);
|
bool _is_poly_hint = !_is_arith_macro && is_poly_hint(lhs, to_app(neg_arg), arg);
|
||||||
|
|
||||||
if (_is_arith_macro || _is_poly_hint) {
|
if (_is_arith_macro || _is_poly_hint) {
|
||||||
collect_poly_args(lhs, arg, args);
|
collect_poly_args(lhs, arg, args);
|
||||||
expr_ref rest(m_manager);
|
expr_ref rest(m_manager);
|
||||||
|
@ -842,34 +844,34 @@ void macro_util::collect_arith_macro_candidates(expr * atom, unsigned num_decls,
|
||||||
/**
|
/**
|
||||||
\brief Collect macro candidates for atom \c atom.
|
\brief Collect macro candidates for atom \c atom.
|
||||||
The candidates are stored in \c r.
|
The candidates are stored in \c r.
|
||||||
|
|
||||||
The following post-condition holds:
|
The following post-condition holds:
|
||||||
|
|
||||||
for each i in [0, r.size() - 1]
|
for each i in [0, r.size() - 1]
|
||||||
we have a conditional macro of the form
|
we have a conditional macro of the form
|
||||||
|
|
||||||
r.get_cond(i) IMPLIES f(x_1, ..., x_n) = r.get_def(i)
|
r.get_cond(i) IMPLIES f(x_1, ..., x_n) = r.get_def(i)
|
||||||
|
|
||||||
where
|
where
|
||||||
f == r.get_fs(i) .., x_n), f is uninterpreted and x_1, ..., x_n are variables.
|
f == r.get_fs(i) .., x_n), f is uninterpreted and x_1, ..., x_n are variables.
|
||||||
r.get_cond(i) and r.get_defs(i) do not contain f or variables not in {x_1, ..., x_n}
|
r.get_cond(i) and r.get_defs(i) do not contain f or variables not in {x_1, ..., x_n}
|
||||||
|
|
||||||
The idea is to use r.get_defs(i) as the interpretation for f in a model M whenever r.get_cond(i)
|
The idea is to use r.get_defs(i) as the interpretation for f in a model M whenever r.get_cond(i)
|
||||||
|
|
||||||
Given a model M and values { v_1, ..., v_n }
|
Given a model M and values { v_1, ..., v_n }
|
||||||
Let M' be M{x_1 -> v_1, ..., v_n -> v_n}
|
Let M' be M{x_1 -> v_1, ..., v_n -> v_n}
|
||||||
|
|
||||||
Note that M'(f(x_1, ..., x_n)) = M(f)(v_1, ..., v_n)
|
Note that M'(f(x_1, ..., x_n)) = M(f)(v_1, ..., v_n)
|
||||||
|
|
||||||
Then, IF we have that M(f)(v_1, ..., v_n) = M'(r.get_def(i)) AND
|
Then, IF we have that M(f)(v_1, ..., v_n) = M'(r.get_def(i)) AND
|
||||||
M'(r.get_cond(i)) = true
|
M'(r.get_cond(i)) = true
|
||||||
THEN M'(atom) = true
|
THEN M'(atom) = true
|
||||||
|
|
||||||
That is, if the conditional macro is used then the atom is satisfied when M'(r.get_cond(i)) = true
|
That is, if the conditional macro is used then the atom is satisfied when M'(r.get_cond(i)) = true
|
||||||
|
|
||||||
IF r.is_ineq(i) = false, then
|
IF r.is_ineq(i) = false, then
|
||||||
M(f)(v_1, ..., v_n) ***MUST BE*** M'(r.get_def(i)) whenever M'(r.get_cond(i)) = true
|
M(f)(v_1, ..., v_n) ***MUST BE*** M'(r.get_def(i)) whenever M'(r.get_cond(i)) = true
|
||||||
|
|
||||||
IF r.satisfy_atom(i) = true, then we have the stronger property:
|
IF r.satisfy_atom(i) = true, then we have the stronger property:
|
||||||
|
|
||||||
Then, IF we have that (M'(r.get_cond(i)) = true IMPLIES M(f)(v_1, ..., v_n) = M'(r.get_def(i)))
|
Then, IF we have that (M'(r.get_cond(i)) = true IMPLIES M(f)(v_1, ..., v_n) = M'(r.get_def(i)))
|
||||||
|
@ -878,8 +880,8 @@ void macro_util::collect_arith_macro_candidates(expr * atom, unsigned num_decls,
|
||||||
void macro_util::collect_macro_candidates_core(expr * atom, unsigned num_decls, macro_candidates & r) {
|
void macro_util::collect_macro_candidates_core(expr * atom, unsigned num_decls, macro_candidates & r) {
|
||||||
expr* lhs, *rhs;
|
expr* lhs, *rhs;
|
||||||
if (m_manager.is_eq(atom, lhs, rhs) || m_manager.is_iff(atom, lhs, rhs)) {
|
if (m_manager.is_eq(atom, lhs, rhs) || m_manager.is_iff(atom, lhs, rhs)) {
|
||||||
if (is_quasi_macro_head(lhs, num_decls) &&
|
if (is_quasi_macro_head(lhs, num_decls) &&
|
||||||
!is_forbidden(to_app(lhs)->get_decl()) &&
|
!is_forbidden(to_app(lhs)->get_decl()) &&
|
||||||
!occurs(to_app(lhs)->get_decl(), rhs) &&
|
!occurs(to_app(lhs)->get_decl(), rhs) &&
|
||||||
!rest_contains_decl(to_app(lhs)->get_decl(), atom)) {
|
!rest_contains_decl(to_app(lhs)->get_decl(), atom)) {
|
||||||
expr_ref cond(m_manager);
|
expr_ref cond(m_manager);
|
||||||
|
@ -889,9 +891,9 @@ void macro_util::collect_macro_candidates_core(expr * atom, unsigned num_decls,
|
||||||
else if (is_hint_atom(lhs, rhs)) {
|
else if (is_hint_atom(lhs, rhs)) {
|
||||||
insert_quasi_macro(to_app(lhs), num_decls, rhs, 0, false, true, true, r);
|
insert_quasi_macro(to_app(lhs), num_decls, rhs, 0, false, true, true, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_quasi_macro_head(rhs, num_decls) &&
|
if (is_quasi_macro_head(rhs, num_decls) &&
|
||||||
!is_forbidden(to_app(rhs)->get_decl()) &&
|
!is_forbidden(to_app(rhs)->get_decl()) &&
|
||||||
!occurs(to_app(rhs)->get_decl(), lhs) &&
|
!occurs(to_app(rhs)->get_decl(), lhs) &&
|
||||||
!rest_contains_decl(to_app(rhs)->get_decl(), atom)) {
|
!rest_contains_decl(to_app(rhs)->get_decl(), atom)) {
|
||||||
expr_ref cond(m_manager);
|
expr_ref cond(m_manager);
|
||||||
|
|
|
@ -1568,6 +1568,9 @@ void cmd_context::validate_model() {
|
||||||
// If r contains as_array/store/map/const expressions, then we do not generate the error.
|
// If r contains as_array/store/map/const expressions, then we do not generate the error.
|
||||||
// TODO: improve evaluator for model expressions.
|
// TODO: improve evaluator for model expressions.
|
||||||
// Note that, if "a" evaluates to false, then the error will be generated.
|
// Note that, if "a" evaluates to false, then the error will be generated.
|
||||||
|
if (has_quantifiers(r)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
for_each_expr(contains_array, r);
|
for_each_expr(contains_array, r);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ Revision History:
|
||||||
#include"ast_smt2_pp.h"
|
#include"ast_smt2_pp.h"
|
||||||
|
|
||||||
namespace smt {
|
namespace smt {
|
||||||
|
|
||||||
quantifier_manager_plugin * mk_default_plugin();
|
quantifier_manager_plugin * mk_default_plugin();
|
||||||
|
|
||||||
struct quantifier_manager::imp {
|
struct quantifier_manager::imp {
|
||||||
|
@ -40,7 +40,7 @@ namespace smt {
|
||||||
ptr_vector<quantifier> m_quantifiers;
|
ptr_vector<quantifier> m_quantifiers;
|
||||||
scoped_ptr<quantifier_manager_plugin> m_plugin;
|
scoped_ptr<quantifier_manager_plugin> m_plugin;
|
||||||
unsigned m_num_instances;
|
unsigned m_num_instances;
|
||||||
|
|
||||||
imp(quantifier_manager & wrapper, context & ctx, smt_params & p, quantifier_manager_plugin * plugin):
|
imp(quantifier_manager & wrapper, context & ctx, smt_params & p, quantifier_manager_plugin * plugin):
|
||||||
m_wrapper(wrapper),
|
m_wrapper(wrapper),
|
||||||
m_context(ctx),
|
m_context(ctx),
|
||||||
|
@ -85,7 +85,7 @@ namespace smt {
|
||||||
out << max_generation << " : " << max_cost << "\n";
|
out << max_generation << " : " << max_cost << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void del(quantifier * q) {
|
void del(quantifier * q) {
|
||||||
if (m_params.m_qi_profile) {
|
if (m_params.m_qi_profile) {
|
||||||
display_stats(verbose_stream(), q);
|
display_stats(verbose_stream(), q);
|
||||||
|
@ -99,15 +99,15 @@ namespace smt {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_shared(enode * n) const {
|
bool is_shared(enode * n) const {
|
||||||
return m_plugin->is_shared(n);
|
return m_plugin->is_shared(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool add_instance(quantifier * q, app * pat,
|
bool add_instance(quantifier * q, app * pat,
|
||||||
unsigned num_bindings,
|
unsigned num_bindings,
|
||||||
enode * const * bindings,
|
enode * const * bindings,
|
||||||
unsigned max_generation,
|
unsigned max_generation,
|
||||||
unsigned min_top_generation,
|
unsigned min_top_generation,
|
||||||
unsigned max_top_generation,
|
unsigned max_top_generation,
|
||||||
ptr_vector<enode> & used_enodes) {
|
ptr_vector<enode> & used_enodes) {
|
||||||
max_generation = std::max(max_generation, get_generation(q));
|
max_generation = std::max(max_generation, get_generation(q));
|
||||||
if (m_num_instances > m_params.m_qi_max_instances)
|
if (m_num_instances > m_params.m_qi_max_instances)
|
||||||
|
@ -136,7 +136,7 @@ namespace smt {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_search_eh() {
|
void init_search_eh() {
|
||||||
m_num_instances = 0;
|
m_num_instances = 0;
|
||||||
ptr_vector<quantifier>::iterator it2 = m_quantifiers.begin();
|
ptr_vector<quantifier>::iterator it2 = m_quantifiers.begin();
|
||||||
|
@ -149,7 +149,7 @@ namespace smt {
|
||||||
m_plugin->init_search_eh();
|
m_plugin->init_search_eh();
|
||||||
TRACE("smt_params", m_params.display(tout); );
|
TRACE("smt_params", m_params.display(tout); );
|
||||||
}
|
}
|
||||||
|
|
||||||
void assign_eh(quantifier * q) {
|
void assign_eh(quantifier * q) {
|
||||||
m_plugin->assign_eh(q);
|
m_plugin->assign_eh(q);
|
||||||
}
|
}
|
||||||
|
@ -175,7 +175,7 @@ namespace smt {
|
||||||
m_plugin->pop(num_scopes);
|
m_plugin->pop(num_scopes);
|
||||||
m_qi_queue.pop_scope(num_scopes);
|
m_qi_queue.pop_scope(num_scopes);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool can_propagate() {
|
bool can_propagate() {
|
||||||
return m_qi_queue.has_work() || m_plugin->can_propagate();
|
return m_qi_queue.has_work() || m_plugin->can_propagate();
|
||||||
}
|
}
|
||||||
|
@ -184,7 +184,7 @@ namespace smt {
|
||||||
m_plugin->propagate();
|
m_plugin->propagate();
|
||||||
m_qi_queue.instantiate();
|
m_qi_queue.instantiate();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool check_quantifier(quantifier* q) {
|
bool check_quantifier(quantifier* q) {
|
||||||
return m_context.is_relevant(q) && m_context.get_assignment(q) == l_true; // TBD: && !m_context->get_manager().is_rec_fun_def(q);
|
return m_context.is_relevant(q) && m_context.get_assignment(q) == l_true; // TBD: && !m_context->get_manager().is_rec_fun_def(q);
|
||||||
}
|
}
|
||||||
|
@ -251,7 +251,7 @@ namespace smt {
|
||||||
quantifier_manager::~quantifier_manager() {
|
quantifier_manager::~quantifier_manager() {
|
||||||
dealloc(m_imp);
|
dealloc(m_imp);
|
||||||
}
|
}
|
||||||
|
|
||||||
context & quantifier_manager::get_context() const {
|
context & quantifier_manager::get_context() const {
|
||||||
return m_imp->m_context;
|
return m_imp->m_context;
|
||||||
}
|
}
|
||||||
|
@ -285,16 +285,16 @@ namespace smt {
|
||||||
return m_imp->get_generation(q);
|
return m_imp->get_generation(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool quantifier_manager::add_instance(quantifier * q, app * pat,
|
bool quantifier_manager::add_instance(quantifier * q, app * pat,
|
||||||
unsigned num_bindings,
|
unsigned num_bindings,
|
||||||
enode * const * bindings,
|
enode * const * bindings,
|
||||||
unsigned max_generation,
|
unsigned max_generation,
|
||||||
unsigned min_top_generation,
|
unsigned min_top_generation,
|
||||||
unsigned max_top_generation,
|
unsigned max_top_generation,
|
||||||
ptr_vector<enode> & used_enodes) {
|
ptr_vector<enode> & used_enodes) {
|
||||||
return m_imp->add_instance(q, pat, num_bindings, bindings, max_generation, min_top_generation, max_generation, used_enodes);
|
return m_imp->add_instance(q, pat, num_bindings, bindings, max_generation, min_top_generation, max_generation, used_enodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool quantifier_manager::add_instance(quantifier * q, unsigned num_bindings, enode * const * bindings, unsigned generation) {
|
bool quantifier_manager::add_instance(quantifier * q, unsigned num_bindings, enode * const * bindings, unsigned generation) {
|
||||||
ptr_vector<enode> tmp;
|
ptr_vector<enode> tmp;
|
||||||
return add_instance(q, 0, num_bindings, bindings, generation, generation, generation, tmp);
|
return add_instance(q, 0, num_bindings, bindings, generation, generation, generation, tmp);
|
||||||
|
@ -347,7 +347,7 @@ namespace smt {
|
||||||
quantifier_manager::check_model_result quantifier_manager::check_model(proto_model * m, obj_map<enode, app *> const & root2value) {
|
quantifier_manager::check_model_result quantifier_manager::check_model(proto_model * m, obj_map<enode, app *> const & root2value) {
|
||||||
return m_imp->check_model(m, root2value);
|
return m_imp->check_model(m, root2value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void quantifier_manager::push() {
|
void quantifier_manager::push() {
|
||||||
m_imp->push();
|
m_imp->push();
|
||||||
}
|
}
|
||||||
|
@ -367,7 +367,7 @@ namespace smt {
|
||||||
plugin->set_manager(*this);
|
plugin->set_manager(*this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void quantifier_manager::display(std::ostream & out) const {
|
void quantifier_manager::display(std::ostream & out) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,12 +382,12 @@ namespace smt {
|
||||||
m_imp->display_stats(out, q);
|
m_imp->display_stats(out, q);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr_vector<quantifier>::const_iterator quantifier_manager::begin_quantifiers() const {
|
ptr_vector<quantifier>::const_iterator quantifier_manager::begin_quantifiers() const {
|
||||||
return m_imp->m_quantifiers.begin();
|
return m_imp->m_quantifiers.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr_vector<quantifier>::const_iterator quantifier_manager::end_quantifiers() const {
|
ptr_vector<quantifier>::const_iterator quantifier_manager::end_quantifiers() const {
|
||||||
return m_imp->m_quantifiers.end();
|
return m_imp->m_quantifiers.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
// The default plugin uses E-matching, MBQI and quick-checker
|
// The default plugin uses E-matching, MBQI and quick-checker
|
||||||
|
@ -404,13 +404,13 @@ namespace smt {
|
||||||
bool m_active;
|
bool m_active;
|
||||||
public:
|
public:
|
||||||
default_qm_plugin():
|
default_qm_plugin():
|
||||||
m_qm(0),
|
m_qm(0),
|
||||||
m_context(0),
|
m_context(0),
|
||||||
m_new_enode_qhead(0),
|
m_new_enode_qhead(0),
|
||||||
m_lazy_matching_idx(0),
|
m_lazy_matching_idx(0),
|
||||||
m_active(false) {
|
m_active(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~default_qm_plugin() {
|
virtual ~default_qm_plugin() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -434,20 +434,18 @@ namespace smt {
|
||||||
|
|
||||||
virtual bool model_based() const { return m_fparams->m_mbqi; }
|
virtual bool model_based() const { return m_fparams->m_mbqi; }
|
||||||
|
|
||||||
virtual bool mbqi_enabled(quantifier *q) const {
|
virtual bool mbqi_enabled(quantifier *q) const {
|
||||||
if(!m_fparams->m_mbqi_id) return true;
|
if (!m_fparams->m_mbqi_id) return true;
|
||||||
const symbol &s = q->get_qid();
|
const symbol &s = q->get_qid();
|
||||||
size_t len = strlen(m_fparams->m_mbqi_id);
|
size_t len = strlen(m_fparams->m_mbqi_id);
|
||||||
if(s == symbol::null || s.is_numerical())
|
if (s == symbol::null || s.is_numerical())
|
||||||
return len == 0;
|
return len == 0;
|
||||||
return strncmp(s.bare_str(),m_fparams->m_mbqi_id,len) == 0;
|
return strncmp(s.bare_str(), m_fparams->m_mbqi_id, len) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Quantifier id's must begin with the prefix specified by
|
/* Quantifier id's must begin with the prefix specified by parameter
|
||||||
parameter mbqi.id to be instantiated with MBQI. The default
|
mbqi.id to be instantiated with MBQI. The default value is the
|
||||||
value is the empty string, so all quantifiers are
|
empty string, so all quantifiers are instantiated. */
|
||||||
instantiated.
|
|
||||||
*/
|
|
||||||
virtual void add(quantifier * q) {
|
virtual void add(quantifier * q) {
|
||||||
if (m_fparams->m_mbqi && mbqi_enabled(q)) {
|
if (m_fparams->m_mbqi && mbqi_enabled(q)) {
|
||||||
m_active = true;
|
m_active = true;
|
||||||
|
@ -455,8 +453,7 @@ namespace smt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void del(quantifier * q) {
|
virtual void del(quantifier * q) { }
|
||||||
}
|
|
||||||
|
|
||||||
virtual void push() {
|
virtual void push() {
|
||||||
m_mam->push_scope();
|
m_mam->push_scope();
|
||||||
|
@ -465,7 +462,7 @@ namespace smt {
|
||||||
m_model_finder->push_scope();
|
m_model_finder->push_scope();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void pop(unsigned num_scopes) {
|
virtual void pop(unsigned num_scopes) {
|
||||||
m_mam->pop_scope(num_scopes);
|
m_mam->pop_scope(num_scopes);
|
||||||
m_lazy_mam->pop_scope(num_scopes);
|
m_lazy_mam->pop_scope(num_scopes);
|
||||||
|
@ -473,7 +470,7 @@ namespace smt {
|
||||||
m_model_finder->pop_scope(num_scopes);
|
m_model_finder->pop_scope(num_scopes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void init_search_eh() {
|
virtual void init_search_eh() {
|
||||||
m_lazy_matching_idx = 0;
|
m_lazy_matching_idx = 0;
|
||||||
if (m_fparams->m_mbqi) {
|
if (m_fparams->m_mbqi) {
|
||||||
|
@ -516,7 +513,7 @@ namespace smt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool use_ematching() const {
|
bool use_ematching() const {
|
||||||
return m_fparams->m_ematching && !m_qm->empty();
|
return m_fparams->m_ematching && !m_qm->empty();
|
||||||
}
|
}
|
||||||
|
@ -538,7 +535,7 @@ namespace smt {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void restart_eh() {
|
virtual void restart_eh() {
|
||||||
if (m_fparams->m_mbqi) {
|
if (m_fparams->m_mbqi) {
|
||||||
m_model_finder->restart_eh();
|
m_model_finder->restart_eh();
|
||||||
m_model_checker->restart_eh();
|
m_model_checker->restart_eh();
|
||||||
}
|
}
|
||||||
|
@ -613,7 +610,7 @@ namespace smt {
|
||||||
}
|
}
|
||||||
return FC_DONE;
|
return FC_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
quantifier_manager_plugin * mk_default_plugin() {
|
quantifier_manager_plugin * mk_default_plugin() {
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace smt {
|
||||||
public:
|
public:
|
||||||
quantifier_manager(context & ctx, smt_params & fp, params_ref const & p);
|
quantifier_manager(context & ctx, smt_params & fp, params_ref const & p);
|
||||||
~quantifier_manager();
|
~quantifier_manager();
|
||||||
|
|
||||||
context & get_context() const;
|
context & get_context() const;
|
||||||
|
|
||||||
void set_plugin(quantifier_manager_plugin * plugin);
|
void set_plugin(quantifier_manager_plugin * plugin);
|
||||||
|
@ -51,12 +51,12 @@ namespace smt {
|
||||||
quantifier_stat * get_stat(quantifier * q) const;
|
quantifier_stat * get_stat(quantifier * q) const;
|
||||||
unsigned get_generation(quantifier * q) const;
|
unsigned get_generation(quantifier * q) const;
|
||||||
|
|
||||||
bool add_instance(quantifier * q, app * pat,
|
bool add_instance(quantifier * q, app * pat,
|
||||||
unsigned num_bindings,
|
unsigned num_bindings,
|
||||||
enode * const * bindings,
|
enode * const * bindings,
|
||||||
unsigned max_generation,
|
unsigned max_generation,
|
||||||
unsigned min_top_generation,
|
unsigned min_top_generation,
|
||||||
unsigned max_top_generation,
|
unsigned max_top_generation,
|
||||||
ptr_vector<enode> & used_enodes);
|
ptr_vector<enode> & used_enodes);
|
||||||
bool add_instance(quantifier * q, unsigned num_bindings, enode * const * bindings, unsigned generation = 0);
|
bool add_instance(quantifier * q, unsigned num_bindings, enode * const * bindings, unsigned generation = 0);
|
||||||
|
|
||||||
|
@ -78,11 +78,11 @@ namespace smt {
|
||||||
bool mbqi_enabled(quantifier *q) const; // can mbqi instantiate this quantifier?
|
bool mbqi_enabled(quantifier *q) const; // can mbqi instantiate this quantifier?
|
||||||
void adjust_model(proto_model * m);
|
void adjust_model(proto_model * m);
|
||||||
check_model_result check_model(proto_model * m, obj_map<enode, app *> const & root2value);
|
check_model_result check_model(proto_model * m, obj_map<enode, app *> const & root2value);
|
||||||
|
|
||||||
void push();
|
void push();
|
||||||
void pop(unsigned num_scopes);
|
void pop(unsigned num_scopes);
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
void display(std::ostream & out) const;
|
void display(std::ostream & out) const;
|
||||||
void display_stats(std::ostream & out, quantifier * q) const;
|
void display_stats(std::ostream & out, quantifier * q) const;
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ namespace smt {
|
||||||
public:
|
public:
|
||||||
quantifier_manager_plugin() {}
|
quantifier_manager_plugin() {}
|
||||||
virtual ~quantifier_manager_plugin() {}
|
virtual ~quantifier_manager_plugin() {}
|
||||||
|
|
||||||
virtual void set_manager(quantifier_manager & qm) = 0;
|
virtual void set_manager(quantifier_manager & qm) = 0;
|
||||||
|
|
||||||
virtual quantifier_manager_plugin * mk_fresh() = 0;
|
virtual quantifier_manager_plugin * mk_fresh() = 0;
|
||||||
|
@ -106,7 +106,7 @@ namespace smt {
|
||||||
virtual void del(quantifier * q) = 0;
|
virtual void del(quantifier * q) = 0;
|
||||||
|
|
||||||
virtual bool is_shared(enode * n) const = 0;
|
virtual bool is_shared(enode * n) const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief This method is invoked whenever q is assigned to true.
|
\brief This method is invoked whenever q is assigned to true.
|
||||||
*/
|
*/
|
||||||
|
@ -131,9 +131,9 @@ namespace smt {
|
||||||
\brief This method is invoked whenever the solver restarts.
|
\brief This method is invoked whenever the solver restarts.
|
||||||
*/
|
*/
|
||||||
virtual void restart_eh() = 0;
|
virtual void restart_eh() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Return true if the quantifier_manager can propagate information
|
\brief Return true if the quantifier_manager can propagate information
|
||||||
information back into the core.
|
information back into the core.
|
||||||
*/
|
*/
|
||||||
virtual bool can_propagate() const = 0;
|
virtual bool can_propagate() const = 0;
|
||||||
|
@ -143,11 +143,11 @@ namespace smt {
|
||||||
\brief Return true if the plugin is "model based"
|
\brief Return true if the plugin is "model based"
|
||||||
*/
|
*/
|
||||||
virtual bool model_based() const = 0;
|
virtual bool model_based() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Is "model based" instantiate allowed to instantiate this quantifier?
|
\brief Is "model based" instantiate allowed to instantiate this quantifier?
|
||||||
*/
|
*/
|
||||||
virtual bool mbqi_enabled(quantifier *q) const {return true;}
|
virtual bool mbqi_enabled(quantifier *q) const {return true;}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Give a change to the plugin to adjust the interpretation of unintepreted functions.
|
\brief Give a change to the plugin to adjust the interpretation of unintepreted functions.
|
||||||
|
@ -161,10 +161,10 @@ namespace smt {
|
||||||
It also provides a mapping from enodes to their interpretations.
|
It also provides a mapping from enodes to their interpretations.
|
||||||
*/
|
*/
|
||||||
virtual quantifier_manager::check_model_result check_model(proto_model * m, obj_map<enode, app *> const & root2value) = 0;
|
virtual quantifier_manager::check_model_result check_model(proto_model * m, obj_map<enode, app *> const & root2value) = 0;
|
||||||
|
|
||||||
virtual void push() = 0;
|
virtual void push() = 0;
|
||||||
virtual void pop(unsigned num_scopes) = 0;
|
virtual void pop(unsigned num_scopes) = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue