3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-05 17:14:07 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2017-07-27 17:02:27 -07:00
commit b482dbd589
379 changed files with 7440 additions and 3352 deletions

4
.dockerignore Normal file
View file

@ -0,0 +1,4 @@
**/*.swp
**/*.pyc
.git
**/*.Dockerfile

11
.gitignore vendored
View file

@ -75,14 +75,3 @@ src/api/ml/z3.mllib
*.bak
doc/api
doc/code
# CMake files copied over by the ``contrib/cmake/boostrap.py`` script
# See #461
examples/CMakeLists.txt
examples/*/CMakeLists.txt
src/CMakeLists.txt
src/*/CMakeLists.txt
src/*/*/CMakeLists.txt
src/*/*/*/CMakeLists.txt
src/api/dotnet/cmake_install_gac.cmake.in
src/api/dotnet/cmake_uninstall_gac.cmake.in

68
.travis.yml Normal file
View file

@ -0,0 +1,68 @@
cache:
# This persistent cache is used to cache the building of
# docker base images.
directories:
- $DOCKER_TRAVIS_CI_CACHE_DIR
sudo: required
language: cpp
services:
- docker
env:
global:
# This environment variable tells the `travis_ci_linux_entry_point.sh`
# script to look for a cached Docker image.
- DOCKER_TRAVIS_CI_CACHE_DIR=$HOME/.cache/docker
# Configurations
matrix:
###############################################################################
# Ubuntu 16.04 LTS
###############################################################################
# 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
# 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
# 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
# 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
# 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
# Both of the two configurations below build the docs because the current
# implementation uses python as part of the building process.
# TODO: Teach one of the configurations to upload built docs somewhere.
# Test with Python 3 and API docs
- LINUX_BASE=ubuntu_16.04 PYTHON_EXECUTABLE=/usr/bin/python3 BUILD_DOCS=1
# Test with LibGMP and API docs
- LINUX_BASE=ubuntu_16.04 TARGET_ARCH=x86_64 USE_LIBGMP=1 BUILD_DOCS=1 PYTHON_EXECUTABLE=/usr/bin/python2.7
# Test without OpenMP
- 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 USE_OPENMP=0
# Unix Makefile generator build
- LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/gcc-5 CXX_COMPILER=/usr/bin/g++-5 TARGET_ARCH=x86_64 Z3_CMAKE_GENERATOR="Unix Makefiles"
# LTO build
- LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/gcc-5 CXX_COMPILER=/usr/bin/g++-5 TARGET_ARCH=x86_64 USE_LTO=1
# Static build. Note we have disable building the bindings because they won't work with a static libz3
- LINUX_BASE=ubuntu_16.04 C_COMPILER=/usr/bin/gcc-5 CXX_COMPILER=/usr/bin/g++-5 TARGET_ARCH=x86_64 Z3_STATIC_BUILD=1 DOTNET_BINDINGS=0 JAVA_BINDINGS=0 PYTHON_BINDINGS=0
###############################################################################
# Ubuntu 14.04 LTS
###############################################################################
# GCC 4.8
# 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
# 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
# TODO: OSX support
#matrix:
# include:
# - os: osx
# osx_image: xcode 8.2
script:
- contrib/ci/scripts/travis_ci_entry_point.sh

View file

@ -14,19 +14,21 @@ if (POLICY CMP0054)
cmake_policy(SET CMP0054 OLD)
endif()
# Provide a friendly message if the user hasn't run the bootstrap script
# to copy all the CMake files into their correct location.
# It is unfortunate that we have to do this, see #461 for the discussion
# on this.
if (NOT (EXISTS "${CMAKE_SOURCE_DIR}/src/CMakeLists.txt"))
message(FATAL_ERROR "Cannot find \"${CMAKE_SOURCE_DIR}/src/CMakeLists.txt\""
". This probably means you need to run"
"``python contrib/cmake/bootstrap.py create``")
if (POLICY CMP0042)
# Enable `MACOSX_RPATH` by default.
cmake_policy(SET CMP0042 NEW)
endif()
set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cxx_compiler_flags_overrides.cmake")
project(Z3 CXX)
if ("${CMAKE_VERSION}" VERSION_LESS "3.4")
# FIXME: Drop this when we upgrade to newer CMake versions.
# HACK: Although we don't need C language support if it is not
# enabled CMake's `FindThreads` module fails in old CMake versions.
enable_language(C)
endif()
################################################################################
# Project version
################################################################################
@ -108,7 +110,7 @@ if (EXISTS "${GIT_DIR}")
endif()
message(STATUS "Using Git hash in version output: ${Z3GITHASH}")
# This mimics the behaviour of the old build system.
string(APPEND Z3_FULL_VERSION_STR " ${Z3GITHASH}")
set(Z3_FULL_VERSION_STR "${Z3_FULL_VERSION_STR} ${Z3GITHASH}")
else()
message(STATUS "Not using Git hash in version output")
unset(Z3GITHASH) # Used in configure_file()
@ -121,7 +123,7 @@ if (EXISTS "${GIT_DIR}")
endif()
message(STATUS "Using Git description in version output: ${Z3_GIT_DESCRIPTION}")
# This mimics the behaviour of the old build system.
string(APPEND Z3_FULL_VERSION_STR " ${Z3_GIT_DESCRIPTION}")
set(Z3_FULL_VERSION_STR "${Z3_FULL_VERSION_STR} ${Z3_GIT_DESCRIPTION}")
else()
message(STATUS "Not including git descrption in version")
endif()
@ -523,10 +525,18 @@ add_subdirectory(src)
# use Z3 via CMake.
################################################################################
include(CMakePackageConfigHelpers)
export(EXPORT Z3_EXPORTED_TARGETS
NAMESPACE z3::
FILE "${CMAKE_BINARY_DIR}/Z3Targets.cmake"
)
if ("${CMAKE_VERSION}" VERSION_LESS "3.0")
# FIXME: Remove this once we drop support for CMake 2.8.12
export(TARGETS libz3
NAMESPACE z3::
FILE "${CMAKE_BINARY_DIR}/Z3Targets.cmake"
)
else()
export(EXPORT Z3_EXPORTED_TARGETS
NAMESPACE z3::
FILE "${CMAKE_BINARY_DIR}/Z3Targets.cmake"
)
endif()
set(Z3_FIRST_PACKAGE_INCLUDE_DIR "${CMAKE_BINARY_DIR}/src/api")
set(Z3_SECOND_PACKAGE_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/src/api")
set(Z3_CXX_PACKAGE_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/src/api/c++")
@ -539,7 +549,6 @@ configure_package_config_file("${CMAKE_SOURCE_DIR}/cmake/Z3Config.cmake.in"
Z3_FIRST_PACKAGE_INCLUDE_DIR
Z3_SECOND_PACKAGE_INCLUDE_DIR
Z3_CXX_PACKAGE_INCLUDE_DIR
INSTALL_PREFIX "${CMAKE_BINARY_DIR}"
)
unset(Z3_FIRST_PACKAGE_INCLUDE_DIR)
unset(Z3_SECOND_PACKAGE_INCLUDE_DIR)

View file

@ -33,34 +33,6 @@ git clean -fx src
which will remove the generated source files.
### Bootstrapping
Most of Z3's CMake files do not live in their correct location. Instead those
files live in the ``contrib/cmake`` folder and a script is provided that will
copy (or hard link) the files into their correct location.
To copy the files run
```
python contrib/cmake/bootstrap.py create
```
in the root of the repository. Once you have done this you can now build Z3 using CMake.
Make sure you remember to rerun this command if you pull down new code/rebase/change branch so
that the copied CMake files are up to date.
To remove the copied files run
```
python contrib/cmake/bootstrap.py remove
```
Note if you plan to do development on Z3 you should read the developer
notes on bootstrapping in this document.
What follows is a brief walk through of how to build Z3 using some
of the more commonly used CMake generators.
### Unix Makefiles
Run the following in the top level directory of the Z3 repository.
@ -294,6 +266,8 @@ The following useful options can be passed to CMake whilst configuring.
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.
* ``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.
If set to ``SERIOUS_ONLY`` a subset of compiler warnings will be treated as errors.
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.
@ -328,44 +302,6 @@ link is not created when building under Windows.
These notes are help developers and packagers of Z3.
### Boostrapping the CMake build
Z3's CMake system is experimental and not officially supported. Consequently
Z3's developers have decided that they do not want the CMake files in the
``src/`` and ``examples/`` folders. Instead the ``contrib/cmake/bootstrap.py``
script copies or hard links them into the correct locations. For context
on this decision see https://github.com/Z3Prover/z3/pull/461 .
The ``contrib/cmake/bootstrap.py create`` command just copies over files which makes
development harder because you have to copy your modifications over to the
files in ``contrib/cmake`` for your changes to committed to git. If you are on a UNIX like
platform you can create hard links instead by running
```
contrib/cmake/boostrap.py create --hard-link
```
Using hard links means that modifying any of the "copied" files also modifies the
file under version control. Using hard links also means that the file modification time
will appear correct (i.e. the hard-linked "copies" have the same file modification time
as the corresponding file under version control) which means CMake will correctly reconfigure
when invoked. This is why using symbolic links is not an option because the file modification
time of a symbolic link is not the same as the file modification of the file being pointed to.
Unfortunately a downside to using hard links (or just plain copies) is that if
you pull down new code (i.e. ``git pull``) then some of the CMake files under
version control may change but the corresponding hard-linked "copies" will not.
This mean that (regardless of whether or not you use hard links) every time you
pull down new code or change branch or do an interactive rebase you must run
(with or without ``--hard-link``):
```
contrb/cmake/boostrap.py create
```
in order to be sure that the copied CMake files are not out of date.
### Install/Uninstall
Install and uninstall targets are supported. Use ``CMAKE_INSTALL_PREFIX`` to
@ -447,3 +383,13 @@ It is tempting use file-globbing in ``CMakeLists.txt`` to find a set for files m
use them as the sources to build a target. This however is a bad idea because it prevents CMake from knowing when it needs to rerun itself. This is why source file names are explicitly listed in the ``CMakeLists.txt`` so that when changes are made the source files used to build a target automatically triggers a rerun of CMake.
Long story short. Don't use file globbing.
### Serious warning flags
By default the `WARNINGS_AS_ERRORS` flag is set to `SERIOUS_ONLY` which means
some warnings will be treated as errors. These warnings are controlled by the
relevant `*_WARNINGS_AS_ERRORS` list defined in
`cmake/compiler_warnings.cmake`.
Additional warnings should only be added here if the warnings has no false
positives.

View file

@ -12,9 +12,9 @@ See the [release notes](RELEASE_NOTES) for notes on various stable releases of Z
## Build status
| Windows x86 | Windows x64 | Ubuntu x64 | Ubuntu x86 | Debian x64 | OSX |
| ----------- | ----------- | ---------- | ---------- | ---------- | --- |
![win32-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/4/badge) | ![win64-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/7/badge) | ![ubuntu-x64-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/3/badge) | ![ubuntu-x86-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/6/badge) | ![debian-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/5/badge) | ![osx-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/2/badge)
| Windows x86 | Windows x64 | Ubuntu x64 | Ubuntu x86 | 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)
[1]: #building-z3-on-windows-using-visual-studio-command-prompt
[2]: #building-z3-using-make-and-gccclang

View file

@ -1,5 +1,15 @@
RELEASE NOTES
Version 4.5.x
=============
- New features (including):
- A new string solver from University of Waterloo
- A new linear real arithmetic solver
- Changed behavior for optimization commands from the SMT2 command-line interface.
Objective values are no longer printed by default. They can be retrieved by
issuing the command (get-objectives). Pareto front objectives are accessed by
issuing multiple (check-sat) calls until it returns unsat.
Version 4.5.0
=============

View file

@ -0,0 +1,140 @@
################################################################################
# Compiler warning flags
################################################################################
# These are passed to relevant compiler provided they are supported
set(GCC_AND_CLANG_WARNINGS
"-Wall"
)
set(GCC_ONLY_WARNINGS "")
set(CLANG_ONLY_WARNINGS "")
set(MSVC_WARNINGS "/W3")
################################################################################
# Serious warnings
################################################################################
# This declares the flags that are passed to the compiler when
# `WARNINGS_AS_ERRORS` is set to `SERIOUS_ONLY`. Only flags that are supported
# by the compiler are used.
#
# In effect this a "whitelist" approach where we explicitly tell the compiler
# which warnings we want to be treated as errors. The alternative would be a
# "blacklist" approach where we ask the compiler to treat all warnings are
# treated as errors but then we explicitly list which warnings which should be
# allowed.
#
# The "whitelist" approach seems simpiler because we can incrementally add
# warnings we "think are serious".
# TODO: Add more warnings that are considered serious enough that we should
# treat them as errors.
set(GCC_AND_CLANG_WARNINGS_AS_ERRORS
# https://clang.llvm.org/docs/DiagnosticsReference.html#wodr
"-Werror=odr"
)
set(GCC_WARNINGS_AS_ERRORS
""
)
set(CLANG_WARNINGS_AS_ERRORS
# https://clang.llvm.org/docs/DiagnosticsReference.html#wdelete-non-virtual-dtor
"-Werror=delete-non-virtual-dtor"
# https://clang.llvm.org/docs/DiagnosticsReference.html#woverloaded-virtual
"-Werror=overloaded-virtual"
)
################################################################################
# Test warning/error flags
################################################################################
set(WARNING_FLAGS_TO_CHECK "")
set(WARNING_AS_ERROR_FLAGS_TO_CHECK "")
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
list(APPEND WARNING_FLAGS_TO_CHECK ${GCC_AND_CLANG_WARNINGS})
list(APPEND WARNING_FLAGS_TO_CHECK ${GCC_ONLY_WARNINGS})
list(APPEND WARNING_AS_ERROR_FLAGS_TO_CHECK ${GCC_AND_CLANG_WARNINGS_AS_ERRORS})
list(APPEND WARNING_AS_ERROR_FLAGS_TO_CHECK ${GCC_WARNINGS_AS_ERRORS})
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
list(APPEND WARNING_FLAGS_TO_CHECK ${GCC_AND_CLANG_WARNINGS})
list(APPEND WARNING_FLAGS_TO_CHECK ${CLANG_ONLY_WARNINGS})
list(APPEND WARNING_AS_ERROR_FLAGS_TO_CHECK ${GCC_AND_CLANG_WARNINGS_AS_ERRORS})
list(APPEND WARNING_AS_ERROR_FLAGS_TO_CHECK ${CLANG_WARNINGS_AS_ERRORS})
# FIXME: Remove "x.." when CMP0054 is set to NEW
elseif ("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC")
list(APPEND WARNING_FLAGS_TO_CHECK ${MSVC_WARNINGS})
# CMake's default flags include /W3 already so remove them if
# they already exist.
if ("${CMAKE_CXX_FLAGS}" MATCHES "/W3")
string(REPLACE "/W3" "" _cmake_cxx_flags_remove_w3 "${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS "${_cmake_cxx_flags_remove_w3}" CACHE STRING "" FORCE)
endif()
else()
message(AUTHOR_WARNING "Unknown compiler")
endif()
# Loop through flags and use the ones which the compiler supports
foreach (flag ${WARNING_FLAGS_TO_CHECK})
z3_add_cxx_flag("${flag}")
endforeach()
# TODO: Remove this eventually.
# Detect legacy `WARNINGS_AS_ERRORS` boolean option and covert to new
# to new option type.
get_property(
WARNINGS_AS_ERRORS_CACHE_VAR_TYPE
CACHE
WARNINGS_AS_ERRORS
PROPERTY
TYPE
)
if ("${WARNINGS_AS_ERRORS_CACHE_VAR_TYPE}" STREQUAL "BOOL")
message(WARNING "Detected legacy WARNINGS_AS_ERRORS option. Upgrading")
set(WARNINGS_AS_ERRORS_DEFAULT "${WARNINGS_AS_ERRORS}")
# Delete old entry
unset(WARNINGS_AS_ERRORS CACHE)
else()
set(WARNINGS_AS_ERRORS_DEFAULT "SERIOUS_ONLY")
endif()
set(WARNINGS_AS_ERRORS
${WARNINGS_AS_ERRORS_DEFAULT}
CACHE STRING
"Treat warnings as errors. ON, OFF, or SERIOUS_ONLY"
)
# Set GUI options
set_property(
CACHE
WARNINGS_AS_ERRORS
PROPERTY STRINGS
"ON;OFF;SERIOUS_ONLY"
)
if ("${WARNINGS_AS_ERRORS}" STREQUAL "ON")
message(STATUS "Treating compiler warnings as errors")
if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU"))
list(APPEND Z3_COMPONENT_CXX_FLAGS "-Werror")
# FIXME: Remove "x.." when CMP0054 is set to NEW
elseif ("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC")
list(APPEND Z3_COMPONENT_CXX_FLAGS "/WX")
else()
message(AUTHOR_WARNING "Unknown compiler")
endif()
elseif ("${WARNINGS_AS_ERRORS}" STREQUAL "SERIOUS_ONLY")
message(STATUS "Treating only serious compiler warnings as errors")
# Loop through the flags
foreach (flag ${WARNING_AS_ERROR_FLAGS_TO_CHECK})
# Add globally because some flags need to be passed at link time.
z3_add_cxx_flag("${flag}" GLOBAL)
endforeach()
elseif ("${WARNINGS_AS_ERRORS}" STREQUAL "OFF")
message(STATUS "Not treating compiler warnings as errors")
# FIXME: Remove "x.." when CMP0054 is set to NEW
if ("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC")
# Warnings as errors is off by default for MSVC so setting this
# is not necessary but this duplicates the behaviour of the old
# build system.
list(APPEND Z3_COMPONENT_CXX_FLAGS "/WX-")
endif()
else()
message(FATAL_ERROR
"WARNINGS_AS_ERRORS set to unsupported value \"${WARNINGS_AS_ERRORS}\""
)
endif()

View file

@ -99,7 +99,9 @@ function(get_git_head_hash GIT_DIR OUTPUT_VAR)
message(FATAL_ERROR \""${GIT_DIR}\" is not an absolute path")
endif()
find_package(Git)
if (NOT Git_FOUND)
# NOTE: Use `GIT_FOUND` rather than `Git_FOUND` which was only
# available in CMake >= 3.5
if (NOT GIT_FOUND)
set(${OUTPUT_VAR} "GIT-NOTFOUND" PARENT_SCOPE)
return()
endif()
@ -146,7 +148,9 @@ function(get_git_head_describe GIT_DIR OUTPUT_VAR)
message(FATAL_ERROR \""${GIT_DIR}\" is not an absolute path")
endif()
find_package(Git)
if (NOT Git_FOUND)
# NOTE: Use `GIT_FOUND` rather than `Git_FOUND` which was only
# available in CMake >= 3.5
if (NOT GIT_FOUND)
set(${OUTPUT_VAR} "GIT-NOTFOUND" PARENT_SCOPE)
return()
endif()

View file

@ -55,6 +55,9 @@ endfunction()
# SOURCES source1 [source2...]
# [COMPONENT_DEPENDENCIES component1 [component2...]]
# [PYG_FILES pygfile1 [pygfile2...]]
# [TACTIC_HEADERS header_file1 [header_file2...]]
# [EXTRA_REGISTER_MODULE_HEADERS header_file1 [header_file2...]]
# [MEMORY_INIT_FINALIZER_HEADERS header_file1 [header_file2...]]
# )
#
# Declares a Z3 component (as a CMake "object library") with target name
@ -80,14 +83,32 @@ endfunction()
# The optional ``PYG_FILES`` keyword should be followed by a list of one or
# more ``<NAME>.pyg`` files that should used to be generate
# ``<NAME>_params.hpp`` header files used by the ``component_name``.
# This generated file will automatically be scanned for the register module
# declarations (i.e. ``REG_PARAMS()``, ``REG_MODULE_PARAMS()``, and
# ``REG_MODULE_DESCRIPTION()``).
#
# The optional ``TACTIC_HEADERS`` keyword should be followed by a list of one or
# more header files that declare a tactic and/or a probe that is part of this
# component (see ``ADD_TACTIC()`` and ``ADD_PROBE()``).
#
# The optional ``EXTRA_REGISTER_MODULE_HEADERS`` keyword should be followed by a list
# of one or more header files that contain module registration declarations.
# NOTE: The header files generated from ``.pyg`` files don't need to be included.
#
# The optional ``MEMORY_INIT_FINALIZER_HEADERS`` keyword should be followed by a list
# of one or more header files that contain memory initializer/finalizer declarations
# (i.e. ``ADD_INITIALIZER()`` or ``ADD_FINALIZER()``).
macro(z3_add_component component_name)
CMAKE_PARSE_ARGUMENTS("Z3_MOD" "NOT_LIBZ3_COMPONENT" "" "SOURCES;COMPONENT_DEPENDENCIES;PYG_FILES" ${ARGN})
CMAKE_PARSE_ARGUMENTS("Z3_MOD"
"NOT_LIBZ3_COMPONENT"
""
"SOURCES;COMPONENT_DEPENDENCIES;PYG_FILES;TACTIC_HEADERS;EXTRA_REGISTER_MODULE_HEADERS;MEMORY_INIT_FINALIZER_HEADERS" ${ARGN})
message(STATUS "Adding component ${component_name}")
# Note: We don't check the sources exist here because
# they might be generated files that don't exist yet.
set(_list_generated_headers "")
set_property(GLOBAL PROPERTY Z3_${component_name}_REGISTER_MODULE_HEADERS "")
foreach (pyg_file ${Z3_MOD_PYG_FILES})
set(_full_pyg_file_path "${CMAKE_CURRENT_SOURCE_DIR}/${pyg_file}")
if (NOT (EXISTS "${_full_pyg_file_path}"))
@ -112,11 +133,70 @@ macro(z3_add_component component_name)
VERBATIM
)
list(APPEND _list_generated_headers "${_full_output_file_path}")
# FIXME: This implicit dependency of a generated file depending on
# generated files was inherited from the old build system.
# Typically generated headers contain `REG_PARAMS()`, `REG_MODULE_PARAMS()`
# and `REG_MODULE_DESCRIPTION()` declarations so add to the list of
# header files to scan.
set_property(GLOBAL
APPEND
PROPERTY Z3_${component_name}_REGISTER_MODULE_HEADERS
"${_full_output_file_path}"
)
endforeach()
unset(_full_include_dir_path)
unset(_full_output_file_path)
unset(_output_file)
# Add tactic/probe headers to global property
set_property(GLOBAL PROPERTY Z3_${component_name}_TACTIC_HEADERS "")
foreach (tactic_header ${Z3_MOD_TACTIC_HEADERS})
set(_full_tactic_header_file_path "${CMAKE_CURRENT_SOURCE_DIR}/${tactic_header}")
if (NOT (EXISTS "${_full_tactic_header_file_path}"))
message(FATAL_ERROR "\"${_full_tactic_header_file_path}\" does not exist")
endif()
set_property(GLOBAL
APPEND
PROPERTY Z3_${component_name}_TACTIC_HEADERS
"${_full_tactic_header_file_path}"
)
endforeach()
unset(_full_tactic_header_file_path)
# Add additional register module headers
foreach (extra_register_module_header ${Z3_MOD_EXTRA_REGISTER_MODULE_HEADERS})
set(_full_extra_register_module_header_path
"${CMAKE_CURRENT_SOURCE_DIR}/${extra_register_module_header}"
)
if (NOT (EXISTS "${_full_extra_register_module_header_path}"))
message(FATAL_ERROR "\"${_full_extra_register_module_header_path}\" does not exist")
endif()
set_property(GLOBAL
APPEND
PROPERTY Z3_${component_name}_REGISTER_MODULE_HEADERS
"${_full_extra_register_module_header_path}"
)
endforeach()
unset(_full_extra_register_module_header)
# Add memory initializer/finalizer headers to global property
set_property(GLOBAL PROPERTY Z3_${component_name}_MEM_INIT_FINALIZER_HEADERS "")
foreach (memory_init_finalizer_header ${Z3_MOD_MEMORY_INIT_FINALIZER_HEADERS})
set(_full_memory_init_finalizer_header_path
"${CMAKE_CURRENT_SOURCE_DIR}/${memory_init_finalizer_header}")
if (NOT (EXISTS "${_full_memory_init_finalizer_header_path}"))
message(FATAL_ERROR "\"${_full_memory_init_finalizer_header_path}\" does not exist")
endif()
set_property(GLOBAL
APPEND
PROPERTY Z3_${component_name}_MEM_INIT_FINALIZER_HEADERS
"${_full_memory_init_finalizer_header_path}"
)
endforeach()
unset(_full_memory_init_finalizer_header_path)
# Using "object" libraries here means we have a convenient
# name to refer to a component in CMake but we don't actually
# create a static/library from them. This allows us to easily
@ -191,25 +271,33 @@ macro(z3_add_install_tactic_rule)
)
endif()
z3_expand_dependencies(_expanded_components ${ARGN})
# Get paths to search
set(_search_paths "")
# Get header files that declare tactics/probes
set(_tactic_header_files "")
foreach (dependency ${_expanded_components})
get_property(_dep_include_dirs GLOBAL PROPERTY Z3_${dependency}_INCLUDES)
list(APPEND _search_paths ${_dep_include_dirs})
get_property(_component_tactic_header_files
GLOBAL
PROPERTY Z3_${dependency}_TACTIC_HEADERS
)
list(APPEND _tactic_header_files ${_component_tactic_header_files})
endforeach()
unset(_component_tactic_header_files)
list(APPEND _search_paths "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}")
add_custom_command(OUTPUT "install_tactic.cpp"
COMMAND "${PYTHON_EXECUTABLE}"
"${CMAKE_SOURCE_DIR}/scripts/mk_install_tactic_cpp.py"
"${CMAKE_CURRENT_BINARY_DIR}"
${_search_paths}
${_tactic_header_files}
DEPENDS "${CMAKE_SOURCE_DIR}/scripts/mk_install_tactic_cpp.py"
${Z3_GENERATED_FILE_EXTRA_DEPENDENCIES}
${_expanded_components}
${_tactic_header_files}
COMMENT "Generating \"${CMAKE_CURRENT_BINARY_DIR}/install_tactic.cpp\""
${ADD_CUSTOM_COMMAND_USES_TERMINAL_ARG}
VERBATIM
)
unset(_expanded_components)
unset(_tactic_header_files)
endmacro()
macro(z3_add_memory_initializer_rule)
@ -230,18 +318,31 @@ macro(z3_add_memory_initializer_rule)
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
set(_mem_init_finalize_headers "")
foreach (dependency ${_expanded_components})
get_property(_dep_mem_init_finalize_headers
GLOBAL
PROPERTY Z3_${dependency}_MEM_INIT_FINALIZER_HEADERS
)
list(APPEND _mem_init_finalize_headers ${_dep_mem_init_finalize_headers})
endforeach()
add_custom_command(OUTPUT "mem_initializer.cpp"
COMMAND "${PYTHON_EXECUTABLE}"
"${CMAKE_SOURCE_DIR}/scripts/mk_mem_initializer_cpp.py"
"${CMAKE_CURRENT_BINARY_DIR}"
${_search_paths}
${_mem_init_finalize_headers}
DEPENDS "${CMAKE_SOURCE_DIR}/scripts/mk_mem_initializer_cpp.py"
${Z3_GENERATED_FILE_EXTRA_DEPENDENCIES}
${_expanded_components}
${_mem_init_finalize_headers}
COMMENT "Generating \"${CMAKE_CURRENT_BINARY_DIR}/mem_initializer.cpp\""
${ADD_CUSTOM_COMMAND_USES_TERMINAL_ARG}
VERBATIM
)
unset(_mem_init_finalize_headers)
unset(_expanded_components)
endmacro()
macro(z3_add_gparams_register_modules_rule)
@ -255,23 +356,27 @@ macro(z3_add_gparams_register_modules_rule)
)
endif()
z3_expand_dependencies(_expanded_components ${ARGN})
# Get paths to search
set(_search_paths "")
# Get the list of header files to parse
set(_register_module_header_files "")
foreach (dependency ${_expanded_components})
get_property(_dep_include_dirs GLOBAL PROPERTY Z3_${dependency}_INCLUDES)
list(APPEND _search_paths ${_dep_include_dirs})
get_property(_component_register_module_header_files GLOBAL PROPERTY Z3_${dependency}_REGISTER_MODULE_HEADERS)
list(APPEND _register_module_header_files ${_component_register_module_header_files})
endforeach()
list(APPEND _search_paths "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}")
unset(_component_register_module_header_files)
add_custom_command(OUTPUT "gparams_register_modules.cpp"
COMMAND "${PYTHON_EXECUTABLE}"
"${CMAKE_SOURCE_DIR}/scripts/mk_gparams_register_modules_cpp.py"
"${CMAKE_CURRENT_BINARY_DIR}"
${_search_paths}
${_register_module_header_files}
DEPENDS "${CMAKE_SOURCE_DIR}/scripts/mk_gparams_register_modules_cpp.py"
${Z3_GENERATED_FILE_EXTRA_DEPENDENCIES}
${_expanded_components}
${_register_module_header_files}
COMMENT "Generating \"${CMAKE_CURRENT_BINARY_DIR}/gparams_register_modules.cpp\""
${ADD_CUSTOM_COMMAND_USES_TERMINAL_ARG}
VERBATIM
)
unset(_expanded_components)
unset(_register_module_header_files)
endmacro()

