mirror of
https://github.com/Z3Prover/z3
synced 2025-04-28 19:35:50 +00:00
Merge branch 'upstream-master' into release-1.0
Conflicts: src/cmd_context/check_logic.cpp src/cmd_context/cmd_context.cpp src/cmd_context/cmd_context.h src/smt/params/smt_params_helper.pyg src/smt/smt_context.cpp
This commit is contained in:
commit
235ea79043
588 changed files with 21784 additions and 15202 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -59,8 +59,8 @@ src/api/dotnet/Enumerations.cs
|
|||
src/api/dotnet/Native.cs
|
||||
src/api/dotnet/Properties/AssemblyInfo.cs
|
||||
src/api/dotnet/Microsoft.Z3.xml
|
||||
src/api/python/z3consts.py
|
||||
src/api/python/z3core.py
|
||||
src/api/python/z3/z3consts.py
|
||||
src/api/python/z3/z3core.py
|
||||
src/ast/pattern/database.h
|
||||
src/util/version.h
|
||||
src/api/java/Native.cpp
|
||||
|
|
|
@ -32,9 +32,10 @@ project(Z3 C CXX)
|
|||
# Project version
|
||||
################################################################################
|
||||
set(Z3_VERSION_MAJOR 4)
|
||||
set(Z3_VERSION_MINOR 4)
|
||||
set(Z3_VERSION_PATCH 2)
|
||||
set(Z3_VERSION_MINOR 5)
|
||||
set(Z3_VERSION_PATCH 1)
|
||||
set(Z3_VERSION_TWEAK 0)
|
||||
set(Z3_FULL_VERSION 0)
|
||||
set(Z3_VERSION "${Z3_VERSION_MAJOR}.${Z3_VERSION_MINOR}.${Z3_VERSION_PATCH}.${Z3_VERSION_TWEAK}")
|
||||
message(STATUS "Z3 version ${Z3_VERSION}")
|
||||
|
||||
|
@ -246,7 +247,7 @@ endif()
|
|||
# FP math
|
||||
################################################################################
|
||||
# FIXME: Support ARM "-mfpu=vfp -mfloat-abi=hard"
|
||||
if ("${TARGET_ARCHITECTURE}" STREQUAL "x86_64")
|
||||
if (("${TARGET_ARCHITECTURE}" STREQUAL "x86_64") OR ("${TARGET_ARCHITECTURE}" STREQUAL "i686"))
|
||||
if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang"))
|
||||
set(SSE_FLAGS "-mfpmath=sse" "-msse" "-msse2")
|
||||
# FIXME: Remove "x.." when CMP0054 is set to NEW
|
||||
|
@ -304,7 +305,10 @@ endif()
|
|||
# library. If not building a shared library ``-fPIC`` isn't needed and would add
|
||||
# unnecessary overhead.
|
||||
if (BUILD_LIBZ3_SHARED)
|
||||
if (NOT MSVC)
|
||||
# Avoid adding -fPIC compiler switch if we compile with MSVC (which does not
|
||||
# support the flag) or if we target Windows, which generally does not use
|
||||
# position independent code for native code shared libraries (DLLs).
|
||||
if (NOT (MSVC OR MINGW OR WIN32))
|
||||
z3_add_cxx_flag("-fPIC" REQUIRED)
|
||||
endif()
|
||||
endif()
|
||||
|
@ -387,4 +391,3 @@ option(ENABLE_EXAMPLE_TARGETS "Build Z3 api examples" ON)
|
|||
if (ENABLE_EXAMPLE_TARGETS)
|
||||
add_subdirectory(examples)
|
||||
endif()
|
||||
|
||||
|
|
16
README.md
16
README.md
|
@ -10,6 +10,12 @@ Z3 can be built using [Visual Studio][1], a [Makefile][2] or using [CMake][3]. I
|
|||
|
||||
See the [release notes](RELEASE_NOTES) for notes on various stable releases of Z3.
|
||||
|
||||
## Build status
|
||||
|
||||
| Windows x86 | Windows x64 | Ubuntu x64 | Ubuntu x86 | Debian x64 | OSX |
|
||||
| ----------- | ----------- | ---------- | ---------- | ---------- | --- |
|
||||
 |  |  |  |  | 
|
||||
|
||||
[1]: #building-z3-on-windows-using-visual-studio-command-prompt
|
||||
[2]: #building-z3-using-make-and-gccclang
|
||||
[3]: #building-z3-using-cmake
|
||||
|
@ -56,6 +62,16 @@ CXX=clang++ CC=clang python scripts/mk_make.py
|
|||
|
||||
Note that Clang < 3.7 does not support OpenMP.
|
||||
|
||||
You can also build Z3 for Windows using Cygwin and the Mingw-w64 cross-compiler.
|
||||
To configure that case correctly, make sure to use Cygwin's own python and not
|
||||
some Windows installation of Python.
|
||||
|
||||
For a 64 bit build (from Cygwin64), configure Z3's sources with
|
||||
```bash
|
||||
CXX=x86_64-w64-mingw32-g++ CC=x86_64-w64-mingw32-gcc AR=x86_64-w64-mingw32-ar python scripts/mk_make.py
|
||||
```
|
||||
A 32 bit build should work similarly (but is untested); the same is true for 32/64 bit builds from within Cygwin32.
|
||||
|
||||
By default, it will install z3 executable at ``PREFIX/bin``, libraries at
|
||||
``PREFIX/lib``, and include files at ``PREFIX/include``, where ``PREFIX``
|
||||
installation prefix if inferred by the ``mk_make.py`` script. It is usually
|
||||
|
|
|
@ -1,5 +1,48 @@
|
|||
RELEASE NOTES
|
||||
|
||||
Version 4.5.0
|
||||
=============
|
||||
|
||||
- New features:
|
||||
- New theories of strings and sequences.
|
||||
- Consequence finding API "get-consequences" to compute
|
||||
set of consequences modulo hard constraints and set of
|
||||
assumptions. Optimized implementations provided for finite
|
||||
domains (QF_FD) and for most SMT logics.
|
||||
- CMake build system (thanks @delcypher).
|
||||
- New API functions, including accessing assertions, parsing SMT-LIB benchmarks.
|
||||
- Updated and improved OCaml API (thanks @martin-neuhaeusser).
|
||||
- Updated and improved Java API (thanks @cheshire).
|
||||
- New resource limit facilities to avoid non-deterministic timeout behaviour.
|
||||
You can enable it from the command-line using the switch rlimit=<numeral>.
|
||||
- New bit-vector simplification and ackermannization
|
||||
tactics (thanks @MikolasJanota, @nunoplopes).
|
||||
- QSAT: a new solver for satisfiability of quantified arithmetic formulas.
|
||||
See: Bjorner, Janota: Playing with Quantified Satisfaction, LPAR 2016.
|
||||
This is the new default solver for logics LIA, LRA, NRA. It furthermore
|
||||
can be applied as a tactic on quantified formulas using algebraic
|
||||
data-types (but excluding selector sub-terms because Z3 does not
|
||||
specify the semantics of applying a selector to a non-matching
|
||||
constructor term).
|
||||
- A specialized logic QF_FD and associated incremental solver
|
||||
(that supports push/pop).
|
||||
The QF_FD domain comprises of bit-vectors, enumeration data-types
|
||||
used only in equalities, and bounded integers: Integers used in
|
||||
QF_FD problems have to be constrained by a finite bound.
|
||||
- Queries in the fixedpoint engine are now function symbols and not
|
||||
formulas with free variables. This makes the association of
|
||||
free variables in the answers unambiguous. To emulate queries
|
||||
over compound formulas, introduce a fresh predicate whose
|
||||
arguments are the relevant free variables in the formula and add a rule
|
||||
that uses the fresh predicate in the head and formula in the body.
|
||||
- minimization of unsat cores is avaialble as an option for the SAT and SMT cores.
|
||||
By setting smt.core.minimize=true resp. sat.core.minimize=true
|
||||
cores produced by these modules are minimized.
|
||||
|
||||
|
||||
- A multitude of bugs has been fixed.
|
||||
|
||||
|
||||
Version 4.4.1
|
||||
=============
|
||||
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
add_subdirectory(c)
|
||||
add_subdirectory(c++)
|
||||
add_subdirectory(tptp)
|
||||
add_subdirectory(python)
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
# FIXME: We should build this as an external project and consume
|
||||
# Z3 as `find_package(z3 CONFIG)`.
|
||||
add_executable(cpp_example EXCLUDE_FROM_ALL example.cpp)
|
||||
target_link_libraries(cpp_example PRIVATE libz3)
|
||||
target_include_directories(cpp_example PRIVATE "${CMAKE_SOURCE_DIR}/src/api")
|
||||
target_include_directories(cpp_example PRIVATE "${CMAKE_SOURCE_DIR}/src/api/c++")
|
||||
if (NOT BUILD_LIBZ3_SHARED)
|
||||
z3_append_linker_flag_list_to_target(cpp_example ${Z3_DEPENDENT_EXTRA_CXX_LINK_FLAGS})
|
||||
endif()
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
# FIXME: We should build this as an external project and consume
|
||||
# Z3 as `find_package(z3 CONFIG)`.
|
||||
add_executable(c_example EXCLUDE_FROM_ALL test_capi.c)
|
||||
target_link_libraries(c_example PRIVATE libz3)
|
||||
target_include_directories(c_example PRIVATE "${CMAKE_SOURCE_DIR}/src/api")
|
||||
# This is needed for when libz3 is built as a static library
|
||||
if (NOT BUILD_LIBZ3_SHARED)
|
||||
z3_append_linker_flag_list_to_target(c_example ${Z3_DEPENDENT_EXTRA_C_LINK_FLAGS})
|
||||
endif()
|
||||
|
|
24
contrib/cmake/examples/python/CMakeLists.txt
Normal file
24
contrib/cmake/examples/python/CMakeLists.txt
Normal file
|
@ -0,0 +1,24 @@
|
|||
set(python_example_files
|
||||
example.py
|
||||
visitor.py
|
||||
)
|
||||
|
||||
set(z3py_bindings_build_dest "${CMAKE_BINARY_DIR}/python")
|
||||
|
||||
set(build_z3_python_examples_target_depends "")
|
||||
foreach (example_file ${python_example_files})
|
||||
add_custom_command(OUTPUT "${z3py_bindings_build_dest}/${example_file}"
|
||||
COMMAND "${CMAKE_COMMAND}" "-E" "copy"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/${example_file}"
|
||||
"${z3py_bindings_build_dest}/${example_file}"
|
||||
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${example_file}"
|
||||
COMMENT "Copying \"${example_file}\" to ${z3py_bindings_build_dest}/${example_file}"
|
||||
)
|
||||
list(APPEND build_z3_python_examples_target_depends "${z3py_bindings_build_dest}/${example_file}")
|
||||
endforeach()
|
||||
|
||||
add_custom_target(build_z3_python_examples
|
||||
ALL
|
||||
DEPENDS
|
||||
${build_z3_python_examples_target_depends}
|
||||
)
|
4
contrib/cmake/examples/tptp/CMakeLists.txt
Normal file
4
contrib/cmake/examples/tptp/CMakeLists.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
add_executable(z3_tptp5 EXCLUDE_FROM_ALL tptp5.cpp tptp5.lex.cpp)
|
||||
target_link_libraries(z3_tptp5 PRIVATE libz3)
|
||||
target_include_directories(z3_tptp5 PRIVATE "${CMAKE_SOURCE_DIR}/src/api")
|
||||
target_include_directories(z3_tptp5 PRIVATE "${CMAKE_SOURCE_DIR}/src/api/c++")
|
|
@ -117,14 +117,16 @@ else()
|
|||
set(lib_type "STATIC")
|
||||
endif()
|
||||
add_library(libz3 ${lib_type} ${object_files})
|
||||
# FIXME: Set "VERSION" and "SOVERSION" properly
|
||||
set_target_properties(libz3 PROPERTIES
|
||||
# FIXME: Should we be using ${Z3_VERSION} here?
|
||||
# VERSION: Sets up symlinks, does it do anything else?
|
||||
# VERSION determines the version in the filename of the shared library.
|
||||
# SOVERSION determines the value of the DT_SONAME field on ELF platforms.
|
||||
# On ELF platforms the final compiled filename will be libz3.so.W.X.Y.Z
|
||||
# but symlinks will be made to this file from libz3.so and also from
|
||||
# libz3.so.W.X.
|
||||
# This indicates that no breaking API changes will be made within a single
|
||||
# minor version.
|
||||
VERSION ${Z3_VERSION}
|
||||
# SOVERSION: On platforms that use ELF this sets the API version
|
||||
# and should be incremented everytime the API changes
|
||||
SOVERSION ${Z3_VERSION})
|
||||
SOVERSION ${Z3_VERSION_MAJOR}.${Z3_VERSION_MINOR})
|
||||
|
||||
if (NOT MSVC)
|
||||
# On UNIX like platforms if we don't change the OUTPUT_NAME
|
||||
|
@ -136,9 +138,10 @@ if (NOT MSVC)
|
|||
set_target_properties(libz3 PROPERTIES OUTPUT_NAME z3)
|
||||
endif()
|
||||
|
||||
# Using INTERFACE means that targets that try link against libz3 will
|
||||
# automatically link against the libs in Z3_DEPENDENT_LIBS
|
||||
target_link_libraries(libz3 INTERFACE ${Z3_DEPENDENT_LIBS})
|
||||
# The `PRIVATE` usage requirement is specified so that when building Z3 as a
|
||||
# shared library the dependent libraries are specified on the link command line
|
||||
# so that if those are also shared libraries they are referenced by `libz3.so`.
|
||||
target_link_libraries(libz3 PRIVATE ${Z3_DEPENDENT_LIBS})
|
||||
|
||||
z3_append_linker_flag_list_to_target(libz3 ${Z3_DEPENDENT_EXTRA_CXX_LINK_FLAGS})
|
||||
|
||||
|
|
|
@ -156,7 +156,7 @@ elseif (DOTNET_TOOLCHAIN_IS_MONO)
|
|||
# We need to give the assembly a strong name so that it can be installed
|
||||
# into the GAC.
|
||||
list(APPEND CSC_FLAGS
|
||||
"/keyfile:${CMAKE_CURRENT_SOURCE_DIR}/Microsoft.Z3.mono.snk"
|
||||
"/keyfile:${CMAKE_CURRENT_SOURCE_DIR}/Microsoft.Z3.snk"
|
||||
)
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown .NET toolchain")
|
||||
|
|
|
@ -110,7 +110,9 @@ set(Z3_JAVA_JAR_SOURCE_FILES
|
|||
BitVecSort.java
|
||||
BoolExpr.java
|
||||
BoolSort.java
|
||||
ConstructorDecRefQueue.java
|
||||
Constructor.java
|
||||
ConstructorListDecRefQueue.java
|
||||
ConstructorList.java
|
||||
Context.java
|
||||
DatatypeExpr.java
|
||||
|
@ -136,7 +138,6 @@ set(Z3_JAVA_JAR_SOURCE_FILES
|
|||
GoalDecRefQueue.java
|
||||
Goal.java
|
||||
IDecRefQueue.java
|
||||
IDisposable.java
|
||||
InterpolationContext.java
|
||||
IntExpr.java
|
||||
IntNum.java
|
||||
|
|
|
@ -4,32 +4,35 @@ message(STATUS "Emitting rules to build Z3 python bindings")
|
|||
###############################################################################
|
||||
# This allows the python bindings to be used directly from the build directory
|
||||
set(z3py_files
|
||||
z3.py
|
||||
z3num.py
|
||||
z3poly.py
|
||||
z3printer.py
|
||||
z3rcf.py
|
||||
z3/__init__.py
|
||||
z3/z3.py
|
||||
z3/z3num.py
|
||||
z3/z3poly.py
|
||||
z3/z3printer.py
|
||||
z3/z3rcf.py
|
||||
z3test.py
|
||||
z3types.py
|
||||
z3util.py
|
||||
z3/z3types.py
|
||||
z3/z3util.py
|
||||
)
|
||||
|
||||
set(z3py_bindings_build_dest "${CMAKE_BINARY_DIR}")
|
||||
set(z3py_bindings_build_dest "${CMAKE_BINARY_DIR}/python")
|
||||
file(MAKE_DIRECTORY "${z3py_bindings_build_dest}")
|
||||
file(MAKE_DIRECTORY "${z3py_bindings_build_dest}/z3")
|
||||
|
||||
set(build_z3_python_bindings_target_depends "")
|
||||
foreach (z3py_file ${z3py_files})
|
||||
add_custom_command(OUTPUT "${z3py_bindings_build_dest}/${z3py_file}"
|
||||
COMMAND "${CMAKE_COMMAND}" "-E" "copy"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/${z3py_file}"
|
||||
"${z3py_bindings_build_dest}"
|
||||
"${z3py_bindings_build_dest}/${z3py_file}"
|
||||
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${z3py_file}"
|
||||
COMMENT "Copying \"${z3py_file}\" to ${z3py_bindings_build_dest}"
|
||||
COMMENT "Copying \"${z3py_file}\" to ${z3py_bindings_build_dest}/${z3py_file}"
|
||||
)
|
||||
list(APPEND build_z3_python_bindings_target_depends "${z3py_bindings_build_dest}/${z3py_file}")
|
||||
endforeach()
|
||||
|
||||
# Generate z3core.py
|
||||
add_custom_command(OUTPUT "${z3py_bindings_build_dest}/z3core.py"
|
||||
add_custom_command(OUTPUT "${z3py_bindings_build_dest}/z3/z3core.py"
|
||||
COMMAND "${PYTHON_EXECUTABLE}"
|
||||
"${CMAKE_SOURCE_DIR}/scripts/update_api.py"
|
||||
${Z3_FULL_PATH_API_HEADER_FILES_TO_SCAN}
|
||||
|
@ -44,10 +47,10 @@ add_custom_command(OUTPUT "${z3py_bindings_build_dest}/z3core.py"
|
|||
COMMENT "Generating z3core.py"
|
||||
${ADD_CUSTOM_COMMAND_USES_TERMINAL_ARG}
|
||||
)
|
||||
list(APPEND build_z3_python_bindings_target_depends "${z3py_bindings_build_dest}/z3core.py")
|
||||
list(APPEND build_z3_python_bindings_target_depends "${z3py_bindings_build_dest}/z3/z3core.py")
|
||||
|
||||
# Generate z3consts.py
|
||||
add_custom_command(OUTPUT "${z3py_bindings_build_dest}/z3consts.py"
|
||||
add_custom_command(OUTPUT "${z3py_bindings_build_dest}/z3/z3consts.py"
|
||||
COMMAND "${PYTHON_EXECUTABLE}"
|
||||
"${CMAKE_SOURCE_DIR}/scripts/mk_consts_files.py"
|
||||
${Z3_FULL_PATH_API_HEADER_FILES_TO_SCAN}
|
||||
|
@ -60,13 +63,29 @@ add_custom_command(OUTPUT "${z3py_bindings_build_dest}/z3consts.py"
|
|||
COMMENT "Generating z3consts.py"
|
||||
${ADD_CUSTOM_COMMAND_USES_TERMINAL_ARG}
|
||||
)
|
||||
list(APPEND build_z3_python_bindings_target_depends "${z3py_bindings_build_dest}/z3consts.py")
|
||||
list(APPEND build_z3_python_bindings_target_depends "${z3py_bindings_build_dest}/z3/z3consts.py")
|
||||
|
||||
if (UNIX)
|
||||
set(LINK_COMMAND "create_symlink")
|
||||
else()
|
||||
set(LINK_COMMAND "copy")
|
||||
endif()
|
||||
|
||||
# Link libz3 into the python directory so bindings work out of the box
|
||||
add_custom_command(OUTPUT "${z3py_bindings_build_dest}/libz3${CMAKE_SHARED_MODULE_SUFFIX}"
|
||||
COMMAND "${CMAKE_COMMAND}" "-E" "${LINK_COMMAND}"
|
||||
"${CMAKE_BINARY_DIR}/libz3${CMAKE_SHARED_MODULE_SUFFIX}"
|
||||
"${z3py_bindings_build_dest}/libz3${CMAKE_SHARED_MODULE_SUFFIX}"
|
||||
DEPENDS libz3
|
||||
COMMENT "Linking libz3 into python directory"
|
||||
)
|
||||
|
||||
# Convenient top-level target
|
||||
add_custom_target(build_z3_python_bindings
|
||||
ALL
|
||||
DEPENDS
|
||||
${build_z3_python_bindings_target_depends}
|
||||
"${z3py_bindings_build_dest}/libz3${CMAKE_SHARED_MODULE_SUFFIX}"
|
||||
)
|
||||
|
||||
###############################################################################
|
||||
|
@ -117,7 +136,7 @@ if (INSTALL_PYTHON_BINDINGS)
|
|||
# Using DESTDIR still seems to work even if we use an absolute path
|
||||
message(STATUS "Python bindings will be installed to \"${CMAKE_INSTALL_PYTHON_PKG_DIR}\"")
|
||||
install(FILES ${build_z3_python_bindings_target_depends}
|
||||
DESTINATION "${CMAKE_INSTALL_PYTHON_PKG_DIR}"
|
||||
DESTINATION "${CMAKE_INSTALL_PYTHON_PKG_DIR}/z3"
|
||||
)
|
||||
else()
|
||||
message(STATUS "Not emitting rules to install Z3 python bindings")
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
z3_add_component(fpa
|
||||
SOURCES
|
||||
bv2fpa_converter.cpp
|
||||
fpa2bv_converter.cpp
|
||||
fpa2bv_rewriter.cpp
|
||||
COMPONENT_DEPENDENCIES
|
||||
ast
|
||||
simplifier
|
||||
model
|
||||
util
|
||||
PYG_FILES
|
||||
fpa2bv_rewriter_params.pyg
|
||||
|
|
|
@ -4,10 +4,12 @@ z3_add_component(rewriter
|
|||
array_rewriter.cpp
|
||||
ast_counter.cpp
|
||||
bool_rewriter.cpp
|
||||
bv_bounds.cpp
|
||||
bv_rewriter.cpp
|
||||
datatype_rewriter.cpp
|
||||
der.cpp
|
||||
dl_rewriter.cpp
|
||||
enum2bv_rewriter.cpp
|
||||
expr_replacer.cpp
|
||||
expr_safe_replace.cpp
|
||||
factor_rewriter.cpp
|
||||
|
@ -15,6 +17,7 @@ z3_add_component(rewriter
|
|||
label_rewriter.cpp
|
||||
mk_simplified_app.cpp
|
||||
pb_rewriter.cpp
|
||||
pb2bv_rewriter.cpp
|
||||
quant_hoist.cpp
|
||||
rewriter.cpp
|
||||
seq_rewriter.cpp
|
||||
|
|
|
@ -3,7 +3,6 @@ z3_add_component(polynomial
|
|||
algebraic_numbers.cpp
|
||||
polynomial_cache.cpp
|
||||
polynomial.cpp
|
||||
polynomial_factorization.cpp
|
||||
rpolynomial.cpp
|
||||
sexpr2upolynomial.cpp
|
||||
upolynomial.cpp
|
||||
|
|
|
@ -12,7 +12,6 @@ z3_add_component(rel
|
|||
dl_interval_relation.cpp
|
||||
dl_lazy_table.cpp
|
||||
dl_mk_explanations.cpp
|
||||
dl_mk_partial_equiv.cpp
|
||||
dl_mk_similarity_compressor.cpp
|
||||
dl_mk_simple_joins.cpp
|
||||
dl_product_relation.cpp
|
||||
|
|
|
@ -1,20 +1,15 @@
|
|||
z3_add_component(opt
|
||||
SOURCES
|
||||
bcd2.cpp
|
||||
fu_malik.cpp
|
||||
hitting_sets.cpp
|
||||
maxhs.cpp
|
||||
maxres.cpp
|
||||
maxsls.cpp
|
||||
maxsmt.cpp
|
||||
mss.cpp
|
||||
mus.cpp
|
||||
opt_cmds.cpp
|
||||
opt_context.cpp
|
||||
opt_pareto.cpp
|
||||
optsmt.cpp
|
||||
opt_solver.cpp
|
||||
pb_sls.cpp
|
||||
sortmax.cpp
|
||||
wmax.cpp
|
||||
COMPONENT_DEPENDENCIES
|
||||
sat_solver
|
||||
|
|
|
@ -2,7 +2,6 @@ z3_add_component(sat
|
|||
SOURCES
|
||||
dimacs.cpp
|
||||
sat_asymm_branch.cpp
|
||||
sat_bceq.cpp
|
||||
sat_clause.cpp
|
||||
sat_clause_set.cpp
|
||||
sat_clause_use_list.cpp
|
||||
|
@ -13,10 +12,10 @@ z3_add_component(sat
|
|||
sat_integrity_checker.cpp
|
||||
sat_model_converter.cpp
|
||||
sat_mus.cpp
|
||||
sat_par.cpp
|
||||
sat_probing.cpp
|
||||
sat_scc.cpp
|
||||
sat_simplifier.cpp
|
||||
sat_sls.cpp
|
||||
sat_solver.cpp
|
||||
sat_watched.cpp
|
||||
COMPONENT_DEPENDENCIES
|
||||
|
|
|
@ -18,6 +18,7 @@ z3_add_component(smt
|
|||
smt_checker.cpp
|
||||
smt_clause.cpp
|
||||
smt_conflict_resolution.cpp
|
||||
smt_consequences.cpp
|
||||
smt_context.cpp
|
||||
smt_context_inv.cpp
|
||||
smt_context_pp.cpp
|
||||
|
@ -42,6 +43,7 @@ z3_add_component(smt
|
|||
smt_statistics.cpp
|
||||
smt_theory.cpp
|
||||
smt_value_sort.cpp
|
||||
smt2_extra_cmds.cpp
|
||||
theory_arith.cpp
|
||||
theory_array_base.cpp
|
||||
theory_array.cpp
|
||||
|
|
|
@ -2,8 +2,11 @@ z3_add_component(solver
|
|||
SOURCES
|
||||
check_sat_result.cpp
|
||||
combined_solver.cpp
|
||||
mus.cpp
|
||||
smt_logics.cpp
|
||||
solver.cpp
|
||||
solver_na2as.cpp
|
||||
solver2tactic.cpp
|
||||
tactic2solver.cpp
|
||||
COMPONENT_DEPENDENCIES
|
||||
model
|
||||
|
|
|
@ -12,6 +12,7 @@ z3_add_component(tactic
|
|||
probe.cpp
|
||||
proof_converter.cpp
|
||||
replace_proof_converter.cpp
|
||||
sine_filter.cpp
|
||||
tactical.cpp
|
||||
tactic.cpp
|
||||
COMPONENT_DEPENDENCIES
|
||||
|
|
|
@ -5,8 +5,10 @@ z3_add_component(bv_tactics
|
|||
bv1_blaster_tactic.cpp
|
||||
bvarray2uf_rewriter.cpp
|
||||
bvarray2uf_tactic.cpp
|
||||
bv_bound_chk_tactic.cpp
|
||||
bv_bounds_tactic.cpp
|
||||
bv_size_reduction_tactic.cpp
|
||||
dt2bv_tactic.cpp
|
||||
elim_small_bv_tactic.cpp
|
||||
max_bv_sharing_tactic.cpp
|
||||
COMPONENT_DEPENDENCIES
|
||||
|
|
|
@ -3,6 +3,7 @@ z3_add_component(core_tactics
|
|||
blast_term_ite_tactic.cpp
|
||||
cofactor_elim_term_ite.cpp
|
||||
cofactor_term_ite_tactic.cpp
|
||||
collect_statistics_tactic.cpp
|
||||
ctx_simplify_tactic.cpp
|
||||
der_tactic.cpp
|
||||
distribute_forall_tactic.cpp
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
z3_add_component(portfolio
|
||||
SOURCES
|
||||
default_tactic.cpp
|
||||
enum2bv_solver.cpp
|
||||
pb2bv_solver.cpp
|
||||
bounded_int2bv_solver.cpp
|
||||
fd_solver.cpp
|
||||
smt_strategic_solver.cpp
|
||||
COMPONENT_DEPENDENCIES
|
||||
aig_tactic
|
||||
|
|
|
@ -42,6 +42,7 @@ add_executable(test-z3
|
|||
factor_rewriter.cpp
|
||||
fixed_bit_vector.cpp
|
||||
for_each_file.cpp
|
||||
get_consequences.cpp
|
||||
get_implied_equalities.cpp
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/gparams_register_modules.cpp"
|
||||
hashtable.cpp
|
||||
|
@ -77,10 +78,10 @@ add_executable(test-z3
|
|||
old_interval.cpp
|
||||
optional.cpp
|
||||
parray.cpp
|
||||
pb2bv.cpp
|
||||
pdr.cpp
|
||||
permutation.cpp
|
||||
polynomial.cpp
|
||||
polynomial_factorization.cpp
|
||||
polynorm.cpp
|
||||
prime_generator.cpp
|
||||
proof_checker.cpp
|
||||
|
|
|
@ -82,7 +82,7 @@ try:
|
|||
mk_dir('tmp')
|
||||
shutil.copyfile('website-adj.dox', 'tmp/website.dox')
|
||||
os.remove('website-adj.dox')
|
||||
shutil.copyfile('../src/api/python/z3.py', 'tmp/z3py.py')
|
||||
shutil.copyfile('../src/api/python/z3/z3.py', 'tmp/z3py.py')
|
||||
cleanup_API('../src/api/z3_api.h', 'tmp/z3_api.h')
|
||||
cleanup_API('../src/api/z3_ast_containers.h', 'tmp/z3_ast_containers.h')
|
||||
cleanup_API('../src/api/z3_algebraic.h', 'tmp/z3_algebraic.h')
|
||||
|
@ -119,7 +119,7 @@ try:
|
|||
print("Removed temporary file z3py.py")
|
||||
os.removedirs('tmp')
|
||||
print("Removed temporary directory tmp.")
|
||||
sys.path.append('../src/api/python')
|
||||
sys.path.append('../src/api/python/z3')
|
||||
pydoc.writedoc('z3')
|
||||
shutil.move('z3.html', 'api/html/z3.html')
|
||||
print("Generated Python documentation.")
|
||||
|
|
|
@ -23,7 +23,7 @@ void demorgan() {
|
|||
|
||||
expr x = c.bool_const("x");
|
||||
expr y = c.bool_const("y");
|
||||
expr conjecture = !(x && y) == (!x || !y);
|
||||
expr conjecture = (!(x && y)) == (!x || !y);
|
||||
|
||||
solver s(c);
|
||||
// adding the negation of the conjecture as a constraint.
|
||||
|
@ -1111,6 +1111,35 @@ void param_descrs_example() {
|
|||
}
|
||||
}
|
||||
|
||||
void consequence_example() {
|
||||
std::cout << "consequence example\n";
|
||||
context c;
|
||||
expr A = c.bool_const("a");
|
||||
expr B = c.bool_const("b");
|
||||
expr C = c.bool_const("c");
|
||||
solver s(c);
|
||||
s.add(implies(A, B));
|
||||
s.add(implies(B, C));
|
||||
expr_vector assumptions(c), vars(c), consequences(c);
|
||||
assumptions.push_back(!C);
|
||||
vars.push_back(A);
|
||||
vars.push_back(B);
|
||||
vars.push_back(C);
|
||||
std::cout << s.consequences(assumptions, vars, consequences) << "\n";
|
||||
std::cout << consequences << "\n";
|
||||
}
|
||||
|
||||
static void parse_example() {
|
||||
std::cout << "parse example\n";
|
||||
context c;
|
||||
sort_vector sorts(c);
|
||||
func_decl_vector decls(c);
|
||||
sort B = c.bool_sort();
|
||||
decls.push_back(c.function("a", 0, 0, B));
|
||||
expr a = c.parse_string("(assert a)", sorts, decls);
|
||||
std::cout << a << "\n";
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
try {
|
||||
|
@ -1154,6 +1183,8 @@ int main() {
|
|||
extract_example(); std::cout << "\n";
|
||||
param_descrs_example(); std::cout << "\n";
|
||||
sudoku_example(); std::cout << "\n";
|
||||
consequence_example(); std::cout << "\n";
|
||||
parse_example(); std::cout << "\n";
|
||||
std::cout << "done\n";
|
||||
}
|
||||
catch (exception & ex) {
|
||||
|
|
|
@ -818,6 +818,7 @@ namespace test_mapi
|
|||
BigIntCheck(ctx, ctx.MkReal("234234333/2"));
|
||||
|
||||
|
||||
#if !FRAMEWORK_LT_4
|
||||
string bn = "1234567890987654321";
|
||||
|
||||
if (ctx.MkInt(bn).BigInteger.ToString() != bn)
|
||||
|
@ -828,6 +829,7 @@ namespace test_mapi
|
|||
|
||||
if (ctx.MkBV(bn, 32).BigInteger.ToString() == bn)
|
||||
throw new TestFailedException();
|
||||
#endif
|
||||
|
||||
// Error handling test.
|
||||
try
|
||||
|
@ -1094,8 +1096,10 @@ namespace test_mapi
|
|||
|
||||
static void BigIntCheck(Context ctx, RatNum r)
|
||||
{
|
||||
#if !FRAMEWORK_LT_4
|
||||
Console.WriteLine("Num: " + r.BigIntNumerator);
|
||||
Console.WriteLine("Den: " + r.BigIntDenominator);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -2159,6 +2163,8 @@ namespace test_mapi
|
|||
Console.WriteLine(Microsoft.Z3.Version.Major.ToString());
|
||||
Console.Write("Z3 Full Version: ");
|
||||
Console.WriteLine(Microsoft.Z3.Version.ToString());
|
||||
Console.Write("Z3 Full Version String: ");
|
||||
Console.WriteLine(Microsoft.Z3.Version.FullVersion);
|
||||
|
||||
|
||||
SimpleExample();
|
||||
|
|
|
@ -188,7 +188,7 @@ class JavaExample
|
|||
/* do something with the context */
|
||||
|
||||
/* be kind to dispose manually and not wait for the GC. */
|
||||
ctx.dispose();
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2291,6 +2291,8 @@ class JavaExample
|
|||
System.out.println(Version.getMajor());
|
||||
System.out.print("Z3 Full Version: ");
|
||||
System.out.println(Version.getString());
|
||||
System.out.print("Z3 Full Version String: ");
|
||||
System.out.println(Version.getFullVersion());
|
||||
|
||||
p.simpleExample();
|
||||
|
||||
|
|
|
@ -323,6 +323,7 @@ let _ =
|
|||
else
|
||||
(
|
||||
Printf.printf "Running Z3 version %s\n" Version.to_string ;
|
||||
Printf.printf "Z3 full version string: %s\n" Version.full_version ;
|
||||
let cfg = [("model", "true"); ("proof", "false")] in
|
||||
let ctx = (mk_context cfg) in
|
||||
let is = (Symbol.mk_int ctx 42) in
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("SolverFoundation.Plugin.Z3")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("SolverFoundation.Plugin.Z3")]
|
||||
[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("ed1476c0-96de-4d2c-983d-3888b140c3ad")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -47,7 +47,7 @@ namespace Microsoft.SolverFoundation.Plugin.Z3
|
|||
private Dictionary<int, Expr> _variables = new Dictionary<int, Expr>();
|
||||
|
||||
/// <summary>A map from MSF variable ids to Z3 goal ids</summary>
|
||||
private Dictionary<IGoal, uint> _goals = new Dictionary<IGoal, uint>();
|
||||
private Dictionary<IGoal, Optimize.Handle> _goals = new Dictionary<IGoal, Optimize.Handle>();
|
||||
|
||||
internal Z3BaseSolver(IRowVariableModel model)
|
||||
{
|
||||
|
@ -64,7 +64,7 @@ namespace Microsoft.SolverFoundation.Plugin.Z3
|
|||
get { return _variables; }
|
||||
}
|
||||
|
||||
internal Dictionary<IGoal, uint> Goals
|
||||
internal Dictionary<IGoal, Optimize.Handle> Goals
|
||||
{
|
||||
get { return _goals; }
|
||||
}
|
||||
|
@ -332,7 +332,7 @@ namespace Microsoft.SolverFoundation.Plugin.Z3
|
|||
// Remember all objective values
|
||||
foreach (var pair in _goals)
|
||||
{
|
||||
var optimalValue = Utils.ToRational(_optSolver.GetUpper(pair.Value));
|
||||
var optimalValue = Utils.ToRational(pair.Value.Upper);
|
||||
_model.SetValue(pair.Key.Index, optimalValue);
|
||||
}
|
||||
model.Dispose();
|
||||
|
@ -356,7 +356,7 @@ namespace Microsoft.SolverFoundation.Plugin.Z3
|
|||
// Remember all objective values
|
||||
foreach (var pair in _goals)
|
||||
{
|
||||
var optimalValue = Utils.ToRational(_optSolver.GetUpper(pair.Value));
|
||||
var optimalValue = Utils.ToRational(pair.Value.Upper);
|
||||
_model.SetValue(pair.Key.Index, optimalValue);
|
||||
}
|
||||
subOptimalModel.Dispose();
|
||||
|
|
76
examples/python/all_interval_series.py
Normal file
76
examples/python/all_interval_series.py
Normal file
|
@ -0,0 +1,76 @@
|
|||
# Copyright Microsoft Research 2016
|
||||
# The following script finds sequences of length n-1 of
|
||||
# integers 0,..,n-1 such that the difference of the n-1
|
||||
# adjacent entries fall in the range 0,..,n-1
|
||||
# This is known as the "The All-Interval Series Problem"
|
||||
# See http://www.csplib.org/Problems/prob007/
|
||||
|
||||
from z3 import *
|
||||
import time
|
||||
|
||||
def diff_at_j_is_i(xs, j, i):
|
||||
assert(0 <= j and j + 1 < len(xs))
|
||||
assert(1 <= i and i < len(xs))
|
||||
return Or([ And(xs[j][k], xs[j+1][k-i]) for k in range(i,len(xs))] +
|
||||
[ And(xs[j][k], xs[j+1][k+i]) for k in range(0,len(xs)-i)])
|
||||
|
||||
|
||||
def ais(n):
|
||||
xij = [ [ Bool("x_%d_%d" % (i,j)) for j in range(n)] for i in range(n) ]
|
||||
s = SolverFor("QF_FD")
|
||||
# Optionally replace by (slower) default solver if using
|
||||
# more then just finite domains (Booleans, Bit-vectors, enumeration types
|
||||
# and bounded integers)
|
||||
# s = Solver()
|
||||
for i in range(n):
|
||||
s.add(AtMost(xij[i] + [1]))
|
||||
s.add(Or(xij[i]))
|
||||
for j in range(n):
|
||||
xi = [ xij[i][j] for i in range(n) ]
|
||||
s.add(AtMost(xi + [1]))
|
||||
s.add(Or(xi))
|
||||
dji = [ [ diff_at_j_is_i(xij, j, i + 1) for i in range(n-1)] for j in range(n-1) ]
|
||||
for j in range(n-1):
|
||||
s.add(AtMost(dji[j] + [1]))
|
||||
s.add(Or(dji[j]))
|
||||
for i in range(n-1):
|
||||
dj = [dji[j][i] for j in range(n-1)]
|
||||
s.add(AtMost(dj + [1]))
|
||||
s.add(Or(dj))
|
||||
return s, xij
|
||||
|
||||
def process_model(s, xij, n):
|
||||
# x_ij integer i is at position j
|
||||
# d_ij difference between integer at position j, j+1 is i
|
||||
# sum_j d_ij = 1 i = 1,...,n-1
|
||||
# sum_j x_ij = 1
|
||||
# sum_i x_ij = 1
|
||||
m = s.model()
|
||||
block = []
|
||||
values = []
|
||||
for i in range(n):
|
||||
k = -1
|
||||
for j in range(n):
|
||||
if is_true(m.eval(xij[i][j])):
|
||||
assert(k == -1)
|
||||
block += [xij[i][j]]
|
||||
k = j
|
||||
values += [k]
|
||||
print values
|
||||
sys.stdout.flush()
|
||||
return block
|
||||
|
||||
def all_models(n):
|
||||
count = 0
|
||||
s, xij = ais(n)
|
||||
start = time.clock()
|
||||
while sat == s.check():
|
||||
block = process_model(s, xij, n)
|
||||
s.add(Not(And(block)))
|
||||
count += 1
|
||||
print s.statistics()
|
||||
print time.clock() - start
|
||||
print count
|
||||
|
||||
set_option(verbose=1)
|
||||
all_models(12)
|
|
@ -1,4 +1,30 @@
|
|||
# Copyright (c) Microsoft Corporation 2015
|
||||
# Copyright (c) Microsoft Corporation 2015, 2016
|
||||
|
||||
# The Z3 Python API requires libz3.dll/.so/.dylib in the
|
||||
# PATH/LD_LIBRARY_PATH/DYLD_LIBRARY_PATH
|
||||
# environment variable and the PYTHON_PATH environment variable
|
||||
# needs to point to the `python' directory that contains `z3/z3.py'
|
||||
# (which is at bin/python in our binary releases).
|
||||
|
||||
# If you obtained example.py as part of our binary release zip files,
|
||||
# which you unzipped into a directory called `MYZ3', then follow these
|
||||
# instructions to run the example:
|
||||
|
||||
# Running this example on Windows:
|
||||
# set PATH=%PATH%;MYZ3\bin
|
||||
# set PYTHONPATH=MYZ3\bin\python
|
||||
# python example.py
|
||||
|
||||
# Running this example on Linux:
|
||||
# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:MYZ3/bin
|
||||
# export PYTHONPATH=MYZ3/bin/python
|
||||
# python example.py
|
||||
|
||||
# Running this example on OSX:
|
||||
# export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:MYZ3/bin
|
||||
# export PYTHONPATH=MYZ3/bin/python
|
||||
# python example.py
|
||||
|
||||
|
||||
from z3 import *
|
||||
|
||||
|
|
185
examples/python/mus/marco.py
Normal file
185
examples/python/mus/marco.py
Normal file
|
@ -0,0 +1,185 @@
|
|||
############################################
|
||||
# Copyright (c) 2016 Microsoft Corporation
|
||||
#
|
||||
# Basic core and correction set enumeration.
|
||||
#
|
||||
# Author: Nikolaj Bjorner (nbjorner)
|
||||
############################################
|
||||
|
||||
"""
|
||||
Enumeration of Minimal Unsatisfiable Cores and Maximal Satisfying Subsets
|
||||
This tutorial illustrates how to use Z3 for extracting all minimal unsatisfiable
|
||||
cores together with all maximal satisfying subsets.
|
||||
|
||||
Origin
|
||||
The algorithm that we describe next represents the essence of the core extraction
|
||||
procedure by Liffiton and Malik and independently by Previti and Marques-Silva:
|
||||
Enumerating Infeasibility: Finding Multiple MUSes Quickly
|
||||
Mark H. Liffiton and Ammar Malik
|
||||
in Proc. 10th International Conference on Integration of Artificial Intelligence (AI)
|
||||
and Operations Research (OR) techniques in Constraint Programming (CPAIOR-2013), 160-175, May 2013.
|
||||
|
||||
Partial MUS Enumeration
|
||||
Alessandro Previti, Joao Marques-Silva in Proc. AAAI-2013 July 2013
|
||||
|
||||
Z3py Features
|
||||
|
||||
This implementation contains no tuning. It was contributed by Mark Liffiton and it is
|
||||
a simplification of one of the versions available from his Marco Polo Web site.
|
||||
It illustrates the following features of Z3's Python-based API:
|
||||
1. Using assumptions to track unsatisfiable cores.
|
||||
2. Using multiple solvers and passing constraints between them.
|
||||
3. Calling the C-based API from Python. Not all API functions are supported over the
|
||||
Python wrappers. This example shows how to get a unique integer identifier of an AST,
|
||||
which can be used as a key in a hash-table.
|
||||
|
||||
Idea of the Algorithm
|
||||
The main idea of the algorithm is to maintain two logical contexts and exchange information
|
||||
between them:
|
||||
|
||||
1. The MapSolver is used to enumerate sets of clauses that are not already
|
||||
supersets of an existing unsatisfiable core and not already a subset of a maximal satisfying
|
||||
assignment. The MapSolver uses one unique atomic predicate per soft clause, so it enumerates
|
||||
sets of atomic predicates. For each minimal unsatisfiable core, say, represented by predicates
|
||||
p1, p2, p5, the MapSolver contains the clause !p1 | !p2 | !p5. For each maximal satisfiable
|
||||
subset, say, represented by predicats p2, p3, p5, the MapSolver contains a clause corresponding
|
||||
to the disjunction of all literals not in the maximal satisfiable subset, p1 | p4 | p6.
|
||||
2. The SubsetSolver contains a set of soft clauses (clauses with the unique indicator atom occurring negated).
|
||||
The MapSolver feeds it a set of clauses (the indicator atoms). Recall that these are not already a superset
|
||||
of an existing minimal unsatisfiable core, or a subset of a maximal satisfying assignment. If asserting
|
||||
these atoms makes the SubsetSolver context infeasible, then it finds a minimal unsatisfiable subset
|
||||
corresponding to these atoms. If asserting the atoms is consistent with the SubsetSolver, then it
|
||||
extends this set of atoms maximally to a satisfying set.
|
||||
"""
|
||||
|
||||
from z3 import *
|
||||
|
||||
def main():
|
||||
x, y = Reals('x y')
|
||||
constraints = [x > 2, x < 1, x < 0, Or(x + y > 0, y < 0), Or(y >= 0, x >= 0), Or(y < 0, x < 0), Or(y > 0, x < 0)]
|
||||
csolver = SubsetSolver(constraints)
|
||||
msolver = MapSolver(n=csolver.n)
|
||||
for orig, lits in enumerate_sets(csolver, msolver):
|
||||
output = "%s %s" % (orig, lits)
|
||||
print(output)
|
||||
|
||||
|
||||
def get_id(x):
|
||||
return Z3_get_ast_id(x.ctx.ref(),x.as_ast())
|
||||
|
||||
|
||||
class SubsetSolver:
|
||||
constraints = []
|
||||
n = 0
|
||||
s = Solver()
|
||||
varcache = {}
|
||||
idcache = {}
|
||||
|
||||
def __init__(self, constraints):
|
||||
self.constraints = constraints
|
||||
self.n = len(constraints)
|
||||
for i in range(self.n):
|
||||
self.s.add(Implies(self.c_var(i), constraints[i]))
|
||||
|
||||
def c_var(self, i):
|
||||
if i not in self.varcache:
|
||||
v = Bool(str(self.constraints[abs(i)]))
|
||||
self.idcache[get_id(v)] = abs(i)
|
||||
if i >= 0:
|
||||
self.varcache[i] = v
|
||||
else:
|
||||
self.varcache[i] = Not(v)
|
||||
return self.varcache[i]
|
||||
|
||||
def check_subset(self, seed):
|
||||
assumptions = self.to_c_lits(seed)
|
||||
return (self.s.check(assumptions) == sat)
|
||||
|
||||
def to_c_lits(self, seed):
|
||||
return [self.c_var(i) for i in seed]
|
||||
|
||||
def complement(self, aset):
|
||||
return set(range(self.n)).difference(aset)
|
||||
|
||||
def seed_from_core(self):
|
||||
core = self.s.unsat_core()
|
||||
return [self.idcache[get_id(x)] for x in core]
|
||||
|
||||
def shrink(self, seed):
|
||||
current = set(seed)
|
||||
for i in seed:
|
||||
if i not in current:
|
||||
continue
|
||||
current.remove(i)
|
||||
if not self.check_subset(current):
|
||||
current = set(self.seed_from_core())
|
||||
else:
|
||||
current.add(i)
|
||||
return current
|
||||
|
||||
def grow(self, seed):
|
||||
current = seed
|
||||
for i in self.complement(current):
|
||||
current.append(i)
|
||||
if not self.check_subset(current):
|
||||
current.pop()
|
||||
return current
|
||||
|
||||
|
||||
|
||||
class MapSolver:
|
||||
def __init__(self, n):
|
||||
"""Initialization.
|
||||
Args:
|
||||
n: The number of constraints to map.
|
||||
"""
|
||||
self.solver = Solver()
|
||||
self.n = n
|
||||
self.all_n = set(range(n)) # used in complement fairly frequently
|
||||
|
||||
def next_seed(self):
|
||||
"""Get the seed from the current model, if there is one.
|
||||
Returns:
|
||||
A seed as an array of 0-based constraint indexes.
|
||||
"""
|
||||
if self.solver.check() == unsat:
|
||||
return None
|
||||
seed = self.all_n.copy() # default to all True for "high bias"
|
||||
model = self.solver.model()
|
||||
for x in model:
|
||||
if is_false(model[x]):
|
||||
seed.remove(int(x.name()))
|
||||
return list(seed)
|
||||
|
||||
def complement(self, aset):
|
||||
"""Return the complement of a given set w.r.t. the set of mapped constraints."""
|
||||
return self.all_n.difference(aset)
|
||||
|
||||
def block_down(self, frompoint):
|
||||
"""Block down from a given set."""
|
||||
comp = self.complement(frompoint)
|
||||
self.solver.add( Or( [Bool(str(i)) for i in comp] ) )
|
||||
|
||||
def block_up(self, frompoint):
|
||||
"""Block up from a given set."""
|
||||
self.solver.add( Or( [Not(Bool(str(i))) for i in frompoint] ) )
|
||||
|
||||
|
||||
|
||||
def enumerate_sets(csolver, map):
|
||||
"""Basic MUS/MCS enumeration, as a simple example."""
|
||||
while True:
|
||||
seed = map.next_seed()
|
||||
if seed is None:
|
||||
return
|
||||
if csolver.check_subset(seed):
|
||||
MSS = csolver.grow(seed)
|
||||
yield ("MSS", csolver.to_c_lits(MSS))
|
||||
map.block_down(MSS)
|
||||
else:
|
||||
MUS = csolver.shrink(seed)
|
||||
yield ("MUS", csolver.to_c_lits(MUS))
|
||||
map.block_up(MUS)
|
||||
|
||||
main()
|
||||
|
168
examples/python/mus/mss.py
Normal file
168
examples/python/mus/mss.py
Normal file
|
@ -0,0 +1,168 @@
|
|||
############################################
|
||||
# Copyright (c) 2016 Microsoft Corporation
|
||||
#
|
||||
# MSS enumeration based on maximal resolution.
|
||||
#
|
||||
# Author: Nikolaj Bjorner (nbjorner)
|
||||
############################################
|
||||
|
||||
"""
|
||||
|
||||
The following is a procedure for enumerating maximal satisfying subsets.
|
||||
It uses maximal resolution to eliminate cores from the state space.
|
||||
Whenever the hard constraints are satisfiable, it finds a model that
|
||||
satisfies the maximal number of soft constraints.
|
||||
During this process it collects the set of cores that are encountered.
|
||||
It then reduces the set of soft constraints using max-resolution in
|
||||
the style of [Narodytska & Bacchus, AAAI'14]. In other words,
|
||||
let F1, ..., F_k be a core among the soft constraints F1,...,F_n
|
||||
Replace F1,.., F_k by
|
||||
F1 or F2, F3 or (F2 & F1), F4 or (F3 & (F2 & F1)), ...,
|
||||
F_k or (F_{k-1} & (...))
|
||||
Optionally, add the core ~F1 or ... or ~F_k to F
|
||||
The current model M satisfies the new set F, F1,...,F_{n-1} if the core is minimal.
|
||||
Whenever we modify the soft constraints by the core reduction any assignment
|
||||
to the reduced set satisfies a k-1 of the original soft constraints.
|
||||
|
||||
"""
|
||||
|
||||
from z3 import *
|
||||
|
||||
def main():
|
||||
x, y = Reals('x y')
|
||||
soft_constraints = [x > 2, x < 1, x < 0, Or(x + y > 0, y < 0), Or(y >= 0, x >= 0), Or(y < 0, x < 0), Or(y > 0, x < 0)]
|
||||
hard_constraints = BoolVal(True)
|
||||
solver = MSSSolver(hard_constraints, soft_constraints)
|
||||
for lits in enumerate_sets(solver):
|
||||
print("%s" % lits)
|
||||
|
||||
|
||||
def enumerate_sets(solver):
|
||||
while True:
|
||||
if sat == solver.s.check():
|
||||
MSS = solver.grow()
|
||||
yield MSS
|
||||
else:
|
||||
break
|
||||
|
||||
class CompareSetSize():
|
||||
def __call__(self, s1, s2):
|
||||
return len(s1) < len(s2)
|
||||
|
||||
|
||||
class MSSSolver:
|
||||
s = Solver()
|
||||
varcache = {}
|
||||
idcache = {}
|
||||
|
||||
def __init__(self, hard, soft):
|
||||
self.n = len(soft)
|
||||
self.soft = soft
|
||||
self.s.add(hard)
|
||||
self.soft_vars = set([self.c_var(i) for i in range(self.n)])
|
||||
self.orig_soft_vars = set([self.c_var(i) for i in range(self.n)])
|
||||
self.s.add([(self.c_var(i) == soft[i]) for i in range(self.n)])
|
||||
|
||||
def c_var(self, i):
|
||||
if i not in self.varcache:
|
||||
v = Bool(str(self.soft[abs(i)]))
|
||||
self.idcache[v] = abs(i)
|
||||
if i >= 0:
|
||||
self.varcache[i] = v
|
||||
else:
|
||||
self.varcache[i] = Not(v)
|
||||
return self.varcache[i]
|
||||
|
||||
# Retrieve the latest model
|
||||
# Add formulas that are true in the model to
|
||||
# the current mss
|
||||
|
||||
def update_unknown(self):
|
||||
self.model = self.s.model()
|
||||
new_unknown = set([])
|
||||
for x in self.unknown:
|
||||
if is_true(self.model[x]):
|
||||
self.mss.append(x)
|
||||
else:
|
||||
new_unknown.add(x)
|
||||
self.unknown = new_unknown
|
||||
|
||||
# Create a name, propositional atom,
|
||||
# for formula 'fml' and return the name.
|
||||
|
||||
def add_def(self, fml):
|
||||
name = Bool("%s" % fml)
|
||||
self.s.add(name == fml)
|
||||
return name
|
||||
|
||||
# replace Fs := f0, f1, f2, .. by
|
||||
# Or(f1, f0), Or(f2, And(f1, f0)), Or(f3, And(f2, And(f1, f0))), ...
|
||||
|
||||
def relax_core(self, Fs):
|
||||
assert(Fs <= self.soft_vars)
|
||||
prefix = BoolVal(True)
|
||||
self.soft_vars -= Fs
|
||||
Fs = [ f for f in Fs ]
|
||||
for i in range(len(Fs)-1):
|
||||
prefix = self.add_def(And(Fs[i], prefix))
|
||||
self.soft_vars.add(self.add_def(Or(prefix, Fs[i+1])))
|
||||
|
||||
# Resolve literals from the core that
|
||||
# are 'explained', e.g., implied by
|
||||
# other literals.
|
||||
|
||||
def resolve_core(self, core):
|
||||
new_core = set([])
|
||||
for x in core:
|
||||
if x in self.mcs_explain:
|
||||
new_core |= self.mcs_explain[x]
|
||||
else:
|
||||
new_core.add(x)
|
||||
return new_core
|
||||
|
||||
|
||||
# Given a current satisfiable state
|
||||
# Extract an MSS, and ensure that currently
|
||||
# encoutered cores are avoided in next iterations
|
||||
# by weakening the set of literals that are
|
||||
# examined in next iterations.
|
||||
# Strengthen the solver state by enforcing that
|
||||
# an element from the MCS is encoutered.
|
||||
|
||||
def grow(self):
|
||||
self.mss = []
|
||||
self.mcs = []
|
||||
self.nmcs = []
|
||||
self.mcs_explain = {}
|
||||
self.unknown = self.soft_vars
|
||||
self.update_unknown()
|
||||
cores = []
|
||||
while len(self.unknown) > 0:
|
||||
x = self.unknown.pop()
|
||||
is_sat = self.s.check(self.mss + [x] + self.nmcs)
|
||||
if is_sat == sat:
|
||||
self.mss.append(x)
|
||||
self.update_unknown()
|
||||
elif is_sat == unsat:
|
||||
core = self.s.unsat_core()
|
||||
core = self.resolve_core(core)
|
||||
self.mcs_explain[Not(x)] = {y for y in core if not eq(x,y)}
|
||||
self.mcs.append(x)
|
||||
self.nmcs.append(Not(x))
|
||||
cores += [core]
|
||||
else:
|
||||
print("solver returned %s" % is_sat)
|
||||
exit()
|
||||
mss = [x for x in self.orig_soft_vars if is_true(self.model[x])]
|
||||
mcs = [x for x in self.orig_soft_vars if not is_true(self.model[x])]
|
||||
self.s.add(Or(mcs))
|
||||
core_literals = set([])
|
||||
cores.sort(CompareSetSize())
|
||||
for core in cores:
|
||||
if len(core & core_literals) == 0:
|
||||
self.relax_core(core)
|
||||
core_literals |= core
|
||||
return mss
|
||||
|
||||
|
||||
main()
|
34
examples/python/socrates.py
Normal file
34
examples/python/socrates.py
Normal file
|
@ -0,0 +1,34 @@
|
|||
############################################
|
||||
# Copyright (c) Microsoft Corporation. All Rights Reserved.
|
||||
#
|
||||
# all humans are mortal
|
||||
# Socrates is a human
|
||||
# so Socrates mortal
|
||||
############################################
|
||||
|
||||
from z3 import *
|
||||
|
||||
Object = DeclareSort('Object')
|
||||
|
||||
Human = Function('Human', Object, BoolSort())
|
||||
Mortal = Function('Mortal', Object, BoolSort())
|
||||
|
||||
# a well known philosopher
|
||||
socrates = Const('socrates', Object)
|
||||
|
||||
# free variables used in forall must be declared Const in python
|
||||
x = Const('x', Object)
|
||||
|
||||
axioms = [ForAll([x], Implies(Human(x), Mortal(x))),
|
||||
Human(socrates)]
|
||||
|
||||
|
||||
s = Solver()
|
||||
s.add(axioms)
|
||||
|
||||
print(s.check()) # prints sat so axioms are coherents
|
||||
|
||||
# classical refutation
|
||||
s.add(Not(Mortal(socrates)))
|
||||
|
||||
print(s.check()) # prints unsat so socrates is Mortal
|
|
@ -828,7 +828,10 @@ class env {
|
|||
}
|
||||
else if (!strcmp(ch,"$to_real")) {
|
||||
check_arity(terms.size(), 1);
|
||||
r = to_real(terms[0]);
|
||||
r = terms[0];
|
||||
if (r.get_sort().is_int()) {
|
||||
r = to_real(terms[0]);
|
||||
}
|
||||
}
|
||||
else if (!strcmp(ch,"$is_int")) {
|
||||
check_arity(terms.size(), 1);
|
||||
|
@ -1224,21 +1227,14 @@ public:
|
|||
|
||||
void display_axiom(std::ostream& out, z3::expr e) {
|
||||
out << "tff(formula" << (++m_formula_id) << ", axiom,\n ";
|
||||
display(out, e);
|
||||
display(out, e, true);
|
||||
out << ").\n";
|
||||
}
|
||||
|
||||
void display(std::ostream& out, z3::expr e) {
|
||||
if (e.is_numeral()) {
|
||||
__int64 num, den;
|
||||
if (Z3_get_numeral_small(ctx, e, &num, &den)) {
|
||||
if (num < 0 && den == 1 && num != std::numeric_limits<__int64>::min()) {
|
||||
out << "-" << (-num);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// potential incompatibility: prints negative numbers with a space.
|
||||
out << e;
|
||||
void display(std::ostream& out, z3::expr e, bool in_paren) {
|
||||
std::string s;
|
||||
if (e.is_numeral(s)) {
|
||||
out << s;
|
||||
}
|
||||
else if (e.is_var()) {
|
||||
unsigned idx = Z3_get_index_value(ctx, e);
|
||||
|
@ -1253,32 +1249,33 @@ public:
|
|||
out << "$false";
|
||||
break;
|
||||
case Z3_OP_AND:
|
||||
display_infix(out, "&", e);
|
||||
display_infix(out, "&", e, in_paren);
|
||||
break;
|
||||
case Z3_OP_OR:
|
||||
display_infix(out, "|", e);
|
||||
display_infix(out, "|", e, in_paren);
|
||||
break;
|
||||
case Z3_OP_IMPLIES:
|
||||
display_infix(out, "=>", e);
|
||||
display_infix(out, "=>", e, in_paren);
|
||||
break;
|
||||
case Z3_OP_NOT:
|
||||
out << "(~";
|
||||
display(out, e.arg(0));
|
||||
out << ")";
|
||||
if (!in_paren) out << "(";
|
||||
out << "~";
|
||||
display(out, e.arg(0), false);
|
||||
if (!in_paren) out << ")";
|
||||
break;
|
||||
case Z3_OP_EQ:
|
||||
if (e.arg(0).is_bool()) {
|
||||
display_infix(out, "<=>", e);
|
||||
display_infix(out, "<=>", e, in_paren);
|
||||
}
|
||||
else {
|
||||
display_infix(out, "=", e);
|
||||
display_infix(out, "=", e, in_paren);
|
||||
}
|
||||
break;
|
||||
case Z3_OP_IFF:
|
||||
display_infix(out, "<=>", e);
|
||||
display_infix(out, "<=>", e, in_paren);
|
||||
break;
|
||||
case Z3_OP_XOR:
|
||||
display_infix(out, "<~>", e);
|
||||
display_infix(out, "<~>", e, in_paren);
|
||||
break;
|
||||
case Z3_OP_MUL:
|
||||
display_binary(out, "$product", e);
|
||||
|
@ -1355,7 +1352,7 @@ public:
|
|||
}
|
||||
}
|
||||
out << "] : ";
|
||||
display(out, e.body());
|
||||
display(out, e.body(), false);
|
||||
for (unsigned i = 0; i < nb; ++i) {
|
||||
names.pop_back();
|
||||
}
|
||||
|
@ -1370,7 +1367,7 @@ public:
|
|||
out << lower_case_fun(e.decl().name()) << "(";
|
||||
unsigned n = e.num_args();
|
||||
for(unsigned i = 0; i < n; ++i) {
|
||||
display(out, e.arg(i));
|
||||
display(out, e.arg(i), n == 1);
|
||||
if (i + 1 < n) {
|
||||
out << ", ";
|
||||
}
|
||||
|
@ -1393,23 +1390,23 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void display_infix(std::ostream& out, char const* conn, z3::expr& e) {
|
||||
out << "(";
|
||||
void display_infix(std::ostream& out, char const* conn, z3::expr& e, bool in_paren) {
|
||||
if (!in_paren) out << "(";
|
||||
unsigned sz = e.num_args();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
display(out, e.arg(i));
|
||||
display(out, e.arg(i), false);
|
||||
if (i + 1 < sz) {
|
||||
out << " " << conn << " ";
|
||||
}
|
||||
}
|
||||
out << ")";
|
||||
if (!in_paren) out << ")";
|
||||
}
|
||||
|
||||
void display_prefix(std::ostream& out, char const* conn, z3::expr& e) {
|
||||
out << conn << "(";
|
||||
unsigned sz = e.num_args();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
display(out, e.arg(i));
|
||||
display(out, e.arg(i), sz == 1);
|
||||
if (i + 1 < sz) {
|
||||
out << ", ";
|
||||
}
|
||||
|
@ -1422,7 +1419,7 @@ public:
|
|||
unsigned sz = e.num_args();
|
||||
unsigned np = 1;
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
display(out, e.arg(i));
|
||||
display(out, e.arg(i), false);
|
||||
if (i + 1 < sz) {
|
||||
out << ", ";
|
||||
}
|
||||
|
@ -1566,7 +1563,7 @@ public:
|
|||
formula_file = "unknown";
|
||||
}
|
||||
out << "tff(" << m_node_number << ",axiom,(";
|
||||
display(out, get_proof_formula(p));
|
||||
display(out, get_proof_formula(p), true);
|
||||
out << "), file('" << formula_file << "','";
|
||||
out << formula_name << "')).\n";
|
||||
break;
|
||||
|
@ -1629,12 +1626,12 @@ public:
|
|||
break;
|
||||
case Z3_OP_PR_HYPOTHESIS:
|
||||
out << "tff(" << m_node_number << ",assumption,(";
|
||||
display(out, get_proof_formula(p));
|
||||
display(out, get_proof_formula(p), true);
|
||||
out << "), introduced(assumption)).\n";
|
||||
break;
|
||||
case Z3_OP_PR_LEMMA: {
|
||||
out << "tff(" << m_node_number << ",plain,(";
|
||||
display(out, get_proof_formula(p));
|
||||
display(out, get_proof_formula(p), true);
|
||||
out << "), inference(lemma,lemma(discharge,";
|
||||
unsigned parent_id = Z3_get_ast_id(ctx, p.arg(0));
|
||||
std::set<unsigned> const& hyps = m_proof_hypotheses.find(parent_id)->second;
|
||||
|
@ -1751,7 +1748,7 @@ public:
|
|||
unsigned id = Z3_get_ast_id(ctx, p);
|
||||
std::set<unsigned> const& hyps = m_proof_hypotheses.find(id)->second;
|
||||
out << "tff(" << m_node_number << ",plain,\n (";
|
||||
display(out, get_proof_formula(p));
|
||||
display(out, get_proof_formula(p), true);
|
||||
out << "),\n inference(" << name << ",[status(" << status << ")";
|
||||
if (!hyps.empty()) {
|
||||
out << ", assumptions(";
|
||||
|
@ -1780,7 +1777,7 @@ public:
|
|||
unsigned display_hyp_inference(std::ostream& out, char const* name, char const* status, z3::expr conclusion, unsigned hyp1, unsigned hyp2 = 0) {
|
||||
++m_node_number;
|
||||
out << "tff(" << m_node_number << ",plain,(\n ";
|
||||
display(out, conclusion);
|
||||
display(out, conclusion, true);
|
||||
out << "),\n inference(" << name << ",[status(" << status << ")],";
|
||||
out << "[" << hyp1;
|
||||
if (hyp2) {
|
||||
|
@ -2369,7 +2366,7 @@ static void prove_tptp() {
|
|||
}
|
||||
catch (failure_ex& ex) {
|
||||
std::cerr << ex.msg << "\n";
|
||||
std::cout << "SZS status GaveUp\n";
|
||||
std::cout << "% SZS status GaveUp\n";
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2401,14 +2398,16 @@ static void prove_tptp() {
|
|||
std::cout << result << "\n";
|
||||
}
|
||||
else if (fmls.has_conjecture()) {
|
||||
std::cout << "SZS status Theorem\n";
|
||||
std::cout << "% SZS status Theorem\n";
|
||||
}
|
||||
else {
|
||||
std::cout << "SZS status Unsatisfiable\n";
|
||||
std::cout << "% SZS status Unsatisfiable\n";
|
||||
}
|
||||
if (g_generate_proof) {
|
||||
try {
|
||||
std::cout << "% SZS output start Proof\n";
|
||||
display_proof(ctx, fmls, solver);
|
||||
std::cout << "% SZS output end Proof\n";
|
||||
}
|
||||
catch (failure_ex& ex) {
|
||||
std::cerr << "Proof display could not be completed: " << ex.msg << "\n";
|
||||
|
@ -2416,7 +2415,7 @@ static void prove_tptp() {
|
|||
}
|
||||
if (g_generate_core) {
|
||||
z3::expr_vector core = solver.unsat_core();
|
||||
std::cout << "SZS core ";
|
||||
std::cout << "% SZS core ";
|
||||
for (unsigned i = 0; i < core.size(); ++i) {
|
||||
std::cout << core[i] << " ";
|
||||
}
|
||||
|
@ -2428,13 +2427,15 @@ static void prove_tptp() {
|
|||
std::cout << result << "\n";
|
||||
}
|
||||
else if (fmls.has_conjecture()) {
|
||||
std::cout << "SZS status CounterSatisfiable\n";
|
||||
std::cout << "% SZS status CounterSatisfiable\n";
|
||||
}
|
||||
else {
|
||||
std::cout << "SZS status Satisfiable\n";
|
||||
std::cout << "% SZS status Satisfiable\n";
|
||||
}
|
||||
if (g_generate_model) {
|
||||
std::cout << "% SZS output start Model\n";
|
||||
display_model(ctx, solver.get_model());
|
||||
std::cout << "% SZS output end Model\n";
|
||||
}
|
||||
break;
|
||||
case z3::unknown:
|
||||
|
@ -2442,12 +2443,12 @@ static void prove_tptp() {
|
|||
std::cout << result << "\n";
|
||||
}
|
||||
else if (!g_first_interrupt) {
|
||||
std::cout << "SZS status Interrupted\n";
|
||||
std::cout << "% SZS status Interrupted\n";
|
||||
}
|
||||
else {
|
||||
std::cout << "SZS status GaveUp\n";
|
||||
std::cout << "% SZS status GaveUp\n";
|
||||
std::string reason = solver.reason_unknown();
|
||||
std::cout << "SZS reason " << reason << "\n";
|
||||
std::cout << "% SZS reason " << reason << "\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -2467,7 +2468,6 @@ static void prove_tptp() {
|
|||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
//std::ostream* out = &std::cout;
|
||||
g_start_time = static_cast<double>(clock());
|
||||
signal(SIGINT, on_ctrl_c);
|
||||
|
||||
|
@ -2480,7 +2480,12 @@ int main(int argc, char** argv) {
|
|||
display_smt2(*g_out);
|
||||
}
|
||||
else {
|
||||
prove_tptp();
|
||||
try {
|
||||
prove_tptp();
|
||||
}
|
||||
catch (z3::exception& ex) {
|
||||
std::cerr << "Exception during proof: " << ex.msg() << "\n";
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ def main(args):
|
|||
dest="java_package_name",
|
||||
default=None,
|
||||
help="Name to give the Java package (e.g. ``com.microsoft.z3``).")
|
||||
parser.add_argument("--ml-output-dir", dest="ml_output_dir", default=None)
|
||||
pargs = parser.parse_args(args)
|
||||
|
||||
if not mk_genfile_common.check_files_exist(pargs.api_files):
|
||||
|
@ -60,6 +61,15 @@ def main(args):
|
|||
logging.info('Generated "{}"'.format(generated_file))
|
||||
count += 1
|
||||
|
||||
if pargs.ml_output_dir:
|
||||
if not mk_genfile_common.check_dir_exists(pargs.ml_output_dir):
|
||||
return 1
|
||||
output = mk_genfile_common.mk_z3consts_ml_internal(
|
||||
pargs.api_files,
|
||||
pargs.ml_output_dir)
|
||||
logging.info('Generated "{}"'.format(output))
|
||||
count += 1
|
||||
|
||||
if count == 0:
|
||||
logging.info('No files generated. You need to specific an output directory'
|
||||
' for the relevant langauge bindings')
|
||||
|
|
|
@ -98,7 +98,7 @@ def mk_z3consts_py_internal(api_files, output_dir):
|
|||
openbrace_pat = re.compile("{ *")
|
||||
closebrace_pat = re.compile("}.*;")
|
||||
|
||||
z3consts = open(os.path.join(output_dir, 'z3consts.py'), 'w')
|
||||
z3consts = open(os.path.join(output_dir, 'z3', 'z3consts.py'), 'w')
|
||||
z3consts_output_path = z3consts.name
|
||||
z3consts.write('# Automatically generated file\n\n')
|
||||
for api_file in api_files:
|
||||
|
@ -323,6 +323,9 @@ def mk_z3consts_java_internal(api_files, package_name, output_dir):
|
|||
generated_enumeration_files.append(efile.name)
|
||||
efile.write('/**\n * Automatically generated file\n **/\n\n')
|
||||
efile.write('package %s.enumerations;\n\n' % package_name)
|
||||
efile.write('import java.util.HashMap;\n')
|
||||
efile.write('import java.util.Map;\n')
|
||||
efile.write('\n')
|
||||
|
||||
efile.write('/**\n')
|
||||
efile.write(' * %s\n' % name)
|
||||
|
@ -342,10 +345,19 @@ def mk_z3consts_java_internal(api_files, package_name, output_dir):
|
|||
efile.write(' %s(int v) {\n' % name)
|
||||
efile.write(' this.intValue = v;\n')
|
||||
efile.write(' }\n\n')
|
||||
efile.write(' // Cannot initialize map in constructor, so need to do it lazily.\n')
|
||||
efile.write(' // Easiest thread-safe way is the initialization-on-demand holder pattern.\n')
|
||||
efile.write(' private static class %s_MappingHolder {\n' % name)
|
||||
efile.write(' private static final Map<Integer, %s> intMapping = new HashMap<>();\n' % name)
|
||||
efile.write(' static {\n')
|
||||
efile.write(' for (%s k : %s.values())\n' % (name, name))
|
||||
efile.write(' intMapping.put(k.toInt(), k);\n')
|
||||
efile.write(' }\n')
|
||||
efile.write(' }\n\n')
|
||||
efile.write(' public static final %s fromInt(int v) {\n' % name)
|
||||
efile.write(' for (%s k: values()) \n' % name)
|
||||
efile.write(' if (k.intValue == v) return k;\n')
|
||||
efile.write(' return values()[0];\n')
|
||||
efile.write(' %s k = %s_MappingHolder.intMapping.get(v);\n' % (name, name))
|
||||
efile.write(' if (k != null) return k;\n')
|
||||
efile.write(' throw new IllegalArgumentException("Illegal value " + v + " for %s");\n' % name)
|
||||
efile.write(' }\n\n')
|
||||
efile.write(' public final int toInt() { return this.intValue; }\n')
|
||||
# efile.write(';\n %s(int v) {}\n' % name)
|
||||
|
@ -364,6 +376,180 @@ def mk_z3consts_java_internal(api_files, package_name, output_dir):
|
|||
api.close()
|
||||
return generated_enumeration_files
|
||||
|
||||
# Extract enumeration types from z3_api.h, and add ML definitions
|
||||
def mk_z3consts_ml_internal(api_files, output_dir):
|
||||
"""
|
||||
Generate ``z3enums.ml`` from the list of API header files
|
||||
in ``api_files`` and write the output file into
|
||||
the ``output_dir`` directory
|
||||
|
||||
Returns the path to the generated file.
|
||||
"""
|
||||
assert os.path.isdir(output_dir)
|
||||
assert isinstance(api_files, list)
|
||||
blank_pat = re.compile("^ *$")
|
||||
comment_pat = re.compile("^ *//.*$")
|
||||
typedef_pat = re.compile("typedef enum *")
|
||||
typedef2_pat = re.compile("typedef enum { *")
|
||||
openbrace_pat = re.compile("{ *")
|
||||
closebrace_pat = re.compile("}.*;")
|
||||
|
||||
|
||||
DeprecatedEnums = [ 'Z3_search_failure' ]
|
||||
if not os.path.exists(output_dir):
|
||||
os.mkdir(output_dir)
|
||||
|
||||
efile = open('%s.ml' % os.path.join(output_dir, "z3enums"), 'w')
|
||||
z3consts_output_path = efile.name
|
||||
efile.write('(* Automatically generated file *)\n\n')
|
||||
efile.write('(** The enumeration types of Z3. *)\n\n')
|
||||
for api_file in api_files:
|
||||
api = open(api_file, 'r')
|
||||
|
||||
SEARCHING = 0
|
||||
FOUND_ENUM = 1
|
||||
IN_ENUM = 2
|
||||
|
||||
mode = SEARCHING
|
||||
decls = {}
|
||||
idx = 0
|
||||
|
||||
linenum = 1
|
||||
for line in api:
|
||||
m1 = blank_pat.match(line)
|
||||
m2 = comment_pat.match(line)
|
||||
if m1 or m2:
|
||||
# skip blank lines and comments
|
||||
linenum = linenum + 1
|
||||
elif mode == SEARCHING:
|
||||
m = typedef_pat.match(line)
|
||||
if m:
|
||||
mode = FOUND_ENUM
|
||||
m = typedef2_pat.match(line)
|
||||
if m:
|
||||
mode = IN_ENUM
|
||||
decls = {}
|
||||
idx = 0
|
||||
elif mode == FOUND_ENUM:
|
||||
m = openbrace_pat.match(line)
|
||||
if m:
|
||||
mode = IN_ENUM
|
||||
decls = {}
|
||||
idx = 0
|
||||
else:
|
||||
assert False, "Invalid %s, line: %s" % (api_file, linenum)
|
||||
else:
|
||||
assert mode == IN_ENUM
|
||||
words = re.split('[^\-a-zA-Z0-9_]+', line)
|
||||
m = closebrace_pat.match(line)
|
||||
if m:
|
||||
name = words[1]
|
||||
if name not in DeprecatedEnums:
|
||||
sorted_decls = sorted(decls.items(), key=lambda pair: pair[1])
|
||||
efile.write('(** %s *)\n' % name[3:])
|
||||
efile.write('type %s =\n' % name[3:]) # strip Z3_
|
||||
for k, i in sorted_decls:
|
||||
efile.write(' | %s \n' % k[3:]) # strip Z3_
|
||||
efile.write('\n')
|
||||
efile.write('(** Convert %s to int*)\n' % name[3:])
|
||||
efile.write('let int_of_%s x : int =\n' % (name[3:])) # strip Z3_
|
||||
efile.write(' match x with\n')
|
||||
for k, i in sorted_decls:
|
||||
efile.write(' | %s -> %d\n' % (k[3:], i))
|
||||
efile.write('\n')
|
||||
efile.write('(** Convert int to %s*)\n' % name[3:])
|
||||
efile.write('let %s_of_int x : %s =\n' % (name[3:],name[3:])) # strip Z3_
|
||||
efile.write(' match x with\n')
|
||||
for k, i in sorted_decls:
|
||||
efile.write(' | %d -> %s\n' % (i, k[3:]))
|
||||
# use Z3.Exception?
|
||||
efile.write(' | _ -> raise (Failure "undefined enum value")\n\n')
|
||||
mode = SEARCHING
|
||||
else:
|
||||
if words[2] != '':
|
||||
if len(words[2]) > 1 and words[2][1] == 'x':
|
||||
idx = int(words[2], 16)
|
||||
else:
|
||||
idx = int(words[2])
|
||||
decls[words[1]] = idx
|
||||
idx = idx + 1
|
||||
linenum = linenum + 1
|
||||
api.close()
|
||||
efile.close()
|
||||
return z3consts_output_path
|
||||
# efile = open('%s.mli' % os.path.join(gendir, "z3enums"), 'w')
|
||||
# efile.write('(* Automatically generated file *)\n\n')
|
||||
# efile.write('(** The enumeration types of Z3. *)\n\n')
|
||||
# for api_file in api_files:
|
||||
# api_file_c = ml.find_file(api_file, ml.name)
|
||||
# api_file = os.path.join(api_file_c.src_dir, api_file)
|
||||
|
||||
# api = open(api_file, 'r')
|
||||
|
||||
# SEARCHING = 0
|
||||
# FOUND_ENUM = 1
|
||||
# IN_ENUM = 2
|
||||
|
||||
# mode = SEARCHING
|
||||
# decls = {}
|
||||
# idx = 0
|
||||
|
||||
# linenum = 1
|
||||
# for line in api:
|
||||
# m1 = blank_pat.match(line)
|
||||
# m2 = comment_pat.match(line)
|
||||
# if m1 or m2:
|
||||
# # skip blank lines and comments
|
||||
# linenum = linenum + 1
|
||||
# elif mode == SEARCHING:
|
||||
# m = typedef_pat.match(line)
|
||||
# if m:
|
||||
# mode = FOUND_ENUM
|
||||
# m = typedef2_pat.match(line)
|
||||
# if m:
|
||||
# mode = IN_ENUM
|
||||
# decls = {}
|
||||
# idx = 0
|
||||
# elif mode == FOUND_ENUM:
|
||||
# m = openbrace_pat.match(line)
|
||||
# if m:
|
||||
# mode = IN_ENUM
|
||||
# decls = {}
|
||||
# idx = 0
|
||||
# else:
|
||||
# assert False, "Invalid %s, line: %s" % (api_file, linenum)
|
||||
# else:
|
||||
# assert mode == IN_ENUM
|
||||
# words = re.split('[^\-a-zA-Z0-9_]+', line)
|
||||
# m = closebrace_pat.match(line)
|
||||
# if m:
|
||||
# name = words[1]
|
||||
# if name not in DeprecatedEnums:
|
||||
# efile.write('(** %s *)\n' % name[3:])
|
||||
# efile.write('type %s =\n' % name[3:]) # strip Z3_
|
||||
# for k, i in sorted(decls.items(), key=lambda pair: pair[1]):
|
||||
# efile.write(' | %s \n' % k[3:]) # strip Z3_
|
||||
# efile.write('\n')
|
||||
# efile.write('(** Convert %s to int*)\n' % name[3:])
|
||||
# efile.write('val int_of_%s : %s -> int\n' % (name[3:], name[3:])) # strip Z3_
|
||||
# efile.write('(** Convert int to %s*)\n' % name[3:])
|
||||
# efile.write('val %s_of_int : int -> %s\n' % (name[3:],name[3:])) # strip Z3_
|
||||
# efile.write('\n')
|
||||
# mode = SEARCHING
|
||||
# else:
|
||||
# if words[2] != '':
|
||||
# if len(words[2]) > 1 and words[2][1] == 'x':
|
||||
# idx = int(words[2], 16)
|
||||
# else:
|
||||
# idx = int(words[2])
|
||||
# decls[words[1]] = idx
|
||||
# idx = idx + 1
|
||||
# linenum = linenum + 1
|
||||
# api.close()
|
||||
# efile.close()
|
||||
# if VERBOSE:
|
||||
# print ('Generated "%s/z3enums.mli"' % ('%s' % gendir))
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Functions for generating a "module definition file" for MSVC
|
||||
|
|
|
@ -9,7 +9,7 @@ from mk_util import *
|
|||
|
||||
# Z3 Project definition
|
||||
def init_project_def():
|
||||
set_version(4, 4, 2, 0)
|
||||
set_version(4, 5, 1, 0)
|
||||
add_lib('util', [])
|
||||
add_lib('polynomial', ['util'], 'math/polynomial')
|
||||
add_lib('sat', ['util'])
|
||||
|
@ -45,7 +45,7 @@ def init_project_def():
|
|||
# Simplifier module will be deleted in the future.
|
||||
# It has been replaced with rewriter module.
|
||||
add_lib('simplifier', ['rewriter'], 'ast/simplifier')
|
||||
add_lib('fpa', ['ast', 'util', 'simplifier'], 'ast/fpa')
|
||||
add_lib('fpa', ['ast', 'util', 'simplifier', 'model'], 'ast/fpa')
|
||||
add_lib('macros', ['simplifier'], 'ast/macros')
|
||||
add_lib('pattern', ['normal_forms', 'smt2parser', 'simplifier'], 'ast/pattern')
|
||||
add_lib('bit_blaster', ['rewriter', 'simplifier'], 'ast/rewriter/bit_blaster')
|
||||
|
@ -87,12 +87,14 @@ def init_project_def():
|
|||
reexports=['api'],
|
||||
dll_name='libz3',
|
||||
static=build_static_lib(),
|
||||
export_files=API_files)
|
||||
add_dot_net_dll('dotnet', ['api_dll'], 'api/dotnet', dll_name='Microsoft.Z3', assembly_info_dir='Properties')
|
||||
export_files=API_files,
|
||||
staging_link='python')
|
||||
add_dot_net_dll('dotnet', ['api_dll'], 'api/dotnet', dll_name='Microsoft.Z3', assembly_info_dir='Properties', default_key_file='src/api/dotnet/Microsoft.Z3.snk')
|
||||
add_java_dll('java', ['api_dll'], 'api/java', dll_name='libz3java', package_name="com.microsoft.z3", manifest_file='manifest')
|
||||
add_ml_lib('ml', ['api_dll'], 'api/ml', lib_name='libz3ml')
|
||||
add_hlib('cpp', 'api/c++', includes2install=['z3++.h'])
|
||||
set_z3py_dir('api/python')
|
||||
add_python(_libz3Component)
|
||||
add_python_install(_libz3Component)
|
||||
# Examples
|
||||
add_cpp_example('cpp_example', 'c++')
|
||||
|
|
|
@ -23,8 +23,11 @@ VERBOSE=True
|
|||
DIST_DIR='dist'
|
||||
FORCE_MK=False
|
||||
DOTNET_ENABLED=True
|
||||
DOTNET_KEY_FILE=None
|
||||
JAVA_ENABLED=True
|
||||
GIT_HASH=False
|
||||
PYTHON_ENABLED=True
|
||||
MAKEJOBS=getenv("MAKEJOBS", '8')
|
||||
|
||||
def set_verbose(flag):
|
||||
global VERBOSE
|
||||
|
@ -52,13 +55,15 @@ def display_help():
|
|||
print(" -b <sudir>, --build=<subdir> subdirectory where x86 and x64 Z3 versions will be built (default: build-dist).")
|
||||
print(" -f, --force force script to regenerate Makefiles.")
|
||||
print(" --nodotnet do not include .NET bindings in the binary distribution files.")
|
||||
print(" --dotnet-key=<file> sign the .NET assembly with the private key in <file>.")
|
||||
print(" --nojava do not include Java bindings in the binary distribution files.")
|
||||
print(" --nopython do not include Python bindings in the binary distribution files.")
|
||||
print(" --githash include git hash in the Zip file.")
|
||||
exit(0)
|
||||
|
||||
# Parse configuration option for mk_make script
|
||||
def parse_options():
|
||||
global FORCE_MK, JAVA_ENABLED, GIT_HASH, DOTNET_ENABLED
|
||||
global FORCE_MK, JAVA_ENABLED, GIT_HASH, DOTNET_ENABLED, DOTNET_KEY_FILE
|
||||
path = BUILD_DIR
|
||||
options, remainder = getopt.gnu_getopt(sys.argv[1:], 'b:hsf', ['build=',
|
||||
'help',
|
||||
|
@ -66,7 +71,9 @@ def parse_options():
|
|||
'force',
|
||||
'nojava',
|
||||
'nodotnet',
|
||||
'githash'
|
||||
'dotnet-key=',
|
||||
'githash',
|
||||
'nopython'
|
||||
])
|
||||
for opt, arg in options:
|
||||
if opt in ('-b', '--build'):
|
||||
|
@ -80,7 +87,11 @@ def parse_options():
|
|||
elif opt in ('-f', '--force'):
|
||||
FORCE_MK = True
|
||||
elif opt == '--nodotnet':
|
||||
DOTNET_ENABLED = False
|
||||
DOTNET_ENABLED = False
|
||||
elif opt == '--nopython':
|
||||
PYTHON_ENABLED = False
|
||||
elif opt == '--dotnet-key':
|
||||
DOTNET_KEY_FILE = arg
|
||||
elif opt == '--nojava':
|
||||
JAVA_ENABLED = False
|
||||
elif opt == '--githash':
|
||||
|
@ -98,11 +109,16 @@ def mk_build_dir(path):
|
|||
if not check_build_dir(path) or FORCE_MK:
|
||||
opts = ["python", os.path.join('scripts', 'mk_make.py'), "-b", path, "--staticlib"]
|
||||
if DOTNET_ENABLED:
|
||||
opts.append('--dotnet')
|
||||
opts.append('--dotnet')
|
||||
if not DOTNET_KEY_FILE is None:
|
||||
opts.append('--dotnet-key=' + DOTNET_KEY_FILE)
|
||||
if JAVA_ENABLED:
|
||||
opts.append('--java')
|
||||
if GIT_HASH:
|
||||
opts.append('--githash=%s' % mk_util.git_hash())
|
||||
opts.append('--git-describe')
|
||||
if PYTHON_ENABLED:
|
||||
opts.append('--python')
|
||||
if subprocess.call(opts) != 0:
|
||||
raise MKException("Failed to generate build directory at '%s'" % path)
|
||||
|
||||
|
@ -124,7 +140,7 @@ class cd:
|
|||
def mk_z3():
|
||||
with cd(BUILD_DIR):
|
||||
try:
|
||||
return subprocess.call(['make', '-j', '8'])
|
||||
return subprocess.call(['make', '-j', MAKEJOBS])
|
||||
except:
|
||||
return 1
|
||||
|
||||
|
@ -171,7 +187,9 @@ def mk_dist_dir():
|
|||
dist_path = os.path.join(DIST_DIR, get_z3_name())
|
||||
mk_dir(dist_path)
|
||||
mk_util.DOTNET_ENABLED = DOTNET_ENABLED
|
||||
mk_util.DOTNET_KEY_FILE = DOTNET_KEY_FILE
|
||||
mk_util.JAVA_ENABLED = JAVA_ENABLED
|
||||
mk_util.PYTHON_ENABLED = PYTHON_ENABLED
|
||||
mk_unix_dist(build_path, dist_path)
|
||||
if is_verbose():
|
||||
print("Generated distribution folder at '%s'" % dist_path)
|
||||
|
|
|
@ -63,6 +63,7 @@ DOTNET_COMPONENT='dotnet'
|
|||
JAVA_COMPONENT='java'
|
||||
ML_COMPONENT='ml'
|
||||
CPP_COMPONENT='cpp'
|
||||
PYTHON_COMPONENT='python'
|
||||
#####################
|
||||
IS_WINDOWS=False
|
||||
IS_LINUX=False
|
||||
|
@ -70,6 +71,7 @@ IS_OSX=False
|
|||
IS_FREEBSD=False
|
||||
IS_OPENBSD=False
|
||||
IS_CYGWIN=False
|
||||
IS_CYGWIN_MINGW=False
|
||||
VERBOSE=True
|
||||
DEBUG_MODE=False
|
||||
SHOW_CPPS = True
|
||||
|
@ -80,7 +82,9 @@ ONLY_MAKEFILES = False
|
|||
Z3PY_SRC_DIR=None
|
||||
VS_PROJ = False
|
||||
TRACE = False
|
||||
PYTHON_ENABLED=False
|
||||
DOTNET_ENABLED=False
|
||||
DOTNET_KEY_FILE=getenv("Z3_DOTNET_KEY_FILE", None)
|
||||
JAVA_ENABLED=False
|
||||
ML_ENABLED=False
|
||||
PYTHON_INSTALL_ENABLED=False
|
||||
|
@ -98,8 +102,10 @@ VS_PAR=False
|
|||
VS_PAR_NUM=8
|
||||
GPROF=False
|
||||
GIT_HASH=False
|
||||
GIT_DESCRIBE=False
|
||||
SLOW_OPTIMIZE=False
|
||||
USE_OMP=True
|
||||
LOG_SYNC=False
|
||||
|
||||
FPMATH="Default"
|
||||
FPMATH_FLAGS="-mfpmath=sse -msse -msse2"
|
||||
|
@ -143,6 +149,9 @@ def is_osx():
|
|||
def is_cygwin():
|
||||
return IS_CYGWIN
|
||||
|
||||
def is_cygwin_mingw():
|
||||
return IS_CYGWIN_MINGW
|
||||
|
||||
def norm_path(p):
|
||||
# We use '/' on mk_project for convenience
|
||||
return os.path.join(*(p.split('/')))
|
||||
|
@ -219,7 +228,10 @@ def rmf(fname):
|
|||
|
||||
def exec_compiler_cmd(cmd):
|
||||
r = exec_cmd(cmd)
|
||||
rmf('a.out')
|
||||
if is_windows() or is_cygwin_mingw():
|
||||
rmf('a.exe')
|
||||
else:
|
||||
rmf('a.out')
|
||||
return r
|
||||
|
||||
def test_cxx_compiler(cc):
|
||||
|
@ -527,11 +539,14 @@ def find_c_compiler():
|
|||
raise MKException('C compiler was not found. Try to set the environment variable CC with the C compiler available in your system.')
|
||||
|
||||
def set_version(major, minor, build, revision):
|
||||
global VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION
|
||||
global VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION, GIT_DESCRIBE
|
||||
VER_MAJOR = major
|
||||
VER_MINOR = minor
|
||||
VER_BUILD = build
|
||||
VER_REVISION = revision
|
||||
if GIT_DESCRIBE:
|
||||
branch = check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD'])
|
||||
VER_REVISION = int(check_output(['git', 'rev-list', '--count', 'HEAD']))
|
||||
|
||||
def get_version():
|
||||
return (VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION)
|
||||
|
@ -597,6 +612,8 @@ elif os.name == 'posix':
|
|||
IS_OPENBSD=True
|
||||
elif os.uname()[0][:6] == 'CYGWIN':
|
||||
IS_CYGWIN=True
|
||||
if (CC != None and "mingw" in CC):
|
||||
IS_CYGWIN_MINGW=True
|
||||
|
||||
def display_help(exit_code):
|
||||
print("mk_make.py: Z3 Makefile generator\n")
|
||||
|
@ -612,6 +629,7 @@ def display_help(exit_code):
|
|||
print(" --pypkgdir=<dir> Force a particular Python package directory (default %s)" % PYTHON_PACKAGE_DIR)
|
||||
print(" -b <subdir>, --build=<subdir> subdirectory where Z3 will be built (default: %s)." % BUILD_DIR)
|
||||
print(" --githash=hash include the given hash in the binaries.")
|
||||
print(" --git-describe include the output of 'git describe' in the version information.")
|
||||
print(" -d, --debug compile Z3 in debug mode.")
|
||||
print(" -t, --trace enable tracing in release mode.")
|
||||
if IS_WINDOWS:
|
||||
|
@ -624,6 +642,7 @@ def display_help(exit_code):
|
|||
if IS_WINDOWS:
|
||||
print(" --optimize generate optimized code during linking.")
|
||||
print(" --dotnet generate .NET bindings.")
|
||||
print(" --dotnet-key=<file> sign the .NET assembly using the private key in <file>.")
|
||||
print(" --java generate Java bindings.")
|
||||
print(" --ml generate OCaml bindings.")
|
||||
print(" --python generate Python bindings.")
|
||||
|
@ -634,6 +653,7 @@ def display_help(exit_code):
|
|||
print(" --gprof enable gprof")
|
||||
print(" -f <path> --foci2=<path> use foci2 library at path")
|
||||
print(" --noomp disable OpenMP and all features that require it.")
|
||||
print(" --log-sync synchronize access to API log files to enable multi-thread API logging.")
|
||||
print("")
|
||||
print("Some influential environment variables:")
|
||||
if not IS_WINDOWS:
|
||||
|
@ -659,14 +679,14 @@ def display_help(exit_code):
|
|||
# Parse configuration option for mk_make script
|
||||
def parse_options():
|
||||
global VERBOSE, DEBUG_MODE, IS_WINDOWS, VS_X64, ONLY_MAKEFILES, SHOW_CPPS, VS_PROJ, TRACE, VS_PAR, VS_PAR_NUM
|
||||
global DOTNET_ENABLED, JAVA_ENABLED, ML_ENABLED, STATIC_LIB, STATIC_BIN, PREFIX, GMP, FOCI2, FOCI2LIB, PYTHON_PACKAGE_DIR, GPROF, GIT_HASH, PYTHON_INSTALL_ENABLED
|
||||
global LINUX_X64, SLOW_OPTIMIZE, USE_OMP
|
||||
global DOTNET_ENABLED, DOTNET_KEY_FILE, JAVA_ENABLED, ML_ENABLED, STATIC_LIB, STATIC_BIN, PREFIX, GMP, FOCI2, FOCI2LIB, PYTHON_PACKAGE_DIR, GPROF, GIT_HASH, GIT_DESCRIBE, PYTHON_INSTALL_ENABLED, PYTHON_ENABLED
|
||||
global LINUX_X64, SLOW_OPTIMIZE, USE_OMP, LOG_SYNC
|
||||
try:
|
||||
options, remainder = getopt.gnu_getopt(sys.argv[1:],
|
||||
'b:df:sxhmcvtnp:gj',
|
||||
['build=', 'debug', 'silent', 'x64', 'help', 'makefiles', 'showcpp', 'vsproj',
|
||||
'trace', 'dotnet', 'staticlib', 'prefix=', 'gmp', 'foci2=', 'java', 'parallel=', 'gprof',
|
||||
'githash=', 'x86', 'ml', 'optimize', 'noomp', 'pypkgdir=', 'python', 'staticbin'])
|
||||
'trace', 'dotnet', 'dotnet-key=', 'staticlib', 'prefix=', 'gmp', 'foci2=', 'java', 'parallel=', 'gprof',
|
||||
'githash=', 'git-describe', 'x86', 'ml', 'optimize', 'noomp', 'pypkgdir=', 'python', 'staticbin', 'log-sync'])
|
||||
except:
|
||||
print("ERROR: Invalid command line option")
|
||||
display_help(1)
|
||||
|
@ -699,6 +719,8 @@ def parse_options():
|
|||
TRACE = True
|
||||
elif opt in ('-.net', '--dotnet'):
|
||||
DOTNET_ENABLED = True
|
||||
elif opt in ('--dotnet-key'):
|
||||
DOTNET_KEY_FILE = arg
|
||||
elif opt in ('--staticlib'):
|
||||
STATIC_LIB = True
|
||||
elif opt in ('--staticbin'):
|
||||
|
@ -723,11 +745,16 @@ def parse_options():
|
|||
GPROF = True
|
||||
elif opt == '--githash':
|
||||
GIT_HASH=arg
|
||||
elif opt == '--git-describe':
|
||||
GIT_DESCRIBE = True
|
||||
elif opt in ('', '--ml'):
|
||||
ML_ENABLED = True
|
||||
elif opt in ('', '--noomp'):
|
||||
USE_OMP = False
|
||||
elif opt in ('', '--log-sync'):
|
||||
LOG_SYNC = True
|
||||
elif opt in ('--python'):
|
||||
PYTHON_ENABLED = True
|
||||
PYTHON_INSTALL_ENABLED = True
|
||||
else:
|
||||
print("ERROR: Invalid command line option '%s'" % opt)
|
||||
|
@ -824,6 +851,9 @@ def is_ml_enabled():
|
|||
def is_dotnet_enabled():
|
||||
return DOTNET_ENABLED
|
||||
|
||||
def is_python_enabled():
|
||||
return PYTHON_ENABLED
|
||||
|
||||
def is_python_install_enabled():
|
||||
return PYTHON_INSTALL_ENABLED
|
||||
|
||||
|
@ -851,8 +881,8 @@ def is_CXX_gpp():
|
|||
return is_compiler(CXX, 'g++')
|
||||
|
||||
def is_clang_in_gpp_form(cc):
|
||||
version_string = check_output([cc, '--version'])
|
||||
return str(version_string).find('clang') != -1
|
||||
version_string = check_output([cc, '--version']).encode('utf-8').decode('utf-8')
|
||||
return version_string.find('clang') != -1
|
||||
|
||||
def is_CXX_clangpp():
|
||||
if is_compiler(CXX, 'g++'):
|
||||
|
@ -1138,7 +1168,8 @@ class ExeComponent(Component):
|
|||
c_dep = get_component(dep)
|
||||
out.write(' ' + c_dep.get_link_name())
|
||||
out.write('\n')
|
||||
out.write('\t$(LINK) $(LINK_OUT_FLAG)%s $(LINK_FLAGS)' % exefile)
|
||||
extra_opt = '-static' if not IS_WINDOWS and STATIC_BIN else ''
|
||||
out.write('\t$(LINK) %s $(LINK_OUT_FLAG)%s $(LINK_FLAGS)' % (extra_opt, exefile))
|
||||
for obj in objs:
|
||||
out.write(' ')
|
||||
out.write(obj)
|
||||
|
@ -1210,7 +1241,7 @@ def get_so_ext():
|
|||
return 'dll'
|
||||
|
||||
class DLLComponent(Component):
|
||||
def __init__(self, name, dll_name, path, deps, export_files, reexports, install, static):
|
||||
def __init__(self, name, dll_name, path, deps, export_files, reexports, install, static, staging_link=None):
|
||||
Component.__init__(self, name, path, deps)
|
||||
if dll_name is None:
|
||||
dll_name = name
|
||||
|
@ -1219,6 +1250,7 @@ class DLLComponent(Component):
|
|||
self.reexports = reexports
|
||||
self.install = install
|
||||
self.static = static
|
||||
self.staging_link = staging_link # link a copy of the shared object into this directory on build
|
||||
|
||||
def get_link_name(self):
|
||||
if self.static:
|
||||
|
@ -1274,6 +1306,13 @@ class DLLComponent(Component):
|
|||
out.write(' $(SLINK_EXTRA_FLAGS)')
|
||||
if IS_WINDOWS:
|
||||
out.write(' /DEF:%s.def' % os.path.join(self.to_src_dir, self.name))
|
||||
if self.staging_link:
|
||||
if IS_WINDOWS:
|
||||
out.write('\n\tcopy %s %s' % (self.dll_file(), self.staging_link))
|
||||
elif IS_OSX:
|
||||
out.write('\n\tcp %s %s' % (self.dll_file(), self.staging_link))
|
||||
else:
|
||||
out.write('\n\tln -f -s %s %s' % (os.path.join(reverse_path(self.staging_link), self.dll_file()), self.staging_link))
|
||||
out.write('\n')
|
||||
if self.static:
|
||||
if IS_WINDOWS:
|
||||
|
@ -1354,6 +1393,32 @@ class DLLComponent(Component):
|
|||
shutil.copy('%s.a' % os.path.join(build_path, self.dll_name),
|
||||
'%s.a' % os.path.join(dist_path, INSTALL_BIN_DIR, self.dll_name))
|
||||
|
||||
class PythonComponent(Component):
|
||||
def __init__(self, name, libz3Component):
|
||||
assert isinstance(libz3Component, DLLComponent)
|
||||
global PYTHON_ENABLED
|
||||
Component.__init__(self, name, None, [])
|
||||
self.libz3Component = libz3Component
|
||||
|
||||
def main_component(self):
|
||||
return False
|
||||
|
||||
def mk_win_dist(self, build_path, dist_path):
|
||||
if not is_python_enabled():
|
||||
return
|
||||
|
||||
src = os.path.join(build_path, 'python', 'z3')
|
||||
dst = os.path.join(dist_path, INSTALL_BIN_DIR, 'python', 'z3')
|
||||
if os.path.exists(dst):
|
||||
shutil.rmtree(dst)
|
||||
shutil.copytree(src, dst)
|
||||
|
||||
def mk_unix_dist(self, build_path, dist_path):
|
||||
self.mk_win_dist(build_path, dist_path)
|
||||
|
||||
def mk_makefile(self, out):
|
||||
return
|
||||
|
||||
class PythonInstallComponent(Component):
|
||||
def __init__(self, name, libz3Component):
|
||||
assert isinstance(libz3Component, DLLComponent)
|
||||
|
@ -1412,13 +1477,18 @@ class PythonInstallComponent(Component):
|
|||
def mk_install(self, out):
|
||||
if not is_python_install_enabled():
|
||||
return
|
||||
MakeRuleCmd.make_install_directory(out, self.pythonPkgDir, in_prefix=self.in_prefix_install)
|
||||
MakeRuleCmd.make_install_directory(out,
|
||||
os.path.join(self.pythonPkgDir, 'z3'),
|
||||
in_prefix=self.in_prefix_install)
|
||||
MakeRuleCmd.make_install_directory(out,
|
||||
os.path.join(self.pythonPkgDir, 'z3', 'lib'),
|
||||
in_prefix=self.in_prefix_install)
|
||||
|
||||
# Sym-link or copy libz3 into python package directory
|
||||
if IS_WINDOWS or IS_OSX:
|
||||
MakeRuleCmd.install_files(out,
|
||||
self.libz3Component.dll_file(),
|
||||
os.path.join(self.pythonPkgDir,
|
||||
os.path.join(self.pythonPkgDir, 'z3', 'lib',
|
||||
self.libz3Component.dll_file()),
|
||||
in_prefix=self.in_prefix_install
|
||||
)
|
||||
|
@ -1429,34 +1499,30 @@ class PythonInstallComponent(Component):
|
|||
# staged installs that use DESTDIR).
|
||||
MakeRuleCmd.create_relative_symbolic_link(out,
|
||||
self.libz3Component.install_path(),
|
||||
os.path.join(self.pythonPkgDir,
|
||||
os.path.join(self.pythonPkgDir, 'z3', 'lib',
|
||||
self.libz3Component.dll_file()
|
||||
),
|
||||
)
|
||||
|
||||
MakeRuleCmd.install_files(out, 'z3*.py', self.pythonPkgDir,
|
||||
MakeRuleCmd.install_files(out, os.path.join('python', 'z3', '*.py'),
|
||||
os.path.join(self.pythonPkgDir, 'z3'),
|
||||
in_prefix=self.in_prefix_install)
|
||||
if sys.version >= "3":
|
||||
pythonPycacheDir = os.path.join(self.pythonPkgDir, '__pycache__')
|
||||
pythonPycacheDir = os.path.join(self.pythonPkgDir, 'z3', '__pycache__')
|
||||
MakeRuleCmd.make_install_directory(out,
|
||||
pythonPycacheDir,
|
||||
in_prefix=self.in_prefix_install)
|
||||
MakeRuleCmd.install_files(out,
|
||||
'{}*.pyc'.format(os.path.join('__pycache__', 'z3')),
|
||||
os.path.join('python', 'z3', '__pycache__', '*.pyc'),
|
||||
pythonPycacheDir,
|
||||
in_prefix=self.in_prefix_install)
|
||||
else:
|
||||
MakeRuleCmd.install_files(out,
|
||||
'z3*.pyc',
|
||||
self.pythonPkgDir,
|
||||
os.path.join('python', 'z3', '*.pyc'),
|
||||
os.path.join(self.pythonPkgDir,'z3'),
|
||||
in_prefix=self.in_prefix_install)
|
||||
|
||||
if PYTHON_PACKAGE_DIR != distutils.sysconfig.get_python_lib():
|
||||
if os.uname()[0] == 'Darwin':
|
||||
LD_LIBRARY_PATH = "DYLD_LIBRARY_PATH"
|
||||
else:
|
||||
LD_LIBRARY_PATH = "LD_LIBRARY_PATH"
|
||||
out.write('\t@echo Z3 shared libraries were installed at \'%s\', make sure this directory is in your %s environment variable.\n' %
|
||||
(os.path.join(PREFIX, INSTALL_LIB_DIR), LD_LIBRARY_PATH))
|
||||
out.write('\t@echo Z3Py was installed at \'%s\', make sure this directory is in your PYTHONPATH environment variable.' % PYTHON_PACKAGE_DIR)
|
||||
|
||||
def mk_uninstall(self, out):
|
||||
|
@ -1468,21 +1534,24 @@ class PythonInstallComponent(Component):
|
|||
in_prefix=self.in_prefix_install
|
||||
)
|
||||
MakeRuleCmd.remove_installed_files(out,
|
||||
'{}*.py'.format(os.path.join(self.pythonPkgDir, 'z3')),
|
||||
os.path.join(self.pythonPkgDir, 'z3', '*.py'),
|
||||
in_prefix=self.in_prefix_install)
|
||||
MakeRuleCmd.remove_installed_files(out,
|
||||
'{}*.pyc'.format(os.path.join(self.pythonPkgDir, 'z3')),
|
||||
os.path.join(self.pythonPkgDir, 'z3', '*.pyc'),
|
||||
in_prefix=self.in_prefix_install)
|
||||
MakeRuleCmd.remove_installed_files(out,
|
||||
'{}*.pyc'.format(os.path.join(self.pythonPkgDir, '__pycache__', 'z3')),
|
||||
os.path.join(self.pythonPkgDir, 'z3', '__pycache__', '*.pyc'),
|
||||
in_prefix=self.in_prefix_install
|
||||
)
|
||||
MakeRuleCmd.remove_installed_files(out,
|
||||
os.path.join(self.pythonPkgDir, 'z3', 'lib',
|
||||
self.libz3Component.dll_file()))
|
||||
|
||||
def mk_makefile(self, out):
|
||||
return
|
||||
|
||||
class DotNetDLLComponent(Component):
|
||||
def __init__(self, name, dll_name, path, deps, assembly_info_dir):
|
||||
def __init__(self, name, dll_name, path, deps, assembly_info_dir, default_key_file):
|
||||
Component.__init__(self, name, path, deps)
|
||||
if dll_name is None:
|
||||
dll_name = name
|
||||
|
@ -1490,6 +1559,7 @@ class DotNetDLLComponent(Component):
|
|||
assembly_info_dir = "."
|
||||
self.dll_name = dll_name
|
||||
self.assembly_info_dir = assembly_info_dir
|
||||
self.key_file = default_key_file
|
||||
|
||||
def mk_pkg_config_file(self):
|
||||
"""
|
||||
|
@ -1515,6 +1585,8 @@ class DotNetDLLComponent(Component):
|
|||
configure_file(pkg_config_template, pkg_config_output, substitutions)
|
||||
|
||||
def mk_makefile(self, out):
|
||||
global DOTNET_KEY_FILE
|
||||
|
||||
if not is_dotnet_enabled():
|
||||
return
|
||||
cs_fp_files = []
|
||||
|
@ -1545,11 +1617,24 @@ class DotNetDLLComponent(Component):
|
|||
'/linkresource:{}.dll'.format(get_component(Z3_DLL_COMPONENT).dll_name),
|
||||
]
|
||||
)
|
||||
else:
|
||||
# We need to give the assembly a strong name so that it
|
||||
# can be installed into the GAC with ``make install``
|
||||
pathToSnk = os.path.join(self.to_src_dir, 'Microsoft.Z3.mono.snk')
|
||||
cscCmdLine.append('/keyfile:{}'.format(pathToSnk))
|
||||
|
||||
# We need to give the assembly a strong name so that it
|
||||
# can be installed into the GAC with ``make install``
|
||||
if not DOTNET_KEY_FILE is None:
|
||||
self.key_file = DOTNET_KEY_FILE
|
||||
|
||||
if not self.key_file is None:
|
||||
if os.path.isfile(self.key_file):
|
||||
self.key_file = os.path.abspath(self.key_file)
|
||||
elif os.path.isfile(os.path.join(self.src_dir, self.key_file)):
|
||||
self.key_file = os.path.abspath(os.path.join(self.src_dir, self.key_file))
|
||||
else:
|
||||
print("Keyfile '%s' could not be found; %s.dll will be unsigned." % (self.key_file, self.dll_name))
|
||||
self.key_file = None
|
||||
|
||||
if not self.key_file is None:
|
||||
print("%s.dll will be signed using key '%s'." % (self.dll_name, self.key_file))
|
||||
cscCmdLine.append('/keyfile:{}'.format(self.key_file))
|
||||
|
||||
cscCmdLine.extend( ['/unsafe+',
|
||||
'/nowarn:1701,1702',
|
||||
|
@ -1573,6 +1658,7 @@ class DotNetDLLComponent(Component):
|
|||
)
|
||||
else:
|
||||
cscCmdLine.extend(['/optimize+'])
|
||||
|
||||
if IS_WINDOWS:
|
||||
if VS_X64:
|
||||
cscCmdLine.extend(['/platform:x64'])
|
||||
|
@ -1821,7 +1907,7 @@ class MLComponent(Component):
|
|||
CP_CMD='copy'
|
||||
|
||||
OCAML_FLAGS = ''
|
||||
if DEBUG_MODE:
|
||||
if DEBUG_MODE:
|
||||
OCAML_FLAGS += '-g'
|
||||
OCAMLCF = OCAMLC + ' ' + OCAML_FLAGS
|
||||
OCAMLOPTF = OCAMLOPT + ' ' + OCAML_FLAGS
|
||||
|
@ -1875,16 +1961,19 @@ class MLComponent(Component):
|
|||
|
||||
|
||||
OCAMLMKLIB = 'ocamlmklib'
|
||||
LIBZ3 = '-L. -lz3'
|
||||
if is_cygwin():
|
||||
# Some ocamlmklib's don't like -g; observed on cygwin, but may be others as well.
|
||||
|
||||
LIBZ3 = '-L. -lz3'
|
||||
if is_cygwin() and not(is_cygwin_mingw()):
|
||||
LIBZ3 = 'libz3.dll'
|
||||
elif DEBUG_MODE:
|
||||
|
||||
if DEBUG_MODE and not(is_cygwin()):
|
||||
# Some ocamlmklib's don't like -g; observed on cygwin, but may be others as well.
|
||||
OCAMLMKLIB += ' -g'
|
||||
|
||||
z3mls = os.path.join(self.sub_dir, 'z3ml')
|
||||
out.write('%s.cma: %s %s %s\n' % (z3mls, cmos, stubso, z3dllso))
|
||||
out.write('\t%s -o %s -I %s %s %s %s\n' % (OCAMLMKLIB, z3mls, self.sub_dir, stubso, cmos, LIBZ3))
|
||||
out.write('%s.cmxa: %s %s %s\n' % (z3mls, cmxs, stubso, z3dllso))
|
||||
out.write('%s.cmxa: %s %s %s %s.cma\n' % (z3mls, cmxs, stubso, z3dllso, z3mls))
|
||||
out.write('\t%s -o %s -I %s %s %s %s\n' % (OCAMLMKLIB, z3mls, self.sub_dir, stubso, cmxs, LIBZ3))
|
||||
out.write('%s.cmxs: %s.cmxa\n' % (z3mls, z3mls))
|
||||
out.write('\t%s -shared -o %s.cmxs -I %s %s.cmxa\n' % (OCAMLOPTF, z3mls, self.sub_dir, z3mls))
|
||||
|
@ -1943,7 +2032,7 @@ class MLComponent(Component):
|
|||
out.write(' %s' % ((os.path.join(self.sub_dir, 'z3ml.cmxa'))))
|
||||
out.write(' %s' % ((os.path.join(self.sub_dir, 'z3ml.cmxs'))))
|
||||
out.write(' %s' % ((os.path.join(self.sub_dir, 'dllz3ml'))))
|
||||
if IS_WINDOWS:
|
||||
if is_windows() or is_cygwin_mingw():
|
||||
out.write('.dll')
|
||||
else:
|
||||
out.write('.so') # .so also on OSX!
|
||||
|
@ -2117,11 +2206,20 @@ class PythonExampleComponent(ExampleComponent):
|
|||
def mk_makefile(self, out):
|
||||
full = os.path.join(EXAMPLE_DIR, self.path)
|
||||
for py in filter(lambda f: f.endswith('.py'), os.listdir(full)):
|
||||
shutil.copyfile(os.path.join(full, py), os.path.join(BUILD_DIR, py))
|
||||
shutil.copyfile(os.path.join(full, py), os.path.join(BUILD_DIR, 'python', py))
|
||||
if is_verbose():
|
||||
print("Copied Z3Py example '%s' to '%s'" % (py, BUILD_DIR))
|
||||
print("Copied Z3Py example '%s' to '%s'" % (py, os.path.join(BUILD_DIR, 'python')))
|
||||
out.write('_ex_%s: \n\n' % self.name)
|
||||
|
||||
def mk_win_dist(self, build_path, dist_path):
|
||||
full = os.path.join(EXAMPLE_DIR, self.path)
|
||||
py = 'example.py'
|
||||
shutil.copyfile(os.path.join(full, py),
|
||||
os.path.join(dist_path, INSTALL_BIN_DIR, 'python', py))
|
||||
|
||||
def mk_unix_dist(self, build_path, dist_path):
|
||||
self.mk_win_dist(build_path, dist_path)
|
||||
|
||||
|
||||
def reg_component(name, c):
|
||||
global _Id, _Components, _ComponentNames, _Name2Component
|
||||
|
@ -2149,19 +2247,23 @@ def add_extra_exe(name, deps=[], path=None, exe_name=None, install=True):
|
|||
c = ExtraExeComponent(name, exe_name, path, deps, install)
|
||||
reg_component(name, c)
|
||||
|
||||
def add_dll(name, deps=[], path=None, dll_name=None, export_files=[], reexports=[], install=True, static=False):
|
||||
c = DLLComponent(name, dll_name, path, deps, export_files, reexports, install, static)
|
||||
def add_dll(name, deps=[], path=None, dll_name=None, export_files=[], reexports=[], install=True, static=False, staging_link=None):
|
||||
c = DLLComponent(name, dll_name, path, deps, export_files, reexports, install, static, staging_link)
|
||||
reg_component(name, c)
|
||||
return c
|
||||
|
||||
def add_dot_net_dll(name, deps=[], path=None, dll_name=None, assembly_info_dir=None):
|
||||
c = DotNetDLLComponent(name, dll_name, path, deps, assembly_info_dir)
|
||||
def add_dot_net_dll(name, deps=[], path=None, dll_name=None, assembly_info_dir=None, default_key_file=None):
|
||||
c = DotNetDLLComponent(name, dll_name, path, deps, assembly_info_dir, default_key_file)
|
||||
reg_component(name, c)
|
||||
|
||||
def add_java_dll(name, deps=[], path=None, dll_name=None, package_name=None, manifest_file=None):
|
||||
c = JavaDLLComponent(name, dll_name, package_name, manifest_file, path, deps)
|
||||
reg_component(name, c)
|
||||
|
||||
def add_python(libz3Component):
|
||||
name = 'python'
|
||||
reg_component(name, PythonComponent(name, libz3Component))
|
||||
|
||||
def add_python_install(libz3Component):
|
||||
name = 'python_install'
|
||||
reg_component(name, PythonInstallComponent(name, libz3Component))
|
||||
|
@ -2198,6 +2300,7 @@ def mk_config():
|
|||
if ONLY_MAKEFILES:
|
||||
return
|
||||
config = open(os.path.join(BUILD_DIR, 'config.mk'), 'w')
|
||||
global CXX, CC, GMP, FOCI2, CPPFLAGS, CXXFLAGS, LDFLAGS, EXAMP_DEBUG_FLAG, FPMATH_FLAGS, HAS_OMP, LOG_SYNC
|
||||
if IS_WINDOWS:
|
||||
config.write(
|
||||
'CC=cl\n'
|
||||
|
@ -2219,7 +2322,9 @@ def mk_config():
|
|||
if HAS_OMP:
|
||||
extra_opt = ' /openmp'
|
||||
else:
|
||||
extra_opt = ' -D_NO_OMP_'
|
||||
extra_opt = ' /D_NO_OMP_'
|
||||
if HAS_OMP and LOG_SYNC:
|
||||
extra_opt = '%s /DZ3_LOG_SYNC' % extra_opt
|
||||
if GIT_HASH:
|
||||
extra_opt = ' %s /D Z3GITHASH=%s' % (extra_opt, GIT_HASH)
|
||||
if STATIC_BIN:
|
||||
|
@ -2288,7 +2393,6 @@ def mk_config():
|
|||
print('OCaml Native: %s' % OCAMLOPT)
|
||||
print('OCaml Library: %s' % OCAML_LIB)
|
||||
else:
|
||||
global CXX, CC, GMP, FOCI2, CPPFLAGS, CXXFLAGS, LDFLAGS, EXAMP_DEBUG_FLAG, FPMATH_FLAGS
|
||||
OS_DEFINES = ""
|
||||
ARITH = "internal"
|
||||
check_ar()
|
||||
|
@ -2326,6 +2430,8 @@ def mk_config():
|
|||
SLIBEXTRAFLAGS = '%s -fopenmp' % SLIBEXTRAFLAGS
|
||||
else:
|
||||
CXXFLAGS = '%s -D_NO_OMP_' % CXXFLAGS
|
||||
if HAS_OMP and LOG_SYNC:
|
||||
CXXFLAGS = '%s -DZ3_LOG_SYNC' % CXXFLAGS
|
||||
if DEBUG_MODE:
|
||||
CXXFLAGS = '%s -g -Wall' % CXXFLAGS
|
||||
EXAMP_DEBUG_FLAG = '-g'
|
||||
|
@ -2336,7 +2442,7 @@ def mk_config():
|
|||
CXXFLAGS = '%s -O3 -D _EXTERNAL_RELEASE -fomit-frame-pointer' % CXXFLAGS
|
||||
if is_CXX_clangpp():
|
||||
CXXFLAGS = '%s -Wno-unknown-pragmas -Wno-overloaded-virtual -Wno-unused-value' % CXXFLAGS
|
||||
sysname = os.uname()[0]
|
||||
sysname, _, _, _, machine = os.uname()
|
||||
if sysname == 'Darwin':
|
||||
SO_EXT = '.dylib'
|
||||
SLIBFLAGS = '-dynamiclib'
|
||||
|
@ -2382,6 +2488,14 @@ def mk_config():
|
|||
CPPFLAGS = '%s -DNDEBUG -D_EXTERNAL_RELEASE' % CPPFLAGS
|
||||
if TRACE or DEBUG_MODE:
|
||||
CPPFLAGS = '%s -D_TRACE' % CPPFLAGS
|
||||
if is_cygwin_mingw():
|
||||
# when cross-compiling with MinGW, we need to statically link its standard libraries
|
||||
# and to make it create an import library.
|
||||
SLIBEXTRAFLAGS = '%s -static-libgcc -static-libstdc++ -Wl,--out-implib,libz3.dll.a' % SLIBEXTRAFLAGS
|
||||
LDFLAGS = '%s -static-libgcc -static-libstdc++' % LDFLAGS
|
||||
if sysname == 'Linux' and machine.startswith('armv7') or machine.startswith('armv8'):
|
||||
CXXFLAGS = '%s -fpic' % CXXFLAGS
|
||||
|
||||
config.write('PREFIX=%s\n' % PREFIX)
|
||||
config.write('CC=%s\n' % CC)
|
||||
config.write('CXX=%s\n' % CXX)
|
||||
|
@ -2395,10 +2509,7 @@ def mk_config():
|
|||
config.write('AR_OUTFLAG=\n')
|
||||
config.write('EXE_EXT=\n')
|
||||
config.write('LINK=%s\n' % CXX)
|
||||
if STATIC_BIN:
|
||||
config.write('LINK_FLAGS=-static\n')
|
||||
else:
|
||||
config.write('LINK_FLAGS=\n')
|
||||
config.write('LINK_FLAGS=\n')
|
||||
config.write('LINK_OUT_FLAG=-o \n')
|
||||
config.write('LINK_EXTRA_FLAGS=-lpthread %s\n' % LDFLAGS)
|
||||
config.write('SO_EXT=%s\n' % SO_EXT)
|
||||
|
@ -2411,6 +2522,8 @@ def mk_config():
|
|||
print('Host platform: %s' % sysname)
|
||||
print('C++ Compiler: %s' % CXX)
|
||||
print('C Compiler : %s' % CC)
|
||||
if is_cygwin_mingw():
|
||||
print('MinGW32 cross: %s' % (is_cygwin_mingw()))
|
||||
print('Archive Tool: %s' % AR)
|
||||
print('Arithmetic: %s' % ARITH)
|
||||
print('OpenMP: %s' % HAS_OMP)
|
||||
|
@ -2471,8 +2584,9 @@ def mk_makefile():
|
|||
if c.main_component():
|
||||
out.write(' %s' % c.name)
|
||||
out.write('\n\t@echo Z3 was successfully built.\n')
|
||||
out.write("\t@echo \"Z3Py scripts can already be executed in the \'%s\' directory.\"\n" % BUILD_DIR)
|
||||
out.write("\t@echo \"Z3Py scripts stored in arbitrary directories can be executed if the \'%s\' directory is added to the PYTHONPATH environment variable.\"\n" % BUILD_DIR)
|
||||
out.write("\t@echo \"Z3Py scripts can already be executed in the \'%s\' directory.\"\n" % os.path.join(BUILD_DIR, 'python'))
|
||||
pathvar = "DYLD_LIBRARY_PATH" if IS_OSX else "PATH" if IS_WINDOWS else "LD_LIBRARY_PATH"
|
||||
out.write("\t@echo \"Z3Py scripts stored in arbitrary directories can be executed if the \'%s\' directory is added to the PYTHONPATH environment variable and the \'%s\' directory is added to the %s environment variable.\"\n" % (os.path.join(BUILD_DIR, 'python'), BUILD_DIR, pathvar))
|
||||
if not IS_WINDOWS:
|
||||
out.write("\t@echo Use the following command to install Z3 at prefix $(PREFIX).\n")
|
||||
out.write('\t@echo " sudo make install"\n\n')
|
||||
|
@ -2566,6 +2680,16 @@ def update_version():
|
|||
mk_all_assembly_infos(major, minor, build, revision)
|
||||
mk_def_files()
|
||||
|
||||
def get_full_version_string(major, minor, build, revision):
|
||||
global GIT_HASH, GIT_DESCRIBE
|
||||
res = "Z3 %s.%s.%s.%s" % (major, minor, build, revision)
|
||||
if GIT_HASH:
|
||||
res += " " + GIT_HASH
|
||||
if GIT_DESCRIBE:
|
||||
branch = check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD', '--long'])
|
||||
res += " master " + check_output(['git', 'describe'])
|
||||
return '"' + res + '"'
|
||||
|
||||
# Update files with the version number
|
||||
def mk_version_dot_h(major, minor, build, revision):
|
||||
c = get_component(UTIL_COMPONENT)
|
||||
|
@ -2579,6 +2703,7 @@ def mk_version_dot_h(major, minor, build, revision):
|
|||
'Z3_VERSION_MINOR': str(minor),
|
||||
'Z3_VERSION_PATCH': str(build),
|
||||
'Z3_VERSION_TWEAK': str(revision),
|
||||
'Z3_FULL_VERSION': get_full_version_string(major, minor, build, revision)
|
||||
}
|
||||
)
|
||||
if VERBOSE:
|
||||
|
@ -2677,33 +2802,42 @@ def mk_def_files():
|
|||
|
||||
def cp_z3py_to_build():
|
||||
mk_dir(BUILD_DIR)
|
||||
mk_dir(os.path.join(BUILD_DIR, 'python'))
|
||||
z3py_dest = os.path.join(BUILD_DIR, 'python', 'z3')
|
||||
z3py_src = os.path.join(Z3PY_SRC_DIR, 'z3')
|
||||
|
||||
# Erase existing .pyc files
|
||||
for root, dirs, files in os.walk(Z3PY_SRC_DIR):
|
||||
for f in files:
|
||||
if f.endswith('.pyc'):
|
||||
rmf(os.path.join(root, f))
|
||||
# Compile Z3Py files
|
||||
if compileall.compile_dir(Z3PY_SRC_DIR, force=1) != 1:
|
||||
if compileall.compile_dir(z3py_src, force=1) != 1:
|
||||
raise MKException("failed to compile Z3Py sources")
|
||||
if is_verbose:
|
||||
print("Generated python bytecode")
|
||||
# Copy sources to build
|
||||
for py in filter(lambda f: f.endswith('.py'), os.listdir(Z3PY_SRC_DIR)):
|
||||
shutil.copyfile(os.path.join(Z3PY_SRC_DIR, py), os.path.join(BUILD_DIR, py))
|
||||
mk_dir(z3py_dest)
|
||||
for py in filter(lambda f: f.endswith('.py'), os.listdir(z3py_src)):
|
||||
shutil.copyfile(os.path.join(z3py_src, py), os.path.join(z3py_dest, py))
|
||||
if is_verbose():
|
||||
print("Copied '%s'" % py)
|
||||
# Python 2.x support
|
||||
for pyc in filter(lambda f: f.endswith('.pyc'), os.listdir(Z3PY_SRC_DIR)):
|
||||
shutil.copyfile(os.path.join(Z3PY_SRC_DIR, pyc), os.path.join(BUILD_DIR, pyc))
|
||||
for pyc in filter(lambda f: f.endswith('.pyc'), os.listdir(z3py_src)):
|
||||
shutil.copyfile(os.path.join(z3py_src, pyc), os.path.join(z3py_dest, pyc))
|
||||
if is_verbose():
|
||||
print("Generated '%s'" % pyc)
|
||||
print("Copied '%s'" % pyc)
|
||||
# Python 3.x support
|
||||
src_pycache = os.path.join(Z3PY_SRC_DIR, '__pycache__')
|
||||
src_pycache = os.path.join(z3py_src, '__pycache__')
|
||||
target_pycache = os.path.join(z3py_dest, '__pycache__')
|
||||
if os.path.exists(src_pycache):
|
||||
for pyc in filter(lambda f: f.endswith('.pyc'), os.listdir(src_pycache)):
|
||||
target_pycache = os.path.join(BUILD_DIR, '__pycache__')
|
||||
mk_dir(target_pycache)
|
||||
shutil.copyfile(os.path.join(src_pycache, pyc), os.path.join(target_pycache, pyc))
|
||||
if is_verbose():
|
||||
print("Generated '%s'" % pyc)
|
||||
print("Copied '%s'" % pyc)
|
||||
# Copy z3test.py
|
||||
shutil.copyfile(os.path.join(Z3PY_SRC_DIR, 'z3test.py'), os.path.join(BUILD_DIR, 'python', 'z3test.py'))
|
||||
|
||||
def mk_bindings(api_files):
|
||||
if not ONLY_MAKEFILES:
|
||||
|
@ -2738,7 +2872,8 @@ def mk_bindings(api_files):
|
|||
dotnet_output_dir=dotnet_output_dir,
|
||||
java_output_dir=java_output_dir,
|
||||
java_package_name=java_package_name,
|
||||
ml_output_dir=ml_output_dir
|
||||
ml_output_dir=ml_output_dir,
|
||||
ml_src_dir=ml_output_dir
|
||||
)
|
||||
cp_z3py_to_build()
|
||||
if is_ml_enabled():
|
||||
|
@ -2792,172 +2927,17 @@ def mk_z3consts_java(api_files):
|
|||
|
||||
# Extract enumeration types from z3_api.h, and add ML definitions
|
||||
def mk_z3consts_ml(api_files):
|
||||
blank_pat = re.compile("^ *$")
|
||||
comment_pat = re.compile("^ *//.*$")
|
||||
typedef_pat = re.compile("typedef enum *")
|
||||
typedef2_pat = re.compile("typedef enum { *")
|
||||
openbrace_pat = re.compile("{ *")
|
||||
closebrace_pat = re.compile("}.*;")
|
||||
|
||||
ml = get_component(ML_COMPONENT)
|
||||
|
||||
DeprecatedEnums = [ 'Z3_search_failure' ]
|
||||
gendir = ml.src_dir
|
||||
if not os.path.exists(gendir):
|
||||
os.mkdir(gendir)
|
||||
|
||||
efile = open('%s.ml' % os.path.join(gendir, "z3enums"), 'w')
|
||||
efile.write('(* Automatically generated file *)\n\n')
|
||||
efile.write('(** The enumeration types of Z3. *)\n\n')
|
||||
full_path_api_files = []
|
||||
for api_file in api_files:
|
||||
api_file_c = ml.find_file(api_file, ml.name)
|
||||
api_file = os.path.join(api_file_c.src_dir, api_file)
|
||||
|
||||
api = open(api_file, 'r')
|
||||
|
||||
SEARCHING = 0
|
||||
FOUND_ENUM = 1
|
||||
IN_ENUM = 2
|
||||
|
||||
mode = SEARCHING
|
||||
decls = {}
|
||||
idx = 0
|
||||
|
||||
linenum = 1
|
||||
for line in api:
|
||||
m1 = blank_pat.match(line)
|
||||
m2 = comment_pat.match(line)
|
||||
if m1 or m2:
|
||||
# skip blank lines and comments
|
||||
linenum = linenum + 1
|
||||
elif mode == SEARCHING:
|
||||
m = typedef_pat.match(line)
|
||||
if m:
|
||||
mode = FOUND_ENUM
|
||||
m = typedef2_pat.match(line)
|
||||
if m:
|
||||
mode = IN_ENUM
|
||||
decls = {}
|
||||
idx = 0
|
||||
elif mode == FOUND_ENUM:
|
||||
m = openbrace_pat.match(line)
|
||||
if m:
|
||||
mode = IN_ENUM
|
||||
decls = {}
|
||||
idx = 0
|
||||
else:
|
||||
assert False, "Invalid %s, line: %s" % (api_file, linenum)
|
||||
else:
|
||||
assert mode == IN_ENUM
|
||||
words = re.split('[^\-a-zA-Z0-9_]+', line)
|
||||
m = closebrace_pat.match(line)
|
||||
if m:
|
||||
name = words[1]
|
||||
if name not in DeprecatedEnums:
|
||||
efile.write('(** %s *)\n' % name[3:])
|
||||
efile.write('type %s =\n' % name[3:]) # strip Z3_
|
||||
for k, i in decls.items():
|
||||
efile.write(' | %s \n' % k[3:]) # strip Z3_
|
||||
efile.write('\n')
|
||||
efile.write('(** Convert %s to int*)\n' % name[3:])
|
||||
efile.write('let int_of_%s x : int =\n' % (name[3:])) # strip Z3_
|
||||
efile.write(' match x with\n')
|
||||
for k, i in decls.items():
|
||||
efile.write(' | %s -> %d\n' % (k[3:], i))
|
||||
efile.write('\n')
|
||||
efile.write('(** Convert int to %s*)\n' % name[3:])
|
||||
efile.write('let %s_of_int x : %s =\n' % (name[3:],name[3:])) # strip Z3_
|
||||
efile.write(' match x with\n')
|
||||
for k, i in decls.items():
|
||||
efile.write(' | %d -> %s\n' % (i, k[3:]))
|
||||
# use Z3.Exception?
|
||||
efile.write(' | _ -> raise (Failure "undefined enum value")\n\n')
|
||||
mode = SEARCHING
|
||||
else:
|
||||
if words[2] != '':
|
||||
if len(words[2]) > 1 and words[2][1] == 'x':
|
||||
idx = int(words[2], 16)
|
||||
else:
|
||||
idx = int(words[2])
|
||||
decls[words[1]] = idx
|
||||
idx = idx + 1
|
||||
linenum = linenum + 1
|
||||
api.close()
|
||||
efile.close()
|
||||
full_path_api_files.append(api_file)
|
||||
generated_file = mk_genfile_common.mk_z3consts_ml_internal(
|
||||
full_path_api_files,
|
||||
ml.src_dir)
|
||||
if VERBOSE:
|
||||
print ('Generated "%s/z3enums.ml"' % ('%s' % gendir))
|
||||
# efile = open('%s.mli' % os.path.join(gendir, "z3enums"), 'w')
|
||||
# efile.write('(* Automatically generated file *)\n\n')
|
||||
# efile.write('(** The enumeration types of Z3. *)\n\n')
|
||||
# for api_file in api_files:
|
||||
# api_file_c = ml.find_file(api_file, ml.name)
|
||||
# api_file = os.path.join(api_file_c.src_dir, api_file)
|
||||
|
||||
# api = open(api_file, 'r')
|
||||
|
||||
# SEARCHING = 0
|
||||
# FOUND_ENUM = 1
|
||||
# IN_ENUM = 2
|
||||
|
||||
# mode = SEARCHING
|
||||
# decls = {}
|
||||
# idx = 0
|
||||
|
||||
# linenum = 1
|
||||
# for line in api:
|
||||
# m1 = blank_pat.match(line)
|
||||
# m2 = comment_pat.match(line)
|
||||
# if m1 or m2:
|
||||
# # skip blank lines and comments
|
||||
# linenum = linenum + 1
|
||||
# elif mode == SEARCHING:
|
||||
# m = typedef_pat.match(line)
|
||||
# if m:
|
||||
# mode = FOUND_ENUM
|
||||
# m = typedef2_pat.match(line)
|
||||
# if m:
|
||||
# mode = IN_ENUM
|
||||
# decls = {}
|
||||
# idx = 0
|
||||
# elif mode == FOUND_ENUM:
|
||||
# m = openbrace_pat.match(line)
|
||||
# if m:
|
||||
# mode = IN_ENUM
|
||||
# decls = {}
|
||||
# idx = 0
|
||||
# else:
|
||||
# assert False, "Invalid %s, line: %s" % (api_file, linenum)
|
||||
# else:
|
||||
# assert mode == IN_ENUM
|
||||
# words = re.split('[^\-a-zA-Z0-9_]+', line)
|
||||
# m = closebrace_pat.match(line)
|
||||
# if m:
|
||||
# name = words[1]
|
||||
# if name not in DeprecatedEnums:
|
||||
# efile.write('(** %s *)\n' % name[3:])
|
||||
# efile.write('type %s =\n' % name[3:]) # strip Z3_
|
||||
# for k, i in decls.items():
|
||||
# efile.write(' | %s \n' % k[3:]) # strip Z3_
|
||||
# efile.write('\n')
|
||||
# efile.write('(** Convert %s to int*)\n' % name[3:])
|
||||
# efile.write('val int_of_%s : %s -> int\n' % (name[3:], name[3:])) # strip Z3_
|
||||
# efile.write('(** Convert int to %s*)\n' % name[3:])
|
||||
# efile.write('val %s_of_int : int -> %s\n' % (name[3:],name[3:])) # strip Z3_
|
||||
# efile.write('\n')
|
||||
# mode = SEARCHING
|
||||
# else:
|
||||
# if words[2] != '':
|
||||
# if len(words[2]) > 1 and words[2][1] == 'x':
|
||||
# idx = int(words[2], 16)
|
||||
# else:
|
||||
# idx = int(words[2])
|
||||
# decls[words[1]] = idx
|
||||
# idx = idx + 1
|
||||
# linenum = linenum + 1
|
||||
# api.close()
|
||||
# efile.close()
|
||||
# if VERBOSE:
|
||||
# print ('Generated "%s/z3enums.mli"' % ('%s' % gendir))
|
||||
print ('Generated "%s"' % generated_file)
|
||||
|
||||
def mk_gui_str(id):
|
||||
return '4D2F40D8-E5F9-473B-B548-%012d' % id
|
||||
|
@ -2996,6 +2976,11 @@ def mk_vs_proj_property_groups(f, name, target_ext, type):
|
|||
f.write(' <CharacterSet>Unicode</CharacterSet>\n')
|
||||
f.write(' <UseOfMfc>false</UseOfMfc>\n')
|
||||
f.write(' </PropertyGroup>\n')
|
||||
f.write(' <PropertyGroup Condition="\'$(Configuration)|$(Platform)\'==\'Release|Win32\'" Label="Configuration">\n')
|
||||
f.write(' <ConfigurationType>%s</ConfigurationType>\n' % type)
|
||||
f.write(' <CharacterSet>Unicode</CharacterSet>\n')
|
||||
f.write(' <UseOfMfc>false</UseOfMfc>\n')
|
||||
f.write(' </PropertyGroup>\n')
|
||||
f.write(' <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\n')
|
||||
f.write(' <ImportGroup Label="ExtensionSettings" />\n')
|
||||
f.write(' <ImportGroup Label="PropertySheets">\n')
|
||||
|
@ -3145,11 +3130,6 @@ def mk_vs_proj_dll(name, components):
|
|||
def mk_win_dist(build_path, dist_path):
|
||||
for c in get_components():
|
||||
c.mk_win_dist(build_path, dist_path)
|
||||
# Add Z3Py to bin directory
|
||||
print("Adding to %s\n" % dist_path)
|
||||
for pyc in filter(lambda f: f.endswith('.pyc') or f.endswith('.py'), os.listdir(build_path)):
|
||||
shutil.copy(os.path.join(build_path, pyc),
|
||||
os.path.join(dist_path, INSTALL_BIN_DIR, pyc))
|
||||
|
||||
def mk_unix_dist(build_path, dist_path):
|
||||
for c in get_components():
|
||||
|
@ -3198,7 +3178,7 @@ class MakeRuleCmd(object):
|
|||
#print("WARNING: Generating makefile rule that {}s {} '{}' which is outside the installation prefix '{}'.".format(
|
||||
# action_string, 'to' if is_install else 'from', path, PREFIX))
|
||||
else:
|
||||
assert not os.path.isabs(path)
|
||||
# assert not os.path.isabs(path)
|
||||
install_root = cls.install_root()
|
||||
return install_root
|
||||
|
||||
|
|
|
@ -25,8 +25,13 @@ VERBOSE=True
|
|||
DIST_DIR='dist'
|
||||
FORCE_MK=False
|
||||
DOTNET_ENABLED=True
|
||||
DOTNET_KEY_FILE=None
|
||||
JAVA_ENABLED=True
|
||||
GIT_HASH=False
|
||||
PYTHON_ENABLED=True
|
||||
X86ONLY=False
|
||||
X64ONLY=False
|
||||
MAKEJOBS=getenv("MAKEJOBS", "24")
|
||||
|
||||
def set_verbose(flag):
|
||||
global VERBOSE
|
||||
|
@ -57,13 +62,17 @@ def display_help():
|
|||
print(" -b <sudir>, --build=<subdir> subdirectory where x86 and x64 Z3 versions will be built (default: build-dist).")
|
||||
print(" -f, --force force script to regenerate Makefiles.")
|
||||
print(" --nodotnet do not include .NET bindings in the binary distribution files.")
|
||||
print(" --dotnet-key=<file> sign the .NET assembly with the private key in <file>.")
|
||||
print(" --nojava do not include Java bindings in the binary distribution files.")
|
||||
print(" --nopython do not include Python bindings in the binary distribution files.")
|
||||
print(" --githash include git hash in the Zip file.")
|
||||
print(" --x86-only x86 dist only.")
|
||||
print(" --x64-only x64 dist only.")
|
||||
exit(0)
|
||||
|
||||
# Parse configuration option for mk_make script
|
||||
def parse_options():
|
||||
global FORCE_MK, JAVA_ENABLED, GIT_HASH, DOTNET_ENABLED
|
||||
global FORCE_MK, JAVA_ENABLED, GIT_HASH, DOTNET_ENABLED, DOTNET_KEY_FILE, PYTHON_ENABLED, X86ONLY, X64ONLY
|
||||
path = BUILD_DIR
|
||||
options, remainder = getopt.gnu_getopt(sys.argv[1:], 'b:hsf', ['build=',
|
||||
'help',
|
||||
|
@ -71,7 +80,11 @@ def parse_options():
|
|||
'force',
|
||||
'nojava',
|
||||
'nodotnet',
|
||||
'githash'
|
||||
'dotnet-key=',
|
||||
'githash',
|
||||
'nopython',
|
||||
'x86-only',
|
||||
'x64-only'
|
||||
])
|
||||
for opt, arg in options:
|
||||
if opt in ('-b', '--build'):
|
||||
|
@ -86,10 +99,18 @@ def parse_options():
|
|||
FORCE_MK = True
|
||||
elif opt == '--nodotnet':
|
||||
DOTNET_ENABLED = False
|
||||
elif opt == '--nopython':
|
||||
PYTHON_ENABLED = False
|
||||
elif opt == '--dotnet-key':
|
||||
DOTNET_KEY_FILE = arg
|
||||
elif opt == '--nojava':
|
||||
JAVA_ENABLED = False
|
||||
elif opt == '--githash':
|
||||
GIT_HASH = True
|
||||
elif opt == '--x86-only' and not X64ONLY:
|
||||
X86ONLY = True
|
||||
elif opt == '--x64-only' and not X86ONLY:
|
||||
X64ONLY = True
|
||||
else:
|
||||
raise MKException("Invalid command line option '%s'" % opt)
|
||||
set_build_dir(path)
|
||||
|
@ -101,15 +122,21 @@ def check_build_dir(path):
|
|||
# Create a build directory using mk_make.py
|
||||
def mk_build_dir(path, x64):
|
||||
if not check_build_dir(path) or FORCE_MK:
|
||||
opts = ["python", os.path.join('scripts', 'mk_make.py'), "--parallel=24", "-b", path]
|
||||
parallel = '--parallel=' + MAKEJOBS
|
||||
opts = ["python", os.path.join('scripts', 'mk_make.py'), parallel, "-b", path]
|
||||
if DOTNET_ENABLED:
|
||||
opts.append('--dotnet')
|
||||
if not DOTNET_KEY_FILE is None:
|
||||
opts.append('--dotnet-key=' + DOTNET_KEY_FILE)
|
||||
if JAVA_ENABLED:
|
||||
opts.append('--java')
|
||||
if x64:
|
||||
opts.append('-x')
|
||||
if GIT_HASH:
|
||||
opts.append('--githash=%s' % mk_util.git_hash())
|
||||
opts.append('--git-describe')
|
||||
if PYTHON_ENABLED:
|
||||
opts.append('--python')
|
||||
if subprocess.call(opts) != 0:
|
||||
raise MKException("Failed to generate build directory at '%s'" % path)
|
||||
|
||||
|
@ -145,7 +172,7 @@ def exec_cmds(cmds):
|
|||
return res
|
||||
|
||||
# Compile Z3 (if x64 == True, then it builds it in x64 mode).
|
||||
def mk_z3_core(x64):
|
||||
def mk_z3(x64):
|
||||
cmds = []
|
||||
if x64:
|
||||
cmds.append('call "%VCINSTALLDIR%vcvarsall.bat" amd64')
|
||||
|
@ -157,9 +184,9 @@ def mk_z3_core(x64):
|
|||
if exec_cmds(cmds) != 0:
|
||||
raise MKException("Failed to make z3, x64: %s" % x64)
|
||||
|
||||
def mk_z3():
|
||||
mk_z3_core(False)
|
||||
mk_z3_core(True)
|
||||
def mk_z3s():
|
||||
mk_z3(False)
|
||||
mk_z3(True)
|
||||
|
||||
def get_z3_name(x64):
|
||||
major, minor, build, revision = get_version()
|
||||
|
@ -172,7 +199,7 @@ def get_z3_name(x64):
|
|||
else:
|
||||
return 'z3-%s.%s.%s-%s-win' % (major, minor, build, platform)
|
||||
|
||||
def mk_dist_dir_core(x64):
|
||||
def mk_dist_dir(x64):
|
||||
if x64:
|
||||
platform = "x64"
|
||||
build_path = BUILD_X64_DIR
|
||||
|
@ -182,19 +209,21 @@ def mk_dist_dir_core(x64):
|
|||
dist_path = os.path.join(DIST_DIR, get_z3_name(x64))
|
||||
mk_dir(dist_path)
|
||||
mk_util.DOTNET_ENABLED = DOTNET_ENABLED
|
||||
mk_util.DOTNET_KEY_FILE = DOTNET_KEY_FILE
|
||||
mk_util.JAVA_ENABLED = JAVA_ENABLED
|
||||
mk_util.PYTHON_ENABLED = PYTHON_ENABLED
|
||||
mk_win_dist(build_path, dist_path)
|
||||
if is_verbose():
|
||||
print("Generated %s distribution folder at '%s'" % (platform, dist_path))
|
||||
|
||||
def mk_dist_dir():
|
||||
mk_dist_dir_core(False)
|
||||
mk_dist_dir_core(True)
|
||||
def mk_dist_dirs():
|
||||
mk_dist_dir(False)
|
||||
mk_dist_dir(True)
|
||||
|
||||
def get_dist_path(x64):
|
||||
return get_z3_name(x64)
|
||||
|
||||
def mk_zip_core(x64):
|
||||
def mk_zip(x64):
|
||||
dist_path = get_dist_path(x64)
|
||||
old = os.getcwd()
|
||||
try:
|
||||
|
@ -211,31 +240,17 @@ def mk_zip_core(x64):
|
|||
os.chdir(old)
|
||||
|
||||
# Create a zip file for each platform
|
||||
def mk_zip():
|
||||
mk_zip_core(False)
|
||||
mk_zip_core(True)
|
||||
def mk_zips():
|
||||
mk_zip(False)
|
||||
mk_zip(True)
|
||||
|
||||
|
||||
VS_RUNTIME_PATS = [re.compile('vcomp.*\.dll'),
|
||||
re.compile('msvcp.*\.dll'),
|
||||
re.compile('msvcr.*\.dll')]
|
||||
|
||||
VS_RUNTIME_FILES = []
|
||||
|
||||
def cp_vs_runtime_visitor(pattern, dir, files):
|
||||
global VS_RUNTIME_FILES
|
||||
for filename in files:
|
||||
for pat in VS_RUNTIME_PATS:
|
||||
if pat.match(filename):
|
||||
if fnmatch(filename, pattern):
|
||||
fname = os.path.join(dir, filename)
|
||||
if not os.path.isdir(fname):
|
||||
VS_RUNTIME_FILES.append(fname)
|
||||
break
|
||||
|
||||
# Copy Visual Studio Runtime libraries
|
||||
def cp_vs_runtime_core(x64):
|
||||
global VS_RUNTIME_FILES
|
||||
def cp_vs_runtime(x64):
|
||||
if x64:
|
||||
platform = "x64"
|
||||
|
||||
|
@ -244,34 +259,64 @@ def cp_vs_runtime_core(x64):
|
|||
vcdir = os.environ['VCINSTALLDIR']
|
||||
path = '%sredist\\%s' % (vcdir, platform)
|
||||
VS_RUNTIME_FILES = []
|
||||
os.walk(path, cp_vs_runtime_visitor, '*.dll')
|
||||
for root, dirs, files in os.walk(path):
|
||||
for filename in files:
|
||||
if fnmatch(filename, '*.dll'):
|
||||
for pat in VS_RUNTIME_PATS:
|
||||
if pat.match(filename):
|
||||
fname = os.path.join(root, filename)
|
||||
if not os.path.isdir(fname):
|
||||
VS_RUNTIME_FILES.append(fname)
|
||||
|
||||
bin_dist_path = os.path.join(DIST_DIR, get_dist_path(x64), 'bin')
|
||||
for f in VS_RUNTIME_FILES:
|
||||
shutil.copy(f, bin_dist_path)
|
||||
if is_verbose():
|
||||
print("Copied '%s' to '%s'" % (f, bin_dist_path))
|
||||
|
||||
def cp_vs_runtime():
|
||||
cp_vs_runtime_core(True)
|
||||
cp_vs_runtime_core(False)
|
||||
def cp_vs_runtimes():
|
||||
cp_vs_runtime(True)
|
||||
cp_vs_runtime(False)
|
||||
|
||||
def cp_license():
|
||||
shutil.copy("LICENSE.txt", os.path.join(DIST_DIR, get_dist_path(True)))
|
||||
shutil.copy("LICENSE.txt", os.path.join(DIST_DIR, get_dist_path(False)))
|
||||
def cp_license(x64):
|
||||
shutil.copy("LICENSE.txt", os.path.join(DIST_DIR, get_dist_path(x64)))
|
||||
|
||||
def cp_licenses():
|
||||
cp_license(True)
|
||||
cp_license(False)
|
||||
|
||||
# Entry point
|
||||
def main():
|
||||
if os.name != 'nt':
|
||||
raise MKException("This script is for Windows only")
|
||||
|
||||
parse_options()
|
||||
check_vc_cmd_prompt()
|
||||
mk_build_dirs()
|
||||
mk_z3()
|
||||
init_project_def()
|
||||
mk_dist_dir()
|
||||
cp_license()
|
||||
cp_vs_runtime()
|
||||
mk_zip()
|
||||
|
||||
if X86ONLY:
|
||||
mk_build_dir(BUILD_X86_DIR, False)
|
||||
mk_z3(False)
|
||||
init_project_def()
|
||||
mk_dist_dir(False)
|
||||
cp_license(False)
|
||||
cp_vs_runtime(False)
|
||||
mk_zip(False)
|
||||
elif X64ONLY:
|
||||
mk_build_dir(BUILD_X64_DIR, True)
|
||||
mk_z3(True)
|
||||
init_project_def()
|
||||
mk_dist_dir(True)
|
||||
cp_license(True)
|
||||
cp_vs_runtime(True)
|
||||
mk_zip(True)
|
||||
else:
|
||||
mk_build_dirs()
|
||||
mk_z3s()
|
||||
init_project_def()
|
||||
mk_dist_dirs()
|
||||
cp_licenses()
|
||||
cp_vs_runtimes()
|
||||
mk_zips()
|
||||
|
||||
main()
|
||||
|
||||
|
|
|
@ -363,9 +363,9 @@ def mk_dotnet(dotnet):
|
|||
dotnet.write(' {\n\n')
|
||||
dotnet.write(' [UnmanagedFunctionPointer(CallingConvention.Cdecl)]\n')
|
||||
dotnet.write(' public delegate void Z3_error_handler(Z3_context c, Z3_error_code e);\n\n')
|
||||
dotnet.write(' public unsafe class LIB\n')
|
||||
dotnet.write(' public class LIB\n')
|
||||
dotnet.write(' {\n')
|
||||
dotnet.write(' const string Z3_DLL_NAME = \"libz3.dll\";\n'
|
||||
dotnet.write(' const string Z3_DLL_NAME = \"libz3\";\n'
|
||||
' \n')
|
||||
dotnet.write(' [DllImport(Z3_DLL_NAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]\n')
|
||||
dotnet.write(' public extern static void Z3_set_error_handler(Z3_context a0, Z3_error_handler a1);\n\n')
|
||||
|
@ -942,7 +942,7 @@ def def_API(name, result, params):
|
|||
log_c.write(" Au(a%s);\n" % sz)
|
||||
exe_c.write("in.get_int_array(%s)" % i)
|
||||
else:
|
||||
error ("unsupported parameter for %s, %s" % (ty, name, p))
|
||||
error ("unsupported parameter for %s, %s, %s" % (ty, name, p))
|
||||
elif kind == OUT_ARRAY:
|
||||
sz = param_array_capacity_pos(p)
|
||||
sz_p = params[sz]
|
||||
|
@ -1195,13 +1195,13 @@ def ml_alloc_and_store(t, lhs, rhs):
|
|||
alloc_str = '%s = caml_alloc_custom(&%s, sizeof(%s), 0, 1); ' % (lhs, pops, pts)
|
||||
return alloc_str + ml_set_wrap(t, lhs, rhs)
|
||||
|
||||
def mk_ml(ml_dir):
|
||||
def mk_ml(ml_src_dir, ml_output_dir):
|
||||
global Type2Str
|
||||
ml_nativef = os.path.join(ml_dir, 'z3native.ml')
|
||||
ml_nativef = os.path.join(ml_output_dir, 'z3native.ml')
|
||||
ml_native = open(ml_nativef, 'w')
|
||||
ml_native.write('(* Automatically generated file *)\n\n')
|
||||
|
||||
ml_pref = open(os.path.join(ml_dir, 'z3native.ml.pre'), 'r')
|
||||
ml_pref = open(os.path.join(ml_src_dir, 'z3native.ml.pre'), 'r')
|
||||
for s in ml_pref:
|
||||
ml_native.write(s);
|
||||
ml_pref.close()
|
||||
|
@ -1250,14 +1250,14 @@ def mk_ml(ml_dir):
|
|||
if mk_util.is_verbose():
|
||||
print ('Generated "%s"' % ml_nativef)
|
||||
|
||||
mk_z3native_stubs_c(ml_dir)
|
||||
mk_z3native_stubs_c(ml_src_dir, ml_output_dir)
|
||||
|
||||
def mk_z3native_stubs_c(ml_dir): # C interface
|
||||
ml_wrapperf = os.path.join(ml_dir, 'z3native_stubs.c')
|
||||
def mk_z3native_stubs_c(ml_src_dir, ml_output_dir): # C interface
|
||||
ml_wrapperf = os.path.join(ml_output_dir, 'z3native_stubs.c')
|
||||
ml_wrapper = open(ml_wrapperf, 'w')
|
||||
ml_wrapper.write('// Automatically generated file\n\n')
|
||||
|
||||
ml_pref = open(os.path.join(ml_dir, 'z3native_stubs.c.pre'), 'r')
|
||||
ml_pref = open(os.path.join(ml_src_dir, 'z3native_stubs.c.pre'), 'r')
|
||||
for s in ml_pref:
|
||||
ml_wrapper.write(s);
|
||||
ml_pref.close()
|
||||
|
@ -1324,36 +1324,80 @@ def mk_z3native_stubs_c(ml_dir): # C interface
|
|||
if len(ap) > 0:
|
||||
ml_wrapper.write(' unsigned _i;\n')
|
||||
|
||||
# declare locals, preprocess arrays, strings, in/out arguments
|
||||
have_context = False
|
||||
# determine if the function has a context as parameter.
|
||||
have_context = (len(params) > 0) and (param_type(params[0]) == CONTEXT)
|
||||
|
||||
if have_context and name not in Unwrapped:
|
||||
ml_wrapper.write(' Z3_error_code ec;\n')
|
||||
|
||||
if result != VOID:
|
||||
ts = type2str(result)
|
||||
if ml_has_plus_type(ts):
|
||||
pts = ml_plus_type(ts)
|
||||
ml_wrapper.write(' %s z3rv_m;\n' % ts)
|
||||
ml_wrapper.write(' %s z3rv;\n' % pts)
|
||||
else:
|
||||
ml_wrapper.write(' %s z3rv;\n' % ts)
|
||||
|
||||
# declare all required local variables
|
||||
# To comply with C89, we need to first declare the variables and initialize them
|
||||
# only afterwards.
|
||||
i = 0
|
||||
for param in params:
|
||||
if param_type(param) == CONTEXT and i == 0:
|
||||
ml_wrapper.write(' Z3_context_plus ctx_p = *(Z3_context_plus*) Data_custom_val(a' + str(i) + ');\n')
|
||||
ml_wrapper.write(' Z3_context _a0 = ctx_p->ctx;\n')
|
||||
have_context = True
|
||||
ml_wrapper.write(' Z3_context_plus ctx_p;\n')
|
||||
ml_wrapper.write(' Z3_context _a0;\n')
|
||||
else:
|
||||
k = param_kind(param)
|
||||
if k == OUT_ARRAY:
|
||||
ml_wrapper.write(' %s * _a%s = (%s*) malloc(sizeof(%s) * (_a%s));\n' % (
|
||||
type2str(param_type(param)),
|
||||
ml_wrapper.write(' %s * _a%s;\n' % (type2str(param_type(param)), i))
|
||||
elif k == OUT_MANAGED_ARRAY:
|
||||
ml_wrapper.write(' %s * _a%s;\n' % (type2str(param_type(param)), i))
|
||||
elif k == IN_ARRAY or k == INOUT_ARRAY:
|
||||
t = param_type(param)
|
||||
ts = type2str(t)
|
||||
ml_wrapper.write(' %s * _a%s;\n' % (ts, i))
|
||||
elif k == IN:
|
||||
t = param_type(param)
|
||||
ml_wrapper.write(' %s _a%s;\n' % (type2str(t), i))
|
||||
elif k == OUT or k == INOUT:
|
||||
t = param_type(param)
|
||||
ml_wrapper.write(' %s _a%s;\n' % (type2str(t), i))
|
||||
ts = type2str(t)
|
||||
if ml_has_plus_type(ts):
|
||||
pts = ml_plus_type(ts)
|
||||
ml_wrapper.write(' %s _a%dp;\n' % (pts, i))
|
||||
i = i + 1
|
||||
|
||||
|
||||
# End of variable declarations in outermost block:
|
||||
# To comply with C89, no variable declarations may occur in the outermost block
|
||||
# from that point onwards (breaks builds with at least VC 2012 and prior)
|
||||
ml_wrapper.write('\n')
|
||||
|
||||
# Declare locals, preprocess arrays, strings, in/out arguments
|
||||
i = 0
|
||||
for param in params:
|
||||
if param_type(param) == CONTEXT and i == 0:
|
||||
ml_wrapper.write(' ctx_p = *(Z3_context_plus*) Data_custom_val(a' + str(i) + ');\n')
|
||||
ml_wrapper.write(' _a0 = ctx_p->ctx;\n')
|
||||
else:
|
||||
k = param_kind(param)
|
||||
if k == OUT_ARRAY:
|
||||
ml_wrapper.write(' _a%s = (%s*) malloc(sizeof(%s) * (_a%s));\n' % (
|
||||
i,
|
||||
type2str(param_type(param)),
|
||||
type2str(param_type(param)),
|
||||
param_array_capacity_pos(param)))
|
||||
elif k == OUT_MANAGED_ARRAY:
|
||||
ml_wrapper.write(' %s * _a%s = 0;\n' % (type2str(param_type(param)), i))
|
||||
ml_wrapper.write(' _a%s = 0;\n' % i)
|
||||
elif k == IN_ARRAY or k == INOUT_ARRAY:
|
||||
t = param_type(param)
|
||||
ts = type2str(t)
|
||||
ml_wrapper.write(' %s * _a%s = (%s*) malloc(sizeof(%s) * _a%s);\n' % (ts, i, ts, ts, param_array_capacity_pos(param)))
|
||||
ml_wrapper.write(' _a%s = (%s*) malloc(sizeof(%s) * _a%s);\n' % (i, ts, ts, param_array_capacity_pos(param)))
|
||||
elif k == IN:
|
||||
t = param_type(param)
|
||||
ml_wrapper.write(' %s _a%s = %s;\n' % (type2str(t), i, ml_unwrap(t, type2str(t), 'a' + str(i))))
|
||||
elif k == OUT:
|
||||
ml_wrapper.write(' %s _a%s;\n' % (type2str(param_type(param)), i))
|
||||
elif k == INOUT:
|
||||
ml_wrapper.write(' %s _a%s = a%s;\n' % (type2str(param_type(param)), i, i))
|
||||
ml_wrapper.write(' _a%s = %s;\n' % (i, ml_unwrap(t, type2str(t), 'a' + str(i))))
|
||||
i = i + 1
|
||||
|
||||
i = 0
|
||||
|
@ -1375,9 +1419,9 @@ def mk_z3native_stubs_c(ml_dir): # C interface
|
|||
if result != VOID:
|
||||
ts = type2str(result)
|
||||
if ml_has_plus_type(ts):
|
||||
ml_wrapper.write('%s z3rv_m = ' % ts)
|
||||
ml_wrapper.write('z3rv_m = ')
|
||||
else:
|
||||
ml_wrapper.write('%s z3rv = ' % ts)
|
||||
ml_wrapper.write('z3rv = ')
|
||||
|
||||
# invoke procedure
|
||||
ml_wrapper.write('%s(' % name)
|
||||
|
@ -1397,8 +1441,8 @@ def mk_z3native_stubs_c(ml_dir): # C interface
|
|||
ml_wrapper.write(');\n')
|
||||
|
||||
if have_context and name not in Unwrapped:
|
||||
ml_wrapper.write(' int ec = Z3_get_error_code(ctx_p->ctx);\n')
|
||||
ml_wrapper.write(' if (ec != 0) {\n')
|
||||
ml_wrapper.write(' ec = Z3_get_error_code(ctx_p->ctx);\n')
|
||||
ml_wrapper.write(' if (ec != Z3_OK) {\n')
|
||||
ml_wrapper.write(' const char * msg = Z3_get_error_msg(ctx_p->ctx, ec);\n')
|
||||
ml_wrapper.write(' caml_raise_with_string(*caml_named_value("Z3EXCEPTION"), msg);\n')
|
||||
ml_wrapper.write(' }\n')
|
||||
|
@ -1408,9 +1452,9 @@ def mk_z3native_stubs_c(ml_dir): # C interface
|
|||
if ml_has_plus_type(ts):
|
||||
pts = ml_plus_type(ts)
|
||||
if name in NULLWrapped:
|
||||
ml_wrapper.write(' %s z3rv = %s_mk(z3rv_m);\n' % (pts, pts))
|
||||
ml_wrapper.write(' z3rv = %s_mk(z3rv_m);\n' % pts)
|
||||
else:
|
||||
ml_wrapper.write(' %s z3rv = %s_mk(ctx_p, (%s) z3rv_m);\n' % (pts, pts, ml_minus_type(ts)))
|
||||
ml_wrapper.write(' z3rv = %s_mk(ctx_p, (%s) z3rv_m);\n' % (pts, ml_minus_type(ts)))
|
||||
|
||||
# convert output params
|
||||
if len(op) > 0:
|
||||
|
@ -1433,10 +1477,10 @@ def mk_z3native_stubs_c(ml_dir): # C interface
|
|||
pts = ml_plus_type(ts)
|
||||
pops = ml_plus_ops_type(ts)
|
||||
if ml_has_plus_type(ts):
|
||||
ml_wrapper.write(' %s _a%dp = %s_mk(ctx_p, (%s) _a%d[_i]);\n' % (pts, i, pts, ml_minus_type(ts), i))
|
||||
ml_wrapper.write(' %s _a%dp = %s_mk(ctx_p, (%s) _a%d[_i - 1]);\n' % (pts, i, pts, ml_minus_type(ts), i))
|
||||
ml_wrapper.write(' %s\n' % ml_alloc_and_store(pt, 'tmp_val', '_a%dp' % i))
|
||||
else:
|
||||
ml_wrapper.write(' %s\n' % ml_alloc_and_store(pt, 'tmp_val', '_a%d[_i]' % i))
|
||||
ml_wrapper.write(' %s\n' % ml_alloc_and_store(pt, 'tmp_val', '_a%d[_i - 1]' % i))
|
||||
ml_wrapper.write(' _iter = caml_alloc(2,0);\n')
|
||||
ml_wrapper.write(' Store_field(_iter, 0, tmp_val);\n')
|
||||
ml_wrapper.write(' Store_field(_iter, 1, _a%s_val);\n' % i)
|
||||
|
@ -1450,7 +1494,7 @@ def mk_z3native_stubs_c(ml_dir): # C interface
|
|||
elif is_out_param(p):
|
||||
if ml_has_plus_type(ts):
|
||||
pts = ml_plus_type(ts)
|
||||
ml_wrapper.write(' %s _a%dp = %s_mk(ctx_p, (%s) _a%d);\n' % (pts, i, pts, ml_minus_type(ts), i))
|
||||
ml_wrapper.write(' _a%dp = %s_mk(ctx_p, (%s) _a%d);\n' % (i, pts, ml_minus_type(ts), i))
|
||||
ml_wrapper.write(' %s\n' % ml_alloc_and_store(pt, '_a%d_val' % i, '_a%dp' % i))
|
||||
else:
|
||||
ml_wrapper.write(' %s\n' % ml_alloc_and_store(pt, '_a%d_val' % i, '_a%d' % i))
|
||||
|
@ -1530,6 +1574,7 @@ def write_log_h_preamble(log_h):
|
|||
log_h.write('#define _Z3_UNUSED\n')
|
||||
log_h.write('#endif\n')
|
||||
#
|
||||
log_h.write('#include<iostream>\n')
|
||||
log_h.write('extern std::ostream * g_z3_log;\n')
|
||||
log_h.write('extern bool g_z3_log_enabled;\n')
|
||||
log_h.write('class z3_log_ctx { bool m_prev; public: z3_log_ctx():m_prev(g_z3_log_enabled) { g_z3_log_enabled = false; } ~z3_log_ctx() { g_z3_log_enabled = m_prev; } bool enabled() const { return m_prev; } };\n')
|
||||
|
@ -1556,27 +1601,25 @@ def write_core_py_preamble(core_py):
|
|||
core_py.write('# Automatically generated file\n')
|
||||
core_py.write('import sys, os\n')
|
||||
core_py.write('import ctypes\n')
|
||||
core_py.write('from z3types import *\n')
|
||||
core_py.write('from z3consts import *\n')
|
||||
core_py.write('import pkg_resources\n')
|
||||
core_py.write('from .z3types import *\n')
|
||||
core_py.write('from .z3consts import *\n')
|
||||
core_py.write(
|
||||
"""
|
||||
_ext = 'dll' if sys.platform in ('win32', 'cygwin') else 'dylib' if sys.platform == 'darwin' else 'so'
|
||||
|
||||
_lib = None
|
||||
def lib():
|
||||
global _lib
|
||||
if _lib == None:
|
||||
_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
for ext in ['dll', 'so', 'dylib']:
|
||||
if _lib is None:
|
||||
_dirs = ['.', os.path.dirname(os.path.abspath(__file__)), pkg_resources.resource_filename('z3', 'lib'), os.path.join(sys.prefix, 'lib'), None]
|
||||
for _dir in _dirs:
|
||||
try:
|
||||
init('libz3.%s' % ext)
|
||||
init(_dir)
|
||||
break
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
init(os.path.join(_dir, 'libz3.%s' % ext))
|
||||
break
|
||||
except:
|
||||
pass
|
||||
if _lib == None:
|
||||
if _lib is None:
|
||||
raise Z3Exception("init(Z3_LIBRARY_PATH) must be invoked before using Z3-python")
|
||||
return _lib
|
||||
|
||||
|
@ -1599,6 +1642,13 @@ else:
|
|||
return ""
|
||||
|
||||
def init(PATH):
|
||||
if PATH:
|
||||
PATH = os.path.realpath(PATH)
|
||||
if os.path.isdir(PATH):
|
||||
PATH = os.path.join(PATH, 'libz3.%s' % _ext)
|
||||
else:
|
||||
PATH = 'libz3.%s' % _ext
|
||||
|
||||
global _lib
|
||||
_lib = ctypes.CDLL(PATH)
|
||||
"""
|
||||
|
@ -1617,7 +1667,8 @@ def generate_files(api_files,
|
|||
dotnet_output_dir=None,
|
||||
java_output_dir=None,
|
||||
java_package_name=None,
|
||||
ml_output_dir=None):
|
||||
ml_output_dir=None,
|
||||
ml_src_dir=None):
|
||||
"""
|
||||
Scan the api files in ``api_files`` and emit the relevant API files into
|
||||
the output directories specified. If an output directory is set to ``None``
|
||||
|
@ -1662,7 +1713,7 @@ def generate_files(api_files,
|
|||
with mk_file_or_temp(api_output_dir, 'api_log_macros.h') as log_h:
|
||||
with mk_file_or_temp(api_output_dir, 'api_log_macros.cpp') as log_c:
|
||||
with mk_file_or_temp(api_output_dir, 'api_commands.cpp') as exe_c:
|
||||
with mk_file_or_temp(z3py_output_dir, 'z3core.py') as core_py:
|
||||
with mk_file_or_temp(z3py_output_dir, os.path.join('z3', 'z3core.py')) as core_py:
|
||||
# Write preambles
|
||||
write_log_h_preamble(log_h)
|
||||
write_log_c_preamble(log_c)
|
||||
|
@ -1692,7 +1743,8 @@ def generate_files(api_files,
|
|||
mk_java(java_output_dir, java_package_name)
|
||||
|
||||
if ml_output_dir:
|
||||
mk_ml(ml_output_dir)
|
||||
assert not ml_src_dir is None
|
||||
mk_ml(ml_src_dir, ml_output_dir)
|
||||
|
||||
def main(args):
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
@ -1719,6 +1771,10 @@ def main(args):
|
|||
dest="java_package_name",
|
||||
default=None,
|
||||
help="Name to give the Java package (e.g. ``com.microsoft.z3``).")
|
||||
parser.add_argument("--ml-src-dir",
|
||||
dest="ml_src_dir",
|
||||
default=None,
|
||||
help="Directory containing OCaml source files. If not specified no files are emitted")
|
||||
parser.add_argument("--ml-output-dir",
|
||||
dest="ml_output_dir",
|
||||
default=None,
|
||||
|
@ -1730,6 +1786,11 @@ def main(args):
|
|||
logging.error('--java-package-name must be specified')
|
||||
return 1
|
||||
|
||||
if pargs.ml_output_dir:
|
||||
if pargs.ml_src_dir is None:
|
||||
logging.error('--ml-src-dir must be specified')
|
||||
return 1
|
||||
|
||||
for api_file in pargs.api_files:
|
||||
if not os.path.exists(api_file):
|
||||
logging.error('"{}" does not exist'.format(api_file))
|
||||
|
@ -1741,7 +1802,8 @@ def main(args):
|
|||
dotnet_output_dir=pargs.dotnet_output_dir,
|
||||
java_output_dir=pargs.java_output_dir,
|
||||
java_package_name=pargs.java_package_name,
|
||||
ml_output_dir=pargs.ml_output_dir)
|
||||
ml_output_dir=pargs.ml_output_dir,
|
||||
ml_src_dir=pargs.ml_src_dir)
|
||||
return 0
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -20,6 +20,7 @@ Revision History:
|
|||
#include"ast.h"
|
||||
#include"ref.h"
|
||||
#include"expr_replacer.h"
|
||||
#include"ast_translation.h"
|
||||
|
||||
/** \brief
|
||||
Information about how a formula is being converted into
|
||||
|
@ -35,7 +36,6 @@ class ackr_info {
|
|||
public:
|
||||
ackr_info(ast_manager& m)
|
||||
: m_m(m)
|
||||
, m_consts(m)
|
||||
, m_er(mk_default_expr_replacer(m))
|
||||
, m_subst(m_m)
|
||||
, m_ref_count(0)
|
||||
|
@ -43,16 +43,20 @@ class ackr_info {
|
|||
{}
|
||||
|
||||
virtual ~ackr_info() {
|
||||
m_consts.reset();
|
||||
for (t2ct::iterator i = m_t2c.begin(); i != m_t2c.end(); ++i) {
|
||||
m_m.dec_ref(i->m_key);
|
||||
m_m.dec_ref(i->m_value);
|
||||
}
|
||||
}
|
||||
|
||||
inline void set_abstr(app* term, app* c) {
|
||||
SASSERT(!m_sealed);
|
||||
SASSERT(c);
|
||||
SASSERT(c && term);
|
||||
m_t2c.insert(term,c);
|
||||
m_c2t.insert(c->get_decl(),term);
|
||||
m_subst.insert(term, c);
|
||||
m_consts.push_back(c);
|
||||
m_m.inc_ref(term);
|
||||
m_m.inc_ref(c);
|
||||
}
|
||||
|
||||
inline void abstract(expr * e, expr_ref& res) {
|
||||
|
@ -77,6 +81,17 @@ class ackr_info {
|
|||
m_er->set_substitution(&m_subst);
|
||||
}
|
||||
|
||||
virtual ackr_info * translate(ast_translation & translator) {
|
||||
ackr_info * const retv = alloc(ackr_info, translator.to());
|
||||
for (t2ct::iterator i = m_t2c.begin(); i != m_t2c.end(); ++i) {
|
||||
app * const k = translator(i->m_key);
|
||||
app * const v = translator(i->m_value);
|
||||
retv->set_abstr(k, v);
|
||||
}
|
||||
if (m_sealed) retv->seal();
|
||||
return retv;
|
||||
}
|
||||
|
||||
//
|
||||
// Reference counting
|
||||
//
|
||||
|
@ -94,7 +109,6 @@ class ackr_info {
|
|||
|
||||
t2ct m_t2c; // terms to constants
|
||||
c2tt m_c2t; // constants to terms (inversion of m_t2c)
|
||||
expr_ref_vector m_consts; // the constants introduced during abstraction
|
||||
|
||||
// replacer and substitution used to compute abstractions
|
||||
scoped_ptr<expr_replacer> m_er;
|
||||
|
|
|
@ -53,7 +53,16 @@ public:
|
|||
|
||||
//void display(std::ostream & out);
|
||||
|
||||
virtual model_converter * translate(ast_translation & translator) {NOT_IMPLEMENTED_YET();}
|
||||
virtual model_converter * translate(ast_translation & translator) {
|
||||
ackr_info_ref retv_info = info->translate(translator);
|
||||
if (fixed_model) {
|
||||
model_ref retv_mod_ref = abstr_model->translate(translator);
|
||||
return alloc(ackr_model_converter, translator.to(), retv_info, retv_mod_ref);
|
||||
}
|
||||
else {
|
||||
return alloc(ackr_model_converter, translator.to(), retv_info);
|
||||
}
|
||||
}
|
||||
protected:
|
||||
ast_manager& m;
|
||||
const ackr_info_ref info;
|
||||
|
|
|
@ -7,7 +7,7 @@ Module Name:
|
|||
|
||||
Abstract:
|
||||
|
||||
Additional APIs for handling Z3 algebraic numbers encoded as
|
||||
Additional APIs for handling Z3 algebraic numbers encoded as
|
||||
Z3_ASTs
|
||||
|
||||
Author:
|
||||
|
@ -15,9 +15,8 @@ Author:
|
|||
Leonardo de Moura (leonardo) 2012-12-07
|
||||
|
||||
Notes:
|
||||
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
|
@ -74,9 +73,9 @@ extern "C" {
|
|||
|
||||
bool Z3_algebraic_is_value_core(Z3_context c, Z3_ast a) {
|
||||
api::context * _c = mk_c(c);
|
||||
return
|
||||
is_expr(a) &&
|
||||
(_c->autil().is_numeral(to_expr(a)) ||
|
||||
return
|
||||
is_expr(a) &&
|
||||
(_c->autil().is_numeral(to_expr(a)) ||
|
||||
_c->autil().is_irrational_algebraic_numeral(to_expr(a)));
|
||||
}
|
||||
|
||||
|
@ -162,9 +161,9 @@ extern "C" {
|
|||
Z3_ast Z3_API Z3_algebraic_add(Z3_context c, Z3_ast a, Z3_ast b) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_algebraic_add(c, a, b);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_IS_ALGEBRAIC_X(a, 0);
|
||||
CHECK_IS_ALGEBRAIC_X(b, 0);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_IS_ALGEBRAIC_X(a, 0);
|
||||
CHECK_IS_ALGEBRAIC_X(b, 0);
|
||||
BIN_OP(+,add);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
@ -172,9 +171,9 @@ extern "C" {
|
|||
Z3_ast Z3_API Z3_algebraic_sub(Z3_context c, Z3_ast a, Z3_ast b) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_algebraic_sub(c, a, b);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_IS_ALGEBRAIC_X(a, 0);
|
||||
CHECK_IS_ALGEBRAIC_X(b, 0);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_IS_ALGEBRAIC_X(a, 0);
|
||||
CHECK_IS_ALGEBRAIC_X(b, 0);
|
||||
BIN_OP(-,sub);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
@ -182,9 +181,9 @@ extern "C" {
|
|||
Z3_ast Z3_API Z3_algebraic_mul(Z3_context c, Z3_ast a, Z3_ast b) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_algebraic_mul(c, a, b);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_IS_ALGEBRAIC_X(a, 0);
|
||||
CHECK_IS_ALGEBRAIC_X(b, 0);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_IS_ALGEBRAIC_X(a, 0);
|
||||
CHECK_IS_ALGEBRAIC_X(b, 0);
|
||||
BIN_OP(*,mul);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
@ -219,8 +218,8 @@ extern "C" {
|
|||
algebraic_numbers::manager & _am = am(c);
|
||||
scoped_anum _r(_am);
|
||||
if (is_rational(c, a)) {
|
||||
scoped_anum av(_am);
|
||||
_am.set(av, get_rational(c, a).to_mpq());
|
||||
scoped_anum av(_am);
|
||||
_am.set(av, get_rational(c, a).to_mpq());
|
||||
_am.root(av, k, _r);
|
||||
}
|
||||
else {
|
||||
|
@ -241,8 +240,8 @@ extern "C" {
|
|||
algebraic_numbers::manager & _am = am(c);
|
||||
scoped_anum _r(_am);
|
||||
if (is_rational(c, a)) {
|
||||
scoped_anum av(_am);
|
||||
_am.set(av, get_rational(c, a).to_mpq());
|
||||
scoped_anum av(_am);
|
||||
_am.set(av, get_rational(c, a).to_mpq());
|
||||
_am.power(av, k, _r);
|
||||
}
|
||||
else {
|
||||
|
@ -328,7 +327,7 @@ extern "C" {
|
|||
scoped_anum tmp(_am);
|
||||
for (unsigned i = 0; i < n; i++) {
|
||||
if (is_rational(c, a[i])) {
|
||||
_am.set(tmp, get_rational(c, a[i]).to_mpq());
|
||||
_am.set(tmp, get_rational(c, a[i]).to_mpq());
|
||||
as.push_back(tmp);
|
||||
}
|
||||
else if (is_irrational(c, a[i])) {
|
||||
|
@ -378,7 +377,7 @@ extern "C" {
|
|||
vector_var2anum v2a(as);
|
||||
_am.isolate_roots(_p, v2a, roots);
|
||||
}
|
||||
Z3_ast_vector_ref* result = alloc(Z3_ast_vector_ref, mk_c(c)->m());
|
||||
Z3_ast_vector_ref* result = alloc(Z3_ast_vector_ref, *mk_c(c), mk_c(c)->m());
|
||||
mk_c(c)->save_object(result);
|
||||
for (unsigned i = 0; i < roots.size(); i++) {
|
||||
result->m_ast_vector.push_back(au(c).mk_numeral(roots.get(i), false));
|
||||
|
|
|
@ -15,7 +15,6 @@ Author:
|
|||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
|
@ -37,7 +36,7 @@ extern "C" {
|
|||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
Z3_sort Z3_API Z3_mk_real_sort(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_real_sort(c);
|
||||
|
@ -50,7 +49,7 @@ extern "C" {
|
|||
Z3_ast Z3_API Z3_mk_real(Z3_context c, int num, int den) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_real(c, num, den);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
if (den == 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
|
@ -60,7 +59,7 @@ extern "C" {
|
|||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
MK_ARITH_OP(Z3_mk_add, OP_ADD);
|
||||
MK_ARITH_OP(Z3_mk_mul, OP_MUL);
|
||||
MK_BINARY_ARITH_OP(Z3_mk_power, OP_POWER);
|
||||
|
@ -70,17 +69,17 @@ extern "C" {
|
|||
Z3_ast Z3_API Z3_mk_div(Z3_context c, Z3_ast n1, Z3_ast n2) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_div(c, n1, n2);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
decl_kind k = OP_IDIV;
|
||||
sort* ty = mk_c(c)->m().get_sort(to_expr(n1));
|
||||
sort* real_ty = mk_c(c)->m().mk_sort(mk_c(c)->get_arith_fid(), REAL_SORT);
|
||||
if (ty == real_ty) {
|
||||
k = OP_DIV;
|
||||
}
|
||||
expr * args[2] = { to_expr(n1), to_expr(n2) };
|
||||
ast* a = mk_c(c)->m().mk_app(mk_c(c)->get_arith_fid(), k, 0, 0, 2, args);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
check_sorts(c, a);
|
||||
expr * args[2] = { to_expr(n1), to_expr(n2) };
|
||||
ast* a = mk_c(c)->m().mk_app(mk_c(c)->get_arith_fid(), k, 0, 0, 2, args);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
check_sorts(c, a);
|
||||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
@ -142,7 +141,7 @@ extern "C" {
|
|||
rational l;
|
||||
mk_c(c)->autil().am().get_lower(val, l, precision);
|
||||
expr * r = mk_c(c)->autil().mk_numeral(l, false);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
RETURN_Z3(of_expr(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
@ -160,7 +159,7 @@ extern "C" {
|
|||
rational l;
|
||||
mk_c(c)->autil().am().get_upper(val, l, precision);
|
||||
expr * r = mk_c(c)->autil().mk_numeral(l, false);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
RETURN_Z3(of_expr(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
@ -176,7 +175,7 @@ extern "C" {
|
|||
RETURN_Z3(0);
|
||||
}
|
||||
expr * r = mk_c(c)->autil().mk_numeral(numerator(val), true);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
RETURN_Z3(of_expr(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
@ -192,7 +191,7 @@ extern "C" {
|
|||
RETURN_Z3(0);
|
||||
}
|
||||
expr * r = mk_c(c)->autil().mk_numeral(denominator(val), true);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
RETURN_Z3(of_expr(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ Author:
|
|||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
|
@ -27,7 +26,7 @@ extern "C" {
|
|||
Z3_sort Z3_API Z3_mk_array_sort(Z3_context c, Z3_sort domain, Z3_sort range) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_array_sort(c, domain, range);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
parameter params[2] = { parameter(to_sort(domain)), parameter(to_sort(range)) };
|
||||
sort * ty = mk_c(c)->m().mk_sort(mk_c(c)->get_array_fid(), ARRAY_SORT, 2, params);
|
||||
mk_c(c)->save_ast_trail(ty);
|
||||
|
@ -57,7 +56,7 @@ extern "C" {
|
|||
RETURN_Z3(of_ast(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
Z3_ast Z3_API Z3_mk_store(Z3_context c, Z3_ast a, Z3_ast i, Z3_ast v) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_store(c, a, i, v);
|
||||
|
@ -82,7 +81,7 @@ extern "C" {
|
|||
RETURN_Z3(of_ast(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
Z3_ast Z3_API Z3_mk_map(Z3_context c, Z3_func_decl f, unsigned n, Z3_ast const* args) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_map(c, f, n, args);
|
||||
|
@ -94,7 +93,7 @@ extern "C" {
|
|||
ast_manager & m = mk_c(c)->m();
|
||||
func_decl* _f = to_func_decl(f);
|
||||
expr* const* _args = to_exprs(args);
|
||||
|
||||
|
||||
ptr_vector<sort> domain;
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
domain.push_back(m.get_sort(_args[i]));
|
||||
|
@ -111,7 +110,7 @@ extern "C" {
|
|||
Z3_ast Z3_API Z3_mk_const_array(Z3_context c, Z3_sort domain, Z3_ast v) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_const_array(c, domain, v);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager & m = mk_c(c)->m();
|
||||
expr * _v = to_expr(v);
|
||||
sort * _range = m.get_sort(_v);
|
||||
|
@ -123,14 +122,14 @@ extern "C" {
|
|||
app * r = m.mk_app(cd, 1, &_v);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
check_sorts(c, r);
|
||||
RETURN_Z3(of_ast(r));
|
||||
RETURN_Z3(of_ast(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_array_default(Z3_context c, Z3_ast array) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_array_default(c, array);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager & m = mk_c(c)->m();
|
||||
expr * _a = to_expr(array);
|
||||
|
||||
|
@ -138,12 +137,12 @@ extern "C" {
|
|||
app * r = m.mk_app(f, 1, &_a);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
check_sorts(c, r);
|
||||
RETURN_Z3(of_ast(r));
|
||||
RETURN_Z3(of_ast(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast mk_app_array_core(Z3_context c, Z3_sort domain, Z3_ast v) {
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager & m = mk_c(c)->m();
|
||||
expr * _v = to_expr(v);
|
||||
sort * _range = m.get_sort(_v);
|
||||
|
@ -178,7 +177,7 @@ extern "C" {
|
|||
LOG_Z3_mk_full_set(c, domain);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_ast r = mk_app_array_core(c, domain, Z3_mk_true(c));
|
||||
RETURN_Z3(r);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
@ -205,8 +204,8 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_get_array_sort_domain(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_VALID_AST(t, 0);
|
||||
if (to_sort(t)->get_family_id() == mk_c(c)->get_array_fid() &&
|
||||
CHECK_VALID_AST(t, 0);
|
||||
if (to_sort(t)->get_family_id() == mk_c(c)->get_array_fid() &&
|
||||
to_sort(t)->get_decl_kind() == ARRAY_SORT) {
|
||||
Z3_sort r = reinterpret_cast<Z3_sort>(to_sort(t)->get_parameter(0).get_ast());
|
||||
RETURN_Z3(r);
|
||||
|
@ -215,13 +214,13 @@ extern "C" {
|
|||
RETURN_Z3(0);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
Z3_sort Z3_API Z3_get_array_sort_range(Z3_context c, Z3_sort t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_array_sort_range(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_VALID_AST(t, 0);
|
||||
if (to_sort(t)->get_family_id() == mk_c(c)->get_array_fid() &&
|
||||
if (to_sort(t)->get_family_id() == mk_c(c)->get_array_fid() &&
|
||||
to_sort(t)->get_decl_kind() == ARRAY_SORT) {
|
||||
Z3_sort r = reinterpret_cast<Z3_sort>(to_sort(t)->get_parameter(1).get_ast());
|
||||
RETURN_Z3(r);
|
||||
|
|
|
@ -335,7 +335,7 @@ extern "C" {
|
|||
Z3_bool Z3_API Z3_is_app(Z3_context c, Z3_ast a) {
|
||||
LOG_Z3_is_app(c, a);
|
||||
RESET_ERROR_CODE();
|
||||
return is_app(reinterpret_cast<ast*>(a));
|
||||
return a != 0 && is_app(reinterpret_cast<ast*>(a));
|
||||
}
|
||||
|
||||
Z3_app Z3_API Z3_to_app(Z3_context c, Z3_ast a) {
|
||||
|
@ -727,7 +727,7 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_simplify_get_param_descrs(c);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_param_descrs_ref * d = alloc(Z3_param_descrs_ref);
|
||||
Z3_param_descrs_ref * d = alloc(Z3_param_descrs_ref, *mk_c(c));
|
||||
mk_c(c)->save_object(d);
|
||||
th_rewriter::get_param_descrs(d->m_descrs);
|
||||
Z3_param_descrs r = of_param_descrs(d);
|
||||
|
@ -970,8 +970,7 @@ extern "C" {
|
|||
case PR_TH_LEMMA: return Z3_OP_PR_TH_LEMMA;
|
||||
case PR_HYPER_RESOLVE: return Z3_OP_PR_HYPER_RESOLVE;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return Z3_OP_UNINTERPRETED;
|
||||
return Z3_OP_INTERNAL;
|
||||
}
|
||||
}
|
||||
if (mk_c(c)->get_arith_fid() == _d->get_family_id()) {
|
||||
|
@ -995,8 +994,7 @@ extern "C" {
|
|||
case OP_TO_INT: return Z3_OP_TO_INT;
|
||||
case OP_IS_INT: return Z3_OP_IS_INT;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return Z3_OP_UNINTERPRETED;
|
||||
return Z3_OP_INTERNAL;
|
||||
}
|
||||
}
|
||||
if (mk_c(c)->get_array_fid() == _d->get_family_id()) {
|
||||
|
@ -1014,8 +1012,7 @@ extern "C" {
|
|||
case OP_AS_ARRAY: return Z3_OP_AS_ARRAY;
|
||||
case OP_ARRAY_EXT: return Z3_OP_ARRAY_EXT;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return Z3_OP_UNINTERPRETED;
|
||||
return Z3_OP_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1072,17 +1069,17 @@ extern "C" {
|
|||
case OP_BV2INT: return Z3_OP_BV2INT;
|
||||
case OP_CARRY: return Z3_OP_CARRY;
|
||||
case OP_XOR3: return Z3_OP_XOR3;
|
||||
case OP_BIT2BOOL: return Z3_OP_BIT2BOOL;
|
||||
case OP_BSMUL_NO_OVFL: return Z3_OP_BSMUL_NO_OVFL;
|
||||
case OP_BUMUL_NO_OVFL: return Z3_OP_BUMUL_NO_OVFL;
|
||||
case OP_BSMUL_NO_UDFL: return Z3_OP_BSMUL_NO_UDFL;
|
||||
case OP_BSMUL_NO_UDFL: return Z3_OP_BSMUL_NO_UDFL;
|
||||
case OP_BSDIV_I: return Z3_OP_BSDIV_I;
|
||||
case OP_BUDIV_I: return Z3_OP_BUDIV_I;
|
||||
case OP_BSREM_I: return Z3_OP_BSREM_I;
|
||||
case OP_BUREM_I: return Z3_OP_BUREM_I;
|
||||
case OP_BSMOD_I: return Z3_OP_BSMOD_I;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return Z3_OP_UNINTERPRETED;
|
||||
return Z3_OP_INTERNAL;
|
||||
}
|
||||
}
|
||||
if (mk_c(c)->get_dt_fid() == _d->get_family_id()) {
|
||||
|
@ -1092,8 +1089,7 @@ extern "C" {
|
|||
case OP_DT_ACCESSOR: return Z3_OP_DT_ACCESSOR;
|
||||
case OP_DT_UPDATE_FIELD: return Z3_OP_DT_UPDATE_FIELD;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return Z3_OP_UNINTERPRETED;
|
||||
return Z3_OP_INTERNAL;
|
||||
}
|
||||
}
|
||||
if (mk_c(c)->get_datalog_fid() == _d->get_family_id()) {
|
||||
|
@ -1114,34 +1110,40 @@ extern "C" {
|
|||
case datalog::OP_DL_CONSTANT: return Z3_OP_FD_CONSTANT;
|
||||
case datalog::OP_DL_LT: return Z3_OP_FD_LT;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return Z3_OP_UNINTERPRETED;
|
||||
return Z3_OP_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (mk_c(c)->get_seq_fid() == _d->get_family_id()) {
|
||||
switch (_d->get_decl_kind()) {
|
||||
case Z3_OP_SEQ_UNIT: return Z3_OP_SEQ_UNIT;
|
||||
case Z3_OP_SEQ_EMPTY: return Z3_OP_SEQ_EMPTY;
|
||||
case Z3_OP_SEQ_CONCAT: return Z3_OP_SEQ_CONCAT;
|
||||
case Z3_OP_SEQ_PREFIX: return Z3_OP_SEQ_PREFIX;
|
||||
case Z3_OP_SEQ_SUFFIX: return Z3_OP_SEQ_SUFFIX;
|
||||
case Z3_OP_SEQ_CONTAINS: return Z3_OP_SEQ_CONTAINS;
|
||||
case Z3_OP_SEQ_EXTRACT: return Z3_OP_SEQ_EXTRACT;
|
||||
case Z3_OP_SEQ_REPLACE: return Z3_OP_SEQ_REPLACE;
|
||||
case Z3_OP_SEQ_AT: return Z3_OP_SEQ_AT;
|
||||
case Z3_OP_SEQ_LENGTH: return Z3_OP_SEQ_LENGTH;
|
||||
case Z3_OP_SEQ_INDEX: return Z3_OP_SEQ_INDEX;
|
||||
case Z3_OP_SEQ_TO_RE: return Z3_OP_SEQ_TO_RE;
|
||||
case Z3_OP_SEQ_IN_RE: return Z3_OP_SEQ_IN_RE;
|
||||
case OP_SEQ_UNIT: return Z3_OP_SEQ_UNIT;
|
||||
case OP_SEQ_EMPTY: return Z3_OP_SEQ_EMPTY;
|
||||
case OP_SEQ_CONCAT: return Z3_OP_SEQ_CONCAT;
|
||||
case OP_SEQ_PREFIX: return Z3_OP_SEQ_PREFIX;
|
||||
case OP_SEQ_SUFFIX: return Z3_OP_SEQ_SUFFIX;
|
||||
case OP_SEQ_CONTAINS: return Z3_OP_SEQ_CONTAINS;
|
||||
case OP_SEQ_EXTRACT: return Z3_OP_SEQ_EXTRACT;
|
||||
case OP_SEQ_REPLACE: return Z3_OP_SEQ_REPLACE;
|
||||
case OP_SEQ_AT: return Z3_OP_SEQ_AT;
|
||||
case OP_SEQ_LENGTH: return Z3_OP_SEQ_LENGTH;
|
||||
case OP_SEQ_INDEX: return Z3_OP_SEQ_INDEX;
|
||||
case OP_SEQ_TO_RE: return Z3_OP_SEQ_TO_RE;
|
||||
case OP_SEQ_IN_RE: return Z3_OP_SEQ_IN_RE;
|
||||
|
||||
case Z3_OP_RE_PLUS: return Z3_OP_RE_PLUS;
|
||||
case Z3_OP_RE_STAR: return Z3_OP_RE_STAR;
|
||||
case Z3_OP_RE_OPTION: return Z3_OP_RE_OPTION;
|
||||
case Z3_OP_RE_CONCAT: return Z3_OP_RE_CONCAT;
|
||||
case Z3_OP_RE_UNION: return Z3_OP_RE_UNION;
|
||||
case OP_STRING_STOI: return Z3_OP_STR_TO_INT;
|
||||
case OP_STRING_ITOS: return Z3_OP_INT_TO_STR;
|
||||
|
||||
case OP_RE_PLUS: return Z3_OP_RE_PLUS;
|
||||
case OP_RE_STAR: return Z3_OP_RE_STAR;
|
||||
case OP_RE_OPTION: return Z3_OP_RE_OPTION;
|
||||
case OP_RE_CONCAT: return Z3_OP_RE_CONCAT;
|
||||
case OP_RE_UNION: return Z3_OP_RE_UNION;
|
||||
case OP_RE_INTERSECT: return Z3_OP_RE_INTERSECT;
|
||||
case OP_RE_LOOP: return Z3_OP_RE_LOOP;
|
||||
case OP_RE_FULL_SET: return Z3_OP_RE_FULL_SET;
|
||||
case OP_RE_EMPTY_SET: return Z3_OP_RE_EMPTY_SET;
|
||||
default:
|
||||
return Z3_OP_UNINTERPRETED;
|
||||
return Z3_OP_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1211,8 +1213,7 @@ extern "C" {
|
|||
case OP_FPA_INTERNAL_TO_IEEE_BV_UNSPECIFIED:
|
||||
return Z3_OP_UNINTERPRETED;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return Z3_OP_UNINTERPRETED;
|
||||
return Z3_OP_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1221,8 +1222,7 @@ extern "C" {
|
|||
case OP_LABEL: return Z3_OP_LABEL;
|
||||
case OP_LABEL_LIT: return Z3_OP_LABEL_LIT;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return Z3_OP_UNINTERPRETED;
|
||||
return Z3_OP_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1230,8 +1230,10 @@ extern "C" {
|
|||
switch(_d->get_decl_kind()) {
|
||||
case OP_PB_LE: return Z3_OP_PB_LE;
|
||||
case OP_PB_GE: return Z3_OP_PB_GE;
|
||||
case OP_PB_EQ: return Z3_OP_PB_EQ;
|
||||
case OP_AT_MOST_K: return Z3_OP_PB_AT_MOST;
|
||||
default: UNREACHABLE();
|
||||
case OP_AT_LEAST_K: return Z3_OP_PB_AT_LEAST;
|
||||
default: return Z3_OP_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_mk_ast_map(c);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_ast_map_ref * m = alloc(Z3_ast_map_ref, mk_c(c)->m());
|
||||
Z3_ast_map_ref * m = alloc(Z3_ast_map_ref, *mk_c(c), mk_c(c)->m());
|
||||
mk_c(c)->save_object(m);
|
||||
Z3_ast_map r = of_ast_map(m);
|
||||
RETURN_Z3(r);
|
||||
|
@ -137,7 +137,7 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_ast_map_keys(c, m);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, to_ast_map(m)->m);
|
||||
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, *mk_c(c), to_ast_map(m)->m);
|
||||
mk_c(c)->save_object(v);
|
||||
obj_map<ast, ast*>::iterator it = to_ast_map_ref(m).begin();
|
||||
obj_map<ast, ast*>::iterator end = to_ast_map_ref(m).end();
|
||||
|
|
|
@ -24,7 +24,7 @@ Revision History:
|
|||
struct Z3_ast_map_ref : public api::object {
|
||||
ast_manager & m;
|
||||
obj_map<ast, ast*> m_map;
|
||||
Z3_ast_map_ref(ast_manager & _m):m(_m) {}
|
||||
Z3_ast_map_ref(api::context& c, ast_manager & _m): api::object(c), m(_m) {}
|
||||
virtual ~Z3_ast_map_ref();
|
||||
};
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_mk_ast_vector(c);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, mk_c(c)->m());
|
||||
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, *mk_c(c), mk_c(c)->m());
|
||||
mk_c(c)->save_object(v);
|
||||
Z3_ast_vector r = of_ast_vector(v);
|
||||
RETURN_Z3(r);
|
||||
|
@ -111,7 +111,7 @@ extern "C" {
|
|||
RETURN_Z3(0);
|
||||
}
|
||||
ast_translation translator(mk_c(c)->m(), mk_c(t)->m());
|
||||
Z3_ast_vector_ref * new_v = alloc(Z3_ast_vector_ref, mk_c(t)->m());
|
||||
Z3_ast_vector_ref * new_v = alloc(Z3_ast_vector_ref, *mk_c(t), mk_c(t)->m());
|
||||
mk_c(t)->save_object(new_v);
|
||||
unsigned sz = to_ast_vector_ref(v).size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
|
|
|
@ -20,9 +20,13 @@ Revision History:
|
|||
|
||||
#include"api_util.h"
|
||||
|
||||
namespace api {
|
||||
class context;
|
||||
};
|
||||
|
||||
struct Z3_ast_vector_ref : public api::object {
|
||||
ast_ref_vector m_ast_vector;
|
||||
Z3_ast_vector_ref(ast_manager & m):m_ast_vector(m) {}
|
||||
Z3_ast_vector_ref(api::context& c, ast_manager & m): api::object(c), m_ast_vector(m) {}
|
||||
virtual ~Z3_ast_vector_ref() {}
|
||||
};
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ Author:
|
|||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
|
@ -27,7 +26,7 @@ extern "C" {
|
|||
Z3_sort Z3_API Z3_mk_bv_sort(Z3_context c, unsigned sz) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_bv_sort(c, sz);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
if (sz == 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
}
|
||||
|
@ -39,7 +38,7 @@ extern "C" {
|
|||
|
||||
#define MK_BV_UNARY(NAME, OP) MK_UNARY(NAME, mk_c(c)->get_bv_fid(), OP, SKIP)
|
||||
#define MK_BV_BINARY(NAME, OP) MK_BINARY(NAME, mk_c(c)->get_bv_fid(), OP, SKIP)
|
||||
|
||||
|
||||
MK_BV_UNARY(Z3_mk_bvnot, OP_BNOT);
|
||||
MK_BV_UNARY(Z3_mk_bvredand, OP_BREDAND);
|
||||
MK_BV_UNARY(Z3_mk_bvredor, OP_BREDOR);
|
||||
|
@ -75,11 +74,11 @@ extern "C" {
|
|||
expr * _n = to_expr(n);
|
||||
parameter params[2] = { parameter(high), parameter(low) };
|
||||
expr * a = mk_c(c)->m().mk_app(mk_c(c)->get_bv_fid(), OP_EXTRACT, 2, params, 1, &_n);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
check_sorts(c, a);
|
||||
return of_ast(a);
|
||||
}
|
||||
|
||||
|
||||
Z3_ast Z3_API Z3_mk_extract(Z3_context c, unsigned high, unsigned low, Z3_ast n) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_extract(c, high, low, n);
|
||||
|
@ -88,7 +87,7 @@ extern "C" {
|
|||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
#define MK_BV_PUNARY(NAME, OP) \
|
||||
Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
|
||||
Z3_TRY; \
|
||||
|
@ -113,7 +112,7 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
|
|||
Z3_ast Z3_API Z3_mk_bv2int(Z3_context c, Z3_ast n, Z3_bool is_signed) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_bv2int(c, n, is_signed);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
Z3_sort int_s = Z3_mk_int_sort(c);
|
||||
if (is_signed) {
|
||||
Z3_ast r = Z3_mk_bv2int(c, n, false);
|
||||
|
@ -125,7 +124,7 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
|
|||
Z3_inc_ref(c, bound);
|
||||
Z3_ast zero = Z3_mk_int(c, 0, s);
|
||||
Z3_inc_ref(c, zero);
|
||||
Z3_ast pred = Z3_mk_bvslt(c, n, zero);
|
||||
Z3_ast pred = Z3_mk_bvslt(c, n, zero);
|
||||
Z3_inc_ref(c, pred);
|
||||
// if n <_sigend 0 then r - s^sz else r
|
||||
Z3_ast args[2] = { r, bound };
|
||||
|
@ -140,19 +139,19 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
|
|||
RETURN_Z3(res);
|
||||
}
|
||||
else {
|
||||
expr * _n = to_expr(n);
|
||||
parameter p(to_sort(int_s));
|
||||
ast* a = mk_c(c)->m().mk_app(mk_c(c)->get_bv_fid(), OP_BV2INT, 1, &p, 1, &_n);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
check_sorts(c, a);
|
||||
RETURN_Z3(of_ast(a));
|
||||
expr * _n = to_expr(n);
|
||||
parameter p(to_sort(int_s));
|
||||
ast* a = mk_c(c)->m().mk_app(mk_c(c)->get_bv_fid(), OP_BV2INT, 1, &p, 1, &_n);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
check_sorts(c, a);
|
||||
RETURN_Z3(of_ast(a));
|
||||
}
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Create a bit-vector of sort \s with 1 in the most significant bit position.
|
||||
|
||||
|
||||
The sort \s must be a bit-vector sort.
|
||||
|
||||
This function is a shorthand for <tt>shl(1, N-1)</tt>
|
||||
|
@ -343,7 +342,7 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
|
|||
return Z3_mk_not(c, eq);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
// only for signed machine integers
|
||||
Z3_ast Z3_API Z3_mk_bvsdiv_no_overflow(Z3_context c, Z3_ast t1, Z3_ast t2) {
|
||||
Z3_TRY;
|
||||
|
@ -369,7 +368,7 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
|
|||
return result;
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
Z3_ast Z3_API Z3_mk_bvsub(Z3_context c, Z3_ast n1, Z3_ast n2) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_bvsub(c, n1, n2);
|
||||
|
@ -389,7 +388,7 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
|
|||
unsigned Z3_API Z3_get_bv_sort_size(Z3_context c, Z3_sort t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_bv_sort_size(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_VALID_AST(t, 0);
|
||||
if (to_sort(t)->get_family_id() == mk_c(c)->get_bv_fid() && to_sort(t)->get_decl_kind() == BV_SORT) {
|
||||
return to_sort(t)->get_parameter(0).get_int();
|
||||
|
@ -398,5 +397,5 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
|
|||
return 0;
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -37,7 +37,7 @@ extern "C" {
|
|||
catch (z3_exception & ex) {
|
||||
// The error handler is only available for contexts
|
||||
// Just throw a warning.
|
||||
warning_msg(ex.msg());
|
||||
warning_msg("%s", ex.msg());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ extern "C" {
|
|||
catch (z3_exception & ex) {
|
||||
// The error handler is only available for contexts
|
||||
// Just throw a warning.
|
||||
warning_msg(ex.msg());
|
||||
warning_msg("%s", ex.msg());
|
||||
return Z3_FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ extern "C" {
|
|||
catch (z3_exception & ex) {
|
||||
// The error handler is only available for contexts
|
||||
// Just throw a warning.
|
||||
warning_msg(ex.msg());
|
||||
warning_msg("%s", ex.msg());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ Author:
|
|||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<typeinfo>
|
||||
#include"api_context.h"
|
||||
#include"smtparser.h"
|
||||
#include"version.h"
|
||||
|
@ -32,6 +33,28 @@ void install_tactics(tactic_manager & ctx);
|
|||
|
||||
namespace api {
|
||||
|
||||
object::object(context& c): m_ref_count(0), m_context(c) { this->m_id = m_context.add_object(this); }
|
||||
|
||||
void object::inc_ref() { m_ref_count++; }
|
||||
|
||||
void object::dec_ref() { SASSERT(m_ref_count > 0); m_ref_count--; if (m_ref_count == 0) m_context.del_object(this); }
|
||||
|
||||
unsigned context::add_object(api::object* o) {
|
||||
unsigned id = m_allocated_objects.size();
|
||||
if (!m_free_object_ids.empty()) {
|
||||
id = m_free_object_ids.back();
|
||||
m_free_object_ids.pop_back();
|
||||
}
|
||||
m_allocated_objects.insert(id, o);
|
||||
return id;
|
||||
}
|
||||
|
||||
void context::del_object(api::object* o) {
|
||||
m_free_object_ids.push_back(o->id());
|
||||
m_allocated_objects.remove(o->id());
|
||||
dealloc(o);
|
||||
}
|
||||
|
||||
static void default_error_handler(Z3_context ctx, Z3_error_code c) {
|
||||
printf("Error: %s\n", Z3_get_error_msg(ctx, c));
|
||||
exit(1);
|
||||
|
@ -47,22 +70,6 @@ namespace api {
|
|||
//
|
||||
// ------------------------
|
||||
|
||||
context::set_interruptable::set_interruptable(context & ctx, event_handler & i):
|
||||
m_ctx(ctx) {
|
||||
#pragma omp critical (set_interruptable)
|
||||
{
|
||||
SASSERT(m_ctx.m_interruptable == 0);
|
||||
m_ctx.m_interruptable = &i;
|
||||
}
|
||||
}
|
||||
|
||||
context::set_interruptable::~set_interruptable() {
|
||||
#pragma omp critical (set_interruptable)
|
||||
{
|
||||
m_ctx.m_interruptable = 0;
|
||||
}
|
||||
}
|
||||
|
||||
context::context(context_params * p, bool user_ref_count):
|
||||
m_params(p != 0 ? *p : context_params()),
|
||||
m_user_ref_count(user_ref_count),
|
||||
|
@ -83,11 +90,10 @@ namespace api {
|
|||
m_print_mode = Z3_PRINT_SMTLIB_FULL;
|
||||
m_searching = false;
|
||||
|
||||
m_interruptable = 0;
|
||||
|
||||
m_smtlib_parser = 0;
|
||||
m_smtlib_parser_has_decls = false;
|
||||
|
||||
|
||||
m_interruptable = 0;
|
||||
m_error_handler = &default_error_handler;
|
||||
|
||||
m_basic_fid = m().get_basic_family_id();
|
||||
|
@ -108,6 +114,30 @@ namespace api {
|
|||
|
||||
context::~context() {
|
||||
reset_parser();
|
||||
m_last_obj = 0;
|
||||
u_map<api::object*>::iterator it = m_allocated_objects.begin();
|
||||
while (it != m_allocated_objects.end()) {
|
||||
DEBUG_CODE(warning_msg("Uncollected memory: %d: %s", it->m_key, typeid(*it->m_value).name()););
|
||||
m_allocated_objects.remove(it->m_key);
|
||||
dealloc(it->m_value);
|
||||
it = m_allocated_objects.begin();
|
||||
}
|
||||
}
|
||||
|
||||
context::set_interruptable::set_interruptable(context & ctx, event_handler & i):
|
||||
m_ctx(ctx) {
|
||||
#pragma omp critical (set_interruptable)
|
||||
{
|
||||
SASSERT(m_ctx.m_interruptable == 0);
|
||||
m_ctx.m_interruptable = &i;
|
||||
}
|
||||
}
|
||||
|
||||
context::set_interruptable::~set_interruptable() {
|
||||
#pragma omp critical (set_interruptable)
|
||||
{
|
||||
m_ctx.m_interruptable = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void context::interrupt() {
|
||||
|
@ -386,6 +416,7 @@ extern "C" {
|
|||
return;
|
||||
}
|
||||
mk_c(c)->m().dec_ref(to_ast(a));
|
||||
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
|
@ -401,6 +432,11 @@ extern "C" {
|
|||
*revision_number = Z3_REVISION_NUMBER;
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_get_full_version(void) {
|
||||
LOG_Z3_get_full_version();
|
||||
return Z3_FULL_VERSION;
|
||||
}
|
||||
|
||||
void Z3_API Z3_enable_trace(Z3_string tag) {
|
||||
memory::initialize(UINT_MAX);
|
||||
LOG_Z3_enable_trace(tag);
|
||||
|
@ -465,6 +501,10 @@ extern "C" {
|
|||
return _get_error_msg(c, err);
|
||||
}
|
||||
|
||||
Z3_API char const * Z3_get_error_msg_ex(Z3_context c, Z3_error_code err) {
|
||||
return Z3_get_error_msg(c, err);
|
||||
}
|
||||
|
||||
|
||||
void Z3_API Z3_set_ast_print_mode(Z3_context c, Z3_ast_print_mode mode) {
|
||||
Z3_TRY;
|
||||
|
|
|
@ -36,6 +36,7 @@ Revision History:
|
|||
#include"tactic_manager.h"
|
||||
#include"context_params.h"
|
||||
#include"api_polynomial.h"
|
||||
#include"hashtable.h"
|
||||
|
||||
namespace smtlib {
|
||||
class parser;
|
||||
|
@ -72,6 +73,8 @@ namespace api {
|
|||
ast_ref_vector m_ast_trail; //!< used when m_user_ref_count == false
|
||||
|
||||
ref<api::object> m_last_obj; //!< reference to the last API object returned by the APIs
|
||||
u_map<api::object*> m_allocated_objects; // !< table containing current set of allocated API objects
|
||||
unsigned_vector m_free_object_ids; // !< free list of identifiers available for allocated objects.
|
||||
|
||||
family_id m_basic_fid;
|
||||
family_id m_array_fid;
|
||||
|
@ -95,7 +98,7 @@ namespace api {
|
|||
|
||||
event_handler * m_interruptable; // Reference to an object that can be interrupted by Z3_interrupt
|
||||
|
||||
public:
|
||||
public:
|
||||
// Scoped obj for setting m_interruptable
|
||||
class set_interruptable {
|
||||
context & m_ctx;
|
||||
|
@ -147,6 +150,9 @@ namespace api {
|
|||
// Sign an error if solver is searching
|
||||
void check_searching();
|
||||
|
||||
unsigned add_object(api::object* o);
|
||||
void del_object(api::object* o);
|
||||
|
||||
Z3_ast_print_mode get_print_mode() const { return m_print_mode; }
|
||||
void set_print_mode(Z3_ast_print_mode m) { m_print_mode = m; }
|
||||
|
||||
|
@ -245,7 +251,7 @@ inline api::context * mk_c(Z3_context c) { return reinterpret_cast<api::context*
|
|||
#define CHECK_VALID_AST(_a_, _ret_) { if (_a_ == 0 || !CHECK_REF_COUNT(_a_)) { SET_ERROR_CODE(Z3_INVALID_ARG); return _ret_; } }
|
||||
#define CHECK_SEARCHING(c) mk_c(c)->check_searching();
|
||||
inline bool is_expr(Z3_ast a) { return is_expr(to_ast(a)); }
|
||||
#define CHECK_IS_EXPR(_p_, _ret_) { if (!is_expr(_p_)) { SET_ERROR_CODE(Z3_INVALID_ARG); return _ret_; } }
|
||||
#define CHECK_IS_EXPR(_p_, _ret_) { if (_p_ == 0 || !is_expr(_p_)) { SET_ERROR_CODE(Z3_INVALID_ARG); return _ret_; } }
|
||||
inline bool is_bool_expr(Z3_context c, Z3_ast a) { return is_expr(a) && mk_c(c)->m().is_bool(to_expr(a)); }
|
||||
#define CHECK_FORMULA(_a_, _ret_) { if (_a_ == 0 || !CHECK_REF_COUNT(_a_) || !is_bool_expr(c, _a_)) { SET_ERROR_CODE(Z3_INVALID_ARG); return _ret_; } }
|
||||
inline void check_sorts(Z3_context c, ast * n) { mk_c(c)->check_sorts(n); }
|
||||
|
|
|
@ -189,7 +189,7 @@ extern "C" {
|
|||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_sort Z3_API Z3_mk_finite_domain_sort(Z3_context c, Z3_symbol name, unsigned __int64 size) {
|
||||
Z3_sort Z3_API Z3_mk_finite_domain_sort(Z3_context c, Z3_symbol name, __uint64 size) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_finite_domain_sort(c, name, size);
|
||||
RESET_ERROR_CODE();
|
||||
|
@ -199,7 +199,7 @@ extern "C" {
|
|||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_get_finite_domain_sort_size(Z3_context c, Z3_sort s, unsigned __int64 * out) {
|
||||
Z3_bool Z3_API Z3_get_finite_domain_sort_size(Z3_context c, Z3_sort s, __uint64 * out) {
|
||||
Z3_TRY;
|
||||
if (out) {
|
||||
*out = 0;
|
||||
|
@ -223,7 +223,7 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_mk_fixedpoint(c);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_fixedpoint_ref * d = alloc(Z3_fixedpoint_ref);
|
||||
Z3_fixedpoint_ref * d = alloc(Z3_fixedpoint_ref, *mk_c(c));
|
||||
d->m_datalog = alloc(api::fixedpoint_context, mk_c(c)->m(), mk_c(c)->fparams());
|
||||
mk_c(c)->save_object(d);
|
||||
Z3_fixedpoint r = of_datalog(d);
|
||||
|
@ -290,8 +290,8 @@ extern "C" {
|
|||
r = to_fixedpoint_ref(d)->ctx().query(to_expr(q));
|
||||
}
|
||||
catch (z3_exception& ex) {
|
||||
mk_c(c)->handle_exception(ex);
|
||||
r = l_undef;
|
||||
mk_c(c)->handle_exception(ex);
|
||||
}
|
||||
to_fixedpoint_ref(d)->ctx().cleanup();
|
||||
}
|
||||
|
@ -369,7 +369,7 @@ extern "C" {
|
|||
return 0;
|
||||
}
|
||||
|
||||
Z3_ast_vector_ref* v = alloc(Z3_ast_vector_ref, m);
|
||||
Z3_ast_vector_ref* v = alloc(Z3_ast_vector_ref, *mk_c(c), m);
|
||||
mk_c(c)->save_object(v);
|
||||
for (unsigned i = 0; i < coll.m_queries.size(); ++i) {
|
||||
v->m_ast_vector.push_back(coll.m_queries[i].get());
|
||||
|
@ -421,7 +421,7 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_get_statistics(c, d);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_stats_ref * st = alloc(Z3_stats_ref);
|
||||
Z3_stats_ref * st = alloc(Z3_stats_ref, (*mk_c(c)));
|
||||
to_fixedpoint_ref(d)->ctx().collect_statistics(st->m_stats);
|
||||
mk_c(c)->save_object(st);
|
||||
Z3_stats r = of_stats(st);
|
||||
|
@ -460,7 +460,7 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_get_rules(c, d);
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
Z3_ast_vector_ref* v = alloc(Z3_ast_vector_ref, m);
|
||||
Z3_ast_vector_ref* v = alloc(Z3_ast_vector_ref, *mk_c(c), m);
|
||||
mk_c(c)->save_object(v);
|
||||
expr_ref_vector rules(m), queries(m);
|
||||
svector<symbol> names;
|
||||
|
@ -483,7 +483,7 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_get_assertions(c, d);
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
Z3_ast_vector_ref* v = alloc(Z3_ast_vector_ref, m);
|
||||
Z3_ast_vector_ref* v = alloc(Z3_ast_vector_ref, *mk_c(c), m);
|
||||
mk_c(c)->save_object(v);
|
||||
unsigned num_asserts = to_fixedpoint_ref(d)->ctx().get_num_assertions();
|
||||
for (unsigned i = 0; i < num_asserts; ++i) {
|
||||
|
@ -568,7 +568,7 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_get_param_descrs(c, f);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_param_descrs_ref * d = alloc(Z3_param_descrs_ref);
|
||||
Z3_param_descrs_ref * d = alloc(Z3_param_descrs_ref, *mk_c(c));
|
||||
mk_c(c)->save_object(d);
|
||||
to_fixedpoint_ref(f)->collect_param_descrs(d->m_descrs);
|
||||
Z3_param_descrs r = of_param_descrs(d);
|
||||
|
|
|
@ -30,13 +30,14 @@ typedef void (*reduce_assign_callback_fptr)(void*, func_decl*, unsigned, expr*co
|
|||
|
||||
namespace api {
|
||||
class fixedpoint_context;
|
||||
class context;
|
||||
};
|
||||
|
||||
|
||||
struct Z3_fixedpoint_ref : public api::object {
|
||||
api::fixedpoint_context * m_datalog;
|
||||
params_ref m_params;
|
||||
Z3_fixedpoint_ref():m_datalog(0) {}
|
||||
Z3_fixedpoint_ref(api::context& c): api::object(c), m_datalog(0) {}
|
||||
virtual ~Z3_fixedpoint_ref() { dealloc(m_datalog); }
|
||||
};
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ Author:
|
|||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
|
@ -24,16 +23,16 @@ Revision History:
|
|||
|
||||
extern "C" {
|
||||
|
||||
Z3_sort Z3_API Z3_mk_tuple_sort(Z3_context c,
|
||||
Z3_sort Z3_API Z3_mk_tuple_sort(Z3_context c,
|
||||
Z3_symbol name,
|
||||
unsigned num_fields,
|
||||
unsigned num_fields,
|
||||
Z3_symbol const field_names[],
|
||||
Z3_sort const field_sorts[],
|
||||
Z3_func_decl * mk_tuple_decl,
|
||||
Z3_func_decl proj_decls[]) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_tuple_sort(c, name, num_fields, field_names, field_sorts, mk_tuple_decl, proj_decls);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
mk_c(c)->reset_last_result();
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
datatype_util& dt_util = mk_c(c)->dtutil();
|
||||
|
@ -43,14 +42,14 @@ extern "C" {
|
|||
std::string recognizer_s("is_");
|
||||
recognizer_s += to_symbol(name).str();
|
||||
symbol recognizer(recognizer_s.c_str());
|
||||
|
||||
|
||||
ptr_vector<accessor_decl> acc;
|
||||
for (unsigned i = 0; i < num_fields; ++i) {
|
||||
acc.push_back(mk_accessor_decl(to_symbol(field_names[i]), type_ref(to_sort(field_sorts[i]))));
|
||||
}
|
||||
|
||||
constructor_decl* constrs[1] = { mk_constructor_decl(to_symbol(name), recognizer, acc.size(), acc.c_ptr()) };
|
||||
|
||||
|
||||
{
|
||||
datatype_decl * dt = mk_datatype_decl(to_symbol(name), 1, constrs);
|
||||
bool is_ok = mk_c(c)->get_dt_plugin()->mk_datatypes(1, &dt, tuples);
|
||||
|
@ -63,7 +62,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
// create tuple type
|
||||
SASSERT(tuples.size() == 1);
|
||||
SASSERT(tuples.size() == 1);
|
||||
tuple = tuples[0].get();
|
||||
mk_c(c)->save_multiple_ast_trail(tuple);
|
||||
|
||||
|
@ -72,9 +71,9 @@ extern "C" {
|
|||
SASSERT(!dt_util.is_recursive(tuple));
|
||||
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(tuple);
|
||||
func_decl* decl = (*decls)[0];
|
||||
mk_c(c)->save_multiple_ast_trail(decl);
|
||||
mk_c(c)->save_multiple_ast_trail(decl);
|
||||
*mk_tuple_decl = of_func_decl(decl);
|
||||
|
||||
|
||||
// Create projections
|
||||
ptr_vector<func_decl> const * accs = dt_util.get_constructor_accessors(decl);
|
||||
if (!accs) {
|
||||
|
@ -90,8 +89,8 @@ extern "C" {
|
|||
RETURN_Z3_mk_tuple_sort(of_sort(tuple));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_sort Z3_API Z3_mk_enumeration_sort(Z3_context c,
|
||||
|
||||
Z3_sort Z3_API Z3_mk_enumeration_sort(Z3_context c,
|
||||
Z3_symbol name,
|
||||
unsigned n,
|
||||
Z3_symbol const enum_names[],
|
||||
|
@ -106,7 +105,7 @@ extern "C" {
|
|||
|
||||
sort_ref_vector sorts(m);
|
||||
sort* e;
|
||||
|
||||
|
||||
ptr_vector<constructor_decl> constrs;
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
symbol e_name(to_symbol(enum_names[i]));
|
||||
|
@ -128,9 +127,9 @@ extern "C" {
|
|||
RETURN_Z3(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// create enum type.
|
||||
SASSERT(sorts.size() == 1);
|
||||
SASSERT(sorts.size() == 1);
|
||||
e = sorts[0].get();
|
||||
mk_c(c)->save_multiple_ast_trail(e);
|
||||
|
||||
|
@ -141,10 +140,10 @@ extern "C" {
|
|||
SASSERT(decls && decls->size() == n);
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
func_decl* decl = (*decls)[i];
|
||||
mk_c(c)->save_multiple_ast_trail(decl);
|
||||
mk_c(c)->save_multiple_ast_trail(decl);
|
||||
enum_consts[i] = of_func_decl(decl);
|
||||
decl = dt_util.get_constructor_recognizer(decl);
|
||||
mk_c(c)->save_multiple_ast_trail(decl);
|
||||
mk_c(c)->save_multiple_ast_trail(decl);
|
||||
enum_testers[i] = of_func_decl(decl);
|
||||
}
|
||||
|
||||
|
@ -168,11 +167,11 @@ extern "C" {
|
|||
ast_manager& m = mk_c(c)->m();
|
||||
mk_c(c)->reset_last_result();
|
||||
datatype_util data_util(m);
|
||||
accessor_decl* head_tail[2] = {
|
||||
accessor_decl* head_tail[2] = {
|
||||
mk_accessor_decl(symbol("head"), type_ref(to_sort(elem_sort))),
|
||||
mk_accessor_decl(symbol("tail"), type_ref(0))
|
||||
};
|
||||
constructor_decl* constrs[2] = {
|
||||
constructor_decl* constrs[2] = {
|
||||
mk_constructor_decl(symbol("nil"), symbol("is_nil"), 0, 0),
|
||||
// Leo: SMT 2.0 document uses 'insert' instead of cons
|
||||
mk_constructor_decl(symbol("cons"), symbol("is_cons"), 2, head_tail)
|
||||
|
@ -197,22 +196,22 @@ extern "C" {
|
|||
func_decl* f;
|
||||
if (nil_decl) {
|
||||
f = cnstrs[0];
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
*nil_decl = of_func_decl(f);
|
||||
}
|
||||
if (is_nil_decl) {
|
||||
f = data_util.get_constructor_recognizer(cnstrs[0]);
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
*is_nil_decl = of_func_decl(f);
|
||||
}
|
||||
if (cons_decl) {
|
||||
f = cnstrs[1];
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
*cons_decl = of_func_decl(f);
|
||||
}
|
||||
if (is_cons_decl) {
|
||||
f = data_util.get_constructor_recognizer(cnstrs[1]);
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
*is_cons_decl = of_func_decl(f);
|
||||
}
|
||||
if (head_decl) {
|
||||
|
@ -220,7 +219,7 @@ extern "C" {
|
|||
SASSERT(acc);
|
||||
SASSERT(acc->size() == 2);
|
||||
f = (*acc)[0];
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
*head_decl = of_func_decl(f);
|
||||
}
|
||||
if (tail_decl) {
|
||||
|
@ -228,7 +227,7 @@ extern "C" {
|
|||
SASSERT(acc);
|
||||
SASSERT(acc->size() == 2);
|
||||
f = (*acc)[1];
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
*tail_decl = of_func_decl(f);
|
||||
}
|
||||
RETURN_Z3_mk_list_sort(of_sort(s));
|
||||
|
@ -255,7 +254,7 @@ extern "C" {
|
|||
) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_constructor(c, name, tester, num_fields, field_names, sorts, sort_refs);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
constructor* cnstr = alloc(constructor, m);
|
||||
cnstr->m_name = to_symbol(name);
|
||||
|
@ -291,7 +290,7 @@ extern "C" {
|
|||
if (!f) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (constructor_decl) {
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
*constructor_decl = of_func_decl(f);
|
||||
|
@ -301,15 +300,15 @@ extern "C" {
|
|||
mk_c(c)->save_multiple_ast_trail(f2);
|
||||
*tester = of_func_decl(f2);
|
||||
}
|
||||
|
||||
|
||||
ptr_vector<func_decl> const* accs = data_util.get_constructor_accessors(f);
|
||||
if (!accs && num_fields > 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
for (unsigned i = 0; i < num_fields; ++i) {
|
||||
func_decl* f2 = (*accs)[i];
|
||||
mk_c(c)->save_multiple_ast_trail(f2);
|
||||
mk_c(c)->save_multiple_ast_trail(f2);
|
||||
accessors[i] = of_func_decl(f2);
|
||||
}
|
||||
RETURN_Z3_query_constructor;
|
||||
|
@ -324,7 +323,7 @@ extern "C" {
|
|||
Z3_CATCH;
|
||||
}
|
||||
|
||||
static datatype_decl* mk_datatype_decl(Z3_context c,
|
||||
static datatype_decl* mk_datatype_decl(Z3_context c,
|
||||
Z3_symbol name,
|
||||
unsigned num_constructors,
|
||||
Z3_constructor constructors[]) {
|
||||
|
@ -342,7 +341,7 @@ extern "C" {
|
|||
}
|
||||
constrs.push_back(mk_constructor_decl(cn->m_name, cn->m_tester, acc.size(), acc.c_ptr()));
|
||||
}
|
||||
return mk_datatype_decl(to_symbol(name), num_constructors, constrs.c_ptr());
|
||||
return mk_datatype_decl(to_symbol(name), num_constructors, constrs.c_ptr());
|
||||
}
|
||||
|
||||
Z3_sort Z3_API Z3_mk_datatype(Z3_context c,
|
||||
|
@ -352,9 +351,9 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_mk_datatype(c, name, num_constructors, constructors);
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
datatype_util data_util(m);
|
||||
|
||||
|
||||
sort_ref_vector sorts(m);
|
||||
{
|
||||
datatype_decl * data = mk_datatype_decl(c, name, num_constructors, constructors);
|
||||
|
@ -370,7 +369,7 @@ extern "C" {
|
|||
|
||||
mk_c(c)->save_ast_trail(s);
|
||||
ptr_vector<func_decl> const* cnstrs = data_util.get_datatype_constructors(s);
|
||||
|
||||
|
||||
for (unsigned i = 0; i < num_constructors; ++i) {
|
||||
constructor* cn = reinterpret_cast<constructor*>(constructors[i]);
|
||||
cn->m_constructor = (*cnstrs)[i];
|
||||
|
@ -411,7 +410,7 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_mk_datatypes(c, num_sorts, sort_names, sorts, constructor_lists);
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
mk_c(c)->reset_last_result();
|
||||
datatype_util data_util(m);
|
||||
|
||||
|
@ -423,7 +422,7 @@ extern "C" {
|
|||
sort_ref_vector _sorts(m);
|
||||
bool ok = mk_c(c)->get_dt_plugin()->mk_datatypes(datas.size(), datas.c_ptr(), _sorts);
|
||||
del_datatype_decls(datas.size(), datas.c_ptr());
|
||||
|
||||
|
||||
if (!ok) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return;
|
||||
|
@ -437,8 +436,8 @@ extern "C" {
|
|||
constructor_list* cl = reinterpret_cast<constructor_list*>(constructor_lists[i]);
|
||||
ptr_vector<func_decl> const* cnstrs = data_util.get_datatype_constructors(s);
|
||||
for (unsigned j = 0; j < cl->size(); ++j) {
|
||||
constructor* cn = (*cl)[j];
|
||||
cn->m_constructor = (*cnstrs)[j];
|
||||
constructor* cn = (*cl)[j];
|
||||
cn->m_constructor = (*cnstrs)[j];
|
||||
}
|
||||
}
|
||||
RETURN_Z3_mk_datatypes;
|
||||
|
@ -452,15 +451,15 @@ extern "C" {
|
|||
CHECK_VALID_AST(t, 0);
|
||||
sort * _t = to_sort(t);
|
||||
datatype_util& dt_util = mk_c(c)->dtutil();
|
||||
|
||||
|
||||
if (!dt_util.is_datatype(_t)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(_t);
|
||||
if (!decls) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
return decls->size();
|
||||
Z3_CATCH_RETURN(0);
|
||||
|
@ -468,7 +467,7 @@ extern "C" {
|
|||
|
||||
Z3_func_decl get_datatype_sort_constructor_core(Z3_context c, Z3_sort t, unsigned idx) {
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_VALID_AST(t, 0);
|
||||
CHECK_VALID_AST(t, 0);
|
||||
sort * _t = to_sort(t);
|
||||
datatype_util& dt_util = mk_c(c)->dtutil();
|
||||
if (!dt_util.is_datatype(_t)) {
|
||||
|
@ -497,10 +496,10 @@ extern "C" {
|
|||
Z3_func_decl Z3_API Z3_get_datatype_sort_recognizer(Z3_context c, Z3_sort t, unsigned idx) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_datatype_sort_recognizer(c, t, idx);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
sort * _t = to_sort(t);
|
||||
datatype_util& dt_util = mk_c(c)->dtutil();
|
||||
|
||||
|
||||
if (!dt_util.is_datatype(_t)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
|
@ -520,13 +519,13 @@ extern "C" {
|
|||
Z3_func_decl Z3_API Z3_get_datatype_sort_constructor_accessor(Z3_context c, Z3_sort t, unsigned idx_c, unsigned idx_a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_datatype_sort_constructor_accessor(c, t, idx_c, idx_a);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
sort * _t = to_sort(t);
|
||||
datatype_util& dt_util = mk_c(c)->dtutil();
|
||||
|
||||
|
||||
if (!dt_util.is_datatype(_t)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(_t);
|
||||
if (!decls || idx_c >= decls->size()) {
|
||||
|
@ -536,24 +535,24 @@ extern "C" {
|
|||
func_decl* decl = (*decls)[idx_c];
|
||||
if (decl->get_arity() <= idx_a) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
ptr_vector<func_decl> const * accs = dt_util.get_constructor_accessors(decl);
|
||||
SASSERT(accs && accs->size() == decl->get_arity());
|
||||
if (!accs || accs->size() <= idx_a) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
decl = (*accs)[idx_a];
|
||||
mk_c(c)->save_ast_trail(decl);
|
||||
RETURN_Z3(of_func_decl(decl));
|
||||
RETURN_Z3(of_func_decl(decl));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_func_decl Z3_API Z3_get_tuple_sort_mk_decl(Z3_context c, Z3_sort t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_tuple_sort_mk_decl(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
sort * tuple = to_sort(t);
|
||||
datatype_util& dt_util = mk_c(c)->dtutil();
|
||||
if (!dt_util.is_datatype(tuple) || dt_util.is_recursive(tuple) || dt_util.get_datatype_num_constructors(tuple) != 1) {
|
||||
|
@ -564,34 +563,34 @@ extern "C" {
|
|||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
unsigned Z3_API Z3_get_tuple_sort_num_fields(Z3_context c, Z3_sort t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_tuple_sort_num_fields(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
sort * tuple = to_sort(t);
|
||||
datatype_util& dt_util = mk_c(c)->dtutil();
|
||||
if (!dt_util.is_datatype(tuple) || dt_util.is_recursive(tuple) || dt_util.get_datatype_num_constructors(tuple) != 1) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(tuple);
|
||||
if (!decls || decls->size() != 1) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
ptr_vector<func_decl> const * accs = dt_util.get_constructor_accessors((*decls)[0]);
|
||||
if (!accs) {
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
return accs->size();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
Z3_func_decl Z3_API Z3_get_tuple_sort_field_decl(Z3_context c, Z3_sort t, unsigned i) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_tuple_sort_field_decl(c, t, i);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
sort * tuple = to_sort(t);
|
||||
datatype_util& dt_util = mk_c(c)->dtutil();
|
||||
if (!dt_util.is_datatype(tuple) || dt_util.is_recursive(tuple) || dt_util.get_datatype_num_constructors(tuple) != 1) {
|
||||
|
@ -619,14 +618,14 @@ extern "C" {
|
|||
}
|
||||
|
||||
Z3_ast Z3_datatype_update_field(
|
||||
Z3_context c, Z3_func_decl f, Z3_ast t, Z3_ast v) {
|
||||
Z3_context c, Z3_func_decl f, Z3_ast t, Z3_ast v) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_datatype_update_field(c, f, t, v);
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager & m = mk_c(c)->m();
|
||||
func_decl* _f = to_func_decl(f);
|
||||
expr* _t = to_expr(t);
|
||||
expr* _v = to_expr(v);
|
||||
expr* _v = to_expr(v);
|
||||
expr* args[2] = { _t, _v };
|
||||
sort* domain[2] = { m.get_sort(_t), m.get_sort(_v) };
|
||||
parameter param(_f);
|
||||
|
|
|
@ -909,12 +909,18 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_fpa_get_numeral_sign(c, t, sgn);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(t, 0);
|
||||
CHECK_VALID_AST(t, 0);
|
||||
if (sgn == 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
}
|
||||
ast_manager & m = mk_c(c)->m();
|
||||
mpf_manager & mpfm = mk_c(c)->fpautil().fm();
|
||||
fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(mk_c(c)->get_fpa_fid());
|
||||
family_id fid = mk_c(c)->get_fpa_fid();
|
||||
fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(fid);
|
||||
expr * e = to_expr(t);
|
||||
if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN)) {
|
||||
if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
}
|
||||
|
@ -929,10 +935,44 @@ extern "C" {
|
|||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_fpa_get_numeral_significand_string(Z3_context c, Z3_ast t) {
|
||||
Z3_ast Z3_API Z3_fpa_get_numeral_sign_bv(Z3_context c, Z3_ast t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fpa_get_numeral_significand_string(c, t);
|
||||
LOG_Z3_fpa_get_numeral_sign_bv(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(t, 0);
|
||||
CHECK_VALID_AST(t, 0);
|
||||
ast_manager & m = mk_c(c)->m();
|
||||
mpf_manager & mpfm = mk_c(c)->fpautil().fm();
|
||||
family_id fid = mk_c(c)->get_fpa_fid();
|
||||
fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(fid);
|
||||
api::context * ctx = mk_c(c);
|
||||
expr * e = to_expr(t);
|
||||
if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
scoped_mpf val(mpfm);
|
||||
bool r = plugin->is_numeral(to_expr(t), val);
|
||||
if (!r || mpfm.is_nan(val)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
}
|
||||
app * a;
|
||||
if (mpfm.is_pos(val))
|
||||
a = ctx->bvutil().mk_numeral(0, 1);
|
||||
else
|
||||
a = ctx->bvutil().mk_numeral(1, 1);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
RETURN_Z3(of_expr(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_fpa_get_numeral_significand_bv(Z3_context c, Z3_ast t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fpa_get_numeral_significand_bv(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(t, 0);
|
||||
CHECK_VALID_AST(t, 0);
|
||||
ast_manager & m = mk_c(c)->m();
|
||||
mpf_manager & mpfm = mk_c(c)->fpautil().fm();
|
||||
unsynch_mpq_manager & mpqm = mpfm.mpq_manager();
|
||||
|
@ -940,17 +980,47 @@ extern "C" {
|
|||
fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(fid);
|
||||
SASSERT(plugin != 0);
|
||||
expr * e = to_expr(t);
|
||||
if (!is_app(e) ||
|
||||
is_app_of(e, fid, OP_FPA_NAN) ||
|
||||
is_app_of(e, fid, OP_FPA_PLUS_INF) ||
|
||||
is_app_of(e, fid, OP_FPA_MINUS_INF)) {
|
||||
if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
scoped_mpf val(mpfm);
|
||||
bool r = plugin->is_numeral(e, val);
|
||||
if (!r || !(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val) || mpfm.is_inf(val))) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
unsigned sbits = val.get().get_sbits();
|
||||
scoped_mpq q(mpqm);
|
||||
mpqm.set(q, mpfm.sig(val));
|
||||
if (mpfm.is_inf(val)) mpqm.set(q, 0);
|
||||
app * a = mk_c(c)->bvutil().mk_numeral(q.get(), sbits-1);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
RETURN_Z3(of_expr(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_fpa_get_numeral_significand_string(Z3_context c, Z3_ast t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fpa_get_numeral_significand_string(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(t, 0);
|
||||
CHECK_VALID_AST(t, 0);
|
||||
ast_manager & m = mk_c(c)->m();
|
||||
mpf_manager & mpfm = mk_c(c)->fpautil().fm();
|
||||
unsynch_mpq_manager & mpqm = mpfm.mpq_manager();
|
||||
family_id fid = mk_c(c)->get_fpa_fid();
|
||||
fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(fid);
|
||||
SASSERT(plugin != 0);
|
||||
expr * e = to_expr(t);
|
||||
if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return "";
|
||||
}
|
||||
scoped_mpf val(mpfm);
|
||||
bool r = plugin->is_numeral(e, val);
|
||||
if (!r || !(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val))) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG)
|
||||
if (!r || !(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val) || mpfm.is_inf(val))) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return "";
|
||||
}
|
||||
unsigned sbits = val.get().get_sbits();
|
||||
|
@ -958,6 +1028,7 @@ extern "C" {
|
|||
mpqm.set(q, mpfm.sig(val));
|
||||
if (!mpfm.is_denormal(val)) mpqm.add(q, mpfm.m_powers2(sbits - 1), q);
|
||||
mpqm.div(q, mpfm.m_powers2(sbits - 1), q);
|
||||
if (mpfm.is_inf(val)) mpqm.set(q, 0);
|
||||
std::stringstream ss;
|
||||
mpqm.display_decimal(ss, q, sbits);
|
||||
return mk_c(c)->mk_external_string(ss.str());
|
||||
|
@ -968,6 +1039,12 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_fpa_get_numeral_significand_uint64(c, t, n);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(t, 0);
|
||||
CHECK_VALID_AST(t, 0);
|
||||
if (n == 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
}
|
||||
ast_manager & m = mk_c(c)->m();
|
||||
mpf_manager & mpfm = mk_c(c)->fpautil().fm();
|
||||
unsynch_mpz_manager & mpzm = mpfm.mpz_manager();
|
||||
|
@ -975,10 +1052,7 @@ extern "C" {
|
|||
fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(fid);
|
||||
SASSERT(plugin != 0);
|
||||
expr * e = to_expr(t);
|
||||
if (!is_app(e) ||
|
||||
is_app_of(e, fid, OP_FPA_NAN) ||
|
||||
is_app_of(e, fid, OP_FPA_PLUS_INF) ||
|
||||
is_app_of(e, fid, OP_FPA_MINUS_INF)) {
|
||||
if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
*n = 0;
|
||||
return 0;
|
||||
|
@ -987,7 +1061,7 @@ extern "C" {
|
|||
bool r = plugin->is_numeral(e, val);
|
||||
const mpz & z = mpfm.sig(val);
|
||||
if (!r ||
|
||||
!(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val)) ||
|
||||
!(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val) || mpfm.is_inf(val)) ||
|
||||
!mpzm.is_uint64(z)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
*n = 0;
|
||||
|
@ -998,74 +1072,137 @@ extern "C" {
|
|||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_fpa_get_numeral_exponent_string(Z3_context c, Z3_ast t) {
|
||||
Z3_string Z3_API Z3_fpa_get_numeral_exponent_string(Z3_context c, Z3_ast t, Z3_bool biased) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fpa_get_numeral_exponent_string(c, t);
|
||||
LOG_Z3_fpa_get_numeral_exponent_string(c, t, biased);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(t, 0);
|
||||
CHECK_VALID_AST(t, 0);
|
||||
ast_manager & m = mk_c(c)->m();
|
||||
mpf_manager & mpfm = mk_c(c)->fpautil().fm();
|
||||
family_id fid = mk_c(c)->get_fpa_fid();
|
||||
fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(mk_c(c)->get_fpa_fid());
|
||||
SASSERT(plugin != 0);
|
||||
expr * e = to_expr(t);
|
||||
if (!is_app(e) ||
|
||||
is_app_of(e, fid, OP_FPA_NAN) ||
|
||||
is_app_of(e, fid, OP_FPA_PLUS_INF) ||
|
||||
is_app_of(e, fid, OP_FPA_MINUS_INF)) {
|
||||
if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return "";
|
||||
}
|
||||
scoped_mpf val(mpfm);
|
||||
bool r = plugin->is_numeral(e, val);
|
||||
if (!r || !(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val))) {
|
||||
if (!r || !(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val) || mpfm.is_inf(val))) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return "";
|
||||
}
|
||||
mpf_exp_t exp = mpfm.is_zero(val) ? 0 :
|
||||
mpfm.is_denormal(val) ? mpfm.mk_min_exp(val.get().get_ebits()) :
|
||||
mpfm.exp(val);
|
||||
unsigned ebits = val.get().get_ebits();
|
||||
mpf_exp_t exp;
|
||||
if (biased) {
|
||||
exp = mpfm.is_zero(val) ? 0 :
|
||||
mpfm.is_inf(val) ? mpfm.mk_top_exp(ebits) :
|
||||
mpfm.bias_exp(ebits, mpfm.exp(val));
|
||||
}
|
||||
else {
|
||||
exp = mpfm.is_zero(val) ? 0 :
|
||||
mpfm.is_inf(val) ? mpfm.mk_top_exp(ebits) :
|
||||
mpfm.is_denormal(val) ? mpfm.mk_min_exp(ebits) :
|
||||
mpfm.exp(val);
|
||||
}
|
||||
std::stringstream ss;
|
||||
ss << exp;
|
||||
return mk_c(c)->mk_external_string(ss.str());
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_fpa_get_numeral_exponent_int64(Z3_context c, Z3_ast t, __int64 * n) {
|
||||
Z3_bool Z3_API Z3_fpa_get_numeral_exponent_int64(Z3_context c, Z3_ast t, __int64 * n, Z3_bool biased) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fpa_get_numeral_exponent_int64(c, t, n);
|
||||
LOG_Z3_fpa_get_numeral_exponent_int64(c, t, n, biased);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(t, 0);
|
||||
CHECK_VALID_AST(t, 0);
|
||||
if (n == 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
}
|
||||
ast_manager & m = mk_c(c)->m();
|
||||
mpf_manager & mpfm = mk_c(c)->fpautil().fm();
|
||||
family_id fid = mk_c(c)->get_fpa_fid();
|
||||
fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(mk_c(c)->get_fpa_fid());
|
||||
SASSERT(plugin != 0);
|
||||
expr * e = to_expr(t);
|
||||
if (!is_app(e) ||
|
||||
is_app_of(e, fid, OP_FPA_NAN) ||
|
||||
is_app_of(e, fid, OP_FPA_PLUS_INF) ||
|
||||
is_app_of(e, fid, OP_FPA_MINUS_INF)) {
|
||||
if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
*n = 0;
|
||||
return 0;
|
||||
}
|
||||
scoped_mpf val(mpfm);
|
||||
bool r = plugin->is_numeral(e, val);
|
||||
if (!r || !(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val))) {
|
||||
if (!r || !(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val) || mpfm.is_inf(val))) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
*n = 0;
|
||||
return 0;
|
||||
}
|
||||
*n = mpfm.is_zero(val) ? 0 :
|
||||
mpfm.is_denormal(val) ? mpfm.mk_min_exp(val.get().get_ebits()) :
|
||||
mpfm.exp(val);
|
||||
unsigned ebits = val.get().get_ebits();
|
||||
if (biased) {
|
||||
*n = mpfm.is_zero(val) ? 0 :
|
||||
mpfm.is_inf(val) ? mpfm.mk_top_exp(ebits) :
|
||||
mpfm.bias_exp(ebits, mpfm.exp(val));
|
||||
}
|
||||
else {
|
||||
*n = mpfm.is_zero(val) ? 0 :
|
||||
mpfm.is_inf(val) ? mpfm.mk_top_exp(ebits) :
|
||||
mpfm.is_denormal(val) ? mpfm.mk_min_exp(ebits) :
|
||||
mpfm.exp(val);
|
||||
}
|
||||
return 1;
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_fpa_get_numeral_exponent_bv(Z3_context c, Z3_ast t, Z3_bool biased) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fpa_get_numeral_exponent_bv(c, t, biased);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(t, 0);
|
||||
CHECK_VALID_AST(t, 0);
|
||||
ast_manager & m = mk_c(c)->m();
|
||||
mpf_manager & mpfm = mk_c(c)->fpautil().fm();
|
||||
family_id fid = mk_c(c)->get_fpa_fid();
|
||||
fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(fid);
|
||||
expr * e = to_expr(t);
|
||||
if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
scoped_mpf val(mpfm);
|
||||
bool r = plugin->is_numeral(e, val);
|
||||
if (!r || !(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val) || mpfm.is_inf(val))) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
unsigned ebits = val.get().get_ebits();
|
||||
mpf_exp_t exp;
|
||||
if (biased) {
|
||||
exp = mpfm.is_zero(val) ? 0 :
|
||||
mpfm.is_inf(val) ? mpfm.mk_top_exp(ebits) :
|
||||
mpfm.bias_exp(ebits, mpfm.exp(val));
|
||||
}
|
||||
else {
|
||||
exp = mpfm.is_zero(val) ? 0 :
|
||||
mpfm.is_inf(val) ? mpfm.mk_top_exp(ebits) :
|
||||
mpfm.is_denormal(val) ? mpfm.mk_min_exp(ebits) :
|
||||
mpfm.exp(val);
|
||||
}
|
||||
app * a = mk_c(c)->bvutil().mk_numeral(exp, ebits);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
RETURN_Z3(of_expr(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_fpa_to_ieee_bv(Z3_context c, Z3_ast t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_fpa_to_ieee_bv(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(t, 0);
|
||||
CHECK_VALID_AST(t, 0);
|
||||
if (!is_fp(c, t)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
|
@ -1095,4 +1232,102 @@ extern "C" {
|
|||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_fpa_is_numeral_nan(Z3_context c, Z3_ast t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fpa_is_numeral_nan(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
api::context * ctx = mk_c(c);
|
||||
fpa_util & fu = ctx->fpautil();
|
||||
if (!is_expr(t) || !fu.is_numeral(to_expr(t))) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
}
|
||||
return fu.is_nan(to_expr(t));
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_fpa_is_numeral_inf(Z3_context c, Z3_ast t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fpa_is_numeral_inf(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
api::context * ctx = mk_c(c);
|
||||
fpa_util & fu = ctx->fpautil();
|
||||
if (!is_expr(t) || !fu.is_numeral(to_expr(t))) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
}
|
||||
return fu.is_inf(to_expr(t));
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_fpa_is_numeral_zero(Z3_context c, Z3_ast t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fpa_is_numeral_zero(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
api::context * ctx = mk_c(c);
|
||||
fpa_util & fu = ctx->fpautil();
|
||||
if (!is_expr(t) || !fu.is_numeral(to_expr(t))) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
}
|
||||
return fu.is_zero(to_expr(t));
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_fpa_is_numeral_normal(Z3_context c, Z3_ast t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fpa_is_numeral_normal(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
api::context * ctx = mk_c(c);
|
||||
fpa_util & fu = ctx->fpautil();
|
||||
if (!is_expr(t) || !fu.is_numeral(to_expr(t))) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
}
|
||||
return fu.is_normal(to_expr(t));
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_fpa_is_numeral_subnormal(Z3_context c, Z3_ast t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fpa_is_numeral_subnormal(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
api::context * ctx = mk_c(c);
|
||||
fpa_util & fu = ctx->fpautil();
|
||||
if (!is_expr(t) || !fu.is_numeral(to_expr(t))) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
}
|
||||
return fu.is_subnormal(to_expr(t));
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_fpa_is_numeral_positive(Z3_context c, Z3_ast t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fpa_is_numeral_positive(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
api::context * ctx = mk_c(c);
|
||||
fpa_util & fu = ctx->fpautil();
|
||||
if (!is_expr(t) || !fu.is_numeral(to_expr(t))) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
}
|
||||
return fu.is_positive(to_expr(t));
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_fpa_is_numeral_negative(Z3_context c, Z3_ast t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fpa_is_numeral_negative(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
api::context * ctx = mk_c(c);
|
||||
fpa_util & fu = ctx->fpautil();
|
||||
if (!is_expr(t) || !fu.is_numeral(to_expr(t))) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
}
|
||||
return fu.is_negative(to_expr(t));
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -32,7 +32,7 @@ extern "C" {
|
|||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
Z3_goal_ref * g = alloc(Z3_goal_ref);
|
||||
Z3_goal_ref * g = alloc(Z3_goal_ref, *mk_c(c));
|
||||
g->m_goal = alloc(goal, mk_c(c)->m(), proofs != 0, models != 0, unsat_cores != 0);
|
||||
mk_c(c)->save_object(g);
|
||||
Z3_goal r = of_goal(g);
|
||||
|
@ -156,7 +156,7 @@ extern "C" {
|
|||
LOG_Z3_goal_translate(c, g, target);
|
||||
RESET_ERROR_CODE();
|
||||
ast_translation translator(mk_c(c)->m(), mk_c(target)->m());
|
||||
Z3_goal_ref * _r = alloc(Z3_goal_ref);
|
||||
Z3_goal_ref * _r = alloc(Z3_goal_ref, *mk_c(target));
|
||||
_r->m_goal = to_goal_ref(g)->translate(translator);
|
||||
mk_c(target)->save_object(_r);
|
||||
Z3_goal r = of_goal(_r);
|
||||
|
|
|
@ -23,6 +23,7 @@ Revision History:
|
|||
|
||||
struct Z3_goal_ref : public api::object {
|
||||
goal_ref m_goal;
|
||||
Z3_goal_ref(api::context& c) : api::object(c) {}
|
||||
virtual ~Z3_goal_ref() {}
|
||||
};
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include<sstream>
|
||||
#include<vector>
|
||||
#include"z3.h"
|
||||
|
@ -212,7 +211,7 @@ extern "C" {
|
|||
LOG_Z3_get_interpolant(c, pf, pat, p);
|
||||
RESET_ERROR_CODE();
|
||||
|
||||
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, mk_c(c)->m());
|
||||
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, *mk_c(c), mk_c(c)->m());
|
||||
mk_c(c)->save_object(v);
|
||||
|
||||
ast *_pf = to_ast(pf);
|
||||
|
@ -303,7 +302,7 @@ extern "C" {
|
|||
|
||||
if (_status == l_false){
|
||||
// copy result back
|
||||
v = alloc(Z3_ast_vector_ref, mk_c(c)->m());
|
||||
v = alloc(Z3_ast_vector_ref, *mk_c(c), mk_c(c)->m());
|
||||
mk_c(c)->save_object(v);
|
||||
for (unsigned i = 0; i < interp.size(); i++){
|
||||
v->m_ast_vector.push_back(interp[i]);
|
||||
|
@ -314,7 +313,7 @@ extern "C" {
|
|||
model_ref mr;
|
||||
m_solver.get()->get_model(mr);
|
||||
if(mr.get()){
|
||||
Z3_model_ref *tmp_val = alloc(Z3_model_ref);
|
||||
Z3_model_ref *tmp_val = alloc(Z3_model_ref, *mk_c(c));
|
||||
tmp_val->m_model = mr.get();
|
||||
mk_c(c)->save_object(tmp_val);
|
||||
*model = of_model(tmp_val);
|
||||
|
@ -375,7 +374,7 @@ extern "C" {
|
|||
for(int i = 0; i < num_theory; i++)
|
||||
fmlas[i] = Z3_mk_implies(ctx,Z3_mk_true(ctx),fmlas[i]);
|
||||
std::copy(cnsts,cnsts+num,fmlas.begin()+num_theory);
|
||||
Z3_string smt = Z3_benchmark_to_smtlib_string(ctx,"none","AUFLIA","unknown","",num_fmlas-1,&fmlas[0],fmlas[num_fmlas-1]);
|
||||
Z3_string smt = Z3_benchmark_to_smtlib_string(ctx,"none","AUFLIA","unknown","",num_fmlas-1,&fmlas[0],fmlas[num_fmlas-1]);
|
||||
std::ofstream f(filename);
|
||||
if(num_theory)
|
||||
f << ";! THEORY=" << num_theory << "\n";
|
||||
|
@ -469,7 +468,7 @@ extern "C" {
|
|||
}
|
||||
f.close();
|
||||
|
||||
#if 0
|
||||
#if 0
|
||||
|
||||
|
||||
if(!parents){
|
||||
|
|
|
@ -15,40 +15,75 @@ Author:
|
|||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include<fstream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"util.h"
|
||||
#include"version.h"
|
||||
|
||||
std::ostream * g_z3_log = 0;
|
||||
bool g_z3_log_enabled = false;
|
||||
|
||||
extern "C" {
|
||||
Z3_bool Z3_API Z3_open_log(Z3_string filename) {
|
||||
if (g_z3_log != 0)
|
||||
Z3_close_log();
|
||||
g_z3_log = alloc(std::ofstream, filename);
|
||||
g_z3_log_enabled = true;
|
||||
if (g_z3_log->bad() || g_z3_log->fail()) {
|
||||
dealloc(g_z3_log);
|
||||
g_z3_log = 0;
|
||||
return Z3_FALSE;
|
||||
}
|
||||
return Z3_TRUE;
|
||||
}
|
||||
|
||||
void Z3_API Z3_append_log(Z3_string str) {
|
||||
if (g_z3_log == 0)
|
||||
return;
|
||||
_Z3_append_log(static_cast<char const *>(str));
|
||||
}
|
||||
|
||||
void Z3_API Z3_close_log(void) {
|
||||
void Z3_close_log_unsafe(void) {
|
||||
if (g_z3_log != 0) {
|
||||
dealloc(g_z3_log);
|
||||
g_z3_log_enabled = false;
|
||||
g_z3_log = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_open_log(Z3_string filename) {
|
||||
Z3_bool res = Z3_TRUE;
|
||||
|
||||
#ifdef Z3_LOG_SYNC
|
||||
#pragma omp critical (z3_log)
|
||||
{
|
||||
#endif
|
||||
if (g_z3_log != 0)
|
||||
Z3_close_log_unsafe();
|
||||
g_z3_log = alloc(std::ofstream, filename);
|
||||
if (g_z3_log->bad() || g_z3_log->fail()) {
|
||||
dealloc(g_z3_log);
|
||||
g_z3_log = 0;
|
||||
res = Z3_FALSE;
|
||||
}
|
||||
else {
|
||||
*g_z3_log << "V \"" << Z3_MAJOR_VERSION << "." << Z3_MINOR_VERSION << "." << Z3_BUILD_NUMBER << "." << Z3_REVISION_NUMBER << " " << __DATE__ << "\"\n";
|
||||
g_z3_log->flush();
|
||||
g_z3_log_enabled = true;
|
||||
}
|
||||
#ifdef Z3_LOG_SYNC
|
||||
}
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void Z3_API Z3_append_log(Z3_string str) {
|
||||
if (g_z3_log == 0)
|
||||
return;
|
||||
#ifdef Z3_LOG_SYNC
|
||||
#pragma omp critical (z3_log)
|
||||
{
|
||||
#endif
|
||||
if (g_z3_log != 0)
|
||||
_Z3_append_log(static_cast<char const *>(str));
|
||||
#ifdef Z3_LOG_SYNC
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Z3_API Z3_close_log(void) {
|
||||
if (g_z3_log != 0) {
|
||||
#ifdef Z3_LOG_SYNC
|
||||
#pragma omp critical (z3_log)
|
||||
{
|
||||
#endif
|
||||
Z3_close_log_unsafe();
|
||||
#ifdef Z3_LOG_SYNC
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ extern "C" {
|
|||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
Z3_func_interp_ref * fi = alloc(Z3_func_interp_ref, to_model_ref(m));
|
||||
Z3_func_interp_ref * fi = alloc(Z3_func_interp_ref, *mk_c(c), to_model_ref(m));
|
||||
fi->m_func_interp = _fi;
|
||||
mk_c(c)->save_object(fi);
|
||||
RETURN_Z3(of_func_interp(fi));
|
||||
|
@ -192,7 +192,7 @@ extern "C" {
|
|||
RETURN_Z3(0);
|
||||
}
|
||||
ptr_vector<expr> const & universe = to_model_ref(m)->get_universe(to_sort(s));
|
||||
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, mk_c(c)->m());
|
||||
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, *mk_c(c), mk_c(c)->m());
|
||||
mk_c(c)->save_object(v);
|
||||
unsigned sz = universe.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
|
@ -262,7 +262,7 @@ extern "C" {
|
|||
SET_ERROR_CODE(Z3_IOB);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
Z3_func_entry_ref * e = alloc(Z3_func_entry_ref, to_func_interp(f)->m_model.get());
|
||||
Z3_func_entry_ref * e = alloc(Z3_func_entry_ref, *mk_c(c), to_func_interp(f)->m_model.get());
|
||||
e->m_func_interp = to_func_interp_ref(f);
|
||||
e->m_func_entry = to_func_interp_ref(f)->get_entry(i);
|
||||
mk_c(c)->save_object(e);
|
||||
|
|
|
@ -23,7 +23,7 @@ Revision History:
|
|||
|
||||
struct Z3_model_ref : public api::object {
|
||||
model_ref m_model;
|
||||
Z3_model_ref() {}
|
||||
Z3_model_ref(api::context& c): api::object(c) {}
|
||||
virtual ~Z3_model_ref() {}
|
||||
};
|
||||
|
||||
|
@ -34,7 +34,7 @@ inline model * to_model_ref(Z3_model s) { return to_model(s)->m_model.get(); }
|
|||
struct Z3_func_interp_ref : public api::object {
|
||||
model_ref m_model; // must have it to prevent reference to m_func_interp to be killed.
|
||||
func_interp * m_func_interp;
|
||||
Z3_func_interp_ref(model * m):m_model(m), m_func_interp(0) {}
|
||||
Z3_func_interp_ref(api::context& c, model * m): api::object(c), m_model(m), m_func_interp(0) {}
|
||||
virtual ~Z3_func_interp_ref() {}
|
||||
};
|
||||
|
||||
|
@ -46,7 +46,7 @@ struct Z3_func_entry_ref : public api::object {
|
|||
model_ref m_model; // must have it to prevent reference to m_func_entry to be killed.
|
||||
func_interp * m_func_interp;
|
||||
func_entry const * m_func_entry;
|
||||
Z3_func_entry_ref(model * m):m_model(m), m_func_interp(0), m_func_entry(0) {}
|
||||
Z3_func_entry_ref(api::context& c, model * m):api::object(c), m_model(m), m_func_interp(0), m_func_entry(0) {}
|
||||
virtual ~Z3_func_entry_ref() {}
|
||||
};
|
||||
|
||||
|
|
|
@ -23,15 +23,17 @@ Revision History:
|
|||
#include"api_util.h"
|
||||
#include"api_model.h"
|
||||
#include"opt_context.h"
|
||||
#include"opt_cmds.h"
|
||||
#include"cancel_eh.h"
|
||||
#include"scoped_timer.h"
|
||||
|
||||
#include"smt2parser.h"
|
||||
#include"api_ast_vector.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
struct Z3_optimize_ref : public api::object {
|
||||
opt::context* m_opt;
|
||||
Z3_optimize_ref():m_opt(0) {}
|
||||
Z3_optimize_ref(api::context& c): api::object(c), m_opt(0) {}
|
||||
virtual ~Z3_optimize_ref() { dealloc(m_opt); }
|
||||
};
|
||||
inline Z3_optimize_ref * to_optimize(Z3_optimize o) { return reinterpret_cast<Z3_optimize_ref *>(o); }
|
||||
|
@ -42,7 +44,7 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_mk_optimize(c);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_optimize_ref * o = alloc(Z3_optimize_ref);
|
||||
Z3_optimize_ref * o = alloc(Z3_optimize_ref, *mk_c(c));
|
||||
o->m_opt = alloc(opt::context,mk_c(c)->m());
|
||||
mk_c(c)->save_object(o);
|
||||
RETURN_Z3(of_optimize(o));
|
||||
|
@ -158,7 +160,7 @@ extern "C" {
|
|||
RESET_ERROR_CODE();
|
||||
model_ref _m;
|
||||
to_optimize_ptr(o)->get_model(_m);
|
||||
Z3_model_ref * m_ref = alloc(Z3_model_ref);
|
||||
Z3_model_ref * m_ref = alloc(Z3_model_ref, *mk_c(c));
|
||||
if (_m) {
|
||||
m_ref->m_model = _m;
|
||||
}
|
||||
|
@ -186,7 +188,7 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_optimize_get_param_descrs(c, o);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_param_descrs_ref * d = alloc(Z3_param_descrs_ref);
|
||||
Z3_param_descrs_ref * d = alloc(Z3_param_descrs_ref, *mk_c(c));
|
||||
mk_c(c)->save_object(d);
|
||||
to_optimize_ptr(o)->collect_param_descrs(d->m_descrs);
|
||||
Z3_param_descrs r = of_param_descrs(d);
|
||||
|
@ -240,7 +242,7 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_optimize_get_statistics(c, d);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_stats_ref * st = alloc(Z3_stats_ref);
|
||||
Z3_stats_ref * st = alloc(Z3_stats_ref, *mk_c(c));
|
||||
to_optimize_ptr(d)->collect_statistics(st->m_stats);
|
||||
mk_c(c)->save_object(st);
|
||||
Z3_stats r = of_stats(st);
|
||||
|
@ -248,6 +250,86 @@ extern "C" {
|
|||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
static void Z3_optimize_from_stream(
|
||||
Z3_context c,
|
||||
Z3_optimize opt,
|
||||
std::istream& s) {
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
cmd_context ctx(false, &m);
|
||||
install_opt_cmds(ctx, to_optimize_ptr(opt));
|
||||
ctx.set_ignore_check(true);
|
||||
if (!parse_smt2_commands(ctx, s)) {
|
||||
SET_ERROR_CODE(Z3_PARSER_ERROR);
|
||||
return;
|
||||
}
|
||||
ptr_vector<expr>::const_iterator it = ctx.begin_assertions();
|
||||
ptr_vector<expr>::const_iterator end = ctx.end_assertions();
|
||||
for (; it != end; ++it) {
|
||||
to_optimize_ptr(opt)->add_hard_constraint(*it);
|
||||
}
|
||||
}
|
||||
|
||||
void Z3_API Z3_optimize_from_string(
|
||||
Z3_context c,
|
||||
Z3_optimize d,
|
||||
Z3_string s) {
|
||||
Z3_TRY;
|
||||
//LOG_Z3_optimize_from_string(c, d, s);
|
||||
std::string str(s);
|
||||
std::istringstream is(str);
|
||||
Z3_optimize_from_stream(c, d, is);
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_optimize_from_file(
|
||||
Z3_context c,
|
||||
Z3_optimize d,
|
||||
Z3_string s) {
|
||||
Z3_TRY;
|
||||
//LOG_Z3_optimize_from_file(c, d, s);
|
||||
std::ifstream is(s);
|
||||
if (!is) {
|
||||
std::ostringstream strm;
|
||||
strm << "Could not open file " << s;
|
||||
throw default_exception(strm.str());
|
||||
|
||||
SET_ERROR_CODE(Z3_PARSER_ERROR);
|
||||
return;
|
||||
}
|
||||
Z3_optimize_from_stream(c, d, is);
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
|
||||
Z3_ast_vector Z3_API Z3_optimize_get_assertions(Z3_context c, Z3_optimize o) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_optimize_get_assertions(c, o);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, *mk_c(c), mk_c(c)->m());
|
||||
mk_c(c)->save_object(v);
|
||||
expr_ref_vector hard(mk_c(c)->m());
|
||||
to_optimize_ptr(o)->get_hard_constraints(hard);
|
||||
for (unsigned i = 0; i < hard.size(); i++) {
|
||||
v->m_ast_vector.push_back(hard[i].get());
|
||||
}
|
||||
RETURN_Z3(of_ast_vector(v));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast_vector Z3_API Z3_optimize_get_objectives(Z3_context c, Z3_optimize o) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_optimize_get_objectives(c, o);
|
||||
RESET_ERROR_CODE();
|
||||
unsigned n = to_optimize_ptr(o)->num_objectives();
|
||||
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, *mk_c(c), mk_c(c)->m());
|
||||
mk_c(c)->save_object(v);
|
||||
for (unsigned i = 0; i < n; i++) {
|
||||
v->m_ast_vector.push_back(to_optimize_ptr(o)->get_objective(i));
|
||||
}
|
||||
RETURN_Z3(of_ast_vector(v));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -30,7 +30,7 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_mk_params(c);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_params_ref * p = alloc(Z3_params_ref);
|
||||
Z3_params_ref * p = alloc(Z3_params_ref, *mk_c(c));
|
||||
mk_c(c)->save_object(p);
|
||||
Z3_params r = of_params(p);
|
||||
RETURN_Z3(r);
|
||||
|
|
|
@ -15,7 +15,6 @@ Author:
|
|||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
|
@ -23,8 +22,8 @@ Revision History:
|
|||
#include"pb_decl_plugin.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
Z3_ast Z3_API Z3_mk_atmost(Z3_context c, unsigned num_args,
|
||||
|
||||
Z3_ast Z3_API Z3_mk_atmost(Z3_context c, unsigned num_args,
|
||||
Z3_ast const args[], unsigned k) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_atmost(c, num_args, args, k);
|
||||
|
@ -38,8 +37,21 @@ extern "C" {
|
|||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_atleast(Z3_context c, unsigned num_args,
|
||||
Z3_ast const args[], unsigned k) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_atmost(c, num_args, args, k);
|
||||
RESET_ERROR_CODE();
|
||||
parameter param(k);
|
||||
pb_util util(mk_c(c)->m());
|
||||
ast* a = util.mk_at_least_k(num_args, to_exprs(args), k);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
check_sorts(c, a);
|
||||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_pble(Z3_context c, unsigned num_args,
|
||||
Z3_ast Z3_API Z3_mk_pble(Z3_context c, unsigned num_args,
|
||||
Z3_ast const args[], int _coeffs[],
|
||||
int k) {
|
||||
Z3_TRY;
|
||||
|
@ -57,5 +69,41 @@ extern "C" {
|
|||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_pbge(Z3_context c, unsigned num_args,
|
||||
Z3_ast const args[], int _coeffs[],
|
||||
int k) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_pble(c, num_args, args, _coeffs, k);
|
||||
RESET_ERROR_CODE();
|
||||
pb_util util(mk_c(c)->m());
|
||||
vector<rational> coeffs;
|
||||
for (unsigned i = 0; i < num_args; ++i) {
|
||||
coeffs.push_back(rational(_coeffs[i]));
|
||||
}
|
||||
ast* a = util.mk_ge(num_args, coeffs.c_ptr(), to_exprs(args), rational(k));
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
check_sorts(c, a);
|
||||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_pbeq(Z3_context c, unsigned num_args,
|
||||
Z3_ast const args[], int _coeffs[],
|
||||
int k) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_pble(c, num_args, args, _coeffs, k);
|
||||
RESET_ERROR_CODE();
|
||||
pb_util util(mk_c(c)->m());
|
||||
vector<rational> coeffs;
|
||||
for (unsigned i = 0; i < num_args; ++i) {
|
||||
coeffs.push_back(rational(_coeffs[i]));
|
||||
}
|
||||
ast* a = util.mk_eq(num_args, coeffs.c_ptr(), to_exprs(args), rational(k));
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
check_sorts(c, a);
|
||||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -14,9 +14,8 @@ Author:
|
|||
Leonardo de Moura (leonardo) 2012-12-08
|
||||
|
||||
Notes:
|
||||
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
|
@ -35,7 +34,7 @@ namespace api {
|
|||
|
||||
pmanager::~pmanager() {
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
@ -53,7 +52,7 @@ extern "C" {
|
|||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
}
|
||||
Z3_ast_vector_ref* result = alloc(Z3_ast_vector_ref, mk_c(c)->m());
|
||||
Z3_ast_vector_ref* result = alloc(Z3_ast_vector_ref, *mk_c(c), mk_c(c)->m());
|
||||
mk_c(c)->save_object(result);
|
||||
if (converter.is_var(to_expr(x))) {
|
||||
expr2var const & mapping = converter.get_mapping();
|
||||
|
|
|
@ -15,7 +15,6 @@ Author:
|
|||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
|
@ -26,17 +25,17 @@ Revision History:
|
|||
extern "C" {
|
||||
|
||||
Z3_ast Z3_API Z3_mk_quantifier(
|
||||
Z3_context c,
|
||||
Z3_bool is_forall,
|
||||
unsigned weight,
|
||||
unsigned num_patterns, Z3_pattern const patterns[],
|
||||
unsigned num_decls, Z3_sort const sorts[],
|
||||
Z3_symbol const decl_names[],
|
||||
Z3_ast body)
|
||||
Z3_context c,
|
||||
Z3_bool is_forall,
|
||||
unsigned weight,
|
||||
unsigned num_patterns, Z3_pattern const patterns[],
|
||||
unsigned num_decls, Z3_sort const sorts[],
|
||||
Z3_symbol const decl_names[],
|
||||
Z3_ast body)
|
||||
{
|
||||
return Z3_mk_quantifier_ex(
|
||||
c,
|
||||
is_forall,
|
||||
c,
|
||||
is_forall,
|
||||
weight,
|
||||
0,
|
||||
0,
|
||||
|
@ -50,15 +49,15 @@ extern "C" {
|
|||
}
|
||||
|
||||
Z3_ast mk_quantifier_ex_core(
|
||||
Z3_context c,
|
||||
Z3_bool is_forall,
|
||||
unsigned weight,
|
||||
Z3_context c,
|
||||
Z3_bool is_forall,
|
||||
unsigned weight,
|
||||
Z3_symbol quantifier_id,
|
||||
Z3_symbol skolem_id,
|
||||
unsigned num_patterns, Z3_pattern const patterns[],
|
||||
unsigned num_no_patterns, Z3_ast const no_patterns[],
|
||||
unsigned num_decls, Z3_sort const sorts[],
|
||||
Z3_symbol const decl_names[],
|
||||
unsigned num_patterns, Z3_pattern const patterns[],
|
||||
unsigned num_no_patterns, Z3_ast const no_patterns[],
|
||||
unsigned num_decls, Z3_sort const sorts[],
|
||||
Z3_symbol const decl_names[],
|
||||
Z3_ast body) {
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
|
@ -86,9 +85,9 @@ extern "C" {
|
|||
expr_ref result(mk_c(c)->m());
|
||||
if (num_decls > 0) {
|
||||
result = mk_c(c)->m().mk_quantifier(
|
||||
(0 != is_forall),
|
||||
names.size(), ts, names.c_ptr(), to_expr(body),
|
||||
weight,
|
||||
(0 != is_forall),
|
||||
names.size(), ts, names.c_ptr(), to_expr(body),
|
||||
weight,
|
||||
to_symbol(quantifier_id),
|
||||
to_symbol(skolem_id),
|
||||
num_patterns, ps,
|
||||
|
@ -104,44 +103,44 @@ extern "C" {
|
|||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_quantifier_ex(
|
||||
Z3_context c,
|
||||
Z3_bool is_forall,
|
||||
unsigned weight,
|
||||
Z3_context c,
|
||||
Z3_bool is_forall,
|
||||
unsigned weight,
|
||||
Z3_symbol quantifier_id,
|
||||
Z3_symbol skolem_id,
|
||||
unsigned num_patterns, Z3_pattern const patterns[],
|
||||
unsigned num_no_patterns, Z3_ast const no_patterns[],
|
||||
unsigned num_decls, Z3_sort const sorts[],
|
||||
Z3_symbol const decl_names[],
|
||||
unsigned num_patterns, Z3_pattern const patterns[],
|
||||
unsigned num_no_patterns, Z3_ast const no_patterns[],
|
||||
unsigned num_decls, Z3_sort const sorts[],
|
||||
Z3_symbol const decl_names[],
|
||||
Z3_ast body)
|
||||
{
|
||||
LOG_Z3_mk_quantifier_ex(c, is_forall, weight, quantifier_id, skolem_id, num_patterns, patterns,
|
||||
LOG_Z3_mk_quantifier_ex(c, is_forall, weight, quantifier_id, skolem_id, num_patterns, patterns,
|
||||
num_no_patterns, no_patterns, num_decls, sorts, decl_names, body);
|
||||
Z3_ast r = mk_quantifier_ex_core(c, is_forall, weight, quantifier_id, skolem_id, num_patterns, patterns,
|
||||
Z3_ast r = mk_quantifier_ex_core(c, is_forall, weight, quantifier_id, skolem_id, num_patterns, patterns,
|
||||
num_no_patterns, no_patterns, num_decls, sorts, decl_names, body);
|
||||
RETURN_Z3(r);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_forall(Z3_context c,
|
||||
unsigned weight,
|
||||
unsigned num_patterns, Z3_pattern const patterns[],
|
||||
unsigned num_decls, Z3_sort const types[],
|
||||
Z3_symbol const decl_names[],
|
||||
|
||||
Z3_ast Z3_API Z3_mk_forall(Z3_context c,
|
||||
unsigned weight,
|
||||
unsigned num_patterns, Z3_pattern const patterns[],
|
||||
unsigned num_decls, Z3_sort const types[],
|
||||
Z3_symbol const decl_names[],
|
||||
Z3_ast body) {
|
||||
return Z3_mk_quantifier(c, 1, weight, num_patterns, patterns, num_decls, types, decl_names, body);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_exists(Z3_context c,
|
||||
unsigned weight,
|
||||
unsigned num_patterns, Z3_pattern const patterns[],
|
||||
unsigned num_decls, Z3_sort const types[],
|
||||
Z3_symbol const decl_names[],
|
||||
|
||||
Z3_ast Z3_API Z3_mk_exists(Z3_context c,
|
||||
unsigned weight,
|
||||
unsigned num_patterns, Z3_pattern const patterns[],
|
||||
unsigned num_decls, Z3_sort const types[],
|
||||
Z3_symbol const decl_names[],
|
||||
Z3_ast body) {
|
||||
return Z3_mk_quantifier(c, 0, weight, num_patterns, patterns, num_decls, types, decl_names, body);
|
||||
}
|
||||
|
||||
|
||||
Z3_ast Z3_API Z3_mk_quantifier_const_ex(Z3_context c,
|
||||
Z3_ast Z3_API Z3_mk_quantifier_const_ex(Z3_context c,
|
||||
Z3_bool is_forall,
|
||||
unsigned weight,
|
||||
Z3_symbol quantifier_id,
|
||||
|
@ -166,7 +165,7 @@ extern "C" {
|
|||
}
|
||||
if (num_bound == 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_USAGE);
|
||||
RETURN_Z3(0);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
for (unsigned i = 0; i < num_bound; ++i) {
|
||||
app* a = to_app(bound[i]);
|
||||
|
@ -191,7 +190,7 @@ extern "C" {
|
|||
app* pat = to_pattern(patterns[i]);
|
||||
SASSERT(mk_c(c)->m().is_pattern(pat));
|
||||
expr_abstract(mk_c(c)->m(), 0, num_bound, bound_asts.c_ptr(), pat, result);
|
||||
SASSERT(result.get()->get_kind() == AST_APP);
|
||||
SASSERT(result.get()->get_kind() == AST_APP);
|
||||
pinned.push_back(result.get());
|
||||
SASSERT(mk_c(c)->m().is_pattern(result.get()));
|
||||
_patterns.push_back(of_pattern(result.get()));
|
||||
|
@ -205,25 +204,25 @@ extern "C" {
|
|||
}
|
||||
app* pat = to_app(to_expr(no_patterns[i]));
|
||||
expr_abstract(mk_c(c)->m(), 0, num_bound, bound_asts.c_ptr(), pat, result);
|
||||
SASSERT(result.get()->get_kind() == AST_APP);
|
||||
SASSERT(result.get()->get_kind() == AST_APP);
|
||||
pinned.push_back(result.get());
|
||||
_no_patterns.push_back(of_ast(result.get()));
|
||||
}
|
||||
expr_ref abs_body(mk_c(c)->m());
|
||||
expr_abstract(mk_c(c)->m(), 0, num_bound, bound_asts.c_ptr(), to_expr(body), abs_body);
|
||||
|
||||
Z3_ast result = mk_quantifier_ex_core(c, is_forall, weight,
|
||||
Z3_ast result = mk_quantifier_ex_core(c, is_forall, weight,
|
||||
quantifier_id,
|
||||
skolem_id,
|
||||
num_patterns, _patterns.c_ptr(),
|
||||
num_patterns, _patterns.c_ptr(),
|
||||
num_no_patterns, _no_patterns.c_ptr(),
|
||||
names.size(), types.c_ptr(), names.c_ptr(),
|
||||
names.size(), types.c_ptr(), names.c_ptr(),
|
||||
of_ast(abs_body.get()));
|
||||
RETURN_Z3(result);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_quantifier_const(Z3_context c,
|
||||
Z3_ast Z3_API Z3_mk_quantifier_const(Z3_context c,
|
||||
Z3_bool is_forall,
|
||||
unsigned weight,
|
||||
unsigned num_bound,
|
||||
|
@ -231,14 +230,14 @@ extern "C" {
|
|||
unsigned num_patterns,
|
||||
Z3_pattern const patterns[],
|
||||
Z3_ast body) {
|
||||
return Z3_mk_quantifier_const_ex(c, is_forall, weight, 0, 0,
|
||||
num_bound, bound,
|
||||
return Z3_mk_quantifier_const_ex(c, is_forall, weight, 0, 0,
|
||||
num_bound, bound,
|
||||
num_patterns, patterns,
|
||||
0, 0,
|
||||
body);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_forall_const(Z3_context c,
|
||||
Z3_ast Z3_API Z3_mk_forall_const(Z3_context c,
|
||||
unsigned weight,
|
||||
unsigned num_bound,
|
||||
Z3_app const bound[],
|
||||
|
@ -248,7 +247,7 @@ extern "C" {
|
|||
return Z3_mk_quantifier_const(c, true, weight, num_bound, bound, num_patterns, patterns, body);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_exists_const(Z3_context c,
|
||||
Z3_ast Z3_API Z3_mk_exists_const(Z3_context c,
|
||||
unsigned weight,
|
||||
unsigned num_bound,
|
||||
Z3_app const bound[],
|
||||
|
@ -257,7 +256,7 @@ extern "C" {
|
|||
Z3_ast body) {
|
||||
return Z3_mk_quantifier_const(c, false, weight, num_bound, bound, num_patterns, patterns, body);
|
||||
}
|
||||
|
||||
|
||||
Z3_pattern Z3_API Z3_mk_pattern(Z3_context c, unsigned num_patterns, Z3_ast const terms[]) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_pattern(c, num_patterns, terms);
|
||||
|
@ -273,7 +272,7 @@ extern "C" {
|
|||
RETURN_Z3(of_pattern(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
Z3_ast Z3_API Z3_mk_bound(Z3_context c, unsigned index, Z3_sort ty) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_bound(c, index, ty);
|
||||
|
@ -436,7 +435,7 @@ extern "C" {
|
|||
else {
|
||||
SET_ERROR_CODE(Z3_SORT_ERROR);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
@ -450,7 +449,7 @@ extern "C" {
|
|||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_SORT_ERROR);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
@ -471,13 +470,13 @@ extern "C" {
|
|||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_pattern_to_ast(Z3_context c, Z3_pattern p) {
|
||||
Z3_ast Z3_API Z3_pattern_to_ast(Z3_context c, Z3_pattern p) {
|
||||
RESET_ERROR_CODE();
|
||||
return (Z3_ast)(p);
|
||||
}
|
||||
return (Z3_ast)(p);
|
||||
}
|
||||
|
||||
Z3_API char const * Z3_pattern_to_string(Z3_context c, Z3_pattern p) {
|
||||
return Z3_ast_to_string(c, reinterpret_cast<Z3_ast>(p));
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -16,7 +16,6 @@ Author:
|
|||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
|
@ -28,7 +27,7 @@ extern "C" {
|
|||
Z3_sort Z3_API Z3_mk_seq_sort(Z3_context c, Z3_sort domain) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_seq_sort(c, domain);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
sort * ty = mk_c(c)->sutil().str.mk_seq(to_sort(domain));
|
||||
mk_c(c)->save_ast_trail(ty);
|
||||
RETURN_Z3(of_sort(ty));
|
||||
|
@ -38,7 +37,7 @@ extern "C" {
|
|||
Z3_sort Z3_API Z3_mk_re_sort(Z3_context c, Z3_sort domain) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_re_sort(c, domain);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
sort * ty = mk_c(c)->sutil().re.mk_re(to_sort(domain));
|
||||
mk_c(c)->save_ast_trail(ty);
|
||||
RETURN_Z3(of_sort(ty));
|
||||
|
@ -48,14 +47,14 @@ extern "C" {
|
|||
Z3_ast Z3_API Z3_mk_string(Z3_context c, Z3_string str) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_string(c, str);
|
||||
RESET_ERROR_CODE();
|
||||
RESET_ERROR_CODE();
|
||||
zstring s(str, zstring::ascii);
|
||||
app* a = mk_c(c)->sutil().str.mk_string(s);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
Z3_sort Z3_API Z3_mk_string_sort(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_string_sort(c);
|
||||
|
@ -71,8 +70,8 @@ extern "C" {
|
|||
LOG_Z3_is_seq_sort(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
bool result = mk_c(c)->sutil().is_seq(to_sort(s));
|
||||
return result?Z3_TRUE:Z3_FALSE;
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
return result?Z3_TRUE:Z3_FALSE;
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_is_re_sort(Z3_context c, Z3_sort s) {
|
||||
|
@ -80,8 +79,8 @@ extern "C" {
|
|||
LOG_Z3_is_re_sort(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
bool result = mk_c(c)->sutil().is_re(to_sort(s));
|
||||
return result?Z3_TRUE:Z3_FALSE;
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
return result?Z3_TRUE:Z3_FALSE;
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_is_string_sort(Z3_context c, Z3_sort s) {
|
||||
|
@ -89,8 +88,8 @@ extern "C" {
|
|||
LOG_Z3_is_string_sort(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
bool result = mk_c(c)->sutil().is_string(to_sort(s));
|
||||
return result?Z3_TRUE:Z3_FALSE;
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
return result?Z3_TRUE:Z3_FALSE;
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_is_string(Z3_context c, Z3_ast s) {
|
||||
|
@ -98,7 +97,7 @@ extern "C" {
|
|||
LOG_Z3_is_string(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
bool result = mk_c(c)->sutil().str.is_string(to_expr(s));
|
||||
return result?Z3_TRUE:Z3_FALSE;
|
||||
return result?Z3_TRUE:Z3_FALSE;
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
|
@ -116,16 +115,19 @@ extern "C" {
|
|||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_seq_empty(Z3_context c, Z3_sort seq) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_seq_empty(c, seq);
|
||||
RESET_ERROR_CODE();
|
||||
app* a = mk_c(c)->sutil().str.mk_empty(to_sort(seq));
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
#define MK_SORTED(NAME, FN ) \
|
||||
Z3_ast Z3_API NAME(Z3_context c, Z3_sort s) { \
|
||||
Z3_TRY; \
|
||||
LOG_ ## NAME(c, s); \
|
||||
RESET_ERROR_CODE(); \
|
||||
app* a = FN(to_sort(s)); \
|
||||
mk_c(c)->save_ast_trail(a); \
|
||||
RETURN_Z3(of_ast(a)); \
|
||||
Z3_CATCH_RETURN(0); \
|
||||
}
|
||||
|
||||
MK_SORTED(Z3_mk_seq_empty, mk_c(c)->sutil().str.mk_empty);
|
||||
|
||||
MK_UNARY(Z3_mk_seq_unit, mk_c(c)->get_seq_fid(), OP_SEQ_UNIT, SKIP);
|
||||
MK_NARY(Z3_mk_seq_concat, mk_c(c)->get_seq_fid(), OP_SEQ_CONCAT, SKIP);
|
||||
MK_BINARY(Z3_mk_seq_prefix, mk_c(c)->get_seq_fid(), OP_SEQ_PREFIX, SKIP);
|
||||
|
@ -139,12 +141,31 @@ extern "C" {
|
|||
MK_UNARY(Z3_mk_seq_to_re, mk_c(c)->get_seq_fid(), OP_SEQ_TO_RE, SKIP);
|
||||
MK_BINARY(Z3_mk_seq_in_re, mk_c(c)->get_seq_fid(), OP_SEQ_IN_RE, SKIP);
|
||||
|
||||
MK_UNARY(Z3_mk_int_to_str, mk_c(c)->get_seq_fid(), OP_STRING_ITOS, SKIP);
|
||||
MK_UNARY(Z3_mk_str_to_int, mk_c(c)->get_seq_fid(), OP_STRING_STOI, SKIP);
|
||||
|
||||
|
||||
Z3_ast Z3_API Z3_mk_re_loop(Z3_context c, Z3_ast r, unsigned lo, unsigned hi) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_re_loop(c, r, lo, hi);
|
||||
RESET_ERROR_CODE();
|
||||
app* a = hi == 0 ? mk_c(c)->sutil().re.mk_loop(to_expr(r), lo) : mk_c(c)->sutil().re.mk_loop(to_expr(r), lo, hi);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
MK_UNARY(Z3_mk_re_plus, mk_c(c)->get_seq_fid(), OP_RE_PLUS, SKIP);
|
||||
MK_UNARY(Z3_mk_re_star, mk_c(c)->get_seq_fid(), OP_RE_STAR, SKIP);
|
||||
MK_UNARY(Z3_mk_re_option, mk_c(c)->get_seq_fid(), OP_RE_OPTION, SKIP);
|
||||
MK_UNARY(Z3_mk_re_complement, mk_c(c)->get_seq_fid(), OP_RE_COMPLEMENT, SKIP);
|
||||
MK_NARY(Z3_mk_re_union, mk_c(c)->get_seq_fid(), OP_RE_UNION, SKIP);
|
||||
MK_NARY(Z3_mk_re_intersect, mk_c(c)->get_seq_fid(), OP_RE_INTERSECT, SKIP);
|
||||
MK_NARY(Z3_mk_re_concat, mk_c(c)->get_seq_fid(), OP_RE_CONCAT, SKIP);
|
||||
MK_BINARY(Z3_mk_re_range, mk_c(c)->get_seq_fid(), OP_RE_RANGE, SKIP);
|
||||
|
||||
MK_SORTED(Z3_mk_re_empty, mk_c(c)->sutil().re.mk_empty);
|
||||
MK_SORTED(Z3_mk_re_full, mk_c(c)->sutil().re.mk_full);
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ Revision History:
|
|||
#include"smt_strategic_solver.h"
|
||||
#include"smt_solver.h"
|
||||
#include"smt_implied_equalities.h"
|
||||
#include"smt_logics.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
@ -58,7 +59,7 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_mk_simple_solver(c);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_solver_ref * s = alloc(Z3_solver_ref, mk_smt_solver_factory());
|
||||
Z3_solver_ref * s = alloc(Z3_solver_ref, *mk_c(c), mk_smt_solver_factory());
|
||||
mk_c(c)->save_object(s);
|
||||
Z3_solver r = of_solver(s);
|
||||
RETURN_Z3(r);
|
||||
|
@ -69,7 +70,7 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_mk_solver(c);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_solver_ref * s = alloc(Z3_solver_ref, mk_smt_strategic_solver_factory());
|
||||
Z3_solver_ref * s = alloc(Z3_solver_ref, *mk_c(c), mk_smt_strategic_solver_factory());
|
||||
mk_c(c)->save_object(s);
|
||||
Z3_solver r = of_solver(s);
|
||||
RETURN_Z3(r);
|
||||
|
@ -80,10 +81,18 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_mk_solver_for_logic(c, logic);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_solver_ref * s = alloc(Z3_solver_ref, mk_smt_strategic_solver_factory(to_symbol(logic)));
|
||||
mk_c(c)->save_object(s);
|
||||
Z3_solver r = of_solver(s);
|
||||
RETURN_Z3(r);
|
||||
if (!smt_logics::supported_logic(to_symbol(logic))) {
|
||||
std::ostringstream strm;
|
||||
strm << "logic '" << to_symbol(logic) << "' is not recognized";
|
||||
throw default_exception(strm.str());
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
else {
|
||||
Z3_solver_ref * s = alloc(Z3_solver_ref, *mk_c(c), mk_smt_strategic_solver_factory(to_symbol(logic)));
|
||||
mk_c(c)->save_object(s);
|
||||
Z3_solver r = of_solver(s);
|
||||
RETURN_Z3(r);
|
||||
}
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
@ -91,7 +100,7 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_mk_solver_from_tactic(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_solver_ref * s = alloc(Z3_solver_ref, mk_tactic2solver_factory(to_tactic_ref(t)));
|
||||
Z3_solver_ref * s = alloc(Z3_solver_ref, *mk_c(c), mk_tactic2solver_factory(to_tactic_ref(t)));
|
||||
mk_c(c)->save_object(s);
|
||||
Z3_solver r = of_solver(s);
|
||||
RETURN_Z3(r);
|
||||
|
@ -103,7 +112,7 @@ extern "C" {
|
|||
LOG_Z3_solver_translate(c, s, target);
|
||||
RESET_ERROR_CODE();
|
||||
params_ref const& p = to_solver(s)->m_params;
|
||||
Z3_solver_ref * sr = alloc(Z3_solver_ref, 0);
|
||||
Z3_solver_ref * sr = alloc(Z3_solver_ref, *mk_c(target), 0);
|
||||
init_solver(c, s);
|
||||
sr->m_solver = to_solver(s)->m_solver->translate(mk_c(target)->m(), p);
|
||||
mk_c(target)->save_object(sr);
|
||||
|
@ -134,7 +143,7 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_solver_get_param_descrs(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_param_descrs_ref * d = alloc(Z3_param_descrs_ref);
|
||||
Z3_param_descrs_ref * d = alloc(Z3_param_descrs_ref, *mk_c(c));
|
||||
mk_c(c)->save_object(d);
|
||||
bool initialized = to_solver(s)->m_solver.get() != 0;
|
||||
if (!initialized)
|
||||
|
@ -255,7 +264,7 @@ extern "C" {
|
|||
LOG_Z3_solver_get_assertions(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
init_solver(c, s);
|
||||
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, mk_c(c)->m());
|
||||
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, *mk_c(c), mk_c(c)->m());
|
||||
mk_c(c)->save_object(v);
|
||||
unsigned sz = to_solver_ref(s)->get_num_assertions();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
|
@ -323,7 +332,7 @@ extern "C" {
|
|||
SET_ERROR_CODE(Z3_INVALID_USAGE);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
Z3_model_ref * m_ref = alloc(Z3_model_ref);
|
||||
Z3_model_ref * m_ref = alloc(Z3_model_ref, *mk_c(c));
|
||||
m_ref->m_model = _m;
|
||||
mk_c(c)->save_object(m_ref);
|
||||
RETURN_Z3(of_model(m_ref));
|
||||
|
@ -352,7 +361,7 @@ extern "C" {
|
|||
init_solver(c, s);
|
||||
ptr_vector<expr> core;
|
||||
to_solver_ref(s)->get_unsat_core(core);
|
||||
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, mk_c(c)->m());
|
||||
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, *mk_c(c), mk_c(c)->m());
|
||||
mk_c(c)->save_object(v);
|
||||
for (unsigned i = 0; i < core.size(); i++) {
|
||||
v->m_ast_vector.push_back(core[i]);
|
||||
|
@ -375,7 +384,7 @@ extern "C" {
|
|||
LOG_Z3_solver_get_statistics(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
init_solver(c, s);
|
||||
Z3_stats_ref * st = alloc(Z3_stats_ref);
|
||||
Z3_stats_ref * st = alloc(Z3_stats_ref, *mk_c(c));
|
||||
to_solver_ref(s)->collect_statistics(st->m_stats);
|
||||
get_memory_statistics(st->m_stats);
|
||||
get_rlimit_statistics(mk_c(c)->m().limit(), st->m_stats);
|
||||
|
@ -413,4 +422,59 @@ extern "C" {
|
|||
Z3_CATCH_RETURN(Z3_L_UNDEF);
|
||||
}
|
||||
|
||||
Z3_lbool Z3_API Z3_solver_get_consequences(Z3_context c,
|
||||
Z3_solver s,
|
||||
Z3_ast_vector assumptions,
|
||||
Z3_ast_vector variables,
|
||||
Z3_ast_vector consequences) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_get_consequences(c, s, assumptions, variables, consequences);
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_SEARCHING(c);
|
||||
init_solver(c, s);
|
||||
expr_ref_vector _assumptions(m), _consequences(m), _variables(m);
|
||||
ast_ref_vector const& __assumptions = to_ast_vector_ref(assumptions);
|
||||
unsigned sz = __assumptions.size();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
if (!is_expr(__assumptions[i])) {
|
||||
SET_ERROR_CODE(Z3_INVALID_USAGE);
|
||||
return Z3_L_UNDEF;
|
||||
}
|
||||
_assumptions.push_back(to_expr(__assumptions[i]));
|
||||
}
|
||||
ast_ref_vector const& __variables = to_ast_vector_ref(variables);
|
||||
sz = __variables.size();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
if (!is_expr(__variables[i])) {
|
||||
SET_ERROR_CODE(Z3_INVALID_USAGE);
|
||||
return Z3_L_UNDEF;
|
||||
}
|
||||
_variables.push_back(to_expr(__variables[i]));
|
||||
}
|
||||
lbool result = l_undef;
|
||||
unsigned timeout = to_solver(s)->m_params.get_uint("timeout", mk_c(c)->get_timeout());
|
||||
unsigned rlimit = to_solver(s)->m_params.get_uint("rlimit", mk_c(c)->get_rlimit());
|
||||
bool use_ctrl_c = to_solver(s)->m_params.get_bool("ctrl_c", false);
|
||||
cancel_eh<reslimit> eh(mk_c(c)->m().limit());
|
||||
api::context::set_interruptable si(*(mk_c(c)), eh);
|
||||
{
|
||||
scoped_ctrl_c ctrlc(eh, false, use_ctrl_c);
|
||||
scoped_timer timer(timeout, &eh);
|
||||
scoped_rlimit _rlimit(mk_c(c)->m().limit(), rlimit);
|
||||
try {
|
||||
result = to_solver_ref(s)->get_consequences(_assumptions, _variables, _consequences);
|
||||
}
|
||||
catch (z3_exception & ex) {
|
||||
mk_c(c)->handle_exception(ex);
|
||||
return Z3_L_UNDEF;
|
||||
}
|
||||
}
|
||||
for (unsigned i = 0; i < _consequences.size(); ++i) {
|
||||
to_ast_vector_ref(consequences).push_back(_consequences[i].get());
|
||||
}
|
||||
return static_cast<Z3_lbool>(result);
|
||||
Z3_CATCH_RETURN(Z3_L_UNDEF);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -26,7 +26,7 @@ struct Z3_solver_ref : public api::object {
|
|||
ref<solver> m_solver;
|
||||
params_ref m_params;
|
||||
symbol m_logic;
|
||||
Z3_solver_ref(solver_factory * f):m_solver_factory(f), m_solver(0), m_logic(symbol::null) {}
|
||||
Z3_solver_ref(api::context& c, solver_factory * f): api::object(c), m_solver_factory(f), m_solver(0), m_logic(symbol::null) {}
|
||||
virtual ~Z3_solver_ref() {}
|
||||
};
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ Revision History:
|
|||
|
||||
struct Z3_stats_ref : public api::object {
|
||||
statistics m_stats;
|
||||
Z3_stats_ref(api::context& c): api::object(c) {}
|
||||
virtual ~Z3_stats_ref() {}
|
||||
};
|
||||
|
||||
|
|
|
@ -25,13 +25,13 @@ Revision History:
|
|||
#include"cancel_eh.h"
|
||||
#include"scoped_timer.h"
|
||||
|
||||
Z3_apply_result_ref::Z3_apply_result_ref(ast_manager & m):m_core(m) {
|
||||
Z3_apply_result_ref::Z3_apply_result_ref(api::context& c, ast_manager & m): api::object(c), m_core(m) {
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
#define RETURN_TACTIC(_t_) { \
|
||||
Z3_tactic_ref * _ref_ = alloc(Z3_tactic_ref); \
|
||||
Z3_tactic_ref * _ref_ = alloc(Z3_tactic_ref, *mk_c(c)); \
|
||||
_ref_->m_tactic = _t_; \
|
||||
mk_c(c)->save_object(_ref_); \
|
||||
Z3_tactic _result_ = of_tactic(_ref_); \
|
||||
|
@ -39,7 +39,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
#define RETURN_PROBE(_t_) { \
|
||||
Z3_probe_ref * _ref_ = alloc(Z3_probe_ref); \
|
||||
Z3_probe_ref * _ref_ = alloc(Z3_probe_ref, *mk_c(c)); \
|
||||
_ref_->m_probe = _t_; \
|
||||
mk_c(c)->save_object(_ref_); \
|
||||
Z3_probe _result_ = of_probe(_ref_); \
|
||||
|
@ -367,7 +367,7 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
LOG_Z3_tactic_get_param_descrs(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_param_descrs_ref * d = alloc(Z3_param_descrs_ref);
|
||||
Z3_param_descrs_ref * d = alloc(Z3_param_descrs_ref, *mk_c(c));
|
||||
mk_c(c)->save_object(d);
|
||||
to_tactic_ref(t)->collect_param_descrs(d->m_descrs);
|
||||
Z3_param_descrs r = of_param_descrs(d);
|
||||
|
@ -404,7 +404,7 @@ extern "C" {
|
|||
static Z3_apply_result _tactic_apply(Z3_context c, Z3_tactic t, Z3_goal g, params_ref p) {
|
||||
goal_ref new_goal;
|
||||
new_goal = alloc(goal, *to_goal_ref(g));
|
||||
Z3_apply_result_ref * ref = alloc(Z3_apply_result_ref, mk_c(c)->m());
|
||||
Z3_apply_result_ref * ref = alloc(Z3_apply_result_ref, (*mk_c(c)), mk_c(c)->m());
|
||||
mk_c(c)->save_object(ref);
|
||||
|
||||
unsigned timeout = p.get_uint("timeout", UINT_MAX);
|
||||
|
@ -505,7 +505,7 @@ extern "C" {
|
|||
SET_ERROR_CODE(Z3_IOB);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
Z3_goal_ref * g = alloc(Z3_goal_ref);
|
||||
Z3_goal_ref * g = alloc(Z3_goal_ref, *mk_c(c));
|
||||
g->m_goal = to_apply_result(r)->m_subgoals[i];
|
||||
mk_c(c)->save_object(g);
|
||||
Z3_goal result = of_goal(g);
|
||||
|
@ -524,7 +524,7 @@ extern "C" {
|
|||
model_ref new_m = to_model_ref(m)->copy();
|
||||
if (to_apply_result(r)->m_mc)
|
||||
to_apply_result(r)->m_mc->operator()(new_m, i);
|
||||
Z3_model_ref * m_ref = alloc(Z3_model_ref);
|
||||
Z3_model_ref * m_ref = alloc(Z3_model_ref, *mk_c(c));
|
||||
m_ref->m_model = new_m;
|
||||
mk_c(c)->save_object(m_ref);
|
||||
RETURN_Z3(of_model(m_ref));
|
||||
|
|
|
@ -21,13 +21,20 @@ Revision History:
|
|||
#include"api_goal.h"
|
||||
#include"tactical.h"
|
||||
|
||||
namespace api {
|
||||
class context;
|
||||
}
|
||||
|
||||
|
||||
struct Z3_tactic_ref : public api::object {
|
||||
tactic_ref m_tactic;
|
||||
Z3_tactic_ref(api::context& c): api::object(c) {}
|
||||
virtual ~Z3_tactic_ref() {}
|
||||
};
|
||||
|
||||
struct Z3_probe_ref : public api::object {
|
||||
probe_ref m_probe;
|
||||
Z3_probe_ref(api::context& c):api::object(c) {}
|
||||
virtual ~Z3_probe_ref() {}
|
||||
};
|
||||
|
||||
|
@ -44,7 +51,7 @@ struct Z3_apply_result_ref : public api::object {
|
|||
model_converter_ref m_mc;
|
||||
proof_converter_ref m_pc;
|
||||
expr_dependency_ref m_core;
|
||||
Z3_apply_result_ref(ast_manager & m);
|
||||
Z3_apply_result_ref(api::context& c, ast_manager & m);
|
||||
virtual ~Z3_apply_result_ref() {}
|
||||
};
|
||||
|
||||
|
|
|
@ -31,15 +31,20 @@ Revision History:
|
|||
#define CHECK_REF_COUNT(a) (reinterpret_cast<ast const*>(a)->get_ref_count() > 0)
|
||||
|
||||
namespace api {
|
||||
class context;
|
||||
|
||||
// Generic wrapper for ref-count objects exposed by the API
|
||||
class object {
|
||||
unsigned m_ref_count;
|
||||
unsigned m_id;
|
||||
context& m_context;
|
||||
public:
|
||||
object():m_ref_count(0) {}
|
||||
object(context& c);
|
||||
virtual ~object() {}
|
||||
unsigned ref_count() const { return m_ref_count; }
|
||||
void inc_ref() { m_ref_count++; }
|
||||
void dec_ref() { SASSERT(m_ref_count > 0); m_ref_count--; if (m_ref_count == 0) dealloc(this); }
|
||||
unsigned id() const { return m_id; }
|
||||
void inc_ref();
|
||||
void dec_ref();
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -82,6 +87,7 @@ inline lbool to_lbool(Z3_lbool b) { return static_cast<lbool>(b); }
|
|||
|
||||
struct Z3_params_ref : public api::object {
|
||||
params_ref m_params;
|
||||
Z3_params_ref(api::context& c): api::object(c) {}
|
||||
virtual ~Z3_params_ref() {}
|
||||
};
|
||||
|
||||
|
@ -91,6 +97,7 @@ inline params_ref to_param_ref(Z3_params p) { return p == 0 ? params_ref() : to_
|
|||
|
||||
struct Z3_param_descrs_ref : public api::object {
|
||||
param_descrs m_descrs;
|
||||
Z3_param_descrs_ref(api::context& c): api::object(c) {}
|
||||
virtual ~Z3_param_descrs_ref() {}
|
||||
};
|
||||
|
||||
|
|
|
@ -63,7 +63,6 @@ namespace z3 {
|
|||
class func_entry;
|
||||
class statistics;
|
||||
class apply_result;
|
||||
class fixedpoint;
|
||||
template<typename T> class ast_vector_tpl;
|
||||
typedef ast_vector_tpl<ast> ast_vector;
|
||||
typedef ast_vector_tpl<expr> expr_vector;
|
||||
|
@ -122,20 +121,30 @@ namespace z3 {
|
|||
unsat, sat, unknown
|
||||
};
|
||||
|
||||
inline check_result to_check_result(Z3_lbool l) {
|
||||
if (l == Z3_L_TRUE) return sat;
|
||||
else if (l == Z3_L_FALSE) return unsat;
|
||||
return unknown;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief A Context manages all other Z3 objects, global configuration options, etc.
|
||||
*/
|
||||
class context {
|
||||
bool m_enable_exceptions;
|
||||
Z3_context m_ctx;
|
||||
static void error_handler(Z3_context c, Z3_error_code e) { /* do nothing */ }
|
||||
static void error_handler(Z3_context /*c*/, Z3_error_code /*e*/) { /* do nothing */ }
|
||||
void init(config & c) {
|
||||
m_ctx = Z3_mk_context_rc(c);
|
||||
m_enable_exceptions = true;
|
||||
Z3_set_error_handler(m_ctx, error_handler);
|
||||
Z3_set_ast_print_mode(m_ctx, Z3_PRINT_SMTLIB2_COMPLIANT);
|
||||
}
|
||||
|
||||
void init_interp(config & c) {
|
||||
m_ctx = Z3_mk_interpolation_context(c);
|
||||
m_enable_exceptions = true;
|
||||
Z3_set_error_handler(m_ctx, error_handler);
|
||||
Z3_set_ast_print_mode(m_ctx, Z3_PRINT_SMTLIB2_COMPLIANT);
|
||||
}
|
||||
|
@ -146,19 +155,31 @@ namespace z3 {
|
|||
struct interpolation {};
|
||||
context() { config c; init(c); }
|
||||
context(config & c) { init(c); }
|
||||
context(config & c, interpolation) { init_interp(c); }
|
||||
context(config & c, interpolation) { init_interp(c); }
|
||||
~context() { Z3_del_context(m_ctx); }
|
||||
operator Z3_context() const { return m_ctx; }
|
||||
|
||||
/**
|
||||
\brief Auxiliary method used to check for API usage errors.
|
||||
*/
|
||||
void check_error() const {
|
||||
Z3_error_code check_error() const {
|
||||
Z3_error_code e = Z3_get_error_code(m_ctx);
|
||||
if (e != Z3_OK)
|
||||
if (e != Z3_OK && enable_exceptions())
|
||||
throw exception(Z3_get_error_msg(m_ctx, e));
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief The C++ API uses by defaults exceptions on errors.
|
||||
For applications that don't work well with exceptions (there should be only few)
|
||||
you have the ability to turn off exceptions. The tradeoffs are that applications
|
||||
have to very careful about using check_error() after calls that may result in an errornous
|
||||
state.
|
||||
*/
|
||||
void set_enable_exceptions(bool f) { m_enable_exceptions = f; }
|
||||
|
||||
bool enable_exceptions() const { return m_enable_exceptions; }
|
||||
|
||||
/**
|
||||
\brief Update global parameter \c param with string \c value.
|
||||
*/
|
||||
|
@ -279,6 +300,15 @@ namespace z3 {
|
|||
|
||||
expr num_val(int n, sort const & s);
|
||||
|
||||
/**
|
||||
\brief parsing
|
||||
*/
|
||||
expr parse_string(char const* s);
|
||||
expr parse_file(char const* file);
|
||||
|
||||
expr parse_string(char const* s, sort_vector const& sorts, func_decl_vector const& decls);
|
||||
expr parse_file(char const* s, sort_vector const& sorts, func_decl_vector const& decls);
|
||||
|
||||
/**
|
||||
\brief Interpolation support
|
||||
*/
|
||||
|
@ -315,7 +345,7 @@ namespace z3 {
|
|||
object(context & c):m_ctx(&c) {}
|
||||
object(object const & s):m_ctx(s.m_ctx) {}
|
||||
context & ctx() const { return *m_ctx; }
|
||||
void check_error() const { m_ctx->check_error(); }
|
||||
Z3_error_code check_error() const { return m_ctx->check_error(); }
|
||||
friend void check_context(object const & a, object const & b);
|
||||
};
|
||||
inline void check_context(object const & a, object const & b) { assert(a.m_ctx == b.m_ctx); }
|
||||
|
@ -405,6 +435,8 @@ namespace z3 {
|
|||
Z3_ast_kind kind() const { Z3_ast_kind r = Z3_get_ast_kind(ctx(), m_ast); check_error(); return r; }
|
||||
unsigned hash() const { unsigned r = Z3_get_ast_hash(ctx(), m_ast); check_error(); return r; }
|
||||
friend std::ostream & operator<<(std::ostream & out, ast const & n);
|
||||
std::string to_string() const { return std::string(Z3_ast_to_string(ctx(), m_ast)); }
|
||||
|
||||
|
||||
/**
|
||||
\brief Return true if the ASTs are structurally identical.
|
||||
|
@ -435,7 +467,10 @@ namespace z3 {
|
|||
\brief Return the internal sort kind.
|
||||
*/
|
||||
Z3_sort_kind sort_kind() const { return Z3_get_sort_kind(*m_ctx, *this); }
|
||||
|
||||
/**
|
||||
\brief Return name of sort.
|
||||
*/
|
||||
symbol name() const { Z3_symbol s = Z3_get_sort_name(ctx(), *this); check_error(); return symbol(ctx(), s); }
|
||||
/**
|
||||
\brief Return true if this sort is the Boolean sort.
|
||||
*/
|
||||
|
@ -654,12 +689,18 @@ namespace z3 {
|
|||
/**
|
||||
\brief Return int value of numeral, throw if result cannot fit in
|
||||
machine int
|
||||
|
||||
It only makes sense to use this function if the caller can ensure that
|
||||
the result is an integer or if exceptions are enabled.
|
||||
If exceptions are disabled, then use the the is_numeral_i function.
|
||||
|
||||
\pre is_numeral()
|
||||
*/
|
||||
int get_numeral_int() const {
|
||||
int result;
|
||||
int result = 0;
|
||||
if (!is_numeral_i(result)) {
|
||||
assert(ctx().enable_exceptions());
|
||||
if (!ctx().enable_exceptions()) return 0;
|
||||
throw exception("numeral does not fit in machine int");
|
||||
}
|
||||
return result;
|
||||
|
@ -668,13 +709,18 @@ namespace z3 {
|
|||
/**
|
||||
\brief Return uint value of numeral, throw if result cannot fit in
|
||||
machine uint
|
||||
|
||||
|
||||
It only makes sense to use this function if the caller can ensure that
|
||||
the result is an integer or if exceptions are enabled.
|
||||
If exceptions are disabled, then use the the is_numeral_u function.
|
||||
\pre is_numeral()
|
||||
*/
|
||||
unsigned get_numeral_uint() const {
|
||||
assert(is_numeral());
|
||||
unsigned result;
|
||||
unsigned result = 0;
|
||||
if (!is_numeral_u(result)) {
|
||||
assert(ctx().enable_exceptions());
|
||||
if (!ctx().enable_exceptions()) return 0;
|
||||
throw exception("numeral does not fit in machine uint");
|
||||
}
|
||||
return result;
|
||||
|
@ -688,8 +734,10 @@ namespace z3 {
|
|||
*/
|
||||
__int64 get_numeral_int64() const {
|
||||
assert(is_numeral());
|
||||
__int64 result;
|
||||
__int64 result = 0;
|
||||
if (!is_numeral_i64(result)) {
|
||||
assert(ctx().enable_exceptions());
|
||||
if (!ctx().enable_exceptions()) return 0;
|
||||
throw exception("numeral does not fit in machine __int64");
|
||||
}
|
||||
return result;
|
||||
|
@ -703,13 +751,33 @@ namespace z3 {
|
|||
*/
|
||||
__uint64 get_numeral_uint64() const {
|
||||
assert(is_numeral());
|
||||
__uint64 result;
|
||||
__uint64 result = 0;
|
||||
if (!is_numeral_u64(result)) {
|
||||
assert(ctx().enable_exceptions());
|
||||
if (!ctx().enable_exceptions()) return 0;
|
||||
throw exception("numeral does not fit in machine __uint64");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Z3_lbool bool_value() const {
|
||||
return Z3_get_bool_value(ctx(), m_ast);
|
||||
}
|
||||
|
||||
expr numerator() const {
|
||||
assert(is_numeral());
|
||||
Z3_ast r = Z3_get_numerator(ctx(), m_ast);
|
||||
check_error();
|
||||
return expr(ctx(),r);
|
||||
}
|
||||
|
||||
|
||||
expr denominator() const {
|
||||
assert(is_numeral());
|
||||
Z3_ast r = Z3_get_denominator(ctx(), m_ast);
|
||||
check_error();
|
||||
return expr(ctx(),r);
|
||||
}
|
||||
|
||||
operator Z3_app() const { assert(is_app()); return reinterpret_cast<Z3_app>(m_ast); }
|
||||
|
||||
|
@ -802,6 +870,9 @@ namespace z3 {
|
|||
friend expr implies(expr const & a, bool b);
|
||||
friend expr implies(bool a, expr const & b);
|
||||
|
||||
friend expr mk_or(expr_vector const& args);
|
||||
friend expr mk_and(expr_vector const& args);
|
||||
|
||||
friend expr ite(expr const & c, expr const & t, expr const & e);
|
||||
|
||||
friend expr distinct(expr_vector const& args);
|
||||
|
@ -824,13 +895,23 @@ namespace z3 {
|
|||
friend expr operator*(expr const & a, int b);
|
||||
friend expr operator*(int a, expr const & b);
|
||||
|
||||
/**
|
||||
\brief Power operator
|
||||
*/
|
||||
/* \brief Power operator */
|
||||
friend expr pw(expr const & a, expr const & b);
|
||||
friend expr pw(expr const & a, int b);
|
||||
friend expr pw(int a, expr const & b);
|
||||
|
||||
/* \brief mod operator */
|
||||
friend expr mod(expr const& a, expr const& b);
|
||||
friend expr mod(expr const& a, int b);
|
||||
friend expr mod(int a, expr const& b);
|
||||
|
||||
/* \brief rem operator */
|
||||
friend expr rem(expr const& a, expr const& b);
|
||||
friend expr rem(expr const& a, int b);
|
||||
friend expr rem(int a, expr const& b);
|
||||
|
||||
friend expr is_int(expr const& e);
|
||||
|
||||
friend expr operator/(expr const & a, expr const & b);
|
||||
friend expr operator/(expr const & a, int b);
|
||||
friend expr operator/(int a, expr const & b);
|
||||
|
@ -876,7 +957,7 @@ namespace z3 {
|
|||
unsigned lo() const { assert (is_app() && Z3_get_decl_num_parameters(ctx(), decl()) == 2); return static_cast<unsigned>(Z3_get_decl_int_parameter(ctx(), decl(), 1)); }
|
||||
unsigned hi() const { assert (is_app() && Z3_get_decl_num_parameters(ctx(), decl()) == 2); return static_cast<unsigned>(Z3_get_decl_int_parameter(ctx(), decl(), 0)); }
|
||||
|
||||
/**
|
||||
/**
|
||||
\brief sequence and regular expression operations.
|
||||
+ is overloaeded as sequence concatenation and regular expression union.
|
||||
concat is overloaded to handle sequences and regular expressions
|
||||
|
@ -913,7 +994,31 @@ namespace z3 {
|
|||
check_error();
|
||||
return expr(ctx(), r);
|
||||
}
|
||||
expr stoi() const {
|
||||
Z3_ast r = Z3_mk_str_to_int(ctx(), *this);
|
||||
check_error();
|
||||
return expr(ctx(), r);
|
||||
}
|
||||
expr itos() const {
|
||||
Z3_ast r = Z3_mk_int_to_str(ctx(), *this);
|
||||
check_error();
|
||||
return expr(ctx(), r);
|
||||
}
|
||||
|
||||
friend expr range(expr const& lo, expr const& hi);
|
||||
/**
|
||||
\brief create a looping regular expression.
|
||||
*/
|
||||
expr loop(unsigned lo) {
|
||||
Z3_ast r = Z3_mk_re_loop(ctx(), m_ast, lo, 0);
|
||||
check_error();
|
||||
return expr(ctx(), r);
|
||||
}
|
||||
expr loop(unsigned lo, unsigned hi) {
|
||||
Z3_ast r = Z3_mk_re_loop(ctx(), m_ast, lo, hi);
|
||||
check_error();
|
||||
return expr(ctx(), r);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -937,33 +1042,46 @@ namespace z3 {
|
|||
|
||||
};
|
||||
|
||||
#define _Z3_MK_BIN_(a, b, binop) \
|
||||
check_context(a, b); \
|
||||
Z3_ast r = binop(a.ctx(), a, b); \
|
||||
a.check_error(); \
|
||||
return expr(a.ctx(), r); \
|
||||
|
||||
|
||||
inline expr implies(expr const & a, expr const & b) {
|
||||
check_context(a, b);
|
||||
assert(a.is_bool() && b.is_bool());
|
||||
Z3_ast r = Z3_mk_implies(a.ctx(), a, b);
|
||||
a.check_error();
|
||||
return expr(a.ctx(), r);
|
||||
assert(a.is_bool() && b.is_bool());
|
||||
_Z3_MK_BIN_(a, b, Z3_mk_implies);
|
||||
}
|
||||
inline expr implies(expr const & a, bool b) { return implies(a, a.ctx().bool_val(b)); }
|
||||
inline expr implies(bool a, expr const & b) { return implies(b.ctx().bool_val(a), b); }
|
||||
|
||||
inline expr pw(expr const & a, expr const & b) {
|
||||
assert(a.is_arith() && b.is_arith());
|
||||
check_context(a, b);
|
||||
Z3_ast r = Z3_mk_power(a.ctx(), a, b);
|
||||
a.check_error();
|
||||
return expr(a.ctx(), r);
|
||||
}
|
||||
|
||||
inline expr pw(expr const & a, expr const & b) { _Z3_MK_BIN_(a, b, Z3_mk_power); }
|
||||
inline expr pw(expr const & a, int b) { return pw(a, a.ctx().num_val(b, a.get_sort())); }
|
||||
inline expr pw(int a, expr const & b) { return pw(b.ctx().num_val(a, b.get_sort()), b); }
|
||||
|
||||
inline expr mod(expr const& a, expr const& b) { _Z3_MK_BIN_(a, b, Z3_mk_mod); }
|
||||
inline expr mod(expr const & a, int b) { return mod(a, a.ctx().num_val(b, a.get_sort())); }
|
||||
inline expr mod(int a, expr const & b) { return mod(b.ctx().num_val(a, b.get_sort()), b); }
|
||||
|
||||
inline expr operator!(expr const & a) {
|
||||
assert(a.is_bool());
|
||||
Z3_ast r = Z3_mk_not(a.ctx(), a);
|
||||
a.check_error();
|
||||
return expr(a.ctx(), r);
|
||||
}
|
||||
inline expr rem(expr const& a, expr const& b) { _Z3_MK_BIN_(a, b, Z3_mk_rem); }
|
||||
inline expr rem(expr const & a, int b) { return rem(a, a.ctx().num_val(b, a.get_sort())); }
|
||||
inline expr rem(int a, expr const & b) { return rem(b.ctx().num_val(a, b.get_sort()), b); }
|
||||
|
||||
#undef _Z3_MK_BIN_
|
||||
|
||||
#define _Z3_MK_UN_(a, mkun) \
|
||||
Z3_ast r = mkun(a.ctx(), a); \
|
||||
a.check_error(); \
|
||||
return expr(a.ctx(), r); \
|
||||
|
||||
|
||||
inline expr operator!(expr const & a) { assert(a.is_bool()); _Z3_MK_UN_(a, Z3_mk_not); }
|
||||
|
||||
inline expr is_int(expr const& e) { _Z3_MK_UN_(e, Z3_mk_is_int); }
|
||||
|
||||
#undef _Z3_MK_UN_
|
||||
|
||||
inline expr operator&&(expr const & a, expr const & b) {
|
||||
check_context(a, b);
|
||||
|
@ -1205,7 +1323,6 @@ namespace z3 {
|
|||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
\brief Create the if-then-else expression <tt>ite(c, t, e)</tt>
|
||||
|
||||
|
@ -1275,51 +1392,51 @@ namespace z3 {
|
|||
inline expr udiv(expr const & a, int b) { return udiv(a, a.ctx().num_val(b, a.get_sort())); }
|
||||
inline expr udiv(int a, expr const & b) { return udiv(b.ctx().num_val(a, b.get_sort()), b); }
|
||||
|
||||
/**
|
||||
\brief signed reminder operator for bitvectors
|
||||
*/
|
||||
inline expr srem(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvsrem(a.ctx(), a, b)); }
|
||||
inline expr srem(expr const & a, int b) { return srem(a, a.ctx().num_val(b, a.get_sort())); }
|
||||
inline expr srem(int a, expr const & b) { return srem(b.ctx().num_val(a, b.get_sort()), b); }
|
||||
|
||||
/**
|
||||
\brief unsigned reminder operator for bitvectors
|
||||
*/
|
||||
inline expr urem(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvurem(a.ctx(), a, b)); }
|
||||
inline expr urem(expr const & a, int b) { return urem(a, a.ctx().num_val(b, a.get_sort())); }
|
||||
inline expr urem(int a, expr const & b) { return urem(b.ctx().num_val(a, b.get_sort()), b); }
|
||||
|
||||
/**
|
||||
\brief shift left operator for bitvectors
|
||||
*/
|
||||
inline expr shl(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvshl(a.ctx(), a, b)); }
|
||||
inline expr shl(expr const & a, int b) { return shl(a, a.ctx().num_val(b, a.get_sort())); }
|
||||
inline expr shl(int a, expr const & b) { return shl(b.ctx().num_val(a, b.get_sort()), b); }
|
||||
|
||||
/**
|
||||
\brief logic shift right operator for bitvectors
|
||||
*/
|
||||
inline expr lshr(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvlshr(a.ctx(), a, b)); }
|
||||
inline expr lshr(expr const & a, int b) { return lshr(a, a.ctx().num_val(b, a.get_sort())); }
|
||||
inline expr lshr(int a, expr const & b) { return lshr(b.ctx().num_val(a, b.get_sort()), b); }
|
||||
|
||||
/**
|
||||
\brief arithmetic shift right operator for bitvectors
|
||||
*/
|
||||
inline expr ashr(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvashr(a.ctx(), a, b)); }
|
||||
inline expr ashr(expr const & a, int b) { return ashr(a, a.ctx().num_val(b, a.get_sort())); }
|
||||
inline expr ashr(int a, expr const & b) { return ashr(b.ctx().num_val(a, b.get_sort()), b); }
|
||||
|
||||
/**
|
||||
\brief Extend the given bit-vector with zeros to the (unsigned) equivalent bitvector of size m+i, where m is the size of the given bit-vector.
|
||||
*/
|
||||
inline expr zext(expr const & a, unsigned i) { return to_expr(a.ctx(), Z3_mk_zero_ext(a.ctx(), i, a)); }
|
||||
|
||||
/**
|
||||
\brief Sign-extend of the given bit-vector to the (signed) equivalent bitvector of size m+i, where m is the size of the given bit-vector.
|
||||
*/
|
||||
inline expr sext(expr const & a, unsigned i) { return to_expr(a.ctx(), Z3_mk_sign_ext(a.ctx(), i, a)); }
|
||||
|
||||
/**
|
||||
\brief signed reminder operator for bitvectors
|
||||
*/
|
||||
inline expr srem(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvsrem(a.ctx(), a, b)); }
|
||||
inline expr srem(expr const & a, int b) { return srem(a, a.ctx().num_val(b, a.get_sort())); }
|
||||
inline expr srem(int a, expr const & b) { return srem(b.ctx().num_val(a, b.get_sort()), b); }
|
||||
|
||||
/**
|
||||
\brief unsigned reminder operator for bitvectors
|
||||
*/
|
||||
inline expr urem(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvurem(a.ctx(), a, b)); }
|
||||
inline expr urem(expr const & a, int b) { return urem(a, a.ctx().num_val(b, a.get_sort())); }
|
||||
inline expr urem(int a, expr const & b) { return urem(b.ctx().num_val(a, b.get_sort()), b); }
|
||||
|
||||
/**
|
||||
\brief shift left operator for bitvectors
|
||||
*/
|
||||
inline expr shl(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvshl(a.ctx(), a, b)); }
|
||||
inline expr shl(expr const & a, int b) { return shl(a, a.ctx().num_val(b, a.get_sort())); }
|
||||
inline expr shl(int a, expr const & b) { return shl(b.ctx().num_val(a, b.get_sort()), b); }
|
||||
|
||||
/**
|
||||
\brief logic shift right operator for bitvectors
|
||||
*/
|
||||
inline expr lshr(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvlshr(a.ctx(), a, b)); }
|
||||
inline expr lshr(expr const & a, int b) { return lshr(a, a.ctx().num_val(b, a.get_sort())); }
|
||||
inline expr lshr(int a, expr const & b) { return lshr(b.ctx().num_val(a, b.get_sort()), b); }
|
||||
|
||||
/**
|
||||
\brief arithmetic shift right operator for bitvectors
|
||||
*/
|
||||
inline expr ashr(expr const & a, expr const & b) { return to_expr(a.ctx(), Z3_mk_bvashr(a.ctx(), a, b)); }
|
||||
inline expr ashr(expr const & a, int b) { return ashr(a, a.ctx().num_val(b, a.get_sort())); }
|
||||
inline expr ashr(int a, expr const & b) { return ashr(b.ctx().num_val(a, b.get_sort()), b); }
|
||||
|
||||
/**
|
||||
\brief Extend the given bit-vector with zeros to the (unsigned) equivalent bitvector of size m+i, where m is the size of the given bit-vector.
|
||||
*/
|
||||
inline expr zext(expr const & a, unsigned i) { return to_expr(a.ctx(), Z3_mk_zero_ext(a.ctx(), i, a)); }
|
||||
|
||||
/**
|
||||
\brief Sign-extend of the given bit-vector to the (signed) equivalent bitvector of size m+i, where m is the size of the given bit-vector.
|
||||
*/
|
||||
inline expr sext(expr const & a, unsigned i) { return to_expr(a.ctx(), Z3_mk_sign_ext(a.ctx(), i, a)); }
|
||||
|
||||
template<typename T> class cast_ast;
|
||||
|
||||
template<> class cast_ast<ast> {
|
||||
|
@ -1497,6 +1614,20 @@ namespace z3 {
|
|||
return expr(ctx, r);
|
||||
}
|
||||
|
||||
inline expr mk_or(expr_vector const& args) {
|
||||
array<Z3_ast> _args(args);
|
||||
Z3_ast r = Z3_mk_or(args.ctx(), _args.size(), _args.ptr());
|
||||
args.check_error();
|
||||
return expr(args.ctx(), r);
|
||||
}
|
||||
inline expr mk_and(expr_vector const& args) {
|
||||
array<Z3_ast> _args(args);
|
||||
Z3_ast r = Z3_mk_and(args.ctx(), _args.size(), _args.ptr());
|
||||
args.check_error();
|
||||
return expr(args.ctx(), r);
|
||||
}
|
||||
|
||||
|
||||
class func_entry : public object {
|
||||
Z3_func_entry m_entry;
|
||||
void init(Z3_func_entry e) {
|
||||
|
@ -1567,7 +1698,7 @@ namespace z3 {
|
|||
Z3_ast r = 0;
|
||||
Z3_bool status = Z3_model_eval(ctx(), m_model, n, model_completion, &r);
|
||||
check_error();
|
||||
if (status == Z3_FALSE)
|
||||
if (status == Z3_FALSE && ctx().enable_exceptions())
|
||||
throw exception("failed to evaluate expression");
|
||||
return expr(ctx(), r);
|
||||
}
|
||||
|
@ -1578,9 +1709,9 @@ namespace z3 {
|
|||
func_decl get_func_decl(unsigned i) const { Z3_func_decl r = Z3_model_get_func_decl(ctx(), m_model, i); check_error(); return func_decl(ctx(), r); }
|
||||
unsigned size() const { return num_consts() + num_funcs(); }
|
||||
func_decl operator[](int i) const {
|
||||
assert(0 <= i);
|
||||
return static_cast<unsigned>(i) < num_consts() ? get_const_decl(i) : get_func_decl(i - num_consts());
|
||||
}
|
||||
assert(0 <= i);
|
||||
return static_cast<unsigned>(i) < num_consts() ? get_const_decl(i) : get_func_decl(i - num_consts());
|
||||
}
|
||||
|
||||
// returns interpretation of constant declaration c.
|
||||
// If c is not assigned any value in the model it returns
|
||||
|
@ -1597,6 +1728,13 @@ namespace z3 {
|
|||
check_error();
|
||||
return func_interp(ctx(), r);
|
||||
}
|
||||
|
||||
// returns true iff the model contains an interpretation
|
||||
// for function f.
|
||||
bool has_interp(func_decl f) const {
|
||||
check_context(*this, f);
|
||||
return 0 != Z3_model_has_interp(ctx(), m_model, f);
|
||||
}
|
||||
|
||||
friend std::ostream & operator<<(std::ostream & out, model const & m);
|
||||
};
|
||||
|
@ -1639,11 +1777,6 @@ namespace z3 {
|
|||
return out;
|
||||
}
|
||||
|
||||
inline check_result to_check_result(Z3_lbool l) {
|
||||
if (l == Z3_L_TRUE) return sat;
|
||||
else if (l == Z3_L_FALSE) return unsat;
|
||||
return unknown;
|
||||
}
|
||||
|
||||
class solver : public object {
|
||||
Z3_solver m_solver;
|
||||
|
@ -1705,6 +1838,11 @@ namespace z3 {
|
|||
return to_check_result(r);
|
||||
}
|
||||
model get_model() const { Z3_model m = Z3_solver_get_model(ctx(), m_solver); check_error(); return model(ctx(), m); }
|
||||
check_result consequences(expr_vector& assumptions, expr_vector& vars, expr_vector& conseq) {
|
||||
Z3_lbool r = Z3_solver_get_consequences(ctx(), m_solver, assumptions, vars, conseq);
|
||||
check_error();
|
||||
return to_check_result(r);
|
||||
}
|
||||
std::string reason_unknown() const { Z3_string r = Z3_solver_get_reason_unknown(ctx(), m_solver); check_error(); return r; }
|
||||
stats statistics() const { Z3_stats r = Z3_solver_get_statistics(ctx(), m_solver); check_error(); return stats(ctx(), r); }
|
||||
expr_vector unsat_core() const { Z3_ast_vector r = Z3_solver_get_unsat_core(ctx(), m_solver); check_error(); return expr_vector(ctx(), r); }
|
||||
|
@ -1731,6 +1869,7 @@ namespace z3 {
|
|||
fmls,
|
||||
fml));
|
||||
}
|
||||
|
||||
param_descrs get_param_descrs() { return param_descrs(ctx(), Z3_solver_get_param_descrs(ctx(), m_solver)); }
|
||||
|
||||
};
|
||||
|
@ -1847,6 +1986,8 @@ namespace z3 {
|
|||
friend tactic repeat(tactic const & t, unsigned max);
|
||||
friend tactic with(tactic const & t, params const & p);
|
||||
friend tactic try_for(tactic const & t, unsigned ms);
|
||||
friend tactic par_or(unsigned n, tactic const* tactics);
|
||||
friend tactic par_and_then(tactic const& t1, tactic const& t2);
|
||||
param_descrs get_param_descrs() { return param_descrs(ctx(), Z3_tactic_get_param_descrs(ctx(), m_tactic)); }
|
||||
};
|
||||
|
||||
|
@ -1880,7 +2021,21 @@ namespace z3 {
|
|||
t.check_error();
|
||||
return tactic(t.ctx(), r);
|
||||
}
|
||||
inline tactic par_or(unsigned n, tactic const* tactics) {
|
||||
if (n == 0) {
|
||||
throw exception("a non-zero number of tactics need to be passed to par_or");
|
||||
}
|
||||
array<Z3_tactic> buffer(n);
|
||||
for (unsigned i = 0; i < n; ++i) buffer[i] = tactics[i];
|
||||
return tactic(tactics[0].ctx(), Z3_tactic_par_or(tactics[0].ctx(), n, buffer.ptr()));
|
||||
}
|
||||
|
||||
inline tactic par_and_then(tactic const & t1, tactic const & t2) {
|
||||
check_context(t1, t2);
|
||||
Z3_tactic r = Z3_tactic_par_and_then(t1.ctx(), t1, t2);
|
||||
t1.check_error();
|
||||
return tactic(t1.ctx(), r);
|
||||
}
|
||||
|
||||
class probe : public object {
|
||||
Z3_probe m_probe;
|
||||
|
@ -2010,8 +2165,12 @@ namespace z3 {
|
|||
check_error();
|
||||
return expr(ctx(), r);
|
||||
}
|
||||
expr_vector assertions() const { Z3_ast_vector r = Z3_optimize_get_assertions(ctx(), m_opt); check_error(); return expr_vector(ctx(), r); }
|
||||
expr_vector objectives() const { Z3_ast_vector r = Z3_optimize_get_objectives(ctx(), m_opt); check_error(); return expr_vector(ctx(), r); }
|
||||
stats statistics() const { Z3_stats r = Z3_optimize_get_statistics(ctx(), m_opt); check_error(); return stats(ctx(), r); }
|
||||
friend std::ostream & operator<<(std::ostream & out, optimize const & s);
|
||||
void from_file(char const* filename) { Z3_optimize_from_file(ctx(), m_opt, filename); check_error(); }
|
||||
void from_string(char const* constraints) { Z3_optimize_from_string(ctx(), m_opt, constraints); check_error(); }
|
||||
std::string help() const { char const * r = Z3_optimize_get_help(ctx(), m_opt); check_error(); return r; }
|
||||
};
|
||||
inline std::ostream & operator<<(std::ostream & out, optimize const & s) { out << Z3_optimize_to_string(s.ctx(), s.m_opt); return out; }
|
||||
|
@ -2297,11 +2456,68 @@ namespace z3 {
|
|||
inline expr store(expr const & a, int i, int v) {
|
||||
return store(a, a.ctx().num_val(i, a.get_sort().array_domain()), a.ctx().num_val(v, a.get_sort().array_range()));
|
||||
}
|
||||
|
||||
#define MK_EXPR1(_fn, _arg) \
|
||||
Z3_ast r = _fn(_arg.ctx(), _arg); \
|
||||
_arg.check_error(); \
|
||||
return expr(_arg.ctx(), r);
|
||||
|
||||
#define MK_EXPR2(_fn, _arg1, _arg2) \
|
||||
check_context(_arg1, _arg2); \
|
||||
Z3_ast r = _fn(_arg1.ctx(), _arg1, _arg2); \
|
||||
_arg1.check_error(); \
|
||||
return expr(_arg1.ctx(), r);
|
||||
|
||||
inline expr const_array(sort const & d, expr const & v) {
|
||||
check_context(d, v);
|
||||
Z3_ast r = Z3_mk_const_array(d.ctx(), d, v);
|
||||
d.check_error();
|
||||
return expr(d.ctx(), r);
|
||||
MK_EXPR2(Z3_mk_const_array, d, v);
|
||||
}
|
||||
|
||||
inline expr empty_set(sort const& s) {
|
||||
MK_EXPR1(Z3_mk_empty_set, s);
|
||||
}
|
||||
|
||||
inline expr full_set(sort const& s) {
|
||||
MK_EXPR1(Z3_mk_full_set, s);
|
||||
}
|
||||
|
||||
inline expr set_add(expr const& s, expr const& e) {
|
||||
MK_EXPR2(Z3_mk_set_add, s, e);
|
||||
}
|
||||
|
||||
inline expr set_del(expr const& s, expr const& e) {
|
||||
MK_EXPR2(Z3_mk_set_del, s, e);
|
||||
}
|
||||
|
||||
inline expr set_union(expr const& a, expr const& b) {
|
||||
check_context(a, b);
|
||||
Z3_ast es[2] = { a, b };
|
||||
Z3_ast r = Z3_mk_set_union(a.ctx(), 2, es);
|
||||
a.check_error();
|
||||
return expr(a.ctx(), r);
|
||||
}
|
||||
|
||||
inline expr set_intersect(expr const& a, expr const& b) {
|
||||
check_context(a, b);
|
||||
Z3_ast es[2] = { a, b };
|
||||
Z3_ast r = Z3_mk_set_intersect(a.ctx(), 2, es);
|
||||
a.check_error();
|
||||
return expr(a.ctx(), r);
|
||||
}
|
||||
|
||||
inline expr set_difference(expr const& a, expr const& b) {
|
||||
MK_EXPR2(Z3_mk_set_difference, a, b);
|
||||
}
|
||||
|
||||
inline expr set_complement(expr const& a) {
|
||||
MK_EXPR1(Z3_mk_set_complement, a);
|
||||
}
|
||||
|
||||
inline expr set_member(expr const& s, expr const& e) {
|
||||
MK_EXPR2(Z3_mk_set_member, s, e);
|
||||
}
|
||||
|
||||
inline expr set_subset(expr const& a, expr const& b) {
|
||||
MK_EXPR2(Z3_mk_set_subset, a, b);
|
||||
}
|
||||
|
||||
// sequence and regular expression operations.
|
||||
|
@ -2332,37 +2548,101 @@ namespace z3 {
|
|||
return expr(s.ctx(), r);
|
||||
}
|
||||
inline expr to_re(expr const& s) {
|
||||
Z3_ast r = Z3_mk_seq_to_re(s.ctx(), s);
|
||||
s.check_error();
|
||||
return expr(s.ctx(), r);
|
||||
MK_EXPR1(Z3_mk_seq_to_re, s);
|
||||
}
|
||||
inline expr in_re(expr const& s, expr const& re) {
|
||||
check_context(s, re);
|
||||
Z3_ast r = Z3_mk_seq_in_re(s.ctx(), s, re);
|
||||
MK_EXPR2(Z3_mk_seq_in_re, s, re);
|
||||
}
|
||||
inline expr plus(expr const& re) {
|
||||
MK_EXPR1(Z3_mk_re_plus, re);
|
||||
}
|
||||
inline expr option(expr const& re) {
|
||||
MK_EXPR1(Z3_mk_re_option, re);
|
||||
}
|
||||
inline expr star(expr const& re) {
|
||||
MK_EXPR1(Z3_mk_re_star, re);
|
||||
}
|
||||
inline expr re_empty(sort const& s) {
|
||||
Z3_ast r = Z3_mk_re_empty(s.ctx(), s);
|
||||
s.check_error();
|
||||
return expr(s.ctx(), r);
|
||||
}
|
||||
inline expr plus(expr const& re) {
|
||||
Z3_ast r = Z3_mk_re_plus(re.ctx(), re);
|
||||
re.check_error();
|
||||
return expr(re.ctx(), r);
|
||||
inline expr re_full(sort const& s) {
|
||||
Z3_ast r = Z3_mk_re_full(s.ctx(), s);
|
||||
s.check_error();
|
||||
return expr(s.ctx(), r);
|
||||
}
|
||||
inline expr option(expr const& re) {
|
||||
Z3_ast r = Z3_mk_re_option(re.ctx(), re);
|
||||
re.check_error();
|
||||
return expr(re.ctx(), r);
|
||||
inline expr re_intersect(expr_vector const& args) {
|
||||
assert(args.size() > 0);
|
||||
context& ctx = args[0].ctx();
|
||||
array<Z3_ast> _args(args);
|
||||
Z3_ast r = Z3_mk_re_intersect(ctx, _args.size(), _args.ptr());
|
||||
ctx.check_error();
|
||||
return expr(ctx, r);
|
||||
}
|
||||
inline expr star(expr const& re) {
|
||||
Z3_ast r = Z3_mk_re_star(re.ctx(), re);
|
||||
re.check_error();
|
||||
return expr(re.ctx(), r);
|
||||
inline expr re_complement(expr const& a) {
|
||||
MK_EXPR1(Z3_mk_re_complement, a);
|
||||
}
|
||||
inline expr range(expr const& lo, expr const& hi) {
|
||||
check_context(lo, hi);
|
||||
Z3_ast r = Z3_mk_re_range(lo.ctx(), lo, hi);
|
||||
lo.check_error();
|
||||
return expr(lo.ctx(), r);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
inline expr interpolant(expr const& a) {
|
||||
return expr(a.ctx(), Z3_mk_interpolant(a.ctx(), a));
|
||||
}
|
||||
|
||||
inline expr context::parse_string(char const* s) {
|
||||
Z3_ast r = Z3_parse_smtlib2_string(*this, s, 0, 0, 0, 0, 0, 0);
|
||||
check_error();
|
||||
return expr(*this, r);
|
||||
|
||||
}
|
||||
inline expr context::parse_file(char const* s) {
|
||||
Z3_ast r = Z3_parse_smtlib2_file(*this, s, 0, 0, 0, 0, 0, 0);
|
||||
check_error();
|
||||
return expr(*this, r);
|
||||
}
|
||||
|
||||
inline expr context::parse_string(char const* s, sort_vector const& sorts, func_decl_vector const& decls) {
|
||||
array<Z3_symbol> sort_names(sorts.size());
|
||||
array<Z3_symbol> decl_names(decls.size());
|
||||
array<Z3_sort> sorts1(sorts);
|
||||
array<Z3_func_decl> decls1(decls);
|
||||
for (unsigned i = 0; i < sorts.size(); ++i) {
|
||||
sort_names[i] = sorts[i].name();
|
||||
}
|
||||
for (unsigned i = 0; i < decls.size(); ++i) {
|
||||
decl_names[i] = decls[i].name();
|
||||
}
|
||||
Z3_ast r = Z3_parse_smtlib2_string(*this, s, sorts.size(), sort_names.ptr(), sorts1.ptr(), decls.size(), decl_names.ptr(), decls1.ptr());
|
||||
check_error();
|
||||
return expr(*this, r);
|
||||
}
|
||||
|
||||
inline expr context::parse_file(char const* s, sort_vector const& sorts, func_decl_vector const& decls) {
|
||||
array<Z3_symbol> sort_names(sorts.size());
|
||||
array<Z3_symbol> decl_names(decls.size());
|
||||
array<Z3_sort> sorts1(sorts);
|
||||
array<Z3_func_decl> decls1(decls);
|
||||
for (unsigned i = 0; i < sorts.size(); ++i) {
|
||||
sort_names[i] = sorts[i].name();
|
||||
}
|
||||
for (unsigned i = 0; i < decls.size(); ++i) {
|
||||
decl_names[i] = decls[i].name();
|
||||
}
|
||||
Z3_ast r = Z3_parse_smtlib2_file(*this, s, sorts.size(), sort_names.ptr(), sorts1.ptr(), decls.size(), decl_names.ptr(), decls1.ptr());
|
||||
check_error();
|
||||
return expr(*this, r);
|
||||
}
|
||||
|
||||
|
||||
inline check_result context::compute_interpolant(expr const& pat, params const& p, expr_vector& i, model& m) {
|
||||
Z3_ast_vector interp = 0;
|
||||
Z3_model mdl = 0;
|
||||
|
|
|
@ -286,8 +286,8 @@ namespace Microsoft.Z3
|
|||
Contract.Ensures(Contract.Result<TupleSort>() != null);
|
||||
|
||||
CheckContextMatch(name);
|
||||
CheckContextMatch(fieldNames);
|
||||
CheckContextMatch(fieldSorts);
|
||||
CheckContextMatch<Symbol>(fieldNames);
|
||||
CheckContextMatch<Sort>(fieldSorts);
|
||||
return new TupleSort(this, name, (uint)fieldNames.Length, fieldNames, fieldSorts);
|
||||
}
|
||||
|
||||
|
@ -303,7 +303,7 @@ namespace Microsoft.Z3
|
|||
Contract.Ensures(Contract.Result<EnumSort>() != null);
|
||||
|
||||
CheckContextMatch(name);
|
||||
CheckContextMatch(enumNames);
|
||||
CheckContextMatch<Symbol>(enumNames);
|
||||
return new EnumSort(this, name, enumNames);
|
||||
}
|
||||
|
||||
|
@ -423,7 +423,7 @@ namespace Microsoft.Z3
|
|||
Contract.Ensures(Contract.Result<DatatypeSort>() != null);
|
||||
|
||||
CheckContextMatch(name);
|
||||
CheckContextMatch(constructors);
|
||||
CheckContextMatch<Constructor>(constructors);
|
||||
return new DatatypeSort(this, name, constructors);
|
||||
}
|
||||
|
||||
|
@ -436,7 +436,7 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(Contract.ForAll(constructors, c => c != null));
|
||||
Contract.Ensures(Contract.Result<DatatypeSort>() != null);
|
||||
|
||||
CheckContextMatch(constructors);
|
||||
CheckContextMatch<Constructor>(constructors);
|
||||
return new DatatypeSort(this, MkSymbol(name), constructors);
|
||||
}
|
||||
|
||||
|
@ -454,7 +454,7 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(Contract.ForAll(names, name => name != null));
|
||||
Contract.Ensures(Contract.Result<DatatypeSort[]>() != null);
|
||||
|
||||
CheckContextMatch(names);
|
||||
CheckContextMatch<Symbol>(names);
|
||||
uint n = (uint)names.Length;
|
||||
ConstructorList[] cla = new ConstructorList[n];
|
||||
IntPtr[] n_constr = new IntPtr[n];
|
||||
|
@ -462,7 +462,7 @@ namespace Microsoft.Z3
|
|||
{
|
||||
Constructor[] constructor = c[i];
|
||||
Contract.Assume(Contract.ForAll(constructor, arr => arr != null), "Clousot does not support yet quantified formula on multidimensional arrays");
|
||||
CheckContextMatch(constructor);
|
||||
CheckContextMatch<Constructor>(constructor);
|
||||
cla[i] = new ConstructorList(this, constructor);
|
||||
n_constr[i] = cla[i].NativeObject;
|
||||
}
|
||||
|
@ -520,7 +520,7 @@ namespace Microsoft.Z3
|
|||
Contract.Ensures(Contract.Result<FuncDecl>() != null);
|
||||
|
||||
CheckContextMatch(name);
|
||||
CheckContextMatch(domain);
|
||||
CheckContextMatch<Sort>(domain);
|
||||
CheckContextMatch(range);
|
||||
return new FuncDecl(this, name, domain, range);
|
||||
}
|
||||
|
@ -551,7 +551,7 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(Contract.ForAll(domain, d => d != null));
|
||||
Contract.Ensures(Contract.Result<FuncDecl>() != null);
|
||||
|
||||
CheckContextMatch(domain);
|
||||
CheckContextMatch<Sort>(domain);
|
||||
CheckContextMatch(range);
|
||||
return new FuncDecl(this, MkSymbol(name), domain, range);
|
||||
}
|
||||
|
@ -582,7 +582,7 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(Contract.ForAll(domain, d => d != null));
|
||||
Contract.Ensures(Contract.Result<FuncDecl>() != null);
|
||||
|
||||
CheckContextMatch(domain);
|
||||
CheckContextMatch<Sort>(domain);
|
||||
CheckContextMatch(range);
|
||||
return new FuncDecl(this, prefix, domain, range);
|
||||
}
|
||||
|
@ -811,7 +811,7 @@ namespace Microsoft.Z3
|
|||
Contract.Ensures(Contract.Result<Expr>() != null);
|
||||
|
||||
CheckContextMatch(f);
|
||||
CheckContextMatch(args);
|
||||
CheckContextMatch<Expr>(args);
|
||||
return Expr.Create(this, f, args);
|
||||
}
|
||||
|
||||
|
@ -884,7 +884,7 @@ namespace Microsoft.Z3
|
|||
|
||||
Contract.Ensures(Contract.Result<BoolExpr>() != null);
|
||||
|
||||
CheckContextMatch(args);
|
||||
CheckContextMatch<Expr>(args);
|
||||
return new BoolExpr(this, Native.Z3_mk_distinct(nCtx, (uint)args.Length, AST.ArrayToNative(args)));
|
||||
}
|
||||
|
||||
|
@ -970,7 +970,7 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(Contract.ForAll(t, a => a != null));
|
||||
Contract.Ensures(Contract.Result<BoolExpr>() != null);
|
||||
|
||||
CheckContextMatch(t);
|
||||
CheckContextMatch<BoolExpr>(t);
|
||||
return new BoolExpr(this, Native.Z3_mk_and(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
|
||||
}
|
||||
|
||||
|
@ -982,7 +982,7 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(t != null);
|
||||
Contract.Requires(Contract.ForAll(t, a => a != null));
|
||||
Contract.Ensures(Contract.Result<BoolExpr>() != null);
|
||||
CheckContextMatch(t);
|
||||
CheckContextMatch<BoolExpr>(t);
|
||||
return new BoolExpr(this, Native.Z3_mk_and(nCtx, (uint)t.Count(), AST.EnumToNative(t)));
|
||||
}
|
||||
|
||||
|
@ -995,7 +995,7 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(Contract.ForAll(t, a => a != null));
|
||||
Contract.Ensures(Contract.Result<BoolExpr>() != null);
|
||||
|
||||
CheckContextMatch(t);
|
||||
CheckContextMatch<BoolExpr>(t);
|
||||
return new BoolExpr(this, Native.Z3_mk_or(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
|
||||
}
|
||||
|
||||
|
@ -1025,7 +1025,7 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(Contract.ForAll(t, a => a != null));
|
||||
Contract.Ensures(Contract.Result<ArithExpr>() != null);
|
||||
|
||||
CheckContextMatch(t);
|
||||
CheckContextMatch<ArithExpr>(t);
|
||||
return (ArithExpr)Expr.Create(this, Native.Z3_mk_add(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
|
||||
}
|
||||
|
||||
|
@ -1051,10 +1051,23 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(Contract.ForAll(t, a => a != null));
|
||||
Contract.Ensures(Contract.Result<ArithExpr>() != null);
|
||||
|
||||
CheckContextMatch(t);
|
||||
CheckContextMatch<ArithExpr>(t);
|
||||
return (ArithExpr)Expr.Create(this, Native.Z3_mk_mul(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create an expression representing <c>t[0] * t[1] * ...</c>.
|
||||
/// </summary>
|
||||
public ArithExpr MkMul(IEnumerable<ArithExpr> t)
|
||||
{
|
||||
Contract.Requires(t != null);
|
||||
Contract.Requires(Contract.ForAll(t, a => a != null));
|
||||
Contract.Ensures(Contract.Result<ArithExpr>() != null);
|
||||
|
||||
CheckContextMatch<ArithExpr>(t);
|
||||
return (ArithExpr)Expr.Create(this, Native.Z3_mk_mul(nCtx, (uint)t.Count(), AST.EnumToNative(t)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create an expression representing <c>t[0] - t[1] - ...</c>.
|
||||
/// </summary>
|
||||
|
@ -1064,7 +1077,7 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(Contract.ForAll(t, a => a != null));
|
||||
Contract.Ensures(Contract.Result<ArithExpr>() != null);
|
||||
|
||||
CheckContextMatch(t);
|
||||
CheckContextMatch<ArithExpr>(t);
|
||||
return (ArithExpr)Expr.Create(this, Native.Z3_mk_sub(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
|
||||
}
|
||||
|
||||
|
@ -2192,7 +2205,7 @@ namespace Microsoft.Z3
|
|||
Contract.Ensures(Contract.Result<ArrayExpr>() != null);
|
||||
|
||||
CheckContextMatch(f);
|
||||
CheckContextMatch(args);
|
||||
CheckContextMatch<ArrayExpr>(args);
|
||||
return (ArrayExpr)Expr.Create(this, Native.Z3_mk_map(nCtx, f.NativeObject, AST.ArrayLength(args), AST.ArrayToNative(args)));
|
||||
}
|
||||
|
||||
|
@ -2302,7 +2315,7 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(args != null);
|
||||
Contract.Requires(Contract.ForAll(args, a => a != null));
|
||||
|
||||
CheckContextMatch(args);
|
||||
CheckContextMatch<ArrayExpr>(args);
|
||||
return (ArrayExpr)Expr.Create(this, Native.Z3_mk_set_union(nCtx, (uint)args.Length, AST.ArrayToNative(args)));
|
||||
}
|
||||
|
||||
|
@ -2315,7 +2328,7 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(Contract.ForAll(args, a => a != null));
|
||||
Contract.Ensures(Contract.Result<Expr>() != null);
|
||||
|
||||
CheckContextMatch(args);
|
||||
CheckContextMatch<ArrayExpr>(args);
|
||||
return (ArrayExpr)Expr.Create(this, Native.Z3_mk_set_intersect(nCtx, (uint)args.Length, AST.ArrayToNative(args)));
|
||||
}
|
||||
|
||||
|
@ -2407,6 +2420,29 @@ namespace Microsoft.Z3
|
|||
return new SeqExpr(this, Native.Z3_mk_string(nCtx, s));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert an integer expression to a string.
|
||||
/// </summary>
|
||||
public SeqExpr IntToString(Expr e)
|
||||
{
|
||||
Contract.Requires(e != null);
|
||||
Contract.Requires(e is ArithExpr);
|
||||
Contract.Ensures(Contract.Result<SeqExpr>() != null);
|
||||
return new SeqExpr(this, Native.Z3_mk_int_to_str(nCtx, e.NativeObject));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert an integer expression to a string.
|
||||
/// </summary>
|
||||
public IntExpr StringToInt(Expr e)
|
||||
{
|
||||
Contract.Requires(e != null);
|
||||
Contract.Requires(e is SeqExpr);
|
||||
Contract.Ensures(Contract.Result<IntExpr>() != null);
|
||||
return new IntExpr(this, Native.Z3_mk_str_to_int(nCtx, e.NativeObject));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Concatentate sequences.
|
||||
/// </summary>
|
||||
|
@ -2416,7 +2452,7 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(Contract.ForAll(t, a => a != null));
|
||||
Contract.Ensures(Contract.Result<SeqExpr>() != null);
|
||||
|
||||
CheckContextMatch(t);
|
||||
CheckContextMatch<SeqExpr>(t);
|
||||
return new SeqExpr(this, Native.Z3_mk_seq_concat(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
|
||||
}
|
||||
|
||||
|
@ -2551,10 +2587,20 @@ namespace Microsoft.Z3
|
|||
return new ReExpr(this, Native.Z3_mk_re_star(nCtx, re.NativeObject));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Take the bounded Kleene star of a regular expression.
|
||||
/// </summary>
|
||||
public ReExpr MkLoop(ReExpr re, uint lo, uint hi = 0)
|
||||
{
|
||||
Contract.Requires(re != null);
|
||||
Contract.Ensures(Contract.Result<ReExpr>() != null);
|
||||
return new ReExpr(this, Native.Z3_mk_re_loop(nCtx, re.NativeObject, lo, hi));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Take the Kleene plus of a regular expression.
|
||||
/// </summary>
|
||||
public ReExpr MPlus(ReExpr re)
|
||||
public ReExpr MkPlus(ReExpr re)
|
||||
{
|
||||
Contract.Requires(re != null);
|
||||
Contract.Ensures(Contract.Result<ReExpr>() != null);
|
||||
|
@ -2564,13 +2610,23 @@ namespace Microsoft.Z3
|
|||
/// <summary>
|
||||
/// Create the optional regular expression.
|
||||
/// </summary>
|
||||
public ReExpr MOption(ReExpr re)
|
||||
public ReExpr MkOption(ReExpr re)
|
||||
{
|
||||
Contract.Requires(re != null);
|
||||
Contract.Ensures(Contract.Result<ReExpr>() != null);
|
||||
return new ReExpr(this, Native.Z3_mk_re_option(nCtx, re.NativeObject));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create the complement regular expression.
|
||||
/// </summary>
|
||||
public ReExpr MkComplement(ReExpr re)
|
||||
{
|
||||
Contract.Requires(re != null);
|
||||
Contract.Ensures(Contract.Result<ReExpr>() != null);
|
||||
return new ReExpr(this, Native.Z3_mk_re_complement(nCtx, re.NativeObject));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create the concatenation of regular languages.
|
||||
/// </summary>
|
||||
|
@ -2580,7 +2636,7 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(Contract.ForAll(t, a => a != null));
|
||||
Contract.Ensures(Contract.Result<ReExpr>() != null);
|
||||
|
||||
CheckContextMatch(t);
|
||||
CheckContextMatch<ReExpr>(t);
|
||||
return new ReExpr(this, Native.Z3_mk_re_concat(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
|
||||
}
|
||||
|
||||
|
@ -2593,9 +2649,55 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(Contract.ForAll(t, a => a != null));
|
||||
Contract.Ensures(Contract.Result<ReExpr>() != null);
|
||||
|
||||
CheckContextMatch(t);
|
||||
CheckContextMatch<ReExpr>(t);
|
||||
return new ReExpr(this, Native.Z3_mk_re_union(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create the intersection of regular languages.
|
||||
/// </summary>
|
||||
public ReExpr MkIntersect(params ReExpr[] t)
|
||||
{
|
||||
Contract.Requires(t != null);
|
||||
Contract.Requires(Contract.ForAll(t, a => a != null));
|
||||
Contract.Ensures(Contract.Result<ReExpr>() != null);
|
||||
|
||||
CheckContextMatch<ReExpr>(t);
|
||||
return new ReExpr(this, Native.Z3_mk_re_intersect(nCtx, (uint)t.Length, AST.ArrayToNative(t)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create the empty regular expression.
|
||||
/// </summary>
|
||||
public ReExpr MkEmptyRe(Sort s)
|
||||
{
|
||||
Contract.Requires(s != null);
|
||||
Contract.Ensures(Contract.Result<SeqExpr>() != null);
|
||||
return new ReExpr(this, Native.Z3_mk_re_empty(nCtx, s.NativeObject));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create the full regular expression.
|
||||
/// </summary>
|
||||
public ReExpr MkFullRe(Sort s)
|
||||
{
|
||||
Contract.Requires(s != null);
|
||||
Contract.Ensures(Contract.Result<SeqExpr>() != null);
|
||||
return new ReExpr(this, Native.Z3_mk_re_full(nCtx, s.NativeObject));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Create a range expression.
|
||||
/// </summary>
|
||||
public ReExpr MkRange(SeqExpr lo, SeqExpr hi)
|
||||
{
|
||||
Contract.Requires(lo != null);
|
||||
Contract.Requires(hi != null);
|
||||
Contract.Ensures(Contract.Result<ReExpr>() != null);
|
||||
CheckContextMatch(lo, hi);
|
||||
return new ReExpr(this, Native.Z3_mk_re_range(nCtx, lo.NativeObject, hi.NativeObject));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -2608,11 +2710,23 @@ namespace Microsoft.Z3
|
|||
{
|
||||
Contract.Requires(args != null);
|
||||
Contract.Requires(Contract.Result<BoolExpr[]>() != null);
|
||||
CheckContextMatch(args);
|
||||
CheckContextMatch<BoolExpr>(args);
|
||||
return new BoolExpr(this, Native.Z3_mk_atmost(nCtx, (uint) args.Length,
|
||||
AST.ArrayToNative(args), k));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create an at-least-k constraint.
|
||||
/// </summary>
|
||||
public BoolExpr MkAtLeast(BoolExpr[] args, uint k)
|
||||
{
|
||||
Contract.Requires(args != null);
|
||||
Contract.Requires(Contract.Result<BoolExpr[]>() != null);
|
||||
CheckContextMatch<BoolExpr>(args);
|
||||
return new BoolExpr(this, Native.Z3_mk_atleast(nCtx, (uint) args.Length,
|
||||
AST.ArrayToNative(args), k));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a pseudo-Boolean less-or-equal constraint.
|
||||
/// </summary>
|
||||
|
@ -2622,11 +2736,40 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(coeffs != null);
|
||||
Contract.Requires(args.Length == coeffs.Length);
|
||||
Contract.Requires(Contract.Result<BoolExpr[]>() != null);
|
||||
CheckContextMatch(args);
|
||||
CheckContextMatch<BoolExpr>(args);
|
||||
return new BoolExpr(this, Native.Z3_mk_pble(nCtx, (uint) args.Length,
|
||||
AST.ArrayToNative(args),
|
||||
coeffs, k));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a pseudo-Boolean greater-or-equal constraint.
|
||||
/// </summary>
|
||||
public BoolExpr MkPBGe(int[] coeffs, BoolExpr[] args, int k)
|
||||
{
|
||||
Contract.Requires(args != null);
|
||||
Contract.Requires(coeffs != null);
|
||||
Contract.Requires(args.Length == coeffs.Length);
|
||||
Contract.Requires(Contract.Result<BoolExpr[]>() != null);
|
||||
CheckContextMatch<BoolExpr>(args);
|
||||
return new BoolExpr(this, Native.Z3_mk_pbge(nCtx, (uint) args.Length,
|
||||
AST.ArrayToNative(args),
|
||||
coeffs, k));
|
||||
}
|
||||
/// <summary>
|
||||
/// Create a pseudo-Boolean equal constraint.
|
||||
/// </summary>
|
||||
public BoolExpr MkPBEq(int[] coeffs, BoolExpr[] args, int k)
|
||||
{
|
||||
Contract.Requires(args != null);
|
||||
Contract.Requires(coeffs != null);
|
||||
Contract.Requires(args.Length == coeffs.Length);
|
||||
Contract.Requires(Contract.Result<BoolExpr[]>() != null);
|
||||
CheckContextMatch<BoolExpr>(args);
|
||||
return new BoolExpr(this, Native.Z3_mk_pbeq(nCtx, (uint) args.Length,
|
||||
AST.ArrayToNative(args),
|
||||
coeffs, k));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Numerals
|
||||
|
@ -3373,7 +3516,7 @@ namespace Microsoft.Z3
|
|||
|
||||
CheckContextMatch(t1);
|
||||
CheckContextMatch(t2);
|
||||
CheckContextMatch(ts);
|
||||
CheckContextMatch<Tactic>(ts);
|
||||
|
||||
IntPtr last = IntPtr.Zero;
|
||||
if (ts != null && ts.Length > 0)
|
||||
|
@ -3564,7 +3707,7 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(t == null || Contract.ForAll(t, tactic => tactic != null));
|
||||
Contract.Ensures(Contract.Result<Tactic>() != null);
|
||||
|
||||
CheckContextMatch(t);
|
||||
CheckContextMatch<Tactic>(t);
|
||||
return new Tactic(this, Native.Z3_tactic_par_or(nCtx, Tactic.ArrayLength(t), Tactic.ArrayToNative(t)));
|
||||
}
|
||||
|
||||
|
@ -4797,7 +4940,7 @@ namespace Microsoft.Z3
|
|||
}
|
||||
|
||||
[Pure]
|
||||
internal void CheckContextMatch(IEnumerable<Z3Object> arr)
|
||||
internal void CheckContextMatch<T>(IEnumerable<T> arr) where T : Z3Object
|
||||
{
|
||||
Contract.Requires(arr == null || Contract.ForAll(arr, a => a != null));
|
||||
|
||||
|
@ -4940,11 +5083,12 @@ namespace Microsoft.Z3
|
|||
// Console.WriteLine("Context Finalizer from " + System.Threading.Thread.CurrentThread.ManagedThreadId);
|
||||
Dispose();
|
||||
|
||||
if (refCount == 0)
|
||||
if (refCount == 0 && m_ctx != IntPtr.Zero)
|
||||
{
|
||||
m_n_err_handler = null;
|
||||
Native.Z3_del_context(m_ctx);
|
||||
IntPtr ctx = m_ctx;
|
||||
m_ctx = IntPtr.Zero;
|
||||
Native.Z3_del_context(ctx);
|
||||
}
|
||||
else
|
||||
GC.ReRegisterForFinalize(this);
|
||||
|
|
|
@ -98,7 +98,7 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(args != null);
|
||||
Contract.Requires(Contract.ForAll(args, a => a != null));
|
||||
|
||||
Context.CheckContextMatch(args);
|
||||
Context.CheckContextMatch<Expr>(args);
|
||||
if (IsApp && args.Length != NumArgs)
|
||||
throw new Z3Exception("Number of arguments does not match");
|
||||
NativeObject = Native.Z3_update_term(Context.nCtx, NativeObject, (uint)args.Length, Expr.ArrayToNative(args));
|
||||
|
@ -120,8 +120,8 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(Contract.ForAll(to, t => t != null));
|
||||
Contract.Ensures(Contract.Result<Expr>() != null);
|
||||
|
||||
Context.CheckContextMatch(from);
|
||||
Context.CheckContextMatch(to);
|
||||
Context.CheckContextMatch<Expr>(from);
|
||||
Context.CheckContextMatch<Expr>(to);
|
||||
if (from.Length != to.Length)
|
||||
throw new Z3Exception("Argument sizes do not match");
|
||||
return Expr.Create(Context, Native.Z3_substitute(Context.nCtx, NativeObject, (uint)from.Length, Expr.ArrayToNative(from), Expr.ArrayToNative(to)));
|
||||
|
@ -152,7 +152,7 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(Contract.ForAll(to, t => t != null));
|
||||
Contract.Ensures(Contract.Result<Expr>() != null);
|
||||
|
||||
Context.CheckContextMatch(to);
|
||||
Context.CheckContextMatch<Expr>(to);
|
||||
return Expr.Create(Context, Native.Z3_substitute_vars(Context.nCtx, NativeObject, (uint)to.Length, Expr.ArrayToNative(to)));
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ Author:
|
|||
Christoph Wintersteiger (cwinter) 2013-06-10
|
||||
|
||||
Notes:
|
||||
|
||||
|
||||
--*/
|
||||
using System;
|
||||
using System.Diagnostics.Contracts;
|
||||
|
@ -27,6 +27,20 @@ namespace Microsoft.Z3
|
|||
[ContractVerification(true)]
|
||||
public class FPNum : FPExpr
|
||||
{
|
||||
/// <summary>
|
||||
/// The sign of a floating-point numeral as a bit-vector expression
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// NaN's do not have a bit-vector sign, so they are invalid arguments.
|
||||
/// </remarks>
|
||||
public BitVecExpr SignBV
|
||||
{
|
||||
get
|
||||
{
|
||||
return new BitVecExpr(Context, Native.Z3_fpa_get_numeral_sign_bv(Context.nCtx, NativeObject));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the sign of a floating-point literal
|
||||
/// </summary>
|
||||
|
@ -38,7 +52,7 @@ namespace Microsoft.Z3
|
|||
get
|
||||
{
|
||||
int res = 0;
|
||||
if (Native.Z3_fpa_get_numeral_sign(Context.nCtx, NativeObject, ref res) == 0)
|
||||
if (Native.Z3_fpa_get_numeral_sign(Context.nCtx, NativeObject, ref res) == 0)
|
||||
throw new Z3Exception("Sign is not a Boolean value");
|
||||
return res != 0;
|
||||
}
|
||||
|
@ -63,7 +77,7 @@ namespace Microsoft.Z3
|
|||
/// The significand value of a floating-point numeral as a UInt64
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This function extracts the significand bits, without the
|
||||
/// This function extracts the significand bits, without the
|
||||
/// hidden bit or normalization. Throws an exception if the
|
||||
/// significand does not fit into a UInt64.
|
||||
/// </remarks>
|
||||
|
@ -73,36 +87,90 @@ namespace Microsoft.Z3
|
|||
{
|
||||
UInt64 result = 0;
|
||||
if (Native.Z3_fpa_get_numeral_significand_uint64(Context.nCtx, NativeObject, ref result) == 0)
|
||||
throw new Z3Exception("Significand is not a 64 bit unsigned integer");
|
||||
throw new Z3Exception("Significand is not a 64 bit unsigned integer");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the exponent value of a floating-point numeral as a string
|
||||
/// The significand of a floating-point numeral as a bit-vector expression
|
||||
/// </summary>
|
||||
public string Exponent
|
||||
/// <remarks>
|
||||
/// +oo, -oo and NaN's do not have a bit-vector significand, so they are invalid arguments.
|
||||
/// </remarks>
|
||||
public BitVecExpr SignificandBV
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.Z3_fpa_get_numeral_exponent_string(Context.nCtx, NativeObject);
|
||||
return new BitVecExpr(Context, Native.Z3_fpa_get_numeral_significand_bv(Context.nCtx, NativeObject));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the (biased) exponent value of a floating-point numeral as a string
|
||||
/// </summary>
|
||||
public string Exponent(bool biased = true)
|
||||
{
|
||||
return Native.Z3_fpa_get_numeral_exponent_string(Context.nCtx, NativeObject, biased ? 1 : 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the exponent value of a floating-point numeral as a signed 64-bit integer
|
||||
/// </summary>
|
||||
public Int64 ExponentInt64
|
||||
public Int64 ExponentInt64(bool biased = true)
|
||||
{
|
||||
get
|
||||
{
|
||||
Int64 result = 0;
|
||||
if (Native.Z3_fpa_get_numeral_exponent_int64(Context.nCtx, NativeObject, ref result) == 0)
|
||||
throw new Z3Exception("Exponent is not a 64 bit integer");
|
||||
return result;
|
||||
}
|
||||
Int64 result = 0;
|
||||
if (Native.Z3_fpa_get_numeral_exponent_int64(Context.nCtx, NativeObject, ref result, biased ? 1 : 0) == 0)
|
||||
throw new Z3Exception("Exponent is not a 64 bit integer");
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The exponent of a floating-point numeral as a bit-vector expression
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// +oo, -oo and NaN's do not have a bit-vector exponent, so they are invalid arguments.
|
||||
/// </remarks>
|
||||
public BitVecExpr ExponentBV(bool biased = true)
|
||||
{
|
||||
return new BitVecExpr(Context, Native.Z3_fpa_get_numeral_exponent_bv(Context.nCtx, NativeObject, biased ? 1 : 0));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the numeral is a NaN.
|
||||
/// </summary>
|
||||
public bool IsNaN { get { return Native.Z3_fpa_is_numeral_nan(Context.nCtx, NativeObject) != 0; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the numeral is a +oo or -oo.
|
||||
/// </summary>
|
||||
public bool IsInf { get { return Native.Z3_fpa_is_numeral_inf(Context.nCtx, NativeObject) != 0; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the numeral is +zero or -zero.
|
||||
/// </summary>
|
||||
public bool IsZero{ get { return Native.Z3_fpa_is_numeral_zero(Context.nCtx, NativeObject) != 0; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the numeral is normal.
|
||||
/// </summary>
|
||||
public bool IsNormal { get { return Native.Z3_fpa_is_numeral_normal(Context.nCtx, NativeObject) != 0; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the numeral is subnormal.
|
||||
/// </summary>
|
||||
public bool IsSubnormal { get { return Native.Z3_fpa_is_numeral_subnormal(Context.nCtx, NativeObject) != 0; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the numeral is positive.
|
||||
/// </summary>
|
||||
public bool IsPositive { get { return Native.Z3_fpa_is_numeral_positive(Context.nCtx, NativeObject) != 0; } }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the numeral is negative.
|
||||
/// </summary>
|
||||
public bool IsNegative { get { return Native.Z3_fpa_is_numeral_negative(Context.nCtx, NativeObject) != 0; } }
|
||||
|
||||
#region Internal
|
||||
internal FPNum(Context ctx, IntPtr obj)
|
||||
: base(ctx, obj)
|
||||
|
@ -113,7 +181,7 @@ namespace Microsoft.Z3
|
|||
|
||||
/// <summary>
|
||||
/// Returns a string representation of the numeral.
|
||||
/// </summary>
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return Native.Z3_get_numeral_string(Context.nCtx, NativeObject);
|
||||
|
|
|
@ -71,7 +71,7 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(constraints != null);
|
||||
Contract.Requires(Contract.ForAll(constraints, c => c != null));
|
||||
|
||||
Context.CheckContextMatch(constraints);
|
||||
Context.CheckContextMatch<BoolExpr>(constraints);
|
||||
foreach (BoolExpr a in constraints)
|
||||
{
|
||||
Native.Z3_fixedpoint_assert(Context.nCtx, NativeObject, a.NativeObject);
|
||||
|
@ -151,7 +151,7 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(relations != null);
|
||||
Contract.Requires(Contract.ForAll(0, relations.Length, i => relations[i] != null));
|
||||
|
||||
Context.CheckContextMatch(relations);
|
||||
Context.CheckContextMatch<FuncDecl>(relations);
|
||||
Z3_lbool r = (Z3_lbool)Native.Z3_fixedpoint_query_relations(Context.nCtx, NativeObject,
|
||||
AST.ArrayLength(relations), AST.ArrayToNative(relations));
|
||||
switch (r)
|
||||
|
|
|
@ -339,7 +339,7 @@ namespace Microsoft.Z3
|
|||
{
|
||||
Contract.Requires(args == null || Contract.ForAll(args, a => a != null));
|
||||
|
||||
Context.CheckContextMatch(args);
|
||||
Context.CheckContextMatch<Expr>(args);
|
||||
return Expr.Create(Context, this, args);
|
||||
}
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(constraints != null);
|
||||
Contract.Requires(Contract.ForAll(constraints, c => c != null));
|
||||
|
||||
Context.CheckContextMatch(constraints);
|
||||
Context.CheckContextMatch<BoolExpr>(constraints);
|
||||
foreach (BoolExpr c in constraints)
|
||||
{
|
||||
Contract.Assert(c != null); // It was an assume, now made an assert just to be sure we do not regress
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace Microsoft.Z3
|
|||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
/// <remarks><seealso cref="Context.Context(Dictionary<string, string>)"/></remarks>
|
||||
/// <remarks><seealso cref="Context"/></remarks>
|
||||
public InterpolationContext(Dictionary<string, string> settings) : base(settings) { }
|
||||
|
||||
#region Terms
|
||||
|
|
|
@ -258,10 +258,13 @@ namespace Microsoft.Z3
|
|||
/// <summary>
|
||||
/// Return a string the describes why the last to check returned unknown
|
||||
/// </summary>
|
||||
public String getReasonUnknown()
|
||||
public String ReasonUnknown
|
||||
{
|
||||
Contract.Ensures(Contract.Result<string>() != null);
|
||||
return Native.Z3_optimize_get_reason_unknown(Context.nCtx, NativeObject);
|
||||
get
|
||||
{
|
||||
Contract.Ensures(Contract.Result<string>() != null);
|
||||
return Native.Z3_optimize_get_reason_unknown(Context.nCtx, NativeObject);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -273,6 +276,52 @@ namespace Microsoft.Z3
|
|||
return Native.Z3_optimize_to_string(Context.nCtx, NativeObject);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse an SMT-LIB2 file with optimization objectives and constraints.
|
||||
/// The parsed constraints and objectives are added to the optimization context.
|
||||
/// </summary>
|
||||
public void FromFile(string file)
|
||||
{
|
||||
Native.Z3_optimize_from_file(Context.nCtx, NativeObject, file);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Similar to FromFile. Instead it takes as argument a string.
|
||||
/// </summary>
|
||||
public void FromString(string s)
|
||||
{
|
||||
Native.Z3_optimize_from_string(Context.nCtx, NativeObject, s);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The set of asserted formulas.
|
||||
/// </summary>
|
||||
public BoolExpr[] Assertions
|
||||
{
|
||||
get
|
||||
{
|
||||
Contract.Ensures(Contract.Result<BoolExpr[]>() != null);
|
||||
|
||||
ASTVector assertions = new ASTVector(Context, Native.Z3_optimize_get_assertions(Context.nCtx, NativeObject));
|
||||
return assertions.ToBoolExprArray();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The set of asserted formulas.
|
||||
/// </summary>
|
||||
public Expr[] Objectives
|
||||
{
|
||||
get
|
||||
{
|
||||
Contract.Ensures(Contract.Result<Expr[]>() != null);
|
||||
|
||||
ASTVector objectives = new ASTVector(Context, Native.Z3_optimize_get_objectives(Context.nCtx, NativeObject));
|
||||
return objectives.ToExprArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Optimize statistics.
|
||||
/// </summary>
|
||||
|
|
|
@ -172,10 +172,10 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(patterns == null || Contract.ForAll(patterns, p => p != null));
|
||||
Contract.Requires(noPatterns == null || Contract.ForAll(noPatterns, np => np != null));
|
||||
|
||||
Context.CheckContextMatch(patterns);
|
||||
Context.CheckContextMatch(noPatterns);
|
||||
Context.CheckContextMatch(sorts);
|
||||
Context.CheckContextMatch(names);
|
||||
Context.CheckContextMatch<Pattern>(patterns);
|
||||
Context.CheckContextMatch<Expr>(noPatterns);
|
||||
Context.CheckContextMatch<Sort>(sorts);
|
||||
Context.CheckContextMatch<Symbol>(names);
|
||||
Context.CheckContextMatch(body);
|
||||
|
||||
if (sorts.Length != names.Length)
|
||||
|
@ -212,8 +212,8 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(noPatterns == null || Contract.ForAll(noPatterns, np => np != null));
|
||||
Contract.Requires(bound == null || Contract.ForAll(bound, n => n != null));
|
||||
|
||||
Context.CheckContextMatch(noPatterns);
|
||||
Context.CheckContextMatch(patterns);
|
||||
Context.CheckContextMatch<Expr>(noPatterns);
|
||||
Context.CheckContextMatch<Pattern>(patterns);
|
||||
//Context.CheckContextMatch(bound);
|
||||
Context.CheckContextMatch(body);
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@ Notes:
|
|||
--*/
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.Contracts;
|
||||
|
||||
namespace Microsoft.Z3
|
||||
|
@ -110,7 +112,7 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(constraints != null);
|
||||
Contract.Requires(Contract.ForAll(constraints, c => c != null));
|
||||
|
||||
Context.CheckContextMatch(constraints);
|
||||
Context.CheckContextMatch<BoolExpr>(constraints);
|
||||
foreach (BoolExpr a in constraints)
|
||||
{
|
||||
Native.Z3_solver_assert(Context.nCtx, NativeObject, a.NativeObject);
|
||||
|
@ -125,6 +127,14 @@ namespace Microsoft.Z3
|
|||
Assert(constraints);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Alias for Assert.
|
||||
/// </summary>
|
||||
public void Add(IEnumerable<BoolExpr> constraints)
|
||||
{
|
||||
Assert(constraints.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assert multiple constraints into the solver, and track them (in the unsat) core
|
||||
/// using the Boolean constants in ps.
|
||||
|
@ -141,8 +151,8 @@ namespace Microsoft.Z3
|
|||
Contract.Requires(constraints != null);
|
||||
Contract.Requires(Contract.ForAll(constraints, c => c != null));
|
||||
Contract.Requires(Contract.ForAll(ps, c => c != null));
|
||||
Context.CheckContextMatch(constraints);
|
||||
Context.CheckContextMatch(ps);
|
||||
Context.CheckContextMatch<BoolExpr>(constraints);
|
||||
Context.CheckContextMatch<BoolExpr>(ps);
|
||||
if (constraints.Length != ps.Length)
|
||||
throw new Z3Exception("Argument size mismatch");
|
||||
|
||||
|
@ -212,12 +222,34 @@ namespace Microsoft.Z3
|
|||
r = (Z3_lbool)Native.Z3_solver_check(Context.nCtx, NativeObject);
|
||||
else
|
||||
r = (Z3_lbool)Native.Z3_solver_check_assumptions(Context.nCtx, NativeObject, (uint)assumptions.Length, AST.ArrayToNative(assumptions));
|
||||
switch (r)
|
||||
{
|
||||
case Z3_lbool.Z3_L_TRUE: return Status.SATISFIABLE;
|
||||
case Z3_lbool.Z3_L_FALSE: return Status.UNSATISFIABLE;
|
||||
default: return Status.UNKNOWN;
|
||||
}
|
||||
return lboolToStatus(r);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve fixed assignments to the set of variables in the form of consequences.
|
||||
/// Each consequence is an implication of the form
|
||||
///
|
||||
/// relevant-assumptions Implies variable = value
|
||||
///
|
||||
/// where the relevant assumptions is a subset of the assumptions that are passed in
|
||||
/// and the equality on the right side of the implication indicates how a variable
|
||||
/// is fixed.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <seealso cref="Model"/>
|
||||
/// <seealso cref="UnsatCore"/>
|
||||
/// <seealso cref="Proof"/>
|
||||
/// </remarks>
|
||||
public Status Consequences(IEnumerable<BoolExpr> assumptions, IEnumerable<Expr> variables, out BoolExpr[] consequences)
|
||||
{
|
||||
ASTVector result = new ASTVector(Context);
|
||||
ASTVector asms = new ASTVector(Context);
|
||||
ASTVector vars = new ASTVector(Context);
|
||||
foreach (var asm in assumptions) asms.Push(asm);
|
||||
foreach (var v in variables) vars.Push(v);
|
||||
Z3_lbool r = (Z3_lbool)Native.Z3_solver_get_consequences(Context.nCtx, NativeObject, asms.NativeObject, vars.NativeObject, result.NativeObject);
|
||||
consequences = result.ToBoolExprArray();
|
||||
return lboolToStatus(r);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -295,7 +327,7 @@ namespace Microsoft.Z3
|
|||
/// </summary>
|
||||
public Solver Translate(Context ctx)
|
||||
{
|
||||
Contract.Requires(ctx != null);
|
||||
Contract.Requires(ctx != null);
|
||||
Contract.Ensures(Contract.Result<Solver>() != null);
|
||||
return new Solver(ctx, Native.Z3_solver_translate(Context.nCtx, NativeObject, ctx.nCtx));
|
||||
}
|
||||
|
@ -355,6 +387,17 @@ namespace Microsoft.Z3
|
|||
Context.Solver_DRQ.Add(o);
|
||||
base.DecRef(o);
|
||||
}
|
||||
|
||||
private Status lboolToStatus(Z3_lbool r)
|
||||
{
|
||||
switch (r)
|
||||
{
|
||||
case Z3_lbool.Z3_L_TRUE: return Status.SATISFIABLE;
|
||||
case Z3_lbool.Z3_L_FALSE: return Status.UNSATISFIABLE;
|
||||
default: return Status.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,6 +83,17 @@ namespace Microsoft.Z3
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A full version string
|
||||
/// </summary>
|
||||
public static string FullVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return Native.Z3_get_full_version();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A string representation of the version information.
|
||||
/// </summary>
|
||||
|
|
|
@ -14,17 +14,20 @@ Author:
|
|||
Christoph Wintersteiger (cwinter) 2012-03-15
|
||||
|
||||
Notes:
|
||||
|
||||
|
||||
--*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.Z3
|
||||
{
|
||||
/// <summary>
|
||||
/// The exception base class for error reporting from Z3
|
||||
/// </summary>
|
||||
public class Z3Exception : Exception
|
||||
/// <summary>
|
||||
/// The exception base class for error reporting from Z3
|
||||
/// </summary>
|
||||
#if !DOTNET_CORE
|
||||
[Serializable]
|
||||
#endif
|
||||
public class Z3Exception : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
|
|
|
@ -138,7 +138,7 @@ namespace Microsoft.Z3
|
|||
}
|
||||
|
||||
[Pure]
|
||||
internal static IntPtr[] EnumToNative(IEnumerable<Z3Object> a)
|
||||
internal static IntPtr[] EnumToNative<T>(IEnumerable<T> a) where T : Z3Object
|
||||
{
|
||||
Contract.Ensures(a == null || Contract.Result<IntPtr[]>() != null);
|
||||
Contract.Ensures(a == null || Contract.Result<IntPtr[]>().Length == a.Count());
|
||||
|
|
65
src/api/dotnet/core/DummyContracts.cs
Normal file
65
src/api/dotnet/core/DummyContracts.cs
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*++
|
||||
Copyright (<c>) 2016 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
Contracts.cs
|
||||
|
||||
Abstract:
|
||||
|
||||
Z3 Managed API: Dummy Code Contracts class for .NET
|
||||
frameworks that don't support them (e.g., CoreCLR).
|
||||
|
||||
Author:
|
||||
|
||||
Christoph Wintersteiger (cwinter) 2016-10-06
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
|
||||
namespace System.Diagnostics.Contracts
|
||||
{
|
||||
public class ContractClass : Attribute
|
||||
{
|
||||
public ContractClass(Type t) { }
|
||||
}
|
||||
|
||||
public class ContractClassFor : Attribute
|
||||
{
|
||||
public ContractClassFor(Type t) { }
|
||||
}
|
||||
|
||||
public class ContractInvariantMethod : Attribute
|
||||
{
|
||||
public ContractInvariantMethod() { }
|
||||
}
|
||||
|
||||
public class ContractVerification : Attribute
|
||||
{
|
||||
public ContractVerification(bool b) { }
|
||||
}
|
||||
|
||||
public class Pure : Attribute { }
|
||||
|
||||
public static class Contract
|
||||
{
|
||||
[Conditional("false")]
|
||||
public static void Ensures(bool b) { }
|
||||
[Conditional("false")]
|
||||
public static void Requires(bool b) { }
|
||||
[Conditional("false")]
|
||||
public static void Assume(bool b, string msg) { }
|
||||
[Conditional("false")]
|
||||
public static void Assert(bool b) { }
|
||||
public static bool ForAll(bool b) { return true; }
|
||||
public static bool ForAll(Object c, Func<Object, bool> p) { return true; }
|
||||
public static bool ForAll(int from, int to, Predicate<int> p) { return true; }
|
||||
[Conditional("false")]
|
||||
public static void Invariant(bool b) { }
|
||||
public static T[] Result<T>() { return new T[1]; }
|
||||
[Conditional("false")]
|
||||
public static void EndContractBlock() { }
|
||||
public static T ValueAtReturn<T>(out T v) { T[] t = new T[1]; v = t[0]; return v; }
|
||||
}
|
||||
}
|
9
src/api/dotnet/core/README.txt
Normal file
9
src/api/dotnet/core/README.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
Z3 API for .NET Core
|
||||
|
||||
Z3's .NET API uses Code Contracts, which are not included in .NET Core. The
|
||||
enclosed file called DummyContracts.cs provides stubs for the Code Contracts
|
||||
functions, so that the API will compile, but not perform any contract
|
||||
checking. To build this using .NET core, run (in this directory):
|
||||
|
||||
dotnet restore
|
||||
dotnet build project.json
|
22
src/api/dotnet/core/project.json
Normal file
22
src/api/dotnet/core/project.json
Normal file
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"version": "1.0.0-*",
|
||||
"buildOptions": {
|
||||
"debugType": "portable",
|
||||
"emitEntryPoint": false,
|
||||
"outputName": "Microsoft.Z3",
|
||||
"compile": [ "../*.cs", "*.cs" ],
|
||||
"define": ["DOTNET_CORE"]
|
||||
},
|
||||
"dependencies": { },
|
||||
"frameworks": {
|
||||
"netcoreapp1.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"type": "platform",
|
||||
"version": "1.0.1"
|
||||
}
|
||||
},
|
||||
"imports": "dnxcore50"
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue