3
0
Fork 0
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:
Murphy Berzish 2017-02-18 15:04:44 -05:00
commit 235ea79043
588 changed files with 21784 additions and 15202 deletions

4
.gitignore vendored
View file

@ -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

View file

@ -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()

View file

@ -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 |
| ----------- | ----------- | ---------- | ---------- | ---------- | --- |
![win32-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/4/badge) | ![win64-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/7/badge) | ![ubuntu-x64-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/3/badge) | ![ubuntu-x86-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/6/badge) | ![debian-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/5/badge) | ![osx-badge](https://cz3.visualstudio.com/_apis/public/build/definitions/bf14bcc7-ebd4-4240-812c-5972fa59e0ad/2/badge)
[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

View file

@ -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
=============

View file

@ -1,2 +1,4 @@
add_subdirectory(c)
add_subdirectory(c++)
add_subdirectory(tptp)
add_subdirectory(python)

View file

@ -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()

View file

@ -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()

View 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}
)

View 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++")

View file

@ -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})

View file

@ -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")

View file

@ -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

View file

@ -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")

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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.")

View file

@ -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) {

View file

@ -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();

View file

@ -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();

View file

@ -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

View file

@ -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")]

View file

@ -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();

View 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)

View file

@ -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 *

View 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
View 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()

View 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

View file

@ -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;
}

View file

@ -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')

View file

@ -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

View file

@ -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++')

View file

@ -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)

View file

@ -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

View file

@ -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()

View file

@ -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__':

View file

@ -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;

View file

@ -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;

View file

@ -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));

View file

@ -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);
}

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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();

View file

@ -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();
};

View file

@ -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++) {

View file

@ -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() {}
};

View file

@ -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);
}
};

View file

@ -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());
}
}

View file

@ -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;

View file

@ -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); }

View file

@ -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);

View file

@ -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); }
};

View file

@ -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);

View file

@ -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);
}
};

View file

@ -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);

View file

@ -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() {}
};

View file

@ -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){

View file

@ -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
}
}
}

View file

@ -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);

View file

@ -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() {}
};

View file

@ -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);
}
};

View file

@ -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);

View file

@ -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);
}
};

View file

@ -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();

View file

@ -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));
}
};

View file

@ -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);

View file

@ -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);
}
};

View file

@ -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() {}
};

View file

@ -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() {}
};

View file

@ -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));

View file

@ -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() {}
};

View file

@ -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() {}
};

View file

@ -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;

View file

@ -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);

View file

@ -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)));
}

View file

@ -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);

View file

@ -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)

View file

@ -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);
}

View file

@ -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

View file

@ -30,7 +30,7 @@ namespace Microsoft.Z3
/// <summary>
/// Constructor.
/// </summary>
/// <remarks><seealso cref="Context.Context(Dictionary&lt;string, string&gt;)"/></remarks>
/// <remarks><seealso cref="Context"/></remarks>
public InterpolationContext(Dictionary<string, string> settings) : base(settings) { }
#region Terms

View file

@ -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>

View file

@ -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);

View file

@ -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
}
}

View file

@ -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>

View file

@ -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.

View file

@ -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());

View 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; }
}
}

View 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

View 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