View file

@ -2,12 +2,13 @@ include(CheckCXXCompilerFlag)
include(CMakeParseArguments)
function(z3_add_cxx_flag flag)
CMAKE_PARSE_ARGUMENTS(z3_add_flag "REQUIRED" "" "" ${ARGN})
CMAKE_PARSE_ARGUMENTS(z3_add_flag "REQUIRED;GLOBAL" "" "" ${ARGN})
string(REPLACE "-" "_" SANITIZED_FLAG_NAME "${flag}")
string(REPLACE "/" "_" SANITIZED_FLAG_NAME "${SANITIZED_FLAG_NAME}")
string(REPLACE "=" "_" SANITIZED_FLAG_NAME "${SANITIZED_FLAG_NAME}")
string(REPLACE " " "_" SANITIZED_FLAG_NAME "${SANITIZED_FLAG_NAME}")
string(REPLACE ":" "_" SANITIZED_FLAG_NAME "${SANITIZED_FLAG_NAME}")
string(REPLACE "+" "_" SANITIZED_FLAG_NAME "${SANITIZED_FLAG_NAME}")
unset(HAS_${SANITIZED_FLAG_NAME})
CHECK_CXX_COMPILER_FLAG("${flag}" HAS_${SANITIZED_FLAG_NAME})
if (z3_add_flag_REQUIRED AND NOT HAS_${SANITIZED_FLAG_NAME})
@ -15,8 +16,13 @@ function(z3_add_cxx_flag flag)
endif()
if (HAS_${SANITIZED_FLAG_NAME})
message(STATUS "C++ compiler supports ${flag}")
list(APPEND Z3_COMPONENT_CXX_FLAGS "${flag}")
set(Z3_COMPONENT_CXX_FLAGS "${Z3_COMPONENT_CXX_FLAGS}" PARENT_SCOPE)
if (z3_add_flag_GLOBAL)
# Set globally
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag} " PARENT_SCOPE)
else()
list(APPEND Z3_COMPONENT_CXX_FLAGS "${flag}")
set(Z3_COMPONENT_CXX_FLAGS "${Z3_COMPONENT_CXX_FLAGS}" PARENT_SCOPE)
endif()
else()
message(STATUS "C++ compiler does not support ${flag}")
endif()

View file

@ -0,0 +1,50 @@
# This base image is not officially supported by Docker it
# is generated by running
# ```
# ./update.sh xenial
# ```
# from git@github.com:daald/docker-brew-ubuntu-core-32bit.git
# at commit 34ea593b40b423755b7d46b6c8c89fc8162ea74b
#
# We could actually store the image generated by this Dockerfile
# rather than just the bare image. However given we have a TravisCI
# cache I'm not sure if it faster to use the TravisCI cache or to
# download from DockerHub everytime.
FROM z3prover/ubuntu32:16.04
RUN apt-get update && \
apt-get -y --no-install-recommends install \
binutils \
clang \
clang-3.9 \
cmake \
doxygen \
default-jdk \
gcc \
gcc-5 \
git \
graphviz \
g++ \
g++ \
libgmp-dev \
libgomp1 \
libomp5 \
libomp-dev \
make \
mono-devel \
ninja-build \
python3 \
python3-setuptools \
python2.7 \
python-setuptools \
sudo
# Create `user` user for container with password `user`. and give it
# password-less sudo access
RUN useradd -m user && \
echo user:user | chpasswd && \
cp /etc/sudoers /etc/sudoers.bak && \
echo 'user ALL=(root) NOPASSWD: ALL' >> /etc/sudoers
USER user
WORKDIR /home/user

View file

@ -0,0 +1,35 @@
FROM ubuntu:14.04
RUN apt-get update && \
apt-get -y --no-install-recommends install \
binutils \
clang-3.9 \
cmake \
doxygen \
default-jdk \
gcc-multilib \
gcc-4.8-multilib \
git \
graphviz \
g++-multilib \
g++-4.8-multilib \
libgmp-dev \
libgomp1 \
lib32gomp1 \
make \
mono-devel \
ninja-build \
python3 \
python3-setuptools \
python2.7 \
python-setuptools
# Create `user` user for container with password `user`. and give it
# password-less sudo access
RUN useradd -m user && \
echo user:user | chpasswd && \
cp /etc/sudoers /etc/sudoers.bak && \
echo 'user ALL=(root) NOPASSWD: ALL' >> /etc/sudoers
USER user
WORKDIR /home/user

View file

@ -0,0 +1,38 @@
FROM ubuntu:16.04
RUN apt-get update && \
apt-get -y --no-install-recommends install \
binutils \
clang \
clang-3.9 \
cmake \
doxygen \
default-jdk \
gcc-multilib \
gcc-5-multilib \
git \
graphviz \
g++-multilib \
g++-5-multilib \
libgmp-dev \
libgomp1 \
libomp5 \
libomp-dev \
make \
mono-devel \
ninja-build \
python3 \
python3-setuptools \
python2.7 \
python-setuptools \
sudo
# Create `user` user for container with password `user`. and give it
# password-less sudo access
RUN useradd -m user && \
echo user:user | chpasswd && \
cp /etc/sudoers /etc/sudoers.bak && \
echo 'user ALL=(root) NOPASSWD: ALL' >> /etc/sudoers
USER user
WORKDIR /home/user

View file

@ -0,0 +1,111 @@
ARG DOCKER_IMAGE_BASE
FROM ${DOCKER_IMAGE_BASE}
# Specify defaults. This can be changed when invoking
# `docker build`.
ARG ASAN_BUILD=0
ARG BUILD_DOCS=0
ARG CC=gcc
ARG CXX=g++
ARG DOTNET_BINDINGS=1
ARG JAVA_BINDINGS=1
ARG NO_SUPPRESS_OUTPUT=0
ARG PYTHON_BINDINGS=1
ARG PYTHON_EXECUTABLE=/usr/bin/python2.7
ARG RUN_SYSTEM_TESTS=1
ARG RUN_UNIT_TESTS=1
ARG TARGET_ARCH=x86_64
ARG TEST_INSTALL=1
ARG UBSAN_BUILD=0
ARG USE_LIBGMP=0
ARG USE_LTO=0
ARG USE_OPENMP=1
ARG Z3_SRC_DIR=/home/user/z3_src
ARG Z3_BUILD_TYPE=RelWithDebInfo
ARG Z3_CMAKE_GENERATOR=Ninja
ARG Z3_INSTALL_PREFIX=/usr
ARG Z3_STATIC_BUILD=0
# Blank default indicates use latest.
ARG Z3_SYSTEM_TEST_GIT_REVISION
ARG Z3_WARNINGS_AS_ERRORS=SERIOUS_ONLY
ARG Z3_VERBOSE_BUILD_OUTPUT=0
ENV \
ASAN_BUILD=${ASAN_BUILD} \
BUILD_DOCS=${BUILD_DOCS} \
CC=${CC} \
CXX=${CXX} \
DOTNET_BINDINGS=${DOTNET_BINDINGS} \
JAVA_BINDINGS=${JAVA_BINDINGS} \
NO_SUPPRESS_OUTPUT=${NO_SUPPRESS_OUTPUT} \
PYTHON_BINDINGS=${PYTHON_BINDINGS} \
PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE} \
RUN_SYSTEM_TESTS=${RUN_SYSTEM_TESTS} \
RUN_UNIT_TESTS=${RUN_UNIT_TESTS} \
TARGET_ARCH=${TARGET_ARCH} \
TEST_INSTALL=${TEST_INSTALL} \
UBSAN_BUILD=${UBSAN_BUILD} \
USE_LIBGMP=${USE_LIBGMP} \
USE_LTO=${USE_LTO} \
USE_OPENMP=${USE_OPENMP} \
Z3_SRC_DIR=${Z3_SRC_DIR} \
Z3_BUILD_DIR=/home/user/z3_build \
Z3_CMAKE_GENERATOR=${Z3_CMAKE_GENERATOR} \
Z3_VERBOSE_BUILD_OUTPUT=${Z3_VERBOSE_BUILD_OUTPUT} \
Z3_STATIC_BUILD=${Z3_STATIC_BUILD} \
Z3_SYSTEM_TEST_DIR=/home/user/z3_system_test \
Z3_SYSTEM_TEST_GIT_REVISION=${Z3_SYSTEM_TEST_GIT_REVISION} \
Z3_WARNINGS_AS_ERRORS=${Z3_WARNINGS_AS_ERRORS} \
Z3_INSTALL_PREFIX=${Z3_INSTALL_PREFIX}
# We add context across incrementally to maximal cache reuse
# Build Z3
RUN mkdir -p "${Z3_SRC_DIR}" && \
mkdir -p "${Z3_SRC_DIR}/contrib/ci/scripts"
# Deliberately leave out `contrib`
ADD /cmake ${Z3_SRC_DIR}/cmake/
ADD /doc ${Z3_SRC_DIR}/doc/
ADD /examples ${Z3_SRC_DIR}/examples/
ADD /scripts ${Z3_SRC_DIR}/scripts/
ADD /src ${Z3_SRC_DIR}/src/
ADD *.txt *.md RELEASE_NOTES ${Z3_SRC_DIR}/
ADD \
/contrib/ci/scripts/build_z3_cmake.sh \
/contrib/ci/scripts/set_compiler_flags.sh \
/contrib/ci/scripts/set_generator_args.sh \
${Z3_SRC_DIR}/contrib/ci/scripts/
RUN ${Z3_SRC_DIR}/contrib/ci/scripts/build_z3_cmake.sh
# Test building docs
ADD \
/contrib/ci/scripts/test_z3_docs.sh \
/contrib/ci/scripts/run_quiet.sh \
${Z3_SRC_DIR}/contrib/ci/scripts/
RUN ${Z3_SRC_DIR}/contrib/ci/scripts/test_z3_docs.sh
# Test examples
ADD \
/contrib/ci/scripts/test_z3_examples_cmake.sh \
${Z3_SRC_DIR}/contrib/ci/scripts/
RUN ${Z3_SRC_DIR}/contrib/ci/scripts/test_z3_examples_cmake.sh
# Run unit tests
ADD \
/contrib/ci/scripts/test_z3_unit_tests_cmake.sh \
${Z3_SRC_DIR}/contrib/ci/scripts/
RUN ${Z3_SRC_DIR}/contrib/ci/scripts/test_z3_unit_tests_cmake.sh
# Run system tests
ADD \
/contrib/ci/scripts/test_z3_system_tests.sh \
${Z3_SRC_DIR}/contrib/ci/scripts/
RUN ${Z3_SRC_DIR}/contrib/ci/scripts/test_z3_system_tests.sh
# Test install
ADD \
/contrib/ci/scripts/test_z3_install_cmake.sh \
${Z3_SRC_DIR}/contrib/ci/scripts/
RUN ${Z3_SRC_DIR}/contrib/ci/scripts/test_z3_install_cmake.sh

114
contrib/ci/README.md Normal file
View file

@ -0,0 +1,114 @@
# Continous integration scripts
## TravisCI
For testing on Linux and macOS we use [TravisCI](https://travis-ci.org/)
TravisCI consumes the `.travis.yml` file in the root of the repository
to tell it how to build and test Z3.
However the logic for building and test Z3 is kept out of this file
and instead in a set of scripts in `scripts/`. This avoids
coupling the build to TravisCI tightly so we can migrate to another
service if required in the future.
The scripts rely on a set of environment variables to control the configuration
of the build. The `.travis.yml` declares a list of configuration with each
configuration setting different environment variables.
Note that the build scripts currently only support Z3 built with CMake. Support
for building Z3 using the older Python/Makefile build system might be added in
the future.
### Configuration variables
* `ASAN_BUILD` - Do [AddressSanitizer](https://github.com/google/sanitizers/wiki/AddressSanitizer) build (`0` or `1`)
* `BUILD_DOCS` - Build API documentation (`0` or `1`)
* `C_COMPILER` - Path to C Compiler
* `CXX_COMPILER` - Path to C++ Compiler
* `DOTNET_BINDINGS` - Build and test .NET 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`)
* `PYTHON_BINDINGS` - Build and test Python API bindings (`0` or `1`)
* `RUN_SYSTEM_TESTS` - Run system tests (`0` or `1`)
* `RUN_UNIT_TESTS` - Run unit tests (`0` or `1`)
* `TARGET_ARCH` - Target architecture (`x86_64` or `i686`)
* `TEST_INSTALL` - Test running `install` target (`0` or `1`)
* `UBSAN_BUILD` - Do [UndefinedBehaviourSanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) build (`0` or `1`)
* `USE_LIBGMP` - Use [GNU multiple precision library](https://gmplib.org/) (`0` or `1`)
* `USE_LTO` - Link binaries using link time optimization (`0` or `1`)
* `USE_OPENMP` - Use OpenMP (`0` or `1`)
* `Z3_BUILD_TYPE` - CMake build type (`RelWithDebInfo`, `Release`, `Debug`, or `MinSizeRel`)
* `Z3_CMAKE_GENERATOR` - CMake generator (`Ninja` or `Unix Makefiles`)
* `Z3_VERBOSE_BUILD_OUTPUT` - Show compile commands in CMake builds (`0` or `1`)
* `Z3_STATIC_BUILD` - Build Z3 binaries and libraries statically (`0` or `1`)
* `Z3_SYSTEM_TEST_GIT_REVISION` - Git revision of [z3test](https://github.com/Z3Prover/z3test). If empty lastest revision will be used.
* `Z3_WARNINGS_AS_ERRORS` - Set the `WARNINGS_AS_ERRORS` CMake option pased to Z3 (`OFF`, `ON`, or `SERIOUS_ONLY`)
### Linux
For Linux we use Docker to perform the build so that it easily reproducible
on a local machine and so that we can avoid depending on TravisCI's environment
and instead use a Linux distribution of our choice.
The `scripts/travis_ci_linux_entry_point.sh` script
1. Creates a base image containing all the dependencies needed to build and test Z3
2. Builds and tests Z3 using the base image propagating configuration environment
variables (if set) into the build using the `--build-arg` argument of the `docker run`
command.
If an environemnt variable is not set a defaults value is used which can be
found in `Dockerfiles/z3_build.Dockerfile`.
#### Linux specific configuration variables
* `LINUX_BASE` - The base docker image identifier to use (`ubuntu_16.04`, `ubuntu32_16.04`, or `ubuntu_14.04`).
#### Reproducing a build locally
A build can be reproduced locally by using the `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.
```yaml
- 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
```
This can be done by running the command
```bash
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 scripts/travis_ci_linux_entry_point.sh
```
The `docker build` command which we use internally supports caching. What this
means in practice is that re-running the above command will re-use successfully
completed stages of the build provided they haven't changed. This requires that
the `Dockerfiles/z3_build.Dockerfile` is carefully crafted to avoid invalidating
the cache when unrelated files sent to the build context change.
#### TravisCI docker image cache
To improve build times the Z3 base docker images are cached using
[TravisCI's cache directory feature](https://docs.travis-ci.com/user/caching).
If the `DOCKER_TRAVIS_CI_CACHE_DIR` environment variable is set (see `.travis.yml`)
then the directory pointed to by the environment variable is used as a cache
for Docker images.
The logic for this can be found in `scripts/travis_ci_linux_entry_point.sh`.
The build time improvements are rather modest (~ 2 minutes) and the cache is
rather large due to TravisCI giving each configuration its own cache. So this
feature might be removed in the future.
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
image everytime.
An [organization](https://hub.docker.com/u/z3prover/) has been created on
DockerHub for this.
### macOS
Not yet implemented.

View file

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

View file

@ -0,0 +1,130 @@
#!/bin/bash
# This script builds Z3
SCRIPT_DIR="$( cd ${BASH_SOURCE[0]%/*} ; echo $PWD )"
set -x
set -e
set -o pipefail
: ${Z3_SRC_DIR?"Z3_SRC_DIR must be specified"}
: ${Z3_BUILD_DIR?"Z3_BUILD_DIR must be specified"}
: ${Z3_BUILD_TYPE?"Z3_BUILD_TYPE must be specified"}
: ${Z3_CMAKE_GENERATOR?"Z3_CMAKE_GENERATOR must be specified"}
: ${Z3_STATIC_BUILD?"Z3_STATIC_BUILD must be specified"}
: ${USE_OPENMP?"USE_OPENMP must be specified"}
: ${USE_LIBGMP?"USE_LIBGMP must be specified"}
: ${BUILD_DOCS?"BUILD_DOCS must be specified"}
: ${PYTHON_EXECUTABLE?"PYTHON_EXECUTABLE must be specified"}
: ${PYTHON_BINDINGS?"PYTHON_BINDINGS must be specified"}
: ${DOTNET_BINDINGS?"DOTNET_BINDINGS must be specified"}
: ${JAVA_BINDINGS?"JAVA_BINDINGS must be specified"}
: ${USE_LTO?"USE_LTO must be specified"}
: ${Z3_INSTALL_PREFIX?"Z3_INSTALL_PREFIX must be specified"}
: ${Z3_WARNINGS_AS_ERRORS?"Z3_WARNINGS_AS_ERRORS must be specified"}
ADDITIONAL_Z3_OPTS=()
# Static or dynamic libz3
if [ "X${Z3_STATIC_BUILD}" = "X1" ]; then
ADDITIONAL_Z3_OPTS+=('-DBUILD_LIBZ3_SHARED=OFF')
else
ADDITIONAL_Z3_OPTS+=('-DBUILD_LIBZ3_SHARED=ON')
fi
# Use OpenMP?
if [ "X${USE_OPENMP}" = "X1" ]; then
ADDITIONAL_Z3_OPTS+=('-DUSE_OPENMP=ON')
else
ADDITIONAL_Z3_OPTS+=('-DUSE_OPENMP=OFF')
fi
# Use LibGMP?
if [ "X${USE_LIBGMP}" = "X1" ]; then
ADDITIONAL_Z3_OPTS+=('-DUSE_LIB_GMP=ON')
else
ADDITIONAL_Z3_OPTS+=('-DUSE_LIB_GMP=OFF')
fi
# Use link time optimziation?
if [ "X${USE_LTO}" = "X1" ]; then
ADDITIONAL_Z3_OPTS+=('-DLINK_TIME_OPTIMIZATION=ON')
else
ADDITIONAL_Z3_OPTS+=('-DLINK_TIME_OPTIMIZATION=OFF')
fi
# Build API docs?
if [ "X${BUILD_DOCS}" = "X1" ]; then
ADDITIONAL_Z3_OPTS+=( \
'-DBUILD_DOCUMENTATION=ON' \
'-DALWAYS_BUILD_DOCS=OFF' \
)
else
ADDITIONAL_Z3_OPTS+=('-DBUILD_DOCUMENTATION=OFF')
fi
# Python bindings?
if [ "X${PYTHON_BINDINGS}" = "X1" ]; then
ADDITIONAL_Z3_OPTS+=( \
'-DBUILD_PYTHON_BINDINGS=ON' \
'-DINSTALL_PYTHON_BINDINGS=ON' \
)
else
ADDITIONAL_Z3_OPTS+=( \
'-DBUILD_PYTHON_BINDINGS=OFF' \
'-DINSTALL_PYTHON_BINDINGS=OFF' \
)
fi
# .NET bindings?
if [ "X${DOTNET_BINDINGS}" = "X1" ]; then
ADDITIONAL_Z3_OPTS+=( \
'-DBUILD_DOTNET_BINDINGS=ON' \
'-DINSTALL_DOTNET_BINDINGS=ON' \
)
else
ADDITIONAL_Z3_OPTS+=( \
'-DBUILD_DOTNET_BINDINGS=OFF' \
'-DINSTALL_DOTNET_BINDINGS=OFF' \
)
fi
# Java bindings?
if [ "X${JAVA_BINDINGS}" = "X1" ]; then
ADDITIONAL_Z3_OPTS+=( \
'-DBUILD_JAVA_BINDINGS=ON' \
'-DINSTALL_JAVA_BINDINGS=ON' \
)
else
ADDITIONAL_Z3_OPTS+=( \
'-DBUILD_JAVA_BINDINGS=OFF' \
'-DINSTALL_JAVA_BINDINGS=OFF' \
)
fi
# Set compiler flags
source ${SCRIPT_DIR}/set_compiler_flags.sh
# Sanity check
if [ ! -e "${Z3_SRC_DIR}/CMakeLists.txt" ]; then
echo "Z3_SRC_DIR is invalid"
exit 1
fi
# Make build tree
mkdir -p "${Z3_BUILD_DIR}"
cd "${Z3_BUILD_DIR}"
# Configure
cmake \
-G "${Z3_CMAKE_GENERATOR}" \
-DCMAKE_BUILD_TYPE=${Z3_BUILD_TYPE} \
-DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE} \
-DCMAKE_INSTALL_PREFIX=${Z3_INSTALL_PREFIX} \
-DWARNINGS_AS_ERRORS=${Z3_WARNINGS_AS_ERRORS} \
"${ADDITIONAL_Z3_OPTS[@]}" \
"${Z3_SRC_DIR}"
# Build
source ${SCRIPT_DIR}/set_generator_args.sh
cmake --build $(pwd) "${GENERATOR_ARGS[@]}"

View file

@ -0,0 +1,41 @@
# Simple wrapper function that runs a command suppressing
# it's output. However it's output will be shown in the
# case that `NO_SUPPRESS_OUTPUT` is set to `1` or the command
# fails.
#
# The use case for this trying to avoid large logs on TravisCI
function run_quiet() {
if [ "X${NO_SUPPRESS_OUTPUT}" = "X1" ]; then
"${@}"
else
OLD_SETTINGS="$-"
set +x
set +e
TMP_DIR="${TMP_DIR:-/tmp/}"
STDOUT="${TMP_DIR}/$$.stdout"
STDERR="${TMP_DIR}/$$.stderr"
"${@}" > "${STDOUT}" 2> "${STDERR}"
EXIT_STATUS="$?"
if [ "${EXIT_STATUS}" -ne 0 ]; then
echo "Command \"$@\" failed"
echo "EXIT CODE: ${EXIT_STATUS}"
echo "STDOUT"
echo ""
echo "\`\`\`"
cat ${STDOUT}
echo "\`\`\`"
echo ""
echo "STDERR"
echo ""
echo "\`\`\`"
cat ${STDERR}
echo "\`\`\`"
echo ""
fi
# Clean up
rm "${STDOUT}" "${STDERR}"
[ $( echo "${OLD_SETTINGS}" | grep -c 'e') -ne 0 ] && set -e
[ $( echo "${OLD_SETTINGS}" | grep -c 'x') -ne 0 ] && set -x
return ${EXIT_STATUS}
fi
}

View file

@ -0,0 +1,46 @@
# This script should is intended to be included by other
# scripts and should not be executed directly
: ${TARGET_ARCH?"TARGET_ARCH must be specified"}
: ${ASAN_BUILD?"ASAN_BUILD must be specified"}
: ${UBSAN_BUILD?"UBSAN_BUILD must be specified"}
: ${CC?"CC must be specified"}
: ${CXX?"CXX must be specified"}
case ${TARGET_ARCH} in
x86_64)
CXXFLAGS="${CXXFLAGS} -m64"
CFLAGS="${CFLAGS} -m64"
;;
i686)
CXXFLAGS="${CXXFLAGS} -m32"
CFLAGS="${CFLAGS} -m32"
;;
*)
echo "Unknown arch \"${TARGET_ARCH}\""
exit 1
esac
if [ "X${ASAN_BUILD}" = "X1" ]; then
CXXFLAGS="${CXXFLAGS} -fsanitize=address -fno-omit-frame-pointer"
CFLAGS="${CFLAGS} -fsanitize=address -fno-omit-frame-pointer"
fi
if [ "X${UBSAN_BUILD}" = "X1" ]; then
CXXFLAGS="${CXXFLAGS} -fsanitize=undefined"
CFLAGS="${CFLAGS} -fsanitize=undefined"
fi
# Report flags
echo "CXXFLAGS: ${CXXFLAGS}"
echo "CFLAGS: ${CFLAGS}"
# Report compiler
echo "CC: ${CC}"
${CC} --version
echo "CXX: ${CXX}"
${CXX} --version
# Export the values
export CFLAGS
export CXXFLAGS

View file

@ -0,0 +1,20 @@
# This script should is intended to be included by other
# scripts and should not be executed directly
: ${Z3_CMAKE_GENERATOR?"Z3_CMAKE_GENERATOR must be specified"}
: ${Z3_VERBOSE_BUILD_OUTPUT?"Z3_VERBOSE_BUILD_OUTPUT must be specified"}
GENERATOR_ARGS=('--')
if [ "${Z3_CMAKE_GENERATOR}" = "Unix Makefiles" ]; then
GENERATOR_ARGS+=("-j$(nproc)")
if [ "X${Z3_VERBOSE_BUILD_OUTPUT}" = "X1" ]; then
GENERATOR_ARGS+=("VERBOSE=1")
fi
elif [ "${Z3_CMAKE_GENERATOR}" = "Ninja" ]; then
if [ "X${Z3_VERBOSE_BUILD_OUTPUT}" = "X1" ]; then
GENERATOR_ARGS+=("-v")
fi
else
echo "Unknown CMake generator \"${Z3_CMAKE_GENERATOR}\""
exit 1
fi

View file

@ -0,0 +1,24 @@
#!/bin/bash
SCRIPT_DIR="$( cd ${BASH_SOURCE[0]%/*} ; echo $PWD )"
. ${SCRIPT_DIR}/run_quiet.sh
set -x
set -e
set -o pipefail
: ${Z3_BUILD_DIR?"Z3_BUILD_DIR must be specified"}
: ${BUILD_DOCS?"BUILD_DOCS must be specified"}
# Set CMake generator args
source ${SCRIPT_DIR}/set_generator_args.sh
cd "${Z3_BUILD_DIR}"
# Generate documentation
if [ "X${BUILD_DOCS}" = "X1" ]; then
# TODO: Make quiet once we've fixed the build
run_quiet cmake --build $(pwd) --target api_docs "${GENERATOR_ARGS[@]}"
fi
# TODO: Test or perhaps deploy the built docs?

View file

@ -0,0 +1,87 @@
#!/bin/bash
# This script tests Z3
SCRIPT_DIR="$( cd ${BASH_SOURCE[0]%/*} ; echo $PWD )"
. ${SCRIPT_DIR}/run_quiet.sh
set -x
set -e
set -o pipefail
: ${Z3_SRC_DIR?"Z3_SRC_DIR must be specified"}
: ${Z3_BUILD_DIR?"Z3_BUILD_DIR must be specified"}
: ${PYTHON_BINDINGS?"PYTHON_BINDINGS must be specified"}
: ${PYTHON_EXECUTABLE?"PYTHON_EXECUTABLE must be specified"}
: ${DOTNET_BINDINGS?"DOTNET_BINDINGS must be specified"}
: ${JAVA_BINDINGS?"JAVA_BINDINGS must be specified"}
# Set compiler flags
source ${SCRIPT_DIR}/set_compiler_flags.sh
# Set CMake generator args
source ${SCRIPT_DIR}/set_generator_args.sh
cd "${Z3_BUILD_DIR}"
# Build and run C example
cmake --build $(pwd) --target c_example "${GENERATOR_ARGS[@]}"
run_quiet examples/c_example_build_dir/c_example
# Build and run C++ example
cmake --build $(pwd) --target cpp_example "${GENERATOR_ARGS[@]}"
run_quiet examples/cpp_example_build_dir/cpp_example
# Build and run tptp5 example
cmake --build $(pwd) --target z3_tptp5 "${GENERATOR_ARGS[@]}"
# FIXME: Do something more useful with example
run_quiet examples/tptp_build_dir/z3_tptp5 -help
# Build an run c_maxsat_example
cmake --build $(pwd) --target c_maxsat_example "${GENERATOR_ARGS[@]}"
run_quiet \
examples/c_maxsat_example_build_dir/c_maxsat_example \
${Z3_SRC_DIR}/examples/maxsat/ex.smt
if [ "X${PYTHON_BINDINGS}" = "X1" ]; then
# Run python examples
# `all_interval_series.py` produces a lot of output so just throw
# away output.
# TODO: This example is slow should we remove it from testing?
run_quiet ${PYTHON_EXECUTABLE} python/all_interval_series.py
run_quiet ${PYTHON_EXECUTABLE} python/complex.py
run_quiet ${PYTHON_EXECUTABLE} python/example.py
# FIXME: `hamiltonian.py` example is disabled because its too slow.
#${PYTHON_EXECUTABLE} python/hamiltonian.py
run_quiet ${PYTHON_EXECUTABLE} python/marco.py
run_quiet ${PYTHON_EXECUTABLE} python/mss.py
run_quiet ${PYTHON_EXECUTABLE} python/socrates.py
run_quiet ${PYTHON_EXECUTABLE} python/visitor.py
run_quiet ${PYTHON_EXECUTABLE} python/z3test.py
fi
if [ "X${DOTNET_BINDINGS}" = "X1" ]; then
# Build .NET example
# 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
# Run .NET example
run_quiet mono ./dotnet_test.exe
fi
if [ "X${JAVA_BINDINGS}" = "X1" ]; then
# Build Java example
# FIXME: Move compilation step into CMake target
mkdir -p examples/java
cp ${Z3_SRC_DIR}/examples/java/JavaExample.java examples/java/
javac examples/java/JavaExample.java -classpath com.microsoft.z3.jar
# Run Java example
if [ "$(uname)" = "Darwin" ]; then
# macOS
export DYLD_LIBRARY_PATH=$(pwd):${DYLD_LIBRARY_PATH}
else
# Assume Linux for now
export LD_LIBRARY_PATH=$(pwd):${LD_LIBRARY_PATH}
fi
run_quiet java -cp .:examples/java:com.microsoft.z3.jar JavaExample
fi

View file

@ -0,0 +1,24 @@
#!/bin/bash
SCRIPT_DIR="$( cd ${BASH_SOURCE[0]%/*} ; echo $PWD )"
set -x
set -e
set -o pipefail
: ${TEST_INSTALL?"TEST_INSTALL must be specified"}
: ${Z3_BUILD_DIR?"Z3_BUILD_DIR must be specified"}
if [ "X${TEST_INSTALL}" != "X1" ]; then
echo "Skipping install"
exit 0
fi
# Set CMake generator args
source ${SCRIPT_DIR}/set_generator_args.sh
cd "${Z3_BUILD_DIR}"
sudo cmake --build $(pwd) --target install "${GENERATOR_ARGS[@]}"
# TODO: Test the installed version in some way

View file

@ -0,0 +1,54 @@
#!/bin/bash
set -x
set -e
set -o pipefail
: ${Z3_BUILD_DIR?"Z3_BUILD_DIR must be specified"}
: ${Z3_BUILD_TYPE?"Z3_BUILD_TYPE must be specified"}
: ${RUN_SYSTEM_TESTS?"RUN_SYSTEM_TESTS must be speicifed"}
: ${PYTHON_BINDINGS?"PYTHON_BINDINGS must be specified"}
: ${PYTHON_EXECUTABLE?"PYTHON_EXECUTABLE must be specified"}
: ${Z3_SYSTEM_TEST_DIR?"Z3_SYSTEM_TEST_DIR must be specified"}
if [ "X${RUN_SYSTEM_TESTS}" != "X1" ]; then
echo "Skipping system tests"
exit 0
fi
Z3_EXE="${Z3_BUILD_DIR}/z3"
Z3_LIB_DIR="${Z3_BUILD_DIR}"
# Set value if not already defined externally
Z3_SYSTEM_TEST_GIT_URL="${Z3_GIT_URL:-https://github.com/Z3Prover/z3test.git}"
# Clone repo to destination
mkdir -p "${Z3_SYSTEM_TEST_GIT_URL}"
git clone "${Z3_SYSTEM_TEST_GIT_URL}" "${Z3_SYSTEM_TEST_DIR}"
cd "${Z3_SYSTEM_TEST_DIR}"
if [ -n "${Z3_SYSTEM_TEST_GIT_REVISION}" ]; then
# If a particular revision is requested then check it out.
# This is useful for reproducible builds
git checkout "${Z3_SYSTEM_TEST_GIT_REVISION}"
fi
###############################################################################
# Run system tests
###############################################################################
# SMTLIBv2 tests
${PYTHON_EXECUTABLE} scripts/test_benchmarks.py "${Z3_EXE}" regressions/smt2
${PYTHON_EXECUTABLE} scripts/test_benchmarks.py "${Z3_EXE}" regressions/smt2-extra
if [ "X${Z3_BUILD_TYPE}" = "XDebug" ]; then
${PYTHON_EXECUTABLE} scripts/test_benchmarks.py "${Z3_EXE}" regressions/smt2-debug
fi
if [ "X${PYTHON_BINDINGS}" = "X1" ]; then
# Run python binding tests
${PYTHON_EXECUTABLE} scripts/test_pyscripts.py "${Z3_LIB_DIR}" regressions/python/
fi
# FIXME: Run `scripts/test_cs.py` once it has been modified to support mono

View file

@ -0,0 +1,24 @@
#!/bin/bash
SCRIPT_DIR="$( cd ${BASH_SOURCE[0]%/*} ; echo $PWD )"
set -x
set -e
set -o pipefail
: ${Z3_BUILD_DIR?"Z3_BUILD_DIR 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
source ${SCRIPT_DIR}/set_generator_args.sh
cd "${Z3_BUILD_DIR}"
# Build and run internal tests
cmake --build $(pwd) --target test-z3 "${GENERATOR_ARGS[@]}"
./test-z3

View file

@ -0,0 +1,18 @@
#!/bin/bash
SCRIPT_DIR="$( cd ${BASH_SOURCE[0]%/*} ; echo $PWD )"
set -x
set -e
set -o pipefail
: ${TRAVIS_OS_NAME?"TRAVIS_OS_NAME should be set"}
if [ "${TRAVIS_OS_NAME}" = "osx" ]; then
${SCRIPT_DIR}/travis_ci_osx_entry_point.sh
elif [ "${TRAVIS_OS_NAME}" = "linux" ]; then
${SCRIPT_DIR}/travis_ci_linux_entry_point.sh
else
echo "Unsupported OS \"${TRAVIS_OS_NAME}\""
exit 1
fi

View file

@ -0,0 +1,215 @@
#!/bin/bash
SCRIPT_DIR="$( cd ${BASH_SOURCE[0]%/*} ; echo $PWD )"
set -x
set -e
set -o pipefail
DOCKER_FILE_DIR="$(cd ${SCRIPT_DIR}/../Dockerfiles; echo $PWD)"
: ${LINUX_BASE?"LINUX_BASE must be specified"}
# Sanity check. Current working directory should be repo root
if [ ! -f "./README.md" ]; then
echo "Current working directory should be repo root"
exit 1
fi
BUILD_OPTS=()
# Override options if they have been provided.
# Otherwise the defaults in the Docker file will be used
if [ -n "${Z3_CMAKE_GENERATOR}" ]; then
BUILD_OPTS+=("--build-arg" "Z3_CMAKE_GENERATOR=${Z3_CMAKE_GENERATOR}")
fi
if [ -n "${USE_OPENMP}" ]; then
BUILD_OPTS+=("--build-arg" "USE_OPENMP=${USE_OPENMP}")
fi
if [ -n "${USE_LIBGMP}" ]; then
BUILD_OPTS+=("--build-arg" "USE_LIBGMP=${USE_LIBGMP}")
fi
if [ -n "${BUILD_DOCS}" ]; then
BUILD_OPTS+=("--build-arg" "BUILD_DOCS=${BUILD_DOCS}")
fi
if [ -n "${PYTHON_EXECUTABLE}" ]; then
BUILD_OPTS+=("--build-arg" "PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}")
fi
if [ -n "${PYTHON_BINDINGS}" ]; then
BUILD_OPTS+=("--build-arg" "PYTHON_BINDINGS=${PYTHON_BINDINGS}")
fi
if [ -n "${DOTNET_BINDINGS}" ]; then
BUILD_OPTS+=("--build-arg" "DOTNET_BINDINGS=${DOTNET_BINDINGS}")
fi
if [ -n "${JAVA_BINDINGS}" ]; then
BUILD_OPTS+=("--build-arg" "JAVA_BINDINGS=${JAVA_BINDINGS}")
fi
if [ -n "${USE_LTO}" ]; then
BUILD_OPTS+=("--build-arg" "USE_LTO=${USE_LTO}")
fi
if [ -n "${Z3_INSTALL_PREFIX}" ]; then
BUILD_OPTS+=("--build-arg" "Z3_INSTALL_PREFIX=${Z3_INSTALL_PREFIX}")
fi
# TravisCI reserves CC for itself so use a different name
if [ -n "${C_COMPILER}" ]; then
BUILD_OPTS+=("--build-arg" "CC=${C_COMPILER}")
fi
# TravisCI reserves CXX for itself so use a different name
if [ -n "${CXX_COMPILER}" ]; then
BUILD_OPTS+=("--build-arg" "CXX=${CXX_COMPILER}")
fi
if [ -n "${TARGET_ARCH}" ]; then
BUILD_OPTS+=("--build-arg" "TARGET_ARCH=${TARGET_ARCH}")
fi
if [ -n "${ASAN_BUILD}" ]; then
BUILD_OPTS+=("--build-arg" "ASAN_BUILD=${ASAN_BUILD}")
fi
if [ -n "${UBSAN_BUILD}" ]; then
BUILD_OPTS+=("--build-arg" "UBSAN_BUILD=${UBSAN_BUILD}")
fi
if [ -n "${TEST_INSTALL}" ]; then
BUILD_OPTS+=("--build-arg" "TEST_INSTALL=${TEST_INSTALL}")
fi
if [ -n "${RUN_SYSTEM_TESTS}" ]; then
BUILD_OPTS+=("--build-arg" "RUN_SYSTEM_TESTS=${RUN_SYSTEM_TESTS}")
fi
if [ -n "${Z3_SYSTEM_TEST_GIT_REVISION}" ]; then
BUILD_OPTS+=( \
"--build-arg" \
"Z3_SYSTEM_TEST_GIT_REVISION=${Z3_SYSTEM_TEST_GIT_REVISION}" \
)
fi
if [ -n "${RUN_UNIT_TESTS}" ]; then
BUILD_OPTS+=("--build-arg" "RUN_UNIT_TESTS=${RUN_UNIT_TESTS}")
fi
if [ -n "${Z3_VERBOSE_BUILD_OUTPUT}" ]; then
BUILD_OPTS+=( \
"--build-arg" \
"Z3_VERBOSE_BUILD_OUTPUT=${Z3_VERBOSE_BUILD_OUTPUT}" \
)
fi
if [ -n "${Z3_STATIC_BUILD}" ]; then
BUILD_OPTS+=("--build-arg" "Z3_STATIC_BUILD=${Z3_STATIC_BUILD}")
fi
if [ -n "${NO_SUPPRESS_OUTPUT}" ]; then
BUILD_OPTS+=( \
"--build-arg" \
"NO_SUPPRESS_OUTPUT=${NO_SUPPRESS_OUTPUT}" \
)
fi
if [ -n "${Z3_WARNINGS_AS_ERRORS}" ]; then
BUILD_OPTS+=( \
"--build-arg" \
"Z3_WARNINGS_AS_ERRORS=${Z3_WARNINGS_AS_ERRORS}" \
)
fi
case ${LINUX_BASE} in
ubuntu_14.04)
BASE_DOCKER_FILE="${DOCKER_FILE_DIR}/z3_base_ubuntu_14.04.Dockerfile"
BASE_DOCKER_IMAGE_NAME="z3_base_ubuntu:14.04"
;;
ubuntu_16.04)
BASE_DOCKER_FILE="${DOCKER_FILE_DIR}/z3_base_ubuntu_16.04.Dockerfile"
BASE_DOCKER_IMAGE_NAME="z3_base_ubuntu:16.04"
;;
ubuntu32_16.04)
BASE_DOCKER_FILE="${DOCKER_FILE_DIR}/z3_base_ubuntu32_16.04.Dockerfile"
BASE_DOCKER_IMAGE_NAME="z3_base_ubuntu32:16.04"
;;
*)
echo "Unknown Linux base ${LINUX_BASE}"
exit 1
;;
esac
# Initially assume that we need to build the base Docker image
MUST_BUILD=1
# Travis CI persistent cache.
#
# This inspired by http://rundef.com/fast-travis-ci-docker-build .
# The idea is to cache the built image for subsequent builds to
# reduce build time.
if [ -n "${DOCKER_TRAVIS_CI_CACHE_DIR}" ]; then
CHECKSUM_FILE="${DOCKER_TRAVIS_CI_CACHE_DIR}/${BASE_DOCKER_IMAGE_NAME}.chksum"
CACHED_DOCKER_IMAGE="${DOCKER_TRAVIS_CI_CACHE_DIR}/${BASE_DOCKER_IMAGE_NAME}.gz"
if [ -f "${CACHED_DOCKER_IMAGE}" ]; then
# There's a cached image to use. Check the checksums of the Dockerfile
# match. If they don't that implies we need to build a fresh image.
if [ -f "${CHECKSUM_FILE}" ]; then
CURRENT_DOCKERFILE_CHECKSUM=$(sha256sum "${BASE_DOCKER_FILE}" | awk '{ print $1 }')
CACHED_DOCKERFILE_CHECKSUM=$(cat "${CHECKSUM_FILE}")
if [ "X${CURRENT_DOCKERFILE_CHECKSUM}" = "X${CACHED_DOCKERFILE_CHECKSUM}" ]; then
# Load the cached image
MUST_BUILD=0
gunzip --stdout "${CACHED_DOCKER_IMAGE}" | docker load
fi
fi
fi
fi
if [ "${MUST_BUILD}" -eq 1 ]; then
# The base image contains all the dependencies we want to build
# Z3.
docker build -t "${BASE_DOCKER_IMAGE_NAME}" - < "${BASE_DOCKER_FILE}"
if [ -n "${DOCKER_TRAVIS_CI_CACHE_DIR}" ]; then
# Write image and checksum to cache
docker save "${BASE_DOCKER_IMAGE_NAME}" | \
gzip > "${CACHED_DOCKER_IMAGE}"
sha256sum "${BASE_DOCKER_FILE}" | awk '{ print $1 }' > \
"${CHECKSUM_FILE}"
fi
fi
DOCKER_MAJOR_VERSION=$(docker info --format '{{.ServerVersion}}' | sed 's/^\([0-9]\+\)\.\([0-9]\+\).*$/\1/')
DOCKER_MINOR_VERSION=$(docker info --format '{{.ServerVersion}}' | sed 's/^\([0-9]\+\)\.\([0-9]\+\).*$/\2/')
DOCKER_BUILD_FILE="${DOCKER_FILE_DIR}/z3_build.Dockerfile"
if [ "${DOCKER_MAJOR_VERSION}${DOCKER_MINOR_VERSION}" -lt 1705 ]; then
# Workaround limitation in older Docker versions where the FROM
# command cannot be parameterized with an ARG.
sed \
-e '/^ARG DOCKER_IMAGE_BASE/d' \
-e 's/${DOCKER_IMAGE_BASE}/'"${BASE_DOCKER_IMAGE_NAME}/" \
"${DOCKER_BUILD_FILE}" > "${DOCKER_BUILD_FILE}.patched"
DOCKER_BUILD_FILE="${DOCKER_BUILD_FILE}.patched"
else
# This feature landed in Docker 17.05
# See https://github.com/moby/moby/pull/31352
BUILD_OPTS+=( \
"--build-arg" \
"DOCKER_IMAGE_BASE=${BASE_DOCKER_IMAGE_NAME}" \
)
fi
# Now build Z3 and test it using the created base image
docker build \
-f "${DOCKER_BUILD_FILE}" \
"${BUILD_OPTS[@]}" \
.

View file

@ -0,0 +1,10 @@
#!/bin/bash
SCRIPT_DIR="$( cd ${BASH_SOURCE[0]%/*} ; echo $PWD )"
set -x
set -e
set -o pipefail
echo "Not implemented"
exit 1

View file

@ -1,25 +1,13 @@
#!/usr/bin/env python
"""
This script is used to copy or delete the
CMake build system files from the contrib/cmake
folder into the their correct location in the Z3
repository.
This script is an artifact of compromise that was
made when the CMake build system was first introduced
(see #461).
It offers two modes
* create - This will symlink the ``cmake`` directory and copy (or hard link)
the appropriate files into their correct locations in the repository.
* remove - This will remove the symlinked ``cmake``
directory and remove the files added by the above
methods.
This has the advantage
that editing the hard link edits the underlying file
(making development easier because copying files is
not neccessary) and CMake will regenerate correctly
because the modification time stamps will be correct.
This script now does nothing. It remains only to not
break out-of-tree scripts that build Z3 using CMake.
Eventually this script will be removed.
"""
import argparse
import logging
@ -28,189 +16,6 @@ import pprint
import shutil
import sys
def get_full_path_to_script():
return os.path.abspath(__file__)
def get_cmake_contrib_dir():
return os.path.dirname(get_full_path_to_script())
def get_repo_root_dir():
r = os.path.dirname(os.path.dirname(get_cmake_contrib_dir()))
assert os.path.isdir(r)
return r
# These are paths that should be ignored when checking if a folder
# in the ``contrib/cmake`` exists in the root of the repository
verificationExceptions = {
os.path.join(get_repo_root_dir(), 'cmake'),
os.path.join(get_repo_root_dir(), 'cmake', 'modules')
}
def contribPathToRepoPath(path):
assert path.startswith(get_cmake_contrib_dir())
stripped = path[len(get_cmake_contrib_dir()) + 1:] # Plus one is to remove leading slash
assert not os.path.isabs(stripped)
logging.debug('stripped:{}'.format(stripped))
r = os.path.join(get_repo_root_dir(), stripped)
assert os.path.isabs(r)
logging.debug('Converted contrib path "{}" to repo path "{}"'.format(path, r))
return r
def verify_mirrored_directory_struture():
"""
Check that the directories contained in ``contrib/cmake`` exist
in the root of the repo.
"""
for (dirpath, _, _) in os.walk(get_cmake_contrib_dir()):
expectedDir = contribPathToRepoPath(dirpath)
logging.debug('expectedDir:{}'.format(expectedDir))
if (not (os.path.exists(expectedDir) and os.path.isdir(expectedDir)) and
expectedDir not in verificationExceptions):
logging.error(('Expected to find directory "{}" but it does not exist'
' or is not a directory').format(expectedDir))
return 1
return 0
def mk_sym_link(target, linkName):
logging.info('Making symbolic link target="{}", linkName="{}"'.format(target, linkName))
if os.path.exists(linkName):
logging.info('Removing existing link "{}"'.format(linkName))
if not os.path.islink(linkName):
logging.warning('"{}" overwriting file that is not a symlink'.format(linkName))
delete_path(linkName)
if os.name == 'posix':
os.symlink(target, linkName)
else:
# TODO: Windows does support symlinks but the implementation to do that
# from python is a little complicated so for now lets just copy everyting
logging.warning('Creating symbolic links is not supported. Just making a copy instead')
if os.path.isdir(target):
# Recursively copy directory
shutil.copytree(src=target, dst=linkName, symlinks=False)
else:
# Copy file
assert os.path.isfile(target)
shutil.copy2(src=target, dst=linkName)
def delete_path(path):
logging.info('Removing "{}"'.format(path))
if not os.path.exists(path):
logging.warning('"{}" does not exist'.format(path))
return
if os.path.isdir(path) and not os.path.islink(path):
# FIXME: If we can get symbolic link support on Windows we
# can disallow this completely.
assert os.name == 'nt'
shutil.rmtree(path)
else:
os.remove(path)
def shouldSkipFile(path):
# Skip this script
if path == get_full_path_to_script():
return True
# Skip the maintainers file
if path == os.path.join(get_cmake_contrib_dir(), 'maintainers.txt'):
return True
# Skip Vim temporary files
if os.path.basename(path).startswith('.') and path.endswith('.swp'):
return True
return False
def create(useHardLinks):
"""
Copy or hard link files in the CMake contrib directory
into the repository where they are intended to live.
Note that symbolic links for the CMakeLists.txt files
are not appropriate because they won't have the right
file modification time when the files they point to
are modified. This would prevent CMake from correctly
reconfiguring when it detects this is required.
"""
# Make the ``cmake`` directory a symbolic link.
# We treat this one specially as it is the only directory
# that doesn't already exist in the repository root so
# we can just use a symlink here
linkName = os.path.join(get_repo_root_dir(), 'cmake')
target = os.path.join(get_cmake_contrib_dir(), 'cmake')
specialDir = target
mk_sym_link(target, linkName)
for (dirPath,_ , fileNames) in os.walk(get_cmake_contrib_dir()):
# Skip the special directory and its children
if dirPath.startswith(specialDir):
logging.info('Skipping directory "{}"'.format(dirPath))
continue
for fileName in fileNames:
fileInContrib = os.path.join(dirPath, fileName)
# Skip files
if shouldSkipFile(fileInContrib):
logging.info('Skipping "{}"'.format(fileInContrib))
continue
fileInRepo = contribPathToRepoPath(fileInContrib)
logging.info('"{}" => "{}"'.format(fileInContrib, fileInRepo))
if useHardLinks:
if not os.name == 'posix':
logging.error('Hard links are not supported on your platform')
return False
if os.path.exists(fileInRepo):
delete_path(fileInRepo)
os.link(fileInContrib, fileInRepo)
else:
try:
shutil.copy2(src=fileInContrib, dst=fileInRepo)
except shutil.Error as e:
# Can hit this if used created hard links first and then run again without
# wanting hard links
if sys.version_info.major <= 2:
logging.error(e.message)
else:
# Python >= 3
if isinstance(e, shutil.SameFileError):
logging.error('Trying to copy "{}" to "{}" but they are the same file'.format(
fileInContrib, fileInRepo))
else:
logging.error(e)
logging.error('You should remove the files using the "remove" mode '
'and try to create again. You probably are mixing the '
'hard-link and non-hard-link create modes')
return False
return True
def remove():
"""
Remove the CMake files from their intended location in
the repository. This is used to remove
the files created by the ``create()`` function.
"""
# This directory is treated specially as it is normally
# a symlink.
linkName = os.path.join(get_repo_root_dir(), 'cmake')
delete_path(linkName)
specialDir = os.path.join(get_cmake_contrib_dir(), 'cmake')
for (dirPath,_ , fileNames) in os.walk(get_cmake_contrib_dir()):
# Skip the special directory and its children
if dirPath.startswith(specialDir):
logging.info('Skipping directory "{}"'.format(dirPath))
continue
for fileName in fileNames:
fileInContrib = os.path.join(dirPath, fileName)
# Skip files
if shouldSkipFile(fileInContrib):
logging.info('Skipping "{}"'.format(fileInContrib))
continue
fileInRepo = contribPathToRepoPath(fileInContrib)
if os.path.exists(fileInRepo):
logging.info('Removing "{}"'.format(fileInRepo))
delete_path(fileInRepo)
return True
def main(args):
logging.basicConfig(level=logging.INFO)
parser = argparse.ArgumentParser(description=__doc__)
@ -233,28 +38,10 @@ def main(args):
logLevel = getattr(logging, pargs.log_level.upper(),None)
logging.basicConfig(level=logLevel)
# Before we start make sure we can transplant the CMake files on to
# repository
if verify_mirrored_directory_struture() != 0:
logging.error('"{}" does not mirror "{}"'.format(get_cmake_contrib_dir(), get_repo_root_dir()))
return 1
if pargs.mode == "create":
if not create(useHardLinks=pargs.hard_link):
logging.error("Failed to create")
return 1
elif pargs.mode == "create_hard_link":
if not create(useHardLinks=True):
logging.error("Failed to create_hard_link")
return 1
elif pargs.mode == "remove":
if not remove():
logging.error("Failed to remove")
return 1
else:
logging.error('Unknown mode "{}"'.format(pargs.mode))
logging.warning('Use of this script is deprecated. The script will be removed in the future')
logging.warning('Action "{}" ignored'.format(pargs.mode))
if pargs.hard_link:
logging.warning('Hard link option ignored')
return 0
if __name__ == '__main__':

