mirror of
https://github.com/Z3Prover/z3
synced 2025-04-12 12:08:18 +00:00
Merge branch 'master' of https://github.com/z3prover/z3
This commit is contained in:
commit
30b0d5ba13
4
.dockerignore
Normal file
4
.dockerignore
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
**/*.swp
|
||||||
|
**/*.pyc
|
||||||
|
.git
|
||||||
|
**/*.Dockerfile
|
68
.travis.yml
Normal file
68
.travis.yml
Normal 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
|
|
@ -266,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.
|
Disabling this is useful for faster incremental builds. The documentation can be manually built by invoking the ``api_docs`` target.
|
||||||
* ``LINK_TIME_OPTIMIZATION`` - BOOL. If set to ``TRUE`` link time optimization will be enabled.
|
* ``LINK_TIME_OPTIMIZATION`` - BOOL. If set to ``TRUE`` link time optimization will be enabled.
|
||||||
* ``API_LOG_SYNC`` - BOOL. If set to ``TRUE`` will enable experimental API log sync feature.
|
* ``API_LOG_SYNC`` - BOOL. If set to ``TRUE`` will enable experimental API log sync feature.
|
||||||
|
* ``WARNINGS_AS_ERRORS`` - STRING. If set to ``TRUE`` compiler warnings will be treated as errors. If set to ``False`` compiler warnings will not be treated as errors.
|
||||||
|
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.
|
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.
|
||||||
|
|
||||||
|
@ -381,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.
|
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.
|
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.
|
||||||
|
|
|
@ -12,9 +12,9 @@ See the [release notes](RELEASE_NOTES) for notes on various stable releases of Z
|
||||||
|
|
||||||
## Build status
|
## Build status
|
||||||
|
|
||||||
| Windows x86 | Windows x64 | Ubuntu x64 | Ubuntu x86 | Debian x64 | OSX |
|
| Windows x86 | Windows x64 | Ubuntu x64 | Ubuntu x86 | Debian x64 | OSX | TravisCI |
|
||||||
| ----------- | ----------- | ---------- | ---------- | ---------- | --- |
|
| ----------- | ----------- | ---------- | ---------- | ---------- | --- | -------- |
|
||||||
 |  |  |  |  | 
|
[](https://cz3.visualstudio.com/Z3/_build/index?definitionId=4) | [](https://cz3.visualstudio.com/Z3/_build/index?definitionId=7) | [](https://cz3.visualstudio.com/Z3/_build/index?definitionId=3) | [](https://cz3.visualstudio.com/Z3/_build/index?definitionId=6) | [](https://cz3.visualstudio.com/Z3/_build/index?definitionId=5) | [](https://cz3.visualstudio.com/Z3/_build/index?definitionId=2) | [](https://travis-ci.org/Z3Prover/z3)
|
||||||
|
|
||||||
[1]: #building-z3-on-windows-using-visual-studio-command-prompt
|
[1]: #building-z3-on-windows-using-visual-studio-command-prompt
|
||||||
[2]: #building-z3-using-make-and-gccclang
|
[2]: #building-z3-using-make-and-gccclang
|
||||||
|
|
|
@ -1,17 +1,61 @@
|
||||||
|
################################################################################
|
||||||
|
# Compiler warning flags
|
||||||
|
################################################################################
|
||||||
|
# These are passed to relevant compiler provided they are supported
|
||||||
set(GCC_AND_CLANG_WARNINGS
|
set(GCC_AND_CLANG_WARNINGS
|
||||||
"-Wall"
|
"-Wall"
|
||||||
)
|
)
|
||||||
set(GCC_ONLY_WARNINGS "")
|
set(GCC_ONLY_WARNINGS "")
|
||||||
set(CLANG_ONLY_WARNINGS "")
|
set(CLANG_ONLY_WARNINGS "")
|
||||||
set(MSVC_WARNINGS "/W3")
|
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_FLAGS_TO_CHECK "")
|
||||||
|
set(WARNING_AS_ERROR_FLAGS_TO_CHECK "")
|
||||||
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
|
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
|
||||||
list(APPEND WARNING_FLAGS_TO_CHECK ${GCC_AND_CLANG_WARNINGS})
|
list(APPEND WARNING_FLAGS_TO_CHECK ${GCC_AND_CLANG_WARNINGS})
|
||||||
list(APPEND WARNING_FLAGS_TO_CHECK ${GCC_ONLY_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")
|
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
|
||||||
list(APPEND WARNING_FLAGS_TO_CHECK ${GCC_AND_CLANG_WARNINGS})
|
list(APPEND WARNING_FLAGS_TO_CHECK ${GCC_AND_CLANG_WARNINGS})
|
||||||
list(APPEND WARNING_FLAGS_TO_CHECK ${CLANG_ONLY_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
|
# FIXME: Remove "x.." when CMP0054 is set to NEW
|
||||||
elseif ("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC")
|
elseif ("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC")
|
||||||
list(APPEND WARNING_FLAGS_TO_CHECK ${MSVC_WARNINGS})
|
list(APPEND WARNING_FLAGS_TO_CHECK ${MSVC_WARNINGS})
|
||||||
|
@ -31,8 +75,40 @@ foreach (flag ${WARNING_FLAGS_TO_CHECK})
|
||||||
z3_add_cxx_flag("${flag}")
|
z3_add_cxx_flag("${flag}")
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
option(WARNINGS_AS_ERRORS "Treat compiler warnings as errors" OFF)
|
# TODO: Remove this eventually.
|
||||||
if (WARNINGS_AS_ERRORS)
|
# 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"))
|
if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU"))
|
||||||
list(APPEND Z3_COMPONENT_CXX_FLAGS "-Werror")
|
list(APPEND Z3_COMPONENT_CXX_FLAGS "-Werror")
|
||||||
# FIXME: Remove "x.." when CMP0054 is set to NEW
|
# FIXME: Remove "x.." when CMP0054 is set to NEW
|
||||||
|
@ -41,8 +117,14 @@ if (WARNINGS_AS_ERRORS)
|
||||||
else()
|
else()
|
||||||
message(AUTHOR_WARNING "Unknown compiler")
|
message(AUTHOR_WARNING "Unknown compiler")
|
||||||
endif()
|
endif()
|
||||||
message(STATUS "Treating compiler warnings as errors")
|
elseif ("${WARNINGS_AS_ERRORS}" STREQUAL "SERIOUS_ONLY")
|
||||||
else()
|
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")
|
message(STATUS "Not treating compiler warnings as errors")
|
||||||
# FIXME: Remove "x.." when CMP0054 is set to NEW
|
# FIXME: Remove "x.." when CMP0054 is set to NEW
|
||||||
if ("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC")
|
if ("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC")
|
||||||
|
@ -51,4 +133,8 @@ else()
|
||||||
# build system.
|
# build system.
|
||||||
list(APPEND Z3_COMPONENT_CXX_FLAGS "/WX-")
|
list(APPEND Z3_COMPONENT_CXX_FLAGS "/WX-")
|
||||||
endif()
|
endif()
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"WARNINGS_AS_ERRORS set to unsupported value \"${WARNINGS_AS_ERRORS}\""
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -2,7 +2,7 @@ include(CheckCXXCompilerFlag)
|
||||||
include(CMakeParseArguments)
|
include(CMakeParseArguments)
|
||||||
|
|
||||||
function(z3_add_cxx_flag flag)
|
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 "${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}")
|
||||||
|
@ -16,8 +16,13 @@ function(z3_add_cxx_flag flag)
|
||||||
endif()
|
endif()
|
||||||
if (HAS_${SANITIZED_FLAG_NAME})
|
if (HAS_${SANITIZED_FLAG_NAME})
|
||||||
message(STATUS "C++ compiler supports ${flag}")
|
message(STATUS "C++ compiler supports ${flag}")
|
||||||
list(APPEND Z3_COMPONENT_CXX_FLAGS "${flag}")
|
if (z3_add_flag_GLOBAL)
|
||||||
set(Z3_COMPONENT_CXX_FLAGS "${Z3_COMPONENT_CXX_FLAGS}" PARENT_SCOPE)
|
# 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()
|
else()
|
||||||
message(STATUS "C++ compiler does not support ${flag}")
|
message(STATUS "C++ compiler does not support ${flag}")
|
||||||
endif()
|
endif()
|
||||||
|
|
50
contrib/ci/Dockerfiles/z3_base_ubuntu32_16.04.Dockerfile
Normal file
50
contrib/ci/Dockerfiles/z3_base_ubuntu32_16.04.Dockerfile
Normal 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
|
||||||
|
|
35
contrib/ci/Dockerfiles/z3_base_ubuntu_14.04.Dockerfile
Normal file
35
contrib/ci/Dockerfiles/z3_base_ubuntu_14.04.Dockerfile
Normal 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
|
||||||
|
|
38
contrib/ci/Dockerfiles/z3_base_ubuntu_16.04.Dockerfile
Normal file
38
contrib/ci/Dockerfiles/z3_base_ubuntu_16.04.Dockerfile
Normal 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
|
||||||
|
|
111
contrib/ci/Dockerfiles/z3_build.Dockerfile
Normal file
111
contrib/ci/Dockerfiles/z3_build.Dockerfile
Normal 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
114
contrib/ci/README.md
Normal 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.
|
3
contrib/ci/maintainers.txt
Normal file
3
contrib/ci/maintainers.txt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# Maintainers
|
||||||
|
|
||||||
|
- Dan Liew (@delcypher)
|
130
contrib/ci/scripts/build_z3_cmake.sh
Executable file
130
contrib/ci/scripts/build_z3_cmake.sh
Executable 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[@]}"
|
41
contrib/ci/scripts/run_quiet.sh
Normal file
41
contrib/ci/scripts/run_quiet.sh
Normal 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
|
||||||
|
}
|
46
contrib/ci/scripts/set_compiler_flags.sh
Normal file
46
contrib/ci/scripts/set_compiler_flags.sh
Normal 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
|
20
contrib/ci/scripts/set_generator_args.sh
Normal file
20
contrib/ci/scripts/set_generator_args.sh
Normal 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
|
24
contrib/ci/scripts/test_z3_docs.sh
Executable file
24
contrib/ci/scripts/test_z3_docs.sh
Executable 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?
|
87
contrib/ci/scripts/test_z3_examples_cmake.sh
Executable file
87
contrib/ci/scripts/test_z3_examples_cmake.sh
Executable 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
|
||||||
|
|
24
contrib/ci/scripts/test_z3_install_cmake.sh
Executable file
24
contrib/ci/scripts/test_z3_install_cmake.sh
Executable 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
|
54
contrib/ci/scripts/test_z3_system_tests.sh
Executable file
54
contrib/ci/scripts/test_z3_system_tests.sh
Executable 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
|
24
contrib/ci/scripts/test_z3_unit_tests_cmake.sh
Executable file
24
contrib/ci/scripts/test_z3_unit_tests_cmake.sh
Executable 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
|
18
contrib/ci/scripts/travis_ci_entry_point.sh
Executable file
18
contrib/ci/scripts/travis_ci_entry_point.sh
Executable 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
|
215
contrib/ci/scripts/travis_ci_linux_entry_point.sh
Executable file
215
contrib/ci/scripts/travis_ci_linux_entry_point.sh
Executable 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[@]}" \
|
||||||
|
.
|
10
contrib/ci/scripts/travis_ci_osx_entry_point.sh
Executable file
10
contrib/ci/scripts/travis_ci_osx_entry_point.sh
Executable 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
|
|
@ -4,9 +4,7 @@
|
||||||
Z3 is a high-performance theorem prover being developed at <a class="el"
|
Z3 is a high-performance theorem prover being developed at <a class="el"
|
||||||
href="http://research.microsoft.com">Microsoft Research</a>.
|
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>
|
<b>The Z3 website is at <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>.
|
|
||||||
|
|
||||||
This website hosts the automatically generated documentation for the Z3 APIs.
|
This website hosts the automatically generated documentation for the Z3 APIs.
|
||||||
|
|
||||||
|
|
|
@ -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)
|
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,8 +365,7 @@ void assert_at_most_one(Z3_context ctx, Z3_solver s, unsigned n, Z3_ast * lits)
|
||||||
void tst_at_most_one()
|
void tst_at_most_one()
|
||||||
{
|
{
|
||||||
Z3_context ctx = mk_context();
|
Z3_context ctx = mk_context();
|
||||||
Z3_solver s = Z3_mk_solver(ctx);
|
Z3_solver s = mk_solver(ctx);
|
||||||
Z3_solver_inc_ref(ctx, s);
|
|
||||||
Z3_ast k1 = mk_bool_var(ctx, "k1");
|
Z3_ast k1 = mk_bool_var(ctx, "k1");
|
||||||
Z3_ast k2 = mk_bool_var(ctx, "k2");
|
Z3_ast k2 = mk_bool_var(ctx, "k2");
|
||||||
Z3_ast k3 = mk_bool_var(ctx, "k3");
|
Z3_ast k3 = mk_bool_var(ctx, "k3");
|
||||||
|
@ -460,7 +467,7 @@ int naive_maxsat(Z3_context ctx, Z3_solver s, unsigned num_hard_cnstrs, Z3_ast *
|
||||||
printf("unsat\n");
|
printf("unsat\n");
|
||||||
return num_soft_cnstrs - k - 1;
|
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);
|
Z3_model_inc_ref(ctx, m);
|
||||||
num_disabled = get_num_disabled_soft_constraints(ctx, m, num_soft_cnstrs, aux_vars);
|
num_disabled = get_num_disabled_soft_constraints(ctx, m, num_soft_cnstrs, aux_vars);
|
||||||
Z3_model_dec_ref(ctx, m);
|
Z3_model_dec_ref(ctx, m);
|
||||||
|
@ -523,7 +530,7 @@ int fu_malik_maxsat_step(Z3_context ctx, Z3_solver s, unsigned num_soft_cnstrs,
|
||||||
unsigned j;
|
unsigned j;
|
||||||
// check whether assumption[i] is in the core or not
|
// check whether assumption[i] is in the core or not
|
||||||
for (j = 0; j < core_size; j++) {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
if (j < core_size) {
|
if (j < core_size) {
|
||||||
|
@ -607,8 +614,7 @@ int smtlib_maxsat(char * file_name, int approach)
|
||||||
Z3_ast * hard_cnstrs, * soft_cnstrs;
|
Z3_ast * hard_cnstrs, * soft_cnstrs;
|
||||||
unsigned result = 0;
|
unsigned result = 0;
|
||||||
ctx = mk_context();
|
ctx = mk_context();
|
||||||
s = Z3_mk_solver(ctx);
|
s = mk_solver(ctx);
|
||||||
Z3_solver_inc_ref(ctx, s);
|
|
||||||
Z3_parse_smtlib_file(ctx, file_name, 0, 0, 0, 0, 0, 0);
|
Z3_parse_smtlib_file(ctx, file_name, 0, 0, 0, 0, 0, 0);
|
||||||
hard_cnstrs = get_hard_constraints(ctx, &num_hard_cnstrs);
|
hard_cnstrs = get_hard_constraints(ctx, &num_hard_cnstrs);
|
||||||
soft_cnstrs = get_soft_constraints(ctx, &num_soft_cnstrs);
|
soft_cnstrs = get_soft_constraints(ctx, &num_soft_cnstrs);
|
||||||
|
|
|
@ -104,6 +104,8 @@ GIT_DESCRIBE=False
|
||||||
SLOW_OPTIMIZE=False
|
SLOW_OPTIMIZE=False
|
||||||
USE_OMP=True
|
USE_OMP=True
|
||||||
LOG_SYNC=False
|
LOG_SYNC=False
|
||||||
|
GUARD_CF=False
|
||||||
|
ALWAYS_DYNAMIC_BASE=False
|
||||||
|
|
||||||
FPMATH="Default"
|
FPMATH="Default"
|
||||||
FPMATH_FLAGS="-mfpmath=sse -msse -msse2"
|
FPMATH_FLAGS="-mfpmath=sse -msse -msse2"
|
||||||
|
@ -623,13 +625,13 @@ def display_help(exit_code):
|
||||||
print(" -d, --debug compile Z3 in debug mode.")
|
print(" -d, --debug compile Z3 in debug mode.")
|
||||||
print(" -t, --trace enable tracing in release mode.")
|
print(" -t, --trace enable tracing in release mode.")
|
||||||
if IS_WINDOWS:
|
if IS_WINDOWS:
|
||||||
|
print(" --guardcf enable Control Flow Guard runtime checks.")
|
||||||
print(" -x, --x64 create 64 binary when using Visual Studio.")
|
print(" -x, --x64 create 64 binary when using Visual Studio.")
|
||||||
else:
|
else:
|
||||||
print(" --x86 force 32-bit x86 build on x64 systems.")
|
print(" --x86 force 32-bit x86 build on x64 systems.")
|
||||||
print(" -m, --makefiles generate only makefiles.")
|
print(" -m, --makefiles generate only makefiles.")
|
||||||
if IS_WINDOWS:
|
if IS_WINDOWS:
|
||||||
print(" -v, --vsproj generate Visual Studio Project Files.")
|
print(" -v, --vsproj generate Visual Studio Project Files.")
|
||||||
if IS_WINDOWS:
|
|
||||||
print(" --optimize generate optimized code during linking.")
|
print(" --optimize generate optimized code during linking.")
|
||||||
print(" --dotnet generate .NET bindings.")
|
print(" --dotnet generate .NET bindings.")
|
||||||
print(" --dotnet-key=<file> sign the .NET assembly using the private key in <file>.")
|
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 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 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 LINUX_X64, SLOW_OPTIMIZE, USE_OMP, LOG_SYNC
|
||||||
|
global GUARD_CF, ALWAYS_DYNAMIC_BASE
|
||||||
try:
|
try:
|
||||||
options, remainder = getopt.gnu_getopt(sys.argv[1:],
|
options, remainder = getopt.gnu_getopt(sys.argv[1:],
|
||||||
'b:df:sxhmcvtnp:gj',
|
'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',
|
'trace', 'dotnet', 'dotnet-key=', 'staticlib', 'prefix=', 'gmp', 'java', 'parallel=', 'gprof',
|
||||||
'githash=', 'git-describe', 'x86', 'ml', 'optimize', 'noomp', 'pypkgdir=', 'python', 'staticbin', 'log-sync'])
|
'githash=', 'git-describe', 'x86', 'ml', 'optimize', 'noomp', 'pypkgdir=', 'python', 'staticbin', 'log-sync'])
|
||||||
except:
|
except:
|
||||||
|
@ -742,6 +745,9 @@ def parse_options():
|
||||||
elif opt in ('--python'):
|
elif opt in ('--python'):
|
||||||
PYTHON_ENABLED = True
|
PYTHON_ENABLED = True
|
||||||
PYTHON_INSTALL_ENABLED = True
|
PYTHON_INSTALL_ENABLED = True
|
||||||
|
elif opt == '--guardcf':
|
||||||
|
GUARD_CF = True
|
||||||
|
ALWAYS_DYNAMIC_BASE = True # /GUARD:CF requires /DYNAMICBASE
|
||||||
else:
|
else:
|
||||||
print("ERROR: Invalid command line option '%s'" % opt)
|
print("ERROR: Invalid command line option '%s'" % opt)
|
||||||
display_help(1)
|
display_help(1)
|
||||||
|
@ -2310,6 +2316,7 @@ def mk_config():
|
||||||
'SLINK_OUT_FLAG=/Fe\n'
|
'SLINK_OUT_FLAG=/Fe\n'
|
||||||
'OS_DEFINES=/D _WINDOWS\n')
|
'OS_DEFINES=/D _WINDOWS\n')
|
||||||
extra_opt = ''
|
extra_opt = ''
|
||||||
|
link_extra_opt = ''
|
||||||
HAS_OMP = test_openmp('cl')
|
HAS_OMP = test_openmp('cl')
|
||||||
if HAS_OMP:
|
if HAS_OMP:
|
||||||
extra_opt = ' /openmp'
|
extra_opt = ' /openmp'
|
||||||
|
@ -2319,10 +2326,14 @@ def mk_config():
|
||||||
extra_opt = '%s /DZ3_LOG_SYNC' % extra_opt
|
extra_opt = '%s /DZ3_LOG_SYNC' % extra_opt
|
||||||
if GIT_HASH:
|
if GIT_HASH:
|
||||||
extra_opt = ' %s /D Z3GITHASH=%s' % (extra_opt, 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:
|
if STATIC_BIN:
|
||||||
static_opt = '/MT'
|
static_opt = '/MT'
|
||||||
else:
|
else:
|
||||||
static_opt = '/MD'
|
static_opt = '/MD'
|
||||||
|
maybe_disable_dynamic_base = '/DYNAMICBASE' if ALWAYS_DYNAMIC_BASE else '/DYNAMICBASE:NO'
|
||||||
if DEBUG_MODE:
|
if DEBUG_MODE:
|
||||||
static_opt = static_opt + 'd'
|
static_opt = static_opt + 'd'
|
||||||
config.write(
|
config.write(
|
||||||
|
@ -2333,8 +2344,8 @@ def mk_config():
|
||||||
config.write(
|
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))
|
'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(
|
config.write(
|
||||||
'LINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X64 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT\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 /DYNAMICBASE:NO\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:
|
elif VS_ARM:
|
||||||
print("ARM on VS is unsupported")
|
print("ARM on VS is unsupported")
|
||||||
exit(1)
|
exit(1)
|
||||||
|
@ -2342,8 +2353,8 @@ def mk_config():
|
||||||
config.write(
|
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))
|
'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(
|
config.write(
|
||||||
'LINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X86 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT\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 /DYNAMICBASE:NO\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:
|
else:
|
||||||
# Windows Release mode
|
# Windows Release mode
|
||||||
LTCG=' /LTCG' if SLOW_OPTIMIZE else ''
|
LTCG=' /LTCG' if SLOW_OPTIMIZE else ''
|
||||||
|
@ -2358,8 +2369,8 @@ def mk_config():
|
||||||
config.write(
|
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))
|
'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(
|
config.write(
|
||||||
'LINK_EXTRA_FLAGS=/link%s /MACHINE:X64 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608\n'
|
'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\n' % (LTCG, LTCG))
|
'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:
|
elif VS_ARM:
|
||||||
print("ARM on VS is unsupported")
|
print("ARM on VS is unsupported")
|
||||||
exit(1)
|
exit(1)
|
||||||
|
@ -2367,8 +2378,8 @@ def mk_config():
|
||||||
config.write(
|
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))
|
'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(
|
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'
|
'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 /DYNAMICBASE:NO\n' % (LTCG, LTCG))
|
'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))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,7 @@ public class Fixedpoint extends Z3Object
|
||||||
/**
|
/**
|
||||||
* Add rule into the fixedpoint solver.
|
* Add rule into the fixedpoint solver.
|
||||||
*
|
*
|
||||||
|
* @param rule implication (Horn clause) representing rule
|
||||||
* @param name Nullable rule name.
|
* @param name Nullable rule name.
|
||||||
* @throws Z3Exception
|
* @throws Z3Exception
|
||||||
**/
|
**/
|
||||||
|
@ -178,6 +179,7 @@ public class Fixedpoint extends Z3Object
|
||||||
/**
|
/**
|
||||||
* Update named rule into in the fixedpoint solver.
|
* Update named rule into in the fixedpoint solver.
|
||||||
*
|
*
|
||||||
|
* @param rule implication (Horn clause) representing rule
|
||||||
* @param name Nullable rule name.
|
* @param name Nullable rule name.
|
||||||
* @throws Z3Exception
|
* @throws Z3Exception
|
||||||
**/
|
**/
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
Several online tutorials for Z3Py are available at:
|
Several online tutorials for Z3Py are available at:
|
||||||
http://rise4fun.com/Z3Py/tutorial/guide
|
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:
|
Small example:
|
||||||
|
|
||||||
|
@ -6054,6 +6054,24 @@ class Solver(Z3PPObject):
|
||||||
"""
|
"""
|
||||||
Z3_solver_pop(self.ctx.ref(), self.solver, num)
|
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):
|
def reset(self):
|
||||||
"""Remove all asserted constraints and backtracking points created using `push()`.
|
"""Remove all asserted constraints and backtracking points created using `push()`.
|
||||||
|
|
||||||
|
|
|
@ -396,6 +396,33 @@ typedef enum
|
||||||
The meaning is given by the equivalence
|
The meaning is given by the equivalence
|
||||||
(xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3)
|
(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_UNDEF: Undef/Null proof object.
|
||||||
|
|
||||||
- Z3_OP_PR_TRUE: Proof for the expression 'true'.
|
- Z3_OP_PR_TRUE: Proof for the expression 'true'.
|
||||||
|
@ -5349,7 +5376,10 @@ extern "C" {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Add a new formula \c a to the given goal.
|
\brief Add a new formula \c a to the given goal.
|
||||||
Conjunctions are split into separate formulas.
|
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 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 true, then nothing is added.
|
||||||
If the formula \c a is \c false, then the entire goal is replaced by the formula \c false.
|
If the formula \c a is \c false, then the entire goal is replaced by the formula \c false.
|
||||||
|
|
|
@ -275,7 +275,9 @@ public:
|
||||||
bool is_uminus(expr const * n) const { return is_app_of(n, m_afid, OP_UMINUS); }
|
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_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_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_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_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_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); }
|
bool is_to_real(expr const * n) const { return is_app_of(n, m_afid, OP_TO_REAL); }
|
||||||
|
|
|
@ -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("bvudiv_i", OP_BUDIV_I));
|
||||||
op_names.push_back(builtin_name("bvsrem_i", OP_BSREM_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("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_left",OP_EXT_ROTATE_LEFT));
|
||||||
op_names.push_back(builtin_name("ext_rotate_right",OP_EXT_ROTATE_RIGHT));
|
op_names.push_back(builtin_name("ext_rotate_right",OP_EXT_ROTATE_RIGHT));
|
||||||
|
|
|
@ -1632,8 +1632,6 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args,
|
||||||
|
|
||||||
res_exp = e_exp;
|
res_exp = e_exp;
|
||||||
|
|
||||||
// Result could overflow into 4.xxx ...
|
|
||||||
|
|
||||||
family_id bvfid = m_bv_util.get_fid();
|
family_id bvfid = m_bv_util.get_fid();
|
||||||
expr_ref res_sgn_c1(m), res_sgn_c2(m), res_sgn_c3(m);
|
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);
|
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 };
|
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);
|
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) {
|
if (sbits > 5) {
|
||||||
sticky_raw = m_bv_util.mk_extract(sbits - 5, 0, sig_abs);
|
expr_ref sticky_raw(m), sig_upper(m), sticky_redd(m), res_sig_norm(m);
|
||||||
sticky = m_bv_util.mk_zero_extend(sbits + 3, m.mk_app(bvfid, OP_BREDOR, sticky_raw.get()));
|
sticky_raw = m_bv_util.mk_extract(sbits - 4, 0, sig_abs);
|
||||||
expr * res_or_args[2] = { m_bv_util.mk_extract(2 * sbits - 1, sbits - 4, sig_abs), sticky };
|
sig_upper = m_bv_util.mk_extract(2 * sbits, sbits - 3, sig_abs);
|
||||||
res_sig = m_bv_util.mk_bv_or(2, res_or_args);
|
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 {
|
else {
|
||||||
unsigned too_short = 6 - sbits;
|
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);
|
res_sig = m_bv_util.mk_extract(sbits + 3, 0, sig_abs);
|
||||||
}
|
}
|
||||||
dbg_decouple("fpa2bv_fma_add_sum_sticky", sticky);
|
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);
|
SASSERT(m_bv_util.get_bv_size(res_sig) == sbits + 4);
|
||||||
|
|
||||||
expr_ref is_zero_sig(m), nil_sbits4(m);
|
expr_ref is_zero_sig(m), nil_sbits4(m);
|
||||||
|
|
|
@ -1030,7 +1030,7 @@ br_status arith_rewriter::mk_power_core(expr * arg1, expr * arg2, expr_ref & res
|
||||||
|
|
||||||
br_status arith_rewriter::mk_to_int_core(expr * arg, expr_ref & result) {
|
br_status arith_rewriter::mk_to_int_core(expr * arg, expr_ref & result) {
|
||||||
numeral a;
|
numeral a;
|
||||||
expr* x;
|
expr* x = 0;
|
||||||
if (m_util.is_numeral(arg, a)) {
|
if (m_util.is_numeral(arg, a)) {
|
||||||
result = m_util.mk_numeral(floor(a), true);
|
result = m_util.mk_numeral(floor(a), true);
|
||||||
return BR_DONE;
|
return BR_DONE;
|
||||||
|
|
|
@ -85,7 +85,7 @@ void substitution::apply(unsigned num_actual_offsets, unsigned const * deltas, e
|
||||||
m_state = APPLY;
|
m_state = APPLY;
|
||||||
|
|
||||||
unsigned j;
|
unsigned j;
|
||||||
expr * e;
|
expr * e = 0;
|
||||||
unsigned off;
|
unsigned off;
|
||||||
expr_offset n1;
|
expr_offset n1;
|
||||||
bool visited;
|
bool visited;
|
||||||
|
@ -214,7 +214,7 @@ void substitution::apply(unsigned num_actual_offsets, unsigned const * deltas, e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SASSERT(m_apply_cache.contains(n));
|
SASSERT(m_apply_cache.contains(n));
|
||||||
m_apply_cache.find(n, e);
|
VERIFY(m_apply_cache.find(n, e));
|
||||||
m_new_exprs.push_back(e);
|
m_new_exprs.push_back(e);
|
||||||
result = e;
|
result = e;
|
||||||
|
|
||||||
|
|
|
@ -72,14 +72,22 @@ void func_decls::finalize(ast_manager & m) {
|
||||||
m_decls = 0;
|
m_decls = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool func_decls::signatures_collide(func_decl* f, func_decl* g) const {
|
||||||
|
return f == g;
|
||||||
|
}
|
||||||
|
|
||||||
bool func_decls::contains(func_decl * f) const {
|
bool func_decls::contains(func_decl * f) const {
|
||||||
if (GET_TAG(m_decls) == 0) {
|
if (GET_TAG(m_decls) == 0) {
|
||||||
return UNTAG(func_decl*, m_decls) == f;
|
func_decl* g = UNTAG(func_decl*, m_decls);
|
||||||
|
return g && signatures_collide(f, g);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
func_decl_set * fs = UNTAG(func_decl_set *, m_decls);
|
func_decl_set * fs = UNTAG(func_decl_set *, m_decls);
|
||||||
return fs->contains(f);
|
for (func_decl* g : *fs) {
|
||||||
|
if (signatures_collide(f, g)) return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool func_decls::insert(ast_manager & m, func_decl * f) {
|
bool func_decls::insert(ast_manager & m, func_decl * f) {
|
||||||
|
|
|
@ -42,6 +42,7 @@ Notes:
|
||||||
|
|
||||||
class func_decls {
|
class func_decls {
|
||||||
func_decl * m_decls;
|
func_decl * m_decls;
|
||||||
|
bool signatures_collide(func_decl* f, func_decl* g) const;
|
||||||
public:
|
public:
|
||||||
func_decls():m_decls(0) {}
|
func_decls():m_decls(0) {}
|
||||||
func_decls(ast_manager & m, func_decl * f);
|
func_decls(ast_manager & m, func_decl * f);
|
||||||
|
|
|
@ -668,7 +668,7 @@ namespace datalog {
|
||||||
T * el = it->m_key;
|
T * el = it->m_key;
|
||||||
item_set * out_edges = it->m_value;
|
item_set * out_edges = it->m_value;
|
||||||
|
|
||||||
unsigned el_comp;
|
unsigned el_comp = 0;
|
||||||
VERIFY( m_component_nums.find(el, el_comp) );
|
VERIFY( m_component_nums.find(el, el_comp) );
|
||||||
|
|
||||||
item_set::iterator eit = out_edges->begin();
|
item_set::iterator eit = out_edges->begin();
|
||||||
|
|
|
@ -51,7 +51,8 @@ void rule_properties::collect(rule_set const& rules) {
|
||||||
for (unsigned i = 0; m_inf_sort.empty() && i < r->get_decl()->get_arity(); ++i) {
|
for (unsigned i = 0; m_inf_sort.empty() && i < r->get_decl()->get_arity(); ++i) {
|
||||||
sort* d = r->get_decl()->get_domain(i);
|
sort* d = r->get_decl()->get_domain(i);
|
||||||
sort_size sz = d->get_num_elements();
|
sort_size sz = d->get_num_elements();
|
||||||
if (!sz.is_finite()) {
|
if (!sz.is_finite() && !m_dl.is_rule_sort(d)) {
|
||||||
|
TRACE("dl", tout << "sort " << mk_pp(d, m) << " is not finite " << sz << "\n";);
|
||||||
m_inf_sort.push_back(m_rule);
|
m_inf_sort.push_back(m_rule);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,13 +36,10 @@ namespace datalog {
|
||||||
|
|
||||||
|
|
||||||
void relation_manager::reset_relations() {
|
void relation_manager::reset_relations() {
|
||||||
relation_map::iterator it=m_relations.begin();
|
for (auto const& kv : m_relations) {
|
||||||
relation_map::iterator end=m_relations.end();
|
func_decl * pred = kv.m_key;
|
||||||
for(;it!=end;++it) {
|
|
||||||
func_decl * pred = it->m_key;
|
|
||||||
get_context().get_manager().dec_ref(pred); //inc_ref in get_relation
|
get_context().get_manager().dec_ref(pred); //inc_ref in get_relation
|
||||||
relation_base * r=(*it).m_value;
|
kv.m_value->deallocate();
|
||||||
r->deallocate();
|
|
||||||
}
|
}
|
||||||
m_relations.reset();
|
m_relations.reset();
|
||||||
}
|
}
|
||||||
|
@ -119,35 +116,25 @@ namespace datalog {
|
||||||
}
|
}
|
||||||
|
|
||||||
void relation_manager::collect_non_empty_predicates(decl_set & res) const {
|
void relation_manager::collect_non_empty_predicates(decl_set & res) const {
|
||||||
relation_map::iterator it = m_relations.begin();
|
for (auto const& kv : m_relations) {
|
||||||
relation_map::iterator end = m_relations.end();
|
if (!kv.m_value->fast_empty()) {
|
||||||
for(; it!=end; ++it) {
|
res.insert(kv.m_key);
|
||||||
if(!it->m_value->fast_empty()) {
|
|
||||||
res.insert(it->m_key);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void relation_manager::restrict_predicates(const decl_set & preds) {
|
void relation_manager::restrict_predicates(const decl_set & preds) {
|
||||||
typedef ptr_vector<func_decl> fd_vector;
|
ptr_vector<func_decl> to_remove;
|
||||||
fd_vector to_remove;
|
|
||||||
|
|
||||||
relation_map::iterator rit = m_relations.begin();
|
for (auto const& kv : m_relations) {
|
||||||
relation_map::iterator rend = m_relations.end();
|
func_decl* pred = kv.m_key;
|
||||||
for(; rit!=rend; ++rit) {
|
|
||||||
func_decl * pred = rit->m_key;
|
|
||||||
if (!preds.contains(pred)) {
|
if (!preds.contains(pred)) {
|
||||||
to_remove.insert(pred);
|
to_remove.insert(pred);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fd_vector::iterator pit = to_remove.begin();
|
for (func_decl* pred : to_remove) {
|
||||||
fd_vector::iterator pend = to_remove.end();
|
m_relations.find(pred)->deallocate();
|
||||||
for(; pit!=pend; ++pit) {
|
|
||||||
func_decl * pred = *pit;
|
|
||||||
relation_base * rel;
|
|
||||||
VERIFY( m_relations.find(pred, rel) );
|
|
||||||
rel->deallocate();
|
|
||||||
m_relations.remove(pred);
|
m_relations.remove(pred);
|
||||||
get_context().get_manager().dec_ref(pred);
|
get_context().get_manager().dec_ref(pred);
|
||||||
}
|
}
|
||||||
|
@ -283,18 +270,16 @@ namespace datalog {
|
||||||
}
|
}
|
||||||
|
|
||||||
table_plugin * relation_manager::get_table_plugin(symbol const& k) {
|
table_plugin * relation_manager::get_table_plugin(symbol const& k) {
|
||||||
table_plugin_vector::iterator tpit = m_table_plugins.begin();
|
for (table_plugin * tp : m_table_plugins) {
|
||||||
table_plugin_vector::iterator tpend = m_table_plugins.end();
|
if (tp->get_name()==k) {
|
||||||
for(; tpit!=tpend; ++tpit) {
|
return tp;
|
||||||
if((*tpit)->get_name()==k) {
|
|
||||||
return *tpit;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
table_relation_plugin & relation_manager::get_table_relation_plugin(table_plugin & tp) {
|
table_relation_plugin & relation_manager::get_table_relation_plugin(table_plugin & tp) {
|
||||||
table_relation_plugin * res;
|
table_relation_plugin * res = 0;
|
||||||
VERIFY( m_table_relation_plugins.find(&tp, res) );
|
VERIFY( m_table_relation_plugins.find(&tp, res) );
|
||||||
return *res;
|
return *res;
|
||||||
}
|
}
|
||||||
|
@ -341,10 +326,9 @@ namespace datalog {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < m_relation_plugins.size(); ++i) {
|
for (relation_plugin* p1 : m_relation_plugins) {
|
||||||
p = m_relation_plugins[i];
|
if (p1->can_handle_signature(s)) {
|
||||||
if (p->can_handle_signature(s)) {
|
return p1->mk_empty(s);
|
||||||
return p->mk_empty(s);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -250,7 +250,7 @@ namespace datalog {
|
||||||
bool detect_equivalences(expr_ref_vector& v, bool inside_disjunction)
|
bool detect_equivalences(expr_ref_vector& v, bool inside_disjunction)
|
||||||
{
|
{
|
||||||
bool have_pair = false;
|
bool have_pair = false;
|
||||||
unsigned prev_pair_idx;
|
unsigned prev_pair_idx = 0;
|
||||||
arg_pair ap;
|
arg_pair ap;
|
||||||
|
|
||||||
unsigned read_idx = 0;
|
unsigned read_idx = 0;
|
||||||
|
@ -296,21 +296,20 @@ namespace datalog {
|
||||||
br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result,
|
br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result,
|
||||||
proof_ref & result_pr)
|
proof_ref & result_pr)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (m.is_not(f) && (m.is_and(args[0]) || m.is_or(args[0]))) {
|
if (m.is_not(f) && (m.is_and(args[0]) || m.is_or(args[0]))) {
|
||||||
SASSERT(num==1);
|
SASSERT(num == 1);
|
||||||
expr_ref tmp(m);
|
expr_ref tmp(m);
|
||||||
app* a = to_app(args[0]);
|
app* a = to_app(args[0]);
|
||||||
m_app_args.reset();
|
m_app_args.reset();
|
||||||
for (unsigned i = 0; i < a->get_num_args(); ++i) {
|
for (expr* arg : *a) {
|
||||||
m_brwr.mk_not(a->get_arg(i), tmp);
|
m_brwr.mk_not(arg, tmp);
|
||||||
m_app_args.push_back(tmp);
|
m_app_args.push_back(tmp);
|
||||||
}
|
}
|
||||||
if (m.is_and(args[0])) {
|
if (m.is_and(args[0])) {
|
||||||
result = m.mk_or(m_app_args.size(), m_app_args.c_ptr());
|
result = mk_or(m_app_args);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = m.mk_and(m_app_args.size(), m_app_args.c_ptr());
|
result = mk_and(m_app_args);
|
||||||
}
|
}
|
||||||
return BR_REWRITE2;
|
return BR_REWRITE2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -216,7 +216,7 @@ namespace opt {
|
||||||
rational remove_negations(smt::theory_wmaxsat& th, expr_ref_vector const& core, ptr_vector<expr>& keys, vector<rational>& weights) {
|
rational remove_negations(smt::theory_wmaxsat& th, expr_ref_vector const& core, ptr_vector<expr>& keys, vector<rational>& weights) {
|
||||||
rational min_weight(-1);
|
rational min_weight(-1);
|
||||||
for (unsigned i = 0; i < core.size(); ++i) {
|
for (unsigned i = 0; i < core.size(); ++i) {
|
||||||
expr* e;
|
expr* e = 0;
|
||||||
VERIFY(m.is_not(core[i], e));
|
VERIFY(m.is_not(core[i], e));
|
||||||
keys.push_back(m_keys[e]);
|
keys.push_back(m_keys[e]);
|
||||||
rational weight = m_weights[e];
|
rational weight = m_weights[e];
|
||||||
|
|
|
@ -2503,7 +2503,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void subst(contains_app& x, rational const& vl, expr_ref& fml, expr_ref* def) {
|
virtual void subst(contains_app& x, rational const& vl, expr_ref& fml, expr_ref* def) {
|
||||||
nlarith::branch_conditions *brs;
|
nlarith::branch_conditions *brs = 0;
|
||||||
VERIFY (m_cache.find(x.x(), fml, brs));
|
VERIFY (m_cache.find(x.x(), fml, brs));
|
||||||
SASSERT(vl.is_unsigned());
|
SASSERT(vl.is_unsigned());
|
||||||
SASSERT(vl.get_unsigned() < brs->size());
|
SASSERT(vl.get_unsigned() < brs->size());
|
||||||
|
|
|
@ -32,7 +32,7 @@ namespace sat {
|
||||||
void model_converter::reset() {
|
void model_converter::reset() {
|
||||||
m_entries.finalize();
|
m_entries.finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void model_converter::operator()(model & m) const {
|
void model_converter::operator()(model & m) const {
|
||||||
vector<entry>::const_iterator begin = m_entries.begin();
|
vector<entry>::const_iterator begin = m_entries.begin();
|
||||||
vector<entry>::const_iterator it = m_entries.end();
|
vector<entry>::const_iterator it = m_entries.end();
|
||||||
|
@ -46,7 +46,7 @@ namespace sat {
|
||||||
literal_vector::const_iterator it2 = it->m_clauses.begin();
|
literal_vector::const_iterator it2 = it->m_clauses.begin();
|
||||||
literal_vector::const_iterator end2 = it->m_clauses.end();
|
literal_vector::const_iterator end2 = it->m_clauses.end();
|
||||||
for (; it2 != end2; ++it2) {
|
for (; it2 != end2; ++it2) {
|
||||||
literal l = *it2;
|
literal l = *it2;
|
||||||
if (l == null_literal) {
|
if (l == null_literal) {
|
||||||
// end of clause
|
// end of clause
|
||||||
if (!sat) {
|
if (!sat) {
|
||||||
|
@ -56,6 +56,7 @@ namespace sat {
|
||||||
sat = false;
|
sat = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sat)
|
if (sat)
|
||||||
continue;
|
continue;
|
||||||
bool sign = l.sign();
|
bool sign = l.sign();
|
||||||
|
@ -125,7 +126,7 @@ namespace sat {
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
model_converter::entry & model_converter::mk(kind k, bool_var v) {
|
model_converter::entry & model_converter::mk(kind k, bool_var v) {
|
||||||
m_entries.push_back(entry(k, v));
|
m_entries.push_back(entry(k, v));
|
||||||
entry & e = m_entries.back();
|
entry & e = m_entries.back();
|
||||||
|
@ -218,7 +219,7 @@ namespace sat {
|
||||||
out << *it2;
|
out << *it2;
|
||||||
}
|
}
|
||||||
out << ")";
|
out << ")";
|
||||||
}
|
}
|
||||||
out << ")\n";
|
out << ")\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,4 +238,22 @@ namespace sat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned model_converter::max_var(unsigned min) const {
|
||||||
|
unsigned result = min;
|
||||||
|
vector<entry>::const_iterator it = m_entries.begin();
|
||||||
|
vector<entry>::const_iterator end = m_entries.end();
|
||||||
|
for (; it != end; ++it) {
|
||||||
|
literal_vector::const_iterator lvit = it->m_clauses.begin();
|
||||||
|
literal_vector::const_iterator lvend = it->m_clauses.end();
|
||||||
|
for (; lvit != lvend; ++lvit) {
|
||||||
|
literal l = *lvit;
|
||||||
|
if (l != null_literal) {
|
||||||
|
if (l.var() > result)
|
||||||
|
result = l.var();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace sat {
|
||||||
\brief Stores eliminated variables and Blocked clauses.
|
\brief Stores eliminated variables and Blocked clauses.
|
||||||
It uses these clauses to extend/patch the model produced for the
|
It uses these clauses to extend/patch the model produced for the
|
||||||
simplified CNF formula.
|
simplified CNF formula.
|
||||||
|
|
||||||
This information may also be used to support incremental solving.
|
This information may also be used to support incremental solving.
|
||||||
If new clauses are asserted into the SAT engine, then we can
|
If new clauses are asserted into the SAT engine, then we can
|
||||||
restore the state by re-asserting all clauses in the model
|
restore the state by re-asserting all clauses in the model
|
||||||
|
@ -50,7 +50,7 @@ namespace sat {
|
||||||
m_kind(src.m_kind),
|
m_kind(src.m_kind),
|
||||||
m_clauses(src.m_clauses) {
|
m_clauses(src.m_clauses) {
|
||||||
}
|
}
|
||||||
bool_var var() const { return m_var; }
|
bool_var var() const { return m_var; }
|
||||||
kind get_kind() const { return static_cast<kind>(m_kind); }
|
kind get_kind() const { return static_cast<kind>(m_kind); }
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
|
@ -74,8 +74,9 @@ namespace sat {
|
||||||
|
|
||||||
void copy(model_converter const & src);
|
void copy(model_converter const & src);
|
||||||
void collect_vars(bool_var_set & s) const;
|
void collect_vars(bool_var_set & s) const;
|
||||||
|
unsigned max_var(unsigned min) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2628,7 +2628,7 @@ namespace sat {
|
||||||
unsigned j = 0;
|
unsigned j = 0;
|
||||||
for (unsigned i = 0; i < clauses.size(); ++i) {
|
for (unsigned i = 0; i < clauses.size(); ++i) {
|
||||||
clause & c = *(clauses[i]);
|
clause & c = *(clauses[i]);
|
||||||
if (c.contains(lit)) {
|
if (c.contains(lit) || c.contains(~lit)) {
|
||||||
detach_clause(c);
|
detach_clause(c);
|
||||||
del_clause(c);
|
del_clause(c);
|
||||||
}
|
}
|
||||||
|
@ -2684,6 +2684,7 @@ namespace sat {
|
||||||
w = max_var(m_clauses, w);
|
w = max_var(m_clauses, w);
|
||||||
w = max_var(true, w);
|
w = max_var(true, w);
|
||||||
w = max_var(false, w);
|
w = max_var(false, w);
|
||||||
|
v = m_mc.max_var(w);
|
||||||
for (unsigned i = 0; i < m_trail.size(); ++i) {
|
for (unsigned i = 0; i < m_trail.size(); ++i) {
|
||||||
if (m_trail[i].var() > w) w = m_trail[i].var();
|
if (m_trail[i].var() > w) w = m_trail[i].var();
|
||||||
}
|
}
|
||||||
|
@ -3150,9 +3151,9 @@ namespace sat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Algorithm 7: Corebased Algorithm with Chunking
|
// Algorithm 7: Corebased Algorithm with Chunking
|
||||||
|
|
||||||
static void back_remove(sat::literal_vector& lits, sat::literal l) {
|
static void back_remove(sat::literal_vector& lits, sat::literal l) {
|
||||||
for (unsigned i = lits.size(); i > 0; ) {
|
for (unsigned i = lits.size(); i > 0; ) {
|
||||||
--i;
|
--i;
|
||||||
|
@ -3176,7 +3177,7 @@ namespace sat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static lbool core_chunking(sat::solver& s, model const& m, sat::bool_var_vector const& vars, sat::literal_vector const& asms, vector<sat::literal_vector>& conseq, unsigned K) {
|
static lbool core_chunking(sat::solver& s, model const& m, sat::bool_var_vector const& vars, sat::literal_vector const& asms, vector<sat::literal_vector>& conseq, unsigned K) {
|
||||||
sat::literal_vector lambda;
|
sat::literal_vector lambda;
|
||||||
for (unsigned i = 0; i < vars.size(); i++) {
|
for (unsigned i = 0; i < vars.size(); i++) {
|
||||||
|
@ -3375,7 +3376,7 @@ namespace sat {
|
||||||
if (check_inconsistent()) return l_false;
|
if (check_inconsistent()) return l_false;
|
||||||
|
|
||||||
unsigned num_iterations = 0;
|
unsigned num_iterations = 0;
|
||||||
extract_fixed_consequences(unfixed_lits, assumptions, unfixed_vars, conseq);
|
extract_fixed_consequences(unfixed_lits, assumptions, unfixed_vars, conseq);
|
||||||
update_unfixed_literals(unfixed_lits, unfixed_vars);
|
update_unfixed_literals(unfixed_lits, unfixed_vars);
|
||||||
while (!unfixed_lits.empty()) {
|
while (!unfixed_lits.empty()) {
|
||||||
if (scope_lvl() > 1) {
|
if (scope_lvl() > 1) {
|
||||||
|
@ -3390,7 +3391,7 @@ namespace sat {
|
||||||
unsigned num_assigned = 0;
|
unsigned num_assigned = 0;
|
||||||
lbool is_sat = l_true;
|
lbool is_sat = l_true;
|
||||||
for (; it != end; ++it) {
|
for (; it != end; ++it) {
|
||||||
literal lit = *it;
|
literal lit = *it;
|
||||||
if (value(lit) != l_undef) {
|
if (value(lit) != l_undef) {
|
||||||
++num_fixed;
|
++num_fixed;
|
||||||
if (lvl(lit) <= 1 && value(lit) == l_true) {
|
if (lvl(lit) <= 1 && value(lit) == l_true) {
|
||||||
|
@ -3445,8 +3446,8 @@ namespace sat {
|
||||||
<< " iterations: " << num_iterations
|
<< " iterations: " << num_iterations
|
||||||
<< " variables: " << unfixed_lits.size()
|
<< " variables: " << unfixed_lits.size()
|
||||||
<< " fixed: " << conseq.size()
|
<< " fixed: " << conseq.size()
|
||||||
<< " status: " << is_sat
|
<< " status: " << is_sat
|
||||||
<< " pre-assigned: " << num_fixed
|
<< " pre-assigned: " << num_fixed
|
||||||
<< " unfixed: " << lits.size() - conseq.size() - unfixed_lits.size()
|
<< " unfixed: " << lits.size() - conseq.size() - unfixed_lits.size()
|
||||||
<< ")\n";);
|
<< ")\n";);
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_literal(expr* e) const {
|
bool is_literal(expr* e) const {
|
||||||
return
|
return
|
||||||
is_uninterp_const(e) ||
|
is_uninterp_const(e) ||
|
||||||
(m.is_not(e, e) && is_uninterp_const(e));
|
(m.is_not(e, e) && is_uninterp_const(e));
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,7 @@ public:
|
||||||
asm2fml.insert(assumptions[i], assumptions[i]);
|
asm2fml.insert(assumptions[i], assumptions[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("sat", tout << _assumptions << "\n";);
|
TRACE("sat", tout << _assumptions << "\n";);
|
||||||
dep2asm_t dep2asm;
|
dep2asm_t dep2asm;
|
||||||
m_model = 0;
|
m_model = 0;
|
||||||
|
@ -163,7 +163,7 @@ public:
|
||||||
if (r != l_true) return r;
|
if (r != l_true) return r;
|
||||||
|
|
||||||
r = m_solver.check(m_asms.size(), m_asms.c_ptr());
|
r = m_solver.check(m_asms.size(), m_asms.c_ptr());
|
||||||
|
|
||||||
switch (r) {
|
switch (r) {
|
||||||
case l_true:
|
case l_true:
|
||||||
if (sz > 0) {
|
if (sz > 0) {
|
||||||
|
@ -280,14 +280,14 @@ public:
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
// build map from bound variables to
|
// build map from bound variables to
|
||||||
// the consequences that cover them.
|
// the consequences that cover them.
|
||||||
u_map<unsigned> bool_var2conseq;
|
u_map<unsigned> bool_var2conseq;
|
||||||
for (unsigned i = 0; i < lconseq.size(); ++i) {
|
for (unsigned i = 0; i < lconseq.size(); ++i) {
|
||||||
TRACE("sat", tout << lconseq[i] << "\n";);
|
TRACE("sat", tout << lconseq[i] << "\n";);
|
||||||
bool_var2conseq.insert(lconseq[i][0].var(), i);
|
bool_var2conseq.insert(lconseq[i][0].var(), i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// extract original fixed variables
|
// extract original fixed variables
|
||||||
u_map<expr*> asm2dep;
|
u_map<expr*> asm2dep;
|
||||||
extract_asm2dep(dep2asm, asm2dep);
|
extract_asm2dep(dep2asm, asm2dep);
|
||||||
|
@ -441,7 +441,7 @@ private:
|
||||||
|
|
||||||
lbool internalize_vars(expr_ref_vector const& vars, sat::bool_var_vector& bvars) {
|
lbool internalize_vars(expr_ref_vector const& vars, sat::bool_var_vector& bvars) {
|
||||||
for (unsigned i = 0; i < vars.size(); ++i) {
|
for (unsigned i = 0; i < vars.size(); ++i) {
|
||||||
internalize_var(vars[i], bvars);
|
internalize_var(vars[i], bvars);
|
||||||
}
|
}
|
||||||
return l_true;
|
return l_true;
|
||||||
}
|
}
|
||||||
|
@ -453,7 +453,7 @@ private:
|
||||||
bool internalized = false;
|
bool internalized = false;
|
||||||
if (is_uninterp_const(v) && m.is_bool(v)) {
|
if (is_uninterp_const(v) && m.is_bool(v)) {
|
||||||
sat::bool_var b = m_map.to_bool_var(v);
|
sat::bool_var b = m_map.to_bool_var(v);
|
||||||
|
|
||||||
if (b != sat::null_bool_var) {
|
if (b != sat::null_bool_var) {
|
||||||
bvars.push_back(b);
|
bvars.push_back(b);
|
||||||
internalized = true;
|
internalized = true;
|
||||||
|
@ -479,7 +479,7 @@ private:
|
||||||
else if (is_uninterp_const(v) && bvutil.is_bv(v)) {
|
else if (is_uninterp_const(v) && bvutil.is_bv(v)) {
|
||||||
// variable does not occur in assertions, so is unconstrained.
|
// variable does not occur in assertions, so is unconstrained.
|
||||||
}
|
}
|
||||||
CTRACE("sat", !internalized, tout << "unhandled variable " << mk_pp(v, m) << "\n";);
|
CTRACE("sat", !internalized, tout << "unhandled variable " << mk_pp(v, m) << "\n";);
|
||||||
return internalized;
|
return internalized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -506,7 +506,7 @@ private:
|
||||||
}
|
}
|
||||||
expr_ref val(m);
|
expr_ref val(m);
|
||||||
expr_ref_vector conj(m);
|
expr_ref_vector conj(m);
|
||||||
internalize_value(value, v, val);
|
internalize_value(value, v, val);
|
||||||
while (!premises.empty()) {
|
while (!premises.empty()) {
|
||||||
expr* e = 0;
|
expr* e = 0;
|
||||||
VERIFY(asm2dep.find(premises.pop().index(), e));
|
VERIFY(asm2dep.find(premises.pop().index(), e));
|
||||||
|
|
|
@ -23,7 +23,7 @@ bool cached_var_subst::key_eq_proc::operator()(cached_var_subst::key * k1, cache
|
||||||
return false;
|
return false;
|
||||||
if (k1->m_num_bindings != k2->m_num_bindings)
|
if (k1->m_num_bindings != k2->m_num_bindings)
|
||||||
return false;
|
return false;
|
||||||
for (unsigned i = 0; i < k1->m_num_bindings; i++)
|
for (unsigned i = 0; i < k1->m_num_bindings; i++)
|
||||||
if (k1->m_bindings[i] != k2->m_bindings[i])
|
if (k1->m_bindings[i] != k2->m_bindings[i])
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
|
@ -49,9 +49,9 @@ void cached_var_subst::operator()(quantifier * qa, unsigned num_bindings, smt::e
|
||||||
|
|
||||||
new_key->m_qa = qa;
|
new_key->m_qa = qa;
|
||||||
new_key->m_num_bindings = num_bindings;
|
new_key->m_num_bindings = num_bindings;
|
||||||
for (unsigned i = 0; i < num_bindings; i++)
|
for (unsigned i = 0; i < num_bindings; i++)
|
||||||
new_key->m_bindings[i] = bindings[i]->get_owner();
|
new_key->m_bindings[i] = bindings[i]->get_owner();
|
||||||
|
|
||||||
instances::entry * entry = m_instances.insert_if_not_there2(new_key, 0);
|
instances::entry * entry = m_instances.insert_if_not_there2(new_key, 0);
|
||||||
if (entry->get_data().m_key != new_key) {
|
if (entry->get_data().m_key != new_key) {
|
||||||
SASSERT(entry->get_data().m_value != 0);
|
SASSERT(entry->get_data().m_value != 0);
|
||||||
|
@ -60,20 +60,27 @@ void cached_var_subst::operator()(quantifier * qa, unsigned num_bindings, smt::e
|
||||||
result = entry->get_data().m_value;
|
result = entry->get_data().m_value;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_proc(qa->get_expr(), new_key->m_num_bindings, new_key->m_bindings, result);
|
SASSERT(entry->get_data().m_value == 0);
|
||||||
|
try {
|
||||||
|
m_proc(qa->get_expr(), new_key->m_num_bindings, new_key->m_bindings, result);
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
// CMW: The var_subst reducer was interrupted and m_instances is
|
||||||
|
// in an inconsistent state; we need to remove (new_key, 0).
|
||||||
|
m_instances.remove(new_key);
|
||||||
|
throw; // Throw on to smt::qi_queue/smt::solver.
|
||||||
|
}
|
||||||
|
|
||||||
// cache result
|
// cache result
|
||||||
entry->get_data().m_value = result;
|
entry->get_data().m_value = result;
|
||||||
|
|
||||||
// remove key from cache
|
// remove key from cache
|
||||||
m_new_keys[num_bindings] = 0;
|
m_new_keys[num_bindings] = 0;
|
||||||
|
|
||||||
// increment reference counters
|
// increment reference counters
|
||||||
m_refs.push_back(qa);
|
m_refs.push_back(qa);
|
||||||
for (unsigned i = 0; i < new_key->m_num_bindings; i++)
|
for (unsigned i = 0; i < new_key->m_num_bindings; i++)
|
||||||
m_refs.push_back(new_key->m_bindings[i]);
|
m_refs.push_back(new_key->m_bindings[i]);
|
||||||
m_refs.push_back(result);
|
m_refs.push_back(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace smt {
|
||||||
init_parser_vars();
|
init_parser_vars();
|
||||||
m_vals.resize(15, 0.0f);
|
m_vals.resize(15, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
qi_queue::~qi_queue() {
|
qi_queue::~qi_queue() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ namespace smt {
|
||||||
if (!m_parser.parse_string(m_params.m_qi_cost.c_str(), m_cost_function)) {
|
if (!m_parser.parse_string(m_params.m_qi_cost.c_str(), m_cost_function)) {
|
||||||
// it is not reasonable to abort here during the creation of smt::context just because an invalid option was provided.
|
// it is not reasonable to abort here during the creation of smt::context just because an invalid option was provided.
|
||||||
// throw default_exception("invalid cost function %s", m_params.m_qi_cost.c_str());
|
// throw default_exception("invalid cost function %s", m_params.m_qi_cost.c_str());
|
||||||
|
|
||||||
// using warning message instead
|
// using warning message instead
|
||||||
warning_msg("invalid cost function '%s', switching to default one", m_params.m_qi_cost.c_str());
|
warning_msg("invalid cost function '%s', switching to default one", m_params.m_qi_cost.c_str());
|
||||||
// Trying again with default function
|
// Trying again with default function
|
||||||
|
@ -107,7 +107,7 @@ namespace smt {
|
||||||
m_vals[SIZE] = static_cast<float>(stat->get_size());
|
m_vals[SIZE] = static_cast<float>(stat->get_size());
|
||||||
m_vals[DEPTH] = static_cast<float>(stat->get_depth());
|
m_vals[DEPTH] = static_cast<float>(stat->get_depth());
|
||||||
m_vals[GENERATION] = static_cast<float>(generation);
|
m_vals[GENERATION] = static_cast<float>(generation);
|
||||||
m_vals[QUANT_GENERATION] = static_cast<float>(stat->get_generation());
|
m_vals[QUANT_GENERATION] = static_cast<float>(stat->get_generation());
|
||||||
m_vals[WEIGHT] = static_cast<float>(q->get_weight());
|
m_vals[WEIGHT] = static_cast<float>(q->get_weight());
|
||||||
m_vals[VARS] = static_cast<float>(q->get_num_decls());
|
m_vals[VARS] = static_cast<float>(q->get_num_decls());
|
||||||
m_vals[PATTERN_WIDTH] = pat ? static_cast<float>(pat->get_num_args()) : 1.0f;
|
m_vals[PATTERN_WIDTH] = pat ? static_cast<float>(pat->get_num_args()) : 1.0f;
|
||||||
|
@ -118,7 +118,7 @@ namespace smt {
|
||||||
TRACE("qi_queue_detail", for (unsigned i = 0; i < m_vals.size(); i++) { tout << m_vals[i] << " "; } tout << "\n";);
|
TRACE("qi_queue_detail", for (unsigned i = 0; i < m_vals.size(); i++) { tout << m_vals[i] << " "; } tout << "\n";);
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
float qi_queue::get_cost(quantifier * q, app * pat, unsigned generation, unsigned min_top_generation, unsigned max_top_generation) {
|
float qi_queue::get_cost(quantifier * q, app * pat, unsigned generation, unsigned min_top_generation, unsigned max_top_generation) {
|
||||||
quantifier_stat * stat = set_values(q, pat, generation, min_top_generation, max_top_generation, 0);
|
quantifier_stat * stat = set_values(q, pat, generation, min_top_generation, max_top_generation, 0);
|
||||||
float r = m_evaluator(m_cost_function, m_vals.size(), m_vals.c_ptr());
|
float r = m_evaluator(m_cost_function, m_vals.size(), m_vals.c_ptr());
|
||||||
|
@ -132,11 +132,11 @@ namespace smt {
|
||||||
float r = m_evaluator(m_new_gen_function, m_vals.size(), m_vals.c_ptr());
|
float r = m_evaluator(m_new_gen_function, m_vals.size(), m_vals.c_ptr());
|
||||||
return static_cast<unsigned>(r);
|
return static_cast<unsigned>(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
void qi_queue::insert(fingerprint * f, app * pat, unsigned generation, unsigned min_top_generation, unsigned max_top_generation) {
|
void qi_queue::insert(fingerprint * f, app * pat, unsigned generation, unsigned min_top_generation, unsigned max_top_generation) {
|
||||||
quantifier * q = static_cast<quantifier*>(f->get_data());
|
quantifier * q = static_cast<quantifier*>(f->get_data());
|
||||||
float cost = get_cost(q, pat, generation, min_top_generation, max_top_generation);
|
float cost = get_cost(q, pat, generation, min_top_generation, max_top_generation);
|
||||||
TRACE("qi_queue_detail",
|
TRACE("qi_queue_detail",
|
||||||
tout << "new instance of " << q->get_qid() << ", weight " << q->get_weight()
|
tout << "new instance of " << q->get_qid() << ", weight " << q->get_weight()
|
||||||
<< ", generation: " << generation << ", scope_level: " << m_context.get_scope_level() << ", cost: " << cost << "\n";
|
<< ", generation: " << generation << ", scope_level: " << m_context.get_scope_level() << ", cost: " << cost << "\n";
|
||||||
for (unsigned i = 0; i < f->get_num_args(); i++) {
|
for (unsigned i = 0; i < f->get_num_args(); i++) {
|
||||||
|
@ -157,7 +157,7 @@ namespace smt {
|
||||||
quantifier * qa = static_cast<quantifier*>(f->get_data());
|
quantifier * qa = static_cast<quantifier*>(f->get_data());
|
||||||
|
|
||||||
if (curr.m_cost <= m_eager_cost_threshold) {
|
if (curr.m_cost <= m_eager_cost_threshold) {
|
||||||
instantiate(curr);
|
instantiate(curr);
|
||||||
}
|
}
|
||||||
else if (m_params.m_qi_promote_unsat && m_checker.is_unsat(qa->get_expr(), f->get_num_args(), f->get_args())) {
|
else if (m_params.m_qi_promote_unsat && m_checker.is_unsat(qa->get_expr(), f->get_num_args(), f->get_args())) {
|
||||||
// do not delay instances that produce a conflict.
|
// do not delay instances that produce a conflict.
|
||||||
|
@ -193,7 +193,7 @@ namespace smt {
|
||||||
// This nasty side-effect may change the behavior of Z3.
|
// This nasty side-effect may change the behavior of Z3.
|
||||||
m_manager.trace_stream() << " #" << bindings[i]->get_owner_id();
|
m_manager.trace_stream() << " #" << bindings[i]->get_owner_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
if (m_manager.proofs_enabled())
|
if (m_manager.proofs_enabled())
|
||||||
m_manager.trace_stream() << " #" << proof_id;
|
m_manager.trace_stream() << " #" << proof_id;
|
||||||
|
@ -233,7 +233,7 @@ namespace smt {
|
||||||
if (m_manager.is_true(s_instance)) {
|
if (m_manager.is_true(s_instance)) {
|
||||||
TRACE("checker", tout << "reduced to true, before:\n" << mk_ll_pp(instance, m_manager););
|
TRACE("checker", tout << "reduced to true, before:\n" << mk_ll_pp(instance, m_manager););
|
||||||
|
|
||||||
if (m_manager.has_trace_stream())
|
if (m_manager.has_trace_stream())
|
||||||
m_manager.trace_stream() << "[end-of-instance]\n";
|
m_manager.trace_stream() << "[end-of-instance]\n";
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -278,7 +278,7 @@ namespace smt {
|
||||||
pr1 = m_manager.mk_modus_ponens(qi_pr, rw);
|
pr1 = m_manager.mk_modus_ponens(qi_pr, rw);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
app * bare_s_lemma = m_manager.mk_or(m_manager.mk_not(q), s_instance);
|
app * bare_s_lemma = m_manager.mk_or(m_manager.mk_not(q), s_instance);
|
||||||
proof * prs[1] = { pr.get() };
|
proof * prs[1] = { pr.get() };
|
||||||
proof * cg = m_manager.mk_congruence(bare_lemma, bare_s_lemma, 1, prs);
|
proof * cg = m_manager.mk_congruence(bare_lemma, bare_s_lemma, 1, prs);
|
||||||
proof * rw = m_manager.mk_rewrite(bare_s_lemma, lemma);
|
proof * rw = m_manager.mk_rewrite(bare_s_lemma, lemma);
|
||||||
|
@ -331,13 +331,13 @@ namespace smt {
|
||||||
s.m_instances_lim = m_instances.size();
|
s.m_instances_lim = m_instances.size();
|
||||||
s.m_instantiated_trail_lim = m_instantiated_trail.size();
|
s.m_instantiated_trail_lim = m_instantiated_trail.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void qi_queue::pop_scope(unsigned num_scopes) {
|
void qi_queue::pop_scope(unsigned num_scopes) {
|
||||||
unsigned new_lvl = m_scopes.size() - num_scopes;
|
unsigned new_lvl = m_scopes.size() - num_scopes;
|
||||||
scope & s = m_scopes[new_lvl];
|
scope & s = m_scopes[new_lvl];
|
||||||
unsigned old_sz = s.m_instantiated_trail_lim;
|
unsigned old_sz = s.m_instantiated_trail_lim;
|
||||||
unsigned sz = m_instantiated_trail.size();
|
unsigned sz = m_instantiated_trail.size();
|
||||||
for (unsigned i = old_sz; i < sz; i++)
|
for (unsigned i = old_sz; i < sz; i++)
|
||||||
m_delayed_entries[m_instantiated_trail[i]].m_instantiated = false;
|
m_delayed_entries[m_instantiated_trail[i]].m_instantiated = false;
|
||||||
m_instantiated_trail.shrink(old_sz);
|
m_instantiated_trail.shrink(old_sz);
|
||||||
m_delayed_entries.shrink(s.m_delayed_entries_lim);
|
m_delayed_entries.shrink(s.m_delayed_entries_lim);
|
||||||
|
@ -359,7 +359,7 @@ namespace smt {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool qi_queue::final_check_eh() {
|
bool qi_queue::final_check_eh() {
|
||||||
TRACE("qi_queue", display_delayed_instances_stats(tout); tout << "lazy threshold: " << m_params.m_qi_lazy_threshold
|
TRACE("qi_queue", display_delayed_instances_stats(tout); tout << "lazy threshold: " << m_params.m_qi_lazy_threshold
|
||||||
<< ", scope_level: " << m_context.get_scope_level() << "\n";);
|
<< ", scope_level: " << m_context.get_scope_level() << "\n";);
|
||||||
if (m_params.m_qi_conservative_final_check) {
|
if (m_params.m_qi_conservative_final_check) {
|
||||||
bool init = false;
|
bool init = false;
|
||||||
|
@ -379,7 +379,7 @@ namespace smt {
|
||||||
entry & e = m_delayed_entries[i];
|
entry & e = m_delayed_entries[i];
|
||||||
TRACE("qi_queue", tout << e.m_qb << ", cost: " << e.m_cost << ", instantiated: " << e.m_instantiated << "\n";);
|
TRACE("qi_queue", tout << e.m_qb << ", cost: " << e.m_cost << ", instantiated: " << e.m_instantiated << "\n";);
|
||||||
if (!e.m_instantiated && e.m_cost <= min_cost) {
|
if (!e.m_instantiated && e.m_cost <= min_cost) {
|
||||||
TRACE("qi_queue",
|
TRACE("qi_queue",
|
||||||
tout << "lazy quantifier instantiation...\n" << mk_pp(static_cast<quantifier*>(e.m_qb->get_data()), m_manager) << "\ncost: " << e.m_cost << "\n";);
|
tout << "lazy quantifier instantiation...\n" << mk_pp(static_cast<quantifier*>(e.m_qb->get_data()), m_manager) << "\ncost: " << e.m_cost << "\n";);
|
||||||
result = false;
|
result = false;
|
||||||
m_instantiated_trail.push_back(i);
|
m_instantiated_trail.push_back(i);
|
||||||
|
@ -389,13 +389,13 @@ namespace smt {
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool result = true;
|
bool result = true;
|
||||||
for (unsigned i = 0; i < m_delayed_entries.size(); i++) {
|
for (unsigned i = 0; i < m_delayed_entries.size(); i++) {
|
||||||
entry & e = m_delayed_entries[i];
|
entry & e = m_delayed_entries[i];
|
||||||
TRACE("qi_queue", tout << e.m_qb << ", cost: " << e.m_cost << ", instantiated: " << e.m_instantiated << "\n";);
|
TRACE("qi_queue", tout << e.m_qb << ", cost: " << e.m_cost << ", instantiated: " << e.m_instantiated << "\n";);
|
||||||
if (!e.m_instantiated && e.m_cost <= m_params.m_qi_lazy_threshold) {
|
if (!e.m_instantiated && e.m_cost <= m_params.m_qi_lazy_threshold) {
|
||||||
TRACE("qi_queue",
|
TRACE("qi_queue",
|
||||||
tout << "lazy quantifier instantiation...\n" << mk_pp(static_cast<quantifier*>(e.m_qb->get_data()), m_manager) << "\ncost: " << e.m_cost << "\n";);
|
tout << "lazy quantifier instantiation...\n" << mk_pp(static_cast<quantifier*>(e.m_qb->get_data()), m_manager) << "\ncost: " << e.m_cost << "\n";);
|
||||||
result = false;
|
result = false;
|
||||||
m_instantiated_trail.push_back(i);
|
m_instantiated_trail.push_back(i);
|
||||||
|
@ -443,7 +443,7 @@ namespace smt {
|
||||||
quantifier * qa = *it2;
|
quantifier * qa = *it2;
|
||||||
delayed_qa_info info;
|
delayed_qa_info info;
|
||||||
qa2info.find(qa, info);
|
qa2info.find(qa, info);
|
||||||
out << qa->get_qid() << ": " << info.m_num << " [" << info.m_min_cost << ", " << info.m_max_cost << "]\n";
|
out << qa->get_qid() << ": " << info.m_num << " [" << info.m_min_cost << ", " << info.m_max_cost << "]\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,6 +482,6 @@ namespace smt {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,7 @@ namespace smt {
|
||||||
|
|
||||||
void context::justify(literal lit, index_set& s) {
|
void context::justify(literal lit, index_set& s) {
|
||||||
ast_manager& m = m_manager;
|
ast_manager& m = m_manager;
|
||||||
|
(void)m;
|
||||||
b_justification js = get_justification(lit.var());
|
b_justification js = get_justification(lit.var());
|
||||||
switch (js.get_kind()) {
|
switch (js.get_kind()) {
|
||||||
case b_justification::CLAUSE: {
|
case b_justification::CLAUSE: {
|
||||||
|
|
|
@ -135,7 +135,7 @@ namespace smt {
|
||||||
m_qi_queue.insert(f, pat, max_generation, min_top_generation, max_top_generation); // TODO
|
m_qi_queue.insert(f, pat, max_generation, min_top_generation, max_top_generation); // TODO
|
||||||
m_num_instances++;
|
m_num_instances++;
|
||||||
}
|
}
|
||||||
TRACE("quantifier",
|
TRACE("quantifier",
|
||||||
tout << mk_pp(q, m()) << " ";
|
tout << mk_pp(q, m()) << " ";
|
||||||
for (unsigned i = 0; i < num_bindings; ++i) {
|
for (unsigned i = 0; i < num_bindings; ++i) {
|
||||||
tout << mk_pp(bindings[i]->get_owner(), m()) << " ";
|
tout << mk_pp(bindings[i]->get_owner(), m()) << " ";
|
||||||
|
@ -372,7 +372,7 @@ namespace smt {
|
||||||
quantifier_manager_plugin * plugin = m_imp->m_plugin->mk_fresh();
|
quantifier_manager_plugin * plugin = m_imp->m_plugin->mk_fresh();
|
||||||
m_imp->~imp();
|
m_imp->~imp();
|
||||||
m_imp = new (m_imp) imp(*this, ctx, p, plugin);
|
m_imp = new (m_imp) imp(*this, ctx, p, plugin);
|
||||||
plugin->set_manager(*this);
|
plugin->set_manager(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void quantifier_manager::display(std::ostream & out) const {
|
void quantifier_manager::display(std::ostream & out) const {
|
||||||
|
|
|
@ -75,7 +75,7 @@ namespace smt {
|
||||||
};
|
};
|
||||||
|
|
||||||
bool model_based() const;
|
bool model_based() const;
|
||||||
bool mbqi_enabled(quantifier *q) const; // can mbqi instantiate this quantifier?
|
bool mbqi_enabled(quantifier *q) const; // can mbqi instantiate this quantifier?
|
||||||
void adjust_model(proto_model * m);
|
void adjust_model(proto_model * m);
|
||||||
check_model_result check_model(proto_model * m, obj_map<enode, app *> const & root2value);
|
check_model_result check_model(proto_model * m, obj_map<enode, app *> const & root2value);
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ namespace smt {
|
||||||
virtual void push() = 0;
|
virtual void push() = 0;
|
||||||
virtual void pop(unsigned num_scopes) = 0;
|
virtual void pop(unsigned num_scopes) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -317,6 +317,9 @@ namespace smt {
|
||||||
|
|
||||||
|
|
||||||
void found_not_handled(expr* n) {
|
void found_not_handled(expr* n) {
|
||||||
|
if (a.is_div0(n)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
m_not_handled = n;
|
m_not_handled = n;
|
||||||
if (is_app(n) && is_underspecified(to_app(n))) {
|
if (is_app(n) && is_underspecified(to_app(n))) {
|
||||||
TRACE("arith", tout << "Unhandled: " << mk_pp(n, m) << "\n";);
|
TRACE("arith", tout << "Unhandled: " << mk_pp(n, m) << "\n";);
|
||||||
|
@ -785,7 +788,7 @@ namespace smt {
|
||||||
}
|
}
|
||||||
|
|
||||||
void internalize_eq_eh(app * atom, bool_var) {
|
void internalize_eq_eh(app * atom, bool_var) {
|
||||||
expr* lhs, *rhs;
|
expr* lhs = 0, *rhs = 0;
|
||||||
VERIFY(m.is_eq(atom, lhs, rhs));
|
VERIFY(m.is_eq(atom, lhs, rhs));
|
||||||
enode * n1 = get_enode(lhs);
|
enode * n1 = get_enode(lhs);
|
||||||
enode * n2 = get_enode(rhs);
|
enode * n2 = get_enode(rhs);
|
||||||
|
@ -903,7 +906,7 @@ namespace smt {
|
||||||
// to_int (to_real x) = x
|
// to_int (to_real x) = x
|
||||||
// to_real(to_int(x)) <= x < to_real(to_int(x)) + 1
|
// to_real(to_int(x)) <= x < to_real(to_int(x)) + 1
|
||||||
void mk_to_int_axiom(app* n) {
|
void mk_to_int_axiom(app* n) {
|
||||||
expr* x, *y;
|
expr* x = 0, *y = 0;
|
||||||
VERIFY (a.is_to_int(n, x));
|
VERIFY (a.is_to_int(n, x));
|
||||||
if (a.is_to_real(x, y)) {
|
if (a.is_to_real(x, y)) {
|
||||||
mk_axiom(th.mk_eq(y, n, false));
|
mk_axiom(th.mk_eq(y, n, false));
|
||||||
|
@ -919,7 +922,7 @@ namespace smt {
|
||||||
|
|
||||||
// is_int(x) <=> to_real(to_int(x)) = x
|
// is_int(x) <=> to_real(to_int(x)) = x
|
||||||
void mk_is_int_axiom(app* n) {
|
void mk_is_int_axiom(app* n) {
|
||||||
expr* x;
|
expr* x = 0;
|
||||||
VERIFY(a.is_is_int(n, x));
|
VERIFY(a.is_is_int(n, x));
|
||||||
literal eq = th.mk_eq(a.mk_to_real(a.mk_to_int(x)), x, false);
|
literal eq = th.mk_eq(a.mk_to_real(a.mk_to_int(x)), x, false);
|
||||||
literal is_int = ctx().get_literal(n);
|
literal is_int = ctx().get_literal(n);
|
||||||
|
@ -1417,12 +1420,14 @@ namespace smt {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int num_of_p = m_solver->settings().st().m_num_of_implied_bounds;
|
int num_of_p = m_solver->settings().st().m_num_of_implied_bounds;
|
||||||
|
(void)num_of_p;
|
||||||
local_bound_propagator bp(*this);
|
local_bound_propagator bp(*this);
|
||||||
m_solver->propagate_bounds_for_touched_rows(bp);
|
m_solver->propagate_bounds_for_touched_rows(bp);
|
||||||
if (m.canceled()) {
|
if (m.canceled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int new_num_of_p = m_solver->settings().st().m_num_of_implied_bounds;
|
int new_num_of_p = m_solver->settings().st().m_num_of_implied_bounds;
|
||||||
|
(void)new_num_of_p;
|
||||||
CTRACE("arith", new_num_of_p > num_of_p, tout << "found " << new_num_of_p << " implied bounds\n";);
|
CTRACE("arith", new_num_of_p > num_of_p, tout << "found " << new_num_of_p << " implied bounds\n";);
|
||||||
if (m_solver->get_status() == lp::lp_status::INFEASIBLE) {
|
if (m_solver->get_status() == lp::lp_status::INFEASIBLE) {
|
||||||
set_conflict();
|
set_conflict();
|
||||||
|
|
|
@ -1074,7 +1074,7 @@ expr_ref theory_seq::mk_first(expr* s) {
|
||||||
|
|
||||||
|
|
||||||
void theory_seq::mk_decompose(expr* e, expr_ref& head, expr_ref& tail) {
|
void theory_seq::mk_decompose(expr* e, expr_ref& head, expr_ref& tail) {
|
||||||
expr* e1, *e2;
|
expr* e1 = 0, *e2 = 0;
|
||||||
zstring s;
|
zstring s;
|
||||||
if (m_util.str.is_empty(e)) {
|
if (m_util.str.is_empty(e)) {
|
||||||
head = m_util.str.mk_unit(mk_nth(e, m_autil.mk_int(0)));
|
head = m_util.str.mk_unit(mk_nth(e, m_autil.mk_int(0)));
|
||||||
|
@ -1401,7 +1401,7 @@ bool theory_seq::occurs(expr* a, expr* b) {
|
||||||
// true if a occurs under an interpreted function or under left/right selector.
|
// true if a occurs under an interpreted function or under left/right selector.
|
||||||
SASSERT(is_var(a));
|
SASSERT(is_var(a));
|
||||||
SASSERT(m_todo.empty());
|
SASSERT(m_todo.empty());
|
||||||
expr* e1, *e2;
|
expr* e1 = 0, *e2 = 0;
|
||||||
m_todo.push_back(b);
|
m_todo.push_back(b);
|
||||||
while (!m_todo.empty()) {
|
while (!m_todo.empty()) {
|
||||||
b = m_todo.back();
|
b = m_todo.back();
|
||||||
|
@ -1990,7 +1990,7 @@ bool theory_seq::solve_nc(unsigned idx) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
expr* e1, *e2;
|
expr* e1 = 0, *e2 = 0;
|
||||||
if (m.is_eq(c, e1, e2)) {
|
if (m.is_eq(c, e1, e2)) {
|
||||||
literal eq = mk_eq(e1, e2, false);
|
literal eq = mk_eq(e1, e2, false);
|
||||||
propagate_lit(deps, 0, 0, ~eq);
|
propagate_lit(deps, 0, 0, ~eq);
|
||||||
|
@ -2246,10 +2246,7 @@ bool theory_seq::internalize_term(app* term) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
TRACE("seq_verbose", tout << mk_pp(term, m) << "\n";);
|
TRACE("seq_verbose", tout << mk_pp(term, m) << "\n";);
|
||||||
unsigned num_args = term->get_num_args();
|
for (expr* arg : *term) {
|
||||||
expr* arg;
|
|
||||||
for (unsigned i = 0; i < num_args; i++) {
|
|
||||||
arg = term->get_arg(i);
|
|
||||||
mk_var(ensure_enode(arg));
|
mk_var(ensure_enode(arg));
|
||||||
}
|
}
|
||||||
if (m.is_bool(term)) {
|
if (m.is_bool(term)) {
|
||||||
|
@ -2316,7 +2313,7 @@ bool theory_seq::check_int_string() {
|
||||||
|
|
||||||
bool theory_seq::add_stoi_axiom(expr* e) {
|
bool theory_seq::add_stoi_axiom(expr* e) {
|
||||||
context& ctx = get_context();
|
context& ctx = get_context();
|
||||||
expr* n;
|
expr* n = 0;
|
||||||
rational val;
|
rational val;
|
||||||
TRACE("seq", tout << mk_pp(e, m) << "\n";);
|
TRACE("seq", tout << mk_pp(e, m) << "\n";);
|
||||||
VERIFY(m_util.str.is_stoi(e, n));
|
VERIFY(m_util.str.is_stoi(e, n));
|
||||||
|
@ -2398,7 +2395,7 @@ expr_ref theory_seq::digit2int(expr* ch) {
|
||||||
bool theory_seq::add_itos_axiom(expr* e) {
|
bool theory_seq::add_itos_axiom(expr* e) {
|
||||||
context& ctx = get_context();
|
context& ctx = get_context();
|
||||||
rational val;
|
rational val;
|
||||||
expr* n;
|
expr* n = 0;
|
||||||
TRACE("seq", tout << mk_pp(e, m) << "\n";);
|
TRACE("seq", tout << mk_pp(e, m) << "\n";);
|
||||||
VERIFY(m_util.str.is_itos(e, n));
|
VERIFY(m_util.str.is_itos(e, n));
|
||||||
if (get_num_value(n, val)) {
|
if (get_num_value(n, val)) {
|
||||||
|
@ -2602,9 +2599,9 @@ void theory_seq::collect_statistics(::statistics & st) const {
|
||||||
|
|
||||||
void theory_seq::init_model(expr_ref_vector const& es) {
|
void theory_seq::init_model(expr_ref_vector const& es) {
|
||||||
expr_ref new_s(m);
|
expr_ref new_s(m);
|
||||||
for (unsigned i = 0; i < es.size(); ++i) {
|
for (expr* e : es) {
|
||||||
dependency* eqs = 0;
|
dependency* eqs = 0;
|
||||||
expr_ref s = canonize(es[i], eqs);
|
expr_ref s = canonize(e, eqs);
|
||||||
if (is_var(s)) {
|
if (is_var(s)) {
|
||||||
new_s = m_factory->get_fresh_value(m.get_sort(s));
|
new_s = m_factory->get_fresh_value(m.get_sort(s));
|
||||||
m_rep.update(s, new_s, eqs);
|
m_rep.update(s, new_s, eqs);
|
||||||
|
@ -2615,13 +2612,11 @@ void theory_seq::init_model(expr_ref_vector const& es) {
|
||||||
void theory_seq::init_model(model_generator & mg) {
|
void theory_seq::init_model(model_generator & mg) {
|
||||||
m_factory = alloc(seq_factory, get_manager(), get_family_id(), mg.get_model());
|
m_factory = alloc(seq_factory, get_manager(), get_family_id(), mg.get_model());
|
||||||
mg.register_factory(m_factory);
|
mg.register_factory(m_factory);
|
||||||
for (unsigned j = 0; j < m_nqs.size(); ++j) {
|
for (ne const& n : m_nqs) {
|
||||||
ne const& n = m_nqs[j];
|
|
||||||
m_factory->register_value(n.l());
|
m_factory->register_value(n.l());
|
||||||
m_factory->register_value(n.r());
|
m_factory->register_value(n.r());
|
||||||
}
|
}
|
||||||
for (unsigned j = 0; j < m_nqs.size(); ++j) {
|
for (ne const& n : m_nqs) {
|
||||||
ne const& n = m_nqs[j];
|
|
||||||
for (unsigned i = 0; i < n.ls().size(); ++i) {
|
for (unsigned i = 0; i < n.ls().size(); ++i) {
|
||||||
init_model(n.ls(i));
|
init_model(n.ls(i));
|
||||||
init_model(n.rs(i));
|
init_model(n.rs(i));
|
||||||
|
@ -2863,77 +2858,123 @@ bool theory_seq::canonize(expr_ref_vector const& es, expr_ref_vector& result, de
|
||||||
return change;
|
return change;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expr_ref theory_seq::expand(expr* e, dependency*& eqs) {
|
||||||
expr_ref theory_seq::expand(expr* e0, dependency*& eqs) {
|
unsigned sz = m_expand_todo.size();
|
||||||
|
m_expand_todo.push_back(e);
|
||||||
expr_ref result(m);
|
expr_ref result(m);
|
||||||
dependency* deps = 0;
|
while (m_expand_todo.size() != sz) {
|
||||||
expr_dep ed;
|
expr* e = m_expand_todo.back();
|
||||||
if (m_rep.find_cache(e0, ed)) {
|
result = expand1(e, eqs);
|
||||||
eqs = m_dm.mk_join(eqs, ed.second);
|
if (result.get()) m_expand_todo.pop_back();
|
||||||
result = ed.first;
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
expr_ref theory_seq::try_expand(expr* e, dependency*& eqs){
|
||||||
|
expr_ref result(m);
|
||||||
|
expr_dep ed;
|
||||||
|
if (m_rep.find_cache(e, ed)) {
|
||||||
|
if (e != ed.first) {
|
||||||
|
eqs = m_dm.mk_join(eqs, ed.second);
|
||||||
|
}
|
||||||
|
result = ed.first;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_expand_todo.push_back(e);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
expr_ref theory_seq::expand1(expr* e0, dependency*& eqs) {
|
||||||
|
expr_ref result(m);
|
||||||
|
result = try_expand(e0, eqs);
|
||||||
|
if (result) return result;
|
||||||
|
dependency* deps = 0;
|
||||||
expr* e = m_rep.find(e0, deps);
|
expr* e = m_rep.find(e0, deps);
|
||||||
expr* e1, *e2, *e3;
|
expr* e1, *e2, *e3;
|
||||||
|
expr_ref arg1(m), arg2(m);
|
||||||
context& ctx = get_context();
|
context& ctx = get_context();
|
||||||
if (m_util.str.is_concat(e, e1, e2)) {
|
if (m_util.str.is_concat(e, e1, e2)) {
|
||||||
result = mk_concat(expand(e1, deps), expand(e2, deps));
|
arg1 = try_expand(e1, deps);
|
||||||
|
arg2 = try_expand(e2, deps);
|
||||||
|
if (!arg1 || !arg2) return result;
|
||||||
|
result = mk_concat(arg1, arg2);
|
||||||
}
|
}
|
||||||
else if (m_util.str.is_empty(e) || m_util.str.is_string(e)) {
|
else if (m_util.str.is_empty(e) || m_util.str.is_string(e)) {
|
||||||
result = e;
|
result = e;
|
||||||
}
|
}
|
||||||
else if (m_util.str.is_prefix(e, e1, e2)) {
|
else if (m_util.str.is_prefix(e, e1, e2)) {
|
||||||
result = m_util.str.mk_prefix(expand(e1, deps), expand(e2, deps));
|
arg1 = try_expand(e1, deps);
|
||||||
|
arg2 = try_expand(e2, deps);
|
||||||
|
if (!arg1 || !arg2) return result;
|
||||||
|
result = m_util.str.mk_prefix(arg1, arg2);
|
||||||
}
|
}
|
||||||
else if (m_util.str.is_suffix(e, e1, e2)) {
|
else if (m_util.str.is_suffix(e, e1, e2)) {
|
||||||
result = m_util.str.mk_suffix(expand(e1, deps), expand(e2, deps));
|
arg1 = try_expand(e1, deps);
|
||||||
|
arg2 = try_expand(e2, deps);
|
||||||
|
if (!arg1 || !arg2) return result;
|
||||||
|
result = m_util.str.mk_suffix(arg1, arg2);
|
||||||
}
|
}
|
||||||
else if (m_util.str.is_contains(e, e1, e2)) {
|
else if (m_util.str.is_contains(e, e1, e2)) {
|
||||||
result = m_util.str.mk_contains(expand(e1, deps), expand(e2, deps));
|
arg1 = try_expand(e1, deps);
|
||||||
|
arg2 = try_expand(e2, deps);
|
||||||
|
if (!arg1 || !arg2) return result;
|
||||||
|
result = m_util.str.mk_contains(arg1, arg2);
|
||||||
}
|
}
|
||||||
else if (m_util.str.is_unit(e, e1)) {
|
else if (m_util.str.is_unit(e, e1)) {
|
||||||
result = m_util.str.mk_unit(expand(e1, deps));
|
arg1 = try_expand(e1, deps);
|
||||||
|
if (!arg1) return result;
|
||||||
|
result = m_util.str.mk_unit(arg1);
|
||||||
}
|
}
|
||||||
else if (m_util.str.is_index(e, e1, e2)) {
|
else if (m_util.str.is_index(e, e1, e2)) {
|
||||||
result = m_util.str.mk_index(expand(e1, deps), expand(e2, deps), m_autil.mk_int(0));
|
arg1 = try_expand(e1, deps);
|
||||||
|
arg2 = try_expand(e2, deps);
|
||||||
|
if (!arg1 || !arg2) return result;
|
||||||
|
result = m_util.str.mk_index(arg1, arg2, m_autil.mk_int(0));
|
||||||
}
|
}
|
||||||
else if (m_util.str.is_index(e, e1, e2, e3)) {
|
else if (m_util.str.is_index(e, e1, e2, e3)) {
|
||||||
result = m_util.str.mk_index(expand(e1, deps), expand(e2, deps), e3);
|
arg1 = try_expand(e1, deps);
|
||||||
|
arg2 = try_expand(e2, deps);
|
||||||
|
if (!arg1 || !arg2) return result;
|
||||||
|
result = m_util.str.mk_index(arg1, arg2, e3);
|
||||||
}
|
}
|
||||||
else if (m.is_ite(e, e1, e2, e3)) {
|
else if (m.is_ite(e, e1, e2, e3)) {
|
||||||
if (ctx.e_internalized(e) && ctx.e_internalized(e2) && ctx.get_enode(e)->get_root() == ctx.get_enode(e2)->get_root()) {
|
if (ctx.e_internalized(e) && ctx.e_internalized(e2) && ctx.get_enode(e)->get_root() == ctx.get_enode(e2)->get_root()) {
|
||||||
result = expand(e2, deps);
|
result = try_expand(e2, deps);
|
||||||
|
if (!result) return result;
|
||||||
add_dependency(deps, ctx.get_enode(e), ctx.get_enode(e2));
|
add_dependency(deps, ctx.get_enode(e), ctx.get_enode(e2));
|
||||||
}
|
}
|
||||||
else if (ctx.e_internalized(e) && ctx.e_internalized(e2) && ctx.get_enode(e)->get_root() == ctx.get_enode(e3)->get_root()) {
|
else if (ctx.e_internalized(e) && ctx.e_internalized(e2) && ctx.get_enode(e)->get_root() == ctx.get_enode(e3)->get_root()) {
|
||||||
result = expand(e3, deps);
|
result = try_expand(e3, deps);
|
||||||
|
if (!result) return result;
|
||||||
add_dependency(deps, ctx.get_enode(e), ctx.get_enode(e3));
|
add_dependency(deps, ctx.get_enode(e), ctx.get_enode(e3));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
literal lit(mk_literal(e1));
|
literal lit(mk_literal(e1));
|
||||||
#if 0
|
#if 0
|
||||||
expr_ref sk_ite = mk_sk_ite(e1, e2, e3);
|
expr_ref sk_ite = mk_sk_ite(e1, e2, e3);
|
||||||
add_axiom(~lit, mk_eq(e2, sk_ite, false));
|
add_axiom(~lit, mk_eq(e2, sk_ite, false));
|
||||||
add_axiom( lit, mk_eq(e3, sk_ite, false));
|
add_axiom( lit, mk_eq(e3, sk_ite, false));
|
||||||
result = sk_ite;
|
result = sk_ite;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
switch (ctx.get_assignment(lit)) {
|
switch (ctx.get_assignment(lit)) {
|
||||||
case l_true:
|
case l_true:
|
||||||
deps = m_dm.mk_join(deps, m_dm.mk_leaf(assumption(lit)));
|
deps = m_dm.mk_join(deps, m_dm.mk_leaf(assumption(lit)));
|
||||||
result = expand(e2, deps);
|
result = try_expand(e2, deps);
|
||||||
break;
|
if (!result) return result;
|
||||||
case l_false:
|
break;
|
||||||
deps = m_dm.mk_join(deps, m_dm.mk_leaf(assumption(~lit)));
|
case l_false:
|
||||||
result = expand(e3, deps);
|
deps = m_dm.mk_join(deps, m_dm.mk_leaf(assumption(~lit)));
|
||||||
break;
|
result = try_expand(e3, deps);
|
||||||
case l_undef:
|
if (!result) return result;
|
||||||
result = e;
|
break;
|
||||||
m_reset_cache = true;
|
case l_undef:
|
||||||
TRACE("seq", tout << "undef: " << result << "\n";
|
result = e;
|
||||||
tout << lit << "@ level: " << ctx.get_scope_level() << "\n";);
|
m_reset_cache = true;
|
||||||
break;
|
TRACE("seq", tout << "undef: " << result << "\n";
|
||||||
}
|
tout << lit << "@ level: " << ctx.get_scope_level() << "\n";);
|
||||||
|
break;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3151,7 +3192,7 @@ void theory_seq::add_indexof_axiom(expr* i) {
|
||||||
|
|
||||||
*/
|
*/
|
||||||
void theory_seq::add_replace_axiom(expr* r) {
|
void theory_seq::add_replace_axiom(expr* r) {
|
||||||
expr* a, *s, *t;
|
expr* a = 0, *s = 0, *t = 0;
|
||||||
VERIFY(m_util.str.is_replace(r, a, s, t));
|
VERIFY(m_util.str.is_replace(r, a, s, t));
|
||||||
expr_ref x = mk_skolem(m_indexof_left, a, s);
|
expr_ref x = mk_skolem(m_indexof_left, a, s);
|
||||||
expr_ref y = mk_skolem(m_indexof_right, a, s);
|
expr_ref y = mk_skolem(m_indexof_right, a, s);
|
||||||
|
@ -3284,7 +3325,7 @@ void theory_seq::add_itos_length_axiom(expr* len) {
|
||||||
|
|
||||||
void theory_seq::propagate_in_re(expr* n, bool is_true) {
|
void theory_seq::propagate_in_re(expr* n, bool is_true) {
|
||||||
TRACE("seq", tout << mk_pp(n, m) << " <- " << (is_true?"true":"false") << "\n";);
|
TRACE("seq", tout << mk_pp(n, m) << " <- " << (is_true?"true":"false") << "\n";);
|
||||||
expr* e1, *e2;
|
expr* e1 = 0, *e2 = 0;
|
||||||
VERIFY(m_util.str.is_in_re(n, e1, e2));
|
VERIFY(m_util.str.is_in_re(n, e1, e2));
|
||||||
|
|
||||||
expr_ref tmp(n, m);
|
expr_ref tmp(n, m);
|
||||||
|
@ -3416,7 +3457,7 @@ bool theory_seq::get_length(expr* e, rational& val) const {
|
||||||
if (!tha) return false;
|
if (!tha) return false;
|
||||||
rational val1;
|
rational val1;
|
||||||
expr_ref len(m), len_val(m);
|
expr_ref len(m), len_val(m);
|
||||||
expr* e1, *e2;
|
expr* e1 = 0, *e2 = 0;
|
||||||
ptr_vector<expr> todo;
|
ptr_vector<expr> todo;
|
||||||
todo.push_back(e);
|
todo.push_back(e);
|
||||||
val.reset();
|
val.reset();
|
||||||
|
@ -3476,7 +3517,7 @@ bool theory_seq::get_length(expr* e, rational& val) const {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void theory_seq::add_extract_axiom(expr* e) {
|
void theory_seq::add_extract_axiom(expr* e) {
|
||||||
expr* s, *i, *l;
|
expr* s = 0, *i = 0, *l = 0;
|
||||||
VERIFY(m_util.str.is_extract(e, s, i, l));
|
VERIFY(m_util.str.is_extract(e, s, i, l));
|
||||||
if (is_tail(s, i, l)) {
|
if (is_tail(s, i, l)) {
|
||||||
add_tail_axiom(e, s);
|
add_tail_axiom(e, s);
|
||||||
|
@ -3636,7 +3677,7 @@ void theory_seq::add_at_axiom(expr* e) {
|
||||||
*/
|
*/
|
||||||
void theory_seq::propagate_step(literal lit, expr* step) {
|
void theory_seq::propagate_step(literal lit, expr* step) {
|
||||||
SASSERT(get_context().get_assignment(lit) == l_true);
|
SASSERT(get_context().get_assignment(lit) == l_true);
|
||||||
expr* re, *acc, *s, *idx, *i, *j;
|
expr* re = 0, *acc = 0, *s = 0, *idx = 0, *i = 0, *j = 0;
|
||||||
VERIFY(is_step(step, s, idx, re, i, j, acc));
|
VERIFY(is_step(step, s, idx, re, i, j, acc));
|
||||||
TRACE("seq", tout << mk_pp(step, m) << " -> " << mk_pp(acc, m) << "\n";);
|
TRACE("seq", tout << mk_pp(step, m) << " -> " << mk_pp(acc, m) << "\n";);
|
||||||
propagate_lit(0, 1, &lit, mk_literal(acc));
|
propagate_lit(0, 1, &lit, mk_literal(acc));
|
||||||
|
@ -3797,7 +3838,7 @@ void theory_seq::propagate_eq(dependency* deps, literal_vector const& _lits, exp
|
||||||
void theory_seq::assign_eh(bool_var v, bool is_true) {
|
void theory_seq::assign_eh(bool_var v, bool is_true) {
|
||||||
context & ctx = get_context();
|
context & ctx = get_context();
|
||||||
expr* e = ctx.bool_var2expr(v);
|
expr* e = ctx.bool_var2expr(v);
|
||||||
expr* e1, *e2;
|
expr* e1 = 0, *e2 = 0;
|
||||||
expr_ref f(m);
|
expr_ref f(m);
|
||||||
bool change = false;
|
bool change = false;
|
||||||
literal lit(v, !is_true);
|
literal lit(v, !is_true);
|
||||||
|
@ -4145,7 +4186,7 @@ expr_ref theory_seq::mk_step(expr* s, expr* idx, expr* re, unsigned i, unsigned
|
||||||
rej(s, idx, re, i) -> len(s) > idx if i is final
|
rej(s, idx, re, i) -> len(s) > idx if i is final
|
||||||
*/
|
*/
|
||||||
void theory_seq::propagate_acc_rej_length(literal lit, expr* e) {
|
void theory_seq::propagate_acc_rej_length(literal lit, expr* e) {
|
||||||
expr *s, * idx, *re;
|
expr *s = 0, *idx = 0, *re = 0;
|
||||||
unsigned src;
|
unsigned src;
|
||||||
eautomaton* aut = 0;
|
eautomaton* aut = 0;
|
||||||
bool is_acc;
|
bool is_acc;
|
||||||
|
@ -4174,7 +4215,7 @@ bool theory_seq::add_accept2step(expr* acc, bool& change) {
|
||||||
|
|
||||||
TRACE("seq", tout << mk_pp(acc, m) << "\n";);
|
TRACE("seq", tout << mk_pp(acc, m) << "\n";);
|
||||||
SASSERT(ctx.get_assignment(acc) == l_true);
|
SASSERT(ctx.get_assignment(acc) == l_true);
|
||||||
expr *e, * idx, *re;
|
expr *e = 0, *idx = 0, *re = 0;
|
||||||
expr_ref step(m);
|
expr_ref step(m);
|
||||||
unsigned src;
|
unsigned src;
|
||||||
eautomaton* aut = 0;
|
eautomaton* aut = 0;
|
||||||
|
@ -4253,7 +4294,7 @@ bool theory_seq::add_accept2step(expr* acc, bool& change) {
|
||||||
bool theory_seq::add_step2accept(expr* step, bool& change) {
|
bool theory_seq::add_step2accept(expr* step, bool& change) {
|
||||||
context& ctx = get_context();
|
context& ctx = get_context();
|
||||||
SASSERT(ctx.get_assignment(step) == l_true);
|
SASSERT(ctx.get_assignment(step) == l_true);
|
||||||
expr* re, *_acc, *s, *idx, *i, *j;
|
expr* re = 0, *_acc = 0, *s = 0, *idx = 0, *i = 0, *j = 0;
|
||||||
VERIFY(is_step(step, s, idx, re, i, j, _acc));
|
VERIFY(is_step(step, s, idx, re, i, j, _acc));
|
||||||
literal acc1 = mk_accept(s, idx, re, i);
|
literal acc1 = mk_accept(s, idx, re, i);
|
||||||
switch (ctx.get_assignment(acc1)) {
|
switch (ctx.get_assignment(acc1)) {
|
||||||
|
@ -4302,7 +4343,7 @@ Recall we also have:
|
||||||
bool theory_seq::add_reject2reject(expr* rej, bool& change) {
|
bool theory_seq::add_reject2reject(expr* rej, bool& change) {
|
||||||
context& ctx = get_context();
|
context& ctx = get_context();
|
||||||
SASSERT(ctx.get_assignment(rej) == l_true);
|
SASSERT(ctx.get_assignment(rej) == l_true);
|
||||||
expr* s, *idx, *re;
|
expr* s = 0, *idx = 0, *re = 0;
|
||||||
unsigned src;
|
unsigned src;
|
||||||
rational r;
|
rational r;
|
||||||
eautomaton* aut = 0;
|
eautomaton* aut = 0;
|
||||||
|
@ -4364,7 +4405,7 @@ bool theory_seq::add_reject2reject(expr* rej, bool& change) {
|
||||||
|
|
||||||
void theory_seq::propagate_not_prefix(expr* e) {
|
void theory_seq::propagate_not_prefix(expr* e) {
|
||||||
context& ctx = get_context();
|
context& ctx = get_context();
|
||||||
expr* e1, *e2;
|
expr* e1 = 0, *e2 = 0;
|
||||||
VERIFY(m_util.str.is_prefix(e, e1, e2));
|
VERIFY(m_util.str.is_prefix(e, e1, e2));
|
||||||
literal lit = ctx.get_literal(e);
|
literal lit = ctx.get_literal(e);
|
||||||
SASSERT(ctx.get_assignment(lit) == l_false);
|
SASSERT(ctx.get_assignment(lit) == l_false);
|
||||||
|
@ -4393,7 +4434,7 @@ void theory_seq::propagate_not_prefix(expr* e) {
|
||||||
|
|
||||||
void theory_seq::propagate_not_prefix2(expr* e) {
|
void theory_seq::propagate_not_prefix2(expr* e) {
|
||||||
context& ctx = get_context();
|
context& ctx = get_context();
|
||||||
expr* e1, *e2;
|
expr* e1 = 0, *e2 = 0;
|
||||||
VERIFY(m_util.str.is_prefix(e, e1, e2));
|
VERIFY(m_util.str.is_prefix(e, e1, e2));
|
||||||
literal lit = ctx.get_literal(e);
|
literal lit = ctx.get_literal(e);
|
||||||
SASSERT(ctx.get_assignment(lit) == l_false);
|
SASSERT(ctx.get_assignment(lit) == l_false);
|
||||||
|
|
|
@ -462,7 +462,10 @@ namespace smt {
|
||||||
expr_ref canonize(expr* e, dependency*& eqs);
|
expr_ref canonize(expr* e, dependency*& eqs);
|
||||||
bool canonize(expr* e, expr_ref_vector& es, dependency*& eqs);
|
bool canonize(expr* e, expr_ref_vector& es, dependency*& eqs);
|
||||||
bool canonize(expr_ref_vector const& es, expr_ref_vector& result, dependency*& eqs);
|
bool canonize(expr_ref_vector const& es, expr_ref_vector& result, dependency*& eqs);
|
||||||
|
ptr_vector<expr> m_expand_todo;
|
||||||
expr_ref expand(expr* e, dependency*& eqs);
|
expr_ref expand(expr* e, dependency*& eqs);
|
||||||
|
expr_ref expand1(expr* e, dependency*& eqs);
|
||||||
|
expr_ref try_expand(expr* e, dependency*& eqs);
|
||||||
void add_dependency(dependency*& dep, enode* a, enode* b);
|
void add_dependency(dependency*& dep, enode* a, enode* b);
|
||||||
|
|
||||||
void get_concat(expr* e, ptr_vector<expr>& concats);
|
void get_concat(expr* e, ptr_vector<expr>& concats);
|
||||||
|
|
|
@ -21,14 +21,13 @@
|
||||||
#include"ast_pp.h"
|
#include"ast_pp.h"
|
||||||
#include"ast_ll_pp.h"
|
#include"ast_ll_pp.h"
|
||||||
#include<list>
|
#include<list>
|
||||||
#include<vector>
|
|
||||||
#include<algorithm>
|
#include<algorithm>
|
||||||
#include"theory_seq_empty.h"
|
#include"theory_seq_empty.h"
|
||||||
#include"theory_arith.h"
|
#include"theory_arith.h"
|
||||||
#include"ast_util.h"
|
#include"ast_util.h"
|
||||||
|
|
||||||
namespace smt {
|
namespace smt {
|
||||||
|
|
||||||
theory_str::theory_str(ast_manager & m, theory_str_params const & params):
|
theory_str::theory_str(ast_manager & m, theory_str_params const & params):
|
||||||
theory(m.mk_family_id("seq")),
|
theory(m.mk_family_id("seq")),
|
||||||
m_params(params),
|
m_params(params),
|
||||||
|
@ -99,7 +98,7 @@ namespace smt {
|
||||||
if (defaultCharset) {
|
if (defaultCharset) {
|
||||||
// valid C strings can't contain the null byte ('\0')
|
// valid C strings can't contain the null byte ('\0')
|
||||||
charSetSize = 255;
|
charSetSize = 255;
|
||||||
char_set.resize(256, 0);
|
char_set.resize(256, 0);
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
// small letters
|
// small letters
|
||||||
for (int i = 97; i < 123; i++) {
|
for (int i = 97; i < 123; i++) {
|
||||||
|
@ -233,11 +232,11 @@ namespace smt {
|
||||||
for (unsigned i = 0; i < num_args; ++i) {
|
for (unsigned i = 0; i < num_args; ++i) {
|
||||||
enode * arg = e->get_arg(i);
|
enode * arg = e->get_arg(i);
|
||||||
theory_var v_arg = mk_var(arg);
|
theory_var v_arg = mk_var(arg);
|
||||||
TRACE("str", tout << "arg has theory var #" << v_arg << std::endl;);
|
TRACE("str", tout << "arg has theory var #" << v_arg << std::endl;); (void)v_arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
theory_var v = mk_var(e);
|
theory_var v = mk_var(e);
|
||||||
TRACE("str", tout << "term has theory var #" << v << std::endl;);
|
TRACE("str", tout << "term has theory var #" << v << std::endl;); (void)v;
|
||||||
|
|
||||||
if (opt_EagerStringConstantLengthAssertions && u.str.is_string(term)) {
|
if (opt_EagerStringConstantLengthAssertions && u.str.is_string(term)) {
|
||||||
TRACE("str", tout << "eagerly asserting length of string term " << mk_pp(term, m) << std::endl;);
|
TRACE("str", tout << "eagerly asserting length of string term " << mk_pp(term, m) << std::endl;);
|
||||||
|
@ -258,7 +257,7 @@ namespace smt {
|
||||||
|
|
||||||
void theory_str::refresh_theory_var(expr * e) {
|
void theory_str::refresh_theory_var(expr * e) {
|
||||||
enode * en = ensure_enode(e);
|
enode * en = ensure_enode(e);
|
||||||
theory_var v = mk_var(en);
|
theory_var v = mk_var(en); (void)v;
|
||||||
TRACE("str", tout << "refresh " << mk_pp(e, get_manager()) << ": v#" << v << std::endl;);
|
TRACE("str", tout << "refresh " << mk_pp(e, get_manager()) << ": v#" << v << std::endl;);
|
||||||
m_basicstr_axiom_todo.push_back(en);
|
m_basicstr_axiom_todo.push_back(en);
|
||||||
}
|
}
|
||||||
|
@ -488,7 +487,6 @@ namespace smt {
|
||||||
|
|
||||||
app * theory_str::mk_str_var(std::string name) {
|
app * theory_str::mk_str_var(std::string name) {
|
||||||
context & ctx = get_context();
|
context & ctx = get_context();
|
||||||
ast_manager & m = get_manager();
|
|
||||||
|
|
||||||
TRACE("str", tout << "creating string variable " << name << " at scope level " << sLevel << std::endl;);
|
TRACE("str", tout << "creating string variable " << name << " at scope level " << sLevel << std::endl;);
|
||||||
|
|
||||||
|
@ -506,7 +504,7 @@ namespace smt {
|
||||||
// this might help??
|
// this might help??
|
||||||
mk_var(ctx.get_enode(a));
|
mk_var(ctx.get_enode(a));
|
||||||
m_basicstr_axiom_todo.push_back(ctx.get_enode(a));
|
m_basicstr_axiom_todo.push_back(ctx.get_enode(a));
|
||||||
TRACE("str", tout << "add " << mk_pp(a, m) << " to m_basicstr_axiom_todo" << std::endl;);
|
TRACE("str", tout << "add " << mk_pp(a, get_manager()) << " to m_basicstr_axiom_todo" << std::endl;);
|
||||||
|
|
||||||
variable_set.insert(a);
|
variable_set.insert(a);
|
||||||
internal_variable_set.insert(a);
|
internal_variable_set.insert(a);
|
||||||
|
@ -517,7 +515,6 @@ namespace smt {
|
||||||
|
|
||||||
app * theory_str::mk_regex_rep_var() {
|
app * theory_str::mk_regex_rep_var() {
|
||||||
context & ctx = get_context();
|
context & ctx = get_context();
|
||||||
ast_manager & m = get_manager();
|
|
||||||
|
|
||||||
sort * string_sort = u.str.mk_string_sort();
|
sort * string_sort = u.str.mk_string_sort();
|
||||||
app * a = mk_fresh_const("regex", string_sort);
|
app * a = mk_fresh_const("regex", string_sort);
|
||||||
|
@ -528,7 +525,7 @@ namespace smt {
|
||||||
SASSERT(ctx.e_internalized(a));
|
SASSERT(ctx.e_internalized(a));
|
||||||
mk_var(ctx.get_enode(a));
|
mk_var(ctx.get_enode(a));
|
||||||
m_basicstr_axiom_todo.push_back(ctx.get_enode(a));
|
m_basicstr_axiom_todo.push_back(ctx.get_enode(a));
|
||||||
TRACE("str", tout << "add " << mk_pp(a, m) << " to m_basicstr_axiom_todo" << std::endl;);
|
TRACE("str", tout << "add " << mk_pp(a, get_manager()) << " to m_basicstr_axiom_todo" << std::endl;);
|
||||||
|
|
||||||
variable_set.insert(a);
|
variable_set.insert(a);
|
||||||
//internal_variable_set.insert(a);
|
//internal_variable_set.insert(a);
|
||||||
|
@ -934,8 +931,7 @@ namespace smt {
|
||||||
SASSERT(len_xy);
|
SASSERT(len_xy);
|
||||||
|
|
||||||
// build RHS: start by extracting x and y from Concat(x, y)
|
// build RHS: start by extracting x and y from Concat(x, y)
|
||||||
unsigned nArgs = a_cat->get_num_args();
|
SASSERT(a_cat->get_num_args() == 2);
|
||||||
SASSERT(nArgs == 2);
|
|
||||||
app * a_x = to_app(a_cat->get_arg(0));
|
app * a_x = to_app(a_cat->get_arg(0));
|
||||||
app * a_y = to_app(a_cat->get_arg(1));
|
app * a_y = to_app(a_cat->get_arg(1));
|
||||||
|
|
||||||
|
@ -1988,7 +1984,8 @@ namespace smt {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline std::string rational_to_string_if_exists(const rational & x, bool x_exists) {
|
// trace code helper
|
||||||
|
inline std::string rational_to_string_if_exists(const rational & x, bool x_exists) {
|
||||||
if (x_exists) {
|
if (x_exists) {
|
||||||
return x.to_string();
|
return x.to_string();
|
||||||
} else {
|
} else {
|
||||||
|
@ -2055,7 +2052,7 @@ namespace smt {
|
||||||
<< "* |parent| = " << rational_to_string_if_exists(parentLen, parentLen_exists) << std::endl
|
<< "* |parent| = " << rational_to_string_if_exists(parentLen, parentLen_exists) << std::endl
|
||||||
<< "* |arg0| = " << rational_to_string_if_exists(arg0Len, arg0Len_exists) << std::endl
|
<< "* |arg0| = " << rational_to_string_if_exists(arg0Len, arg0Len_exists) << std::endl
|
||||||
<< "* |arg1| = " << rational_to_string_if_exists(arg1Len, arg1Len_exists) << std::endl;
|
<< "* |arg1| = " << rational_to_string_if_exists(arg1Len, arg1Len_exists) << std::endl;
|
||||||
);
|
); (void)arg0Len_exists;
|
||||||
|
|
||||||
if (parentLen_exists && !arg1Len_exists) {
|
if (parentLen_exists && !arg1Len_exists) {
|
||||||
TRACE("str", tout << "make up len for arg1" << std::endl;);
|
TRACE("str", tout << "make up len for arg1" << std::endl;);
|
||||||
|
@ -2126,7 +2123,8 @@ namespace smt {
|
||||||
<< "* |parent| = " << rational_to_string_if_exists(parentLen, parentLen_exists) << std::endl
|
<< "* |parent| = " << rational_to_string_if_exists(parentLen, parentLen_exists) << std::endl
|
||||||
<< "* |arg0| = " << rational_to_string_if_exists(arg0Len, arg0Len_exists) << std::endl
|
<< "* |arg0| = " << rational_to_string_if_exists(arg0Len, arg0Len_exists) << std::endl
|
||||||
<< "* |arg1| = " << rational_to_string_if_exists(arg1Len, arg1Len_exists) << std::endl;
|
<< "* |arg1| = " << rational_to_string_if_exists(arg1Len, arg1Len_exists) << std::endl;
|
||||||
);
|
); (void)arg1Len_exists;
|
||||||
|
|
||||||
if (parentLen_exists && !arg0Len_exists) {
|
if (parentLen_exists && !arg0Len_exists) {
|
||||||
TRACE("str", tout << "make up len for arg0" << std::endl;);
|
TRACE("str", tout << "make up len for arg0" << std::endl;);
|
||||||
expr_ref implyL11(m.mk_and(ctx.mk_eq_atom(mk_strlen(a_parent), mk_int(parentLen)),
|
expr_ref implyL11(m.mk_and(ctx.mk_eq_atom(mk_strlen(a_parent), mk_int(parentLen)),
|
||||||
|
@ -4497,8 +4495,6 @@ namespace smt {
|
||||||
}
|
}
|
||||||
|
|
||||||
void theory_str::process_unroll_eq_const_str(expr * unrollFunc, expr * constStr) {
|
void theory_str::process_unroll_eq_const_str(expr * unrollFunc, expr * constStr) {
|
||||||
ast_manager & m = get_manager();
|
|
||||||
|
|
||||||
if (!u.re.is_unroll(to_app(unrollFunc))) {
|
if (!u.re.is_unroll(to_app(unrollFunc))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4510,8 +4506,8 @@ namespace smt {
|
||||||
zstring strValue;
|
zstring strValue;
|
||||||
u.str.is_string(constStr, strValue);
|
u.str.is_string(constStr, strValue);
|
||||||
|
|
||||||
TRACE("str", tout << "unrollFunc: " << mk_pp(unrollFunc, m) << std::endl
|
TRACE("str", tout << "unrollFunc: " << mk_pp(unrollFunc, get_manager()) << std::endl
|
||||||
<< "constStr: " << mk_pp(constStr, m) << std::endl;);
|
<< "constStr: " << mk_pp(constStr, get_manager()) << std::endl;);
|
||||||
|
|
||||||
if (strValue == "") {
|
if (strValue == "") {
|
||||||
return;
|
return;
|
||||||
|
@ -4656,7 +4652,7 @@ namespace smt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool theory_str::get_value(expr* e, rational& val) const {
|
bool theory_str::get_arith_value(expr* e, rational& val) const {
|
||||||
if (opt_DisableIntegerTheoryIntegration) {
|
if (opt_DisableIntegerTheoryIntegration) {
|
||||||
TRACE("str", tout << "WARNING: integer theory integration disabled" << std::endl;);
|
TRACE("str", tout << "WARNING: integer theory integration disabled" << std::endl;);
|
||||||
return false;
|
return false;
|
||||||
|
@ -4785,7 +4781,7 @@ namespace smt {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (ctx.e_internalized(len) && get_value(len, val1)) {
|
if (ctx.e_internalized(len) && get_arith_value(len, val1)) {
|
||||||
val += val1;
|
val += val1;
|
||||||
TRACE("str", tout << "integer theory: subexpression " << mk_ismt2_pp(len, m) << " has length " << val1 << std::endl;);
|
TRACE("str", tout << "integer theory: subexpression " << mk_ismt2_pp(len, m) << " has length " << val1 << std::endl;);
|
||||||
}
|
}
|
||||||
|
@ -4808,17 +4804,16 @@ namespace smt {
|
||||||
bool theory_str::in_same_eqc(expr * n1, expr * n2) {
|
bool theory_str::in_same_eqc(expr * n1, expr * n2) {
|
||||||
if (n1 == n2) return true;
|
if (n1 == n2) return true;
|
||||||
context & ctx = get_context();
|
context & ctx = get_context();
|
||||||
ast_manager & m = get_manager();
|
|
||||||
|
|
||||||
// similar to get_eqc_value(), make absolutely sure
|
// similar to get_eqc_value(), make absolutely sure
|
||||||
// that we've set this up properly for the context
|
// that we've set this up properly for the context
|
||||||
|
|
||||||
if (!ctx.e_internalized(n1)) {
|
if (!ctx.e_internalized(n1)) {
|
||||||
TRACE("str", tout << "WARNING: expression " << mk_ismt2_pp(n1, m) << " was not internalized" << std::endl;);
|
TRACE("str", tout << "WARNING: expression " << mk_ismt2_pp(n1, get_manager()) << " was not internalized" << std::endl;);
|
||||||
ctx.internalize(n1, false);
|
ctx.internalize(n1, false);
|
||||||
}
|
}
|
||||||
if (!ctx.e_internalized(n2)) {
|
if (!ctx.e_internalized(n2)) {
|
||||||
TRACE("str", tout << "WARNING: expression " << mk_ismt2_pp(n2, m) << " was not internalized" << std::endl;);
|
TRACE("str", tout << "WARNING: expression " << mk_ismt2_pp(n2, get_manager()) << " was not internalized" << std::endl;);
|
||||||
ctx.internalize(n2, false);
|
ctx.internalize(n2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4877,7 +4872,7 @@ namespace smt {
|
||||||
expr * strAst = itor1->first;
|
expr * strAst = itor1->first;
|
||||||
expr * substrAst = itor1->second;
|
expr * substrAst = itor1->second;
|
||||||
|
|
||||||
expr * boolVar;
|
expr * boolVar = NULL;
|
||||||
if (!contain_pair_bool_map.find(strAst, substrAst, boolVar)) {
|
if (!contain_pair_bool_map.find(strAst, substrAst, boolVar)) {
|
||||||
TRACE("str", tout << "warning: no entry for boolVar in contain_pair_bool_map" << std::endl;);
|
TRACE("str", tout << "warning: no entry for boolVar in contain_pair_bool_map" << std::endl;);
|
||||||
}
|
}
|
||||||
|
@ -5014,7 +5009,7 @@ namespace smt {
|
||||||
expr * strAst = itor1->first;
|
expr * strAst = itor1->first;
|
||||||
expr * substrAst = itor1->second;
|
expr * substrAst = itor1->second;
|
||||||
|
|
||||||
expr * boolVar;
|
expr * boolVar = NULL;
|
||||||
if (!contain_pair_bool_map.find(strAst, substrAst, boolVar)) {
|
if (!contain_pair_bool_map.find(strAst, substrAst, boolVar)) {
|
||||||
TRACE("str", tout << "warning: no entry for boolVar in contain_pair_bool_map" << std::endl;);
|
TRACE("str", tout << "warning: no entry for boolVar in contain_pair_bool_map" << std::endl;);
|
||||||
}
|
}
|
||||||
|
@ -5625,8 +5620,7 @@ namespace smt {
|
||||||
}
|
}
|
||||||
|
|
||||||
void theory_str::print_grounded_concat(expr * node, std::map<expr*, std::map<std::vector<expr*>, std::set<expr*> > > & groundedMap) {
|
void theory_str::print_grounded_concat(expr * node, std::map<expr*, std::map<std::vector<expr*>, std::set<expr*> > > & groundedMap) {
|
||||||
ast_manager & m = get_manager();
|
TRACE("str", tout << mk_pp(node, get_manager()) << std::endl;);
|
||||||
TRACE("str", tout << mk_pp(node, m) << std::endl;);
|
|
||||||
if (groundedMap.find(node) != groundedMap.end()) {
|
if (groundedMap.find(node) != groundedMap.end()) {
|
||||||
std::map<std::vector<expr*>, std::set<expr*> >::iterator itor = groundedMap[node].begin();
|
std::map<std::vector<expr*>, std::set<expr*> >::iterator itor = groundedMap[node].begin();
|
||||||
for (; itor != groundedMap[node].end(); ++itor) {
|
for (; itor != groundedMap[node].end(); ++itor) {
|
||||||
|
@ -5634,13 +5628,13 @@ namespace smt {
|
||||||
tout << "\t[grounded] ";
|
tout << "\t[grounded] ";
|
||||||
std::vector<expr*>::const_iterator vIt = itor->first.begin();
|
std::vector<expr*>::const_iterator vIt = itor->first.begin();
|
||||||
for (; vIt != itor->first.end(); ++vIt) {
|
for (; vIt != itor->first.end(); ++vIt) {
|
||||||
tout << mk_pp(*vIt, m) << ", ";
|
tout << mk_pp(*vIt, get_manager()) << ", ";
|
||||||
}
|
}
|
||||||
tout << std::endl;
|
tout << std::endl;
|
||||||
tout << "\t[condition] ";
|
tout << "\t[condition] ";
|
||||||
std::set<expr*>::iterator sIt = itor->second.begin();
|
std::set<expr*>::iterator sIt = itor->second.begin();
|
||||||
for (; sIt != itor->second.end(); sIt++) {
|
for (; sIt != itor->second.end(); sIt++) {
|
||||||
tout << mk_pp(*sIt, m) << ", ";
|
tout << mk_pp(*sIt, get_manager()) << ", ";
|
||||||
}
|
}
|
||||||
tout << std::endl;
|
tout << std::endl;
|
||||||
);
|
);
|
||||||
|
@ -6936,7 +6930,7 @@ namespace smt {
|
||||||
}
|
}
|
||||||
|
|
||||||
void theory_str::more_value_tests(expr * valTester, zstring valTesterValue) {
|
void theory_str::more_value_tests(expr * valTester, zstring valTesterValue) {
|
||||||
ast_manager & m = get_manager();
|
ast_manager & m = get_manager(); (void)m;
|
||||||
|
|
||||||
expr * fVar = valueTester_fvar_map[valTester];
|
expr * fVar = valueTester_fvar_map[valTester];
|
||||||
if (m_params.m_UseBinarySearch) {
|
if (m_params.m_UseBinarySearch) {
|
||||||
|
@ -6991,17 +6985,16 @@ namespace smt {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool theory_str::free_var_attempt(expr * nn1, expr * nn2) {
|
bool theory_str::free_var_attempt(expr * nn1, expr * nn2) {
|
||||||
ast_manager & m = get_manager();
|
|
||||||
zstring nn2_str;
|
zstring nn2_str;
|
||||||
if (internal_lenTest_vars.contains(nn1) && u.str.is_string(nn2, nn2_str)) {
|
if (internal_lenTest_vars.contains(nn1) && u.str.is_string(nn2, nn2_str)) {
|
||||||
TRACE("str", tout << "acting on equivalence between length tester var " << mk_ismt2_pp(nn1, m)
|
TRACE("str", tout << "acting on equivalence between length tester var " << mk_pp(nn1, get_manager())
|
||||||
<< " and constant " << mk_ismt2_pp(nn2, m) << std::endl;);
|
<< " and constant " << mk_pp(nn2, get_manager()) << std::endl;);
|
||||||
more_len_tests(nn1, nn2_str);
|
more_len_tests(nn1, nn2_str);
|
||||||
return true;
|
return true;
|
||||||
} else if (internal_valTest_vars.contains(nn1) && u.str.is_string(nn2, nn2_str)) {
|
} else if (internal_valTest_vars.contains(nn1) && u.str.is_string(nn2, nn2_str)) {
|
||||||
if (nn2_str == "more") {
|
if (nn2_str == "more") {
|
||||||
TRACE("str", tout << "acting on equivalence between value var " << mk_ismt2_pp(nn1, m)
|
TRACE("str", tout << "acting on equivalence between value var " << mk_pp(nn1, get_manager())
|
||||||
<< " and constant " << mk_ismt2_pp(nn2, m) << std::endl;);
|
<< " and constant " << mk_pp(nn2, get_manager()) << std::endl;);
|
||||||
more_value_tests(nn1, nn2_str);
|
more_value_tests(nn1, nn2_str);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -7302,6 +7295,7 @@ namespace smt {
|
||||||
// this might help??
|
// this might help??
|
||||||
theory_var v = mk_var(n);
|
theory_var v = mk_var(n);
|
||||||
TRACE("str", tout << "variable " << mk_ismt2_pp(ap, get_manager()) << " is #" << v << std::endl;);
|
TRACE("str", tout << "variable " << mk_ismt2_pp(ap, get_manager()) << " is #" << v << std::endl;);
|
||||||
|
(void)v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (ex_sort == bool_sort && !is_quantifier(ex)) {
|
} else if (ex_sort == bool_sort && !is_quantifier(ex)) {
|
||||||
|
@ -7388,7 +7382,6 @@ namespace smt {
|
||||||
}
|
}
|
||||||
|
|
||||||
void theory_str::init_search_eh() {
|
void theory_str::init_search_eh() {
|
||||||
ast_manager & m = get_manager();
|
|
||||||
context & ctx = get_context();
|
context & ctx = get_context();
|
||||||
|
|
||||||
TRACE("str",
|
TRACE("str",
|
||||||
|
@ -7396,7 +7389,7 @@ namespace smt {
|
||||||
unsigned nFormulas = ctx.get_num_asserted_formulas();
|
unsigned nFormulas = ctx.get_num_asserted_formulas();
|
||||||
for (unsigned i = 0; i < nFormulas; ++i) {
|
for (unsigned i = 0; i < nFormulas; ++i) {
|
||||||
expr * ex = ctx.get_asserted_formula(i);
|
expr * ex = ctx.get_asserted_formula(i);
|
||||||
tout << mk_ismt2_pp(ex, m) << (ctx.is_relevant(ex) ? " (rel)" : " (NOT REL)") << std::endl;
|
tout << mk_pp(ex, get_manager()) << (ctx.is_relevant(ex) ? " (rel)" : " (NOT REL)") << std::endl;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
/*
|
/*
|
||||||
|
@ -7411,36 +7404,6 @@ namespace smt {
|
||||||
set_up_axioms(ex);
|
set_up_axioms(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Similar recursive descent, except over all initially assigned terms.
|
|
||||||
* This is done to find equalities between terms, etc. that we otherwise
|
|
||||||
* might not get a chance to see.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
expr_ref_vector assignments(m);
|
|
||||||
ctx.get_assignments(assignments);
|
|
||||||
for (expr_ref_vector::iterator i = assignments.begin(); i != assignments.end(); ++i) {
|
|
||||||
expr * ex = *i;
|
|
||||||
if (m.is_eq(ex)) {
|
|
||||||
TRACE("str", tout << "processing assignment " << mk_ismt2_pp(ex, m) <<
|
|
||||||
": expr is equality" << std::endl;);
|
|
||||||
app * eq = (app*)ex;
|
|
||||||
SASSERT(eq->get_num_args() == 2);
|
|
||||||
expr * lhs = eq->get_arg(0);
|
|
||||||
expr * rhs = eq->get_arg(1);
|
|
||||||
|
|
||||||
enode * e_lhs = ctx.get_enode(lhs);
|
|
||||||
enode * e_rhs = ctx.get_enode(rhs);
|
|
||||||
std::pair<enode*,enode*> eq_pair(e_lhs, e_rhs);
|
|
||||||
m_str_eq_todo.push_back(eq_pair);
|
|
||||||
} else {
|
|
||||||
TRACE("str", tout << "processing assignment " << mk_ismt2_pp(ex, m)
|
|
||||||
<< ": expr ignored" << std::endl;);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// this might be cheating but we need to make sure that certain maps are populated
|
// this might be cheating but we need to make sure that certain maps are populated
|
||||||
// before the first call to new_eq_eh()
|
// before the first call to new_eq_eh()
|
||||||
propagate();
|
propagate();
|
||||||
|
@ -7476,8 +7439,7 @@ namespace smt {
|
||||||
}
|
}
|
||||||
|
|
||||||
void theory_str::assign_eh(bool_var v, bool is_true) {
|
void theory_str::assign_eh(bool_var v, bool is_true) {
|
||||||
context & ctx = get_context();
|
TRACE("str", tout << "assert: v" << v << " #" << get_context().bool_var2expr(v)->get_id() << " is_true: " << is_true << std::endl;);
|
||||||
TRACE("str", tout << "assert: v" << v << " #" << ctx.bool_var2expr(v)->get_id() << " is_true: " << is_true << std::endl;);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void theory_str::push_scope_eh() {
|
void theory_str::push_scope_eh() {
|
||||||
|
@ -7544,7 +7506,6 @@ namespace smt {
|
||||||
void theory_str::pop_scope_eh(unsigned num_scopes) {
|
void theory_str::pop_scope_eh(unsigned num_scopes) {
|
||||||
sLevel -= num_scopes;
|
sLevel -= num_scopes;
|
||||||
TRACE("str", tout << "pop " << num_scopes << " to " << sLevel << std::endl;);
|
TRACE("str", tout << "pop " << num_scopes << " to " << sLevel << std::endl;);
|
||||||
ast_manager & m = get_manager();
|
|
||||||
|
|
||||||
TRACE_CODE(if (is_trace_enabled("t_str_dump_assign_on_scope_change")) { dump_assignments(); });
|
TRACE_CODE(if (is_trace_enabled("t_str_dump_assign_on_scope_change")) { dump_assignments(); });
|
||||||
|
|
||||||
|
@ -7553,10 +7514,9 @@ namespace smt {
|
||||||
|
|
||||||
obj_map<expr, std::stack<T_cut *> >::iterator varItor = cut_var_map.begin();
|
obj_map<expr, std::stack<T_cut *> >::iterator varItor = cut_var_map.begin();
|
||||||
while (varItor != cut_var_map.end()) {
|
while (varItor != cut_var_map.end()) {
|
||||||
expr * e = varItor->m_key;
|
|
||||||
std::stack<T_cut*> & val = cut_var_map[varItor->m_key];
|
std::stack<T_cut*> & val = cut_var_map[varItor->m_key];
|
||||||
while ((val.size() > 0) && (val.top()->level != 0) && (val.top()->level >= sLevel)) {
|
while ((val.size() > 0) && (val.top()->level != 0) && (val.top()->level >= sLevel)) {
|
||||||
TRACE("str", tout << "remove cut info for " << mk_pp(e, m) << std::endl; print_cut_var(e, tout););
|
// TRACE("str", tout << "remove cut info for " << mk_pp(e, get_manager()) << std::endl; print_cut_var(e, tout););
|
||||||
// T_cut * aCut = val.top();
|
// T_cut * aCut = val.top();
|
||||||
val.pop();
|
val.pop();
|
||||||
// dealloc(aCut);
|
// dealloc(aCut);
|
||||||
|
@ -7578,8 +7538,7 @@ namespace smt {
|
||||||
ptr_vector<enode> new_m_basicstr;
|
ptr_vector<enode> new_m_basicstr;
|
||||||
for (ptr_vector<enode>::iterator it = m_basicstr_axiom_todo.begin(); it != m_basicstr_axiom_todo.end(); ++it) {
|
for (ptr_vector<enode>::iterator it = m_basicstr_axiom_todo.begin(); it != m_basicstr_axiom_todo.end(); ++it) {
|
||||||
enode * e = *it;
|
enode * e = *it;
|
||||||
app * a = e->get_owner();
|
TRACE("str", tout << "consider deleting " << mk_pp(e->get_owner(), get_manager())
|
||||||
TRACE("str", tout << "consider deleting " << mk_pp(a, get_manager())
|
|
||||||
<< ", enode scope level is " << e->get_iscope_lvl()
|
<< ", enode scope level is " << e->get_iscope_lvl()
|
||||||
<< std::endl;);
|
<< std::endl;);
|
||||||
if (e->get_iscope_lvl() <= (unsigned)sLevel) {
|
if (e->get_iscope_lvl() <= (unsigned)sLevel) {
|
||||||
|
@ -8481,7 +8440,7 @@ namespace smt {
|
||||||
|
|
||||||
// check integer theory
|
// check integer theory
|
||||||
rational Ival;
|
rational Ival;
|
||||||
bool Ival_exists = get_value(a, Ival);
|
bool Ival_exists = get_arith_value(a, Ival);
|
||||||
if (Ival_exists) {
|
if (Ival_exists) {
|
||||||
TRACE("str", tout << "integer theory assigns " << mk_pp(a, m) << " = " << Ival.to_string() << std::endl;);
|
TRACE("str", tout << "integer theory assigns " << mk_pp(a, m) << " = " << Ival.to_string() << std::endl;);
|
||||||
// if that value is not -1, we can assert (str.to-int S) = Ival --> S = "Ival"
|
// if that value is not -1, we can assert (str.to-int S) = Ival --> S = "Ival"
|
||||||
|
@ -8652,7 +8611,7 @@ namespace smt {
|
||||||
rational lenValue;
|
rational lenValue;
|
||||||
expr_ref concatlenExpr (mk_strlen(concat), m) ;
|
expr_ref concatlenExpr (mk_strlen(concat), m) ;
|
||||||
bool allLeafResolved = true;
|
bool allLeafResolved = true;
|
||||||
if (! get_value(concatlenExpr, lenValue)) {
|
if (! get_arith_value(concatlenExpr, lenValue)) {
|
||||||
// the length fo concat is unresolved yet
|
// the length fo concat is unresolved yet
|
||||||
if (get_len_value(concat, lenValue)) {
|
if (get_len_value(concat, lenValue)) {
|
||||||
// but all leaf nodes have length information
|
// but all leaf nodes have length information
|
||||||
|
@ -8689,7 +8648,7 @@ namespace smt {
|
||||||
expr * var = *it;
|
expr * var = *it;
|
||||||
rational lenValue;
|
rational lenValue;
|
||||||
expr_ref varlen (mk_strlen(var), m) ;
|
expr_ref varlen (mk_strlen(var), m) ;
|
||||||
if (! get_value(varlen, lenValue)) {
|
if (! get_arith_value(varlen, lenValue)) {
|
||||||
if (propagate_length_within_eqc(var)) {
|
if (propagate_length_within_eqc(var)) {
|
||||||
axiomAdded = true;
|
axiomAdded = true;
|
||||||
}
|
}
|
||||||
|
@ -8862,7 +8821,7 @@ namespace smt {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bool hasEqcValue = false;
|
bool hasEqcValue = false;
|
||||||
expr * eqcString = get_eqc_value(itor->first, hasEqcValue);
|
get_eqc_value(itor->first, hasEqcValue);
|
||||||
if (!hasEqcValue) {
|
if (!hasEqcValue) {
|
||||||
TRACE("str", tout << "found free variable " << mk_pp(itor->first, m) << std::endl;);
|
TRACE("str", tout << "found free variable " << mk_pp(itor->first, m) << std::endl;);
|
||||||
needToAssignFreeVars = true;
|
needToAssignFreeVars = true;
|
||||||
|
@ -8870,7 +8829,7 @@ namespace smt {
|
||||||
// break;
|
// break;
|
||||||
} else {
|
} else {
|
||||||
// debug
|
// debug
|
||||||
TRACE("str", tout << "variable " << mk_pp(itor->first, m) << " = " << mk_pp(eqcString, m) << std::endl;);
|
// TRACE("str", tout << "variable " << mk_pp(itor->first, m) << " = " << mk_pp(eqcString, m) << std::endl;);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9105,7 +9064,6 @@ namespace smt {
|
||||||
}
|
}
|
||||||
|
|
||||||
void theory_str::print_value_tester_list(svector<std::pair<int, expr*> > & testerList) {
|
void theory_str::print_value_tester_list(svector<std::pair<int, expr*> > & testerList) {
|
||||||
ast_manager & m = get_manager();
|
|
||||||
TRACE("str",
|
TRACE("str",
|
||||||
int ss = testerList.size();
|
int ss = testerList.size();
|
||||||
tout << "valueTesterList = {";
|
tout << "valueTesterList = {";
|
||||||
|
@ -9114,7 +9072,7 @@ namespace smt {
|
||||||
tout << std::endl;
|
tout << std::endl;
|
||||||
}
|
}
|
||||||
tout << "(" << testerList[i].first << ", ";
|
tout << "(" << testerList[i].first << ", ";
|
||||||
tout << mk_ismt2_pp(testerList[i].second, m);
|
tout << mk_pp(testerList[i].second, get_manager());
|
||||||
tout << "), ";
|
tout << "), ";
|
||||||
}
|
}
|
||||||
tout << std::endl << "}" << std::endl;
|
tout << std::endl << "}" << std::endl;
|
||||||
|
@ -9217,8 +9175,8 @@ namespace smt {
|
||||||
coverAll = get_next_val_encode(val_range_map[lastestValIndi], base);
|
coverAll = get_next_val_encode(val_range_map[lastestValIndi], base);
|
||||||
}
|
}
|
||||||
|
|
||||||
long long l = (tries) * distance;
|
size_t l = (tries) * distance;
|
||||||
long long h = l;
|
size_t h = l;
|
||||||
for (int i = 0; i < distance; i++) {
|
for (int i = 0; i < distance; i++) {
|
||||||
if (coverAll)
|
if (coverAll)
|
||||||
break;
|
break;
|
||||||
|
@ -9239,10 +9197,10 @@ namespace smt {
|
||||||
);
|
);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
expr_ref_vector orList(m), andList(m);
|
expr_ref_vector orList(m), andList(m);
|
||||||
|
|
||||||
for (long long i = l; i < h; i++) {
|
for (size_t i = l; i < h; i++) {
|
||||||
orList.push_back(m.mk_eq(val_indicator, mk_string(longlong_to_string(i).c_str()) ));
|
orList.push_back(m.mk_eq(val_indicator, mk_string(longlong_to_string(i).c_str()) ));
|
||||||
if (m_params.m_AggressiveValueTesting) {
|
if (m_params.m_AggressiveValueTesting) {
|
||||||
literal lit = mk_eq(val_indicator, mk_string(longlong_to_string(i).c_str()), false);
|
literal lit = mk_eq(val_indicator, mk_string(longlong_to_string(i).c_str()), false);
|
||||||
|
@ -9346,8 +9304,7 @@ namespace smt {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool anEqcHasValue = false;
|
bool anEqcHasValue = false;
|
||||||
// Z3_ast anEqc = get_eqc_value(t, aTester, anEqcHasValue);
|
get_eqc_value(aTester, anEqcHasValue);
|
||||||
expr * aTester_eqc_value = get_eqc_value(aTester, anEqcHasValue);
|
|
||||||
if (!anEqcHasValue) {
|
if (!anEqcHasValue) {
|
||||||
TRACE("str", tout << "value tester " << mk_ismt2_pp(aTester, m)
|
TRACE("str", tout << "value tester " << mk_ismt2_pp(aTester, m)
|
||||||
<< " doesn't have an equivalence class value." << std::endl;);
|
<< " doesn't have an equivalence class value." << std::endl;);
|
||||||
|
@ -9359,8 +9316,8 @@ namespace smt {
|
||||||
<< mk_ismt2_pp(makeupAssert, m) << std::endl;);
|
<< mk_ismt2_pp(makeupAssert, m) << std::endl;);
|
||||||
assert_axiom(makeupAssert);
|
assert_axiom(makeupAssert);
|
||||||
} else {
|
} else {
|
||||||
TRACE("str", tout << "value tester " << mk_ismt2_pp(aTester, m)
|
// TRACE("str", tout << "value tester " << mk_ismt2_pp(aTester, m)
|
||||||
<< " == " << mk_ismt2_pp(aTester_eqc_value, m) << std::endl;);
|
// << " == " << mk_ismt2_pp(aTester_eqc_value, m) << std::endl;);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9514,8 +9471,8 @@ namespace smt {
|
||||||
items.reset();
|
items.reset();
|
||||||
|
|
||||||
rational low, high;
|
rational low, high;
|
||||||
bool low_exists = lower_bound(cntInUnr, low);
|
bool low_exists = lower_bound(cntInUnr, low); (void)low_exists;
|
||||||
bool high_exists = upper_bound(cntInUnr, high);
|
bool high_exists = upper_bound(cntInUnr, high); (void)high_exists;
|
||||||
|
|
||||||
TRACE("str",
|
TRACE("str",
|
||||||
tout << "unroll " << mk_pp(unrFunc, mgr) << std::endl;
|
tout << "unroll " << mk_pp(unrFunc, mgr) << std::endl;
|
||||||
|
@ -9523,7 +9480,7 @@ namespace smt {
|
||||||
bool unrLenValue_exists = get_len_value(unrFunc, unrLenValue);
|
bool unrLenValue_exists = get_len_value(unrFunc, unrLenValue);
|
||||||
tout << "unroll length: " << (unrLenValue_exists ? unrLenValue.to_string() : "?") << std::endl;
|
tout << "unroll length: " << (unrLenValue_exists ? unrLenValue.to_string() : "?") << std::endl;
|
||||||
rational cntInUnrValue;
|
rational cntInUnrValue;
|
||||||
bool cntHasValue = get_value(cntInUnr, cntInUnrValue);
|
bool cntHasValue = get_arith_value(cntInUnr, cntInUnrValue);
|
||||||
tout << "unroll count: " << (cntHasValue ? cntInUnrValue.to_string() : "?")
|
tout << "unroll count: " << (cntHasValue ? cntInUnrValue.to_string() : "?")
|
||||||
<< " low = "
|
<< " low = "
|
||||||
<< (low_exists ? low.to_string() : "?")
|
<< (low_exists ? low.to_string() : "?")
|
||||||
|
@ -10266,7 +10223,7 @@ namespace smt {
|
||||||
} else {
|
} else {
|
||||||
tout << "no eqc string constant";
|
tout << "no eqc string constant";
|
||||||
}
|
}
|
||||||
tout << std::endl;);
|
tout << std::endl;); (void)effectiveInScope;
|
||||||
if (effectiveLenInd == lenTesterInCbEq) {
|
if (effectiveLenInd == lenTesterInCbEq) {
|
||||||
effectiveLenIndiStr = lenTesterValue;
|
effectiveLenIndiStr = lenTesterValue;
|
||||||
} else {
|
} else {
|
||||||
|
@ -10351,7 +10308,6 @@ namespace smt {
|
||||||
|
|
||||||
void theory_str::process_free_var(std::map<expr*, int> & freeVar_map) {
|
void theory_str::process_free_var(std::map<expr*, int> & freeVar_map) {
|
||||||
context & ctx = get_context();
|
context & ctx = get_context();
|
||||||
ast_manager & m = get_manager();
|
|
||||||
|
|
||||||
std::set<expr*> eqcRepSet;
|
std::set<expr*> eqcRepSet;
|
||||||
std::set<expr*> leafVarSet;
|
std::set<expr*> leafVarSet;
|
||||||
|
@ -10378,8 +10334,8 @@ namespace smt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (duplicated && dupVar != NULL) {
|
if (duplicated && dupVar != NULL) {
|
||||||
TRACE("str", tout << "Duplicated free variable found:" << mk_ismt2_pp(freeVar, m)
|
TRACE("str", tout << "Duplicated free variable found:" << mk_pp(freeVar, get_manager())
|
||||||
<< " = " << mk_ismt2_pp(dupVar, m) << " (SKIP)" << std::endl;);
|
<< " = " << mk_ismt2_pp(dupVar, get_manager()) << " (SKIP)" << std::endl;);
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
eqcRepSet.insert(freeVar);
|
eqcRepSet.insert(freeVar);
|
||||||
|
|
|
@ -219,7 +219,7 @@ protected:
|
||||||
/*
|
/*
|
||||||
* If DisableIntegerTheoryIntegration is set to true,
|
* If DisableIntegerTheoryIntegration is set to true,
|
||||||
* ALL calls to the integer theory integration methods
|
* ALL calls to the integer theory integration methods
|
||||||
* (get_value, get_len_value, lower_bound, upper_bound)
|
* (get_arith_value, get_len_value, lower_bound, upper_bound)
|
||||||
* will ignore what the arithmetic solver believes about length terms,
|
* will ignore what the arithmetic solver believes about length terms,
|
||||||
* and will return no information.
|
* and will return no information.
|
||||||
*
|
*
|
||||||
|
@ -464,7 +464,7 @@ protected:
|
||||||
bool in_same_eqc(expr * n1, expr * n2);
|
bool in_same_eqc(expr * n1, expr * n2);
|
||||||
expr * collect_eq_nodes(expr * n, expr_ref_vector & eqcSet);
|
expr * collect_eq_nodes(expr * n, expr_ref_vector & eqcSet);
|
||||||
|
|
||||||
bool get_value(expr* e, rational& val) const;
|
bool get_arith_value(expr* e, rational& val) const;
|
||||||
bool get_len_value(expr* e, rational& val);
|
bool get_len_value(expr* e, rational& val);
|
||||||
bool lower_bound(expr* _e, rational& lo);
|
bool lower_bound(expr* _e, rational& lo);
|
||||||
bool upper_bound(expr* _e, rational& hi);
|
bool upper_bound(expr* _e, rational& hi);
|
||||||
|
|
|
@ -169,7 +169,7 @@ public:
|
||||||
for (; bit != bend; ++bit) {
|
for (; bit != bend; ++bit) {
|
||||||
if (!is_app(*bit)) continue;
|
if (!is_app(*bit)) continue;
|
||||||
app* x = to_app(*bit);
|
app* x = to_app(*bit);
|
||||||
bool s1, s2;
|
bool s1 = false, s2 = false;
|
||||||
rational lo, hi;
|
rational lo, hi;
|
||||||
if (a.is_int(x) &&
|
if (a.is_int(x) &&
|
||||||
bounds.has_lower(x, lo, s1) && !s1 && zero <= lo &&
|
bounds.has_lower(x, lo, s1) && !s1 && zero <= lo &&
|
||||||
|
|
|
@ -176,7 +176,7 @@ public:
|
||||||
bound_manager::iterator bit = bounds.begin(), bend = bounds.end();
|
bound_manager::iterator bit = bounds.begin(), bend = bounds.end();
|
||||||
for (; bit != bend; ++bit) {
|
for (; bit != bend; ++bit) {
|
||||||
expr* x = *bit;
|
expr* x = *bit;
|
||||||
bool s1, s2;
|
bool s1 = false, s2 = false;
|
||||||
rational lo, hi;
|
rational lo, hi;
|
||||||
if (a.is_int(x) &&
|
if (a.is_int(x) &&
|
||||||
bounds.has_lower(x, lo, s1) && !s1 && lo.is_zero() &&
|
bounds.has_lower(x, lo, s1) && !s1 && lo.is_zero() &&
|
||||||
|
|
|
@ -47,10 +47,10 @@ class collect_statistics_tactic : public tactic {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
collect_statistics_tactic(ast_manager & m, params_ref const & p) :
|
collect_statistics_tactic(ast_manager & m, params_ref const & p) :
|
||||||
m(m),
|
m(m),
|
||||||
m_params(p) {
|
m_params(p) {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~collect_statistics_tactic() {}
|
virtual ~collect_statistics_tactic() {}
|
||||||
|
|
||||||
virtual tactic * translate(ast_manager & m_) {
|
virtual tactic * translate(ast_manager & m_) {
|
||||||
|
@ -60,21 +60,21 @@ public:
|
||||||
virtual void updt_params(params_ref const & p) {
|
virtual void updt_params(params_ref const & p) {
|
||||||
m_params = p;
|
m_params = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void collect_param_descrs(param_descrs & r) {}
|
virtual void collect_param_descrs(param_descrs & r) {}
|
||||||
|
|
||||||
virtual void operator()(goal_ref const & g, goal_ref_buffer & result,
|
virtual void operator()(goal_ref const & g, goal_ref_buffer & result,
|
||||||
model_converter_ref & mc, proof_converter_ref & pc,
|
model_converter_ref & mc, proof_converter_ref & pc,
|
||||||
expr_dependency_ref & core) {
|
expr_dependency_ref & core) {
|
||||||
mc = 0;
|
mc = 0;
|
||||||
tactic_report report("collect-statistics", *g);
|
tactic_report report("collect-statistics", *g);
|
||||||
|
|
||||||
collect_proc cp(m, m_stats);
|
collect_proc cp(m, m_stats);
|
||||||
expr_mark visited;
|
expr_mark visited;
|
||||||
const unsigned sz = g->size();
|
const unsigned sz = g->size();
|
||||||
for (unsigned i = 0; i < sz; i++)
|
for (unsigned i = 0; i < sz; i++)
|
||||||
for_each_expr(cp, visited, g->form(i));
|
for_each_expr(cp, visited, g->form(i));
|
||||||
|
|
||||||
std::cout << "(" << std::endl;
|
std::cout << "(" << std::endl;
|
||||||
stats_type::iterator it = m_stats.begin();
|
stats_type::iterator it = m_stats.begin();
|
||||||
stats_type::iterator end = m_stats.end();
|
stats_type::iterator end = m_stats.end();
|
||||||
|
@ -84,7 +84,7 @@ public:
|
||||||
|
|
||||||
g->inc_depth();
|
g->inc_depth();
|
||||||
result.push_back(g.get());
|
result.push_back(g.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void cleanup() {}
|
virtual void cleanup() {}
|
||||||
|
|
||||||
|
@ -98,11 +98,12 @@ protected:
|
||||||
class collect_proc {
|
class collect_proc {
|
||||||
public:
|
public:
|
||||||
ast_manager & m;
|
ast_manager & m;
|
||||||
stats_type & m_stats;
|
stats_type & m_stats;
|
||||||
obj_hashtable<sort> m_seen_sorts;
|
obj_hashtable<sort> m_seen_sorts;
|
||||||
obj_hashtable<func_decl> m_seen_func_decls;
|
obj_hashtable<func_decl> m_seen_func_decls;
|
||||||
|
unsigned m_qdepth;
|
||||||
|
|
||||||
collect_proc(ast_manager & m, stats_type & s) : m(m), m_stats(s) {}
|
collect_proc(ast_manager & m, stats_type & s) : m(m), m_stats(s), m_qdepth(0) {}
|
||||||
|
|
||||||
void operator()(var * v) {
|
void operator()(var * v) {
|
||||||
m_stats["bound-variables"]++;
|
m_stats["bound-variables"]++;
|
||||||
|
@ -113,7 +114,18 @@ protected:
|
||||||
m_stats["quantifiers"]++;
|
m_stats["quantifiers"]++;
|
||||||
SASSERT(is_app(q->get_expr()));
|
SASSERT(is_app(q->get_expr()));
|
||||||
app * body = to_app(q->get_expr());
|
app * body = to_app(q->get_expr());
|
||||||
|
if (q->is_forall())
|
||||||
|
m_stats["forall-variables"] += q->get_num_decls();
|
||||||
|
else
|
||||||
|
m_stats["exists-variables"] += q->get_num_decls();
|
||||||
|
m_stats["patterns"] += q->get_num_patterns();
|
||||||
|
m_stats["no-patterns"] += q->get_num_no_patterns();
|
||||||
|
m_qdepth++;
|
||||||
|
if (m_stats.find("max-quantification-depth") == m_stats.end() ||
|
||||||
|
m_stats["max-quantification-depth"] < m_qdepth)
|
||||||
|
m_stats["max-quantification-depth"] = m_qdepth;
|
||||||
this->operator()(body);
|
this->operator()(body);
|
||||||
|
m_qdepth--;
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(app * n) {
|
void operator()(app * n) {
|
||||||
|
@ -121,7 +133,7 @@ protected:
|
||||||
this->operator()(n->get_decl());
|
this->operator()(n->get_decl());
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(sort * s) {
|
void operator()(sort * s) {
|
||||||
if (m.is_uninterp(s)) {
|
if (m.is_uninterp(s)) {
|
||||||
if (!m_seen_sorts.contains(s)) {
|
if (!m_seen_sorts.contains(s)) {
|
||||||
m_stats["uninterpreted-sorts"]++;
|
m_stats["uninterpreted-sorts"]++;
|
||||||
|
@ -135,7 +147,7 @@ protected:
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "(declare-sort " << mk_ismt2_pp(s, m, prms) << ")";
|
ss << "(declare-sort " << mk_ismt2_pp(s, m, prms) << ")";
|
||||||
m_stats[ss.str()]++;
|
m_stats[ss.str()]++;
|
||||||
|
|
||||||
if (s->get_info()->get_num_parameters() > 0) {
|
if (s->get_info()->get_num_parameters() > 0) {
|
||||||
std::stringstream ssname;
|
std::stringstream ssname;
|
||||||
ssname << "(declare-sort (_ " << s->get_name() << " *))";
|
ssname << "(declare-sort (_ " << s->get_name() << " *))";
|
||||||
|
|
|
@ -137,7 +137,8 @@ void goal::push_back(expr * f, proof * pr, expr_dependency * d) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void goal::quick_process(bool save_first, expr_ref& f, expr_dependency * d) {
|
void goal::quick_process(bool save_first, expr_ref& f, expr_dependency * d) {
|
||||||
if (!m().is_and(f) && !(m().is_not(f) && m().is_or(to_app(f)->get_arg(0)))) {
|
expr* g = 0;
|
||||||
|
if (!m().is_and(f) && !(m().is_not(f, g) && m().is_or(g))) {
|
||||||
if (!save_first) {
|
if (!save_first) {
|
||||||
push_back(f, 0, d);
|
push_back(f, 0, d);
|
||||||
}
|
}
|
||||||
|
@ -170,8 +171,8 @@ void goal::quick_process(bool save_first, expr_ref& f, expr_dependency * d) {
|
||||||
todo.push_back(expr_pol(t->get_arg(i), false));
|
todo.push_back(expr_pol(t->get_arg(i), false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m().is_not(curr)) {
|
else if (m().is_not(curr, g)) {
|
||||||
todo.push_back(expr_pol(to_app(curr)->get_arg(0), !pol));
|
todo.push_back(expr_pol(g, !pol));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!pol) {
|
if (!pol) {
|
||||||
|
|
|
@ -168,7 +168,7 @@ public:
|
||||||
|
|
||||||
// translate bit-vector consequences back to integer values
|
// translate bit-vector consequences back to integer values
|
||||||
for (unsigned i = 0; i < consequences.size(); ++i) {
|
for (unsigned i = 0; i < consequences.size(); ++i) {
|
||||||
expr* a, *b, *u, *v;
|
expr* a = 0, *b = 0, *u = 0, *v = 0;
|
||||||
func_decl* f;
|
func_decl* f;
|
||||||
rational num;
|
rational num;
|
||||||
unsigned bvsize;
|
unsigned bvsize;
|
||||||
|
@ -228,7 +228,7 @@ private:
|
||||||
for (; it != end; ++it) {
|
for (; it != end; ++it) {
|
||||||
expr* e = *it;
|
expr* e = *it;
|
||||||
rational lo, hi;
|
rational lo, hi;
|
||||||
bool s1, s2;
|
bool s1 = false, s2 = false;
|
||||||
SASSERT(is_uninterp_const(e));
|
SASSERT(is_uninterp_const(e));
|
||||||
func_decl* f = to_app(e)->get_decl();
|
func_decl* f = to_app(e)->get_decl();
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,7 @@ public:
|
||||||
|
|
||||||
// translate enumeration constants to bit-vectors.
|
// translate enumeration constants to bit-vectors.
|
||||||
for (unsigned i = 0; i < vars.size(); ++i) {
|
for (unsigned i = 0; i < vars.size(); ++i) {
|
||||||
func_decl* f;
|
func_decl* f = 0;
|
||||||
if (is_app(vars[i]) && is_uninterp_const(vars[i]) && m_rewriter.enum2bv().find(to_app(vars[i])->get_decl(), f)) {
|
if (is_app(vars[i]) && is_uninterp_const(vars[i]) && m_rewriter.enum2bv().find(to_app(vars[i])->get_decl(), f)) {
|
||||||
bvars.push_back(m.mk_const(f));
|
bvars.push_back(m.mk_const(f));
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ public:
|
||||||
|
|
||||||
// translate bit-vector consequences back to enumeration types
|
// translate bit-vector consequences back to enumeration types
|
||||||
for (unsigned i = 0; i < consequences.size(); ++i) {
|
for (unsigned i = 0; i < consequences.size(); ++i) {
|
||||||
expr* a, *b, *u, *v;
|
expr* a = 0, *b = 0, *u = 0, *v = 0;
|
||||||
func_decl* f;
|
func_decl* f;
|
||||||
rational num;
|
rational num;
|
||||||
unsigned bvsize;
|
unsigned bvsize;
|
||||||
|
|
|
@ -48,7 +48,7 @@ static void tst1() {
|
||||||
SASSERT(v1.size() == v2.size());
|
SASSERT(v1.size() == v2.size());
|
||||||
if (v1.size() > 0) {
|
if (v1.size() > 0) {
|
||||||
unsigned idx = rand()%v1.size();
|
unsigned idx = rand()%v1.size();
|
||||||
SASSERT(v1.get(idx) == v2[idx]);
|
VERIFY(v1.get(idx) == v2[idx]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (op <= 5) {
|
else if (op <= 5) {
|
||||||
|
|
|
@ -133,7 +133,7 @@ public:
|
||||||
params[0] = parameter(2);
|
params[0] = parameter(2);
|
||||||
ar = m_manager.mk_app(m_fid, OP_REPEAT, 1, params, 1, es);
|
ar = m_manager.mk_app(m_fid, OP_REPEAT, 1, params, 1, es);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT(((a64 << 32) | a64) == u64(e.get()));
|
VERIFY(((a64 << 32) | a64) == u64(e.get()));
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_BREDOR, e1.get());
|
ar = m_manager.mk_app(m_fid, OP_BREDOR, e1.get());
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
|
@ -163,11 +163,11 @@ public:
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_BIT0);
|
ar = m_manager.mk_app(m_fid, OP_BIT0);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT(!bit2bool(e.get()));
|
VERIFY(!bit2bool(e.get()));
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_BIT1);
|
ar = m_manager.mk_app(m_fid, OP_BIT1);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT(bit2bool(e.get()));
|
VERIFY(bit2bool(e.get()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,113 +187,113 @@ public:
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_BADD, 2, e1e2);
|
ar = m_manager.mk_app(m_fid, OP_BADD, 2, e1e2);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT((a + b) == u32(e.get()));
|
VERIFY((a + b) == u32(e.get()));
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_BSUB, 2, e1e2);
|
ar = m_manager.mk_app(m_fid, OP_BSUB, 2, e1e2);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT((a - b) == u32(e.get()));
|
VERIFY((a - b) == u32(e.get()));
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_BMUL, 2, e1e2);
|
ar = m_manager.mk_app(m_fid, OP_BMUL, 2, e1e2);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT((a * b) == u32(e.get()));
|
VERIFY((a * b) == u32(e.get()));
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_BAND, 2, e1e2);
|
ar = m_manager.mk_app(m_fid, OP_BAND, 2, e1e2);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT((a & b) == u32(e.get()));
|
VERIFY((a & b) == u32(e.get()));
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_BOR, 2, e1e2);
|
ar = m_manager.mk_app(m_fid, OP_BOR, 2, e1e2);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT((a | b) == u32(e.get()));
|
VERIFY((a | b) == u32(e.get()));
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_BNOR, 2, e1e2);
|
ar = m_manager.mk_app(m_fid, OP_BNOR, 2, e1e2);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT(~(a | b) == u32(e.get()));
|
VERIFY(~(a | b) == u32(e.get()));
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_BXOR, 2, e1e2);
|
ar = m_manager.mk_app(m_fid, OP_BXOR, 2, e1e2);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT((a ^ b) == u32(e.get()));
|
VERIFY((a ^ b) == u32(e.get()));
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_BXNOR, 2, e1e2);
|
ar = m_manager.mk_app(m_fid, OP_BXNOR, 2, e1e2);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT((~(a ^ b)) == u32(e.get()));
|
VERIFY((~(a ^ b)) == u32(e.get()));
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_BNAND, 2, e1e2);
|
ar = m_manager.mk_app(m_fid, OP_BNAND, 2, e1e2);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT((~(a & b)) == u32(e.get()));
|
VERIFY((~(a & b)) == u32(e.get()));
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_ULEQ, 2, e1e2);
|
ar = m_manager.mk_app(m_fid, OP_ULEQ, 2, e1e2);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT((a <= b) == ast2bool(e.get()));
|
VERIFY((a <= b) == ast2bool(e.get()));
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_UGEQ, 2, e1e2);
|
ar = m_manager.mk_app(m_fid, OP_UGEQ, 2, e1e2);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT((a >= b) == ast2bool(e.get()));
|
VERIFY((a >= b) == ast2bool(e.get()));
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_ULT, 2, e1e2);
|
ar = m_manager.mk_app(m_fid, OP_ULT, 2, e1e2);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT((a < b) == ast2bool(e.get()));
|
VERIFY((a < b) == ast2bool(e.get()));
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_UGT, 2, e1e2);
|
ar = m_manager.mk_app(m_fid, OP_UGT, 2, e1e2);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT((a > b) == ast2bool(e.get()));
|
VERIFY((a > b) == ast2bool(e.get()));
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_SLEQ, 2, e1e2);
|
ar = m_manager.mk_app(m_fid, OP_SLEQ, 2, e1e2);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT((sa <= sb) == ast2bool(e.get()));
|
VERIFY((sa <= sb) == ast2bool(e.get()));
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_SGEQ, 2, e1e2);
|
ar = m_manager.mk_app(m_fid, OP_SGEQ, 2, e1e2);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT((sa >= sb) == ast2bool(e.get()));
|
VERIFY((sa >= sb) == ast2bool(e.get()));
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_SLT, 2, e1e2);
|
ar = m_manager.mk_app(m_fid, OP_SLT, 2, e1e2);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT((sa < sb) == ast2bool(e.get()));
|
VERIFY((sa < sb) == ast2bool(e.get()));
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_SGT, 2, e1e2);
|
ar = m_manager.mk_app(m_fid, OP_SGT, 2, e1e2);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT((sa > sb) == ast2bool(e.get()));
|
VERIFY((sa > sb) == ast2bool(e.get()));
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_BSHL, 2, e1e2);
|
ar = m_manager.mk_app(m_fid, OP_BSHL, 2, e1e2);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT(((b>=32)?0:(a << b)) == u32(e.get()));
|
VERIFY(((b>=32)?0:(a << b)) == u32(e.get()));
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_BLSHR, 2, e1e2);
|
ar = m_manager.mk_app(m_fid, OP_BLSHR, 2, e1e2);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT(((b>=32)?0:(a >> b)) == u32(e.get()));
|
VERIFY(((b>=32)?0:(a >> b)) == u32(e.get()));
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_BASHR, 2, e1e2);
|
ar = m_manager.mk_app(m_fid, OP_BASHR, 2, e1e2);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
|
|
||||||
std::cout << "compare: " << sa << " >> " << b << " = " << (sa >> b) << " with " << i32(e.get()) << "\n";
|
std::cout << "compare: " << sa << " >> " << b << " = " << (sa >> b) << " with " << i32(e.get()) << "\n";
|
||||||
SASSERT(b >= 32 || ((sa >> b) == i32(e.get())));
|
VERIFY(b >= 32 || ((sa >> b) == i32(e.get())));
|
||||||
|
|
||||||
if (b != 0) {
|
if (b != 0) {
|
||||||
ar = m_manager.mk_app(m_fid, OP_BSDIV, 2, e1e2);
|
ar = m_manager.mk_app(m_fid, OP_BSDIV, 2, e1e2);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT((sa / sb) == i32(e.get()));
|
VERIFY((sa / sb) == i32(e.get()));
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_BUDIV, 2, e1e2);
|
ar = m_manager.mk_app(m_fid, OP_BUDIV, 2, e1e2);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT((a / b) == u32(e.get()));
|
VERIFY((a / b) == u32(e.get()));
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_BSREM, 2, e1e2);
|
ar = m_manager.mk_app(m_fid, OP_BSREM, 2, e1e2);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
//SASSERT((sa % sb) == i32(e.get()));
|
//VERIFY((sa % sb) == i32(e.get()));
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_BUREM, 2, e1e2);
|
ar = m_manager.mk_app(m_fid, OP_BUREM, 2, e1e2);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT((a % b) == u32(e.get()));
|
VERIFY((a % b) == u32(e.get()));
|
||||||
|
|
||||||
// TBD: BSMOD.
|
// TBD: BSMOD.
|
||||||
}
|
}
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_CONCAT, 2, e1e2);
|
ar = m_manager.mk_app(m_fid, OP_CONCAT, 2, e1e2);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT(((a64 << 32) | b64) == u64(e.get()));
|
VERIFY(((a64 << 32) | b64) == u64(e.get()));
|
||||||
|
|
||||||
ar = m_manager.mk_app(m_fid, OP_BCOMP, 2, e1e2);
|
ar = m_manager.mk_app(m_fid, OP_BCOMP, 2, e1e2);
|
||||||
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
m_simp.reduce(ar->get_decl(), ar->get_num_args(), ar->get_args(), e);
|
||||||
SASSERT((a == b) == bit2bool(e.get()));
|
VERIFY((a == b) == bit2bool(e.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void test() {
|
void test() {
|
||||||
|
|
|
@ -38,7 +38,7 @@ void tst_check_assumptions()
|
||||||
|
|
||||||
expr * npE = np.get();
|
expr * npE = np.get();
|
||||||
lbool res1 = ctx.check(1, &npE);
|
lbool res1 = ctx.check(1, &npE);
|
||||||
SASSERT(res1==l_true);
|
VERIFY(res1 == l_true);
|
||||||
|
|
||||||
ctx.assert_expr(npE);
|
ctx.assert_expr(npE);
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ static void STD_CALL on_ctrl_c(int) {
|
||||||
raise(SIGINT);
|
raise(SIGINT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static void display_model(sat::solver const & s) {
|
static void display_model(sat::solver const & s) {
|
||||||
sat::model const & m = s.get_model();
|
sat::model const & m = s.get_model();
|
||||||
for (unsigned i = 1; i < m.size(); i++) {
|
for (unsigned i = 1; i < m.size(); i++) {
|
||||||
|
@ -49,6 +50,7 @@ static void display_model(sat::solver const & s) {
|
||||||
}
|
}
|
||||||
std::cout << "\n";
|
std::cout << "\n";
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void display_status(lbool r) {
|
static void display_status(lbool r) {
|
||||||
switch (r) {
|
switch (r) {
|
||||||
|
|
|
@ -14,6 +14,36 @@ Copyright (c) 2015 Microsoft Corporation
|
||||||
using namespace datalog;
|
using namespace datalog;
|
||||||
|
|
||||||
|
|
||||||
|
void tst_dl_context() {
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
symbol relations[] = { symbol("tr_skip"), symbol("tr_sparse"), symbol("tr_hashtable"), symbol("smt_relation2") };
|
||||||
|
|
||||||
|
const unsigned rel_cnt = sizeof(relations)/sizeof(symbol);
|
||||||
|
const char * test_file = "c:\\tvm\\src\\benchmarks\\datalog\\t0.datalog";
|
||||||
|
|
||||||
|
params_ref params;
|
||||||
|
for(unsigned rel_index=0; rel_index<rel_cnt; rel_index++) {
|
||||||
|
params.set_sym("default_relation", relations[rel_index]);
|
||||||
|
for(int eager_checking=1; eager_checking>=0; eager_checking--) {
|
||||||
|
params.set_bool("eager_emptiness_checking", eager_checking!=0);
|
||||||
|
|
||||||
|
std::cerr << "Testing " << relations[rel_index] << "\n";
|
||||||
|
std::cerr << "Eager emptiness checking " << (eager_checking!=0 ? "on" : "off") << "\n";
|
||||||
|
dl_context_simple_query_test(params);
|
||||||
|
dl_context_saturate_file(params, test_file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
|
||||||
static lbool dl_context_eval_unary_predicate(ast_manager & m, context & ctx, char const* problem_text,
|
static lbool dl_context_eval_unary_predicate(ast_manager & m, context & ctx, char const* problem_text,
|
||||||
const char * pred_name) {
|
const char * pred_name) {
|
||||||
parser* p = parser::create(ctx,m);
|
parser* p = parser::create(ctx,m);
|
||||||
|
@ -72,29 +102,4 @@ void dl_context_saturate_file(params_ref & params, const char * f) {
|
||||||
ctx.get_rel_context()->saturate();
|
ctx.get_rel_context()->saturate();
|
||||||
std::cerr << "Done\n";
|
std::cerr << "Done\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_dl_context() {
|
|
||||||
symbol relations[] = { symbol("tr_skip"), symbol("tr_sparse"), symbol("tr_hashtable"), symbol("smt_relation2") };
|
|
||||||
const unsigned rel_cnt = sizeof(relations)/sizeof(symbol);
|
|
||||||
|
|
||||||
return;
|
|
||||||
#if 0
|
|
||||||
const char * test_file = "c:\\tvm\\src\\benchmarks\\datalog\\t0.datalog";
|
|
||||||
|
|
||||||
params_ref params;
|
|
||||||
for(unsigned rel_index=0; rel_index<rel_cnt; rel_index++) {
|
|
||||||
params.set_sym("default_relation", relations[rel_index]);
|
|
||||||
for(int eager_checking=1; eager_checking>=0; eager_checking--) {
|
|
||||||
params.set_bool("eager_emptiness_checking", eager_checking!=0);
|
|
||||||
|
|
||||||
std::cerr << "Testing " << relations[rel_index] << "\n";
|
|
||||||
std::cerr << "Eager emptiness checking " << (eager_checking!=0 ? "on" : "off") << "\n";
|
|
||||||
dl_context_simple_query_test(params);
|
|
||||||
dl_context_saturate_file(params, test_file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ void dl_query_ask_for_last_arg(context & ctx, func_decl * pred, relation_fact &
|
||||||
|
|
||||||
lbool is_sat = ctx.query(query);
|
lbool is_sat = ctx.query(query);
|
||||||
std::cerr << "@@ last arg query should succeed: " << should_be_successful << "\n";
|
std::cerr << "@@ last arg query should succeed: " << should_be_successful << "\n";
|
||||||
SASSERT(is_sat != l_undef);
|
VERIFY(is_sat != l_undef);
|
||||||
|
|
||||||
relation_fact res_fact(m);
|
relation_fact res_fact(m);
|
||||||
res_fact.push_back(f.back());
|
res_fact.push_back(f.back());
|
||||||
|
|
|
@ -158,8 +158,7 @@ static void FUN_NAME(int a, ext_numeral_kind ak, int b, ext_numeral_kind bk, boo
|
||||||
scoped_mpq _a(m), _b(m); \
|
scoped_mpq _a(m), _b(m); \
|
||||||
m.set(_a, a); \
|
m.set(_a, a); \
|
||||||
m.set(_b, b); \
|
m.set(_b, b); \
|
||||||
bool r = OP_NAME(m, _a, ak, _b, bk); \
|
VERIFY(expected == OP_NAME(m, _a, ak, _b, bk)); \
|
||||||
SASSERT(r == expected); \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MK_TST_REL(NAME) MK_TST_REL_CORE(tst_ ## NAME, NAME)
|
#define MK_TST_REL(NAME) MK_TST_REL_CORE(tst_ ## NAME, NAME)
|
||||||
|
|
|
@ -47,12 +47,13 @@ static void tst1() {
|
||||||
for (; it != end; ++it) {
|
for (; it != end; ++it) {
|
||||||
SASSERT(h.contains(*it));
|
SASSERT(h.contains(*it));
|
||||||
}
|
}
|
||||||
int last = -1;
|
|
||||||
while (!h.empty()) {
|
while (!h.empty()) {
|
||||||
int m1 = h.min_value();
|
int m1 = h.min_value();
|
||||||
int m2 = h.erase_min();
|
int m2 = h.erase_min();
|
||||||
|
(void)m1;
|
||||||
|
(void)m2;
|
||||||
SASSERT(m1 == m2);
|
SASSERT(m1 == m2);
|
||||||
SASSERT(last < m2);
|
SASSERT(-1 < m2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,6 +77,7 @@ static void dump_heap(const int_heap2 & h, std::ostream & out) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tst2() {
|
static void tst2() {
|
||||||
|
(void)dump_heap;
|
||||||
int_heap2 h(N);
|
int_heap2 h(N);
|
||||||
for (int i = 0; i < N * 10; i++) {
|
for (int i = 0; i < N * 10; i++) {
|
||||||
if (i % 1000 == 0) std::cout << "i: " << i << std::endl;
|
if (i % 1000 == 0) std::cout << "i: " << i << std::endl;
|
||||||
|
|
|
@ -44,19 +44,19 @@ static void bug_to_rational() {
|
||||||
unsynch_mpq_manager mq;
|
unsynch_mpq_manager mq;
|
||||||
scoped_mpq r(mq);
|
scoped_mpq r(mq);
|
||||||
|
|
||||||
double ad, rd;
|
double ad = 0, rd = 0;
|
||||||
|
|
||||||
m.set(a, 0.0);
|
m.set(a, 0.0);
|
||||||
m.to_rational(a, r);
|
m.to_rational(a, r);
|
||||||
ad = m.to_double(a);
|
ad = m.to_double(a);
|
||||||
rd = mq.get_double(r);
|
rd = mq.get_double(r);
|
||||||
SASSERT(ad == rd);
|
VERIFY(ad == rd);
|
||||||
|
|
||||||
m.set(a, 1.0);
|
m.set(a, 1.0);
|
||||||
m.to_rational(a, r);
|
m.to_rational(a, r);
|
||||||
ad = m.to_double(a);
|
ad = m.to_double(a);
|
||||||
rd = mq.get_double(r);
|
rd = mq.get_double(r);
|
||||||
SASSERT(ad == rd);
|
VERIFY(ad == rd);
|
||||||
|
|
||||||
m.set(a, 1.5);
|
m.set(a, 1.5);
|
||||||
m.to_rational(a, r);
|
m.to_rational(a, r);
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace karr {
|
||||||
}
|
}
|
||||||
lbool is_sat = hb.saturate();
|
lbool is_sat = hb.saturate();
|
||||||
hb.display(std::cout);
|
hb.display(std::cout);
|
||||||
SASSERT(is_sat == l_true);
|
VERIFY(is_sat == l_true);
|
||||||
dst.reset();
|
dst.reset();
|
||||||
unsigned basis_size = hb.get_basis_size();
|
unsigned basis_size = hb.get_basis_size();
|
||||||
for (unsigned i = 0; i < basis_size; ++i) {
|
for (unsigned i = 0; i < basis_size; ++i) {
|
||||||
|
@ -85,7 +85,7 @@ namespace karr {
|
||||||
}
|
}
|
||||||
lbool is_sat = hb.saturate();
|
lbool is_sat = hb.saturate();
|
||||||
hb.display(std::cout);
|
hb.display(std::cout);
|
||||||
SASSERT(is_sat == l_true);
|
VERIFY(is_sat == l_true);
|
||||||
dst.reset();
|
dst.reset();
|
||||||
unsigned basis_size = hb.get_basis_size();
|
unsigned basis_size = hb.get_basis_size();
|
||||||
bool first_initial = true;
|
bool first_initial = true;
|
||||||
|
|
|
@ -35,6 +35,7 @@ static void tst1() {
|
||||||
list<int> * l5 = append(r, l4, l2);
|
list<int> * l5 = append(r, l4, l2);
|
||||||
TRACE("list", display(tout, l5->begin(), l5->end()); tout << "\n";);
|
TRACE("list", display(tout, l5->begin(), l5->end()); tout << "\n";);
|
||||||
list<int> * l6 = append(r, l5, l5);
|
list<int> * l6 = append(r, l5, l5);
|
||||||
|
(void) l6;
|
||||||
TRACE("list", display(tout, l6->begin(), l6->end()); tout << "\n";);
|
TRACE("list", display(tout, l6->begin(), l6->end()); tout << "\n";);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ static void add_ineq(opt::model_based_opt& mbo,
|
||||||
mbo.add_constraint(vars, rational(k), rel);
|
mbo.add_constraint(vars, rational(k), rel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static void add_ineq(opt::model_based_opt& mbo,
|
static void add_ineq(opt::model_based_opt& mbo,
|
||||||
unsigned x, int a,
|
unsigned x, int a,
|
||||||
unsigned y, int b,
|
unsigned y, int b,
|
||||||
|
@ -31,6 +32,7 @@ static void add_ineq(opt::model_based_opt& mbo,
|
||||||
vars.push_back(var(z, rational(c)));
|
vars.push_back(var(z, rational(c)));
|
||||||
mbo.add_constraint(vars, rational(k), rel);
|
mbo.add_constraint(vars, rational(k), rel);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void add_random_ineq(opt::model_based_opt& mbo,
|
static void add_random_ineq(opt::model_based_opt& mbo,
|
||||||
random_gen& r,
|
random_gen& r,
|
||||||
|
@ -295,7 +297,7 @@ static void test8() {
|
||||||
unsigned z = mbo.add_var(rational(4));
|
unsigned z = mbo.add_var(rational(4));
|
||||||
unsigned u = mbo.add_var(rational(5));
|
unsigned u = mbo.add_var(rational(5));
|
||||||
unsigned v = mbo.add_var(rational(6));
|
unsigned v = mbo.add_var(rational(6));
|
||||||
unsigned w = mbo.add_var(rational(6));
|
// unsigned w = mbo.add_var(rational(6));
|
||||||
|
|
||||||
add_ineq(mbo, x0, 1, y, -1, 0, opt::t_le);
|
add_ineq(mbo, x0, 1, y, -1, 0, opt::t_le);
|
||||||
add_ineq(mbo, x, 1, y, -1, 0, opt::t_lt);
|
add_ineq(mbo, x, 1, y, -1, 0, opt::t_lt);
|
||||||
|
|
|
@ -28,7 +28,6 @@ void tst_model_evaluator() {
|
||||||
expr_ref vB2(m.mk_var(2, m.mk_bool_sort()), m);
|
expr_ref vB2(m.mk_var(2, m.mk_bool_sort()), m);
|
||||||
expr* vI0p = vI0.get();
|
expr* vI0p = vI0.get();
|
||||||
expr* vI1p = vI1.get();
|
expr* vI1p = vI1.get();
|
||||||
expr* vB0p = vB0.get();
|
|
||||||
expr* vB1p = vB1.get();
|
expr* vB1p = vB1.get();
|
||||||
expr* vB2p = vB2.get();
|
expr* vB2p = vB2.get();
|
||||||
|
|
||||||
|
|
|
@ -435,7 +435,7 @@ static void tst_limits(unsigned prec) {
|
||||||
bool overflow = false;
|
bool overflow = false;
|
||||||
try { m.inc(a); }
|
try { m.inc(a); }
|
||||||
catch (mpff_manager::overflow_exception) { overflow = true; }
|
catch (mpff_manager::overflow_exception) { overflow = true; }
|
||||||
SASSERT(overflow);
|
VERIFY(overflow);
|
||||||
m.set_max(a);
|
m.set_max(a);
|
||||||
m.dec(a);
|
m.dec(a);
|
||||||
SASSERT(m.eq(a, b));
|
SASSERT(m.eq(a, b));
|
||||||
|
|
|
@ -147,6 +147,7 @@ void tst_div2k(synch_mpz_manager & m, mpz const & v, unsigned k) {
|
||||||
m.power(two, k, pw);
|
m.power(two, k, pw);
|
||||||
m.machine_div(v, pw, y);
|
m.machine_div(v, pw, y);
|
||||||
bool is_eq = m.eq(x, y);
|
bool is_eq = m.eq(x, y);
|
||||||
|
(void)is_eq;
|
||||||
CTRACE("mpz_2k", !is_eq, tout << "div: " << m.to_string(v) << ", k: " << k << " r: " << m.to_string(x) << ", expected: " << m.to_string(y) << "\n";);
|
CTRACE("mpz_2k", !is_eq, tout << "div: " << m.to_string(v) << ", k: " << k << " r: " << m.to_string(x) << ", expected: " << m.to_string(y) << "\n";);
|
||||||
SASSERT(is_eq);
|
SASSERT(is_eq);
|
||||||
m.del(x);
|
m.del(x);
|
||||||
|
@ -174,6 +175,7 @@ void tst_mul2k(synch_mpz_manager & m, mpz const & v, unsigned k) {
|
||||||
m.power(two, k, pw);
|
m.power(two, k, pw);
|
||||||
m.mul(v, pw, y);
|
m.mul(v, pw, y);
|
||||||
bool is_eq = m.eq(x, y);
|
bool is_eq = m.eq(x, y);
|
||||||
|
(void)is_eq;
|
||||||
CTRACE("mpz_2k", !is_eq, tout << "mul: " << m.to_string(v) << ", k: " << k << " r: " << m.to_string(x) << ", expected: " << m.to_string(y) << "\n";);
|
CTRACE("mpz_2k", !is_eq, tout << "mul: " << m.to_string(v) << ", k: " << k << " r: " << m.to_string(x) << ", expected: " << m.to_string(y) << "\n";);
|
||||||
SASSERT(is_eq);
|
SASSERT(is_eq);
|
||||||
m.del(x);
|
m.del(x);
|
||||||
|
|
|
@ -391,7 +391,6 @@ static void tst7() {
|
||||||
params_ref ps;
|
params_ref ps;
|
||||||
reslimit rlim;
|
reslimit rlim;
|
||||||
nlsat::solver s(rlim, ps);
|
nlsat::solver s(rlim, ps);
|
||||||
anum_manager & am = s.am();
|
|
||||||
nlsat::pmanager & pm = s.pm();
|
nlsat::pmanager & pm = s.pm();
|
||||||
nlsat::var x0, x1, x2, a, b, c, d;
|
nlsat::var x0, x1, x2, a, b, c, d;
|
||||||
a = s.mk_var(false);
|
a = s.mk_var(false);
|
||||||
|
@ -423,7 +422,7 @@ static void tst7() {
|
||||||
|
|
||||||
nlsat::literal_vector litsv(lits.size(), lits.c_ptr());
|
nlsat::literal_vector litsv(lits.size(), lits.c_ptr());
|
||||||
lbool res = s.check(litsv);
|
lbool res = s.check(litsv);
|
||||||
SASSERT(res == l_false);
|
VERIFY(res == l_false);
|
||||||
for (unsigned i = 0; i < litsv.size(); ++i) {
|
for (unsigned i = 0; i < litsv.size(); ++i) {
|
||||||
s.display(std::cout, litsv[i]);
|
s.display(std::cout, litsv[i]);
|
||||||
std::cout << " ";
|
std::cout << " ";
|
||||||
|
|
|
@ -61,6 +61,7 @@ static void tst1() {
|
||||||
m.recycle(c1);
|
m.recycle(c1);
|
||||||
|
|
||||||
cell * c3 = m.allocate<true>();
|
cell * c3 = m.allocate<true>();
|
||||||
|
(void)c3;
|
||||||
SASSERT(c3->m_coeff.is_zero());
|
SASSERT(c3->m_coeff.is_zero());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -120,9 +120,9 @@ class interval_tester {
|
||||||
|
|
||||||
interval singleton(int i) { return interval(m, rational(i)); }
|
interval singleton(int i) { return interval(m, rational(i)); }
|
||||||
interval all() { return interval(m); }
|
interval all() { return interval(m); }
|
||||||
interval l(int i, bool o = false, int idx = 0) { return interval(m, rational(i), o, true, idx == 0 ? 0 : m.mk_leaf(reinterpret_cast<void*>(idx))); }
|
interval l(int i, bool o = false, size_t idx = 0) { return interval(m, rational(i), o, true, idx == 0 ? 0 : m.mk_leaf(reinterpret_cast<void*>(idx))); }
|
||||||
interval r(int i, bool o = false, int idx = 0) { return interval(m, rational(i), o, false, idx == 0 ? 0 : m.mk_leaf(reinterpret_cast<void*>(idx))); }
|
interval r(int i, bool o = false, size_t idx = 0) { return interval(m, rational(i), o, false, idx == 0 ? 0 : m.mk_leaf(reinterpret_cast<void*>(idx))); }
|
||||||
interval b(int l, int u, bool lo = false, bool uo = false, int idx_l = 0, int idx_u = 0) {
|
interval b(int l, int u, bool lo = false, bool uo = false, size_t idx_l = 0, size_t idx_u = 0) {
|
||||||
return interval(m, rational(l), lo, idx_l == 0 ? 0 : m.mk_leaf(reinterpret_cast<void*>(idx_l)), rational(u), uo, idx_u == 0 ? 0 : m.mk_leaf(reinterpret_cast<void*>(idx_u)));
|
return interval(m, rational(l), lo, idx_l == 0 ? 0 : m.mk_leaf(reinterpret_cast<void*>(idx_l)), rational(u), uo, idx_u == 0 ? 0 : m.mk_leaf(reinterpret_cast<void*>(idx_u)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,10 +83,10 @@ static void test_semantics(ast_manager& m, expr_ref_vector const& vars, vector<r
|
||||||
th_rw(fml2, result2, proof);
|
th_rw(fml2, result2, proof);
|
||||||
SASSERT(m.is_true(result2) || m.is_false(result2));
|
SASSERT(m.is_true(result2) || m.is_false(result2));
|
||||||
lbool res = solver.check();
|
lbool res = solver.check();
|
||||||
SASSERT(res == l_true);
|
VERIFY(res == l_true);
|
||||||
solver.assert_expr(m.is_true(result2) ? m.mk_not(result1) : result1.get());
|
solver.assert_expr(m.is_true(result2) ? m.mk_not(result1) : result1.get());
|
||||||
res = solver.check();
|
res = solver.check();
|
||||||
SASSERT(res == l_false);
|
VERIFY(res == l_false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,10 +152,10 @@ static void test_solver_semantics(ast_manager& m, expr_ref_vector const& vars, v
|
||||||
th_rw(fml2, result2, proof);
|
th_rw(fml2, result2, proof);
|
||||||
SASSERT(m.is_true(result2) || m.is_false(result2));
|
SASSERT(m.is_true(result2) || m.is_false(result2));
|
||||||
lbool res = slv->check_sat(0,0);
|
lbool res = slv->check_sat(0,0);
|
||||||
SASSERT(res == l_true);
|
VERIFY(res == l_true);
|
||||||
slv->assert_expr(m.is_true(result2) ? m.mk_not(result1) : result1.get());
|
slv->assert_expr(m.is_true(result2) ? m.mk_not(result1) : result1.get());
|
||||||
res = slv->check_sat(0,0);
|
res = slv->check_sat(0,0);
|
||||||
SASSERT(res == l_false);
|
VERIFY(res == l_false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,8 @@ private:
|
||||||
expr_ref_vector& factors = poly.factors();
|
expr_ref_vector& factors = poly.factors();
|
||||||
expr_ref_vector& coefficients = poly.coefficients();
|
expr_ref_vector& coefficients = poly.coefficients();
|
||||||
expr_ref& coefficient = poly.coefficient();
|
expr_ref& coefficient = poly.coefficient();
|
||||||
|
(void) coefficient;
|
||||||
|
(void) coefficients;
|
||||||
|
|
||||||
m_rw(term);
|
m_rw(term);
|
||||||
|
|
||||||
|
@ -170,7 +172,7 @@ static expr_ref mk_mul(arith_util& arith, unsigned num_args, expr* const* args)
|
||||||
|
|
||||||
static void nf(expr_ref& term) {
|
static void nf(expr_ref& term) {
|
||||||
ast_manager& m = term.get_manager();
|
ast_manager& m = term.get_manager();
|
||||||
expr *e1, *e2;
|
expr *e1 = 0, *e2 = 0;
|
||||||
|
|
||||||
th_rewriter rw(m);
|
th_rewriter rw(m);
|
||||||
arith_util arith(m);
|
arith_util arith(m);
|
||||||
|
|
|
@ -11,7 +11,6 @@ void tst_checker1() {
|
||||||
ast_manager m(PGM_FINE);
|
ast_manager m(PGM_FINE);
|
||||||
expr_ref a(m);
|
expr_ref a(m);
|
||||||
proof_ref p1(m), p2(m), p3(m), p4(m);
|
proof_ref p1(m), p2(m), p3(m), p4(m);
|
||||||
bool result;
|
|
||||||
expr_ref_vector side_conditions(m);
|
expr_ref_vector side_conditions(m);
|
||||||
|
|
||||||
a = m.mk_const(symbol("a"), m.mk_bool_sort());
|
a = m.mk_const(symbol("a"), m.mk_bool_sort());
|
||||||
|
@ -26,8 +25,7 @@ void tst_checker1() {
|
||||||
proof_checker checker(m);
|
proof_checker checker(m);
|
||||||
p4 = m.mk_lemma(p3.get(), m.mk_or(a.get(), m.mk_not(a.get())));
|
p4 = m.mk_lemma(p3.get(), m.mk_or(a.get(), m.mk_not(a.get())));
|
||||||
ast_ll_pp(std::cout, m, p4.get());
|
ast_ll_pp(std::cout, m, p4.get());
|
||||||
result = checker.check(p4.get(), side_conditions);
|
VERIFY(checker.check(p4.get(), side_conditions));
|
||||||
SASSERT(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_proof_checker() {
|
void tst_proof_checker() {
|
||||||
|
|
|
@ -163,7 +163,7 @@ static app_ref generate_ineqs(ast_manager& m, sort* s, vector<expr_ref_vector>&
|
||||||
|
|
||||||
app* x = vars[0].get();
|
app* x = vars[0].get();
|
||||||
app* y = vars[1].get();
|
app* y = vars[1].get();
|
||||||
app* z = vars[2].get();
|
// app* z = vars[2].get();
|
||||||
//
|
//
|
||||||
// ax <= by, ax < by, not (ax >= by), not (ax > by)
|
// ax <= by, ax < by, not (ax >= by), not (ax > by)
|
||||||
//
|
//
|
||||||
|
@ -247,7 +247,7 @@ static void test2(char const *ex) {
|
||||||
ctx.push();
|
ctx.push();
|
||||||
ctx.assert_expr(fml);
|
ctx.assert_expr(fml);
|
||||||
lbool result = ctx.check();
|
lbool result = ctx.check();
|
||||||
SASSERT(result == l_true);
|
VERIFY(result == l_true);
|
||||||
ref<model> md;
|
ref<model> md;
|
||||||
ctx.get_model(md);
|
ctx.get_model(md);
|
||||||
ctx.pop(1);
|
ctx.pop(1);
|
||||||
|
|
|
@ -196,7 +196,7 @@ static void tst2() {
|
||||||
// get_int64, get_uint64
|
// get_int64, get_uint64
|
||||||
uint64 u1 = uint64_max.get_uint64();
|
uint64 u1 = uint64_max.get_uint64();
|
||||||
uint64 u2 = UINT64_MAX;
|
uint64 u2 = UINT64_MAX;
|
||||||
SASSERT(u1 == u2);
|
VERIFY(u1 == u2);
|
||||||
std::cout << "int64_max: " << int64_max << ", INT64_MAX: " << INT64_MAX << ", int64_max.get_int64(): " << int64_max.get_int64() << ", int64_max.get_uint64(): " << int64_max.get_uint64() << "\n";
|
std::cout << "int64_max: " << int64_max << ", INT64_MAX: " << INT64_MAX << ", int64_max.get_int64(): " << int64_max.get_int64() << ", int64_max.get_uint64(): " << int64_max.get_uint64() << "\n";
|
||||||
SASSERT(int64_max.get_int64() == INT64_MAX);
|
SASSERT(int64_max.get_int64() == INT64_MAX);
|
||||||
SASSERT(int64_min.get_int64() == INT64_MIN);
|
SASSERT(int64_min.get_int64() == INT64_MIN);
|
||||||
|
|
|
@ -34,10 +34,6 @@ static void add_clause(sat::solver& s, random_gen& r, trail_t& t) {
|
||||||
s.mk_clause(cls.size(), cls.c_ptr());
|
s.mk_clause(cls.size(), cls.c_ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void display_state(std::ostream& out, sat::solver& s, trail_t& t) {
|
|
||||||
s.display(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pop_user_scope(sat::solver& s, trail_t& t) {
|
static void pop_user_scope(sat::solver& s, trail_t& t) {
|
||||||
std::cout << "pop\n";
|
std::cout << "pop\n";
|
||||||
s.user_pop(1);
|
s.user_pop(1);
|
||||||
|
|
|
@ -38,6 +38,7 @@ void tst_simple_parser() {
|
||||||
TRACE("simple_parser", tout << mk_pp(r, m) << "\n";);
|
TRACE("simple_parser", tout << mk_pp(r, m) << "\n";);
|
||||||
p.parse_string("(+ x (* y x) x)", r);
|
p.parse_string("(+ x (* y x) x)", r);
|
||||||
float vals[2] = { 2.0f, 3.0f };
|
float vals[2] = { 2.0f, 3.0f };
|
||||||
|
(void)vals;
|
||||||
TRACE("simple_parser",
|
TRACE("simple_parser",
|
||||||
tout << mk_pp(r, m) << "\n";
|
tout << mk_pp(r, m) << "\n";
|
||||||
tout << "val: " << eval(r, 2, vals) << "\n";);
|
tout << "val: " << eval(r, 2, vals) << "\n";);
|
||||||
|
|
|
@ -36,5 +36,14 @@ void tst_small_object_allocator() {
|
||||||
r3 = new (soa) char[1];
|
r3 = new (soa) char[1];
|
||||||
TRACE("small_object_allocator",
|
TRACE("small_object_allocator",
|
||||||
tout << "r1: " << (void*)r1 << " r2: " << (void*)r2 << " r3: " << (void*)r3 << " r4: " << (void*)r4 << "\n";);
|
tout << "r1: " << (void*)r1 << " r2: " << (void*)r2 << " r3: " << (void*)r3 << " r4: " << (void*)r4 << "\n";);
|
||||||
|
(void)r1;
|
||||||
|
(void)r2;
|
||||||
|
(void)r3;
|
||||||
|
(void)r4;
|
||||||
|
|
||||||
|
(void)q1;
|
||||||
|
|
||||||
|
(void)p1;
|
||||||
|
(void)p2;
|
||||||
|
(void)p3;
|
||||||
}
|
}
|
||||||
|
|
|
@ -364,15 +364,13 @@ void test_at_most_1(unsigned n, bool full) {
|
||||||
for (unsigned i = 0; i < ext.m_clauses.size(); ++i) {
|
for (unsigned i = 0; i < ext.m_clauses.size(); ++i) {
|
||||||
solver.assert_expr(ext.m_clauses[i].get());
|
solver.assert_expr(ext.m_clauses[i].get());
|
||||||
}
|
}
|
||||||
lbool res;
|
|
||||||
if (full) {
|
if (full) {
|
||||||
solver.push();
|
solver.push();
|
||||||
solver.assert_expr(m.mk_not(m.mk_eq(result1, result2)));
|
solver.assert_expr(m.mk_not(m.mk_eq(result1, result2)));
|
||||||
|
|
||||||
std::cout << result1 << "\n";
|
std::cout << result1 << "\n";
|
||||||
|
|
||||||
res = solver.check();
|
VERIFY(l_false == solver.check());
|
||||||
SASSERT(res == l_false);
|
|
||||||
|
|
||||||
solver.pop(1);
|
solver.pop(1);
|
||||||
}
|
}
|
||||||
|
@ -390,8 +388,7 @@ void test_at_most_1(unsigned n, bool full) {
|
||||||
std::cout << atom << "\n";
|
std::cout << atom << "\n";
|
||||||
if (is_true) ++k;
|
if (is_true) ++k;
|
||||||
}
|
}
|
||||||
res = solver.check();
|
VERIFY(l_false == solver.check());
|
||||||
SASSERT(res == l_true);
|
|
||||||
if (k > 1) {
|
if (k > 1) {
|
||||||
solver.assert_expr(result1);
|
solver.assert_expr(result1);
|
||||||
}
|
}
|
||||||
|
@ -402,8 +399,7 @@ void test_at_most_1(unsigned n, bool full) {
|
||||||
else {
|
else {
|
||||||
solver.assert_expr(m.mk_not(result1));
|
solver.assert_expr(m.mk_not(result1));
|
||||||
}
|
}
|
||||||
res = solver.check();
|
VERIFY(l_false == solver.check());
|
||||||
SASSERT(res == l_false);
|
|
||||||
solver.pop(1);
|
solver.pop(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,8 @@ void tst_substitution()
|
||||||
|
|
||||||
bool ok1 = unif(v1.get(), v2.get(), subst, false);
|
bool ok1 = unif(v1.get(), v2.get(), subst, false);
|
||||||
bool ok2 = unif(v2.get(), v1.get(), subst, false);
|
bool ok2 = unif(v2.get(), v1.get(), subst, false);
|
||||||
|
(void)ok1;
|
||||||
|
(void)ok2;
|
||||||
|
|
||||||
expr_ref res(m);
|
expr_ref res(m);
|
||||||
|
|
||||||
|
|
|
@ -129,18 +129,18 @@ static void tst_isolate_roots(polynomial_ref const & p, unsigned prec, mpbq_mana
|
||||||
tout << "fourier upper: " << um.sign_variations_at(fseq, uppers[i]) << "\n";);
|
tout << "fourier upper: " << um.sign_variations_at(fseq, uppers[i]) << "\n";);
|
||||||
unsigned fsv_lower = um.sign_variations_at(fseq, lowers[i]);
|
unsigned fsv_lower = um.sign_variations_at(fseq, lowers[i]);
|
||||||
unsigned fsv_upper = um.sign_variations_at(fseq, uppers[i]);
|
unsigned fsv_upper = um.sign_variations_at(fseq, uppers[i]);
|
||||||
SASSERT(um.eval_sign_at(q.size(), q.c_ptr(), lowers[i]) == 0 ||
|
VERIFY(um.eval_sign_at(q.size(), q.c_ptr(), lowers[i]) == 0 ||
|
||||||
um.eval_sign_at(q.size(), q.c_ptr(), uppers[i]) == 0 ||
|
um.eval_sign_at(q.size(), q.c_ptr(), uppers[i]) == 0 ||
|
||||||
// fsv_lower - fsv_upper is an upper bound for the number of roots in the interval
|
// fsv_lower - fsv_upper is an upper bound for the number of roots in the interval
|
||||||
// fsv_upper - fsv_upper - num_roots is even
|
// fsv_upper - fsv_upper - num_roots is even
|
||||||
// Recall that num_roots == 1 in the interval.
|
// Recall that num_roots == 1 in the interval.
|
||||||
(fsv_lower - fsv_upper >= 1 && (fsv_lower - fsv_upper - 1) % 2 == 0));
|
(fsv_lower - fsv_upper >= 1 && (fsv_lower - fsv_upper - 1) % 2 == 0));
|
||||||
|
|
||||||
// Double checking using Descartes bounds for the interval
|
// Double checking using Descartes bounds for the interval
|
||||||
// Must use square free component.
|
// Must use square free component.
|
||||||
unsigned dab = um.descartes_bound_a_b(q_sqf.size(), q_sqf.c_ptr(), bqm, lowers[i], uppers[i]);
|
unsigned dab = um.descartes_bound_a_b(q_sqf.size(), q_sqf.c_ptr(), bqm, lowers[i], uppers[i]);
|
||||||
TRACE("upolynomial", tout << "Descartes bound: " << dab << "\n";);
|
TRACE("upolynomial", tout << "Descartes bound: " << dab << "\n";);
|
||||||
SASSERT(dab == 1);
|
VERIFY(dab == 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::cout << "\n";
|
std::cout << "\n";
|
||||||
|
@ -164,7 +164,7 @@ static void check_roots(mpbq_vector const & roots, mpbq_vector const & lowers, m
|
||||||
for (unsigned j = 0; j < roots.size(); j++) {
|
for (unsigned j = 0; j < roots.size(); j++) {
|
||||||
if (to_rational(roots[j]) == r) {
|
if (to_rational(roots[j]) == r) {
|
||||||
SASSERT(!visited[j]);
|
SASSERT(!visited[j]);
|
||||||
SASSERT(!found);
|
VERIFY(!found);
|
||||||
found = true;
|
found = true;
|
||||||
visited[j] = true;
|
visited[j] = true;
|
||||||
}
|
}
|
||||||
|
@ -172,7 +172,7 @@ static void check_roots(mpbq_vector const & roots, mpbq_vector const & lowers, m
|
||||||
for (unsigned j = 0; j < lowers.size(); j++) {
|
for (unsigned j = 0; j < lowers.size(); j++) {
|
||||||
unsigned j_prime = j + roots.size();
|
unsigned j_prime = j + roots.size();
|
||||||
if (to_rational(lowers[j]) < r && r < to_rational(uppers[j])) {
|
if (to_rational(lowers[j]) < r && r < to_rational(uppers[j])) {
|
||||||
SASSERT(!found);
|
VERIFY(!found);
|
||||||
SASSERT(!visited[j_prime]);
|
SASSERT(!visited[j_prime]);
|
||||||
found = true;
|
found = true;
|
||||||
visited[j_prime] = true;
|
visited[j_prime] = true;
|
||||||
|
@ -499,7 +499,7 @@ static void tst_refinable(polynomial_ref const & p, mpbq_manager & bqm, mpbq & a
|
||||||
std::cout << "new (" << bqm.to_string(a) << ", " << bqm.to_string(b) << ")\n";
|
std::cout << "new (" << bqm.to_string(a) << ", " << bqm.to_string(b) << ")\n";
|
||||||
int sign_a = um.eval_sign_at(_p.size(), _p.c_ptr(), a);
|
int sign_a = um.eval_sign_at(_p.size(), _p.c_ptr(), a);
|
||||||
int sign_b = um.eval_sign_at(_p.size(), _p.c_ptr(), b);
|
int sign_b = um.eval_sign_at(_p.size(), _p.c_ptr(), b);
|
||||||
SASSERT(sign_a != 0 && sign_b != 0 && sign_a == -sign_b);
|
VERIFY(sign_a != 0 && sign_b != 0 && sign_a == -sign_b);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::cout << "new root: " << bqm.to_string(a) << "\n";
|
std::cout << "new root: " << bqm.to_string(a) << "\n";
|
||||||
|
|
|
@ -91,6 +91,31 @@ public:
|
||||||
SASSERT(invariant());
|
SASSERT(invariant());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class iterator {
|
||||||
|
scoped_vector const& m_vec;
|
||||||
|
unsigned m_index;
|
||||||
|
public:
|
||||||
|
iterator(scoped_vector const& v, unsigned idx): m_vec(v), m_index(idx) {}
|
||||||
|
|
||||||
|
bool operator==(iterator const& other) const { return &other.m_vec == &m_vec && other.m_index == m_index; }
|
||||||
|
bool operator!=(iterator const& other) const { return &other.m_vec != &m_vec || other.m_index != m_index; }
|
||||||
|
T const& operator*() { return m_vec[m_index]; }
|
||||||
|
|
||||||
|
iterator & operator++() {
|
||||||
|
++m_index;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator operator++(int) {
|
||||||
|
iterator r = *this;
|
||||||
|
++m_index;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
iterator begin() { return iterator(*this, 0); }
|
||||||
|
iterator end() { return iterator(*this, m_size); }
|
||||||
|
|
||||||
void push_back(T const& t) {
|
void push_back(T const& t) {
|
||||||
set_index(m_size, m_elems.size());
|
set_index(m_size, m_elems.size());
|
||||||
m_elems.push_back(t);
|
m_elems.push_back(t);
|
||||||
|
|
|
@ -79,12 +79,7 @@ class total_order {
|
||||||
}
|
}
|
||||||
|
|
||||||
cell * to_cell(T const & a) const {
|
cell * to_cell(T const & a) const {
|
||||||
void * r;
|
void * r = m_map.find(a);
|
||||||
#ifdef Z3DEBUG
|
|
||||||
bool ok =
|
|
||||||
#endif
|
|
||||||
m_map.find(a, r);
|
|
||||||
SASSERT(ok);
|
|
||||||
return reinterpret_cast<cell*>(r);
|
return reinterpret_cast<cell*>(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,11 @@ public:
|
||||||
return v != 0;
|
return v != 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
T * find(unsigned k) const {
|
||||||
|
SASSERT(k < m_map.size() && m_map[k] != 0);
|
||||||
|
return m_map[k];
|
||||||
|
}
|
||||||
|
|
||||||
void insert(unsigned k, T * v) {
|
void insert(unsigned k, T * v) {
|
||||||
m_map.reserve(k+1);
|
m_map.reserve(k+1);
|
||||||
|
|
Loading…
Reference in a new issue