3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-07-19 19:02:02 +00:00

Merge remote-tracking branch 'upstream/master' into HEAD

This commit is contained in:
Murphy Berzish 2017-10-30 13:55:31 -04:00
commit a8d025f5b4
1661 changed files with 45439 additions and 28238 deletions

View file

@ -17,15 +17,31 @@ env:
############################################################################### ###############################################################################
# Ubuntu 16.04 LTS # Ubuntu 16.04 LTS
############################################################################### ###############################################################################
# 64-bit UBSan Debug build
- LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/clang-3.9 CXX_COMPILER=/usr/bin/clang++-3.9 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=Debug UBSAN_BUILD=1 RUN_UNIT_TESTS=SKIP
# 64-bit ASan Debug build
- LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/clang-3.9 CXX_COMPILER=/usr/bin/clang++-3.9 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=Debug ASAN_BUILD=1 RUN_UNIT_TESTS=SKIP ASAN_DSO=/usr/lib/clang/3.9/lib/linux/libclang_rt.asan-x86_64.so
# Build for running unit tests under ASan/UBSan
# FIXME: We should really be doing a debug build but the unit tests run too
# slowly when we do that.
- LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/clang-3.9 CXX_COMPILER=/usr/bin/clang++-3.9 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=RelWithDebInfo ASAN_BUILD=1 RUN_UNIT_TESTS=BUILD_AND_RUN ASAN_DSO=/usr/lib/clang/3.9/lib/linux/libclang_rt.asan-x86_64.so UBSAN_BUILD=1 RUN_API_EXAMPLES=0 RUN_SYSTEM_TESTS=0 DOTNET_BINDINGS=0 JAVA_BINDINGS=0 PYTHON_BINDINGS=0
# 64-bit GCC 5.4 RelWithDebInfo # 64-bit GCC 5.4 RelWithDebInfo
- LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/gcc-5 CXX_COMPILER=/usr/bin/g++-5 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=RelWithDebInfo - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/gcc-5 CXX_COMPILER=/usr/bin/g++-5 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=RelWithDebInfo
# 64-bit Clang 3.9 RelWithDebInfo # 64-bit Clang 3.9 RelWithDebInfo
- LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/clang-3.9 CXX_COMPILER=/usr/bin/clang++-3.9 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=RelWithDebInfo - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/clang-3.9 CXX_COMPILER=/usr/bin/clang++-3.9 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=RelWithDebInfo
# Debug builds
#
# Note the unit tests for the debug builds are compiled but **not**
# executed. This is because the debug build of unit tests takes a large
# amount of time to execute compared to the optimized builds. The hope is
# that just running the optimized unit tests is sufficient.
#
# 64-bit GCC 5.4 Debug # 64-bit GCC 5.4 Debug
- LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/gcc-5 CXX_COMPILER=/usr/bin/g++-5 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=Debug - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/gcc-5 CXX_COMPILER=/usr/bin/g++-5 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=Debug RUN_UNIT_TESTS=BUILD_ONLY
# 64-bit Clang Debug # 64-bit Clang Debug
- LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/clang-3.9 CXX_COMPILER=/usr/bin/clang++-3.9 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=Debug - LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/clang-3.9 CXX_COMPILER=/usr/bin/clang++-3.9 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=Debug RUN_UNIT_TESTS=BUILD_ONLY
# 32-bit GCC 5.4 RelWithDebInfo # 32-bit GCC 5.4 RelWithDebInfo
- LINUX_BASE=ubuntu32_16.04 C_COMPILER=/usr/bin/gcc-5 CXX_COMPILER=/usr/bin/g++-5 TARGET_ARCH=i686 Z3_BUILD_TYPE=RelWithDebInfo - LINUX_BASE=ubuntu32_16.04 C_COMPILER=/usr/bin/gcc-5 CXX_COMPILER=/usr/bin/g++-5 TARGET_ARCH=i686 Z3_BUILD_TYPE=RelWithDebInfo
@ -57,12 +73,24 @@ env:
# 64-bit GCC 4.8 RelWithDebInfo # 64-bit GCC 4.8 RelWithDebInfo
- LINUX_BASE=ubuntu_14.04 C_COMPILER=/usr/bin/gcc-4.8 CXX_COMPILER=/usr/bin/g++-4.8 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=RelWithDebInfo - LINUX_BASE=ubuntu_14.04 C_COMPILER=/usr/bin/gcc-4.8 CXX_COMPILER=/usr/bin/g++-4.8 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=RelWithDebInfo
# 64-bit GCC 4.8 Debug # 64-bit GCC 4.8 Debug
- LINUX_BASE=ubuntu_14.04 C_COMPILER=/usr/bin/gcc-4.8 CXX_COMPILER=/usr/bin/g++-4.8 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=Debug - LINUX_BASE=ubuntu_14.04 C_COMPILER=/usr/bin/gcc-4.8 CXX_COMPILER=/usr/bin/g++-4.8 TARGET_ARCH=x86_64 Z3_BUILD_TYPE=Debug RUN_UNIT_TESTS=BUILD_ONLY
# TODO: OSX support # macOS (a.k.a OSX) support
#matrix: matrix:
# include: include:
# - os: osx # For now just test a single configuration. macOS builds on TravisCI are
# osx_image: xcode 8.2 # very slow so we should keep the number of configurations we test on this
# OS to a minimum.
- os: osx
osx_image: xcode8.3
# Note: Apple Clang does not support OpenMP
env: Z3_BUILD_TYPE=RelWithDebInfo USE_OPENMP=0
script: script:
- contrib/ci/scripts/travis_ci_entry_point.sh # Use `travis_wait` when doing LTO builds because this configuration will
# have long link times during which it will not show any output which
# TravisCI might kill due to perceived inactivity.
- if [ "X${USE_LTO}" = "X1" ]; then
travis_wait 45 contrib/ci/scripts/travis_ci_entry_point.sh || exit 1;
else
contrib/ci/scripts/travis_ci_entry_point.sh || exit 1;
fi

View file

@ -234,22 +234,18 @@ if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
if ("${TARGET_ARCHITECTURE}" STREQUAL "x86_64") if ("${TARGET_ARCHITECTURE}" STREQUAL "x86_64")
list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_USE_THREAD_LOCAL") list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_USE_THREAD_LOCAL")
endif() endif()
z3_add_cxx_flag("-fno-strict-aliasing" REQUIRED)
elseif ("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") elseif ("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
# Does OSX really not need any special flags? # Does OSX really not need any special flags?
message(STATUS "Platform: Darwin") message(STATUS "Platform: Darwin")
elseif ("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD") elseif ("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD")
message(STATUS "Platform: FreeBSD") message(STATUS "Platform: FreeBSD")
list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_FREEBSD_") list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_FREEBSD_")
z3_add_cxx_flag("-fno-strict-aliasing" REQUIRED)
elseif ("${CMAKE_SYSTEM_NAME}" MATCHES "OpenBSD") elseif ("${CMAKE_SYSTEM_NAME}" MATCHES "OpenBSD")
message(STATUS "Platform: OpenBSD") message(STATUS "Platform: OpenBSD")
list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_OPENBSD_") list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_OPENBSD_")
z3_add_cxx_flag("-fno-strict-aliasing" REQUIRED)
elseif (CYGWIN) elseif (CYGWIN)
message(STATUS "Platform: Cygwin") message(STATUS "Platform: Cygwin")
list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_CYGWIN") list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_CYGWIN")
z3_add_cxx_flag("-fno-strict-aliasing" REQUIRED)
elseif (WIN32) elseif (WIN32)
message(STATUS "Platform: Windows") message(STATUS "Platform: Windows")
list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_WINDOWS") list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_WINDOWS")
@ -257,8 +253,10 @@ else()
message(FATAL_ERROR "Platform \"${CMAKE_SYSTEM_NAME}\" not recognised") message(FATAL_ERROR "Platform \"${CMAKE_SYSTEM_NAME}\" not recognised")
endif() endif()
list(APPEND Z3_COMPONENT_EXTRA_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/src") list(APPEND Z3_COMPONENT_EXTRA_INCLUDE_DIRS
"${CMAKE_BINARY_DIR}/src"
"${CMAKE_SOURCE_DIR}/src"
)
################################################################################ ################################################################################
# GNU multiple precision library support # GNU multiple precision library support
################################################################################ ################################################################################
@ -279,33 +277,37 @@ endif()
################################################################################ ################################################################################
# OpenMP support # OpenMP support
################################################################################ ################################################################################
option(USE_OPENMP "Use OpenMP" ON) find_package(OpenMP)
set(OPENMP_FOUND FALSE)
if (USE_OPENMP)
# Because this is on by default we make the configure succeed with a warning
# if OpenMP support is not detected.
find_package(OpenMP)
if (NOT OPENMP_FOUND)
message(WARNING "OpenMP support was requested but your compiler doesn't support it")
endif()
endif()
if (OPENMP_FOUND) if (OPENMP_FOUND)
list(APPEND Z3_COMPONENT_CXX_FLAGS ${OpenMP_CXX_FLAGS}) set(USE_OPENMP_DEFAULT ON)
# GCC and Clang need to have additional flags passed to the linker. else()
# We can't do ``target_link_libraries(libz3 INTERFACE ${OpenMP_CXX_FLAGS})`` set(USE_OPENMP_DEFAULT OFF)
# because ``/openmp`` is interpreted as file name rather than a linker endif()
# flag by MSVC and breaks the build # By setting `USE_OPENMP` this way configuration will fail during the first
if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") OR # configure if the user explicitly passes `-DUSE_OPENMP=ON` and the compiler
("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")) # does not support OpenMP. However if the option is not set explicitly during
list(APPEND Z3_DEPENDENT_EXTRA_CXX_LINK_FLAGS ${OpenMP_CXX_FLAGS}) # the first configure OpenMP support will be automatically enabled/disabled
endif() # depending on whether OpenMP is available.
unset(CMAKE_REQUIRED_FLAGS) option(USE_OPENMP "Use OpenMP" ${USE_OPENMP_DEFAULT})
message(STATUS "Using OpenMP")
if (USE_OPENMP)
if (NOT OPENMP_FOUND)
message(FATAL_ERROR "USE_OPENMP is ON but your compiler does not support OpenMP")
endif()
list(APPEND Z3_COMPONENT_CXX_FLAGS ${OpenMP_CXX_FLAGS})
# GCC and Clang need to have additional flags passed to the linker.
# We can't do ``target_link_libraries(libz3 INTERFACE ${OpenMP_CXX_FLAGS})``
# because ``/openmp`` is interpreted as file name rather than a linker
# flag by MSVC and breaks the build
if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") OR
("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU"))
list(APPEND Z3_DEPENDENT_EXTRA_CXX_LINK_FLAGS ${OpenMP_CXX_FLAGS})
endif()
message(STATUS "Using OpenMP")
else() else()
list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_NO_OMP_") list(APPEND Z3_COMPONENT_CXX_DEFINES "-D_NO_OMP_")
message(STATUS "Not using OpenMP") message(STATUS "Not using OpenMP")
set(USE_OPENMP OFF CACHE BOOL "Use OpenMP" FORCE)
endif() endif()
################################################################################ ################################################################################
@ -411,6 +413,38 @@ endif()
################################################################################ ################################################################################
include(${CMAKE_SOURCE_DIR}/cmake/compiler_lto.cmake) include(${CMAKE_SOURCE_DIR}/cmake/compiler_lto.cmake)
################################################################################
# Control flow integrity
################################################################################
option(ENABLE_CFI "Enable control flow integrity checking" OFF)
if (ENABLE_CFI)
set(build_types_with_cfi "RELEASE" "RELWITHDEBINFO")
if (NOT LINK_TIME_OPTIMIZATION)
message(FATAL_ERROR "Cannot enable control flow integrity checking without link-time optimization."
"You should set LINK_TIME_OPTIMIZATION to ON or ENABLE_CFI to OFF.")
endif()
if (DEFINED CMAKE_CONFIGURATION_TYPES)
# Multi configuration generator
message(STATUS "Note CFI is only enabled for the following configurations: ${build_types_with_cfi}")
# No need for else because this is the same as the set that LTO requires.
endif()
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
z3_add_cxx_flag("-fsanitize=cfi" REQUIRED)
z3_add_cxx_flag("-fsanitize-cfi-cross-dso" REQUIRED)
elseif ("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC")
z3_add_cxx_flag("/guard:cf" REQUIRED)
message(STATUS "Enabling CFI for MSVC")
foreach (_build_type ${build_types_with_cfi})
message(STATUS "Enabling CFI for MSVC")
string(APPEND CMAKE_EXE_LINKER_FLAGS_${_build_type} " /GUARD:CF")
string(APPEND CMAKE_SHARED_LINKER_FLAGS_${_build_type} " /GUARD:CF")
endforeach()
else()
message(FATAL_ERROR "Can't enable control flow integrity for compiler \"${CMAKE_CXX_COMPILER_ID}\"."
"You should set ENABLE_CFI to OFF or use Clang or MSVC to compile.")
endif()
endif()
################################################################################ ################################################################################
# MSVC specific flags inherited from old build system # MSVC specific flags inherited from old build system
################################################################################ ################################################################################

View file

@ -265,9 +265,12 @@ The following useful options can be passed to CMake whilst configuring.
* ``ALWAYS_BUILD_DOCS`` - BOOL. If set to ``TRUE`` and ``BUILD_DOCUMENTATION`` is ``TRUE`` then documentation for API bindings will always be built. * ``ALWAYS_BUILD_DOCS`` - BOOL. If set to ``TRUE`` and ``BUILD_DOCUMENTATION`` is ``TRUE`` then documentation for API bindings will always be built.
Disabling this is useful for faster incremental builds. The documentation can be manually built by invoking the ``api_docs`` target. Disabling this is useful for faster incremental builds. The documentation can be manually built by invoking the ``api_docs`` target.
* ``LINK_TIME_OPTIMIZATION`` - BOOL. If set to ``TRUE`` link time optimization will be enabled. * ``LINK_TIME_OPTIMIZATION`` - BOOL. If set to ``TRUE`` link time optimization will be enabled.
* ``ENABLE_CFI`` - BOOL. If set to ``TRUE`` will enable Control Flow Integrity security checks. This is only supported by MSVC and Clang and will
fail on other compilers. This requires LINK_TIME_OPTIMIZATION to also be enabled.
* ``API_LOG_SYNC`` - BOOL. If set to ``TRUE`` will enable experimental API log sync feature. * ``API_LOG_SYNC`` - BOOL. If set to ``TRUE`` will enable experimental API log sync feature.
* ``WARNINGS_AS_ERRORS`` - STRING. If set to ``TRUE`` compiler warnings will be treated as errors. If set to ``False`` compiler warnings will not be treated as errors. * ``WARNINGS_AS_ERRORS`` - STRING. If set to ``TRUE`` compiler warnings will be treated as errors. If set to ``False`` compiler warnings will not be treated as errors.
If set to ``SERIOUS_ONLY`` a subset of compiler warnings will be treated as errors. If set to ``SERIOUS_ONLY`` a subset of compiler warnings will be treated as errors.
* ``Z3_C_EXAMPLES_FORCE_CXX_LINKER`` - BOOL. If set to ``TRUE`` the C API examples will request that the C++ linker is used rather than the C linker.
On the command line these can be passed to ``cmake`` using the ``-D`` option. In ``ccmake`` and ``cmake-gui`` these can be set in the user interface. On the command line these can be passed to ``cmake`` using the ``-D`` option. In ``ccmake`` and ``cmake-gui`` these can be set in the user interface.

View file

@ -12,9 +12,9 @@ See the [release notes](RELEASE_NOTES) for notes on various stable releases of Z
## Build status ## Build status
| Windows x86 | Windows x64 | Ubuntu x64 | Ubuntu x86 | Debian x64 | OSX | TravisCI | | Windows x86 | Windows x64 | Ubuntu x64 | Debian x64 | OSX | TravisCI |
| ----------- | ----------- | ---------- | ---------- | ---------- | --- | -------- | | ----------- | ----------- | ---------- | ---------- | --- | -------- |
[![win32-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/4/badge)](https://cz3.visualstudio.com/Z3/_build/index?definitionId=4) | [![win64-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/7/badge)](https://cz3.visualstudio.com/Z3/_build/index?definitionId=7) | [![ubuntu-x64-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/3/badge)](https://cz3.visualstudio.com/Z3/_build/index?definitionId=3) | [![ubuntu-x86-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/6/badge)](https://cz3.visualstudio.com/Z3/_build/index?definitionId=6) | [![debian-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/5/badge)](https://cz3.visualstudio.com/Z3/_build/index?definitionId=5) | [![osx-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/2/badge)](https://cz3.visualstudio.com/Z3/_build/index?definitionId=2) | [![Build Status](https://travis-ci.org/Z3Prover/z3.svg?branch=master)](https://travis-ci.org/Z3Prover/z3) [![win32-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/4/badge)](https://cz3.visualstudio.com/Z3/_build/index?definitionId=4) | [![win64-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/7/badge)](https://cz3.visualstudio.com/Z3/_build/index?definitionId=7) | [![ubuntu-x64-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/3/badge)](https://cz3.visualstudio.com/Z3/_build/index?definitionId=3) | [![debian-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/5/badge)](https://cz3.visualstudio.com/Z3/_build/index?definitionId=5) | [![osx-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/2/badge)](https://cz3.visualstudio.com/Z3/_build/index?definitionId=2) | [![Build Status](https://travis-ci.org/Z3Prover/z3.svg?branch=master)](https://travis-ci.org/Z3Prover/z3)
[1]: #building-z3-on-windows-using-visual-studio-command-prompt [1]: #building-z3-on-windows-using-visual-studio-command-prompt
[2]: #building-z3-using-make-and-gccclang [2]: #building-z3-using-make-and-gccclang
@ -124,7 +124,7 @@ utility is used to install ``Microsoft.Z3.dll`` into the
[pkg-config](http://www.freedesktop.org/wiki/Software/pkg-config/) file [pkg-config](http://www.freedesktop.org/wiki/Software/pkg-config/) file
(``Microsoft.Z3.Sharp.pc``) is also installed which allows the (``Microsoft.Z3.Sharp.pc``) is also installed which allows the
[MonoDevelop](http://www.monodevelop.com/) IDE to find the bindings. Running [MonoDevelop](http://www.monodevelop.com/) IDE to find the bindings. Running
``make uninstall`` will remove the dll from the GAC and the pkg-config file. ``make uninstall`` will remove the dll from the GAC and the ``pkg-config`` file.
See [``examples/dotnet``](examples/dotnet) for examples. See [``examples/dotnet``](examples/dotnet) for examples.
@ -170,8 +170,8 @@ If you do need to install to a non standard prefix a better approach is to use
a [Python virtual environment](https://virtualenv.readthedocs.org/en/latest/) a [Python virtual environment](https://virtualenv.readthedocs.org/en/latest/)
and install Z3 there. Python packages also work for Python3. and install Z3 there. Python packages also work for Python3.
Under Windows, recall to build inside the Visual C++ native command build environment. Under Windows, recall to build inside the Visual C++ native command build environment.
Note that the buit/python/z3 directory should be accessible from where python is used with Z3 Note that the ``build/python/z3`` directory should be accessible from where python is used with Z3
and it depends on libz3.dll to be in the path. and it depends on ``libz3.dll`` to be in the path.
```bash ```bash
virtualenv venv virtualenv venv

View file

@ -4,23 +4,55 @@
# of the git directory changes CMake will be forced to re-run. This useful # of the git directory changes CMake will be forced to re-run. This useful
# for fetching the current git hash and including it in the build. # for fetching the current git hash and including it in the build.
# #
# `GIT_DIR` is the path to the git directory (i.e. the `.git` directory) # `GIT_DOT_FILE` is the path to the git directory (i.e. the `.git` directory) or
# `.git` file used by a git worktree.
# `SUCCESS_VAR` is the name of the variable to set. It will be set to TRUE # `SUCCESS_VAR` is the name of the variable to set. It will be set to TRUE
# if the dependency was successfully added and FALSE otherwise. # if the dependency was successfully added and FALSE otherwise.
function(add_git_dir_dependency GIT_DIR SUCCESS_VAR) function(add_git_dir_dependency GIT_DOT_FILE SUCCESS_VAR)
if (NOT "${ARGC}" EQUAL 2) if (NOT "${ARGC}" EQUAL 2)
message(FATAL_ERROR "Invalid number (${ARGC}) of arguments") message(FATAL_ERROR "Invalid number (${ARGC}) of arguments")
endif() endif()
if (NOT IS_ABSOLUTE "${GIT_DIR}") if (NOT IS_ABSOLUTE "${GIT_DOT_FILE}")
message(FATAL_ERROR "GIT_DIR (\"${GIT_DIR}\") is not an absolute path") message(FATAL_ERROR "GIT_DOT_FILE (\"${GIT_DOT_FILE}\") is not an absolute path")
endif() endif()
if (NOT IS_DIRECTORY "${GIT_DIR}") if (NOT EXISTS "${GIT_DOT_FILE}")
message(FATAL_ERROR "GIT_DIR (\"${GIT_DIR}\") is not a directory") message(FATAL_ERROR "GIT_DOT_FILE (\"${GIT_DOT_FILE}\") does not exist")
endif() endif()
set(GIT_HEAD_FILE "${GIT_DIR}/HEAD") if (NOT IS_DIRECTORY "${GIT_DOT_FILE}")
# Might be a git worktree. In this case we need parse out the worktree
# git directory
file(READ "${GIT_DOT_FILE}" GIT_DOT_FILE_DATA LIMIT 512)
string(STRIP "${GIT_DOT_FILE_DATA}" GIT_DOT_FILE_DATA_STRIPPED)
if ("${GIT_DOT_FILE_DATA_STRIPPED}" MATCHES "^gitdir:[ ]*(.+)$")
# Git worktree
message(STATUS "Found git worktree")
set(GIT_WORKTREE_DIR "${CMAKE_MATCH_1}")
set(GIT_HEAD_FILE "${GIT_WORKTREE_DIR}/HEAD")
# Figure out where real git directory lives
set(GIT_COMMON_DIR_FILE "${GIT_WORKTREE_DIR}/commondir")
if (NOT EXISTS "${GIT_COMMON_DIR_FILE}")
message(FATAL_ERROR "Found git worktree dir but could not find \"${GIT_COMMON_DIR_FILE}\"")
endif()
file(READ "${GIT_COMMON_DIR_FILE}" GIT_COMMON_DIR_FILE_DATA LIMIT 512)
string(STRIP "${GIT_COMMON_DIR_FILE_DATA}" GIT_COMMON_DIR_FILE_DATA_STRIPPED)
get_filename_component(GIT_DIR "${GIT_WORKTREE_DIR}/${GIT_COMMON_DIR_FILE_DATA_STRIPPED}" ABSOLUTE)
if (NOT IS_DIRECTORY "${GIT_DIR}")
message(FATAL_ERROR "Failed to compute path to git directory from git worktree")
endif()
else()
message(FATAL_ERROR "GIT_DOT_FILE (\"${GIT_DOT_FILE}\") is not a directory or a pointer to git worktree directory")
endif()
else()
# Just a normal `.git` directory
message(STATUS "Found simple git working directory")
set(GIT_HEAD_FILE "${GIT_DOT_FILE}/HEAD")
set(GIT_DIR "${GIT_DOT_FILE}")
endif()
message(STATUS "Found git directory \"${GIT_DIR}\"")
if (NOT EXISTS "${GIT_HEAD_FILE}") if (NOT EXISTS "${GIT_HEAD_FILE}")
message(AUTHOR_WARNING "Git head file \"${GIT_HEAD_FILE}\" cannot be found") message(AUTHOR_WARNING "Git head file \"${GIT_HEAD_FILE}\" cannot be found")
set(${SUCCESS_VAR} FALSE PARENT_SCOPE) set(${SUCCESS_VAR} FALSE PARENT_SCOPE)
@ -79,24 +111,25 @@ function(add_git_dir_dependency GIT_DIR SUCCESS_VAR)
set(${SUCCESS_VAR} TRUE PARENT_SCOPE) set(${SUCCESS_VAR} TRUE PARENT_SCOPE)
endfunction() endfunction()
# get_git_head_hash(GIT_DIR OUTPUT_VAR) # get_git_head_hash(GIT_DOT_FILE OUTPUT_VAR)
# #
# Retrieve the current commit hash for a git working directory where `GIT_DIR` # Retrieve the current commit hash for a git working directory where
# is the `.git` directory in the root of the git working directory. # `GIT_DOT_FILE` is the `.git` directory or `.git` pointer file in a git
# worktree in the root of the git working directory.
# #
# `OUTPUT_VAR` should be the name of the variable to put the result in. If this # `OUTPUT_VAR` should be the name of the variable to put the result in. If this
# function fails then either a fatal error will be raised or `OUTPUT_VAR` will # function fails then either a fatal error will be raised or `OUTPUT_VAR` will
# contain a string with the suffix `NOTFOUND` which can be used in CMake `if()` # contain a string with the suffix `NOTFOUND` which can be used in CMake `if()`
# commands. # commands.
function(get_git_head_hash GIT_DIR OUTPUT_VAR) function(get_git_head_hash GIT_DOT_FILE OUTPUT_VAR)
if (NOT "${ARGC}" EQUAL 2) if (NOT "${ARGC}" EQUAL 2)
message(FATAL_ERROR "Invalid number of arguments") message(FATAL_ERROR "Invalid number of arguments")
endif() endif()
if (NOT IS_DIRECTORY "${GIT_DIR}") if (NOT EXISTS "${GIT_DOT_FILE}")
message(FATAL_ERROR "\"${GIT_DIR}\" is not a directory") message(FATAL_ERROR "\"${GIT_DOT_FILE}\" does not exist")
endif() endif()
if (NOT IS_ABSOLUTE "${GIT_DIR}") if (NOT IS_ABSOLUTE "${GIT_DOT_FILE}")
message(FATAL_ERROR \""${GIT_DIR}\" is not an absolute path") message(FATAL_ERROR \""${GIT_DOT_FILE}\" is not an absolute path")
endif() endif()
find_package(Git) find_package(Git)
# NOTE: Use `GIT_FOUND` rather than `Git_FOUND` which was only # NOTE: Use `GIT_FOUND` rather than `Git_FOUND` which was only
@ -105,7 +138,7 @@ function(get_git_head_hash GIT_DIR OUTPUT_VAR)
set(${OUTPUT_VAR} "GIT-NOTFOUND" PARENT_SCOPE) set(${OUTPUT_VAR} "GIT-NOTFOUND" PARENT_SCOPE)
return() return()
endif() endif()
get_filename_component(GIT_WORKING_DIR "${GIT_DIR}" DIRECTORY) get_filename_component(GIT_WORKING_DIR "${GIT_DOT_FILE}" DIRECTORY)
execute_process( execute_process(
COMMAND COMMAND
"${GIT_EXECUTABLE}" "${GIT_EXECUTABLE}"
@ -128,24 +161,25 @@ function(get_git_head_hash GIT_DIR OUTPUT_VAR)
set(${OUTPUT_VAR} "${Z3_GIT_HASH}" PARENT_SCOPE) set(${OUTPUT_VAR} "${Z3_GIT_HASH}" PARENT_SCOPE)
endfunction() endfunction()
# get_git_head_describe(GIT_DIR OUTPUT_VAR) # get_git_head_describe(GIT_DOT_FILE OUTPUT_VAR)
# #
# Retrieve the output of `git describe` for a git working directory where # Retrieve the output of `git describe` for a git working directory where
# `GIT_DIR` is the `.git` directory in the root of the git working directory. # `GIT_DOT_FILE` is the `.git` directory or `.git` pointer file in a git
# worktree in the root of the git working directory.
# #
# `OUTPUT_VAR` should be the name of the variable to put the result in. If this # `OUTPUT_VAR` should be the name of the variable to put the result in. If this
# function fails then either a fatal error will be raised or `OUTPUT_VAR` will # function fails then either a fatal error will be raised or `OUTPUT_VAR` will
# contain a string with the suffix `NOTFOUND` which can be used in CMake `if()` # contain a string with the suffix `NOTFOUND` which can be used in CMake `if()`
# commands. # commands.
function(get_git_head_describe GIT_DIR OUTPUT_VAR) function(get_git_head_describe GIT_DOT_FILE OUTPUT_VAR)
if (NOT "${ARGC}" EQUAL 2) if (NOT "${ARGC}" EQUAL 2)
message(FATAL_ERROR "Invalid number of arguments") message(FATAL_ERROR "Invalid number of arguments")
endif() endif()
if (NOT IS_DIRECTORY "${GIT_DIR}") if (NOT EXISTS "${GIT_DOT_FILE}")
message(FATAL_ERROR "\"${GIT_DIR}\" is not a directory") message(FATAL_ERROR "\"${GIT_DOT_FILE}\" does not exist")
endif() endif()
if (NOT IS_ABSOLUTE "${GIT_DIR}") if (NOT IS_ABSOLUTE "${GIT_DOT_FILE}")
message(FATAL_ERROR \""${GIT_DIR}\" is not an absolute path") message(FATAL_ERROR \""${GIT_DOT_FILE}\" is not an absolute path")
endif() endif()
find_package(Git) find_package(Git)
# NOTE: Use `GIT_FOUND` rather than `Git_FOUND` which was only # NOTE: Use `GIT_FOUND` rather than `Git_FOUND` which was only
@ -154,7 +188,7 @@ function(get_git_head_describe GIT_DIR OUTPUT_VAR)
set(${OUTPUT_VAR} "GIT-NOTFOUND" PARENT_SCOPE) set(${OUTPUT_VAR} "GIT-NOTFOUND" PARENT_SCOPE)
return() return()
endif() endif()
get_filename_component(GIT_WORKING_DIR "${GIT_DIR}" DIRECTORY) get_filename_component(GIT_WORKING_DIR "${GIT_DOT_FILE}" DIRECTORY)
execute_process( execute_process(
COMMAND COMMAND
"${GIT_EXECUTABLE}" "${GIT_EXECUTABLE}"

View file

@ -184,7 +184,12 @@ foreach (_build_type ${_build_types_as_upper})
# Address space layout randomization # Address space layout randomization
# See https://msdn.microsoft.com/en-us/library/bb384887.aspx # See https://msdn.microsoft.com/en-us/library/bb384887.aspx
string(APPEND CMAKE_EXE_LINKER_FLAGS_${_build_type} " /DYNAMICBASE") string(APPEND CMAKE_EXE_LINKER_FLAGS_${_build_type} " /DYNAMICBASE")
string(APPEND CMAKE_SHARED_LINKER_FLAGS_${_build_type} " /DYNAMICBASE:NO") if(ENABLE_CFI)
# CFI requires /DYNAMICBASE to be enabled.
string(APPEND CMAKE_SHARED_LINKER_FLAGS_${_build_type} " /DYNAMICBASE")
else()
string(APPEND CMAKE_SHARED_LINKER_FLAGS_${_build_type} " /DYNAMICBASE:NO")
endif()
# FIXME: This is not necessary. This is MSVC's default. # FIXME: This is not necessary. This is MSVC's default.
# Indicate that the executable is compatible with DEP # Indicate that the executable is compatible with DEP

View file

@ -36,15 +36,8 @@ function(z3_add_component_dependencies_to_target target_name)
# Remaing args should be component names # Remaing args should be component names
set(_expanded_deps ${ARGN}) set(_expanded_deps ${ARGN})
foreach (dependency ${_expanded_deps}) foreach (dependency ${_expanded_deps})
# FIXME: Adding these include paths wouldn't be necessary if the sources
# used include paths rooted in the ``src`` directory.
get_property(_dep_include_dirs GLOBAL PROPERTY Z3_${dependency}_INCLUDES)
foreach (inc_dir ${_dep_include_dirs})
target_include_directories(${target_name} PRIVATE "${inc_dir}")
endforeach()
unset(_dep_include_dirs)
# Ensure this component's dependencies are built before this component. # Ensure this component's dependencies are built before this component.
# This important because we might need the generated header files in # This is important because we might need the generated header files in
# other components. # other components.
add_dependencies(${target_name} ${dependency}) add_dependencies(${target_name} ${dependency})
endforeach() endforeach()
@ -214,18 +207,14 @@ macro(z3_add_component component_name)
target_compile_options(${component_name} PRIVATE ${flag}) target_compile_options(${component_name} PRIVATE ${flag})
endforeach() endforeach()
# It's unfortunate that we have to manage the include directories and dependencies ourselves. # It's unfortunate that we have to manage dependencies ourselves.
# #
# If we weren't building "object" libraries we could use # If we weren't building "object" libraries we could use
# ``` # ```
# target_include_directories(${component_name} INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}")
# target_link_libraries(${component_name} INTERFACE ${Z3_MOD_COMPONENT_DEPENDENCIES}) # target_link_libraries(${component_name} INTERFACE ${Z3_MOD_COMPONENT_DEPENDENCIES})
# ``` # ```
# but we can't do that with "object" libraries. # but we can't do that with "object" libraries.
# Record this component's include directories
set_property(GLOBAL PROPERTY Z3_${component_name}_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}")
set_property(GLOBAL APPEND PROPERTY Z3_${component_name}_INCLUDES "${CMAKE_CURRENT_BINARY_DIR}")
set_property(GLOBAL PROPERTY Z3_${component_name}_DEPS "") set_property(GLOBAL PROPERTY Z3_${component_name}_DEPS "")
# Record this component's dependencies # Record this component's dependencies
foreach (dependency ${Z3_MOD_COMPONENT_DEPENDENCIES}) foreach (dependency ${Z3_MOD_COMPONENT_DEPENDENCIES})
@ -243,12 +232,6 @@ macro(z3_add_component component_name)
endif() endif()
#message(STATUS "Component \"${component_name}\" has the following dependencies ${_expanded_deps}") #message(STATUS "Component \"${component_name}\" has the following dependencies ${_expanded_deps}")
# For any generated header files for this component
target_include_directories(${component_name} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
# So that any generated header files can refer to source files in the component's
# source tree
target_include_directories(${component_name} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}")
# Add any extra include directories # Add any extra include directories
foreach (extra_include ${Z3_COMPONENT_EXTRA_INCLUDE_DIRS}) foreach (extra_include ${Z3_COMPONENT_EXTRA_INCLUDE_DIRS})
target_include_directories(${component_name} PRIVATE "${extra_include}") target_include_directories(${component_name} PRIVATE "${extra_include}")
@ -283,7 +266,6 @@ macro(z3_add_install_tactic_rule)
endforeach() endforeach()
unset(_component_tactic_header_files) unset(_component_tactic_header_files)
list(APPEND _search_paths "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}")
add_custom_command(OUTPUT "install_tactic.cpp" add_custom_command(OUTPUT "install_tactic.cpp"
COMMAND "${PYTHON_EXECUTABLE}" COMMAND "${PYTHON_EXECUTABLE}"
"${CMAKE_SOURCE_DIR}/scripts/mk_install_tactic_cpp.py" "${CMAKE_SOURCE_DIR}/scripts/mk_install_tactic_cpp.py"
@ -311,13 +293,6 @@ macro(z3_add_memory_initializer_rule)
) )
endif() endif()
z3_expand_dependencies(_expanded_components ${ARGN}) z3_expand_dependencies(_expanded_components ${ARGN})
# Get paths to search
set(_search_paths "")
foreach (dependency ${_expanded_components})
get_property(_dep_include_dirs GLOBAL PROPERTY Z3_${dependency}_INCLUDES)
list(APPEND _search_paths ${_dep_include_dirs})
endforeach()
list(APPEND _search_paths "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}")
# Get header files that declare initializers and finalizers # Get header files that declare initializers and finalizers
set(_mem_init_finalize_headers "") set(_mem_init_finalize_headers "")

View file

@ -30,6 +30,7 @@ RUN apt-get update && \
libgomp1 \ libgomp1 \
libomp5 \ libomp5 \
libomp-dev \ libomp-dev \
llvm-3.9 \
make \ make \
mono-devel \ mono-devel \
ninja-build \ ninja-build \
@ -47,4 +48,4 @@ RUN useradd -m user && \
echo 'user ALL=(root) NOPASSWD: ALL' >> /etc/sudoers echo 'user ALL=(root) NOPASSWD: ALL' >> /etc/sudoers
USER user USER user
WORKDIR /home/user WORKDIR /home/user
ENV ASAN_SYMBOLIZER_PATH=/usr/lib/llvm-3.9/bin/llvm-symbolizer

View file

@ -16,6 +16,7 @@ RUN apt-get update && \
libgmp-dev \ libgmp-dev \
libgomp1 \ libgomp1 \
lib32gomp1 \ lib32gomp1 \
llvm-3.9 \
make \ make \
mono-devel \ mono-devel \
ninja-build \ ninja-build \
@ -32,4 +33,4 @@ RUN useradd -m user && \
echo 'user ALL=(root) NOPASSWD: ALL' >> /etc/sudoers echo 'user ALL=(root) NOPASSWD: ALL' >> /etc/sudoers
USER user USER user
WORKDIR /home/user WORKDIR /home/user
ENV ASAN_SYMBOLIZER_PATH=/usr/lib/llvm-3.9/bin/llvm-symbolizer

View file

@ -18,6 +18,7 @@ RUN apt-get update && \
libgomp1 \ libgomp1 \
libomp5 \ libomp5 \
libomp-dev \ libomp-dev \
llvm-3.9 \
make \ make \
mono-devel \ mono-devel \
ninja-build \ ninja-build \
@ -35,4 +36,4 @@ RUN useradd -m user && \
echo 'user ALL=(root) NOPASSWD: ALL' >> /etc/sudoers echo 'user ALL=(root) NOPASSWD: ALL' >> /etc/sudoers
USER user USER user
WORKDIR /home/user WORKDIR /home/user
ENV ASAN_SYMBOLIZER_PATH=/usr/lib/llvm-3.9/bin/llvm-symbolizer

View file

@ -2,37 +2,40 @@ ARG DOCKER_IMAGE_BASE
FROM ${DOCKER_IMAGE_BASE} FROM ${DOCKER_IMAGE_BASE}
# Specify defaults. This can be changed when invoking # Build arguments. This can be changed when invoking
# `docker build`. # `docker build`.
ARG ASAN_BUILD=0 ARG ASAN_BUILD
ARG BUILD_DOCS=0 ARG ASAN_DSO
ARG CC=gcc ARG BUILD_DOCS
ARG CXX=g++ ARG CC
ARG DOTNET_BINDINGS=1 ARG CXX
ARG JAVA_BINDINGS=1 ARG DOTNET_BINDINGS
ARG NO_SUPPRESS_OUTPUT=0 ARG JAVA_BINDINGS
ARG PYTHON_BINDINGS=1 ARG NO_SUPPRESS_OUTPUT
ARG PYTHON_BINDINGS
ARG PYTHON_EXECUTABLE=/usr/bin/python2.7 ARG PYTHON_EXECUTABLE=/usr/bin/python2.7
ARG RUN_SYSTEM_TESTS=1 ARG RUN_API_EXAMPLES
ARG RUN_UNIT_TESTS=1 ARG RUN_SYSTEM_TESTS
ARG TARGET_ARCH=x86_64 ARG RUN_UNIT_TESTS
ARG TEST_INSTALL=1 ARG SANITIZER_PRINT_SUPPRESSIONS
ARG UBSAN_BUILD=0 ARG TARGET_ARCH
ARG USE_LIBGMP=0 ARG TEST_INSTALL
ARG USE_LTO=0 ARG UBSAN_BUILD
ARG USE_OPENMP=1 ARG USE_LIBGMP
ARG USE_LTO
ARG USE_OPENMP
ARG Z3_SRC_DIR=/home/user/z3_src ARG Z3_SRC_DIR=/home/user/z3_src
ARG Z3_BUILD_TYPE=RelWithDebInfo ARG Z3_BUILD_TYPE
ARG Z3_CMAKE_GENERATOR=Ninja ARG Z3_CMAKE_GENERATOR
ARG Z3_INSTALL_PREFIX=/usr ARG Z3_INSTALL_PREFIX
ARG Z3_STATIC_BUILD=0 ARG Z3_STATIC_BUILD
# Blank default indicates use latest.
ARG Z3_SYSTEM_TEST_GIT_REVISION ARG Z3_SYSTEM_TEST_GIT_REVISION
ARG Z3_WARNINGS_AS_ERRORS=SERIOUS_ONLY ARG Z3_WARNINGS_AS_ERRORS
ARG Z3_VERBOSE_BUILD_OUTPUT=0 ARG Z3_VERBOSE_BUILD_OUTPUT
ENV \ ENV \
ASAN_BUILD=${ASAN_BUILD} \ ASAN_BUILD=${ASAN_BUILD} \
ASAN_DSO=${ASAN_DSO} \
BUILD_DOCS=${BUILD_DOCS} \ BUILD_DOCS=${BUILD_DOCS} \
CC=${CC} \ CC=${CC} \
CXX=${CXX} \ CXX=${CXX} \
@ -41,6 +44,8 @@ ENV \
NO_SUPPRESS_OUTPUT=${NO_SUPPRESS_OUTPUT} \ NO_SUPPRESS_OUTPUT=${NO_SUPPRESS_OUTPUT} \
PYTHON_BINDINGS=${PYTHON_BINDINGS} \ PYTHON_BINDINGS=${PYTHON_BINDINGS} \
PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE} \ PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE} \
SANITIZER_PRINT_SUPPRESSIONS=${SANITIZER_PRINT_SUPPRESSIONS} \
RUN_API_EXAMPLES=${RUN_API_EXAMPLES} \
RUN_SYSTEM_TESTS=${RUN_SYSTEM_TESTS} \ RUN_SYSTEM_TESTS=${RUN_SYSTEM_TESTS} \
RUN_UNIT_TESTS=${RUN_UNIT_TESTS} \ RUN_UNIT_TESTS=${RUN_UNIT_TESTS} \
TARGET_ARCH=${TARGET_ARCH} \ TARGET_ARCH=${TARGET_ARCH} \
@ -51,6 +56,7 @@ ENV \
USE_OPENMP=${USE_OPENMP} \ USE_OPENMP=${USE_OPENMP} \
Z3_SRC_DIR=${Z3_SRC_DIR} \ Z3_SRC_DIR=${Z3_SRC_DIR} \
Z3_BUILD_DIR=/home/user/z3_build \ Z3_BUILD_DIR=/home/user/z3_build \
Z3_BUILD_TYPE=${Z3_BUILD_TYPE} \
Z3_CMAKE_GENERATOR=${Z3_CMAKE_GENERATOR} \ Z3_CMAKE_GENERATOR=${Z3_CMAKE_GENERATOR} \
Z3_VERBOSE_BUILD_OUTPUT=${Z3_VERBOSE_BUILD_OUTPUT} \ Z3_VERBOSE_BUILD_OUTPUT=${Z3_VERBOSE_BUILD_OUTPUT} \
Z3_STATIC_BUILD=${Z3_STATIC_BUILD} \ Z3_STATIC_BUILD=${Z3_STATIC_BUILD} \
@ -63,7 +69,8 @@ ENV \
# Build Z3 # Build Z3
RUN mkdir -p "${Z3_SRC_DIR}" && \ RUN mkdir -p "${Z3_SRC_DIR}" && \
mkdir -p "${Z3_SRC_DIR}/contrib/ci/scripts" mkdir -p "${Z3_SRC_DIR}/contrib/ci/scripts" && \
mkdir -p "${Z3_SRC_DIR}/contrib/suppressions/sanitizers"
# Deliberately leave out `contrib` # Deliberately leave out `contrib`
ADD /cmake ${Z3_SRC_DIR}/cmake/ ADD /cmake ${Z3_SRC_DIR}/cmake/
ADD /doc ${Z3_SRC_DIR}/doc/ ADD /doc ${Z3_SRC_DIR}/doc/
@ -74,6 +81,7 @@ ADD *.txt *.md RELEASE_NOTES ${Z3_SRC_DIR}/
ADD \ ADD \
/contrib/ci/scripts/build_z3_cmake.sh \ /contrib/ci/scripts/build_z3_cmake.sh \
/contrib/ci/scripts/ci_defaults.sh \
/contrib/ci/scripts/set_compiler_flags.sh \ /contrib/ci/scripts/set_compiler_flags.sh \
/contrib/ci/scripts/set_generator_args.sh \ /contrib/ci/scripts/set_generator_args.sh \
${Z3_SRC_DIR}/contrib/ci/scripts/ ${Z3_SRC_DIR}/contrib/ci/scripts/
@ -89,7 +97,13 @@ RUN ${Z3_SRC_DIR}/contrib/ci/scripts/test_z3_docs.sh
# Test examples # Test examples
ADD \ ADD \
/contrib/ci/scripts/test_z3_examples_cmake.sh \ /contrib/ci/scripts/test_z3_examples_cmake.sh \
/contrib/ci/scripts/sanitizer_env.sh \
${Z3_SRC_DIR}/contrib/ci/scripts/ ${Z3_SRC_DIR}/contrib/ci/scripts/
ADD \
/contrib/suppressions/sanitizers/asan.txt \
/contrib/suppressions/sanitizers/lsan.txt \
/contrib/suppressions/sanitizers/ubsan.txt \
${Z3_SRC_DIR}/contrib/suppressions/sanitizers/
RUN ${Z3_SRC_DIR}/contrib/ci/scripts/test_z3_examples_cmake.sh RUN ${Z3_SRC_DIR}/contrib/ci/scripts/test_z3_examples_cmake.sh
# Run unit tests # Run unit tests

View file

@ -30,8 +30,10 @@ the future.
* `JAVA_BINDINGS` - Build and test Java API bindings (`0` or `1`) * `JAVA_BINDINGS` - Build and test Java API bindings (`0` or `1`)
* `NO_SUPPRESS_OUTPUT` - Don't suppress output of some commands (`0` or `1`) * `NO_SUPPRESS_OUTPUT` - Don't suppress output of some commands (`0` or `1`)
* `PYTHON_BINDINGS` - Build and test Python API bindings (`0` or `1`) * `PYTHON_BINDINGS` - Build and test Python API bindings (`0` or `1`)
* `RUN_API_EXAMPLES` - Build and run API examples (`0` or `1`)
* `RUN_SYSTEM_TESTS` - Run system tests (`0` or `1`) * `RUN_SYSTEM_TESTS` - Run system tests (`0` or `1`)
* `RUN_UNIT_TESTS` - Run unit tests (`0` or `1`) * `RUN_UNIT_TESTS` - Run unit tests (`BUILD_ONLY` or `BUILD_AND_RUN` or `SKIP`)
* `SANITIZER_PRINT_SUPPRESSIONS` - Show ASan/UBSan suppressions (`0` or `1`)
* `TARGET_ARCH` - Target architecture (`x86_64` or `i686`) * `TARGET_ARCH` - Target architecture (`x86_64` or `i686`)
* `TEST_INSTALL` - Test running `install` target (`0` or `1`) * `TEST_INSTALL` - Test running `install` target (`0` or `1`)
* `UBSAN_BUILD` - Do [UndefinedBehaviourSanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) build (`0` or `1`) * `UBSAN_BUILD` - Do [UndefinedBehaviourSanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) build (`0` or `1`)
@ -58,8 +60,9 @@ The `scripts/travis_ci_linux_entry_point.sh` script
variables (if set) into the build using the `--build-arg` argument of the `docker run` variables (if set) into the build using the `--build-arg` argument of the `docker run`
command. command.
If an environemnt variable is not set a defaults value is used which can be The default values of the configuration environment variables
found in `Dockerfiles/z3_build.Dockerfile`. can be found in
[`scripts/ci_defaults.sh`](scripts/ci_defaults.sh).
#### Linux specific configuration variables #### Linux specific configuration variables
@ -67,8 +70,9 @@ found in `Dockerfiles/z3_build.Dockerfile`.
#### Reproducing a build locally #### Reproducing a build locally
A build can be reproduced locally by using the `scripts/travis_ci_linux_entry_point.sh` A build can be reproduced locally by using the
script and setting the appropriate environment variable. `scripts/travis_ci_linux_entry_point.sh` script and setting the appropriate
environment variable.
For example lets say we wanted to reproduce the build below. For example lets say we wanted to reproduce the build below.
@ -104,11 +108,43 @@ feature might be removed in the future.
It may be better to just build the base image once (outside of TravisCI), upload It may be better to just build the base image once (outside of TravisCI), upload
it to [DockerHub](https://hub.docker.com/) and have the build pull down the pre-built it to [DockerHub](https://hub.docker.com/) and have the build pull down the pre-built
image everytime. image every time.
An [organization](https://hub.docker.com/u/z3prover/) has been created on An [organization](https://hub.docker.com/u/z3prover/) has been created on
DockerHub for this. DockerHub for this.
### macOS ### macOS
Not yet implemented. For macOS we execute directly on TravisCI's macOS environment. The entry point
for the TravisCI builds is the
[`scripts/travis_ci_osx_entry_point.sh`](scripts/travis_ci_osx_entry_point.sh)
scripts.
#### macOS specific configuration variables
* `MACOS_SKIP_DEPS_UPDATE` - If set to `1` installing the necessary build dependencies
is skipped. This is useful for local testing if the dependencies are already installed.
* `MACOS_UPDATE_CMAKE` - If set to `1` the installed version of CMake will be upgraded.
#### Reproducing a build locally
To reproduce a build (e.g. like the one shown below)
```yaml
- os: osx
osx_image: xcode8.3
# Note: Apple Clang does not support OpenMP
env: Z3_BUILD_TYPE=RelWithDebInfo USE_OPENMP=0
```
Run the following:
```bash
TRAVIS_BUILD_DIR=$(pwd) \
Z3_BUILD_TYPE=RelWithDebInfo \
USE_OPEN_MP=0 \
contrib/ci/scripts/travis_ci_osx_entry_point.sh
```
Note this assumes that the current working directory is the root of the Z3
git repository.

View file

@ -22,6 +22,7 @@ set -o pipefail
: ${USE_LTO?"USE_LTO must be specified"} : ${USE_LTO?"USE_LTO must be specified"}
: ${Z3_INSTALL_PREFIX?"Z3_INSTALL_PREFIX must be specified"} : ${Z3_INSTALL_PREFIX?"Z3_INSTALL_PREFIX must be specified"}
: ${Z3_WARNINGS_AS_ERRORS?"Z3_WARNINGS_AS_ERRORS must be specified"} : ${Z3_WARNINGS_AS_ERRORS?"Z3_WARNINGS_AS_ERRORS must be specified"}
: ${UBSAN_BUILD?"UBSAN_BUILD must be specified"}
ADDITIONAL_Z3_OPTS=() ADDITIONAL_Z3_OPTS=()
@ -105,6 +106,16 @@ fi
# Set compiler flags # Set compiler flags
source ${SCRIPT_DIR}/set_compiler_flags.sh source ${SCRIPT_DIR}/set_compiler_flags.sh
if [ "X${UBSAN_BUILD}" = "X1" ]; then
# HACK: When building with UBSan the C++ linker
# must be used to avoid the following linker errors.
# undefined reference to `__ubsan_vptr_type_cache'
# undefined reference to `__ubsan_handle_dynamic_type_cache_miss'
ADDITIONAL_Z3_OPTS+=( \
'-DZ3_C_EXAMPLES_FORCE_CXX_LINKER=ON' \
)
fi
# Sanity check # Sanity check
if [ ! -e "${Z3_SRC_DIR}/CMakeLists.txt" ]; then if [ ! -e "${Z3_SRC_DIR}/CMakeLists.txt" ]; then
echo "Z3_SRC_DIR is invalid" echo "Z3_SRC_DIR is invalid"

View file

@ -0,0 +1,60 @@
# This file should be sourced by other scripts
# and not executed directly
# Set CI build defaults
export ASAN_BUILD="${ASAN_BUILD:-0}"
export BUILD_DOCS="${BUILD_DOCS:-0}"
export DOTNET_BINDINGS="${DOTNET_BINDINGS:-1}"
export JAVA_BINDINGS="${JAVA_BINDINGS:-1}"
export NO_SUPPRESS_OUTPUT="${NO_SUPPRESS_OUTPUT:-0}"
export PYTHON_BINDINGS="${PYTHON_BINDINGS:-1}"
export RUN_API_EXAMPLES="${RUN_API_EXAMPLES:-1}"
export RUN_SYSTEM_TESTS="${RUN_SYSTEM_TESTS:-1}"
export RUN_UNIT_TESTS="${RUN_UNIT_TESTS:-BUILD_AND_RUN}"
# Don't print suppressions by default because that breaks the Z3
# regression tests because they don't expect them to appear in Z3's
# output.
export SANITIZER_PRINT_SUPPRESSIONS="${SANITIZER_PRINT_SUPPRESSIONS:-0}"
export TARGET_ARCH="${TARGET_ARCH:-x86_64}"
export TEST_INSTALL="${TEST_INSTALL:-1}"
export UBSAN_BUILD="${UBSAN_BUILD:-0}"
export USE_LIBGMP="${USE_LIBGMP:-0}"
export USE_LTO="${USE_LTO:-0}"
export USE_OPENMP="${USE_OPENMP:-1}"
export Z3_BUILD_TYPE="${Z3_BUILD_TYPE:-RelWithDebInfo}"
export Z3_CMAKE_GENERATOR="${Z3_CMAKE_GENERATOR:-Ninja}"
export Z3_STATIC_BUILD="${Z3_STATIC_BUILD:-0}"
# Default is blank which means get latest revision
export Z3_SYSTEM_TEST_GIT_REVISION="${Z3_SYSTEM_TEST_GIT_REVISION:-}"
export Z3_WARNINGS_AS_ERRORS="${Z3_WARNINGS_AS_ERRORS:-SERIOUS_ONLY}"
export Z3_VERBOSE_BUILD_OUTPUT="${Z3_VERBOSE_BUILD_OUTPUT:-0}"
# Platform specific defaults
PLATFORM="$(uname -s)"
case "${PLATFORM}" in
Linux*)
export C_COMPILER="${C_COMPILER:-gcc}"
export CXX_COMPILER="${CXX_COMPILER:-g++}"
export Z3_INSTALL_PREFIX="${Z3_INSTALL_PREFIX:-/usr}"
;;
Darwin*)
export C_COMPILER="${C_COMPILER:-clang}"
export CXX_COMPILER="${CXX_COMPILER:-clang++}"
export Z3_INSTALL_PREFIX="${Z3_INSTALL_PREFIX:-/usr/local}"
;;
*)
echo "Unknown platform \"${PLATFORM}\""
exit 1
;;
esac
unset PLATFORM
# NOTE: The following variables are not set here because
# they are specific to the CI implementation
# PYTHON_EXECUTABLE
# ASAN_DSO
# Z3_SRC_DIR
# Z3_BUILD_DIR
# Z3_SYSTEM_TEST_DIR

View file

@ -0,0 +1,47 @@
#!/bin/bash
SCRIPT_DIR="$( cd ${BASH_SOURCE[0]%/*} ; echo $PWD )"
. ${SCRIPT_DIR}/run_quiet.sh
set -x
set -e
set -o pipefail
run_quiet brew update
export HOMEBREW_NO_AUTO_UPDATE=1
function brew_install_or_upgrade() {
if brew ls --versions "$1" > /dev/null 2>&1 ; then
brew upgrade "$1"
else
brew install "$1"
fi
}
# FIXME: We should fix the versions of dependencies used
# so that we have reproducible builds.
# HACK: Just use CMake version in TravisCI for now
if [ "X${MACOS_UPDATE_CMAKE}" = "X1" ]; then
brew_install_or_upgrade cmake
fi
if [ "X${Z3_CMAKE_GENERATOR}" = "XNinja" ]; then
brew_install_or_upgrade ninja
fi
if [ "X${USE_LIBGMP}" = "X1" ]; then
brew_install_or_upgrade gmp
fi
if [ "X${BUILD_DOCS}" = "X1" ]; then
brew_install_or_upgrade doxygen
fi
if [ "X${DOTNET_BINDINGS}" = "X1" ]; then
brew_install_or_upgrade mono
fi
if [ "X${JAVA_BINDINGS}" = "X1" ]; then
brew cask install java
fi

View file

@ -34,8 +34,8 @@ function run_quiet() {
fi fi
# Clean up # Clean up
rm "${STDOUT}" "${STDERR}" rm "${STDOUT}" "${STDERR}"
[ $( echo "${OLD_SETTINGS}" | grep -c 'e') -ne 0 ] && set -e [ "$( echo "${OLD_SETTINGS}" | grep -c 'e')" != "0" ] && set -e
[ $( echo "${OLD_SETTINGS}" | grep -c 'x') -ne 0 ] && set -x [ "$( echo "${OLD_SETTINGS}" | grep -c 'x')" != "0" ] && set -x
return ${EXIT_STATUS} return ${EXIT_STATUS}
fi fi
} }

View file

@ -0,0 +1,82 @@
# This script is intended to be included by other
# scripts and should not be executed directly
: ${Z3_SRC_DIR?"Z3_SRC_DIR must be specified"}
: ${ASAN_BUILD?"ASAN_BUILD must be specified"}
: ${UBSAN_BUILD?"UBSAN_BUILD must be specified"}
if [ "X${ASAN_BUILD}" = "X1" ]; then
# Use suppression files
export LSAN_OPTIONS="suppressions=${Z3_SRC_DIR}/contrib/suppressions/sanitizers/lsan.txt"
# NOTE: If you get bad stacktraces try using `fast_unwind_on_malloc=0`
# NOTE: `malloc_context_size` controls size of recorded stacktrace for allocations.
# If the reported stacktraces appear incomplete try increasing the value.
export ASAN_OPTIONS="malloc_context_size=100,suppressions=${Z3_SRC_DIR}/contrib/suppressions/sanitizers/asan.txt"
: ${SANITIZER_PRINT_SUPPRESSIONS?"SANITIZER_PRINT_SUPPRESSIONS must be specified"}
if [ "X${SANITIZER_PRINT_SUPPRESSIONS}" = "X1" ]; then
export LSAN_OPTIONS="${LSAN_OPTIONS},print_suppressions=1"
export ASAN_OPTIONS="${ASAN_OPTIONS},print_suppressions=1"
else
export LSAN_OPTIONS="${LSAN_OPTIONS},print_suppressions=0"
export ASAN_OPTIONS="${ASAN_OPTIONS},print_suppressions=0"
fi
: ${ASAN_SYMBOLIZER_PATH?"ASAN_SYMBOLIZER_PATH must be specified"}
# Run command without checking for leaks
function run_no_lsan() {
ASAN_OPTIONS="${ASAN_OPTIONS},detect_leaks=0" "${@}"
}
# Check path to ASan DSO
: ${ASAN_DSO?"ASAN_DSO must be specified"}
if [ ! -e "${ASAN_DSO}" ]; then
echo "ASAN_DSO (${ASAN_DSO}) does not exist"
exit 1
fi
# FIXME: We'll need to refactor this when we can do UBSan builds
# against a UBSan DSO.
function run_non_native_binding() {
# We need to preload the ASan DSO that libz3
# will have undefined references to.
# Don't run leak checking because we get lots reported leaks
# in the language runtime (e.g. python).
PLATFORM="$(uname -s)"
case "${PLATFORM}" in
Linux*)
LD_PRELOAD="${ASAN_DSO}" run_no_lsan "${@}"
;;
Darwin*)
DYLD_INSERT_LIBRARIES="${ASAN_DSO}" run_no_lsan "${@}"
;;
*)
echo "Unknown platform \"${PLATFORM}\""
exit 1
;;
esac
unset PLATFORM
}
else
# In non-ASan build just run directly
function run_no_lsan() {
"${@}"
}
function run_non_native_binding() {
"${@}"
}
fi
if [ "X${UBSAN_BUILD}" = "X1" ]; then
# `halt_on_error=1,abort_on_error=1` means that on the first UBSan error
# the program will terminate by calling `abort(). Without this UBSan will
# allow execution to continue. We also use a suppression file.
export UBSAN_OPTIONS="halt_on_error=1,abort_on_error=1,suppressions=${Z3_SRC_DIR}/contrib/suppressions/sanitizers/ubsan.txt"
: ${SANITIZER_PRINT_SUPPRESSIONS?"SANITIZER_PRINT_SUPPRESSIONS must be specified"}
if [ "X${SANITIZER_PRINT_SUPPRESSIONS}" = "X1" ]; then
export UBSAN_OPTIONS="${UBSAN_OPTIONS},print_suppressions=1"
else
export UBSAN_OPTIONS="${UBSAN_OPTIONS},print_suppressions=0"
fi
fi

View file

@ -1,4 +1,4 @@
# This script should is intended to be included by other # This script is intended to be included by other
# scripts and should not be executed directly # scripts and should not be executed directly
: ${Z3_CMAKE_GENERATOR?"Z3_CMAKE_GENERATOR must be specified"} : ${Z3_CMAKE_GENERATOR?"Z3_CMAKE_GENERATOR must be specified"}

View file

@ -14,6 +14,13 @@ set -o pipefail
: ${PYTHON_EXECUTABLE?"PYTHON_EXECUTABLE must be specified"} : ${PYTHON_EXECUTABLE?"PYTHON_EXECUTABLE must be specified"}
: ${DOTNET_BINDINGS?"DOTNET_BINDINGS must be specified"} : ${DOTNET_BINDINGS?"DOTNET_BINDINGS must be specified"}
: ${JAVA_BINDINGS?"JAVA_BINDINGS must be specified"} : ${JAVA_BINDINGS?"JAVA_BINDINGS must be specified"}
: ${UBSAN_BUILD?"UBSAN_BUILD must be specified"}
: ${RUN_API_EXAMPLES?"RUN_API_EXAMPLES must be specified"}
if [ "X${RUN_API_EXAMPLES}" = "X0" ]; then
echo "Skipping run of API examples"
exit 0
fi
# Set compiler flags # Set compiler flags
source ${SCRIPT_DIR}/set_compiler_flags.sh source ${SCRIPT_DIR}/set_compiler_flags.sh
@ -21,6 +28,9 @@ source ${SCRIPT_DIR}/set_compiler_flags.sh
# Set CMake generator args # Set CMake generator args
source ${SCRIPT_DIR}/set_generator_args.sh source ${SCRIPT_DIR}/set_generator_args.sh
# Sanitizer environment variables
source ${SCRIPT_DIR}/sanitizer_env.sh
cd "${Z3_BUILD_DIR}" cd "${Z3_BUILD_DIR}"
# Build and run C example # Build and run C example
@ -38,9 +48,21 @@ run_quiet examples/tptp_build_dir/z3_tptp5 -help
# Build an run c_maxsat_example # Build an run c_maxsat_example
cmake --build $(pwd) --target c_maxsat_example "${GENERATOR_ARGS[@]}" cmake --build $(pwd) --target c_maxsat_example "${GENERATOR_ARGS[@]}"
run_quiet \ # FIXME: It is known that the maxsat example leaks memory and the
examples/c_maxsat_example_build_dir/c_maxsat_example \ # the Z3 developers have stated this is "wontfix".
${Z3_SRC_DIR}/examples/maxsat/ex.smt # See https://github.com/Z3Prover/z3/issues/1299
run_no_lsan \
run_quiet \
examples/c_maxsat_example_build_dir/c_maxsat_example \
${Z3_SRC_DIR}/examples/maxsat/ex.smt
if [ "X${UBSAN_BUILD}" = "X1" ]; then
# FIXME: We really need libz3 to link against a shared UBSan runtime.
# Right now we link against the static runtime which breaks all the
# non-native language bindings.
echo "FIXME: Can't run other examples when building with UBSan"
exit 0
fi
if [ "X${PYTHON_BINDINGS}" = "X1" ]; then if [ "X${PYTHON_BINDINGS}" = "X1" ]; then
@ -48,16 +70,21 @@ if [ "X${PYTHON_BINDINGS}" = "X1" ]; then
# `all_interval_series.py` produces a lot of output so just throw # `all_interval_series.py` produces a lot of output so just throw
# away output. # away output.
# TODO: This example is slow should we remove it from testing? # TODO: This example is slow should we remove it from testing?
run_quiet ${PYTHON_EXECUTABLE} python/all_interval_series.py if [ "X${ASAN_BUILD}" = "X1" -a "X${Z3_BUILD_TYPE}" = "XDebug" ]; then
run_quiet ${PYTHON_EXECUTABLE} python/complex.py # Too slow when doing ASan Debug build
run_quiet ${PYTHON_EXECUTABLE} python/example.py echo "Skipping all_interval_series.py under ASan Debug build"
else
run_quiet run_non_native_binding ${PYTHON_EXECUTABLE} python/all_interval_series.py
fi
run_quiet run_non_native_binding ${PYTHON_EXECUTABLE} python/complex.py
run_quiet run_non_native_binding ${PYTHON_EXECUTABLE} python/example.py
# FIXME: `hamiltonian.py` example is disabled because its too slow. # FIXME: `hamiltonian.py` example is disabled because its too slow.
#${PYTHON_EXECUTABLE} python/hamiltonian.py #${PYTHON_EXECUTABLE} python/hamiltonian.py
run_quiet ${PYTHON_EXECUTABLE} python/marco.py run_quiet run_non_native_binding ${PYTHON_EXECUTABLE} python/marco.py
run_quiet ${PYTHON_EXECUTABLE} python/mss.py run_quiet run_non_native_binding ${PYTHON_EXECUTABLE} python/mss.py
run_quiet ${PYTHON_EXECUTABLE} python/socrates.py run_quiet run_non_native_binding ${PYTHON_EXECUTABLE} python/socrates.py
run_quiet ${PYTHON_EXECUTABLE} python/visitor.py run_quiet run_non_native_binding ${PYTHON_EXECUTABLE} python/visitor.py
run_quiet ${PYTHON_EXECUTABLE} python/z3test.py run_quiet run_non_native_binding ${PYTHON_EXECUTABLE} python/z3test.py
fi fi
if [ "X${DOTNET_BINDINGS}" = "X1" ]; then if [ "X${DOTNET_BINDINGS}" = "X1" ]; then
@ -65,7 +92,7 @@ if [ "X${DOTNET_BINDINGS}" = "X1" ]; then
# FIXME: Move compliation step into CMake target # FIXME: Move compliation step into CMake target
mcs ${Z3_SRC_DIR}/examples/dotnet/Program.cs /target:exe /out:dotnet_test.exe /reference:Microsoft.Z3.dll /r:System.Numerics.dll mcs ${Z3_SRC_DIR}/examples/dotnet/Program.cs /target:exe /out:dotnet_test.exe /reference:Microsoft.Z3.dll /r:System.Numerics.dll
# Run .NET example # Run .NET example
run_quiet mono ./dotnet_test.exe run_quiet run_non_native_binding mono ./dotnet_test.exe
fi fi
if [ "X${JAVA_BINDINGS}" = "X1" ]; then if [ "X${JAVA_BINDINGS}" = "X1" ]; then
@ -82,6 +109,14 @@ if [ "X${JAVA_BINDINGS}" = "X1" ]; then
# Assume Linux for now # Assume Linux for now
export LD_LIBRARY_PATH=$(pwd):${LD_LIBRARY_PATH} export LD_LIBRARY_PATH=$(pwd):${LD_LIBRARY_PATH}
fi fi
run_quiet java -cp .:examples/java:com.microsoft.z3.jar JavaExample if [ "X${ASAN_BUILD}" = "X1" ]; then
# The JVM seems to crash (SEGV) if we pre-load ASan
# so don't run it for now.
echo "Skipping JavaExample under ASan build"
else
run_quiet \
run_non_native_binding \
java -cp .:examples/java:com.microsoft.z3.jar JavaExample
fi
fi fi

View file

@ -10,12 +10,17 @@ set -o pipefail
: ${PYTHON_BINDINGS?"PYTHON_BINDINGS must be specified"} : ${PYTHON_BINDINGS?"PYTHON_BINDINGS must be specified"}
: ${PYTHON_EXECUTABLE?"PYTHON_EXECUTABLE must be specified"} : ${PYTHON_EXECUTABLE?"PYTHON_EXECUTABLE must be specified"}
: ${Z3_SYSTEM_TEST_DIR?"Z3_SYSTEM_TEST_DIR must be specified"} : ${Z3_SYSTEM_TEST_DIR?"Z3_SYSTEM_TEST_DIR must be specified"}
: ${UBSAN_BUILD?"UBSAN_BUILD must be specified"}
if [ "X${RUN_SYSTEM_TESTS}" != "X1" ]; then if [ "X${RUN_SYSTEM_TESTS}" != "X1" ]; then
echo "Skipping system tests" echo "Skipping system tests"
exit 0 exit 0
fi fi
# Sanitizer environment variables
SCRIPT_DIR="$( cd ${BASH_SOURCE[0]%/*} ; echo $PWD )"
source ${SCRIPT_DIR}/sanitizer_env.sh
Z3_EXE="${Z3_BUILD_DIR}/z3" Z3_EXE="${Z3_BUILD_DIR}/z3"
Z3_LIB_DIR="${Z3_BUILD_DIR}" Z3_LIB_DIR="${Z3_BUILD_DIR}"
@ -23,7 +28,7 @@ Z3_LIB_DIR="${Z3_BUILD_DIR}"
Z3_SYSTEM_TEST_GIT_URL="${Z3_GIT_URL:-https://github.com/Z3Prover/z3test.git}" Z3_SYSTEM_TEST_GIT_URL="${Z3_GIT_URL:-https://github.com/Z3Prover/z3test.git}"
# Clone repo to destination # Clone repo to destination
mkdir -p "${Z3_SYSTEM_TEST_GIT_URL}" mkdir -p "${Z3_SYSTEM_TEST_DIR}"
git clone "${Z3_SYSTEM_TEST_GIT_URL}" "${Z3_SYSTEM_TEST_DIR}" git clone "${Z3_SYSTEM_TEST_GIT_URL}" "${Z3_SYSTEM_TEST_DIR}"
cd "${Z3_SYSTEM_TEST_DIR}" cd "${Z3_SYSTEM_TEST_DIR}"
@ -48,7 +53,18 @@ fi
if [ "X${PYTHON_BINDINGS}" = "X1" ]; then if [ "X${PYTHON_BINDINGS}" = "X1" ]; then
# Run python binding tests # Run python binding tests
${PYTHON_EXECUTABLE} scripts/test_pyscripts.py "${Z3_LIB_DIR}" regressions/python/ if [ "X${UBSAN_BUILD}" = "X1" ]; then
# FIXME: We need to build libz3 with a shared UBSan runtime for the bindings
# to work.
echo "FIXME: Skipping python binding tests when building with UBSan"
elif [ "X${ASAN_BUILD}" = "X1" ]; then
# FIXME: The `test_pyscripts.py` doesn't propagate LD_PRELOAD
# so under ASan the tests fail to run
# to work.
echo "FIXME: Skipping python binding tests when building with ASan"
else
run_non_native_binding ${PYTHON_EXECUTABLE} scripts/test_pyscripts.py "${Z3_LIB_DIR}" regressions/python/
fi
fi fi
# FIXME: Run `scripts/test_cs.py` once it has been modified to support mono # FIXME: Run `scripts/test_cs.py` once it has been modified to support mono

View file

@ -1,6 +1,7 @@
#!/bin/bash #!/bin/bash
SCRIPT_DIR="$( cd ${BASH_SOURCE[0]%/*} ; echo $PWD )" SCRIPT_DIR="$( cd ${BASH_SOURCE[0]%/*} ; echo $PWD )"
. ${SCRIPT_DIR}/run_quiet.sh
set -x set -x
set -e set -e
@ -9,16 +10,38 @@ set -o pipefail
: ${Z3_BUILD_DIR?"Z3_BUILD_DIR must be specified"} : ${Z3_BUILD_DIR?"Z3_BUILD_DIR must be specified"}
: ${RUN_UNIT_TESTS?"RUN_UNIT_TESTS must be specified"} : ${RUN_UNIT_TESTS?"RUN_UNIT_TESTS must be specified"}
if [ "X${RUN_UNIT_TESTS}" != "X1" ]; then
echo "Skipping unit tests"
exit 0
fi
# Set CMake generator args # Set CMake generator args
source ${SCRIPT_DIR}/set_generator_args.sh source ${SCRIPT_DIR}/set_generator_args.sh
# Sanitizer environment variables
source ${SCRIPT_DIR}/sanitizer_env.sh
cd "${Z3_BUILD_DIR}" cd "${Z3_BUILD_DIR}"
# Build and run internal tests function build_unit_tests() {
cmake --build $(pwd) --target test-z3 "${GENERATOR_ARGS[@]}" # Build internal tests
./test-z3 cmake --build $(pwd) --target test-z3 "${GENERATOR_ARGS[@]}"
}
function run_unit_tests() {
# Run all tests that don't require arguments
run_quiet ./test-z3 /a
}
case "${RUN_UNIT_TESTS}" in
BUILD_AND_RUN)
build_unit_tests
run_unit_tests
;;
BUILD_ONLY)
build_unit_tests
;;
SKIP)
echo "RUN_UNIT_TESTS set to \"${RUN_UNIT_TESTS}\" so skipping build and run"
exit 0
;;
*)
echo "Error: RUN_UNIT_TESTS set to unhandled value \"${RUN_UNIT_TESTS}\""
exit 1
;;
esac

View file

@ -11,16 +11,21 @@ DOCKER_FILE_DIR="$(cd ${SCRIPT_DIR}/../Dockerfiles; echo $PWD)"
: ${LINUX_BASE?"LINUX_BASE must be specified"} : ${LINUX_BASE?"LINUX_BASE must be specified"}
# Sanity check. Current working directory should be repo root # Sanity check. Current working directory should be repo root
if [ ! -f "./README.md" ]; then if [ ! -f "./README.md" ]; then
echo "Current working directory should be repo root" echo "Current working directory should be repo root"
exit 1 exit 1
fi fi
# Get defaults
source "${SCRIPT_DIR}/ci_defaults.sh"
BUILD_OPTS=() BUILD_OPTS=()
# Override options if they have been provided. # Pass Docker build arguments
# Otherwise the defaults in the Docker file will be used if [ -n "${Z3_BUILD_TYPE}" ]; then
BUILD_OPTS+=("--build-arg" "Z3_BUILD_TYPE=${Z3_BUILD_TYPE}")
fi
if [ -n "${Z3_CMAKE_GENERATOR}" ]; then if [ -n "${Z3_CMAKE_GENERATOR}" ]; then
BUILD_OPTS+=("--build-arg" "Z3_CMAKE_GENERATOR=${Z3_CMAKE_GENERATOR}") BUILD_OPTS+=("--build-arg" "Z3_CMAKE_GENERATOR=${Z3_CMAKE_GENERATOR}")
fi fi
@ -79,6 +84,14 @@ if [ -n "${ASAN_BUILD}" ]; then
BUILD_OPTS+=("--build-arg" "ASAN_BUILD=${ASAN_BUILD}") BUILD_OPTS+=("--build-arg" "ASAN_BUILD=${ASAN_BUILD}")
fi fi
if [ -n "${ASAN_DSO}" ]; then
BUILD_OPTS+=("--build-arg" "ASAN_DSO=${ASAN_DSO}")
fi
if [ -n "${SANITIZER_PRINT_SUPPRESSIONS}" ]; then
BUILD_OPTS+=("--build-arg" "SANITIZER_PRINT_SUPPRESSIONS=${SANITIZER_PRINT_SUPPRESSIONS}")
fi
if [ -n "${UBSAN_BUILD}" ]; then if [ -n "${UBSAN_BUILD}" ]; then
BUILD_OPTS+=("--build-arg" "UBSAN_BUILD=${UBSAN_BUILD}") BUILD_OPTS+=("--build-arg" "UBSAN_BUILD=${UBSAN_BUILD}")
fi fi
@ -87,6 +100,10 @@ if [ -n "${TEST_INSTALL}" ]; then
BUILD_OPTS+=("--build-arg" "TEST_INSTALL=${TEST_INSTALL}") BUILD_OPTS+=("--build-arg" "TEST_INSTALL=${TEST_INSTALL}")
fi fi
if [ -n "${RUN_API_EXAMPLES}" ]; then
BUILD_OPTS+=("--build-arg" "RUN_API_EXAMPLES=${RUN_API_EXAMPLES}")
fi
if [ -n "${RUN_SYSTEM_TESTS}" ]; then if [ -n "${RUN_SYSTEM_TESTS}" ]; then
BUILD_OPTS+=("--build-arg" "RUN_SYSTEM_TESTS=${RUN_SYSTEM_TESTS}") BUILD_OPTS+=("--build-arg" "RUN_SYSTEM_TESTS=${RUN_SYSTEM_TESTS}")
fi fi

View file

@ -6,5 +6,46 @@ set -x
set -e set -e
set -o pipefail set -o pipefail
echo "Not implemented" # Get defaults
exit 1 source "${SCRIPT_DIR}/ci_defaults.sh"
if [ -z "${TRAVIS_BUILD_DIR}" ]; then
echo "TRAVIS_BUILD_DIR must be set to root of Z3 repository"
exit 1
fi
if [ ! -d "${TRAVIS_BUILD_DIR}" ]; then
echo "TRAVIS_BUILD_DIR must be a directory"
exit 1
fi
# These variables are specific to the macOS TravisCI
# implementation and are not set in `ci_defaults.sh`.
export PYTHON_EXECUTABLE="${PYTHON_EXECUTABLE:-$(which python)}"
export Z3_SRC_DIR="${TRAVIS_BUILD_DIR}"
export Z3_BUILD_DIR="${Z3_SRC_DIR}/build"
export Z3_SYSTEM_TEST_DIR="${Z3_SRC_DIR}/z3_system_test"
# Overwrite whatever what set in TravisCI
export CC="${C_COMPILER}"
export CXX="${CXX_COMPILER}"
if [ "X${MACOS_SKIP_DEPS_UPDATE}" = "X1" ]; then
# This is just for local testing to avoid updating
echo "Skipping dependency update"
else
"${SCRIPT_DIR}/install_deps_osx.sh"
fi
# Build Z3
"${SCRIPT_DIR}/build_z3_cmake.sh"
# Test building docs
"${SCRIPT_DIR}/test_z3_docs.sh"
# Test examples
"${SCRIPT_DIR}/test_z3_examples_cmake.sh"
# Run unit tests
"${SCRIPT_DIR}/test_z3_unit_tests_cmake.sh"
# Run system tests
"${SCRIPT_DIR}/test_z3_system_tests.sh"
# Test install
"${SCRIPT_DIR}/test_z3_install_cmake.sh"

View file

@ -0,0 +1,7 @@
# Suppression files
This directory contains suppression files used by various
program analysis tools.
Suppression files tell a program analysis tool to suppress
various warnings/errors.

View file

@ -0,0 +1,3 @@
# Maintainers
- Dan Liew (@delcypher)

View file

@ -0,0 +1,4 @@
# Sanitizer supression files
This directory contains files used to suppress
ASan/LSan/UBSan warnings/errors.

View file

@ -0,0 +1 @@
# AddressSanitizer suppression file

View file

@ -0,0 +1,5 @@
# LeakSanitizer suppression file
# Ignore Clang OpenMP leaks.
# See https://github.com/Z3Prover/z3/issues/1308
leak:___kmp_allocate

View file

@ -0,0 +1,7 @@
# UndefinedBehavior sanitizer suppression file
# FIXME: UBSan doesn't usually have false positives so we need to fix all of these!
# Occurs when running tptp example
# See https://github.com/Z3Prover/z3/issues/964
null:rational.h
null:mpq.h

View file

@ -188,7 +188,7 @@ try:
if Z3PY_ENABLED: if Z3PY_ENABLED:
print("Z3Py documentation enabled") print("Z3Py documentation enabled")
doxygen_config_substitutions['PYTHON_API_FILES'] = 'z3.py' doxygen_config_substitutions['PYTHON_API_FILES'] = 'z3*.py'
else: else:
print("Z3Py documentation disabled") print("Z3Py documentation disabled")
doxygen_config_substitutions['PYTHON_API_FILES'] = '' doxygen_config_substitutions['PYTHON_API_FILES'] = ''
@ -288,8 +288,21 @@ try:
# Put z3py at the beginning of the search path to try to avoid picking up # Put z3py at the beginning of the search path to try to avoid picking up
# an installed copy of Z3py. # an installed copy of Z3py.
sys.path.insert(0, os.path.dirname(Z3PY_PACKAGE_PATH)) sys.path.insert(0, os.path.dirname(Z3PY_PACKAGE_PATH))
pydoc.writedoc('z3') for modulename in (
shutil.move('z3.html', os.path.join(OUTPUT_DIRECTORY, 'html', 'z3.html')) 'z3',
'z3.z3consts',
'z3.z3core',
'z3.z3num',
'z3.z3poly',
'z3.z3printer',
'z3.z3rcf',
'z3.z3types',
'z3.z3util',
):
pydoc.writedoc(modulename)
doc = modulename + '.html'
shutil.move(doc, os.path.join(OUTPUT_DIRECTORY, 'html', doc))
print("Generated pydoc Z3Py documentation.") print("Generated pydoc Z3Py documentation.")
if ML_ENABLED: if ML_ENABLED:

View file

@ -7,6 +7,30 @@ else()
set(EXTERNAL_PROJECT_BUILD_ALWAYS_ARG "") set(EXTERNAL_PROJECT_BUILD_ALWAYS_ARG "")
endif() endif()
option(Z3_C_EXAMPLES_FORCE_CXX_LINKER
"Force C++ linker when building C example projects" OFF)
if (Z3_C_EXAMPLES_FORCE_CXX_LINKER)
# HACK: This is a workaround for UBSan.
message(STATUS "Forcing C++ linker to be used when building example C projects")
set(EXTERNAL_C_PROJ_USE_CXX_LINKER_ARG
"-DFORCE_CXX_LINKER=ON"
)
else()
set(EXTERNAL_C_PROJ_USE_CXX_LINKER_ARG "")
endif()
if (DEFINED CMAKE_CONFIGURATION_TYPES)
message(WARNING
"Cannot set built type of external project when building with a "
"multi-configuration generator")
set(EXTERNAL_PROJECT_CMAKE_BUILD_TYPE_ARG "")
else()
set(EXTERNAL_PROJECT_CMAKE_BUILD_TYPE_ARG
"-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}"
)
endif()
################################################################################ ################################################################################
# Build example project using libz3's C API as an external project # Build example project using libz3's C API as an external project
################################################################################ ################################################################################
@ -14,7 +38,10 @@ ExternalProject_Add(c_example
DEPENDS libz3 DEPENDS libz3
# Configure step # Configure step
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/c" SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/c"
CMAKE_ARGS "-DZ3_DIR=${CMAKE_BINARY_DIR}" CMAKE_ARGS
"-DZ3_DIR=${CMAKE_BINARY_DIR}"
"${EXTERNAL_C_PROJ_USE_CXX_LINKER_ARG}"
"${EXTERNAL_PROJECT_CMAKE_BUILD_TYPE_ARG}"
# Build step # Build step
${EXTERNAL_PROJECT_BUILD_ALWAYS_ARG} ${EXTERNAL_PROJECT_BUILD_ALWAYS_ARG}
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/c_example_build_dir" BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/c_example_build_dir"
@ -30,7 +57,10 @@ ExternalProject_Add(c_maxsat_example
DEPENDS libz3 DEPENDS libz3
# Configure step # Configure step
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/maxsat" SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/maxsat"
CMAKE_ARGS "-DZ3_DIR=${CMAKE_BINARY_DIR}" CMAKE_ARGS
"-DZ3_DIR=${CMAKE_BINARY_DIR}"
"${EXTERNAL_C_PROJ_USE_CXX_LINKER_ARG}"
"${EXTERNAL_PROJECT_CMAKE_BUILD_TYPE_ARG}"
# Build step # Build step
${EXTERNAL_PROJECT_BUILD_ALWAYS_ARG} ${EXTERNAL_PROJECT_BUILD_ALWAYS_ARG}
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/c_maxsat_example_build_dir" BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/c_maxsat_example_build_dir"
@ -47,7 +77,9 @@ ExternalProject_Add(cpp_example
DEPENDS libz3 DEPENDS libz3
# Configure step # Configure step
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/c++" SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/c++"
CMAKE_ARGS "-DZ3_DIR=${CMAKE_BINARY_DIR}" CMAKE_ARGS
"-DZ3_DIR=${CMAKE_BINARY_DIR}"
"${EXTERNAL_PROJECT_CMAKE_BUILD_TYPE_ARG}"
# Build step # Build step
${EXTERNAL_PROJECT_BUILD_ALWAYS_ARG} ${EXTERNAL_PROJECT_BUILD_ALWAYS_ARG}
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/cpp_example_build_dir" BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/cpp_example_build_dir"
@ -63,7 +95,9 @@ ExternalProject_Add(z3_tptp5
DEPENDS libz3 DEPENDS libz3
# Configure step # Configure step
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/tptp" SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/tptp"
CMAKE_ARGS "-DZ3_DIR=${CMAKE_BINARY_DIR}" CMAKE_ARGS
"-DZ3_DIR=${CMAKE_BINARY_DIR}"
"${EXTERNAL_PROJECT_CMAKE_BUILD_TYPE_ARG}"
# Build step # Build step
${EXTERNAL_PROJECT_BUILD_ALWAYS_ARG} ${EXTERNAL_PROJECT_BUILD_ALWAYS_ARG}
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/tptp_build_dir" BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/tptp_build_dir"

View file

@ -470,7 +470,7 @@ void unsat_core_example2() {
// The solver s already contains p1 => F // The solver s already contains p1 => F
// To disable F, we add (not p1) as an additional assumption // To disable F, we add (not p1) as an additional assumption
qs.push_back(!p1); qs.push_back(!p1);
std::cout << s.check(qs.size(), &qs[0]) << "\n"; std::cout << s.check((unsigned)qs.size(), &qs[0]) << "\n";
expr_vector core2 = s.unsat_core(); expr_vector core2 = s.unsat_core();
std::cout << core2 << "\n"; std::cout << core2 << "\n";
std::cout << "size: " << core2.size() << "\n"; std::cout << "size: " << core2.size() << "\n";

View file

@ -7,6 +7,19 @@
# the C++ standard library in resulting in a link failure. # the C++ standard library in resulting in a link failure.
project(Z3_C_EXAMPLE C CXX) project(Z3_C_EXAMPLE C CXX)
cmake_minimum_required(VERSION 2.8.12) cmake_minimum_required(VERSION 2.8.12)
# Set C version required to C99
if ("${CMAKE_VERSION}" VERSION_LESS "3.1")
if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR
("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang"))
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 ")
endif()
else()
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_EXTENSIONS OFF)
endif()
find_package(Z3 find_package(Z3
REQUIRED REQUIRED
CONFIG CONFIG
@ -22,6 +35,17 @@ message(STATUS "Found Z3 ${Z3_VERSION_STRING}")
message(STATUS "Z3_DIR: ${Z3_DIR}") message(STATUS "Z3_DIR: ${Z3_DIR}")
add_executable(c_example test_capi.c) add_executable(c_example test_capi.c)
option(FORCE_CXX_LINKER "Force linker with C++ linker" OFF)
if (FORCE_CXX_LINKER)
# This is a hack for avoiding UBSan linking errors
message(STATUS "Forcing use of C++ linker")
set_target_properties(c_example
PROPERTIES
LINKER_LANGUAGE CXX
)
endif()
target_include_directories(c_example PRIVATE ${Z3_C_INCLUDE_DIRS}) target_include_directories(c_example PRIVATE ${Z3_C_INCLUDE_DIRS})
target_link_libraries(c_example PRIVATE ${Z3_LIBRARIES}) target_link_libraries(c_example PRIVATE ${Z3_LIBRARIES})

View file

@ -65,6 +65,15 @@ void throw_z3_error(Z3_context c, Z3_error_code e)
longjmp(g_catch_buffer, e); longjmp(g_catch_buffer, e);
} }
/**
\brief Error handling that depends on checking an error code on the context.
*/
void nothrow_z3_error(Z3_context c, Z3_error_code e) {
// no-op
}
/** /**
\brief Create a logical context. \brief Create a logical context.
@ -1592,18 +1601,16 @@ void error_code_example1()
void error_code_example2() { void error_code_example2() {
Z3_config cfg; Z3_config cfg;
Z3_context ctx = NULL; Z3_context ctx = NULL;
int r; Z3_error_code e;
printf("\nerror_code_example2\n"); printf("\nerror_code_example2\n");
LOG_MSG("error_code_example2"); LOG_MSG("error_code_example2");
/* low tech try&catch */ if (1) {
r = setjmp(g_catch_buffer);
if (r == 0) {
Z3_ast x, y, app; Z3_ast x, y, app;
cfg = Z3_mk_config(); cfg = Z3_mk_config();
ctx = mk_context_custom(cfg, throw_z3_error); ctx = mk_context_custom(cfg, nothrow_z3_error);
Z3_del_config(cfg); Z3_del_config(cfg);
x = mk_int_var(ctx, "x"); x = mk_int_var(ctx, "x");
@ -1611,11 +1618,14 @@ void error_code_example2() {
printf("before Z3_mk_iff\n"); printf("before Z3_mk_iff\n");
/* the next call will produce an error */ /* the next call will produce an error */
app = Z3_mk_iff(ctx, x, y); app = Z3_mk_iff(ctx, x, y);
e = Z3_get_error_code(ctx);
if (e != Z3_OK) goto err;
unreachable(); unreachable();
Z3_del_context(ctx); Z3_del_context(ctx);
} }
else { else {
printf("Z3 error: %s.\n", Z3_get_error_msg(ctx, (Z3_error_code)r)); err:
printf("Z3 error: %s.\n", Z3_get_error_msg(ctx, e));
if (ctx != NULL) { if (ctx != NULL) {
Z3_del_context(ctx); Z3_del_context(ctx);
} }
@ -1781,15 +1791,14 @@ void parser_example5() {
Z3_config cfg; Z3_config cfg;
Z3_context ctx = NULL; Z3_context ctx = NULL;
Z3_solver s = NULL; Z3_solver s = NULL;
int r; Z3_error_code e;
printf("\nparser_example5\n"); printf("\nparser_example5\n");
LOG_MSG("parser_example5"); LOG_MSG("parser_example5");
r = setjmp(g_catch_buffer); if (1) {
if (r == 0) {
cfg = Z3_mk_config(); cfg = Z3_mk_config();
ctx = mk_context_custom(cfg, throw_z3_error); ctx = mk_context_custom(cfg, nothrow_z3_error);
s = mk_solver(ctx); s = mk_solver(ctx);
Z3_del_config(cfg); Z3_del_config(cfg);
@ -1798,12 +1807,15 @@ void parser_example5() {
"(benchmark tst :extrafuns ((x Int (y Int)) :formula (> x y) :formula (> x 0))", "(benchmark tst :extrafuns ((x Int (y Int)) :formula (> x y) :formula (> x 0))",
0, 0, 0, 0, 0, 0,
0, 0, 0); 0, 0, 0);
e = Z3_get_error_code(ctx);
if (e != Z3_OK) goto err;
unreachable(); unreachable();
del_solver(ctx, s); del_solver(ctx, s);
Z3_del_context(ctx); Z3_del_context(ctx);
} }
else { else {
printf("Z3 error: %s.\n", Z3_get_error_msg(ctx, (Z3_error_code)r)); err:
printf("Z3 error: %s.\n", Z3_get_error_msg(ctx, e));
if (ctx != NULL) { if (ctx != NULL) {
printf("Error message: '%s'.\n",Z3_get_smtlib_error(ctx)); printf("Error message: '%s'.\n",Z3_get_smtlib_error(ctx));
del_solver(ctx, s); del_solver(ctx, s);
@ -2639,6 +2651,7 @@ void smt2parser_example() {
ctx = mk_context(); ctx = mk_context();
fs = Z3_parse_smtlib2_string(ctx, "(declare-fun a () (_ BitVec 8)) (assert (bvuge a #x10)) (assert (bvule a #xf0))", 0, 0, 0, 0, 0, 0); fs = Z3_parse_smtlib2_string(ctx, "(declare-fun a () (_ BitVec 8)) (assert (bvuge a #x10)) (assert (bvule a #xf0))", 0, 0, 0, 0, 0, 0);
printf("formulas: %s\n", Z3_ast_to_string(ctx, fs)); printf("formulas: %s\n", Z3_ast_to_string(ctx, fs));
Z3_del_context(ctx); Z3_del_context(ctx);
} }
@ -2756,80 +2769,279 @@ void fpa_example() {
double_sort = Z3_mk_fpa_sort(ctx, 11, 53); double_sort = Z3_mk_fpa_sort(ctx, 11, 53);
rm_sort = Z3_mk_fpa_rounding_mode_sort(ctx); rm_sort = Z3_mk_fpa_rounding_mode_sort(ctx);
// Show that there are x, y s.t. (x + y) = 42.0 (with rounding mode). // Show that there are x, y s.t. (x + y) = 42.0 (with rounding mode).
s_rm = Z3_mk_string_symbol(ctx, "rm"); s_rm = Z3_mk_string_symbol(ctx, "rm");
rm = Z3_mk_const(ctx, s_rm, rm_sort); rm = Z3_mk_const(ctx, s_rm, rm_sort);
s_x = Z3_mk_string_symbol(ctx, "x"); s_x = Z3_mk_string_symbol(ctx, "x");
s_y = Z3_mk_string_symbol(ctx, "y"); s_y = Z3_mk_string_symbol(ctx, "y");
x = Z3_mk_const(ctx, s_x, double_sort); x = Z3_mk_const(ctx, s_x, double_sort);
y = Z3_mk_const(ctx, s_y, double_sort); y = Z3_mk_const(ctx, s_y, double_sort);
n = Z3_mk_fpa_numeral_double(ctx, 42.0, double_sort); n = Z3_mk_fpa_numeral_double(ctx, 42.0, double_sort);
s_x_plus_y = Z3_mk_string_symbol(ctx, "x_plus_y"); s_x_plus_y = Z3_mk_string_symbol(ctx, "x_plus_y");
x_plus_y = Z3_mk_const(ctx, s_x_plus_y, double_sort); x_plus_y = Z3_mk_const(ctx, s_x_plus_y, double_sort);
c1 = Z3_mk_eq(ctx, x_plus_y, Z3_mk_fpa_add(ctx, rm, x, y)); c1 = Z3_mk_eq(ctx, x_plus_y, Z3_mk_fpa_add(ctx, rm, x, y));
args[0] = c1; args[0] = c1;
args[1] = Z3_mk_eq(ctx, x_plus_y, n); args[1] = Z3_mk_eq(ctx, x_plus_y, n);
c2 = Z3_mk_and(ctx, 2, (Z3_ast*)&args); c2 = Z3_mk_and(ctx, 2, (Z3_ast*)&args);
args2[0] = c2; args2[0] = c2;
args2[1] = Z3_mk_not(ctx, Z3_mk_eq(ctx, rm, Z3_mk_fpa_rtz(ctx))); args2[1] = Z3_mk_not(ctx, Z3_mk_eq(ctx, rm, Z3_mk_fpa_rtz(ctx)));
c3 = Z3_mk_and(ctx, 2, (Z3_ast*)&args2); c3 = Z3_mk_and(ctx, 2, (Z3_ast*)&args2);
and_args[0] = Z3_mk_not(ctx, Z3_mk_fpa_is_zero(ctx, y)); and_args[0] = Z3_mk_not(ctx, Z3_mk_fpa_is_zero(ctx, y));
and_args[1] = Z3_mk_not(ctx, Z3_mk_fpa_is_nan(ctx, y)); and_args[1] = Z3_mk_not(ctx, Z3_mk_fpa_is_nan(ctx, y));
and_args[2] = Z3_mk_not(ctx, Z3_mk_fpa_is_infinite(ctx, y)); and_args[2] = Z3_mk_not(ctx, Z3_mk_fpa_is_infinite(ctx, y));
args3[0] = c3; args3[0] = c3;
args3[1] = Z3_mk_and(ctx, 3, and_args); args3[1] = Z3_mk_and(ctx, 3, and_args);
c4 = Z3_mk_and(ctx, 2, (Z3_ast*)&args3); c4 = Z3_mk_and(ctx, 2, (Z3_ast*)&args3);
printf("c4: %s\n", Z3_ast_to_string(ctx, c4)); printf("c4: %s\n", Z3_ast_to_string(ctx, c4));
Z3_solver_push(ctx, s); Z3_solver_push(ctx, s);
Z3_solver_assert(ctx, s, c4); Z3_solver_assert(ctx, s, c4);
check(ctx, s, Z3_L_TRUE); check(ctx, s, Z3_L_TRUE);
Z3_solver_pop(ctx, s, 1); Z3_solver_pop(ctx, s, 1);
// Show that the following are equal: // Show that the following are equal:
// (fp #b0 #b10000000001 #xc000000000000) // (fp #b0 #b10000000001 #xc000000000000)
// ((_ to_fp 11 53) #x401c000000000000)) // ((_ to_fp 11 53) #x401c000000000000))
// ((_ to_fp 11 53) RTZ 1.75 2))) // ((_ to_fp 11 53) RTZ 1.75 2)))
// ((_ to_fp 11 53) RTZ 7.0))) // ((_ to_fp 11 53) RTZ 7.0)))
Z3_solver_push(ctx, s); Z3_solver_push(ctx, s);
c1 = Z3_mk_fpa_fp(ctx, c1 = Z3_mk_fpa_fp(ctx,
Z3_mk_numeral(ctx, "0", Z3_mk_bv_sort(ctx, 1)), Z3_mk_numeral(ctx, "0", Z3_mk_bv_sort(ctx, 1)),
Z3_mk_numeral(ctx, "1025", Z3_mk_bv_sort(ctx, 11)), Z3_mk_numeral(ctx, "1025", Z3_mk_bv_sort(ctx, 11)),
Z3_mk_numeral(ctx, "3377699720527872", Z3_mk_bv_sort(ctx, 52))); Z3_mk_numeral(ctx, "3377699720527872", Z3_mk_bv_sort(ctx, 52)));
c2 = Z3_mk_fpa_to_fp_bv(ctx, c2 = Z3_mk_fpa_to_fp_bv(ctx,
Z3_mk_numeral(ctx, "4619567317775286272", Z3_mk_bv_sort(ctx, 64)), Z3_mk_numeral(ctx, "4619567317775286272", Z3_mk_bv_sort(ctx, 64)),
Z3_mk_fpa_sort(ctx, 11, 53)); Z3_mk_fpa_sort(ctx, 11, 53));
c3 = Z3_mk_fpa_to_fp_int_real(ctx, c3 = Z3_mk_fpa_to_fp_int_real(ctx,
Z3_mk_fpa_rtz(ctx), Z3_mk_fpa_rtz(ctx),
Z3_mk_numeral(ctx, "2", Z3_mk_int_sort(ctx)), /* exponent */ Z3_mk_numeral(ctx, "2", Z3_mk_int_sort(ctx)), /* exponent */
Z3_mk_numeral(ctx, "1.75", Z3_mk_real_sort(ctx)), /* significand */ Z3_mk_numeral(ctx, "1.75", Z3_mk_real_sort(ctx)), /* significand */
Z3_mk_fpa_sort(ctx, 11, 53)); Z3_mk_fpa_sort(ctx, 11, 53));
c4 = Z3_mk_fpa_to_fp_real(ctx, c4 = Z3_mk_fpa_to_fp_real(ctx,
Z3_mk_fpa_rtz(ctx), Z3_mk_fpa_rtz(ctx),
Z3_mk_numeral(ctx, "7.0", Z3_mk_real_sort(ctx)), Z3_mk_numeral(ctx, "7.0", Z3_mk_real_sort(ctx)),
Z3_mk_fpa_sort(ctx, 11, 53)); Z3_mk_fpa_sort(ctx, 11, 53));
args3[0] = Z3_mk_eq(ctx, c1, c2); args3[0] = Z3_mk_eq(ctx, c1, c2);
args3[1] = Z3_mk_eq(ctx, c1, c3); args3[1] = Z3_mk_eq(ctx, c1, c3);
args3[2] = Z3_mk_eq(ctx, c1, c4); args3[2] = Z3_mk_eq(ctx, c1, c4);
c5 = Z3_mk_and(ctx, 3, args3); c5 = Z3_mk_and(ctx, 3, args3);
printf("c5: %s\n", Z3_ast_to_string(ctx, c5)); printf("c5: %s\n", Z3_ast_to_string(ctx, c5));
Z3_solver_assert(ctx, s, c5); Z3_solver_assert(ctx, s, c5);
check(ctx, s, Z3_L_TRUE); check(ctx, s, Z3_L_TRUE);
Z3_solver_pop(ctx, s, 1); Z3_solver_pop(ctx, s, 1);
del_solver(ctx, s); del_solver(ctx, s);
Z3_del_context(ctx); Z3_del_context(ctx);
} }
/**
\brief Demonstrates some basic features of model construction
*/
void mk_model_example() {
Z3_context ctx;
Z3_model m;
Z3_sort intSort;
Z3_symbol aSymbol, bSymbol, cSymbol;
Z3_func_decl aFuncDecl, bFuncDecl, cFuncDecl;
Z3_ast aApp, bApp, cApp;
Z3_sort int2intArraySort;
Z3_ast zeroNumeral, oneNumeral, twoNumeral, threeNumeral, fourNumeral;
Z3_sort arrayDomain[1];
Z3_func_decl cAsFuncDecl;
Z3_func_interp cAsFuncInterp;
Z3_ast_vector zeroArgs;
Z3_ast_vector oneArgs;
Z3_ast cFuncDeclAsArray;
Z3_string modelAsString;
printf("\nmk_model_example\n");
ctx = mk_context();
// Construct empty model
m = Z3_mk_model(ctx);
Z3_model_inc_ref(ctx, m);
// Create constants "a" and "b"
intSort = Z3_mk_int_sort(ctx);
aSymbol = Z3_mk_string_symbol(ctx, "a");
aFuncDecl = Z3_mk_func_decl(ctx, aSymbol,
/*domain_size=*/0,
/*domain=*/NULL,
/*range=*/intSort);
aApp = Z3_mk_app(ctx, aFuncDecl,
/*num_args=*/0,
/*args=*/NULL);
bSymbol = Z3_mk_string_symbol(ctx, "b");
bFuncDecl = Z3_mk_func_decl(ctx, bSymbol,
/*domain_size=*/0,
/*domain=*/NULL,
/*range=*/intSort);
bApp = Z3_mk_app(ctx, bFuncDecl,
/*num_args=*/0,
/*args=*/NULL);
// Create array "c" that maps int to int.
cSymbol = Z3_mk_string_symbol(ctx, "c");
int2intArraySort = Z3_mk_array_sort(ctx,
/*domain=*/intSort,
/*range=*/intSort);
cFuncDecl = Z3_mk_func_decl(ctx, cSymbol,
/*domain_size=*/0,
/*domain=*/NULL,
/*range=*/int2intArraySort);
cApp = Z3_mk_app(ctx, cFuncDecl,
/*num_args=*/0,
/*args=*/NULL);
// Create numerals to be used in model
zeroNumeral = Z3_mk_int(ctx, 0, intSort);
oneNumeral = Z3_mk_int(ctx, 1, intSort);
twoNumeral = Z3_mk_int(ctx, 2, intSort);
threeNumeral = Z3_mk_int(ctx, 3, intSort);
fourNumeral = Z3_mk_int(ctx, 4, intSort);
// Add assignments to model
// a == 1
Z3_add_const_interp(ctx, m, aFuncDecl, oneNumeral);
// b == 2
Z3_add_const_interp(ctx, m, bFuncDecl, twoNumeral);
// Create a fresh function that represents
// reading from array.
arrayDomain[0] = intSort;
cAsFuncDecl = Z3_mk_fresh_func_decl(ctx,
/*prefix=*/"",
/*domain_size*/ 1,
/*domain=*/arrayDomain,
/*sort=*/intSort);
// Create function interpretation with default
// value of "0".
cAsFuncInterp =
Z3_add_func_interp(ctx, m, cAsFuncDecl,
/*default_value=*/zeroNumeral);
Z3_func_interp_inc_ref(ctx, cAsFuncInterp);
// Add [0] = 3
zeroArgs = Z3_mk_ast_vector(ctx);
Z3_ast_vector_inc_ref(ctx, zeroArgs);
Z3_ast_vector_push(ctx, zeroArgs, zeroNumeral);
Z3_func_interp_add_entry(ctx, cAsFuncInterp, zeroArgs, threeNumeral);
// Add [1] = 4
oneArgs = Z3_mk_ast_vector(ctx);
Z3_ast_vector_inc_ref(ctx, oneArgs);
Z3_ast_vector_push(ctx, oneArgs, oneNumeral);
Z3_func_interp_add_entry(ctx, cAsFuncInterp, oneArgs, fourNumeral);
// Now use the `(_ as_array)` to associate
// the `cAsFuncInterp` with the `cFuncDecl`
// in the model
cFuncDeclAsArray = Z3_mk_as_array(ctx, cAsFuncDecl);
Z3_add_const_interp(ctx, m, cFuncDecl, cFuncDeclAsArray);
// Print the model
modelAsString = Z3_model_to_string(ctx, m);
printf("Model:\n%s\n", modelAsString);
// Check the interpretations we expect to be present
// are.
{
Z3_func_decl expectedInterpretations[3] = {aFuncDecl, bFuncDecl, cFuncDecl};
int index;
for (index = 0;
index < sizeof(expectedInterpretations) / sizeof(Z3_func_decl);
++index) {
Z3_func_decl d = expectedInterpretations[index];
if (Z3_model_has_interp(ctx, m, d)) {
printf("Found interpretation for \"%s\"\n",
Z3_ast_to_string(ctx, Z3_func_decl_to_ast(ctx, d)));
} else {
printf("Missing interpretation");
exit(1);
}
}
}
{
// Evaluate a + b under model
Z3_ast addArgs[] = {aApp, bApp};
Z3_ast aPlusB = Z3_mk_add(ctx,
/*num_args=*/2,
/*args=*/addArgs);
Z3_ast aPlusBEval = NULL;
Z3_bool aPlusBEvalSuccess =
Z3_model_eval(ctx, m, aPlusB,
/*model_completion=*/Z3_FALSE, &aPlusBEval);
if (aPlusBEvalSuccess != Z3_TRUE) {
printf("Failed to evaluate model\n");
exit(1);
}
{
int aPlusBValue = 0;
Z3_bool getAPlusBValueSuccess =
Z3_get_numeral_int(ctx, aPlusBEval, &aPlusBValue);
if (getAPlusBValueSuccess != Z3_TRUE) {
printf("Failed to get integer value for a+b\n");
exit(1);
}
printf("Evaluated a + b = %d\n", aPlusBValue);
if (aPlusBValue != 3) {
printf("a+b did not evaluate to expected value\n");
exit(1);
}
}
}
{
// Evaluate c[0] + c[1] + c[2] under model
Z3_ast c0 = Z3_mk_select(ctx, cApp, zeroNumeral);
Z3_ast c1 = Z3_mk_select(ctx, cApp, oneNumeral);
Z3_ast c2 = Z3_mk_select(ctx, cApp, twoNumeral);
Z3_ast arrayAddArgs[] = {c0, c1, c2};
Z3_ast arrayAdd = Z3_mk_add(ctx,
/*num_args=*/3,
/*args=*/arrayAddArgs);
Z3_ast arrayAddEval = NULL;
Z3_bool arrayAddEvalSuccess =
Z3_model_eval(ctx, m, arrayAdd,
/*model_completion=*/Z3_FALSE, &arrayAddEval);
if (arrayAddEvalSuccess != Z3_TRUE) {
printf("Failed to evaluate model\n");
exit(1);
}
{
int arrayAddValue = 0;
Z3_bool getArrayAddValueSuccess =
Z3_get_numeral_int(ctx, arrayAddEval, &arrayAddValue);
if (getArrayAddValueSuccess != Z3_TRUE) {
printf("Failed to get integer value for c[0] + c[1] + c[2]\n");
exit(1);
}
printf("Evaluated c[0] + c[1] + c[2] = %d\n", arrayAddValue);
if (arrayAddValue != 7) {
printf("c[0] + c[1] + c[2] did not evaluate to expected value\n");
exit(1);
}
}
}
Z3_ast_vector_dec_ref(ctx, oneArgs);
Z3_ast_vector_dec_ref(ctx, zeroArgs);
Z3_func_interp_dec_ref(ctx, cAsFuncInterp);
Z3_model_dec_ref(ctx, m);
Z3_del_context(ctx);
}
/*@}*/ /*@}*/
/*@}*/ /*@}*/
int main() { int main() {
#ifdef LOG_Z3_CALLS #ifdef LOG_Z3_CALLS
Z3_open_log("z3.log"); Z3_open_log("z3.log");
@ -2873,5 +3085,6 @@ int main() {
substitute_example(); substitute_example();
substitute_vars_example(); substitute_vars_example();
fpa_example(); fpa_example();
mk_model_example();
return 0; return 0;
} }

View file

@ -25,6 +25,16 @@ add_executable(c_maxsat_example maxsat.c)
target_include_directories(c_maxsat_example PRIVATE ${Z3_C_INCLUDE_DIRS}) target_include_directories(c_maxsat_example PRIVATE ${Z3_C_INCLUDE_DIRS})
target_link_libraries(c_maxsat_example PRIVATE ${Z3_LIBRARIES}) target_link_libraries(c_maxsat_example PRIVATE ${Z3_LIBRARIES})
option(FORCE_CXX_LINKER "Force linker with C++ linker" OFF)
if (FORCE_CXX_LINKER)
# This is a hack for avoiding UBSan linking errors
message(STATUS "Forcing use of C++ linker")
set_target_properties(c_maxsat_example
PROPERTIES
LINKER_LANGUAGE CXX
)
endif()
if ("${CMAKE_SYSTEM_NAME}" MATCHES "[Ww]indows") if ("${CMAKE_SYSTEM_NAME}" MATCHES "[Ww]indows")
# On Windows we need to copy the Z3 libraries # On Windows we need to copy the Z3 libraries
# into the same directory as the executable # into the same directory as the executable

View file

@ -587,6 +587,14 @@ def mk_def_file_internal(defname, dll_name, export_header_files):
############################################################################### ###############################################################################
# Functions for generating ``gparams_register_modules.cpp`` # Functions for generating ``gparams_register_modules.cpp``
############################################################################### ###############################################################################
def path_after_src(h_file):
h_file = h_file.replace("\\","/")
idx = h_file.rfind("src/")
if idx == -1:
return h_file
return h_file[idx + 4:]
def mk_gparams_register_modules_internal(h_files_full_path, path): def mk_gparams_register_modules_internal(h_files_full_path, path):
""" """
Generate a ``gparams_register_modules.cpp`` file in the directory ``path``. Generate a ``gparams_register_modules.cpp`` file in the directory ``path``.
@ -608,7 +616,7 @@ def mk_gparams_register_modules_internal(h_files_full_path, path):
fullname = os.path.join(path, 'gparams_register_modules.cpp') fullname = os.path.join(path, 'gparams_register_modules.cpp')
fout = open(fullname, 'w') fout = open(fullname, 'w')
fout.write('// Automatically generated file.\n') fout.write('// Automatically generated file.\n')
fout.write('#include"gparams.h"\n') fout.write('#include "util/gparams.h"\n')
reg_pat = re.compile('[ \t]*REG_PARAMS\(\'([^\']*)\'\)') reg_pat = re.compile('[ \t]*REG_PARAMS\(\'([^\']*)\'\)')
reg_mod_pat = re.compile('[ \t]*REG_MODULE_PARAMS\(\'([^\']*)\', *\'([^\']*)\'\)') reg_mod_pat = re.compile('[ \t]*REG_MODULE_PARAMS\(\'([^\']*)\', *\'([^\']*)\'\)')
reg_mod_descr_pat = re.compile('[ \t]*REG_MODULE_DESCRIPTION\(\'([^\']*)\', *\'([^\']*)\'\)') reg_mod_descr_pat = re.compile('[ \t]*REG_MODULE_DESCRIPTION\(\'([^\']*)\', *\'([^\']*)\'\)')
@ -620,13 +628,13 @@ def mk_gparams_register_modules_internal(h_files_full_path, path):
if m: if m:
if not added_include: if not added_include:
added_include = True added_include = True
fout.write('#include"%s"\n' % os.path.basename(h_file)) fout.write('#include "%s"\n' % path_after_src(h_file))
cmds.append((m.group(1))) cmds.append((m.group(1)))
m = reg_mod_pat.match(line) m = reg_mod_pat.match(line)
if m: if m:
if not added_include: if not added_include:
added_include = True added_include = True
fout.write('#include"%s"\n' % os.path.basename(h_file)) fout.write('#include "%s"\n' % path_after_src(h_file))
mod_cmds.append((m.group(1), m.group(2))) mod_cmds.append((m.group(1), m.group(2)))
m = reg_mod_descr_pat.match(line) m = reg_mod_descr_pat.match(line)
if m: if m:
@ -680,9 +688,9 @@ def mk_install_tactic_cpp_internal(h_files_full_path, path):
fullname = os.path.join(path, 'install_tactic.cpp') fullname = os.path.join(path, 'install_tactic.cpp')
fout = open(fullname, 'w') fout = open(fullname, 'w')
fout.write('// Automatically generated file.\n') fout.write('// Automatically generated file.\n')
fout.write('#include"tactic.h"\n') fout.write('#include "tactic/tactic.h"\n')
fout.write('#include"tactic_cmds.h"\n') fout.write('#include "cmd_context/tactic_cmds.h"\n')
fout.write('#include"cmd_context.h"\n') fout.write('#include "cmd_context/cmd_context.h"\n')
tactic_pat = re.compile('[ \t]*ADD_TACTIC\(.*\)') tactic_pat = re.compile('[ \t]*ADD_TACTIC\(.*\)')
probe_pat = re.compile('[ \t]*ADD_PROBE\(.*\)') probe_pat = re.compile('[ \t]*ADD_PROBE\(.*\)')
for h_file in sorted_headers_by_component(h_files_full_path): for h_file in sorted_headers_by_component(h_files_full_path):
@ -691,8 +699,8 @@ def mk_install_tactic_cpp_internal(h_files_full_path, path):
for line in fin: for line in fin:
if tactic_pat.match(line): if tactic_pat.match(line):
if not added_include: if not added_include:
added_include = True added_include = True
fout.write('#include"%s"\n' % os.path.basename(h_file)) fout.write('#include "%s"\n' % path_after_src(h_file))
try: try:
eval(line.strip('\n '), eval_globals, None) eval(line.strip('\n '), eval_globals, None)
except Exception as e: except Exception as e:
@ -702,7 +710,7 @@ def mk_install_tactic_cpp_internal(h_files_full_path, path):
if probe_pat.match(line): if probe_pat.match(line):
if not added_include: if not added_include:
added_include = True added_include = True
fout.write('#include"%s"\n' % os.path.basename(h_file)) fout.write('#include "%s"\n' % path_after_src(h_file))
try: try:
eval(line.strip('\n '), eval_globals, None) eval(line.strip('\n '), eval_globals, None)
except Exception as e: except Exception as e:
@ -764,19 +772,19 @@ def mk_mem_initializer_cpp_internal(h_files_full_path, path):
if m: if m:
if not added_include: if not added_include:
added_include = True added_include = True
fout.write('#include"%s"\n' % os.path.basename(h_file)) fout.write('#include "%s"\n' % path_after_src(h_file))
initializer_cmds.append((m.group(1), 0)) initializer_cmds.append((m.group(1), 0))
m = initializer_prio_pat.match(line) m = initializer_prio_pat.match(line)
if m: if m:
if not added_include: if not added_include:
added_include = True added_include = True
fout.write('#include"%s"\n' % os.path.basename(h_file)) fout.write('#include "%s"\n' % path_after_src(h_file))
initializer_cmds.append((m.group(1), int(m.group(2)))) initializer_cmds.append((m.group(1), int(m.group(2))))
m = finalizer_pat.match(line) m = finalizer_pat.match(line)
if m: if m:
if not added_include: if not added_include:
added_include = True added_include = True
fout.write('#include"%s"\n' % os.path.basename(h_file)) fout.write('#include "%s"\n' % path_after_src(h_file))
finalizer_cmds.append(m.group(1)) finalizer_cmds.append(m.group(1))
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')
@ -881,9 +889,9 @@ def mk_hpp_from_pyg(pyg_file, output_dir):
out.write('// Automatically generated file\n') out.write('// Automatically generated file\n')
out.write('#ifndef __%s_HPP_\n' % class_name.upper()) out.write('#ifndef __%s_HPP_\n' % class_name.upper())
out.write('#define __%s_HPP_\n' % class_name.upper()) out.write('#define __%s_HPP_\n' % class_name.upper())
out.write('#include"params.h"\n') out.write('#include "util/params.h"\n')
if export: if export:
out.write('#include"gparams.h"\n') out.write('#include "util/gparams.h"\n')
out.write('struct %s {\n' % class_name) out.write('struct %s {\n' % class_name)
out.write(' params_ref const & p;\n') out.write(' params_ref const & p;\n')
if export: if export:

View file

@ -23,6 +23,7 @@ def init_project_def():
add_lib('subpaving', ['interval'], 'math/subpaving') add_lib('subpaving', ['interval'], 'math/subpaving')
add_lib('ast', ['util', 'polynomial']) add_lib('ast', ['util', 'polynomial'])
add_lib('rewriter', ['ast', 'polynomial', 'automata'], 'ast/rewriter') add_lib('rewriter', ['ast', 'polynomial', 'automata'], 'ast/rewriter')
add_lib('macros', ['rewriter'], 'ast/macros')
add_lib('normal_forms', ['rewriter'], 'ast/normal_forms') add_lib('normal_forms', ['rewriter'], 'ast/normal_forms')
add_lib('model', ['rewriter']) add_lib('model', ['rewriter'])
add_lib('tactic', ['ast', 'model']) add_lib('tactic', ['ast', 'model'])
@ -30,30 +31,26 @@ def init_project_def():
add_lib('parser_util', ['ast'], 'parsers/util') add_lib('parser_util', ['ast'], 'parsers/util')
add_lib('grobner', ['ast'], 'math/grobner') add_lib('grobner', ['ast'], 'math/grobner')
add_lib('euclid', ['util'], 'math/euclid') add_lib('euclid', ['util'], 'math/euclid')
add_lib('core_tactics', ['tactic', 'normal_forms'], 'tactic/core') add_lib('core_tactics', ['tactic', 'macros', 'normal_forms', 'rewriter'], 'tactic/core')
add_lib('sat_tactic', ['tactic', 'sat'], 'sat/tactic') add_lib('sat_tactic', ['tactic', 'sat'], 'sat/tactic')
add_lib('arith_tactics', ['core_tactics', 'sat'], 'tactic/arith') add_lib('arith_tactics', ['core_tactics', 'sat'], 'tactic/arith')
add_lib('nlsat_tactic', ['nlsat', 'sat_tactic', 'arith_tactics'], 'nlsat/tactic') add_lib('nlsat_tactic', ['nlsat', 'sat_tactic', 'arith_tactics'], 'nlsat/tactic')
add_lib('subpaving_tactic', ['core_tactics', 'subpaving'], 'math/subpaving/tactic') add_lib('subpaving_tactic', ['core_tactics', 'subpaving'], 'math/subpaving/tactic')
add_lib('aig_tactic', ['tactic'], 'tactic/aig') add_lib('aig_tactic', ['tactic'], 'tactic/aig')
add_lib('solver', ['model', 'tactic']) add_lib('proofs', ['rewriter', 'util'], 'ast/proofs')
add_lib('solver', ['model', 'tactic', 'proofs'])
add_lib('ackermannization', ['model', 'rewriter', 'ast', 'solver', 'tactic'], 'ackermannization') add_lib('ackermannization', ['model', 'rewriter', 'ast', 'solver', 'tactic'], 'ackermannization')
add_lib('interp', ['solver']) add_lib('interp', ['solver'])
add_lib('cmd_context', ['solver', 'rewriter', 'interp']) add_lib('cmd_context', ['solver', 'rewriter', 'interp'])
add_lib('extra_cmds', ['cmd_context', 'subpaving_tactic', 'arith_tactics'], 'cmd_context/extra_cmds') add_lib('extra_cmds', ['cmd_context', 'subpaving_tactic', 'arith_tactics'], 'cmd_context/extra_cmds')
add_lib('smt2parser', ['cmd_context', 'parser_util'], 'parsers/smt2') add_lib('smt2parser', ['cmd_context', 'parser_util'], 'parsers/smt2')
add_lib('proof_checker', ['rewriter'], 'ast/proof_checker') add_lib('fpa', ['ast', 'util', 'rewriter', 'model'], 'ast/fpa')
# Simplifier module will be deleted in the future. add_lib('pattern', ['normal_forms', 'smt2parser', 'rewriter'], 'ast/pattern')
# It has been replaced with rewriter module. add_lib('bit_blaster', ['rewriter', 'rewriter'], 'ast/rewriter/bit_blaster')
add_lib('simplifier', ['rewriter'], 'ast/simplifier') add_lib('smt_params', ['ast', 'rewriter', 'pattern', 'bit_blaster'], 'smt/params')
add_lib('fpa', ['ast', 'util', 'simplifier', 'model'], 'ast/fpa') add_lib('proto_model', ['model', 'rewriter', 'smt_params'], 'smt/proto_model')
add_lib('macros', ['simplifier'], 'ast/macros')
add_lib('pattern', ['normal_forms', 'smt2parser', 'simplifier'], 'ast/pattern')
add_lib('bit_blaster', ['rewriter', 'simplifier'], 'ast/rewriter/bit_blaster')
add_lib('smt_params', ['ast', 'simplifier', 'pattern', 'bit_blaster'], 'smt/params')
add_lib('proto_model', ['model', 'simplifier', 'smt_params'], 'smt/proto_model')
add_lib('smt', ['bit_blaster', 'macros', 'normal_forms', 'cmd_context', 'proto_model', add_lib('smt', ['bit_blaster', 'macros', 'normal_forms', 'cmd_context', 'proto_model',
'substitution', 'grobner', 'euclid', 'simplex', 'proof_checker', 'pattern', 'parser_util', 'fpa', 'lp']) 'substitution', 'grobner', 'euclid', 'simplex', 'proofs', 'pattern', 'parser_util', 'fpa', 'lp'])
add_lib('bv_tactics', ['tactic', 'bit_blaster', 'core_tactics'], 'tactic/bv') add_lib('bv_tactics', ['tactic', 'bit_blaster', 'core_tactics'], 'tactic/bv')
add_lib('fuzzing', ['ast'], 'test/fuzzing') add_lib('fuzzing', ['ast'], 'test/fuzzing')
add_lib('smt_tactic', ['smt'], 'smt/tactic') add_lib('smt_tactic', ['smt'], 'smt/tactic')
@ -65,12 +62,13 @@ def init_project_def():
add_lib('transforms', ['muz', 'hilbert', 'dataflow'], 'muz/transforms') add_lib('transforms', ['muz', 'hilbert', 'dataflow'], 'muz/transforms')
add_lib('rel', ['muz', 'transforms'], 'muz/rel') add_lib('rel', ['muz', 'transforms'], 'muz/rel')
add_lib('pdr', ['muz', 'transforms', 'arith_tactics', 'core_tactics', 'smt_tactic'], 'muz/pdr') add_lib('pdr', ['muz', 'transforms', 'arith_tactics', 'core_tactics', 'smt_tactic'], 'muz/pdr')
add_lib('spacer', ['muz', 'transforms', 'arith_tactics', 'smt_tactic'], 'muz/spacer')
add_lib('clp', ['muz', 'transforms'], 'muz/clp') add_lib('clp', ['muz', 'transforms'], 'muz/clp')
add_lib('tab', ['muz', 'transforms'], 'muz/tab') add_lib('tab', ['muz', 'transforms'], 'muz/tab')
add_lib('bmc', ['muz', 'transforms'], 'muz/bmc') add_lib('bmc', ['muz', 'transforms'], 'muz/bmc')
add_lib('ddnf', ['muz', 'transforms', 'rel'], 'muz/ddnf') add_lib('ddnf', ['muz', 'transforms', 'rel'], 'muz/ddnf')
add_lib('duality_intf', ['muz', 'transforms', 'duality'], 'muz/duality') add_lib('duality_intf', ['muz', 'transforms', 'duality'], 'muz/duality')
add_lib('fp', ['muz', 'pdr', 'clp', 'tab', 'rel', 'bmc', 'duality_intf', 'ddnf'], 'muz/fp') add_lib('fp', ['muz', 'pdr', 'clp', 'tab', 'rel', 'bmc', 'duality_intf', 'ddnf', 'spacer'], 'muz/fp')
add_lib('nlsat_smt_tactic', ['nlsat_tactic', 'smt_tactic'], 'tactic/nlsat_smt') add_lib('nlsat_smt_tactic', ['nlsat_tactic', 'smt_tactic'], 'tactic/nlsat_smt')
add_lib('ufbv_tactic', ['normal_forms', 'core_tactics', 'macros', 'smt_tactic', 'rewriter'], 'tactic/ufbv') add_lib('ufbv_tactic', ['normal_forms', 'core_tactics', 'macros', 'smt_tactic', 'rewriter'], 'tactic/ufbv')
add_lib('sat_solver', ['solver', 'core_tactics', 'aig_tactic', 'bv_tactics', 'arith_tactics', 'sat_tactic'], 'sat/sat_solver') add_lib('sat_solver', ['solver', 'core_tactics', 'aig_tactic', 'bv_tactics', 'arith_tactics', 'sat_tactic'], 'sat/sat_solver')
@ -79,7 +77,7 @@ def init_project_def():
add_lib('portfolio', ['smtlogic_tactics', 'sat_solver', 'ufbv_tactic', 'fpa_tactics', 'aig_tactic', 'fp', 'qe','sls_tactic', 'subpaving_tactic'], 'tactic/portfolio') add_lib('portfolio', ['smtlogic_tactics', 'sat_solver', 'ufbv_tactic', 'fpa_tactics', 'aig_tactic', 'fp', 'qe','sls_tactic', 'subpaving_tactic'], 'tactic/portfolio')
add_lib('smtparser', ['portfolio'], 'parsers/smt') add_lib('smtparser', ['portfolio'], 'parsers/smt')
add_lib('opt', ['smt', 'smtlogic_tactics', 'sls_tactic', 'sat_solver'], 'opt') add_lib('opt', ['smt', 'smtlogic_tactics', 'sls_tactic', 'sat_solver'], 'opt')
API_files = ['z3_api.h', 'z3_ast_containers.h', 'z3_algebraic.h', 'z3_polynomial.h', 'z3_rcf.h', 'z3_fixedpoint.h', 'z3_optimization.h', 'z3_interp.h', 'z3_fpa.h'] API_files = ['z3_api.h', 'z3_ast_containers.h', 'z3_algebraic.h', 'z3_polynomial.h', 'z3_rcf.h', 'z3_fixedpoint.h', 'z3_optimization.h', 'z3_interp.h', 'z3_fpa.h', 'z3_spacer.h']
add_lib('api', ['portfolio', 'smtparser', 'realclosure', 'interp', 'opt'], add_lib('api', ['portfolio', 'smtparser', 'realclosure', 'interp', 'opt'],
includes2install=['z3.h', 'z3_v1.h', 'z3_macros.h'] + API_files) includes2install=['z3.h', 'z3_v1.h', 'z3_macros.h'] + API_files)
add_exe('shell', ['api', 'sat', 'extra_cmds','opt'], exe_name='z3') add_exe('shell', ['api', 'sat', 'extra_cmds','opt'], exe_name='z3')

View file

@ -1913,7 +1913,11 @@ class MLComponent(Component):
src_dir = self.to_src_dir src_dir = self.to_src_dir
mk_dir(os.path.join(BUILD_DIR, self.sub_dir)) mk_dir(os.path.join(BUILD_DIR, self.sub_dir))
api_src = get_component(API_COMPONENT).to_src_dir api_src = get_component(API_COMPONENT).to_src_dir
out.write('CXXFLAGS_OCAML=$(CXXFLAGS:/GL=)\n') # remove /GL; the ocaml tools don't like it. # remove /GL and -std=c++11; the ocaml tools don't like them.
if IS_WINDOWS:
out.write('CXXFLAGS_OCAML=$(CXXFLAGS:/GL=)\n')
else:
out.write('CXXFLAGS_OCAML=$(subst -std=c++11,,$(CXXFLAGS))\n')
if IS_WINDOWS: if IS_WINDOWS:
prefix_lib = '-L' + os.path.abspath(BUILD_DIR).replace('\\', '\\\\') prefix_lib = '-L' + os.path.abspath(BUILD_DIR).replace('\\', '\\\\')
@ -2443,26 +2447,26 @@ def mk_config():
SO_EXT = '.dylib' SO_EXT = '.dylib'
SLIBFLAGS = '-dynamiclib' SLIBFLAGS = '-dynamiclib'
elif sysname == 'Linux': elif sysname == 'Linux':
CXXFLAGS = '%s -fno-strict-aliasing -D_LINUX_' % CXXFLAGS CXXFLAGS = '%s -D_LINUX_' % CXXFLAGS
OS_DEFINES = '-D_LINUX_' OS_DEFINES = '-D_LINUX_'
SO_EXT = '.so' SO_EXT = '.so'
LDFLAGS = '%s -lrt' % LDFLAGS LDFLAGS = '%s -lrt' % LDFLAGS
SLIBFLAGS = '-shared' SLIBFLAGS = '-shared'
SLIBEXTRAFLAGS = '%s -lrt' % SLIBEXTRAFLAGS SLIBEXTRAFLAGS = '%s -lrt' % SLIBEXTRAFLAGS
elif sysname == 'FreeBSD': elif sysname == 'FreeBSD':
CXXFLAGS = '%s -fno-strict-aliasing -D_FREEBSD_' % CXXFLAGS CXXFLAGS = '%s -D_FREEBSD_' % CXXFLAGS
OS_DEFINES = '-D_FREEBSD_' OS_DEFINES = '-D_FREEBSD_'
SO_EXT = '.so' SO_EXT = '.so'
LDFLAGS = '%s -lrt' % LDFLAGS LDFLAGS = '%s -lrt' % LDFLAGS
SLIBFLAGS = '-shared' SLIBFLAGS = '-shared'
SLIBEXTRAFLAGS = '%s -lrt' % SLIBEXTRAFLAGS SLIBEXTRAFLAGS = '%s -lrt' % SLIBEXTRAFLAGS
elif sysname == 'OpenBSD': elif sysname == 'OpenBSD':
CXXFLAGS = '%s -fno-strict-aliasing -D_OPENBSD_' % CXXFLAGS CXXFLAGS = '%s -D_OPENBSD_' % CXXFLAGS
OS_DEFINES = '-D_OPENBSD_' OS_DEFINES = '-D_OPENBSD_'
SO_EXT = '.so' SO_EXT = '.so'
SLIBFLAGS = '-shared' SLIBFLAGS = '-shared'
elif sysname[:6] == 'CYGWIN': elif sysname[:6] == 'CYGWIN':
CXXFLAGS = '%s -D_CYGWIN -fno-strict-aliasing' % CXXFLAGS CXXFLAGS = '%s -D_CYGWIN' % CXXFLAGS
OS_DEFINES = '-D_CYGWIN' OS_DEFINES = '-D_CYGWIN'
SO_EXT = '.dll' SO_EXT = '.dll'
SLIBFLAGS = '-shared' SLIBFLAGS = '-shared'
@ -3046,6 +3050,7 @@ def mk_vs_proj_cl_compile(f, name, components, debug):
else: else:
f.write(';') f.write(';')
f.write(get_component(dep).to_src_dir) f.write(get_component(dep).to_src_dir)
f.write(';%s\n' % os.path.join(REV_BUILD_DIR, SRC_DIR))
f.write('</AdditionalIncludeDirectories>\n') f.write('</AdditionalIncludeDirectories>\n')
f.write(' </ClCompile>\n') f.write(' </ClCompile>\n')

View file

@ -321,16 +321,19 @@ def mk_py_wrappers():
core_py.write("def %s(" % name) core_py.write("def %s(" % name)
display_args(num) display_args(num)
core_py.write("):\n") core_py.write("):\n")
core_py.write(" _lib = lib()\n")
core_py.write(" if _lib is None or _lib.%s is None:\n" % name)
core_py.write(" return\n")
if result != VOID: if result != VOID:
core_py.write(" r = lib().%s(" % name) core_py.write(" r = _lib.%s(" % name)
else: else:
core_py.write(" lib().%s(" % name) core_py.write(" _lib.%s(" % name)
display_args_to_z3(params) display_args_to_z3(params)
core_py.write(")\n") core_py.write(")\n")
if len(params) > 0 and param_type(params[0]) == CONTEXT: if len(params) > 0 and param_type(params[0]) == CONTEXT:
core_py.write(" err = lib().Z3_get_error_code(a0)\n") core_py.write(" err = _lib.Z3_get_error_code(a0)\n")
core_py.write(" if err != Z3_OK:\n") core_py.write(" if err != Z3_OK:\n")
core_py.write(" raise Z3Exception(lib().Z3_get_error_msg(a0, err))\n") core_py.write(" raise Z3Exception(_lib.Z3_get_error_msg(a0, err))\n")
if result == STRING: if result == STRING:
core_py.write(" return _to_pystr(r)\n") core_py.write(" return _to_pystr(r)\n")
elif result != VOID: elif result != VOID:
@ -765,12 +768,12 @@ def mk_log_macro(file, name, params):
cap = param_array_capacity_pos(p) cap = param_array_capacity_pos(p)
if cap not in auxs: if cap not in auxs:
auxs.add(cap) auxs.add(cap)
file.write("unsigned _Z3_UNUSED Z3ARG%s; " % cap) file.write("unsigned _Z3_UNUSED Z3ARG%s = 0; " % cap)
sz = param_array_size_pos(p) sz = param_array_size_pos(p)
if sz not in auxs: if sz not in auxs:
auxs.add(sz) auxs.add(sz)
file.write("unsigned * _Z3_UNUSED Z3ARG%s; " % sz) file.write("unsigned * _Z3_UNUSED Z3ARG%s = 0; " % sz)
file.write("%s _Z3_UNUSED Z3ARG%s; " % (param2str(p), i)) file.write("%s _Z3_UNUSED Z3ARG%s = 0; " % (param2str(p), i))
i = i + 1 i = i + 1
file.write("if (_LOG_CTX.enabled()) { log_%s(" % name) file.write("if (_LOG_CTX.enabled()) { log_%s(" % name)
i = 0 i = 0
@ -1570,7 +1573,7 @@ def def_APIs(api_files):
def write_log_h_preamble(log_h): def write_log_h_preamble(log_h):
log_h.write('// Automatically generated file\n') log_h.write('// Automatically generated file\n')
log_h.write('#include\"z3.h\"\n') log_h.write('#include\"api/z3.h\"\n')
log_h.write('#ifdef __GNUC__\n') log_h.write('#ifdef __GNUC__\n')
log_h.write('#define _Z3_UNUSED __attribute__((unused))\n') log_h.write('#define _Z3_UNUSED __attribute__((unused))\n')
log_h.write('#else\n') log_h.write('#else\n')
@ -1589,17 +1592,22 @@ def write_log_h_preamble(log_h):
def write_log_c_preamble(log_c): def write_log_c_preamble(log_c):
log_c.write('// Automatically generated file\n') log_c.write('// Automatically generated file\n')
log_c.write('#include<iostream>\n') log_c.write('#include<iostream>\n')
log_c.write('#include\"z3.h\"\n') log_c.write('#include\"api/z3.h\"\n')
log_c.write('#include\"api_log_macros.h\"\n') log_c.write('#include\"api/api_log_macros.h\"\n')
log_c.write('#include\"z3_logger.h\"\n') log_c.write('#include\"api/z3_logger.h\"\n')
def write_exe_c_preamble(exe_c): def write_exe_c_preamble(exe_c):
exe_c.write('// Automatically generated file\n') exe_c.write('// Automatically generated file\n')
exe_c.write('#include\"z3.h\"\n') exe_c.write('#include\"api/z3.h\"\n')
exe_c.write('#include\"z3_replayer.h\"\n') exe_c.write('#include\"api/z3_replayer.h\"\n')
# #
exe_c.write('void Z3_replayer_error_handler(Z3_context ctx, Z3_error_code c) { printf("[REPLAYER ERROR HANDLER]: %s\\n", Z3_get_error_msg(ctx, c)); }\n') exe_c.write('void Z3_replayer_error_handler(Z3_context ctx, Z3_error_code c) { printf("[REPLAYER ERROR HANDLER]: %s\\n", Z3_get_error_msg(ctx, c)); }\n')
def write_core_py_post(core_py):
core_py.write("""
""")
def write_core_py_preamble(core_py): def write_core_py_preamble(core_py):
core_py.write('# Automatically generated file\n') core_py.write('# Automatically generated file\n')
core_py.write('import sys, os\n') core_py.write('import sys, os\n')
@ -1612,18 +1620,19 @@ def write_core_py_preamble(core_py):
_ext = 'dll' if sys.platform in ('win32', 'cygwin') else 'dylib' if sys.platform == 'darwin' else 'so' _ext = 'dll' if sys.platform in ('win32', 'cygwin') else 'dylib' if sys.platform == 'darwin' else 'so'
_lib = None _lib = None
def lib(): def lib():
global _lib global _lib
if _lib is None: if _lib is None:
_dirs = ['.', os.path.dirname(os.path.abspath(__file__)), pkg_resources.resource_filename('z3', 'lib'), os.path.join(sys.prefix, 'lib'), None] _dirs = ['.', os.path.dirname(os.path.abspath(__file__)), pkg_resources.resource_filename('z3', 'lib'), os.path.join(sys.prefix, 'lib'), None]
for _dir in _dirs: for _dir in _dirs:
try: try:
init(_dir) init(_dir)
break break
except: except:
pass pass
if _lib is None: if _lib is None:
raise Z3Exception("init(Z3_LIBRARY_PATH) must be invoked before using Z3-python") raise Z3Exception("init(Z3_LIBRARY_PATH) must be invoked before using Z3-python")
return _lib return _lib
def _to_ascii(s): def _to_ascii(s):
@ -1728,6 +1737,7 @@ def generate_files(api_files,
def_APIs(api_files) def_APIs(api_files)
mk_bindings(exe_c) mk_bindings(exe_c)
mk_py_wrappers() mk_py_wrappers()
write_core_py_post(core_py)
if mk_util.is_verbose(): if mk_util.is_verbose():
print("Generated '{}'".format(log_h.name)) print("Generated '{}'".format(log_h.name))

69
scripts/update_include.py Normal file
View file

@ -0,0 +1,69 @@
# Copyright (c) 2017 Microsoft Corporation
import os
import re
is_include = re.compile("#include \"(.*)\"")
is_include2 = re.compile("#include\"(.*)\"")
def fix_include(file, paths):
tmp = "%s.tmp" % file
ins = open(file)
ous = open(tmp,'w')
line = ins.readline()
found = False
while line:
m = is_include.search(line)
if m and m.group(1) in paths:
ous.write("#include \"")
ous.write(paths[m.group(1)])
ous.write("\"\n")
found = True
line = ins.readline()
continue
m = is_include2.search(line)
if m and m.group(1) in paths:
ous.write("#include \"")
ous.write(paths[m.group(1)])
ous.write("\"\n")
found = True
line = ins.readline()
continue
ous.write(line)
line = ins.readline()
ins.close()
ous.close()
if found:
print(file)
os.system("move %s %s" % (tmp, file))
else:
os.system("del %s" % tmp)
def find_paths(dir):
paths = {}
for root, dirs, files in os.walk(dir):
root1 = root.replace("\\","/")[4:]
for f in files:
if f.endswith('.h') or f.endswith('.hpp') or f.endswith('.cpp'):
path = "%s/%s" % (root1, f)
paths[f] = path
if f.endswith('.pyg'):
f = f.replace("pyg","hpp")
path = "%s/%s" % (root1, f)
paths[f] = path
return paths
paths = find_paths('src')
def fixup(dir):
for root, dirs, files in os.walk(dir):
for f in files:
if f == "z3.h":
continue
if f.endswith('.h') or f.endswith('.cpp'):
path = "%s\\%s" % (root, f)
fix_include(path, paths)
fixup('src')

View file

@ -14,6 +14,7 @@ set(Z3_API_HEADER_FILES_TO_SCAN
z3_optimization.h z3_optimization.h
z3_interp.h z3_interp.h
z3_fpa.h z3_fpa.h
z3_spacer.h
) )
set(Z3_FULL_PATH_API_HEADER_FILES_TO_SCAN "") set(Z3_FULL_PATH_API_HEADER_FILES_TO_SCAN "")
foreach (header_file ${Z3_API_HEADER_FILES_TO_SCAN}) foreach (header_file ${Z3_API_HEADER_FILES_TO_SCAN})
@ -66,10 +67,7 @@ add_subdirectory(interp)
add_subdirectory(cmd_context) add_subdirectory(cmd_context)
add_subdirectory(cmd_context/extra_cmds) add_subdirectory(cmd_context/extra_cmds)
add_subdirectory(parsers/smt2) add_subdirectory(parsers/smt2)
add_subdirectory(ast/proof_checker) add_subdirectory(ast/proofs)
## Simplifier module will be deleted in the future.
## It has been replaced with rewriter component.
add_subdirectory(ast/simplifier)
add_subdirectory(ast/fpa) add_subdirectory(ast/fpa)
add_subdirectory(ast/macros) add_subdirectory(ast/macros)
add_subdirectory(ast/pattern) add_subdirectory(ast/pattern)
@ -92,6 +90,7 @@ add_subdirectory(muz/tab)
add_subdirectory(muz/bmc) add_subdirectory(muz/bmc)
add_subdirectory(muz/ddnf) add_subdirectory(muz/ddnf)
add_subdirectory(muz/duality) add_subdirectory(muz/duality)
add_subdirectory(muz/spacer)
add_subdirectory(muz/fp) add_subdirectory(muz/fp)
add_subdirectory(tactic/nlsat_smt) add_subdirectory(tactic/nlsat_smt)
add_subdirectory(tactic/ufbv) add_subdirectory(tactic/ufbv)
@ -168,6 +167,7 @@ set (libz3_public_headers
z3_polynomial.h z3_polynomial.h
z3_rcf.h z3_rcf.h
z3_v1.h z3_v1.h
z3_spacer.h
) )
foreach (header ${libz3_public_headers}) foreach (header ${libz3_public_headers})
set_property(TARGET libz3 APPEND PROPERTY set_property(TARGET libz3 APPEND PROPERTY

View file

@ -14,8 +14,8 @@
Revision History: Revision History:
--*/ --*/
#include"ackr_model_converter.h" #include "ackermannization/ackr_model_converter.h"
#include"ackermannize_bv_model_converter.h" #include "ackermannization/ackermannize_bv_model_converter.h"
model_converter * mk_ackermannize_bv_model_converter(ast_manager & m, const ackr_info_ref& info) { model_converter * mk_ackermannize_bv_model_converter(ast_manager & m, const ackr_info_ref& info) {
return mk_ackr_model_converter(m, info); return mk_ackr_model_converter(m, info);

View file

@ -17,8 +17,8 @@
#ifndef ACKERMANNIZE_BV_MODEL_CONVERTER_H_ #ifndef ACKERMANNIZE_BV_MODEL_CONVERTER_H_
#define ACKERMANNIZE_BV_MODEL_CONVERTER_H_ #define ACKERMANNIZE_BV_MODEL_CONVERTER_H_
#include"model_converter.h" #include "tactic/model_converter.h"
#include"ackr_info.h" #include "ackermannization/ackr_info.h"
model_converter * mk_ackermannize_bv_model_converter(ast_manager & m, const ackr_info_ref& info); model_converter * mk_ackermannize_bv_model_converter(ast_manager & m, const ackr_info_ref& info);

View file

@ -13,12 +13,12 @@ Mikolas Janota
Revision History: Revision History:
--*/ --*/
#include"ackermannize_bv_tactic.h" #include "ackermannization/ackermannize_bv_tactic.h"
#include"tactical.h" #include "tactic/tactical.h"
#include"lackr.h" #include "ackermannization/lackr.h"
#include"model_smt2_pp.h" #include "model/model_smt2_pp.h"
#include"ackermannize_bv_tactic_params.hpp" #include "ackermannization/ackermannize_bv_tactic_params.hpp"
#include"ackermannize_bv_model_converter.h" #include "ackermannization/ackermannize_bv_model_converter.h"
class ackermannize_bv_tactic : public tactic { class ackermannize_bv_tactic : public tactic {

View file

@ -16,7 +16,7 @@ Revision History:
#ifndef _ACKERMANNIZE_TACTIC_H_ #ifndef _ACKERMANNIZE_TACTIC_H_
#define _ACKERMANNIZE_TACTIC_H_ #define _ACKERMANNIZE_TACTIC_H_
#include"tactical.h" #include "tactic/tactical.h"
tactic * mk_ackermannize_bv_tactic(ast_manager & m, params_ref const & p); tactic * mk_ackermannize_bv_tactic(ast_manager & m, params_ref const & p);

View file

@ -14,9 +14,9 @@
Revision History: Revision History:
--*/ --*/
#include"ackr_helper.h" #include "ackermannization/ackr_helper.h"
#include"ackr_bound_probe.h" #include "ackermannization/ackr_bound_probe.h"
#include"ast_smt2_pp.h" #include "ast/ast_smt2_pp.h"
/* /*
For each function f, calculate the number of its occurrences o_f and compute "o_f choose 2". For each function f, calculate the number of its occurrences o_f and compute "o_f choose 2".

View file

@ -18,7 +18,7 @@
#ifndef ACKR_BOUND_PROBE_H_ #ifndef ACKR_BOUND_PROBE_H_
#define ACKR_BOUND_PROBE_H_ #define ACKR_BOUND_PROBE_H_
#include"probe.h" #include "tactic/probe.h"
probe * mk_ackr_bound_probe(); probe * mk_ackr_bound_probe();

View file

@ -14,7 +14,7 @@
Revision History: Revision History:
--*/ --*/
#include"ackr_helper.h" #include "ackermannization/ackr_helper.h"
double ackr_helper::calculate_lemma_bound(ackr_helper::fun2terms_map& occurrences) { double ackr_helper::calculate_lemma_bound(ackr_helper::fun2terms_map& occurrences) {
fun2terms_map::iterator it = occurrences.begin(); fun2terms_map::iterator it = occurrences.begin();

View file

@ -17,7 +17,7 @@
#ifndef ACKR_HELPER_H_ #ifndef ACKR_HELPER_H_
#define ACKR_HELPER_H_ #define ACKR_HELPER_H_
#include"bv_decl_plugin.h" #include "ast/bv_decl_plugin.h"
class ackr_helper { class ackr_helper {
public: public:

View file

@ -16,11 +16,11 @@ Revision History:
#ifndef ACKR_INFO_H_ #ifndef ACKR_INFO_H_
#define ACKR_INFO_H_ #define ACKR_INFO_H_
#include"obj_hashtable.h" #include "util/obj_hashtable.h"
#include"ast.h" #include "ast/ast.h"
#include"ref.h" #include "util/ref.h"
#include"expr_replacer.h" #include "ast/rewriter/expr_replacer.h"
#include"ast_translation.h" #include "ast/ast_translation.h"
/** \brief /** \brief
Information about how a formula is being converted into Information about how a formula is being converted into

View file

@ -3,27 +3,27 @@ Copyright (c) 2015 Microsoft Corporation
Module Name: Module Name:
ackr_model_converter.cpp ackr_model_converter.cpp
Abstract: Abstract:
Author: Author:
Mikolas Janota Mikolas Janota
Revision History: Revision History:
--*/ --*/
#include"ackr_model_converter.h" #include "ackermannization/ackr_model_converter.h"
#include"model_evaluator.h" #include "model/model_evaluator.h"
#include"ast_smt2_pp.h" #include "ast/ast_smt2_pp.h"
#include"ackr_info.h" #include "ackermannization/ackr_info.h"
class ackr_model_converter : public model_converter { class ackr_model_converter : public model_converter {
public: public:
ackr_model_converter(ast_manager & m, ackr_model_converter(ast_manager & m,
const ackr_info_ref& info, const ackr_info_ref& info,
model_ref& abstr_model) model_ref& abstr_model)
: m(m) : m(m)
, info(info) , info(info)
, abstr_model(abstr_model) , abstr_model(abstr_model)
@ -31,7 +31,7 @@ public:
{ } { }
ackr_model_converter(ast_manager & m, ackr_model_converter(ast_manager & m,
const ackr_info_ref& info) const ackr_info_ref& info)
: m(m) : m(m)
, info(info) , info(info)
, fixed_model(false) , fixed_model(false)
@ -51,8 +51,6 @@ public:
virtual void operator()(model_ref & md) { operator()(md, 0); } virtual void operator()(model_ref & md) { operator()(md, 0); }
//void display(std::ostream & out);
virtual model_converter * translate(ast_translation & translator) { virtual model_converter * translate(ast_translation & translator) {
ackr_info_ref retv_info = info->translate(translator); ackr_info_ref retv_info = info->translate(translator);
if (fixed_model) { if (fixed_model) {
@ -63,42 +61,45 @@ public:
return alloc(ackr_model_converter, translator.to(), retv_info); return alloc(ackr_model_converter, translator.to(), retv_info);
} }
} }
protected: protected:
ast_manager& m; ast_manager & m;
const ackr_info_ref info; const ackr_info_ref info;
model_ref abstr_model; model_ref abstr_model;
bool fixed_model; bool fixed_model;
void convert(model * source, model * destination); void convert(model * source, model * destination);
void add_entry(model_evaluator & evaluator, void add_entry(model_evaluator & evaluator,
app* term, expr* value, app* term, expr* value,
obj_map<func_decl, func_interp*>& interpretations); obj_map<func_decl, func_interp*>& interpretations);
void convert_constants(model * source, model * destination); void convert_constants(model * source, model * destination);
}; };
void ackr_model_converter::convert(model * source, model * destination) { void ackr_model_converter::convert(model * source, model * destination) {
destination->copy_func_interps(*source); destination->copy_func_interps(*source);
destination->copy_usort_interps(*source); destination->copy_usort_interps(*source);
convert_constants(source,destination); convert_constants(source, destination);
} }
void ackr_model_converter::convert_constants(model * source, model * destination) { void ackr_model_converter::convert_constants(model * source, model * destination) {
TRACE("ackr_model", tout << "converting constants\n";); TRACE("ackr_model", tout << "converting constants\n";);
obj_map<func_decl, func_interp*> interpretations; obj_map<func_decl, func_interp*> interpretations;
model_evaluator evaluator(*source); model_evaluator evaluator(*source);
evaluator.set_model_completion(true);
for (unsigned i = 0; i < source->get_num_constants(); i++) { for (unsigned i = 0; i < source->get_num_constants(); i++) {
func_decl * const c = source->get_constant(i); func_decl * const c = source->get_constant(i);
app * const term = info->find_term(c); app * const term = info->find_term(c);
expr * value = source->get_const_interp(c); expr * value = source->get_const_interp(c);
if(!term) { if (!term) {
destination->register_decl(c, value); destination->register_decl(c, value);
} else { }
else {
add_entry(evaluator, term, value, interpretations); add_entry(evaluator, term, value, interpretations);
} }
} }
obj_map<func_decl, func_interp*>::iterator e = interpretations.end(); obj_map<func_decl, func_interp*>::iterator e = interpretations.end();
for (obj_map<func_decl, func_interp*>::iterator i = interpretations.begin(); for (obj_map<func_decl, func_interp*>::iterator i = interpretations.begin();
i!=e; ++i) { i != e; ++i) {
func_decl* const fd = i->m_key; func_decl* const fd = i->m_key;
func_interp* const fi = i->get_value(); func_interp* const fi = i->get_value();
fi->set_else(m.get_some_value(fd->get_range())); fi->set_else(m.get_some_value(fd->get_range()));
@ -107,34 +108,40 @@ void ackr_model_converter::convert_constants(model * source, model * destination
} }
void ackr_model_converter::add_entry(model_evaluator & evaluator, void ackr_model_converter::add_entry(model_evaluator & evaluator,
app* term, expr* value, app* term, expr* value,
obj_map<func_decl, func_interp*>& interpretations) { obj_map<func_decl, func_interp*>& interpretations) {
TRACE("ackr_model", tout << "add_entry" TRACE("ackr_model", tout << "add_entry"
<< mk_ismt2_pp(term, m, 2) << mk_ismt2_pp(term, m, 2)
<< "->" << "->"
<< mk_ismt2_pp(value, m, 2) << "\n"; << mk_ismt2_pp(value, m, 2) << "\n";
); );
func_interp* fi = 0; func_interp * fi = 0;
func_decl * const declaration = term->get_decl(); func_decl * const declaration = term->get_decl();
const unsigned sz = declaration->get_arity(); const unsigned sz = declaration->get_arity();
SASSERT(sz == term->get_num_args()); SASSERT(sz == term->get_num_args());
if (!interpretations.find(declaration, fi)) { if (!interpretations.find(declaration, fi)) {
fi = alloc(func_interp,m,sz); fi = alloc(func_interp, m, sz);
interpretations.insert(declaration, fi); interpretations.insert(declaration, fi);
} }
expr_ref_vector args(m); expr_ref_vector args(m);
for (unsigned gi = 0; gi < sz; ++gi) { for (unsigned gi = 0; gi < sz; ++gi) {
expr * const arg = term->get_arg(gi); expr * const arg = term->get_arg(gi);
expr_ref aarg(m); expr_ref aarg(m);
info->abstract(arg, aarg); info->abstract(arg, aarg);
expr_ref arg_value(m); expr_ref arg_value(m);
evaluator(aarg,arg_value); evaluator(aarg, arg_value);
args.push_back(arg_value); args.push_back(arg_value);
} }
if (fi->get_entry(args.c_ptr()) == 0) { if (fi->get_entry(args.c_ptr()) == 0) {
TRACE("ackr_model",
tout << mk_ismt2_pp(declaration, m) << " args: " << std::endl;
for (unsigned i = 0; i < args.size(); i++)
tout << mk_ismt2_pp(args.get(i), m) << std::endl;
tout << " -> " << mk_ismt2_pp(value, m) << "\n"; );
fi->insert_new_entry(args.c_ptr(), value); fi->insert_new_entry(args.c_ptr(), value);
} else { }
else {
TRACE("ackr_model", tout << "entry already present\n";); TRACE("ackr_model", tout << "entry already present\n";);
} }
} }

View file

@ -3,23 +3,23 @@ Copyright (c) 2015 Microsoft Corporation
Module Name: Module Name:
ackr_model_converter.h ackr_model_converter.h
Abstract: Abstract:
Author: Author:
Mikolas Janota Mikolas Janota
Revision History: Revision History:
--*/ --*/
#ifndef ACKR_MODEL_CONVERTER_H_ #ifndef ACKR_MODEL_CONVERTER_H_
#define ACKR_MODEL_CONVERTER_H_ #define ACKR_MODEL_CONVERTER_H_
#include"model_converter.h" #include "tactic/model_converter.h"
#include"ackr_info.h" #include "ackermannization/ackr_info.h"
model_converter * mk_ackr_model_converter(ast_manager & m, const ackr_info_ref& info, model_ref& abstr_model); model_converter * mk_ackr_model_converter(ast_manager & m, const ackr_info_ref & info, model_ref & abstr_model);
model_converter * mk_ackr_model_converter(ast_manager & m, const ackr_info_ref& info); model_converter * mk_ackr_model_converter(ast_manager & m, const ackr_info_ref & info);
#endif /* LACKR_MODEL_CONVERTER_H_ */ #endif /* LACKR_MODEL_CONVERTER_H_ */

View file

@ -15,13 +15,13 @@
Revision History: Revision History:
--*/ --*/
#include"lackr.h" #include "ackermannization/lackr.h"
#include"ackermannization_params.hpp" #include "ackermannization/ackermannization_params.hpp"
#include"tactic.h" #include "tactic/tactic.h"
#include"lackr_model_constructor.h" #include "ackermannization/lackr_model_constructor.h"
#include"ackr_info.h" #include "ackermannization/ackr_info.h"
#include"for_each_expr.h" #include "ast/for_each_expr.h"
#include"model_smt2_pp.h" #include "model/model_smt2_pp.h"
lackr::lackr(ast_manager& m, params_ref p, lackr_stats& st, expr_ref_vector& formulas, lackr::lackr(ast_manager& m, params_ref p, lackr_stats& st, expr_ref_vector& formulas,
solver * uffree_solver) solver * uffree_solver)

View file

@ -17,17 +17,17 @@
#ifndef LACKR_H_ #ifndef LACKR_H_
#define LACKR_H_ #define LACKR_H_
#include"ackr_info.h" #include "ackermannization/ackr_info.h"
#include"ackr_helper.h" #include "ackermannization/ackr_helper.h"
#include"th_rewriter.h" #include "ast/rewriter/th_rewriter.h"
#include"cooperate.h" #include "util/cooperate.h"
#include"bv_decl_plugin.h" #include "ast/bv_decl_plugin.h"
#include"lbool.h" #include "util/lbool.h"
#include"model.h" #include "model/model.h"
#include"solver.h" #include "solver/solver.h"
#include"util.h" #include "util/util.h"
#include"tactic_exception.h" #include "tactic/tactic_exception.h"
#include"goal.h" #include "tactic/goal.h"
struct lackr_stats { struct lackr_stats {
lackr_stats() : m_it(0), m_ackrs_sz(0) {} lackr_stats() : m_it(0), m_ackrs_sz(0) {}

View file

@ -14,13 +14,13 @@
Revision History: Revision History:
--*/ --*/
#include"lackr_model_constructor.h" #include "ackermannization/lackr_model_constructor.h"
#include"model_evaluator.h" #include "model/model_evaluator.h"
#include"ast_smt2_pp.h" #include "ast/ast_smt2_pp.h"
#include"ackr_info.h" #include "ackermannization/ackr_info.h"
#include"for_each_expr.h" #include "ast/for_each_expr.h"
#include"bv_rewriter.h" #include "ast/rewriter/bv_rewriter.h"
#include"bool_rewriter.h" #include "ast/rewriter/bool_rewriter.h"
struct lackr_model_constructor::imp { struct lackr_model_constructor::imp {
public: public:

View file

@ -18,10 +18,10 @@
#ifndef LACKR_MODEL_CONSTRUCTOR_H_ #ifndef LACKR_MODEL_CONSTRUCTOR_H_
#define LACKR_MODEL_CONSTRUCTOR_H_ #define LACKR_MODEL_CONSTRUCTOR_H_
#include"ast.h" #include "ast/ast.h"
#include"ackr_info.h" #include "ackermannization/ackr_info.h"
#include"ackr_helper.h" #include "ackermannization/ackr_helper.h"
#include"model.h" #include "model/model.h"
class lackr_model_constructor { class lackr_model_constructor {
public: public:

View file

@ -14,11 +14,11 @@
Revision History: Revision History:
--*/ --*/
#include"lackr_model_converter_lazy.h" #include "ackermannization/lackr_model_converter_lazy.h"
#include"model_evaluator.h" #include "model/model_evaluator.h"
#include"ast_smt2_pp.h" #include "ast/ast_smt2_pp.h"
#include"ackr_info.h" #include "ackermannization/ackr_info.h"
#include"lackr_model_constructor.h" #include "ackermannization/lackr_model_constructor.h"
class lackr_model_converter_lazy : public model_converter { class lackr_model_converter_lazy : public model_converter {
public: public:

View file

@ -17,8 +17,8 @@
#ifndef LACKR_MODEL_CONVERTER_LAZY_H_ #ifndef LACKR_MODEL_CONVERTER_LAZY_H_
#define LACKR_MODEL_CONVERTER_LAZY_H_ #define LACKR_MODEL_CONVERTER_LAZY_H_
#include"model_converter.h" #include "tactic/model_converter.h"
#include"ackr_info.h" #include "ackermannization/ackr_info.h"
model_converter * mk_lackr_model_converter_lazy(ast_manager & m, const ackr_info_ref& info, model_ref& abstr_model); model_converter * mk_lackr_model_converter_lazy(ast_manager & m, const ackr_info_ref& info, model_ref& abstr_model);

View file

@ -57,6 +57,7 @@ z3_add_component(api
api_parsers.cpp api_parsers.cpp
api_pb.cpp api_pb.cpp
api_polynomial.cpp api_polynomial.cpp
api_qe.cpp
api_quant.cpp api_quant.cpp
api_rcf.cpp api_rcf.cpp
api_seq.cpp api_seq.cpp

View file

@ -17,14 +17,14 @@ Author:
Notes: Notes:
--*/ --*/
#include"z3.h" #include "api/z3.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_context.h" #include "api/api_context.h"
#include"api_ast_vector.h" #include "api/api_ast_vector.h"
#include"algebraic_numbers.h" #include "math/polynomial/algebraic_numbers.h"
#include"expr2polynomial.h" #include "ast/expr2polynomial.h"
#include"cancel_eh.h" #include "util/cancel_eh.h"
#include"scoped_timer.h" #include "util/scoped_timer.h"
#define CHECK_IS_ALGEBRAIC(ARG, RET) { \ #define CHECK_IS_ALGEBRAIC(ARG, RET) { \

View file

@ -15,12 +15,12 @@ Author:
Revision History: Revision History:
--*/ --*/
#include"z3.h" #include "api/z3.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_context.h" #include "api/api_context.h"
#include"api_util.h" #include "api/api_util.h"
#include"arith_decl_plugin.h" #include "ast/arith_decl_plugin.h"
#include"algebraic_numbers.h" #include "math/polynomial/algebraic_numbers.h"
#define MK_ARITH_OP(NAME, OP) MK_NARY(NAME, mk_c(c)->get_arith_fid(), OP, SKIP) #define MK_ARITH_OP(NAME, OP) MK_NARY(NAME, mk_c(c)->get_arith_fid(), OP, SKIP)
#define MK_BINARY_ARITH_OP(NAME, OP) MK_BINARY(NAME, mk_c(c)->get_arith_fid(), OP, SKIP) #define MK_BINARY_ARITH_OP(NAME, OP) MK_BINARY(NAME, mk_c(c)->get_arith_fid(), OP, SKIP)

View file

@ -15,11 +15,11 @@ Author:
Revision History: Revision History:
--*/ --*/
#include"z3.h" #include "api/z3.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_context.h" #include "api/api_context.h"
#include"api_util.h" #include "api/api_util.h"
#include"array_decl_plugin.h" #include "ast/array_decl_plugin.h"
extern "C" { extern "C" {
@ -34,6 +34,19 @@ extern "C" {
Z3_CATCH_RETURN(0); Z3_CATCH_RETURN(0);
} }
Z3_sort Z3_API Z3_mk_array_sort_n(Z3_context c, unsigned n, Z3_sort const* domain, Z3_sort range) {
Z3_TRY;
LOG_Z3_mk_array_sort_n(c, n, domain, range);
RESET_ERROR_CODE();
vector<parameter> params;
for (unsigned i = 0; i < n; ++i) params.push_back(parameter(to_sort(domain[i])));
params.push_back(parameter(to_sort(range)));
sort * ty = mk_c(c)->m().mk_sort(mk_c(c)->get_array_fid(), ARRAY_SORT, params.size(), params.c_ptr());
mk_c(c)->save_ast_trail(ty);
RETURN_Z3(of_sort(ty));
Z3_CATCH_RETURN(0);
}
Z3_ast Z3_API Z3_mk_select(Z3_context c, Z3_ast a, Z3_ast i) { Z3_ast Z3_API Z3_mk_select(Z3_context c, Z3_ast a, Z3_ast i) {
Z3_TRY; Z3_TRY;
LOG_Z3_mk_select(c, a, i); LOG_Z3_mk_select(c, a, i);
@ -57,6 +70,35 @@ extern "C" {
Z3_CATCH_RETURN(0); Z3_CATCH_RETURN(0);
} }
Z3_ast Z3_API Z3_mk_select_n(Z3_context c, Z3_ast a, unsigned n, Z3_ast const* idxs) {
Z3_TRY;
LOG_Z3_mk_select_n(c, a, n, idxs);
RESET_ERROR_CODE();
ast_manager & m = mk_c(c)->m();
expr * _a = to_expr(a);
// expr * _i = to_expr(i);
sort * a_ty = m.get_sort(_a);
// sort * i_ty = m.get_sort(_i);
if (a_ty->get_family_id() != mk_c(c)->get_array_fid()) {
SET_ERROR_CODE(Z3_SORT_ERROR);
RETURN_Z3(0);
}
ptr_vector<sort> domain;
ptr_vector<expr> args;
args.push_back(_a);
domain.push_back(a_ty);
for (unsigned i = 0; i < n; ++i) {
args.push_back(to_expr(idxs[i]));
domain.push_back(m.get_sort(to_expr(idxs[i])));
}
func_decl * d = m.mk_func_decl(mk_c(c)->get_array_fid(), OP_SELECT, 2, a_ty->get_parameters(), domain.size(), domain.c_ptr());
app * r = m.mk_app(d, args.size(), args.c_ptr());
mk_c(c)->save_ast_trail(r);
check_sorts(c, r);
RETURN_Z3(of_ast(r));
Z3_CATCH_RETURN(0);
}
Z3_ast Z3_API Z3_mk_store(Z3_context c, Z3_ast a, Z3_ast i, Z3_ast v) { Z3_ast Z3_API Z3_mk_store(Z3_context c, Z3_ast a, Z3_ast i, Z3_ast v) {
Z3_TRY; Z3_TRY;
LOG_Z3_mk_store(c, a, i, v); LOG_Z3_mk_store(c, a, i, v);
@ -82,6 +124,37 @@ extern "C" {
Z3_CATCH_RETURN(0); Z3_CATCH_RETURN(0);
} }
Z3_ast Z3_API Z3_mk_store_n(Z3_context c, Z3_ast a, unsigned n, Z3_ast const* idxs, Z3_ast v) {
Z3_TRY;
LOG_Z3_mk_store_n(c, a, n, idxs, v);
RESET_ERROR_CODE();
ast_manager & m = mk_c(c)->m();
expr * _a = to_expr(a);
expr * _v = to_expr(v);
sort * a_ty = m.get_sort(_a);
sort * v_ty = m.get_sort(_v);
if (a_ty->get_family_id() != mk_c(c)->get_array_fid()) {
SET_ERROR_CODE(Z3_SORT_ERROR);
RETURN_Z3(0);
}
ptr_vector<sort> domain;
ptr_vector<expr> args;
args.push_back(_a);
domain.push_back(a_ty);
for (unsigned i = 0; i < n; ++i) {
args.push_back(to_expr(idxs[i]));
domain.push_back(m.get_sort(to_expr(idxs[i])));
}
args.push_back(_v);
domain.push_back(v_ty);
func_decl * d = m.mk_func_decl(mk_c(c)->get_array_fid(), OP_STORE, 2, a_ty->get_parameters(), domain.size(), domain.c_ptr());
app * r = m.mk_app(d, args.size(), args.c_ptr());
mk_c(c)->save_ast_trail(r);
check_sorts(c, r);
RETURN_Z3(of_ast(r));
Z3_CATCH_RETURN(0);
}
Z3_ast Z3_API Z3_mk_map(Z3_context c, Z3_func_decl f, unsigned n, Z3_ast const* args) { Z3_ast Z3_API Z3_mk_map(Z3_context c, Z3_func_decl f, unsigned n, Z3_ast const* args) {
Z3_TRY; Z3_TRY;
LOG_Z3_mk_map(c, f, n, args); LOG_Z3_mk_map(c, f, n, args);
@ -188,6 +261,18 @@ extern "C" {
MK_BINARY(Z3_mk_set_subset, mk_c(c)->get_array_fid(), OP_SET_SUBSET, SKIP); MK_BINARY(Z3_mk_set_subset, mk_c(c)->get_array_fid(), OP_SET_SUBSET, SKIP);
MK_BINARY(Z3_mk_array_ext, mk_c(c)->get_array_fid(), OP_ARRAY_EXT, SKIP); MK_BINARY(Z3_mk_array_ext, mk_c(c)->get_array_fid(), OP_ARRAY_EXT, SKIP);
Z3_ast Z3_API Z3_mk_as_array(Z3_context c, Z3_func_decl f) {
Z3_TRY;
LOG_Z3_mk_as_array(c, f);
RESET_ERROR_CODE();
ast_manager & m = mk_c(c)->m();
array_util a(m);
app * r = a.mk_as_array(to_func_decl(f));
mk_c(c)->save_ast_trail(r);
return of_ast(r);
Z3_CATCH_RETURN(0);
}
Z3_ast Z3_mk_set_member(Z3_context c, Z3_ast elem, Z3_ast set) { Z3_ast Z3_mk_set_member(Z3_context c, Z3_ast elem, Z3_ast set) {
return Z3_mk_select(c, set, elem); return Z3_mk_select(c, set, elem);
} }
@ -222,7 +307,8 @@ extern "C" {
CHECK_VALID_AST(t, 0); CHECK_VALID_AST(t, 0);
if (to_sort(t)->get_family_id() == mk_c(c)->get_array_fid() && if (to_sort(t)->get_family_id() == mk_c(c)->get_array_fid() &&
to_sort(t)->get_decl_kind() == ARRAY_SORT) { to_sort(t)->get_decl_kind() == ARRAY_SORT) {
Z3_sort r = reinterpret_cast<Z3_sort>(to_sort(t)->get_parameter(1).get_ast()); unsigned n = to_sort(t)->get_num_parameters();
Z3_sort r = reinterpret_cast<Z3_sort>(to_sort(t)->get_parameter(n-1).get_ast());
RETURN_Z3(r); RETURN_Z3(r);
} }
SET_ERROR_CODE(Z3_INVALID_ARG); SET_ERROR_CODE(Z3_INVALID_ARG);

View file

@ -16,28 +16,28 @@ Revision History:
--*/ --*/
#include<iostream> #include<iostream>
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_context.h" #include "api/api_context.h"
#include"api_util.h" #include "api/api_util.h"
#include"well_sorted.h" #include "ast/well_sorted.h"
#include"arith_decl_plugin.h" #include "ast/arith_decl_plugin.h"
#include"bv_decl_plugin.h" #include "ast/bv_decl_plugin.h"
#include"datatype_decl_plugin.h" #include "ast/datatype_decl_plugin.h"
#include"array_decl_plugin.h" #include "ast/array_decl_plugin.h"
#include"pb_decl_plugin.h" #include "ast/pb_decl_plugin.h"
#include"ast_translation.h" #include "ast/ast_translation.h"
#include"ast_pp.h" #include "ast/ast_pp.h"
#include"ast_ll_pp.h" #include "ast/ast_ll_pp.h"
#include"ast_smt_pp.h" #include "ast/ast_smt_pp.h"
#include"ast_smt2_pp.h" #include "ast/ast_smt2_pp.h"
#include"th_rewriter.h" #include "ast/rewriter/th_rewriter.h"
#include"var_subst.h" #include "ast/rewriter/var_subst.h"
#include"expr_safe_replace.h" #include "ast/rewriter/expr_safe_replace.h"
#include"pp.h" #include "ast/pp.h"
#include"scoped_ctrl_c.h" #include "util/scoped_ctrl_c.h"
#include"cancel_eh.h" #include "util/cancel_eh.h"
#include"scoped_timer.h" #include "util/scoped_timer.h"
#include"pp_params.hpp" #include "ast/pp_params.hpp"
extern bool is_numeral_sort(Z3_context c, Z3_sort ty); extern bool is_numeral_sort(Z3_context c, Z3_sort ty);
@ -1204,16 +1204,8 @@ extern "C" {
case OP_FPA_TO_SBV: return Z3_OP_FPA_TO_SBV; case OP_FPA_TO_SBV: return Z3_OP_FPA_TO_SBV;
case OP_FPA_TO_REAL: return Z3_OP_FPA_TO_REAL; case OP_FPA_TO_REAL: return Z3_OP_FPA_TO_REAL;
case OP_FPA_TO_IEEE_BV: return Z3_OP_FPA_TO_IEEE_BV; case OP_FPA_TO_IEEE_BV: return Z3_OP_FPA_TO_IEEE_BV;
case OP_FPA_INTERNAL_MIN_I: return Z3_OP_FPA_MIN_I; case OP_FPA_BVWRAP: return Z3_OP_FPA_BVWRAP;
case OP_FPA_INTERNAL_MAX_I: return Z3_OP_FPA_MAX_I; case OP_FPA_BV2RM: return Z3_OP_FPA_BV2RM;
case OP_FPA_INTERNAL_BV2RM:
case OP_FPA_INTERNAL_BVWRAP:
case OP_FPA_INTERNAL_MIN_UNSPECIFIED:
case OP_FPA_INTERNAL_MAX_UNSPECIFIED:
case OP_FPA_INTERNAL_TO_UBV_UNSPECIFIED:
case OP_FPA_INTERNAL_TO_SBV_UNSPECIFIED:
case OP_FPA_INTERNAL_TO_REAL_UNSPECIFIED:
case OP_FPA_INTERNAL_TO_IEEE_BV_UNSPECIFIED:
return Z3_OP_UNINTERPRETED; return Z3_OP_UNINTERPRETED;
default: default:
return Z3_OP_INTERNAL; return Z3_OP_INTERNAL;

View file

@ -16,13 +16,13 @@ Revision History:
--*/ --*/
#include<iostream> #include<iostream>
#include"z3.h" #include "api/z3.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_context.h" #include "api/api_context.h"
#include"api_ast_map.h" #include "api/api_ast_map.h"
#include"api_ast_vector.h" #include "api/api_ast_vector.h"
#include"ast_smt2_pp.h" #include "ast/ast_smt2_pp.h"
#include"dec_ref_util.h" #include "util/dec_ref_util.h"
Z3_ast_map_ref::~Z3_ast_map_ref() { Z3_ast_map_ref::~Z3_ast_map_ref() {
dec_ref_key_values(m, m_map); dec_ref_key_values(m, m_map);

View file

@ -18,8 +18,8 @@ Revision History:
#ifndef API_AST_MAP_H_ #ifndef API_AST_MAP_H_
#define API_AST_MAP_H_ #define API_AST_MAP_H_
#include"api_util.h" #include "api/api_util.h"
#include"obj_hashtable.h" #include "util/obj_hashtable.h"
struct Z3_ast_map_ref : public api::object { struct Z3_ast_map_ref : public api::object {
ast_manager & m; ast_manager & m;

View file

@ -16,12 +16,12 @@ Revision History:
--*/ --*/
#include<iostream> #include<iostream>
#include"z3.h" #include "api/z3.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_context.h" #include "api/api_context.h"
#include"api_ast_vector.h" #include "api/api_ast_vector.h"
#include"ast_translation.h" #include "ast/ast_translation.h"
#include"ast_smt2_pp.h" #include "ast/ast_smt2_pp.h"
extern "C" { extern "C" {

View file

@ -18,7 +18,7 @@ Revision History:
#ifndef API_AST_VECTOR_H_ #ifndef API_AST_VECTOR_H_
#define API_AST_VECTOR_H_ #define API_AST_VECTOR_H_
#include"api_util.h" #include "api/api_util.h"
namespace api { namespace api {
class context; class context;

View file

@ -15,11 +15,11 @@ Author:
Revision History: Revision History:
--*/ --*/
#include"z3.h" #include "api/z3.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_context.h" #include "api/api_context.h"
#include"api_util.h" #include "api/api_util.h"
#include"bv_decl_plugin.h" #include "ast/bv_decl_plugin.h"
extern "C" { extern "C" {

View file

@ -15,16 +15,16 @@ Author:
Revision History: Revision History:
--*/ --*/
#include"z3.h" #include "api/z3.h"
#include"api_context.h" #include "api/api_context.h"
#include"pp.h" #include "ast/pp.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_util.h" #include "api/api_util.h"
#include"cmd_context.h" #include "cmd_context/cmd_context.h"
#include"symbol.h" #include "util/symbol.h"
#include"gparams.h" #include "util/gparams.h"
#include"env_params.h" #include "util/env_params.h"
#include"context_params.h" #include "cmd_context/context_params.h"
extern "C" { extern "C" {
void Z3_API Z3_global_param_set(Z3_string param_id, Z3_string param_value) { void Z3_API Z3_global_param_set(Z3_string param_id, Z3_string param_value) {

View file

@ -18,15 +18,15 @@ Revision History:
--*/ --*/
#include<typeinfo> #include<typeinfo>
#include"api_context.h" #include "api/api_context.h"
#include"smtparser.h" #include "parsers/smt/smtparser.h"
#include"version.h" #include "util/version.h"
#include"ast_pp.h" #include "ast/ast_pp.h"
#include"ast_ll_pp.h" #include "ast/ast_ll_pp.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_util.h" #include "api/api_util.h"
#include"reg_decl_plugins.h" #include "ast/reg_decl_plugins.h"
#include"realclosure.h" #include "math/realclosure/realclosure.h"
// The install_tactics procedure is automatically generated // The install_tactics procedure is automatically generated
void install_tactics(tactic_manager & ctx); void install_tactics(tactic_manager & ctx);
@ -142,7 +142,7 @@ namespace api {
#pragma omp critical (set_interruptable) #pragma omp critical (set_interruptable)
{ {
if (m_interruptable) if (m_interruptable)
(*m_interruptable)(); (*m_interruptable)(API_INTERRUPT_EH_CALLER);
m_limit.cancel(); m_limit.cancel();
m().limit().cancel(); m().limit().cancel();
} }
@ -150,8 +150,9 @@ namespace api {
void context::set_error_code(Z3_error_code err) { void context::set_error_code(Z3_error_code err) {
m_error_code = err; m_error_code = err;
if (err != Z3_OK) if (err != Z3_OK) {
invoke_error_handler(err); invoke_error_handler(err);
}
} }
void context::check_searching() { void context::check_searching() {

View file

@ -20,22 +20,22 @@ Revision History:
#ifndef API_CONTEXT_H_ #ifndef API_CONTEXT_H_
#define API_CONTEXT_H_ #define API_CONTEXT_H_
#include"z3.h" #include "api/z3.h"
#include"ast.h" #include "ast/ast.h"
#include"api_util.h" #include "api/api_util.h"
#include"arith_decl_plugin.h" #include "ast/arith_decl_plugin.h"
#include"bv_decl_plugin.h" #include "ast/bv_decl_plugin.h"
#include"seq_decl_plugin.h" #include "ast/seq_decl_plugin.h"
#include"datatype_decl_plugin.h" #include "ast/datatype_decl_plugin.h"
#include"dl_decl_plugin.h" #include "ast/dl_decl_plugin.h"
#include"fpa_decl_plugin.h" #include "ast/fpa_decl_plugin.h"
#include"smt_kernel.h" #include "smt/smt_kernel.h"
#include"smt_params.h" #include "smt/params/smt_params.h"
#include"event_handler.h" #include "util/event_handler.h"
#include"tactic_manager.h" #include "cmd_context/tactic_manager.h"
#include"context_params.h" #include "cmd_context/context_params.h"
#include"api_polynomial.h" #include "api/api_polynomial.h"
#include"hashtable.h" #include "util/hashtable.h"
namespace smtlib { namespace smtlib {
class parser; class parser;

View file

@ -15,24 +15,24 @@ Author:
Revision History: Revision History:
--*/ --*/
#include"api_datalog.h" #include "api/api_datalog.h"
#include"api_context.h" #include "api/api_context.h"
#include"api_util.h" #include "api/api_util.h"
#include"ast_pp.h" #include "ast/ast_pp.h"
#include"api_ast_vector.h" #include "api/api_ast_vector.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_stats.h" #include "api/api_stats.h"
#include"datalog_parser.h" #include "muz/fp/datalog_parser.h"
#include"cancel_eh.h" #include "util/cancel_eh.h"
#include"scoped_timer.h" #include "util/scoped_timer.h"
#include"dl_cmds.h" #include "muz/fp/dl_cmds.h"
#include"cmd_context.h" #include "cmd_context/cmd_context.h"
#include"smt2parser.h" #include "parsers/smt2/smt2parser.h"
#include"dl_context.h" #include "muz/base/dl_context.h"
#include"dl_register_engine.h" #include "muz/fp/dl_register_engine.h"
#include"dl_external_relation.h" #include "muz/rel/dl_external_relation.h"
#include"dl_decl_plugin.h" #include "ast/dl_decl_plugin.h"
#include"rel_context.h" #include "muz/rel/rel_context.h"
namespace api { namespace api {
@ -605,5 +605,6 @@ extern "C" {
} }
#include "api_datalog_spacer.inc"
}; };

View file

@ -19,11 +19,11 @@ Revision History:
#ifndef API_DATALOG_H_ #ifndef API_DATALOG_H_
#define API_DATALOG_H_ #define API_DATALOG_H_
#include"z3.h" #include "api/z3.h"
#include"ast.h" #include "ast/ast.h"
#include"smt_params.h" #include "smt/params/smt_params.h"
#include"smt_kernel.h" #include "smt/smt_kernel.h"
#include"api_util.h" #include "api/api_util.h"
typedef void (*reduce_app_callback_fptr)(void*, func_decl*, unsigned, expr*const*, expr**); typedef void (*reduce_app_callback_fptr)(void*, func_decl*, unsigned, expr*const*, expr**);
typedef void (*reduce_assign_callback_fptr)(void*, func_decl*, unsigned, expr*const*, unsigned, expr*const*); typedef void (*reduce_assign_callback_fptr)(void*, func_decl*, unsigned, expr*const*, unsigned, expr*const*);

View file

@ -0,0 +1,113 @@
/*++
Copyright (c) 2017 Arie Gurfinkel
Module Name:
api_datalog_spacer.inc
Abstract:
Spacer-specific datalog API
Author:
Arie Gurfinkel (arie)
Notes:
this file is included at the bottom of api_datalog.cpp
--*/
Z3_lbool Z3_API Z3_fixedpoint_query_from_lvl (Z3_context c, Z3_fixedpoint d, Z3_ast q, unsigned lvl) {
Z3_TRY;
LOG_Z3_fixedpoint_query_from_lvl (c, d, q, lvl);
RESET_ERROR_CODE();
lbool r = l_undef;
unsigned timeout = to_fixedpoint(d)->m_params.get_uint("timeout", mk_c(c)->get_timeout());
unsigned rlimit = to_fixedpoint(d)->m_params.get_uint("rlimit", mk_c(c)->get_rlimit());
{
scoped_rlimit _rlimit(mk_c(c)->m().limit(), rlimit);
cancel_eh<reslimit> eh(mk_c(c)->m().limit());
api::context::set_interruptable si(*(mk_c(c)), eh);
scoped_timer timer(timeout, &eh);
try {
r = to_fixedpoint_ref(d)->ctx().query_from_lvl (to_expr(q), lvl);
}
catch (z3_exception& ex) {
mk_c(c)->handle_exception(ex);
r = l_undef;
}
to_fixedpoint_ref(d)->ctx().cleanup();
}
return of_lbool(r);
Z3_CATCH_RETURN(Z3_L_UNDEF);
}
Z3_ast Z3_API Z3_fixedpoint_get_ground_sat_answer(Z3_context c, Z3_fixedpoint d) {
Z3_TRY;
LOG_Z3_fixedpoint_get_ground_sat_answer(c, d);
RESET_ERROR_CODE();
expr* e = to_fixedpoint_ref(d)->ctx().get_ground_sat_answer();
mk_c(c)->save_ast_trail(e);
RETURN_Z3(of_expr(e));
Z3_CATCH_RETURN(0);
}
Z3_ast_vector Z3_API Z3_fixedpoint_get_rules_along_trace(
Z3_context c,
Z3_fixedpoint d)
{
Z3_TRY;
LOG_Z3_fixedpoint_get_rules_along_trace(c, d);
ast_manager& m = mk_c(c)->m();
Z3_ast_vector_ref* v = alloc(Z3_ast_vector_ref, *mk_c(c), m);
mk_c(c)->save_object(v);
expr_ref_vector rules(m);
svector<symbol> names;
to_fixedpoint_ref(d)->ctx().get_rules_along_trace_as_formulas(rules, names);
for (unsigned i = 0; i < rules.size(); ++i) {
v->m_ast_vector.push_back(rules[i].get());
}
RETURN_Z3(of_ast_vector(v));
Z3_CATCH_RETURN(0);
}
Z3_symbol Z3_API Z3_fixedpoint_get_rule_names_along_trace(
Z3_context c,
Z3_fixedpoint d)
{
Z3_TRY;
LOG_Z3_fixedpoint_get_rule_names_along_trace(c, d);
ast_manager& m = mk_c(c)->m();
Z3_ast_vector_ref* v = alloc(Z3_ast_vector_ref, *mk_c(c), m);
mk_c(c)->save_object(v);
expr_ref_vector rules(m);
svector<symbol> names;
std::stringstream ss;
to_fixedpoint_ref(d)->ctx().get_rules_along_trace_as_formulas(rules, names);
for (unsigned i = 0; i < names.size(); ++i) {
ss << ";" << names[i].str();
}
RETURN_Z3(of_symbol(symbol(ss.str().substr(1).c_str())));
Z3_CATCH_RETURN(0);
}
void Z3_API Z3_fixedpoint_add_invariant(Z3_context c, Z3_fixedpoint d, Z3_func_decl pred, Z3_ast property) {
Z3_TRY;
LOG_Z3_fixedpoint_add_invariant(c, d, pred, property);
RESET_ERROR_CODE();
to_fixedpoint_ref(d)->ctx ().add_invariant(to_func_decl(pred), to_expr(property));
Z3_CATCH;
}
Z3_ast Z3_API Z3_fixedpoint_get_reachable(Z3_context c, Z3_fixedpoint d, Z3_func_decl pred) {
Z3_TRY;
LOG_Z3_fixedpoint_get_reachable(c, d, pred);
RESET_ERROR_CODE();
expr_ref r = to_fixedpoint_ref(d)->ctx().get_reachable(to_func_decl(pred));
mk_c(c)->save_ast_trail(r);
RETURN_Z3(of_expr(r.get()));
Z3_CATCH_RETURN(0);
}

View file

@ -15,11 +15,11 @@ Author:
Revision History: Revision History:
--*/ --*/
#include"z3.h" #include "api/z3.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_context.h" #include "api/api_context.h"
#include"api_util.h" #include "api/api_util.h"
#include"datatype_decl_plugin.h" #include "ast/datatype_decl_plugin.h"
extern "C" { extern "C" {
@ -45,13 +45,13 @@ extern "C" {
ptr_vector<accessor_decl> acc; ptr_vector<accessor_decl> acc;
for (unsigned i = 0; i < num_fields; ++i) { for (unsigned i = 0; i < num_fields; ++i) {
acc.push_back(mk_accessor_decl(to_symbol(field_names[i]), type_ref(to_sort(field_sorts[i])))); acc.push_back(mk_accessor_decl(m, to_symbol(field_names[i]), type_ref(to_sort(field_sorts[i]))));
} }
constructor_decl* constrs[1] = { mk_constructor_decl(to_symbol(name), recognizer, acc.size(), acc.c_ptr()) }; constructor_decl* constrs[1] = { mk_constructor_decl(to_symbol(name), recognizer, acc.size(), acc.c_ptr()) };
{ {
datatype_decl * dt = mk_datatype_decl(to_symbol(name), 1, constrs); datatype_decl * dt = mk_datatype_decl(dt_util, to_symbol(name), 0, nullptr, 1, constrs);
bool is_ok = mk_c(c)->get_dt_plugin()->mk_datatypes(1, &dt, 0, 0, tuples); bool is_ok = mk_c(c)->get_dt_plugin()->mk_datatypes(1, &dt, 0, 0, tuples);
del_datatype_decl(dt); del_datatype_decl(dt);
@ -69,18 +69,13 @@ extern "C" {
// create constructor // create constructor
SASSERT(dt_util.is_datatype(tuple)); SASSERT(dt_util.is_datatype(tuple));
SASSERT(!dt_util.is_recursive(tuple)); SASSERT(!dt_util.is_recursive(tuple));
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(tuple); ptr_vector<func_decl> const & decls = *dt_util.get_datatype_constructors(tuple);
func_decl* decl = (*decls)[0]; func_decl* decl = (decls)[0];
mk_c(c)->save_multiple_ast_trail(decl); mk_c(c)->save_multiple_ast_trail(decl);
*mk_tuple_decl = of_func_decl(decl); *mk_tuple_decl = of_func_decl(decl);
// Create projections // Create projections
ptr_vector<func_decl> const * accs = dt_util.get_constructor_accessors(decl); ptr_vector<func_decl> const & _accs = *dt_util.get_constructor_accessors(decl);
if (!accs) {
SET_ERROR_CODE(Z3_INVALID_ARG);
RETURN_Z3(0);
}
ptr_vector<func_decl> const & _accs = *accs;
SASSERT(_accs.size() == num_fields); SASSERT(_accs.size() == num_fields);
for (unsigned i = 0; i < _accs.size(); i++) { for (unsigned i = 0; i < _accs.size(); i++) {
mk_c(c)->save_multiple_ast_trail(_accs[i]); mk_c(c)->save_multiple_ast_trail(_accs[i]);
@ -118,7 +113,7 @@ extern "C" {
{ {
datatype_decl * dt = mk_datatype_decl(to_symbol(name), n, constrs.c_ptr()); datatype_decl * dt = mk_datatype_decl(dt_util, to_symbol(name), 0, 0, n, constrs.c_ptr());
bool is_ok = mk_c(c)->get_dt_plugin()->mk_datatypes(1, &dt, 0, 0, sorts); bool is_ok = mk_c(c)->get_dt_plugin()->mk_datatypes(1, &dt, 0, 0, sorts);
del_datatype_decl(dt); del_datatype_decl(dt);
@ -136,10 +131,10 @@ extern "C" {
// create constructor // create constructor
SASSERT(dt_util.is_datatype(e)); SASSERT(dt_util.is_datatype(e));
SASSERT(!dt_util.is_recursive(e)); SASSERT(!dt_util.is_recursive(e));
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(e); ptr_vector<func_decl> const & decls = *dt_util.get_datatype_constructors(e);
SASSERT(decls && decls->size() == n); SASSERT(decls.size() == n);
for (unsigned i = 0; i < n; ++i) { for (unsigned i = 0; i < n; ++i) {
func_decl* decl = (*decls)[i]; func_decl* decl = (decls)[i];
mk_c(c)->save_multiple_ast_trail(decl); mk_c(c)->save_multiple_ast_trail(decl);
enum_consts[i] = of_func_decl(decl); enum_consts[i] = of_func_decl(decl);
decl = dt_util.get_constructor_recognizer(decl); decl = dt_util.get_constructor_recognizer(decl);
@ -165,11 +160,12 @@ extern "C" {
LOG_Z3_mk_list_sort(c, name, elem_sort, nil_decl, is_nil_decl, cons_decl, is_cons_decl, head_decl, tail_decl); LOG_Z3_mk_list_sort(c, name, elem_sort, nil_decl, is_nil_decl, cons_decl, is_cons_decl, head_decl, tail_decl);
RESET_ERROR_CODE(); RESET_ERROR_CODE();
ast_manager& m = mk_c(c)->m(); ast_manager& m = mk_c(c)->m();
datatype_util& dt_util = mk_c(c)->dtutil();
mk_c(c)->reset_last_result(); mk_c(c)->reset_last_result();
datatype_util data_util(m); datatype_util data_util(m);
accessor_decl* head_tail[2] = { accessor_decl* head_tail[2] = {
mk_accessor_decl(symbol("head"), type_ref(to_sort(elem_sort))), mk_accessor_decl(m, symbol("head"), type_ref(to_sort(elem_sort))),
mk_accessor_decl(symbol("tail"), type_ref(0)) mk_accessor_decl(m, symbol("tail"), type_ref(0))
}; };
constructor_decl* constrs[2] = { constructor_decl* constrs[2] = {
mk_constructor_decl(symbol("nil"), symbol("is_nil"), 0, 0), mk_constructor_decl(symbol("nil"), symbol("is_nil"), 0, 0),
@ -179,7 +175,7 @@ extern "C" {
sort_ref_vector sorts(m); sort_ref_vector sorts(m);
{ {
datatype_decl * decl = mk_datatype_decl(to_symbol(name), 2, constrs); datatype_decl * decl = mk_datatype_decl(dt_util, to_symbol(name), 0, nullptr, 2, constrs);
bool is_ok = mk_c(c)->get_dt_plugin()->mk_datatypes(1, &decl, 0, 0, sorts); bool is_ok = mk_c(c)->get_dt_plugin()->mk_datatypes(1, &decl, 0, 0, sorts);
del_datatype_decl(decl); del_datatype_decl(decl);
@ -215,18 +211,16 @@ extern "C" {
*is_cons_decl = of_func_decl(f); *is_cons_decl = of_func_decl(f);
} }
if (head_decl) { if (head_decl) {
ptr_vector<func_decl> const* acc = data_util.get_constructor_accessors(cnstrs[1]); ptr_vector<func_decl> const& acc = *data_util.get_constructor_accessors(cnstrs[1]);
SASSERT(acc); SASSERT(acc.size() == 2);
SASSERT(acc->size() == 2); f = (acc)[0];
f = (*acc)[0];
mk_c(c)->save_multiple_ast_trail(f); mk_c(c)->save_multiple_ast_trail(f);
*head_decl = of_func_decl(f); *head_decl = of_func_decl(f);
} }
if (tail_decl) { if (tail_decl) {
ptr_vector<func_decl> const* acc = data_util.get_constructor_accessors(cnstrs[1]); ptr_vector<func_decl> const& acc = *data_util.get_constructor_accessors(cnstrs[1]);
SASSERT(acc); SASSERT(acc.size() == 2);
SASSERT(acc->size() == 2); f = (acc)[1];
f = (*acc)[1];
mk_c(c)->save_multiple_ast_trail(f); mk_c(c)->save_multiple_ast_trail(f);
*tail_decl = of_func_decl(f); *tail_decl = of_func_decl(f);
} }
@ -301,13 +295,9 @@ extern "C" {
*tester = of_func_decl(f2); *tester = of_func_decl(f2);
} }
ptr_vector<func_decl> const* accs = data_util.get_constructor_accessors(f); ptr_vector<func_decl> const& accs = *data_util.get_constructor_accessors(f);
if (!accs && num_fields > 0) {
SET_ERROR_CODE(Z3_INVALID_ARG);
return;
}
for (unsigned i = 0; i < num_fields; ++i) { for (unsigned i = 0; i < num_fields; ++i) {
func_decl* f2 = (*accs)[i]; func_decl* f2 = (accs)[i];
mk_c(c)->save_multiple_ast_trail(f2); mk_c(c)->save_multiple_ast_trail(f2);
accessors[i] = of_func_decl(f2); accessors[i] = of_func_decl(f2);
} }
@ -327,21 +317,23 @@ extern "C" {
Z3_symbol name, Z3_symbol name,
unsigned num_constructors, unsigned num_constructors,
Z3_constructor constructors[]) { Z3_constructor constructors[]) {
datatype_util& dt_util = mk_c(c)->dtutil();
ast_manager& m = mk_c(c)->m();
ptr_vector<constructor_decl> constrs; ptr_vector<constructor_decl> constrs;
for (unsigned i = 0; i < num_constructors; ++i) { for (unsigned i = 0; i < num_constructors; ++i) {
constructor* cn = reinterpret_cast<constructor*>(constructors[i]); constructor* cn = reinterpret_cast<constructor*>(constructors[i]);
ptr_vector<accessor_decl> acc; ptr_vector<accessor_decl> acc;
for (unsigned j = 0; j < cn->m_sorts.size(); ++j) { for (unsigned j = 0; j < cn->m_sorts.size(); ++j) {
if (cn->m_sorts[j].get()) { if (cn->m_sorts[j].get()) {
acc.push_back(mk_accessor_decl(cn->m_field_names[j], type_ref(cn->m_sorts[j].get()))); acc.push_back(mk_accessor_decl(m, cn->m_field_names[j], type_ref(cn->m_sorts[j].get())));
} }
else { else {
acc.push_back(mk_accessor_decl(cn->m_field_names[j], type_ref(cn->m_sort_refs[j]))); acc.push_back(mk_accessor_decl(m, cn->m_field_names[j], type_ref(cn->m_sort_refs[j])));
} }
} }
constrs.push_back(mk_constructor_decl(cn->m_name, cn->m_tester, acc.size(), acc.c_ptr())); constrs.push_back(mk_constructor_decl(cn->m_name, cn->m_tester, acc.size(), acc.c_ptr()));
} }
return mk_datatype_decl(to_symbol(name), num_constructors, constrs.c_ptr()); return mk_datatype_decl(dt_util, to_symbol(name), 0, nullptr, num_constructors, constrs.c_ptr());
} }
Z3_sort Z3_API Z3_mk_datatype(Z3_context c, Z3_sort Z3_API Z3_mk_datatype(Z3_context c,
@ -368,11 +360,11 @@ extern "C" {
sort * s = sorts.get(0); sort * s = sorts.get(0);
mk_c(c)->save_ast_trail(s); mk_c(c)->save_ast_trail(s);
ptr_vector<func_decl> const* cnstrs = data_util.get_datatype_constructors(s); ptr_vector<func_decl> const& cnstrs = *data_util.get_datatype_constructors(s);
for (unsigned i = 0; i < num_constructors; ++i) { for (unsigned i = 0; i < num_constructors; ++i) {
constructor* cn = reinterpret_cast<constructor*>(constructors[i]); constructor* cn = reinterpret_cast<constructor*>(constructors[i]);
cn->m_constructor = (*cnstrs)[i]; cn->m_constructor = cnstrs[i];
} }
RETURN_Z3_mk_datatype(of_sort(s)); RETURN_Z3_mk_datatype(of_sort(s));
Z3_CATCH_RETURN(0); Z3_CATCH_RETURN(0);
@ -417,7 +409,7 @@ extern "C" {
ptr_vector<datatype_decl> datas; ptr_vector<datatype_decl> datas;
for (unsigned i = 0; i < num_sorts; ++i) { for (unsigned i = 0; i < num_sorts; ++i) {
constructor_list* cl = reinterpret_cast<constructor_list*>(constructor_lists[i]); constructor_list* cl = reinterpret_cast<constructor_list*>(constructor_lists[i]);
datas.push_back(mk_datatype_decl(c,sort_names[i], cl->size(), reinterpret_cast<Z3_constructor*>(cl->c_ptr()))); datas.push_back(mk_datatype_decl(c, sort_names[i], cl->size(), reinterpret_cast<Z3_constructor*>(cl->c_ptr())));
} }
sort_ref_vector _sorts(m); sort_ref_vector _sorts(m);
bool ok = mk_c(c)->get_dt_plugin()->mk_datatypes(datas.size(), datas.c_ptr(), 0, 0, _sorts); bool ok = mk_c(c)->get_dt_plugin()->mk_datatypes(datas.size(), datas.c_ptr(), 0, 0, _sorts);
@ -434,10 +426,10 @@ extern "C" {
mk_c(c)->save_multiple_ast_trail(s); mk_c(c)->save_multiple_ast_trail(s);
sorts[i] = of_sort(s); sorts[i] = of_sort(s);
constructor_list* cl = reinterpret_cast<constructor_list*>(constructor_lists[i]); constructor_list* cl = reinterpret_cast<constructor_list*>(constructor_lists[i]);
ptr_vector<func_decl> const* cnstrs = data_util.get_datatype_constructors(s); ptr_vector<func_decl> const& cnstrs = *data_util.get_datatype_constructors(s);
for (unsigned j = 0; j < cl->size(); ++j) { for (unsigned j = 0; j < cl->size(); ++j) {
constructor* cn = (*cl)[j]; constructor* cn = (*cl)[j];
cn->m_constructor = (*cnstrs)[j]; cn->m_constructor = cnstrs[j];
} }
} }
RETURN_Z3_mk_datatypes; RETURN_Z3_mk_datatypes;
@ -456,12 +448,7 @@ extern "C" {
SET_ERROR_CODE(Z3_INVALID_ARG); SET_ERROR_CODE(Z3_INVALID_ARG);
return 0; return 0;
} }
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(_t); return dt_util.get_datatype_constructors(_t)->size();
if (!decls) {
SET_ERROR_CODE(Z3_INVALID_ARG);
return 0;
}
return decls->size();
Z3_CATCH_RETURN(0); Z3_CATCH_RETURN(0);
} }
@ -474,12 +461,12 @@ extern "C" {
SET_ERROR_CODE(Z3_INVALID_ARG); SET_ERROR_CODE(Z3_INVALID_ARG);
return 0; return 0;
} }
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(_t); ptr_vector<func_decl> const & decls = *dt_util.get_datatype_constructors(_t);
if (!decls || idx >= decls->size()) { if (idx >= decls.size()) {
SET_ERROR_CODE(Z3_INVALID_ARG); SET_ERROR_CODE(Z3_INVALID_ARG);
return 0; return 0;
} }
func_decl* decl = (*decls)[idx]; func_decl* decl = (decls)[idx];
mk_c(c)->save_ast_trail(decl); mk_c(c)->save_ast_trail(decl);
return of_func_decl(decl); return of_func_decl(decl);
} }
@ -504,12 +491,12 @@ extern "C" {
SET_ERROR_CODE(Z3_INVALID_ARG); SET_ERROR_CODE(Z3_INVALID_ARG);
RETURN_Z3(0); RETURN_Z3(0);
} }
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(_t); ptr_vector<func_decl> const & decls = *dt_util.get_datatype_constructors(_t);
if (!decls || idx >= decls->size()) { if (idx >= decls.size()) {
SET_ERROR_CODE(Z3_INVALID_ARG); SET_ERROR_CODE(Z3_INVALID_ARG);
RETURN_Z3(0); RETURN_Z3(0);
} }
func_decl* decl = (*decls)[idx]; func_decl* decl = (decls)[idx];
decl = dt_util.get_constructor_recognizer(decl); decl = dt_util.get_constructor_recognizer(decl);
mk_c(c)->save_ast_trail(decl); mk_c(c)->save_ast_trail(decl);
RETURN_Z3(of_func_decl(decl)); RETURN_Z3(of_func_decl(decl));
@ -527,23 +514,23 @@ extern "C" {
SET_ERROR_CODE(Z3_INVALID_ARG); SET_ERROR_CODE(Z3_INVALID_ARG);
RETURN_Z3(0); RETURN_Z3(0);
} }
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(_t); ptr_vector<func_decl> const & decls = *dt_util.get_datatype_constructors(_t);
if (!decls || idx_c >= decls->size()) { if (idx_c >= decls.size()) {
SET_ERROR_CODE(Z3_INVALID_ARG); SET_ERROR_CODE(Z3_INVALID_ARG);
return 0; return 0;
} }
func_decl* decl = (*decls)[idx_c]; func_decl* decl = (decls)[idx_c];
if (decl->get_arity() <= idx_a) { if (decl->get_arity() <= idx_a) {
SET_ERROR_CODE(Z3_INVALID_ARG); SET_ERROR_CODE(Z3_INVALID_ARG);
RETURN_Z3(0); RETURN_Z3(0);
} }
ptr_vector<func_decl> const * accs = dt_util.get_constructor_accessors(decl); ptr_vector<func_decl> const & accs = *dt_util.get_constructor_accessors(decl);
SASSERT(accs && accs->size() == decl->get_arity()); SASSERT(accs.size() == decl->get_arity());
if (!accs || accs->size() <= idx_a) { if (accs.size() <= idx_a) {
SET_ERROR_CODE(Z3_INVALID_ARG); SET_ERROR_CODE(Z3_INVALID_ARG);
RETURN_Z3(0); RETURN_Z3(0);
} }
decl = (*accs)[idx_a]; decl = (accs)[idx_a];
mk_c(c)->save_ast_trail(decl); mk_c(c)->save_ast_trail(decl);
RETURN_Z3(of_func_decl(decl)); RETURN_Z3(of_func_decl(decl));
Z3_CATCH_RETURN(0); Z3_CATCH_RETURN(0);
@ -574,16 +561,13 @@ extern "C" {
SET_ERROR_CODE(Z3_INVALID_ARG); SET_ERROR_CODE(Z3_INVALID_ARG);
return 0; return 0;
} }
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(tuple); ptr_vector<func_decl> const & decls = *dt_util.get_datatype_constructors(tuple);
if (!decls || decls->size() != 1) { if (decls.size() != 1) {
SET_ERROR_CODE(Z3_INVALID_ARG); SET_ERROR_CODE(Z3_INVALID_ARG);
return 0; return 0;
} }
ptr_vector<func_decl> const * accs = dt_util.get_constructor_accessors((*decls)[0]); ptr_vector<func_decl> const & accs = *dt_util.get_constructor_accessors(decls[0]);
if (!accs) { return accs.size();
return 0;
}
return accs->size();
Z3_CATCH_RETURN(0); Z3_CATCH_RETURN(0);
} }
@ -597,21 +581,17 @@ extern "C" {
SET_ERROR_CODE(Z3_INVALID_ARG); SET_ERROR_CODE(Z3_INVALID_ARG);
RETURN_Z3(0); RETURN_Z3(0);
} }
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(tuple); ptr_vector<func_decl> const & decls = *dt_util.get_datatype_constructors(tuple);
if (!decls || decls->size() != 1) { if (decls.size() != 1) {
SET_ERROR_CODE(Z3_INVALID_ARG); SET_ERROR_CODE(Z3_INVALID_ARG);
RETURN_Z3(0); RETURN_Z3(0);
} }
ptr_vector<func_decl> const * accs = dt_util.get_constructor_accessors((*decls)[0]); ptr_vector<func_decl> const & accs = *dt_util.get_constructor_accessors((decls)[0]);
if (!accs) { if (accs.size() <= i) {
SET_ERROR_CODE(Z3_INVALID_ARG);
RETURN_Z3(0);
}
if (accs->size() <= i) {
SET_ERROR_CODE(Z3_IOB); SET_ERROR_CODE(Z3_IOB);
RETURN_Z3(0); RETURN_Z3(0);
} }
func_decl* acc = (*accs)[i]; func_decl* acc = (accs)[i];
mk_c(c)->save_ast_trail(acc); mk_c(c)->save_ast_trail(acc);
RETURN_Z3(of_func_decl(acc)); RETURN_Z3(of_func_decl(acc));
Z3_CATCH_RETURN(0); Z3_CATCH_RETURN(0);

View file

@ -17,10 +17,10 @@ Notes:
--*/ --*/
#include<iostream> #include<iostream>
#include"z3.h" #include "api/z3.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_context.h" #include "api/api_context.h"
#include"fpa_decl_plugin.h" #include "ast/fpa_decl_plugin.h"
bool is_fp_sort(Z3_context c, Z3_sort s) { bool is_fp_sort(Z3_context c, Z3_sort s) {
return mk_c(c)->fpautil().is_float(to_sort(s)); return mk_c(c)->fpautil().is_float(to_sort(s));

View file

@ -16,11 +16,11 @@ Revision History:
--*/ --*/
#include<iostream> #include<iostream>
#include"z3.h" #include "api/z3.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_context.h" #include "api/api_context.h"
#include"api_goal.h" #include "api/api_goal.h"
#include"ast_translation.h" #include "ast/ast_translation.h"
extern "C" { extern "C" {

View file

@ -18,8 +18,8 @@ Revision History:
#ifndef API_GOAL_H_ #ifndef API_GOAL_H_
#define API_GOAL_H_ #define API_GOAL_H_
#include"api_util.h" #include "api/api_util.h"
#include"goal.h" #include "tactic/goal.h"
struct Z3_goal_ref : public api::object { struct Z3_goal_ref : public api::object {
goal_ref m_goal; goal_ref m_goal;

View file

@ -17,27 +17,27 @@
--*/ --*/
#include<sstream> #include<sstream>
#include<vector> #include<vector>
#include"z3.h" #include "api/z3.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_context.h" #include "api/api_context.h"
#include"api_tactic.h" #include "api/api_tactic.h"
#include"api_solver.h" #include "api/api_solver.h"
#include"api_model.h" #include "api/api_model.h"
#include"api_stats.h" #include "api/api_stats.h"
#include"api_ast_vector.h" #include "api/api_ast_vector.h"
#include"tactic2solver.h" #include "solver/tactic2solver.h"
#include"scoped_ctrl_c.h" #include "util/scoped_ctrl_c.h"
#include"cancel_eh.h" #include "util/cancel_eh.h"
#include"scoped_timer.h" #include "util/scoped_timer.h"
#include"smt_strategic_solver.h" #include "tactic/portfolio/smt_strategic_solver.h"
#include"smt_solver.h" #include "smt/smt_solver.h"
#include"smt_implied_equalities.h" #include "smt/smt_implied_equalities.h"
#include"iz3interp.h" #include "interp/iz3interp.h"
#include"iz3profiling.h" #include "interp/iz3profiling.h"
#include"iz3hash.h" #include "interp/iz3hash.h"
#include"iz3pp.h" #include "interp/iz3pp.h"
#include"iz3checker.h" #include "interp/iz3checker.h"
#include"scoped_proof.h" #include "ast/scoped_proof.h"
using namespace stl_ext; using namespace stl_ext;
@ -249,7 +249,7 @@ extern "C" {
params_ref _p; params_ref _p;
_p.set_bool("proof", true); // this is currently useless _p.set_bool("proof", true); // this is currently useless
scoped_proof_mode spm(mk_c(c)->m(), PGM_FINE); scoped_proof_mode spm(mk_c(c)->m(), PGM_ENABLED);
scoped_ptr<solver_factory> sf = mk_smt_solver_factory(); scoped_ptr<solver_factory> sf = mk_smt_solver_factory();
scoped_ptr<solver> m_solver((*sf)(mk_c(c)->m(), _p, true, true, true, ::symbol::null)); scoped_ptr<solver> m_solver((*sf)(mk_c(c)->m(), _p, true, true, true, ::symbol::null));
m_solver.get()->updt_params(_p); // why do we have to do this? m_solver.get()->updt_params(_p); // why do we have to do this?

View file

@ -16,10 +16,10 @@ Revision History:
--*/ --*/
#include<fstream> #include<fstream>
#include"z3.h" #include "api/z3.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"util.h" #include "util/util.h"
#include"version.h" #include "util/version.h"
std::ostream * g_z3_log = 0; std::ostream * g_z3_log = 0;
bool g_z3_log_enabled = false; bool g_z3_log_enabled = false;

View file

@ -16,20 +16,31 @@ Revision History:
--*/ --*/
#include<iostream> #include<iostream>
#include"z3.h" #include "api/z3.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_context.h" #include "api/api_context.h"
#include"api_model.h" #include "api/api_model.h"
#include"api_ast_vector.h" #include "api/api_ast_vector.h"
#include"array_decl_plugin.h" #include "ast/array_decl_plugin.h"
#include"model.h" #include "model/model.h"
#include"model_v2_pp.h" #include "model/model_v2_pp.h"
#include"model_smt2_pp.h" #include "model/model_smt2_pp.h"
#include"model_params.hpp" #include "model/model_params.hpp"
#include"model_evaluator_params.hpp" #include "model/model_evaluator_params.hpp"
extern "C" { extern "C" {
Z3_model Z3_API Z3_mk_model(Z3_context c) {
Z3_TRY;
LOG_Z3_mk_model(c);
RESET_ERROR_CODE();
Z3_model_ref * m_ref = alloc(Z3_model_ref, *mk_c(c));
m_ref->m_model = alloc(model, mk_c(c)->m());
mk_c(c)->save_object(m_ref);
RETURN_Z3(of_model(m_ref));
Z3_CATCH_RETURN(0);
}
void Z3_API Z3_model_inc_ref(Z3_context c, Z3_model m) { void Z3_API Z3_model_inc_ref(Z3_context c, Z3_model m) {
Z3_TRY; Z3_TRY;
LOG_Z3_model_inc_ref(c, m); LOG_Z3_model_inc_ref(c, m);
@ -224,6 +235,36 @@ extern "C" {
Z3_CATCH_RETURN(0); Z3_CATCH_RETURN(0);
} }
Z3_func_interp Z3_API Z3_add_func_interp(Z3_context c, Z3_model m, Z3_func_decl f, Z3_ast else_val) {
Z3_TRY;
LOG_Z3_add_func_interp(c, m, f, else_val);
RESET_ERROR_CODE();
func_decl* d = to_func_decl(f);
model* mdl = to_model_ref(m);
Z3_func_interp_ref * f_ref = alloc(Z3_func_interp_ref, *mk_c(c), mdl);
f_ref->m_func_interp = alloc(func_interp, mk_c(c)->m(), d->get_arity());
mk_c(c)->save_object(f_ref);
mdl->register_decl(d, f_ref->m_func_interp);
f_ref->m_func_interp->set_else(to_expr(else_val));
RETURN_Z3(of_func_interp(f_ref));
Z3_CATCH_RETURN(0);
}
void Z3_API Z3_add_const_interp(Z3_context c, Z3_model m, Z3_func_decl f, Z3_ast a) {
Z3_TRY;
LOG_Z3_add_const_interp(c, m, f, a);
RESET_ERROR_CODE();
func_decl* d = to_func_decl(f);
if (d->get_arity() != 0) {
SET_ERROR_CODE(Z3_INVALID_ARG);
}
else {
model* mdl = to_model_ref(m);
mdl->register_decl(d, to_expr(a));
}
Z3_CATCH;
}
void Z3_API Z3_func_interp_inc_ref(Z3_context c, Z3_func_interp f) { void Z3_API Z3_func_interp_inc_ref(Z3_context c, Z3_func_interp f) {
Z3_TRY; Z3_TRY;
LOG_Z3_func_interp_inc_ref(c, f); LOG_Z3_func_interp_inc_ref(c, f);
@ -283,6 +324,15 @@ extern "C" {
Z3_CATCH_RETURN(0); Z3_CATCH_RETURN(0);
} }
void Z3_API Z3_func_interp_set_else(Z3_context c, Z3_func_interp f, Z3_ast else_value) {
Z3_TRY;
LOG_Z3_func_interp_set_else(c, f, else_value);
RESET_ERROR_CODE();
// CHECK_NON_NULL(f, 0);
to_func_interp_ref(f)->set_else(to_expr(else_value));
Z3_CATCH;
}
unsigned Z3_API Z3_func_interp_get_arity(Z3_context c, Z3_func_interp f) { unsigned Z3_API Z3_func_interp_get_arity(Z3_context c, Z3_func_interp f) {
Z3_TRY; Z3_TRY;
LOG_Z3_func_interp_get_arity(c, f); LOG_Z3_func_interp_get_arity(c, f);
@ -292,6 +342,24 @@ extern "C" {
Z3_CATCH_RETURN(0); Z3_CATCH_RETURN(0);
} }
void Z3_API Z3_func_interp_add_entry(Z3_context c, Z3_func_interp fi, Z3_ast_vector args, Z3_ast value) {
Z3_TRY;
LOG_Z3_func_interp_add_entry(c, fi, args, value);
//CHECK_NON_NULL(fi, void);
//CHECK_NON_NULL(args, void);
//CHECK_NON_NULL(value, void);
func_interp* _fi = to_func_interp_ref(fi);
expr* _value = to_expr(value);
if (to_ast_vector_ref(args).size() != _fi->get_arity()) {
SET_ERROR_CODE(Z3_IOB);
return;
}
// check sorts of value
expr* const* _args = (expr* const*) to_ast_vector_ref(args).c_ptr();
_fi->insert_entry(_args, _value);
Z3_CATCH;
}
void Z3_API Z3_func_entry_inc_ref(Z3_context c, Z3_func_entry e) { void Z3_API Z3_func_entry_inc_ref(Z3_context c, Z3_func_entry e) {
Z3_TRY; Z3_TRY;
LOG_Z3_func_entry_inc_ref(c, e); LOG_Z3_func_entry_inc_ref(c, e);

View file

@ -18,8 +18,8 @@ Revision History:
#ifndef API_MODEL_H_ #ifndef API_MODEL_H_
#define API_MODEL_H_ #define API_MODEL_H_
#include"api_util.h" #include "api/api_util.h"
#include"model.h" #include "model/model.h"
struct Z3_model_ref : public api::object { struct Z3_model_ref : public api::object {
model_ref m_model; model_ref m_model;

View file

@ -16,14 +16,14 @@ Revision History:
--*/ --*/
#include<iostream> #include<iostream>
#include"z3.h" #include "api/z3.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_context.h" #include "api/api_context.h"
#include"api_util.h" #include "api/api_util.h"
#include"arith_decl_plugin.h" #include "ast/arith_decl_plugin.h"
#include"bv_decl_plugin.h" #include "ast/bv_decl_plugin.h"
#include"algebraic_numbers.h" #include "math/polynomial/algebraic_numbers.h"
#include"fpa_decl_plugin.h" #include "ast/fpa_decl_plugin.h"
bool is_numeral_sort(Z3_context c, Z3_sort ty) { bool is_numeral_sort(Z3_context c, Z3_sort ty) {
sort * _ty = to_sort(ty); sort * _ty = to_sort(ty);

View file

@ -16,18 +16,18 @@ Revision History:
--*/ --*/
#include<iostream> #include<iostream>
#include"z3.h" #include "api/z3.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_stats.h" #include "api/api_stats.h"
#include"api_context.h" #include "api/api_context.h"
#include"api_util.h" #include "api/api_util.h"
#include"api_model.h" #include "api/api_model.h"
#include"opt_context.h" #include "opt/opt_context.h"
#include"opt_cmds.h" #include "opt/opt_cmds.h"
#include"cancel_eh.h" #include "util/cancel_eh.h"
#include"scoped_timer.h" #include "util/scoped_timer.h"
#include"smt2parser.h" #include "parsers/smt2/smt2parser.h"
#include"api_ast_vector.h" #include "api/api_ast_vector.h"
extern "C" { extern "C" {
@ -283,15 +283,16 @@ extern "C" {
Z3_optimize opt, Z3_optimize opt,
std::istream& s) { std::istream& s) {
ast_manager& m = mk_c(c)->m(); ast_manager& m = mk_c(c)->m();
cmd_context ctx(false, &m); scoped_ptr<cmd_context> ctx = alloc(cmd_context, false, &m);
install_opt_cmds(ctx, to_optimize_ptr(opt)); install_opt_cmds(*ctx.get(), to_optimize_ptr(opt));
ctx.set_ignore_check(true); ctx->set_ignore_check(true);
if (!parse_smt2_commands(ctx, s)) { if (!parse_smt2_commands(*ctx.get(), s)) {
ctx = nullptr;
SET_ERROR_CODE(Z3_PARSER_ERROR); SET_ERROR_CODE(Z3_PARSER_ERROR);
return; return;
} }
ptr_vector<expr>::const_iterator it = ctx.begin_assertions(); ptr_vector<expr>::const_iterator it = ctx->begin_assertions();
ptr_vector<expr>::const_iterator end = ctx.end_assertions(); ptr_vector<expr>::const_iterator end = ctx->end_assertions();
for (; it != end; ++it) { for (; it != end; ++it) {
to_optimize_ptr(opt)->add_hard_constraint(*it); to_optimize_ptr(opt)->add_hard_constraint(*it);
} }
@ -320,9 +321,6 @@ extern "C" {
std::ostringstream strm; std::ostringstream strm;
strm << "Could not open file " << s; strm << "Could not open file " << s;
throw default_exception(strm.str()); throw default_exception(strm.str());
SET_ERROR_CODE(Z3_PARSER_ERROR);
return;
} }
Z3_optimize_from_stream(c, d, is); Z3_optimize_from_stream(c, d, is);
Z3_CATCH; Z3_CATCH;

View file

@ -18,11 +18,11 @@ Revision History:
--*/ --*/
#include<iostream> #include<iostream>
#include"z3.h" #include "api/z3.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_context.h" #include "api/api_context.h"
#include"api_util.h" #include "api/api_util.h"
#include"params.h" #include "util/params.h"
extern "C" { extern "C" {

View file

@ -16,14 +16,14 @@ Revision History:
--*/ --*/
#include<iostream> #include<iostream>
#include"z3.h" #include "api/z3.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_context.h" #include "api/api_context.h"
#include"api_util.h" #include "api/api_util.h"
#include"cmd_context.h" #include "cmd_context/cmd_context.h"
#include"smt2parser.h" #include "parsers/smt2/smt2parser.h"
#include"smtparser.h" #include "parsers/smt/smtparser.h"
#include"solver_na2as.h" #include "solver/solver_na2as.h"
extern "C" { extern "C" {
@ -56,19 +56,20 @@ extern "C" {
Z3_func_decl const decls[]) { Z3_func_decl const decls[]) {
Z3_TRY; Z3_TRY;
LOG_Z3_parse_smtlib_string(c, str, num_sorts, sort_names, sorts, num_decls, decl_names, decls); LOG_Z3_parse_smtlib_string(c, str, num_sorts, sort_names, sorts, num_decls, decl_names, decls);
std::ostringstream outs; scoped_ptr<std::ostringstream> outs = alloc(std::ostringstream);
bool ok = false; bool ok = false;
RESET_ERROR_CODE(); RESET_ERROR_CODE();
init_smtlib_parser(c, num_sorts, sort_names, sorts, num_decls, decl_names, decls); init_smtlib_parser(c, num_sorts, sort_names, sorts, num_decls, decl_names, decls);
mk_c(c)->m_smtlib_parser->set_error_stream(outs); mk_c(c)->m_smtlib_parser->set_error_stream(*outs);
try { try {
ok = mk_c(c)->m_smtlib_parser->parse_string(str); ok = mk_c(c)->m_smtlib_parser->parse_string(str);
} }
catch (...) { catch (...) {
ok = false; ok = false;
} }
mk_c(c)->m_smtlib_error_buffer = outs.str(); mk_c(c)->m_smtlib_error_buffer = outs->str();
outs = nullptr;
if (!ok) { if (!ok) {
mk_c(c)->reset_parser(); mk_c(c)->reset_parser();
SET_ERROR_CODE(Z3_PARSER_ERROR); SET_ERROR_CODE(Z3_PARSER_ERROR);
@ -88,16 +89,17 @@ extern "C" {
LOG_Z3_parse_smtlib_file(c, file_name, num_sorts, sort_names, types, num_decls, decl_names, decls); LOG_Z3_parse_smtlib_file(c, file_name, num_sorts, sort_names, types, num_decls, decl_names, decls);
bool ok = false; bool ok = false;
RESET_ERROR_CODE(); RESET_ERROR_CODE();
std::ostringstream outs; scoped_ptr<std::ostringstream> outs = alloc(std::ostringstream);
init_smtlib_parser(c, num_sorts, sort_names, types, num_decls, decl_names, decls); init_smtlib_parser(c, num_sorts, sort_names, types, num_decls, decl_names, decls);
mk_c(c)->m_smtlib_parser->set_error_stream(outs); mk_c(c)->m_smtlib_parser->set_error_stream(*outs);
try { try {
ok = mk_c(c)->m_smtlib_parser->parse_file(file_name); ok = mk_c(c)->m_smtlib_parser->parse_file(file_name);
} }
catch(...) { catch(...) {
ok = false; ok = false;
} }
mk_c(c)->m_smtlib_error_buffer = outs.str(); mk_c(c)->m_smtlib_error_buffer = outs->str();
outs = nullptr;
if (!ok) { if (!ok) {
mk_c(c)->reset_parser(); mk_c(c)->reset_parser();
SET_ERROR_CODE(Z3_PARSER_ERROR); SET_ERROR_CODE(Z3_PARSER_ERROR);
@ -260,21 +262,22 @@ extern "C" {
Z3_symbol const decl_names[], Z3_symbol const decl_names[],
Z3_func_decl const decls[]) { Z3_func_decl const decls[]) {
Z3_TRY; Z3_TRY;
cmd_context ctx(false, &(mk_c(c)->m())); scoped_ptr<cmd_context> ctx = alloc(cmd_context, false, &(mk_c(c)->m()));
ctx.set_ignore_check(true); ctx->set_ignore_check(true);
for (unsigned i = 0; i < num_decls; ++i) { for (unsigned i = 0; i < num_decls; ++i) {
ctx.insert(to_symbol(decl_names[i]), to_func_decl(decls[i])); ctx->insert(to_symbol(decl_names[i]), to_func_decl(decls[i]));
} }
for (unsigned i = 0; i < num_sorts; ++i) { for (unsigned i = 0; i < num_sorts; ++i) {
psort* ps = ctx.pm().mk_psort_cnst(to_sort(sorts[i])); psort* ps = ctx->pm().mk_psort_cnst(to_sort(sorts[i]));
ctx.insert(ctx.pm().mk_psort_user_decl(0, to_symbol(sort_names[i]), ps)); ctx->insert(ctx->pm().mk_psort_user_decl(0, to_symbol(sort_names[i]), ps));
} }
if (!parse_smt2_commands(ctx, is)) { if (!parse_smt2_commands(*ctx.get(), is)) {
ctx = nullptr;
SET_ERROR_CODE(Z3_PARSER_ERROR); SET_ERROR_CODE(Z3_PARSER_ERROR);
return of_ast(mk_c(c)->m().mk_true()); return of_ast(mk_c(c)->m().mk_true());
} }
ptr_vector<expr>::const_iterator it = ctx.begin_assertions(); ptr_vector<expr>::const_iterator it = ctx->begin_assertions();
ptr_vector<expr>::const_iterator end = ctx.end_assertions(); ptr_vector<expr>::const_iterator end = ctx->end_assertions();
unsigned size = static_cast<unsigned>(end - it); unsigned size = static_cast<unsigned>(end - it);
return of_ast(mk_c(c)->mk_and(size, it)); return of_ast(mk_c(c)->mk_and(size, it));
Z3_CATCH_RETURN(0); Z3_CATCH_RETURN(0);

View file

@ -15,11 +15,11 @@ Author:
Revision History: Revision History:
--*/ --*/
#include"z3.h" #include "api/z3.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_context.h" #include "api/api_context.h"
#include"api_util.h" #include "api/api_util.h"
#include"pb_decl_plugin.h" #include "ast/pb_decl_plugin.h"
extern "C" { extern "C" {

View file

@ -16,15 +16,15 @@ Author:
Notes: Notes:
--*/ --*/
#include"z3.h" #include "api/z3.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_context.h" #include "api/api_context.h"
#include"api_polynomial.h" #include "api/api_polynomial.h"
#include"api_ast_vector.h" #include "api/api_ast_vector.h"
#include"expr2polynomial.h" #include "ast/expr2polynomial.h"
#include"cancel_eh.h" #include "util/cancel_eh.h"
#include"scoped_timer.h" #include "util/scoped_timer.h"
#include"expr2var.h" #include "ast/expr2var.h"
namespace api { namespace api {

View file

@ -19,7 +19,7 @@ Notes:
#ifndef API_POLYNOMIAL_H_ #ifndef API_POLYNOMIAL_H_
#define API_POLYNOMIAL_H_ #define API_POLYNOMIAL_H_
#include"polynomial.h" #include "math/polynomial/polynomial.h"
namespace api { namespace api {

173
src/api/api_qe.cpp Normal file
View file

@ -0,0 +1,173 @@
/*++
Copyright (c) 2017 Arie Gurfinkel
Module Name:
api_qe.cpp
Abstract:
Model-based Projection (MBP) and Quantifier Elimination (QE) API
Author:
Arie Gurfinkel (arie)
Notes:
--*/
#include <iostream>
#include "api/z3.h"
#include "api/api_log_macros.h"
#include "api/api_context.h"
#include "api/api_util.h"
#include "api/api_model.h"
#include "api/api_ast_map.h"
#include "api/api_ast_vector.h"
#include "qe/qe_vartest.h"
#include "qe/qe_lite.h"
#include "muz/spacer/spacer_util.h"
#include "ast/expr_map.h"
extern "C"
{
static bool to_apps(unsigned n, Z3_app const es[], app_ref_vector& result) {
for (unsigned i = 0; i < n; ++i) {
if (!is_app(to_app(es[i]))) {
return false;
}
result.push_back (to_app (es [i]));
}
return true;
}
Z3_ast Z3_API Z3_qe_model_project (Z3_context c,
Z3_model m,
unsigned num_bounds,
Z3_app const bound[],
Z3_ast body)
{
Z3_TRY;
LOG_Z3_qe_model_project (c, m, num_bounds, bound, body);
RESET_ERROR_CODE();
app_ref_vector vars(mk_c(c)->m ());
if (!to_apps(num_bounds, bound, vars)) {
SET_ERROR_CODE (Z3_INVALID_ARG);
RETURN_Z3(0);
}
expr_ref result (mk_c(c)->m ());
result = to_expr (body);
model_ref model (to_model_ref (m));
spacer::qe_project (mk_c(c)->m (), vars, result, model);
mk_c(c)->save_ast_trail (result.get ());
return of_expr (result.get ());
Z3_CATCH_RETURN(0);
}
Z3_ast Z3_API Z3_qe_model_project_skolem (Z3_context c,
Z3_model m,
unsigned num_bounds,
Z3_app const bound[],
Z3_ast body,
Z3_ast_map map)
{
Z3_TRY;
LOG_Z3_qe_model_project_skolem (c, m, num_bounds, bound, body, map);
RESET_ERROR_CODE();
ast_manager& man = mk_c(c)->m ();
app_ref_vector vars(man);
if (!to_apps(num_bounds, bound, vars)) {
RETURN_Z3(0);
}
expr_ref result (mk_c(c)->m ());
result = to_expr (body);
model_ref model (to_model_ref (m));
expr_map emap (man);
spacer::qe_project (mk_c(c)->m (), vars, result, model, emap);
mk_c(c)->save_ast_trail (result.get ());
obj_map<ast, ast*> &map_z3 = to_ast_map_ref(map);
for (expr_map::iterator it = emap.begin(), end = emap.end(); it != end; ++it){
man.inc_ref(&(it->get_key()));
man.inc_ref(it->get_value());
map_z3.insert(&(it->get_key()), it->get_value());
}
return of_expr (result.get ());
Z3_CATCH_RETURN(0);
}
Z3_ast Z3_API Z3_model_extrapolate (Z3_context c,
Z3_model m,
Z3_ast fml)
{
Z3_TRY;
LOG_Z3_model_extrapolate (c, m, fml);
RESET_ERROR_CODE();
model_ref model (to_model_ref (m));
expr_ref_vector facts (mk_c(c)->m ());
facts.push_back (to_expr (fml));
flatten_and (facts);
spacer::model_evaluator_util mev (mk_c(c)->m());
mev.set_model (*model);
expr_ref_vector lits (mk_c(c)->m());
spacer::compute_implicant_literals (mev, facts, lits);
expr_ref result (mk_c(c)->m ());
result = mk_and (lits);
mk_c(c)->save_ast_trail (result.get ());
return of_expr (result.get ());
Z3_CATCH_RETURN(0);
}
Z3_ast Z3_API Z3_qe_lite (Z3_context c, Z3_ast_vector vars, Z3_ast body)
{
Z3_TRY;
LOG_Z3_qe_lite (c, vars, body);
RESET_ERROR_CODE();
ast_ref_vector &vVars = to_ast_vector_ref (vars);
app_ref_vector vApps (mk_c(c)->m());
for (unsigned i = 0; i < vVars.size (); ++i) {
app *a = to_app (vVars.get (i));
if (a->get_kind () != AST_APP) {
SET_ERROR_CODE (Z3_INVALID_ARG);
RETURN_Z3(0);
}
vApps.push_back (a);
}
expr_ref result (mk_c(c)->m ());
result = to_expr (body);
params_ref p;
qe_lite qe (mk_c(c)->m (), p);
qe (vApps, result);
// -- copy back variables that were not eliminated
if (vApps.size () < vVars.size ()) {
vVars.reset ();
for (app* v : vApps) {
vVars.push_back (v);
}
}
mk_c(c)->save_ast_trail (result.get ());
return of_expr (result);
Z3_CATCH_RETURN(0);
}
}

View file

@ -15,12 +15,12 @@ Author:
Revision History: Revision History:
--*/ --*/
#include"z3.h" #include "api/z3.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_context.h" #include "api/api_context.h"
#include"api_util.h" #include "api/api_util.h"
#include"pattern_validation.h" #include "parsers/util/pattern_validation.h"
#include"expr_abstract.h" #include "ast/expr_abstract.h"
extern "C" { extern "C" {
@ -63,9 +63,11 @@ extern "C" {
RESET_ERROR_CODE(); RESET_ERROR_CODE();
if (!mk_c(c)->m().is_bool(to_expr(body))) { if (!mk_c(c)->m().is_bool(to_expr(body))) {
SET_ERROR_CODE(Z3_SORT_ERROR); SET_ERROR_CODE(Z3_SORT_ERROR);
return nullptr;
} }
if (num_patterns > 0 && num_no_patterns > 0) { if (num_patterns > 0 && num_no_patterns > 0) {
SET_ERROR_CODE(Z3_INVALID_USAGE); SET_ERROR_CODE(Z3_INVALID_USAGE);
return nullptr;
} }
expr * const* ps = reinterpret_cast<expr * const*>(patterns); expr * const* ps = reinterpret_cast<expr * const*>(patterns);
expr * const* no_ps = reinterpret_cast<expr * const*>(no_patterns); expr * const* no_ps = reinterpret_cast<expr * const*>(no_patterns);
@ -76,7 +78,7 @@ extern "C" {
for (unsigned i = 0; i < num_patterns; i++) { for (unsigned i = 0; i < num_patterns; i++) {
if (!v(num_decls, ps[i], 0, 0)) { if (!v(num_decls, ps[i], 0, 0)) {
SET_ERROR_CODE(Z3_INVALID_PATTERN); SET_ERROR_CODE(Z3_INVALID_PATTERN);
return 0; return nullptr;
} }
} }
} }

View file

@ -20,10 +20,10 @@ Notes:
--*/ --*/
#include<iostream> #include<iostream>
#include"z3.h" #include "api/z3.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_context.h" #include "api/api_context.h"
#include"realclosure.h" #include "math/realclosure/realclosure.h"
static rcmanager & rcfm(Z3_context c) { static rcmanager & rcfm(Z3_context c) {
return mk_c(c)->rcfm(); return mk_c(c)->rcfm();

View file

@ -16,11 +16,11 @@ Author:
Revision History: Revision History:
--*/ --*/
#include"z3.h" #include "api/z3.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_context.h" #include "api/api_context.h"
#include"api_util.h" #include "api/api_util.h"
#include"ast_pp.h" #include "ast/ast_pp.h"
extern "C" { extern "C" {

View file

@ -17,22 +17,22 @@ Revision History:
--*/ --*/
#include<iostream> #include<iostream>
#include"z3.h" #include "api/z3.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_context.h" #include "api/api_context.h"
#include"api_tactic.h" #include "api/api_tactic.h"
#include"api_solver.h" #include "api/api_solver.h"
#include"api_model.h" #include "api/api_model.h"
#include"api_stats.h" #include "api/api_stats.h"
#include"api_ast_vector.h" #include "api/api_ast_vector.h"
#include"tactic2solver.h" #include "solver/tactic2solver.h"
#include"scoped_ctrl_c.h" #include "util/scoped_ctrl_c.h"
#include"cancel_eh.h" #include "util/cancel_eh.h"
#include"scoped_timer.h" #include "util/scoped_timer.h"
#include"smt_strategic_solver.h" #include "tactic/portfolio/smt_strategic_solver.h"
#include"smt_solver.h" #include "smt/smt_solver.h"
#include"smt_implied_equalities.h" #include "smt/smt_implied_equalities.h"
#include"smt_logics.h" #include "solver/smt_logics.h"
extern "C" { extern "C" {
@ -296,10 +296,14 @@ extern "C" {
result = to_solver_ref(s)->check_sat(num_assumptions, _assumptions); result = to_solver_ref(s)->check_sat(num_assumptions, _assumptions);
} }
catch (z3_exception & ex) { catch (z3_exception & ex) {
to_solver_ref(s)->set_reason_unknown(eh);
mk_c(c)->handle_exception(ex); mk_c(c)->handle_exception(ex);
return Z3_L_UNDEF; return Z3_L_UNDEF;
} }
} }
if (result == l_undef) {
to_solver_ref(s)->set_reason_unknown(eh);
}
return static_cast<Z3_lbool>(result); return static_cast<Z3_lbool>(result);
} }
@ -438,6 +442,7 @@ extern "C" {
unsigned sz = __assumptions.size(); unsigned sz = __assumptions.size();
for (unsigned i = 0; i < sz; ++i) { for (unsigned i = 0; i < sz; ++i) {
if (!is_expr(__assumptions[i])) { if (!is_expr(__assumptions[i])) {
_assumptions.finalize(); _consequences.finalize(); _variables.finalize();
SET_ERROR_CODE(Z3_INVALID_USAGE); SET_ERROR_CODE(Z3_INVALID_USAGE);
return Z3_L_UNDEF; return Z3_L_UNDEF;
} }
@ -447,6 +452,7 @@ extern "C" {
sz = __variables.size(); sz = __variables.size();
for (unsigned i = 0; i < sz; ++i) { for (unsigned i = 0; i < sz; ++i) {
if (!is_expr(__variables[i])) { if (!is_expr(__variables[i])) {
_assumptions.finalize(); _consequences.finalize(); _variables.finalize();
SET_ERROR_CODE(Z3_INVALID_USAGE); SET_ERROR_CODE(Z3_INVALID_USAGE);
return Z3_L_UNDEF; return Z3_L_UNDEF;
} }
@ -466,10 +472,15 @@ extern "C" {
result = to_solver_ref(s)->get_consequences(_assumptions, _variables, _consequences); result = to_solver_ref(s)->get_consequences(_assumptions, _variables, _consequences);
} }
catch (z3_exception & ex) { catch (z3_exception & ex) {
to_solver_ref(s)->set_reason_unknown(eh);
_assumptions.finalize(); _consequences.finalize(); _variables.finalize();
mk_c(c)->handle_exception(ex); mk_c(c)->handle_exception(ex);
return Z3_L_UNDEF; return Z3_L_UNDEF;
} }
} }
if (result == l_undef) {
to_solver_ref(s)->set_reason_unknown(eh);
}
for (unsigned i = 0; i < _consequences.size(); ++i) { for (unsigned i = 0; i < _consequences.size(); ++i) {
to_ast_vector_ref(consequences).push_back(_consequences[i].get()); to_ast_vector_ref(consequences).push_back(_consequences[i].get());
} }

View file

@ -18,8 +18,8 @@ Revision History:
#ifndef API_SOLVER_H_ #ifndef API_SOLVER_H_
#define API_SOLVER_H_ #define API_SOLVER_H_
#include"api_util.h" #include "api/api_util.h"
#include"solver.h" #include "solver/solver.h"
struct Z3_solver_ref : public api::object { struct Z3_solver_ref : public api::object {
scoped_ptr<solver_factory> m_solver_factory; scoped_ptr<solver_factory> m_solver_factory;

View file

@ -16,10 +16,10 @@ Revision History:
--*/ --*/
#include<iostream> #include<iostream>
#include"z3.h" #include "api/z3.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_context.h" #include "api/api_context.h"
#include"api_stats.h" #include "api/api_stats.h"
extern "C" { extern "C" {

View file

@ -18,8 +18,8 @@ Revision History:
#ifndef API_STATS_H_ #ifndef API_STATS_H_
#define API_STATS_H_ #define API_STATS_H_
#include"api_util.h" #include "api/api_util.h"
#include"statistics.h" #include "util/statistics.h"
struct Z3_stats_ref : public api::object { struct Z3_stats_ref : public api::object {
statistics m_stats; statistics m_stats;

View file

@ -16,14 +16,14 @@ Revision History:
--*/ --*/
#include<iostream> #include<iostream>
#include"z3.h" #include "api/z3.h"
#include"api_log_macros.h" #include "api/api_log_macros.h"
#include"api_context.h" #include "api/api_context.h"
#include"api_tactic.h" #include "api/api_tactic.h"
#include"api_model.h" #include "api/api_model.h"
#include"scoped_ctrl_c.h" #include "util/scoped_ctrl_c.h"
#include"cancel_eh.h" #include "util/cancel_eh.h"
#include"scoped_timer.h" #include "util/scoped_timer.h"
Z3_apply_result_ref::Z3_apply_result_ref(api::context& c, ast_manager & m): api::object(c), m_core(m) { Z3_apply_result_ref::Z3_apply_result_ref(api::context& c, ast_manager & m): api::object(c), m_core(m) {
} }

View file

@ -18,8 +18,8 @@ Revision History:
#ifndef API_TACTIC_H_ #ifndef API_TACTIC_H_
#define API_TACTIC_H_ #define API_TACTIC_H_
#include"api_goal.h" #include "api/api_goal.h"
#include"tactical.h" #include "tactic/tactical.h"
namespace api { namespace api {
class context; class context;

View file

@ -18,9 +18,9 @@ Revision History:
#ifndef API_UTIL_H_ #ifndef API_UTIL_H_
#define API_UTIL_H_ #define API_UTIL_H_
#include"params.h" #include "util/params.h"
#include"lbool.h" #include "util/lbool.h"
#include"ast.h" #include "ast/ast.h"
#define Z3_TRY try { #define Z3_TRY try {
#define Z3_CATCH_CORE(CODE) } catch (z3_exception & ex) { mk_c(c)->handle_exception(ex); CODE } #define Z3_CATCH_CORE(CODE) } catch (z3_exception & ex) { mk_c(c)->handle_exception(ex); CODE }

Some files were not shown because too many files have changed in this diff Show more