View file

@ -1,54 +0,0 @@
set(GCC_AND_CLANG_WARNINGS
"-Wall"
)
set(GCC_ONLY_WARNINGS "")
set(CLANG_ONLY_WARNINGS "")
set(MSVC_WARNINGS "/W3")
set(WARNING_FLAGS_TO_CHECK "")
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
list(APPEND WARNING_FLAGS_TO_CHECK ${GCC_AND_CLANG_WARNINGS})
list(APPEND WARNING_FLAGS_TO_CHECK ${GCC_ONLY_WARNINGS})
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
list(APPEND WARNING_FLAGS_TO_CHECK ${GCC_AND_CLANG_WARNINGS})
list(APPEND WARNING_FLAGS_TO_CHECK ${CLANG_ONLY_WARNINGS})
# FIXME: Remove "x.." when CMP0054 is set to NEW
elseif ("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC")
list(APPEND WARNING_FLAGS_TO_CHECK ${MSVC_WARNINGS})
# CMake's default flags include /W3 already so remove them if
# they already exist.
if ("${CMAKE_CXX_FLAGS}" MATCHES "/W3")
string(REPLACE "/W3" "" _cmake_cxx_flags_remove_w3 "${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS "${_cmake_cxx_flags_remove_w3}" CACHE STRING "" FORCE)
endif()
else()
message(AUTHOR_WARNING "Unknown compiler")
endif()
# Loop through flags and use the ones which the compiler supports
foreach (flag ${WARNING_FLAGS_TO_CHECK})
z3_add_cxx_flag("${flag}")
endforeach()
option(WARNINGS_AS_ERRORS "Treat compiler warnings as errors" OFF)
if (WARNINGS_AS_ERRORS)
if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU"))
list(APPEND Z3_COMPONENT_CXX_FLAGS "-Werror")
# FIXME: Remove "x.." when CMP0054 is set to NEW
elseif ("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC")
list(APPEND Z3_COMPONENT_CXX_FLAGS "/WX")
else()
message(AUTHOR_WARNING "Unknown compiler")
endif()
message(STATUS "Treating compiler warnings as errors")
else()
message(STATUS "Not treating compiler warnings as errors")
# FIXME: Remove "x.." when CMP0054 is set to NEW
if ("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC")
# Warnings as errors is off by default for MSVC so setting this
# is not necessary but this duplicates the behaviour of the old
# build system.
list(APPEND Z3_COMPONENT_CXX_FLAGS "/WX-")
endif()
endif()

View file

@ -4,9 +4,7 @@
Z3 is a high-performance theorem prover being developed at <a class="el"
href="http://research.microsoft.com">Microsoft Research</a>.
<b>The Z3 website moved to <a class="el" href="http://github.com/z3prover">http://github.com/z3prover.</a>.</b>
The old Z3 websites can be found <a class="el" href="http://research.microsoft.com/en-us/um/redmond/projects/z3/old/index.html">here</a> and <a href="http://z3.codeplex.com">here</a>.
<b>The Z3 website is at <a class="el" href="http://github.com/z3prover">http://github.com/z3prover.</a>.</b>
This website hosts the automatically generated documentation for the Z3 APIs.

View file

@ -704,10 +704,13 @@ INPUT_ENCODING = UTF-8
FILE_PATTERNS = website.dox \
z3_api.h \
z3_algebraic.h \
z3_ast_containers.h \
z3_fixedpoint.h \
z3_fpa.h \
z3_interp.h \
z3_optimization.h \
z3_polynomial.h \
z3_rcf.h \
z3_interp.h \
z3_fpa.h \
z3++.h \
@PYTHON_API_FILES@ @DOTNET_API_FILES@ @JAVA_API_FILES@

View file

@ -23,6 +23,22 @@ ExternalProject_Add(c_example
)
set_target_properties(c_example PROPERTIES EXCLUDE_FROM_ALL TRUE)
################################################################################
# Build maxsat example project using libz3's C API as an external project
################################################################################
ExternalProject_Add(c_maxsat_example
DEPENDS libz3
# Configure step
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/maxsat"
CMAKE_ARGS "-DZ3_DIR=${CMAKE_BINARY_DIR}"
# Build step
${EXTERNAL_PROJECT_BUILD_ALWAYS_ARG}
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/c_maxsat_example_build_dir"
# Install Step
INSTALL_COMMAND "${CMAKE_COMMAND}" -E echo "" # Dummy command
)
set_target_properties(c_maxsat_example PROPERTIES EXCLUDE_FROM_ALL TRUE)
################################################################################
# Build example project using libz3's C++ API as an external project

View file

@ -2152,6 +2152,31 @@ namespace test_mapi
Console.WriteLine("OK, model: {0}", s.Model.ToString());
}
public static void TranslationExample()
{
Context ctx1 = new Context();
Context ctx2 = new Context();
Sort s1 = ctx1.IntSort;
Sort s2 = ctx2.IntSort;
Sort s3 = s1.Translate(ctx2);
Console.WriteLine(s1 == s2);
Console.WriteLine(s1.Equals(s2));
Console.WriteLine(s2.Equals(s3));
Console.WriteLine(s1.Equals(s3));
Expr e1 = ctx1.MkIntConst("e1");
Expr e2 = ctx2.MkIntConst("e1");
Expr e3 = e1.Translate(ctx2);
Console.WriteLine(e1 == e2);
Console.WriteLine(e1.Equals(e2));
Console.WriteLine(e2.Equals(e3));
Console.WriteLine(e1.Equals(e3));
}
static void Main(string[] args)
{
try
@ -2225,6 +2250,8 @@ namespace test_mapi
QuantifierExample4(ctx);
}
TranslationExample();
Log.Close();
if (Log.isOpen())
Console.WriteLine("Log is still open!");

View file

@ -281,7 +281,7 @@ class JavaExample
}
void disprove(Context ctx, BoolExpr f, boolean useMBQI)
throws TestFailedException
throws TestFailedException
{
BoolExpr[] a = {};
disprove(ctx, f, useMBQI, a);
@ -2279,6 +2279,29 @@ class JavaExample
System.out.println(my);
}
public void translationExample() {
Context ctx1 = new Context();
Context ctx2 = new Context();
Sort s1 = ctx1.getIntSort();
Sort s2 = ctx2.getIntSort();
Sort s3 = s1.translate(ctx2);
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
System.out.println(s2.equals(s3));
System.out.println(s1.equals(s3));
Expr e1 = ctx1.mkIntConst("e1");
Expr e2 = ctx2.mkIntConst("e1");
Expr e3 = e1.translate(ctx2);
System.out.println(e1 == e2);
System.out.println(e1.equals(e2));
System.out.println(e2.equals(e3));
System.out.println(e1.equals(e3));
}
public static void main(String[] args)
{
JavaExample p = new JavaExample();
@ -2300,8 +2323,8 @@ class JavaExample
HashMap<String, String> cfg = new HashMap<String, String>();
cfg.put("model", "true");
Context ctx = new Context(cfg);
p.optimizeExample(ctx);
p.optimizeExample(ctx);
p.basicTests(ctx);
p.castingTest(ctx);
p.sudokuExample(ctx);
@ -2355,7 +2378,9 @@ class JavaExample
Context ctx = new Context(cfg);
p.quantifierExample3(ctx);
p.quantifierExample4(ctx);
}
}
p.translationExample();
Log.close();
if (Log.isOpen())

View file

@ -0,0 +1,42 @@
################################################################################
# Example maxsat project
################################################################################
# NOTE: Even though this is a C project, libz3 uses C++. When using libz3
# as a static library if we don't configure this project to also support
# C++ we will use the C linker rather than the C++ linker and will not link
# the C++ standard library in resulting in a link failure.
project(Z3_C_MAXSAT_EXAMPLE C CXX)
cmake_minimum_required(VERSION 2.8.12)
find_package(Z3
REQUIRED
CONFIG
# `NO_DEFAULT_PATH` is set so that -DZ3_DIR has to be passed to find Z3.
# This should prevent us from accidently picking up an installed
# copy of Z3. This is here to benefit Z3's build sytem when building
# this project. When making your own project you probably shouldn't
# use this option.
NO_DEFAULT_PATH
)
message(STATUS "Z3_FOUND: ${Z3_FOUND}")
message(STATUS "Found Z3 ${Z3_VERSION_STRING}")
message(STATUS "Z3_DIR: ${Z3_DIR}")
add_executable(c_maxsat_example maxsat.c)
target_include_directories(c_maxsat_example PRIVATE ${Z3_C_INCLUDE_DIRS})
target_link_libraries(c_maxsat_example PRIVATE ${Z3_LIBRARIES})
if ("${CMAKE_SYSTEM_NAME}" MATCHES "[Ww]indows")
# On Windows we need to copy the Z3 libraries
# into the same directory as the executable
# so that they can be found.
foreach (z3_lib ${Z3_LIBRARIES})
message(STATUS "Adding copy rule for ${z3_lib}")
add_custom_command(TARGET c_maxsat_example
POST_BUILD
COMMAND
${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:${z3_lib}>
$<TARGET_FILE_DIR:c_maxsat_example>
)
endforeach()
endif()

View file

@ -348,7 +348,15 @@ void assert_at_most_k(Z3_context ctx, Z3_solver s, unsigned n, Z3_ast * lits, un
*/
void assert_at_most_one(Z3_context ctx, Z3_solver s, unsigned n, Z3_ast * lits)
{
assert_at_most_k(ctx, s, n, lits, 1);
assert_at_most_k(ctx, s, n, lits, 1);
}
Z3_solver mk_solver(Z3_context ctx)
{
Z3_solver r = Z3_mk_solver(ctx);
Z3_solver_inc_ref(ctx, r);
return r;
}
/**
@ -357,7 +365,7 @@ void assert_at_most_one(Z3_context ctx, Z3_solver s, unsigned n, Z3_ast * lits)
void tst_at_most_one()
{
Z3_context ctx = mk_context();
Z3_solver s = Z3_mk_solver(ctx);
Z3_solver s = mk_solver(ctx);
Z3_ast k1 = mk_bool_var(ctx, "k1");
Z3_ast k2 = mk_bool_var(ctx, "k2");
Z3_ast k3 = mk_bool_var(ctx, "k3");
@ -376,7 +384,9 @@ void tst_at_most_one()
if (result != Z3_L_TRUE)
error("BUG");
m = Z3_solver_get_model(ctx, s);
Z3_model_inc_ref(ctx, m);
printf("model:\n%s\n", Z3_model_to_string(ctx, m));
Z3_model_dec_ref(ctx, m);
Z3_solver_assert(ctx, s, mk_binary_or(ctx, k2, k3));
Z3_solver_assert(ctx, s, mk_binary_or(ctx, k1, k6));
printf("it must be sat...\n");
@ -384,12 +394,15 @@ void tst_at_most_one()
if (result != Z3_L_TRUE)
error("BUG");
m = Z3_solver_get_model(ctx, s);
Z3_model_inc_ref(ctx, m);
printf("model:\n%s\n", Z3_model_to_string(ctx, m));
Z3_solver_assert(ctx, s, mk_binary_or(ctx, k4, k5));
printf("it must be unsat...\n");
result = Z3_solver_check(ctx, s);
if (result != Z3_L_FALSE)
error("BUG");
Z3_model_dec_ref(ctx, m);
Z3_solver_dec_ref(ctx, s);
Z3_del_context(ctx);
}
@ -454,8 +467,10 @@ int naive_maxsat(Z3_context ctx, Z3_solver s, unsigned num_hard_cnstrs, Z3_ast *
printf("unsat\n");
return num_soft_cnstrs - k - 1;
}
m = Z3_solver_get_model(ctx, s);
m = Z3_solver_get_model(ctx, s);
Z3_model_inc_ref(ctx, m);
num_disabled = get_num_disabled_soft_constraints(ctx, m, num_soft_cnstrs, aux_vars);
Z3_model_dec_ref(ctx, m);
if (num_disabled > k) {
error("BUG");
}
@ -506,6 +521,7 @@ int fu_malik_maxsat_step(Z3_context ctx, Z3_solver s, unsigned num_soft_cnstrs,
}
else {
core = Z3_solver_get_unsat_core(ctx, s);
Z3_ast_vector_inc_ref(ctx, core);
core_size = Z3_ast_vector_size(ctx, core);
block_vars = (Z3_ast*) malloc(sizeof(Z3_ast) * core_size);
k = 0;
@ -514,7 +530,7 @@ int fu_malik_maxsat_step(Z3_context ctx, Z3_solver s, unsigned num_soft_cnstrs,
unsigned j;
// check whether assumption[i] is in the core or not
for (j = 0; j < core_size; j++) {
if (assumptions[i] == Z3_ast_vector_get(ctx, core, j))
if (assumptions[i] == Z3_ast_vector_get(ctx, core, j))
break;
}
if (j < core_size) {
@ -531,6 +547,7 @@ int fu_malik_maxsat_step(Z3_context ctx, Z3_solver s, unsigned num_soft_cnstrs,
}
}
assert_at_most_one(ctx, s, k, block_vars);
Z3_ast_vector_dec_ref(ctx, core);
return 0; // not done.
}
}
@ -597,7 +614,7 @@ int smtlib_maxsat(char * file_name, int approach)
Z3_ast * hard_cnstrs, * soft_cnstrs;
unsigned result = 0;
ctx = mk_context();
s = Z3_mk_solver(ctx);
s = mk_solver(ctx);
Z3_parse_smtlib_file(ctx, file_name, 0, 0, 0, 0, 0, 0);
hard_cnstrs = get_hard_constraints(ctx, &num_hard_cnstrs);
soft_cnstrs = get_soft_constraints(ctx, &num_soft_cnstrs);
@ -615,6 +632,7 @@ int smtlib_maxsat(char * file_name, int approach)
}
free_cnstr_array(hard_cnstrs);
free_cnstr_array(soft_cnstrs);
Z3_solver_dec_ref(ctx, s);
return result;
}

View file

@ -1,5 +1,11 @@
set(python_example_files
all_interval_series.py
complex/complex.py
example.py
hamiltonian/hamiltonian.py
mus/marco.py
mus/mss.py
socrates.py
visitor.py
)
@ -10,7 +16,10 @@ foreach (example_file ${python_example_files})
add_custom_command(OUTPUT "${z3py_bindings_build_dest}/${example_file}"
COMMAND "${CMAKE_COMMAND}" "-E" "copy"
"${CMAKE_CURRENT_SOURCE_DIR}/${example_file}"
"${z3py_bindings_build_dest}/${example_file}"
# We flatten the hierarchy so that all python files have
# the `z3` directory in their directory so that their import
# statements "just work".
"${z3py_bindings_build_dest}/"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${example_file}"
COMMENT "Copying \"${example_file}\" to ${z3py_bindings_build_dest}/${example_file}"
)

View file

@ -4,7 +4,7 @@
# adjacent entries fall in the range 0,..,n-1
# This is known as the "The All-Interval Series Problem"
# See http://www.csplib.org/Problems/prob007/
from __future__ import print_function
from z3 import *
import time
@ -56,7 +56,7 @@ def process_model(s, xij, n):
block += [xij[i][j]]
k = j
values += [k]
print values
print(values)
sys.stdout.flush()
return block
@ -68,9 +68,9 @@ def all_models(n):
block = process_model(s, xij, n)
s.add(Not(And(block)))
count += 1
print s.statistics()
print time.clock() - start
print count
print(s.statistics())
print(time.clock() - start)
print(count)
set_option(verbose=1)
all_models(12)

View file

@ -6,6 +6,10 @@
#
# Author: Leonardo de Moura (leonardo)
############################################
from __future__ import print_function
import sys
if sys.version_info.major >= 3:
from functools import reduce
from z3 import *
def _to_complex(a):
@ -53,7 +57,7 @@ class ComplexExpr:
return self
if k < 0:
return (self ** (-k)).inv()
return reduce(lambda x, y: x * y, [self for _ in xrange(k)], ComplexExpr(1, 0))
return reduce(lambda x, y: x * y, [self for _ in range(k)], ComplexExpr(1, 0))
def inv(self):
den = self.r*self.r + self.i*self.i
@ -63,6 +67,12 @@ class ComplexExpr:
inv_other = _to_complex(other).inv()
return self.__mul__(inv_other)
if sys.version_info.major >= 3:
# In python 3 the meaning of the '/' operator
# was changed.
def __truediv__(self, other):
return self.__div__(other)
def __rdiv__(self, other):
other = _to_complex(other)
return self.inv().__mul__(other)
@ -113,5 +123,5 @@ print(s.model())
s.add(x.i != 1)
print(s.check())
# print(s.model())
print ((3 + I) ** 2)/(5 - I)
print ((3 + I) ** -3)/(5 - I)
print(((3 + I) ** 2)/(5 - I))
print(((3 + I) ** -3)/(5 - I))

View file

@ -45,11 +45,6 @@ def enumerate_sets(solver):
else:
break
class CompareSetSize():
def __call__(self, s1, s2):
return len(s1) < len(s2)
class MSSSolver:
s = Solver()
varcache = {}
@ -157,7 +152,7 @@ class MSSSolver:
mcs = [x for x in self.orig_soft_vars if not is_true(self.model[x])]
self.s.add(Or(mcs))
core_literals = set([])
cores.sort(CompareSetSize())
cores.sort(key=lambda element: len(element))
for core in cores:
if len(core & core_literals) == 0:
self.relax_core(core)

View file

@ -1,5 +1,5 @@
# Copyright (c) Microsoft Corporation 2015
from __future__ import print_function
from z3 import *
def visitor(e, seen):
@ -22,8 +22,8 @@ fml = x + x + y > 2
seen = {}
for e in visitor(fml, seen):
if is_const(e) and e.decl().kind() == Z3_OP_UNINTERPRETED:
print "Variable", e
print("Variable", e)
else:
print e
print(e)

View file

@ -587,7 +587,7 @@ def mk_def_file_internal(defname, dll_name, export_header_files):
###############################################################################
# Functions for generating ``gparams_register_modules.cpp``
###############################################################################
def mk_gparams_register_modules_internal(component_src_dirs, path):
def mk_gparams_register_modules_internal(h_files_full_path, path):
"""
Generate a ``gparams_register_modules.cpp`` file in the directory ``path``.
Returns the path to the generated file.
@ -600,7 +600,7 @@ def mk_gparams_register_modules_internal(component_src_dirs, path):
This procedure is invoked by gparams::init()
"""
assert isinstance(component_src_dirs, list)
assert isinstance(h_files_full_path, list)
assert check_dir_exists(path)
cmds = []
mod_cmds = []
@ -612,11 +612,6 @@ def mk_gparams_register_modules_internal(component_src_dirs, path):
reg_pat = re.compile('[ \t]*REG_PARAMS\(\'([^\']*)\'\)')
reg_mod_pat = re.compile('[ \t]*REG_MODULE_PARAMS\(\'([^\']*)\', *\'([^\']*)\'\)')
reg_mod_descr_pat = re.compile('[ \t]*REG_MODULE_DESCRIPTION\(\'([^\']*)\', *\'([^\']*)\'\)')
h_files_full_path = []
for component_src_dir in component_src_dirs:
h_files = filter(lambda f: f.endswith('.h') or f.endswith('.hpp'), os.listdir(component_src_dir))
h_files = list(map(lambda p: os.path.join(component_src_dir, p), h_files))
h_files_full_path.extend(h_files)
for h_file in sorted_headers_by_component(h_files_full_path):
added_include = False
with open(h_file, 'r') as fin:
@ -651,7 +646,7 @@ def mk_gparams_register_modules_internal(component_src_dirs, path):
# Functions/data structures for generating ``install_tactics.cpp``
###############################################################################
def mk_install_tactic_cpp_internal(component_src_dirs, path):
def mk_install_tactic_cpp_internal(h_files_full_path, path):
"""
Generate a ``install_tactics.cpp`` file in the directory ``path``.
Returns the path the generated file.
@ -662,9 +657,10 @@ def mk_install_tactic_cpp_internal(component_src_dirs, path):
void install_tactics(tactic_manager & ctx)
```
It installs all tactics found in the given component directories
``component_src_dirs`` The procedure looks for ``ADD_TACTIC`` commands
in the ``.h`` and ``.hpp`` files of these components.
It installs all tactics declared in the given header files
``h_files_full_path`` The procedure looks for ``ADD_TACTIC`` and
``ADD_PROBE``commands in the ``.h`` and ``.hpp`` files of these
components.
"""
ADD_TACTIC_DATA = []
ADD_PROBE_DATA = []
@ -679,7 +675,7 @@ def mk_install_tactic_cpp_internal(component_src_dirs, path):
'ADD_PROBE': ADD_PROBE,
}
assert isinstance(component_src_dirs, list)
assert isinstance(h_files_full_path, list)
assert check_dir_exists(path)
fullname = os.path.join(path, 'install_tactic.cpp')
fout = open(fullname, 'w')
@ -689,11 +685,6 @@ def mk_install_tactic_cpp_internal(component_src_dirs, path):
fout.write('#include"cmd_context.h"\n')
tactic_pat = re.compile('[ \t]*ADD_TACTIC\(.*\)')
probe_pat = re.compile('[ \t]*ADD_PROBE\(.*\)')
h_files_full_path = []
for component_src_dir in sorted(component_src_dirs):
h_files = filter(lambda f: f.endswith('.h') or f.endswith('.hpp'), os.listdir(component_src_dir))
h_files = list(map(lambda p: os.path.join(component_src_dir, p), h_files))
h_files_full_path.extend(h_files)
for h_file in sorted_headers_by_component(h_files_full_path):
added_include = False
with open(h_file, 'r') as fin:
@ -740,7 +731,7 @@ def mk_install_tactic_cpp_internal(component_src_dirs, path):
# Functions for generating ``mem_initializer.cpp``
###############################################################################
def mk_mem_initializer_cpp_internal(component_src_dirs, path):
def mk_mem_initializer_cpp_internal(h_files_full_path, path):
"""
Generate a ``mem_initializer.cpp`` file in the directory ``path``.
Returns the path to the generated file.
@ -754,7 +745,7 @@ def mk_mem_initializer_cpp_internal(component_src_dirs, path):
These procedures are invoked by the Z3 memory_manager
"""
assert isinstance(component_src_dirs, list)
assert isinstance(h_files_full_path, list)
assert check_dir_exists(path)
initializer_cmds = []
finalizer_cmds = []
@ -765,11 +756,6 @@ def mk_mem_initializer_cpp_internal(component_src_dirs, path):
# ADD_INITIALIZER with priority
initializer_prio_pat = re.compile('[ \t]*ADD_INITIALIZER\(\'([^\']*)\',[ \t]*(-?[0-9]*)\)')
finalizer_pat = re.compile('[ \t]*ADD_FINALIZER\(\'([^\']*)\'\)')
h_files_full_path = []
for component_src_dir in sorted(component_src_dirs):
h_files = filter(lambda f: f.endswith('.h') or f.endswith('.hpp'), os.listdir(component_src_dir))
h_files = list(map(lambda p: os.path.join(component_src_dir, p), h_files))
h_files_full_path.extend(h_files)
for h_file in sorted_headers_by_component(h_files_full_path):
added_include = False
with open(h_file, 'r') as fin:

View file

@ -1,10 +1,8 @@
#!/usr/bin/env python
"""
Determines the available global parameters
in header files in the list of source directions
and generates a ``gparams_register_modules.cpp`` file in
the destination directory that defines a function
``void gparams_register_modules()``.
Determines the available global parameters from a list of header files and
generates a ``gparams_register_modules.cpp`` file in the destination directory
that defines a function ``void gparams_register_modules()``.
"""
import mk_genfile_common
import argparse
@ -16,19 +14,22 @@ def main(args):
logging.basicConfig(level=logging.INFO)
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("destination_dir", help="destination directory")
parser.add_argument("source_dirs", nargs="+",
help="One or more source directories to search")
parser.add_argument("header_files", nargs="+",
help="One or more header files to parse")
pargs = parser.parse_args(args)
if not mk_genfile_common.check_dir_exists(pargs.destination_dir):
return 1
for source_dir in pargs.source_dirs:
if not mk_genfile_common.check_dir_exists(source_dir):
return 1
if not mk_genfile_common.check_files_exist(pargs.header_files):
return 1
h_files_full_path = []
for header_file in pargs.header_files:
h_files_full_path.append(os.path.abspath(header_file))
output = mk_genfile_common.mk_gparams_register_modules_internal(
pargs.source_dirs,
h_files_full_path,
pargs.destination_dir
)
logging.info('Generated "{}"'.format(output))

View file

@ -1,10 +1,8 @@
#!/usr/bin/env python
"""
Determines the available tactics
in header files in the list of source directions
and generates a ``install_tactic.cpp`` file in
the destination directory that defines a function
``void install_tactics(tactic_manager& ctx)``.
Determines the available tactics from a list of header files and generates a
``install_tactic.cpp`` file in the destination directory that defines a
function ``void install_tactics(tactic_manager& ctx)``.
"""
import mk_genfile_common
import argparse
@ -16,19 +14,22 @@ def main(args):
logging.basicConfig(level=logging.INFO)
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("destination_dir", help="destination directory")
parser.add_argument("source_dirs", nargs="+",
help="One or more source directories to search")
parser.add_argument("header_files", nargs="+",
help="One or more header files to parse")
pargs = parser.parse_args(args)
if not mk_genfile_common.check_dir_exists(pargs.destination_dir):
return 1
for source_dir in pargs.source_dirs:
if not mk_genfile_common.check_dir_exists(source_dir):
return 1
if not mk_genfile_common.check_files_exist(pargs.header_files):
return 1
h_files_full_path = []
for header_file in pargs.header_files:
h_files_full_path.append(os.path.abspath(header_file))
output = mk_genfile_common.mk_install_tactic_cpp_internal(
pargs.source_dirs,
h_files_full_path,
pargs.destination_dir
)
logging.info('Generated "{}"'.format(output))

View file

@ -1,6 +1,6 @@
#!/usr/bin/env python
"""
Scans the source directories for
Scans the listed header files for
memory initializers and finalizers and
emits and implementation of
``void mem_initialize()`` and
@ -17,19 +17,19 @@ def main(args):
logging.basicConfig(level=logging.INFO)
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("destination_dir", help="destination directory")
parser.add_argument("source_dirs", nargs="+",
help="One or more source directories to search")
parser.add_argument("header_files", nargs="+",
help="One or more header files to parse")
pargs = parser.parse_args(args)
if not mk_genfile_common.check_dir_exists(pargs.destination_dir):
return 1
for source_dir in pargs.source_dirs:
if not mk_genfile_common.check_dir_exists(source_dir):
return 1
h_files_full_path = []
for header_file in pargs.header_files:
h_files_full_path.append(os.path.abspath(header_file))
output = mk_genfile_common.mk_mem_initializer_cpp_internal(
pargs.source_dirs,
h_files_full_path,
pargs.destination_dir
)
logging.info('Generated "{}"'.format(output))

View file

@ -104,6 +104,8 @@ GIT_DESCRIBE=False
SLOW_OPTIMIZE=False
USE_OMP=True
LOG_SYNC=False
GUARD_CF=False
ALWAYS_DYNAMIC_BASE=False
FPMATH="Default"
FPMATH_FLAGS="-mfpmath=sse -msse -msse2"
@ -623,13 +625,13 @@ def display_help(exit_code):
print(" -d, --debug compile Z3 in debug mode.")
print(" -t, --trace enable tracing in release mode.")
if IS_WINDOWS:
print(" --guardcf enable Control Flow Guard runtime checks.")
print(" -x, --x64 create 64 binary when using Visual Studio.")
else:
print(" --x86 force 32-bit x86 build on x64 systems.")
print(" -m, --makefiles generate only makefiles.")
if IS_WINDOWS:
print(" -v, --vsproj generate Visual Studio Project Files.")
if IS_WINDOWS:
print(" --optimize generate optimized code during linking.")
print(" --dotnet generate .NET bindings.")
print(" --dotnet-key=<file> sign the .NET assembly using the private key in <file>.")
@ -670,10 +672,11 @@ def parse_options():
global VERBOSE, DEBUG_MODE, IS_WINDOWS, VS_X64, ONLY_MAKEFILES, SHOW_CPPS, VS_PROJ, TRACE, VS_PAR, VS_PAR_NUM
global DOTNET_ENABLED, DOTNET_KEY_FILE, JAVA_ENABLED, ML_ENABLED, STATIC_LIB, STATIC_BIN, PREFIX, GMP, PYTHON_PACKAGE_DIR, GPROF, GIT_HASH, GIT_DESCRIBE, PYTHON_INSTALL_ENABLED, PYTHON_ENABLED
global LINUX_X64, SLOW_OPTIMIZE, USE_OMP, LOG_SYNC
global GUARD_CF, ALWAYS_DYNAMIC_BASE
try:
options, remainder = getopt.gnu_getopt(sys.argv[1:],
'b:df:sxhmcvtnp:gj',
['build=', 'debug', 'silent', 'x64', 'help', 'makefiles', 'showcpp', 'vsproj',
['build=', 'debug', 'silent', 'x64', 'help', 'makefiles', 'showcpp', 'vsproj', 'guardcf',
'trace', 'dotnet', 'dotnet-key=', 'staticlib', 'prefix=', 'gmp', 'java', 'parallel=', 'gprof',
'githash=', 'git-describe', 'x86', 'ml', 'optimize', 'noomp', 'pypkgdir=', 'python', 'staticbin', 'log-sync'])
except:
@ -742,6 +745,9 @@ def parse_options():
elif opt in ('--python'):
PYTHON_ENABLED = True
PYTHON_INSTALL_ENABLED = True
elif opt == '--guardcf':
GUARD_CF = True
ALWAYS_DYNAMIC_BASE = True # /GUARD:CF requires /DYNAMICBASE
else:
print("ERROR: Invalid command line option '%s'" % opt)
display_help(1)
@ -2310,6 +2316,7 @@ def mk_config():
'SLINK_OUT_FLAG=/Fe\n'
'OS_DEFINES=/D _WINDOWS\n')
extra_opt = ''
link_extra_opt = ''
HAS_OMP = test_openmp('cl')
if HAS_OMP:
extra_opt = ' /openmp'
@ -2319,10 +2326,14 @@ def mk_config():
extra_opt = '%s /DZ3_LOG_SYNC' % extra_opt
if GIT_HASH:
extra_opt = ' %s /D Z3GITHASH=%s' % (extra_opt, GIT_HASH)
if GUARD_CF:
extra_opt = ' %s /guard:cf' % extra_opt
link_extra_opt = ' %s /GUARD:CF' % link_extra_opt
if STATIC_BIN:
static_opt = '/MT'
else:
static_opt = '/MD'
maybe_disable_dynamic_base = '/DYNAMICBASE' if ALWAYS_DYNAMIC_BASE else '/DYNAMICBASE:NO'
if DEBUG_MODE:
static_opt = static_opt + 'd'
config.write(
@ -2333,8 +2344,8 @@ def mk_config():
config.write(
'CXXFLAGS=/c /Zi /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _AMD64_ /D _DEBUG /D Z3DEBUG /D _CONSOLE /D _TRACE /D _WINDOWS /Gm- /EHsc /RTC1 /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze- %s %s\n' % (extra_opt, static_opt))
config.write(
'LINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X64 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT\n'
'SLINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X64 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO\n')
'LINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X64 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT %s\n'
'SLINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X64 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 %s %s\n' % (link_extra_opt, maybe_disable_dynamic_base, link_extra_opt))
elif VS_ARM:
print("ARM on VS is unsupported")
exit(1)
@ -2342,8 +2353,8 @@ def mk_config():
config.write(
'CXXFLAGS=/c /Zi /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D Z3DEBUG /D _CONSOLE /D _TRACE /D _WINDOWS /Gm- /EHsc /RTC1 /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze- /arch:SSE2 %s %s\n' % (extra_opt, static_opt))
config.write(
'LINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X86 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT\n'
'SLINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X86 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO\n')
'LINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X86 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT %s\n'
'SLINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X86 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 %s %s\n' % (link_extra_opt, maybe_disable_dynamic_base, link_extra_opt))
else:
# Windows Release mode
LTCG=' /LTCG' if SLOW_OPTIMIZE else ''
@ -2358,8 +2369,8 @@ def mk_config():
config.write(
'CXXFLAGS=/c%s /Zi /nologo /W3 /WX- /O2 /D _EXTERNAL_RELEASE /D WIN32 /D NDEBUG /D _LIB /D _WINDOWS /D _AMD64_ /D _UNICODE /D UNICODE /Gm- /EHsc /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /TP %s %s\n' % (GL, extra_opt, static_opt))
config.write(
'LINK_EXTRA_FLAGS=/link%s /MACHINE:X64 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608\n'
'SLINK_EXTRA_FLAGS=/link%s /MACHINE:X64 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608\n' % (LTCG, LTCG))
'LINK_EXTRA_FLAGS=/link%s /MACHINE:X64 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 %s\n'
'SLINK_EXTRA_FLAGS=/link%s /MACHINE:X64 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 %s\n' % (LTCG, link_extra_opt, LTCG, link_extra_opt))
elif VS_ARM:
print("ARM on VS is unsupported")
exit(1)
@ -2367,8 +2378,8 @@ def mk_config():
config.write(
'CXXFLAGS=/nologo /c%s /Zi /W3 /WX- /O2 /Oy- /D _EXTERNAL_RELEASE /D WIN32 /D NDEBUG /D _CONSOLE /D _WINDOWS /D ASYNC_COMMANDS /Gm- /EHsc /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze- /arch:SSE2 %s %s\n' % (GL, extra_opt, static_opt))
config.write(
'LINK_EXTRA_FLAGS=/link%s /DEBUG /MACHINE:X86 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT\n'
'SLINK_EXTRA_FLAGS=/link%s /DEBUG /MACHINE:X86 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO\n' % (LTCG, LTCG))
'LINK_EXTRA_FLAGS=/link%s /DEBUG /MACHINE:X86 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT %s\n'
'SLINK_EXTRA_FLAGS=/link%s /DEBUG /MACHINE:X86 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 %s %s\n' % (LTCG, link_extra_opt, LTCG, maybe_disable_dynamic_base, link_extra_opt))
@ -2712,12 +2723,22 @@ def mk_all_assembly_infos(major, minor, build, revision):
else:
raise MKException("Failed to find assembly template info file '%s'" % assembly_info_template)
def get_header_files_for_components(component_src_dirs):
assert isinstance(component_src_dirs, list)
h_files_full_path = []
for component_src_dir in sorted(component_src_dirs):
h_files = filter(lambda f: f.endswith('.h') or f.endswith('.hpp'), os.listdir(component_src_dir))
h_files = list(map(lambda p: os.path.join(component_src_dir, p), h_files))
h_files_full_path.extend(h_files)
return h_files_full_path
def mk_install_tactic_cpp(cnames, path):
component_src_dirs = []
for cname in cnames:
c = get_component(cname)
component_src_dirs.append(c.src_dir)
generated_file = mk_genfile_common.mk_install_tactic_cpp_internal(component_src_dirs, path)
h_files_full_path = get_header_files_for_components(component_src_dirs)
generated_file = mk_genfile_common.mk_install_tactic_cpp_internal(h_files_full_path, path)
if VERBOSE:
print("Generated '{}'".format(generated_file))
@ -2735,7 +2756,8 @@ def mk_mem_initializer_cpp(cnames, path):
for cname in cnames:
c = get_component(cname)
component_src_dirs.append(c.src_dir)
generated_file = mk_genfile_common.mk_mem_initializer_cpp_internal(component_src_dirs, path)
h_files_full_path = get_header_files_for_components(component_src_dirs)
generated_file = mk_genfile_common.mk_mem_initializer_cpp_internal(h_files_full_path, path)
if VERBOSE:
print("Generated '{}'".format(generated_file))
@ -2753,7 +2775,8 @@ def mk_gparams_register_modules(cnames, path):
for cname in cnames:
c = get_component(cname)
component_src_dirs.append(c.src_dir)
generated_file = mk_genfile_common.mk_gparams_register_modules_internal(component_src_dirs, path)
h_files_full_path = get_header_files_for_components(component_src_dirs)
generated_file = mk_genfile_common.mk_gparams_register_modules_internal(h_files_full_path, path)
if VERBOSE:
print("Generated '{}'".format(generated_file))

View file

@ -17,4 +17,7 @@ z3_add_component(ackermannization
PYG_FILES
ackermannization_params.pyg
ackermannize_bv_tactic_params.pyg
TACTIC_HEADERS
ackermannize_bv_tactic.h
ackr_bound_probe.h
)

View file

@ -7,7 +7,7 @@ set(generated_files
# Sanity check
foreach (gen_file ${generated_files})
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${gen_file}")
message(FATAL_ERROR "\"${CMAKE_CURRENT_SOURCE_DIR}/${gen_files}\""
message(FATAL_ERROR "\"${CMAKE_CURRENT_SOURCE_DIR}/${gen_file}\""
${z3_polluted_tree_msg})
endif()
endforeach()

View file

@ -558,6 +558,7 @@ extern "C" {
Z3_TRY;
LOG_Z3_get_sort(c, a);
RESET_ERROR_CODE();
CHECK_IS_EXPR(a, 0);
Z3_sort r = of_sort(mk_c(c)->m().get_sort(to_expr(a)));
RETURN_Z3(r);
Z3_CATCH_RETURN(0);
@ -821,9 +822,13 @@ extern "C" {
RESET_ERROR_CODE();
std::ostringstream buffer;
switch (mk_c(c)->get_print_mode()) {
case Z3_PRINT_SMTLIB_FULL:
buffer << mk_pp(to_ast(a), mk_c(c)->m());
case Z3_PRINT_SMTLIB_FULL: {
params_ref p;
p.set_uint("max_depth", 4294967295u);
p.set_uint("min_alias_size", 4294967295u);
buffer << mk_pp(to_ast(a), mk_c(c)->m(), p);
break;
}
case Z3_PRINT_LOW_LEVEL:
buffer << mk_ll_pp(to_ast(a), mk_c(c)->m());
break;
@ -1066,7 +1071,7 @@ extern "C" {
case OP_BIT2BOOL: return Z3_OP_BIT2BOOL;
case OP_BSMUL_NO_OVFL: return Z3_OP_BSMUL_NO_OVFL;
case OP_BUMUL_NO_OVFL: return Z3_OP_BUMUL_NO_OVFL;
case OP_BSMUL_NO_UDFL: return Z3_OP_BSMUL_NO_UDFL;
case OP_BSMUL_NO_UDFL: return Z3_OP_BSMUL_NO_UDFL;
case OP_BSDIV_I: return Z3_OP_BSDIV_I;
case OP_BUDIV_I: return Z3_OP_BUDIV_I;
case OP_BSREM_I: return Z3_OP_BSREM_I;

View file

@ -87,7 +87,7 @@ namespace z3 {
inline std::ostream & operator<<(std::ostream & out, exception const & e) { out << e.msg(); return out; }
#if !defined(Z3_THROW)
#if __cpp_exceptions || _CPPUNWIND
#if __cpp_exceptions || _CPPUNWIND || __EXCEPTIONS
#define Z3_THROW(x) throw x
#else
#define Z3_THROW(x) {}
@ -2796,6 +2796,6 @@ namespace z3 {
/*@}*/
/*@}*/
#undef Z3_THROW
#endif

View file

@ -14,7 +14,7 @@ Author:
Christoph Wintersteiger (cwinter) 2012-03-16
Notes:
--*/
using System;
@ -25,7 +25,7 @@ using System.Diagnostics.Contracts;
namespace Microsoft.Z3
{
/// <summary>
/// The abstract syntax tree (AST) class.
/// The abstract syntax tree (AST) class.
/// </summary>
[ContractVerification(true)]
public class AST : Z3Object, IComparable
@ -35,7 +35,7 @@ namespace Microsoft.Z3
/// </summary>
/// <param name="a">An AST</param>
/// <param name="b">An AST</param>
/// <returns>True if <paramref name="a"/> and <paramref name="b"/> are from the same context
/// <returns>True if <paramref name="a"/> and <paramref name="b"/> are from the same context
/// and represent the same sort; false otherwise.</returns>
public static bool operator ==(AST a, AST b)
{
@ -51,7 +51,7 @@ namespace Microsoft.Z3
/// </summary>
/// <param name="a">An AST</param>
/// <param name="b">An AST</param>
/// <returns>True if <paramref name="a"/> and <paramref name="b"/> are not from the same context
/// <returns>True if <paramref name="a"/> and <paramref name="b"/> are not from the same context
/// or represent different sorts; false otherwise.</returns>
public static bool operator !=(AST a, AST b)
{
@ -120,12 +120,12 @@ namespace Microsoft.Z3
if (ReferenceEquals(Context, ctx))
return this;
else
return new AST(ctx, Native.Z3_translate(Context.nCtx, NativeObject, ctx.nCtx));
return Create(ctx, Native.Z3_translate(Context.nCtx, NativeObject, ctx.nCtx));
}
/// <summary>
/// The kind of the AST.
/// </summary>
/// </summary>
public Z3_ast_kind ASTKind
{
get { return (Z3_ast_kind)Native.Z3_get_ast_kind(Context.nCtx, NativeObject); }
@ -224,10 +224,10 @@ namespace Microsoft.Z3
{
Native.Z3_dec_ref(ctx.nCtx, obj);
}
};
};
internal override void IncRef(IntPtr o)
{
{
// Console.WriteLine("AST IncRef()");
if (Context == null || o == IntPtr.Zero)
return;

View file

@ -163,13 +163,7 @@ namespace Microsoft.Z3
/// <returns>A copy of the term which is associated with <paramref name="ctx"/></returns>
new public Expr Translate(Context ctx)
{
Contract.Requires(ctx != null);
Contract.Ensures(Contract.Result<Expr>() != null);
if (ReferenceEquals(Context, ctx))
return this;
else
return Expr.Create(ctx, Native.Z3_translate(Context.nCtx, NativeObject, ctx.nCtx));
return (Expr)base.Translate(ctx);
}
/// <summary>
@ -809,7 +803,62 @@ namespace Microsoft.Z3
/// Retrieve string corresponding to string constant.
/// </summary>
/// <remarks>the expression should be a string constant, (IsString should be true).</remarks>
public string String { get { return Native.Z3_get_string(Context.nCtx, NativeObject); } }
public string String { get { return Native.Z3_get_string(Context.nCtx, NativeObject); } }
/// <summary>
/// Check whether expression is a concatentation.
/// </summary>
/// <returns>a Boolean</returns>
public bool IsConcat { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_CONCAT; } }
/// <summary>
/// Check whether expression is a prefix.
/// </summary>
/// <returns>a Boolean</returns>
public bool IsPrefix { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_PREFIX; } }
/// <summary>
/// Check whether expression is a suffix.
/// </summary>
/// <returns>a Boolean</returns>
public bool IsSuffix { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_SUFFIX; } }
/// <summary>
/// Check whether expression is a contains.
/// </summary>
/// <returns>a Boolean</returns>
public bool IsContains { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_CONTAINS; } }
/// <summary>
/// Check whether expression is an extract.
/// </summary>
/// <returns>a Boolean</returns>
public bool IsExtract { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_EXTRACT; } }
/// <summary>
/// Check whether expression is a replace.
/// </summary>
/// <returns>a Boolean</returns>
public bool IsReplace { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_REPLACE; } }
/// <summary>
/// Check whether expression is an at.
/// </summary>
/// <returns>a Boolean</returns>
public bool IsAt { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_AT; } }
/// <summary>
/// Check whether expression is a sequence length.
/// </summary>
/// <returns>a Boolean</returns>
public bool IsLength { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_LENGTH; } }
/// <summary>
/// Check whether expression is a sequence index.
/// </summary>
/// <returns>a Boolean</returns>
public bool IsIndex { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SEQ_INDEX; } }
#endregion

View file

@ -14,7 +14,7 @@ Author:
Christoph Wintersteiger (cwinter) 2012-03-16
Notes:
--*/
using System;
@ -23,7 +23,7 @@ using System.Diagnostics.Contracts;
namespace Microsoft.Z3
{
/// <summary>
/// Function declarations.
/// Function declarations.
/// </summary>
[ContractVerification(true)]
public class FuncDecl : AST
@ -62,7 +62,7 @@ namespace Microsoft.Z3
/// <summary>
/// A hash code.
/// </summary>
/// </summary>
public override int GetHashCode()
{
return base.GetHashCode();
@ -205,7 +205,7 @@ namespace Microsoft.Z3
}
/// <summary>
/// Function declarations can have Parameters associated with them.
/// Function declarations can have Parameters associated with them.
/// </summary>
public class Parameter
{
@ -315,6 +315,17 @@ namespace Microsoft.Z3
#endif
#endregion
/// <summary>
/// Translates (copies) the function declaration to the Context <paramref name="ctx"/>.
/// </summary>
/// <param name="ctx">A context</param>
/// <returns>A copy of the function declaration which is associated with <paramref name="ctx"/></returns>
new public FuncDecl Translate(Context ctx)
{
return (FuncDecl) base.Translate(ctx);
}
/// <summary>
/// Create expression that applies function to arguments.
/// </summary>
@ -342,6 +353,5 @@ namespace Microsoft.Z3
Context.CheckContextMatch<Expr>(args);
return Expr.Create(Context, this, args);
}
}
}

View file

@ -14,7 +14,7 @@ Author:
Christoph Wintersteiger (cwinter) 2012-03-19
Notes:
--*/
using System;
@ -157,6 +157,16 @@ namespace Microsoft.Z3
}
}
/// <summary>
/// Translates (copies) the quantifier to the Context <paramref name="ctx"/>.
/// </summary>
/// <param name="ctx">A context</param>
/// <returns>A copy of the quantifier which is associated with <paramref name="ctx"/></returns>
new public Quantifier Translate(Context ctx)
{
return (Quantifier)base.Translate(ctx);
}
#region Internal
[ContractVerification(false)] // F: Clousot ForAll decompilation gets confused below. Setting verification off until I fixed the bug
internal Quantifier(Context ctx, bool isForall, Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null)

View file

@ -14,7 +14,7 @@ Author:
Christoph Wintersteiger (cwinter) 2012-03-15
Notes:
--*/
using System;
@ -33,7 +33,7 @@ namespace Microsoft.Z3
/// </summary>
/// <param name="a">A Sort</param>
/// <param name="b">A Sort</param>
/// <returns>True if <paramref name="a"/> and <paramref name="b"/> are from the same context
/// <returns>True if <paramref name="a"/> and <paramref name="b"/> are from the same context
/// and represent the same sort; false otherwise.</returns>
public static bool operator ==(Sort a, Sort b)
{
@ -49,7 +49,7 @@ namespace Microsoft.Z3
/// </summary>
/// <param name="a">A Sort</param>
/// <param name="b">A Sort</param>
/// <returns>True if <paramref name="a"/> and <paramref name="b"/> are not from the same context
/// <returns>True if <paramref name="a"/> and <paramref name="b"/> are not from the same context
/// or represent different sorts; false otherwise.</returns>
public static bool operator !=(Sort a, Sort b)
{
@ -113,10 +113,20 @@ namespace Microsoft.Z3
return Native.Z3_sort_to_string(Context.nCtx, NativeObject);
}
/// <summary>
/// Translates (copies) the sort to the Context <paramref name="ctx"/>.
/// </summary>
/// <param name="ctx">A context</param>
/// <returns>A copy of the sort which is associated with <paramref name="ctx"/></returns>
new public Sort Translate(Context ctx)
{
return (Sort)base.Translate(ctx);
}
#region Internal
/// <summary>
/// Sort constructor
/// </summary>
/// </summary>
internal Sort(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); }
#if DEBUG
@ -154,5 +164,5 @@ namespace Microsoft.Z3
}
}
#endregion
}
}
}

View file

@ -87,12 +87,10 @@ public class AST extends Z3Object implements Comparable<AST>
**/
public AST translate(Context ctx)
{
if (getContext() == ctx) {
return this;
} else {
return new AST(ctx, Native.translate(getContext().nCtx(),
getNativeObject(), ctx.nCtx()));
return create(ctx, Native.translate(getContext().nCtx(), getNativeObject(), ctx.nCtx()));
}
}

View file

@ -25,6 +25,12 @@ import java.util.Map;
/**
* The main interaction with Z3 happens via the Context.
* For applications that spawn an unbounded number of contexts,
* the proper use is within a try-with-resources
* scope so that the Context object gets garbage collected in
* a predictable way. Contexts maintain all data-structures
* related to terms and formulas that are created relative
* to them.
**/
public class Context implements AutoCloseable {
private final long m_ctx;

View file

@ -194,14 +194,7 @@ public class Expr extends AST
**/
public Expr translate(Context ctx)
{
if (getContext() == ctx) {
return this;
} else {
return Expr.create(
ctx,
Native.translate(getContext().nCtx(), getNativeObject(),
ctx.nCtx()));
}
return (Expr) super.translate(ctx);
}
/**
@ -1297,6 +1290,15 @@ public class Expr extends AST
return Native.getString(getContext().nCtx(), getNativeObject());
}
/**
* Check whether expression is a concatenation
* @return a boolean
*/
public boolean isConcat()
{
return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_SEQ_CONCAT;
}
/**
* Indicates whether the term is a binary equivalence modulo namings.
* Remarks: This binary predicate is used in proof terms. It captures

View file

@ -88,6 +88,7 @@ public class Fixedpoint extends Z3Object
/**
* Add rule into the fixedpoint solver.
*
* @param rule implication (Horn clause) representing rule
* @param name Nullable rule name.
* @throws Z3Exception
**/
@ -178,6 +179,7 @@ public class Fixedpoint extends Z3Object
/**
* Update named rule into in the fixedpoint solver.
*
* @param rule implication (Horn clause) representing rule
* @param name Nullable rule name.
* @throws Z3Exception
**/

View file

@ -1,6 +1,6 @@
/**
Copyright (c) 2012-2014 Microsoft Corporation
Module Name:
FuncDecl.java
@ -12,8 +12,8 @@ Author:
@author Christoph Wintersteiger (cwinter) 2012-03-15
Notes:
**/
**/
package com.microsoft.z3;
@ -59,6 +59,18 @@ public class FuncDecl extends AST
return Native.getFuncDeclId(getContext().nCtx(), getNativeObject());
}
/**
* Translates (copies) the function declaration to the Context {@code ctx}.
* @param ctx A context
*
* @return A copy of the function declaration which is associated with {@code ctx}
* @throws Z3Exception on error
**/
public FuncDecl translate(Context ctx)
{
return (FuncDecl) super.translate(ctx);
}
/**
* The arity of the function declaration
**/
@ -68,7 +80,7 @@ public class FuncDecl extends AST
}
/**
* The size of the domain of the function declaration
* The size of the domain of the function declaration
* @see #getArity
**/
public int getDomainSize()
@ -324,7 +336,7 @@ public class FuncDecl extends AST
}
FuncDecl(Context ctx, Symbol name, Sort[] domain, Sort range)
{
super(ctx, Native.mkFuncDecl(ctx.nCtx(), name.getNativeObject(),
AST.arrayLength(domain), AST.arrayToNative(domain),
@ -333,7 +345,7 @@ public class FuncDecl extends AST
}
FuncDecl(Context ctx, String prefix, Sort[] domain, Sort range)
{
super(ctx, Native.mkFreshFuncDecl(ctx.nCtx(), prefix,
AST.arrayLength(domain), AST.arrayToNative(domain),
@ -351,7 +363,7 @@ public class FuncDecl extends AST
}
/**
* Create expression that applies function to arguments.
* Create expression that applies function to arguments.
**/
public Expr apply(Expr ... args)
{

View file

@ -145,6 +145,19 @@ public class Quantifier extends BoolExpr
.nCtx(), getNativeObject()));
}
/**
* Translates (copies) the quantifier to the Context {@code ctx}.
*
* @param ctx A context
*
* @return A copy of the quantifier which is associated with {@code ctx}
* @throws Z3Exception on error
**/
public Quantifier translate(Context ctx)
{
return (Quantifier) super.translate(ctx);
}
/**
* Create a quantified expression.
*

View file

@ -87,6 +87,19 @@ public class Sort extends AST
return Native.sortToString(getContext().nCtx(), getNativeObject());
}
/**
* Translates (copies) the sort to the Context {@code ctx}.
*
* @param ctx A context
*
* @return A copy of the sort which is associated with {@code ctx}
* @throws Z3Exception on error
**/
public Sort translate(Context ctx)
{
return (Sort) super.translate(ctx);
}
/**
* Sort constructor
**/

View file

@ -12,7 +12,7 @@
Several online tutorials for Z3Py are available at:
http://rise4fun.com/Z3Py/tutorial/guide
Please send feedback, comments and/or corrections to leonardo@microsoft.com. Your comments are very valuable.
Please send feedback, comments and/or corrections on the Issue tracker for https://github.com/Z3prover/z3.git. Your comments are very valuable.
Small example:
@ -50,6 +50,7 @@ from fractions import Fraction
import sys
import io
import math
import copy
if sys.version < '3':
def _is_int(v):
@ -288,6 +289,9 @@ class AstRef(Z3PPObject):
if self.ctx.ref() is not None:
Z3_dec_ref(self.ctx.ref(), self.as_ast())
def __deepcopy__(self, memo={}):
return _to_ast_ref(self.ast, self.ctx)
def __str__(self):
return obj_to_string(self)
@ -314,7 +318,7 @@ class AstRef(Z3PPObject):
raise Z3Exception("Symbolic expressions cannot be cast to concrete Boolean values.")
def sexpr(self):
"""Return an string representing the AST node in s-expression notation.
"""Return a string representing the AST node in s-expression notation.
>>> x = Int('x')
>>> ((x + 1)*x).sexpr()
@ -4357,6 +4361,11 @@ class Datatype:
self.name = name
self.constructors = []
def __deepcopy__(self, memo={}):
r = Datatype(self.name, self.ctx)
r.constructors = copy.deepcopy(self.constructors)
return r
def declare_core(self, name, rec_name, *args):
if __debug__:
_z3_assert(isinstance(name, str), "String expected")
@ -4647,11 +4656,17 @@ class ParamsRef:
Consider using the function `args2params` to create instances of this object.
"""
def __init__(self, ctx=None):
def __init__(self, ctx=None, params=None):
self.ctx = _get_ctx(ctx)
self.params = Z3_mk_params(self.ctx.ref())
if params is None:
self.params = Z3_mk_params(self.ctx.ref())
else:
self.params = params
Z3_params_inc_ref(self.ctx.ref(), self.params)
def __deepcopy__(self, memo={}):
return ParamsRef(self.ctx, self.params)
def __del__(self):
if self.ctx.ref() is not None:
Z3_params_dec_ref(self.ctx.ref(), self.params)
@ -4711,6 +4726,9 @@ class ParamDescrsRef:
self.descr = descr
Z3_param_descrs_inc_ref(self.ctx.ref(), self.descr)
def __deepcopy__(self, memo={}):
return ParamsDescrsRef(self.descr, self.ctx)
def __del__(self):
if self.ctx.ref() is not None:
Z3_param_descrs_dec_ref(self.ctx.ref(), self.descr)
@ -4772,6 +4790,9 @@ class Goal(Z3PPObject):
self.goal = Z3_mk_goal(self.ctx.ref(), models, unsat_cores, proofs)
Z3_goal_inc_ref(self.ctx.ref(), self.goal)
def __deepcopy__(self, memo={}):
return Goal(False, False, False, self.ctx, self.goal)
def __del__(self):
if self.goal is not None and self.ctx.ref() is not None:
Z3_goal_dec_ref(self.ctx.ref(), self.goal)
@ -5034,6 +5055,9 @@ class AstVector(Z3PPObject):
self.ctx = ctx
Z3_ast_vector_inc_ref(self.ctx.ref(), self.vector)
def __deepcopy__(self, memo={}):
return AstVector(self.vector, self.ctx)
def __del__(self):
if self.vector is not None and self.ctx.ref() is not None:
Z3_ast_vector_dec_ref(self.ctx.ref(), self.vector)
@ -5169,6 +5193,9 @@ class AstMap:
self.ctx = ctx
Z3_ast_map_inc_ref(self.ctx.ref(), self.map)
def __deepcopy__(self, memo={}):
return AstMap(self.map, self.ctx)
def __del__(self):
if self.map is not None and self.ctx.ref() is not None:
Z3_ast_map_dec_ref(self.ctx.ref(), self.map)
@ -5284,6 +5311,9 @@ class FuncEntry:
self.ctx = ctx
Z3_func_entry_inc_ref(self.ctx.ref(), self.entry)
def __deepcopy__(self, memo={}):
return FuncEntry(self.entry, self.ctx)
def __del__(self):
if self.ctx.ref() is not None:
Z3_func_entry_dec_ref(self.ctx.ref(), self.entry)
@ -5390,6 +5420,9 @@ class FuncInterp(Z3PPObject):
if self.f is not None:
Z3_func_interp_inc_ref(self.ctx.ref(), self.f)
def __deepcopy__(self, memo={}):
return FuncInterp(self.f, self.ctx)
def __del__(self):
if self.f is not None and self.ctx.ref() is not None:
Z3_func_interp_dec_ref(self.ctx.ref(), self.f)
@ -5500,6 +5533,9 @@ class ModelRef(Z3PPObject):
self.ctx = ctx
Z3_model_inc_ref(self.ctx.ref(), self.model)
def __deepcopy__(self, memo={}):
return ModelRef(self.m, self.ctx)
def __del__(self):
if self.ctx.ref() is not None:
Z3_model_dec_ref(self.ctx.ref(), self.model)
@ -5776,6 +5812,9 @@ class Statistics:
self.ctx = ctx
Z3_stats_inc_ref(self.ctx.ref(), self.stats)
def __deepcopy__(self, memo={}):
return Statistics(self.stats, self.ctx)
def __del__(self):
if self.ctx.ref() is not None:
Z3_stats_dec_ref(self.ctx.ref(), self.stats)
@ -5910,6 +5949,9 @@ class CheckSatResult:
def __init__(self, r):
self.r = r
def __deepcopy__(self, memo={}):
return CheckSatResult(self.r)
def __eq__(self, other):
return isinstance(other, CheckSatResult) and self.r == other.r
@ -5949,6 +5991,9 @@ class Solver(Z3PPObject):
self.solver = solver
Z3_solver_inc_ref(self.ctx.ref(), self.solver)
def __deepcopy__(self, memo={}):
return Solver(self.solver, self.ctx)
def __del__(self):
if self.solver is not None and self.ctx.ref() is not None:
Z3_solver_dec_ref(self.ctx.ref(), self.solver)
@ -6009,6 +6054,24 @@ class Solver(Z3PPObject):
"""
Z3_solver_pop(self.ctx.ref(), self.solver, num)
def num_scopes(self):
"""Return the current number of backtracking points.
>>> s = Solver()
>>> s.num_scopes()
0L
>>> s.push()
>>> s.num_scopes()
1L
>>> s.push()
>>> s.num_scopes()
2L
>>> s.pop()
>>> s.num_scopes()
1L
"""
return Z3_solver_get_num_scopes(self.ctx.ref(), self.solver)
def reset(self):
"""Remove all asserted constraints and backtracking points created using `push()`.
@ -6384,6 +6447,9 @@ class Fixedpoint(Z3PPObject):
Z3_fixedpoint_inc_ref(self.ctx.ref(), self.fixedpoint)
self.vars = []
def __deepcopy__(self, memo={}):
return FixedPoint(self.fixedpoint, self.ctx)
def __del__(self):
if self.fixedpoint is not None and self.ctx.ref() is not None:
Z3_fixedpoint_dec_ref(self.ctx.ref(), self.fixedpoint)
@ -6758,6 +6824,9 @@ class Optimize(Z3PPObject):
self.optimize = Z3_mk_optimize(self.ctx.ref())
Z3_optimize_inc_ref(self.ctx.ref(), self.optimize)
def __deepcopy__(self, memo={}):
return Optimize(self.optimize, self.ctx)
def __del__(self):
if self.optimize is not None and self.ctx.ref() is not None:
Z3_optimize_dec_ref(self.ctx.ref(), self.optimize)
@ -6910,6 +6979,9 @@ class ApplyResult(Z3PPObject):
self.ctx = ctx
Z3_apply_result_inc_ref(self.ctx.ref(), self.result)
def __deepcopy__(self, memo={}):
return ApplyResult(self.result, self.ctx)
def __del__(self):
if self.ctx.ref() is not None:
Z3_apply_result_dec_ref(self.ctx.ref(), self.result)
@ -7038,6 +7110,9 @@ class Tactic:
raise Z3Exception("unknown tactic '%s'" % tactic)
Z3_tactic_inc_ref(self.ctx.ref(), self.tactic)
def __deepcopy__(self, memo={}):
return Tactic(self.tactic, self.ctx)
def __del__(self):
if self.tactic is not None and self.ctx.ref() is not None:
Z3_tactic_dec_ref(self.ctx.ref(), self.tactic)
@ -7310,6 +7385,9 @@ class Probe:
raise Z3Exception("unknown probe '%s'" % probe)
Z3_probe_inc_ref(self.ctx.ref(), self.probe)
def __deepcopy__(self, memo={}):
return Probe(self.probe, self.ctx)
def __del__(self):
if self.probe is not None and self.ctx.ref() is not None:
Z3_probe_dec_ref(self.ctx.ref(), self.probe)

View file

@ -48,6 +48,7 @@ DEFINE_TYPE(Z3_rcf_num);
/*@{*/
/** @name Types
@{
Most of the types in the C API are opaque pointers.
@ -395,6 +396,33 @@ typedef enum
The meaning is given by the equivalence
(xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3)
- Z3_OP_BSMUL_NO_OVFL: a predicate to check that bit-wise signed multiplication does not overflow.
Signed multiplication overflows if the operands have the same sign and the result of multiplication
does not fit within the available bits. \sa Z3_mk_bvmul_no_overflow.
- Z3_OP_BUMUL_NO_OVFL: check that bit-wise unsigned multiplication does not overflow.
Unsigned multiplication overflows if the result does not fit within the available bits.
\sa Z3_mk_bvmul_no_overflow.
- Z3_OP_BSMUL_NO_UDFL: check that bit-wise signed multiplication does not underflow.
Signed multiplication underflows if the operands have opposite signs and the result of multiplication
does not fit within the avaialble bits. Z3_mk_bvmul_no_underflow.
- Z3_OP_BSDIV_I: Binary signed division.
It has the same semantics as Z3_OP_BSDIV, but created in a context where the second operand can be assumed to be non-zero.
- Z3_OP_BUDIV_I: Binary unsigned division.
It has the same semantics as Z3_OP_BUDIV, but created in a context where the second operand can be assumed to be non-zero.
- Z3_OP_BSREM_I: Binary signed remainder.
It has the same semantics as Z3_OP_BSREM, but created in a context where the second operand can be assumed to be non-zero.
- Z3_OP_BUREM_I: Binary unsigned remainder.
It has the same semantics as Z3_OP_BUREM, but created in a context where the second operand can be assumed to be non-zero.
- Z3_OP_BSMOD_I: Binary signed modulus.
It has the same semantics as Z3_OP_BSMOD, but created in a context where the second operand can be assumed to be non-zero.
- Z3_OP_PR_UNDEF: Undef/Null proof object.
- Z3_OP_PR_TRUE: Proof for the expression 'true'.
@ -5238,7 +5266,6 @@ extern "C" {
def_API('Z3_get_error_msg', STRING, (_in(CONTEXT), _in(ERROR_CODE)))
*/
Z3_string Z3_API Z3_get_error_msg(Z3_context c, Z3_error_code err);
/*@}*/
/**
\brief Return a string describing the given error code.
@ -5349,6 +5376,13 @@ extern "C" {
/**
\brief Add a new formula \c a to the given goal.
The formula is split according to the following procedure that is applied
until a fixed-point:
Conjunctions are split into separate formulas.
Negations are distributed over disjunctions, resulting in separate formulas.
If the goal is \c false, adding new formulas is a no-op.
If the formula \c a is \c true, then nothing is added.
If the formula \c a is \c false, then the entire goal is replaced by the formula \c false.
def_API('Z3_goal_assert', VOID, (_in(CONTEXT), _in(GOAL), _in(AST)))
*/
@ -5791,9 +5825,35 @@ extern "C" {
/** @name Solvers*/
/*@{*/
/**
\brief Create a new (incremental) solver. This solver also uses a
set of builtin tactics for handling the first check-sat command, and
check-sat commands that take more than a given number of milliseconds to be solved.
\brief Create a new solver. This solver is a "combined solver" (see
combined_solver module) that internally uses a non-incremental (solver1) and an
incremental solver (solver2). This combined solver changes its behaviour based
on how it is used and how its parameters are set.
If the solver is used in a non incremental way (i.e. no calls to
`Z3_solver_push()` or `Z3_solver_pop()`, and no calls to
`Z3_solver_assert()` or `Z3_solver_assert_and_track()` after checking
satisfiability without an intervening `Z3_solver_reset()`) then solver1
will be used. This solver will apply Z3's "default" tactic.
The "default" tactic will attempt to probe the logic used by the
assertions and will apply a specialized tactic if one is supported.
Otherwise the general `(and-then simplify smt)` tactic will be used.
If the solver is used in an incremental way then the combined solver
will switch to using solver2 (which behaves similarly to the general
"smt" tactic).
Note however it is possible to set the `solver2_timeout`,
`solver2_unknown`, and `ignore_solver1` parameters of the combined
solver to change its behaviour.
The function #Z3_solver_get_model retrieves a model if the
assertions is satisfiable (i.e., the result is \c
Z3_L_TRUE) and model construction is enabled.
The function #Z3_solver_get_model can also be used even
if the result is \c Z3_L_UNDEF, but the returned model
is not guaranteed to satisfy quantified assertions.
\remark User must use #Z3_solver_inc_ref and #Z3_solver_dec_ref to manage solver objects.
Even if the context was created using #Z3_mk_context instead of #Z3_mk_context_rc.
@ -5803,7 +5863,17 @@ extern "C" {
Z3_solver Z3_API Z3_mk_solver(Z3_context c);
/**
\brief Create a new (incremental) solver.
\brief Create a new incremental solver.
This is equivalent to applying the "smt" tactic.
Unlike `Z3_mk_solver()` this solver
- Does not attempt to apply any logic specific tactics.
- Does not change its behaviour based on whether it used
incrementally/non-incrementally.
Note that these differences can result in very different performance
compared to `Z3_mk_solver()`.
The function #Z3_solver_get_model retrieves a model if the
assertions is satisfiable (i.e., the result is \c

View file

@ -75,7 +75,7 @@ extern "C" {
\brief Add a maximization constraint.
\param c - context
\param o - optimization context
\param a - arithmetical term
\param t - arithmetical term
def_API('Z3_optimize_maximize', UINT, (_in(CONTEXT), _in(OPTIMIZE), _in(AST)))
*/
unsigned Z3_API Z3_optimize_maximize(Z3_context c, Z3_optimize o, Z3_ast t);
@ -84,7 +84,7 @@ extern "C" {
\brief Add a minimization constraint.
\param c - context
\param o - optimization context
\param a - arithmetical term
\param t - arithmetical term
def_API('Z3_optimize_minimize', UINT, (_in(CONTEXT), _in(OPTIMIZE), _in(AST)))
*/

View file

@ -275,7 +275,9 @@ public:
bool is_uminus(expr const * n) const { return is_app_of(n, m_afid, OP_UMINUS); }
bool is_mul(expr const * n) const { return is_app_of(n, m_afid, OP_MUL); }
bool is_div(expr const * n) const { return is_app_of(n, m_afid, OP_DIV); }
bool is_div0(expr const * n) const { return is_app_of(n, m_afid, OP_DIV_0); }
bool is_idiv(expr const * n) const { return is_app_of(n, m_afid, OP_IDIV); }
bool is_idiv0(expr const * n) const { return is_app_of(n, m_afid, OP_IDIV_0); }
bool is_mod(expr const * n) const { return is_app_of(n, m_afid, OP_MOD); }
bool is_rem(expr const * n) const { return is_app_of(n, m_afid, OP_REM); }
bool is_to_real(expr const * n) const { return is_app_of(n, m_afid, OP_TO_REAL); }

View file

@ -667,6 +667,8 @@ public:
expr * get_arg(unsigned idx) const { SASSERT(idx < m_num_args); return m_args[idx]; }
expr * const * get_args() const { return m_args; }
unsigned get_size() const { return get_obj_size(get_num_args()); }
expr * const * begin() const { return m_args; }
expr * const * end() const { return m_args + m_num_args; }
unsigned get_depth() const { return flags()->m_depth; }
bool is_ground() const { return flags()->m_ground; }
@ -2082,6 +2084,7 @@ public:
bool is_undef_proof(expr const * e) const { return e == m_undef_proof; }
bool is_asserted(expr const * e) const { return is_app_of(e, m_basic_family_id, PR_ASSERTED); }
bool is_hypothesis (expr const *e) const {return is_app_of (e, m_basic_family_id, PR_HYPOTHESIS);}
bool is_goal(expr const * e) const { return is_app_of(e, m_basic_family_id, PR_GOAL); }
bool is_modus_ponens(expr const * e) const { return is_app_of(e, m_basic_family_id, PR_MODUS_PONENS); }
bool is_reflexivity(expr const * e) const { return is_app_of(e, m_basic_family_id, PR_REFLEXIVITY); }
@ -2112,6 +2115,7 @@ public:
bool is_skolemize(expr const * e) const { return is_app_of(e, m_basic_family_id, PR_SKOLEMIZE); }
MATCH_UNARY(is_asserted);
MATCH_UNARY(is_hypothesis);
MATCH_UNARY(is_lemma);
bool has_fact(proof const * p) const {

View file

@ -557,7 +557,14 @@ class smt2_printer {
format * f;
if (v->get_idx() < m_var_names.size()) {
symbol s = m_var_names[m_var_names.size() - v->get_idx() - 1];
f = mk_string(m(), s.str().c_str());
std::string vname;
if (is_smt2_quoted_symbol (s)) {
vname = mk_smt2_quoted_symbol (s);
}
else {
vname = s.str();
}
f = mk_string(m(), vname.c_str ());
}
else {
// fallback... it is not supposed to happen when the printer is correctly used.
@ -884,7 +891,14 @@ class smt2_printer {
symbol * it = m_var_names.end() - num_decls;
for (unsigned i = 0; i < num_decls; i++, it++) {
format * fs[1] = { m_env.pp_sort(q->get_decl_sort(i)) };
buf.push_back(mk_seq1<format**,f2f>(m(), fs, fs+1, f2f(), it->str().c_str()));
std::string var_name;
if (is_smt2_quoted_symbol (*it)) {
var_name = mk_smt2_quoted_symbol (*it);
}
else {
var_name = it->str ();\
}
buf.push_back(mk_seq1<format**,f2f>(m(), fs, fs+1, f2f(), var_name.c_str ()));
}
return mk_seq5(m(), buf.begin(), buf.end(), f2f());
}

View file

@ -732,7 +732,7 @@ void bv_decl_plugin::get_op_names(svector<builtin_name> & op_names, symbol const
op_names.push_back(builtin_name("bvudiv_i", OP_BUDIV_I));
op_names.push_back(builtin_name("bvsrem_i", OP_BSREM_I));
op_names.push_back(builtin_name("bvurem_i", OP_BUREM_I));
op_names.push_back(builtin_name("bvumod_i", OP_BSMOD_I));
op_names.push_back(builtin_name("bvsmod_i", OP_BSMOD_I));
op_names.push_back(builtin_name("ext_rotate_left",OP_EXT_ROTATE_LEFT));
op_names.push_back(builtin_name("ext_rotate_right",OP_EXT_ROTATE_RIGHT));

View file

@ -35,6 +35,13 @@ class expr_map {
obj_map<expr, expr*> m_expr2expr;
obj_map<expr, proof*> m_expr2pr;
public:
typedef obj_map<expr, expr*> Map;
typedef Map::iterator iterator;
typedef Map::key key;
typedef Map::value value;
typedef Map::data data;
typedef Map::entry entry;
expr_map(ast_manager & m);
expr_map(ast_manager & m, bool store_proofs);
~expr_map();
@ -44,6 +51,8 @@ public:
void erase(expr * k);
void reset();
void flush();
iterator begin () const { return m_expr2expr.begin (); }
iterator end () const {return m_expr2expr.end (); }
void set_store_proofs(bool f) {
if (m_store_proofs != f) flush();
m_store_proofs = f;

View file

@ -1632,8 +1632,6 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args,
res_exp = e_exp;
// Result could overflow into 4.xxx ...
family_id bvfid = m_bv_util.get_fid();
expr_ref res_sgn_c1(m), res_sgn_c2(m), res_sgn_c3(m);
expr_ref not_e_sgn(m), not_f_sgn(m), not_sign_bv(m);
@ -1646,11 +1644,34 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args,
expr * res_sgn_or_args[3] = { res_sgn_c1, res_sgn_c2, res_sgn_c3 };
res_sgn = m_bv_util.mk_bv_or(3, res_sgn_or_args);
// Result could have overflown into 4.xxx.
SASSERT(m_bv_util.get_bv_size(sig_abs) == 2 * sbits + 2);
expr_ref ovfl_into_4(m);
ovfl_into_4 = m.mk_eq(m_bv_util.mk_extract(2 * sbits + 1, 2 * sbits, sig_abs),
m_bv_util.mk_numeral(1, 2));
dbg_decouple("fpa2bv_fma_ovfl_into_4", ovfl_into_4);
if (sbits > 5) {
sticky_raw = m_bv_util.mk_extract(sbits - 5, 0, sig_abs);
sticky = m_bv_util.mk_zero_extend(sbits + 3, m.mk_app(bvfid, OP_BREDOR, sticky_raw.get()));
expr * res_or_args[2] = { m_bv_util.mk_extract(2 * sbits - 1, sbits - 4, sig_abs), sticky };
res_sig = m_bv_util.mk_bv_or(2, res_or_args);
expr_ref sticky_raw(m), sig_upper(m), sticky_redd(m), res_sig_norm(m);
sticky_raw = m_bv_util.mk_extract(sbits - 4, 0, sig_abs);
sig_upper = m_bv_util.mk_extract(2 * sbits, sbits - 3, sig_abs);
SASSERT(m_bv_util.get_bv_size(sig_upper) == sbits + 4);
sticky_redd = m.mk_app(bvfid, OP_BREDOR, sticky_raw.get());
sticky = m_bv_util.mk_zero_extend(sbits + 3, sticky_redd);
expr * res_or_args[2] = { sig_upper, sticky };
res_sig_norm = m_bv_util.mk_bv_or(2, res_or_args);
expr_ref sticky_raw_ovfl(m), sig_upper_ovfl(m), sticky_redd_ovfl(m), sticky_ovfl(m), res_sig_ovfl(m);
sticky_raw_ovfl = m_bv_util.mk_extract(sbits - 4, 0, sig_abs);
sig_upper_ovfl = m_bv_util.mk_extract(2 * sbits, sbits - 3, sig_abs);
SASSERT(m_bv_util.get_bv_size(sig_upper_ovfl) == sbits + 4);
sticky_redd_ovfl = m.mk_app(bvfid, OP_BREDOR, sticky_raw_ovfl.get());
sticky_ovfl = m_bv_util.mk_zero_extend(sbits + 3, sticky_redd_ovfl);
expr * res_or_args_ovfl[2] = { sig_upper_ovfl, sticky_ovfl };
res_sig_ovfl = m_bv_util.mk_bv_or(2, res_or_args_ovfl);
res_sig = m.mk_ite(ovfl_into_4, res_sig_ovfl, res_sig_norm);
res_exp = m.mk_ite(ovfl_into_4, m_bv_util.mk_bv_add(res_exp, m_bv_util.mk_numeral(1, ebits+2)),
res_exp);
}
else {
unsigned too_short = 6 - sbits;
@ -1658,6 +1679,8 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args,
res_sig = m_bv_util.mk_extract(sbits + 3, 0, sig_abs);
}
dbg_decouple("fpa2bv_fma_add_sum_sticky", sticky);
dbg_decouple("fpa2bv_fma_sig_abs", sig_abs);
dbg_decouple("fpa2bv_fma_res_sig", res_sig);
SASSERT(m_bv_util.get_bv_size(res_sig) == sbits + 4);
expr_ref is_zero_sig(m), nil_sbits4(m);

View file

@ -8,4 +8,6 @@ z3_add_component(normal_forms
rewriter
PYG_FILES
nnf_params.pyg
EXTRA_REGISTER_MODULE_HEADERS
nnf.h
)

View file

@ -2,7 +2,7 @@
# for other components then we should refactor this code into
# z3_add_component()
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/database.h")
message(FATAL_ERROR "The generated file \"database.h\""
message(FATAL_ERROR "The generated file \"${CMAKE_CURRENT_SOURCE_DIR}/database.h\""
${z3_polluted_tree_msg})
endif()

View file

@ -109,6 +109,7 @@ public:
bool is_ge(func_decl* a) const;
bool is_ge(expr* a) const { return is_app(a) && is_ge(to_app(a)->get_decl()); }
bool is_ge(expr* a, rational& k) const;
bool is_aux_bool(func_decl* f) const { return is_decl_of(f, m_fid, OP_PB_AUX_BOOL); }
bool is_aux_bool(expr* e) const { return is_app_of(e, m_fid, OP_PB_AUX_BOOL); }
rational get_coeff(expr* a, unsigned index) const { return get_coeff(to_app(a)->get_decl(), index); }
rational get_coeff(func_decl* a, unsigned index) const;

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