mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 17:15:31 +00:00
added facility to persist model transformations
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
commit
fd49a0c89c
195 changed files with 3601 additions and 2139 deletions
|
@ -7,6 +7,30 @@ else()
|
|||
set(EXTERNAL_PROJECT_BUILD_ALWAYS_ARG "")
|
||||
endif()
|
||||
|
||||
option(Z3_C_EXAMPLES_FORCE_CXX_LINKER
|
||||
"Force C++ linker when building C example projects" OFF)
|
||||
|
||||
if (Z3_C_EXAMPLES_FORCE_CXX_LINKER)
|
||||
# HACK: This is a workaround for UBSan.
|
||||
message(STATUS "Forcing C++ linker to be used when building example C projects")
|
||||
set(EXTERNAL_C_PROJ_USE_CXX_LINKER_ARG
|
||||
"-DFORCE_CXX_LINKER=ON"
|
||||
)
|
||||
else()
|
||||
set(EXTERNAL_C_PROJ_USE_CXX_LINKER_ARG "")
|
||||
endif()
|
||||
|
||||
if (DEFINED CMAKE_CONFIGURATION_TYPES)
|
||||
message(WARNING
|
||||
"Cannot set built type of external project when building with a "
|
||||
"multi-configuration generator")
|
||||
set(EXTERNAL_PROJECT_CMAKE_BUILD_TYPE_ARG "")
|
||||
else()
|
||||
set(EXTERNAL_PROJECT_CMAKE_BUILD_TYPE_ARG
|
||||
"-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}"
|
||||
)
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# Build example project using libz3's C API as an external project
|
||||
################################################################################
|
||||
|
@ -14,7 +38,10 @@ ExternalProject_Add(c_example
|
|||
DEPENDS libz3
|
||||
# Configure step
|
||||
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/c"
|
||||
CMAKE_ARGS "-DZ3_DIR=${CMAKE_BINARY_DIR}"
|
||||
CMAKE_ARGS
|
||||
"-DZ3_DIR=${CMAKE_BINARY_DIR}"
|
||||
"${EXTERNAL_C_PROJ_USE_CXX_LINKER_ARG}"
|
||||
"${EXTERNAL_PROJECT_CMAKE_BUILD_TYPE_ARG}"
|
||||
# Build step
|
||||
${EXTERNAL_PROJECT_BUILD_ALWAYS_ARG}
|
||||
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/c_example_build_dir"
|
||||
|
@ -30,7 +57,10 @@ ExternalProject_Add(c_maxsat_example
|
|||
DEPENDS libz3
|
||||
# Configure step
|
||||
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/maxsat"
|
||||
CMAKE_ARGS "-DZ3_DIR=${CMAKE_BINARY_DIR}"
|
||||
CMAKE_ARGS
|
||||
"-DZ3_DIR=${CMAKE_BINARY_DIR}"
|
||||
"${EXTERNAL_C_PROJ_USE_CXX_LINKER_ARG}"
|
||||
"${EXTERNAL_PROJECT_CMAKE_BUILD_TYPE_ARG}"
|
||||
# Build step
|
||||
${EXTERNAL_PROJECT_BUILD_ALWAYS_ARG}
|
||||
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/c_maxsat_example_build_dir"
|
||||
|
@ -47,7 +77,9 @@ ExternalProject_Add(cpp_example
|
|||
DEPENDS libz3
|
||||
# Configure step
|
||||
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/c++"
|
||||
CMAKE_ARGS "-DZ3_DIR=${CMAKE_BINARY_DIR}"
|
||||
CMAKE_ARGS
|
||||
"-DZ3_DIR=${CMAKE_BINARY_DIR}"
|
||||
"${EXTERNAL_PROJECT_CMAKE_BUILD_TYPE_ARG}"
|
||||
# Build step
|
||||
${EXTERNAL_PROJECT_BUILD_ALWAYS_ARG}
|
||||
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/cpp_example_build_dir"
|
||||
|
@ -63,7 +95,9 @@ ExternalProject_Add(z3_tptp5
|
|||
DEPENDS libz3
|
||||
# Configure step
|
||||
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/tptp"
|
||||
CMAKE_ARGS "-DZ3_DIR=${CMAKE_BINARY_DIR}"
|
||||
CMAKE_ARGS
|
||||
"-DZ3_DIR=${CMAKE_BINARY_DIR}"
|
||||
"${EXTERNAL_PROJECT_CMAKE_BUILD_TYPE_ARG}"
|
||||
# Build step
|
||||
${EXTERNAL_PROJECT_BUILD_ALWAYS_ARG}
|
||||
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/tptp_build_dir"
|
||||
|
|
|
@ -7,6 +7,19 @@
|
|||
# the C++ standard library in resulting in a link failure.
|
||||
project(Z3_C_EXAMPLE C CXX)
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
# Set C version required to C99
|
||||
if ("${CMAKE_VERSION}" VERSION_LESS "3.1")
|
||||
if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR
|
||||
("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang"))
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 ")
|
||||
endif()
|
||||
else()
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_C_EXTENSIONS OFF)
|
||||
endif()
|
||||
|
||||
find_package(Z3
|
||||
REQUIRED
|
||||
CONFIG
|
||||
|
@ -22,6 +35,17 @@ message(STATUS "Found Z3 ${Z3_VERSION_STRING}")
|
|||
message(STATUS "Z3_DIR: ${Z3_DIR}")
|
||||
|
||||
add_executable(c_example test_capi.c)
|
||||
|
||||
option(FORCE_CXX_LINKER "Force linker with C++ linker" OFF)
|
||||
if (FORCE_CXX_LINKER)
|
||||
# This is a hack for avoiding UBSan linking errors
|
||||
message(STATUS "Forcing use of C++ linker")
|
||||
set_target_properties(c_example
|
||||
PROPERTIES
|
||||
LINKER_LANGUAGE CXX
|
||||
)
|
||||
endif()
|
||||
|
||||
target_include_directories(c_example PRIVATE ${Z3_C_INCLUDE_DIRS})
|
||||
target_link_libraries(c_example PRIVATE ${Z3_LIBRARIES})
|
||||
|
||||
|
|
|
@ -2771,80 +2771,279 @@ void fpa_example() {
|
|||
double_sort = Z3_mk_fpa_sort(ctx, 11, 53);
|
||||
rm_sort = Z3_mk_fpa_rounding_mode_sort(ctx);
|
||||
|
||||
// Show that there are x, y s.t. (x + y) = 42.0 (with rounding mode).
|
||||
s_rm = Z3_mk_string_symbol(ctx, "rm");
|
||||
rm = Z3_mk_const(ctx, s_rm, rm_sort);
|
||||
s_x = Z3_mk_string_symbol(ctx, "x");
|
||||
s_y = Z3_mk_string_symbol(ctx, "y");
|
||||
x = Z3_mk_const(ctx, s_x, double_sort);
|
||||
y = Z3_mk_const(ctx, s_y, double_sort);
|
||||
n = Z3_mk_fpa_numeral_double(ctx, 42.0, double_sort);
|
||||
|
||||
s_x_plus_y = Z3_mk_string_symbol(ctx, "x_plus_y");
|
||||
x_plus_y = Z3_mk_const(ctx, s_x_plus_y, double_sort);
|
||||
c1 = Z3_mk_eq(ctx, x_plus_y, Z3_mk_fpa_add(ctx, rm, x, y));
|
||||
|
||||
args[0] = c1;
|
||||
args[1] = Z3_mk_eq(ctx, x_plus_y, n);
|
||||
c2 = Z3_mk_and(ctx, 2, (Z3_ast*)&args);
|
||||
|
||||
args2[0] = c2;
|
||||
args2[1] = Z3_mk_not(ctx, Z3_mk_eq(ctx, rm, Z3_mk_fpa_rtz(ctx)));
|
||||
c3 = Z3_mk_and(ctx, 2, (Z3_ast*)&args2);
|
||||
|
||||
and_args[0] = Z3_mk_not(ctx, Z3_mk_fpa_is_zero(ctx, y));
|
||||
and_args[1] = Z3_mk_not(ctx, Z3_mk_fpa_is_nan(ctx, y));
|
||||
and_args[2] = Z3_mk_not(ctx, Z3_mk_fpa_is_infinite(ctx, y));
|
||||
args3[0] = c3;
|
||||
args3[1] = Z3_mk_and(ctx, 3, and_args);
|
||||
c4 = Z3_mk_and(ctx, 2, (Z3_ast*)&args3);
|
||||
|
||||
printf("c4: %s\n", Z3_ast_to_string(ctx, c4));
|
||||
Z3_solver_push(ctx, s);
|
||||
Z3_solver_assert(ctx, s, c4);
|
||||
check(ctx, s, Z3_L_TRUE);
|
||||
Z3_solver_pop(ctx, s, 1);
|
||||
|
||||
// Show that the following are equal:
|
||||
// (fp #b0 #b10000000001 #xc000000000000)
|
||||
// ((_ to_fp 11 53) #x401c000000000000))
|
||||
// ((_ to_fp 11 53) RTZ 1.75 2)))
|
||||
// ((_ to_fp 11 53) RTZ 7.0)))
|
||||
|
||||
Z3_solver_push(ctx, s);
|
||||
c1 = Z3_mk_fpa_fp(ctx,
|
||||
Z3_mk_numeral(ctx, "0", Z3_mk_bv_sort(ctx, 1)),
|
||||
Z3_mk_numeral(ctx, "1025", Z3_mk_bv_sort(ctx, 11)),
|
||||
// Show that there are x, y s.t. (x + y) = 42.0 (with rounding mode).
|
||||
s_rm = Z3_mk_string_symbol(ctx, "rm");
|
||||
rm = Z3_mk_const(ctx, s_rm, rm_sort);
|
||||
s_x = Z3_mk_string_symbol(ctx, "x");
|
||||
s_y = Z3_mk_string_symbol(ctx, "y");
|
||||
x = Z3_mk_const(ctx, s_x, double_sort);
|
||||
y = Z3_mk_const(ctx, s_y, double_sort);
|
||||
n = Z3_mk_fpa_numeral_double(ctx, 42.0, double_sort);
|
||||
|
||||
s_x_plus_y = Z3_mk_string_symbol(ctx, "x_plus_y");
|
||||
x_plus_y = Z3_mk_const(ctx, s_x_plus_y, double_sort);
|
||||
c1 = Z3_mk_eq(ctx, x_plus_y, Z3_mk_fpa_add(ctx, rm, x, y));
|
||||
|
||||
args[0] = c1;
|
||||
args[1] = Z3_mk_eq(ctx, x_plus_y, n);
|
||||
c2 = Z3_mk_and(ctx, 2, (Z3_ast*)&args);
|
||||
|
||||
args2[0] = c2;
|
||||
args2[1] = Z3_mk_not(ctx, Z3_mk_eq(ctx, rm, Z3_mk_fpa_rtz(ctx)));
|
||||
c3 = Z3_mk_and(ctx, 2, (Z3_ast*)&args2);
|
||||
|
||||
and_args[0] = Z3_mk_not(ctx, Z3_mk_fpa_is_zero(ctx, y));
|
||||
and_args[1] = Z3_mk_not(ctx, Z3_mk_fpa_is_nan(ctx, y));
|
||||
and_args[2] = Z3_mk_not(ctx, Z3_mk_fpa_is_infinite(ctx, y));
|
||||
args3[0] = c3;
|
||||
args3[1] = Z3_mk_and(ctx, 3, and_args);
|
||||
c4 = Z3_mk_and(ctx, 2, (Z3_ast*)&args3);
|
||||
|
||||
printf("c4: %s\n", Z3_ast_to_string(ctx, c4));
|
||||
Z3_solver_push(ctx, s);
|
||||
Z3_solver_assert(ctx, s, c4);
|
||||
check(ctx, s, Z3_L_TRUE);
|
||||
Z3_solver_pop(ctx, s, 1);
|
||||
|
||||
// Show that the following are equal:
|
||||
// (fp #b0 #b10000000001 #xc000000000000)
|
||||
// ((_ to_fp 11 53) #x401c000000000000))
|
||||
// ((_ to_fp 11 53) RTZ 1.75 2)))
|
||||
// ((_ to_fp 11 53) RTZ 7.0)))
|
||||
|
||||
Z3_solver_push(ctx, s);
|
||||
c1 = Z3_mk_fpa_fp(ctx,
|
||||
Z3_mk_numeral(ctx, "0", Z3_mk_bv_sort(ctx, 1)),
|
||||
Z3_mk_numeral(ctx, "1025", Z3_mk_bv_sort(ctx, 11)),
|
||||
Z3_mk_numeral(ctx, "3377699720527872", Z3_mk_bv_sort(ctx, 52)));
|
||||
c2 = Z3_mk_fpa_to_fp_bv(ctx,
|
||||
Z3_mk_numeral(ctx, "4619567317775286272", Z3_mk_bv_sort(ctx, 64)),
|
||||
Z3_mk_fpa_sort(ctx, 11, 53));
|
||||
c2 = Z3_mk_fpa_to_fp_bv(ctx,
|
||||
Z3_mk_numeral(ctx, "4619567317775286272", Z3_mk_bv_sort(ctx, 64)),
|
||||
Z3_mk_fpa_sort(ctx, 11, 53));
|
||||
c3 = Z3_mk_fpa_to_fp_int_real(ctx,
|
||||
Z3_mk_fpa_rtz(ctx),
|
||||
Z3_mk_numeral(ctx, "2", Z3_mk_int_sort(ctx)), /* exponent */
|
||||
Z3_mk_numeral(ctx, "2", Z3_mk_int_sort(ctx)), /* exponent */
|
||||
Z3_mk_numeral(ctx, "1.75", Z3_mk_real_sort(ctx)), /* significand */
|
||||
Z3_mk_fpa_sort(ctx, 11, 53));
|
||||
c4 = Z3_mk_fpa_to_fp_real(ctx,
|
||||
Z3_mk_fpa_rtz(ctx),
|
||||
Z3_mk_numeral(ctx, "7.0", Z3_mk_real_sort(ctx)),
|
||||
Z3_mk_fpa_sort(ctx, 11, 53));
|
||||
args3[0] = Z3_mk_eq(ctx, c1, c2);
|
||||
args3[1] = Z3_mk_eq(ctx, c1, c3);
|
||||
args3[2] = Z3_mk_eq(ctx, c1, c4);
|
||||
c5 = Z3_mk_and(ctx, 3, args3);
|
||||
|
||||
printf("c5: %s\n", Z3_ast_to_string(ctx, c5));
|
||||
Z3_solver_assert(ctx, s, c5);
|
||||
check(ctx, s, Z3_L_TRUE);
|
||||
Z3_solver_pop(ctx, s, 1);
|
||||
|
||||
Z3_mk_fpa_rtz(ctx),
|
||||
Z3_mk_numeral(ctx, "7.0", Z3_mk_real_sort(ctx)),
|
||||
Z3_mk_fpa_sort(ctx, 11, 53));
|
||||
args3[0] = Z3_mk_eq(ctx, c1, c2);
|
||||
args3[1] = Z3_mk_eq(ctx, c1, c3);
|
||||
args3[2] = Z3_mk_eq(ctx, c1, c4);
|
||||
c5 = Z3_mk_and(ctx, 3, args3);
|
||||
|
||||
printf("c5: %s\n", Z3_ast_to_string(ctx, c5));
|
||||
Z3_solver_assert(ctx, s, c5);
|
||||
check(ctx, s, Z3_L_TRUE);
|
||||
Z3_solver_pop(ctx, s, 1);
|
||||
|
||||
del_solver(ctx, s);
|
||||
Z3_del_context(ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Demonstrates some basic features of model construction
|
||||
*/
|
||||
|
||||
void mk_model_example() {
|
||||
Z3_context ctx;
|
||||
Z3_model m;
|
||||
Z3_sort intSort;
|
||||
Z3_symbol aSymbol, bSymbol, cSymbol;
|
||||
Z3_func_decl aFuncDecl, bFuncDecl, cFuncDecl;
|
||||
Z3_ast aApp, bApp, cApp;
|
||||
Z3_sort int2intArraySort;
|
||||
Z3_ast zeroNumeral, oneNumeral, twoNumeral, threeNumeral, fourNumeral;
|
||||
Z3_sort arrayDomain[1];
|
||||
Z3_func_decl cAsFuncDecl;
|
||||
Z3_func_interp cAsFuncInterp;
|
||||
Z3_ast_vector zeroArgs;
|
||||
Z3_ast_vector oneArgs;
|
||||
Z3_ast cFuncDeclAsArray;
|
||||
Z3_string modelAsString;
|
||||
|
||||
printf("\nmk_model_example\n");
|
||||
ctx = mk_context();
|
||||
// Construct empty model
|
||||
m = Z3_mk_model(ctx);
|
||||
Z3_model_inc_ref(ctx, m);
|
||||
|
||||
// Create constants "a" and "b"
|
||||
intSort = Z3_mk_int_sort(ctx);
|
||||
aSymbol = Z3_mk_string_symbol(ctx, "a");
|
||||
aFuncDecl = Z3_mk_func_decl(ctx, aSymbol,
|
||||
/*domain_size=*/0,
|
||||
/*domain=*/NULL,
|
||||
/*range=*/intSort);
|
||||
aApp = Z3_mk_app(ctx, aFuncDecl,
|
||||
/*num_args=*/0,
|
||||
/*args=*/NULL);
|
||||
bSymbol = Z3_mk_string_symbol(ctx, "b");
|
||||
bFuncDecl = Z3_mk_func_decl(ctx, bSymbol,
|
||||
/*domain_size=*/0,
|
||||
/*domain=*/NULL,
|
||||
/*range=*/intSort);
|
||||
bApp = Z3_mk_app(ctx, bFuncDecl,
|
||||
/*num_args=*/0,
|
||||
/*args=*/NULL);
|
||||
|
||||
// Create array "c" that maps int to int.
|
||||
cSymbol = Z3_mk_string_symbol(ctx, "c");
|
||||
int2intArraySort = Z3_mk_array_sort(ctx,
|
||||
/*domain=*/intSort,
|
||||
/*range=*/intSort);
|
||||
cFuncDecl = Z3_mk_func_decl(ctx, cSymbol,
|
||||
/*domain_size=*/0,
|
||||
/*domain=*/NULL,
|
||||
/*range=*/int2intArraySort);
|
||||
cApp = Z3_mk_app(ctx, cFuncDecl,
|
||||
/*num_args=*/0,
|
||||
/*args=*/NULL);
|
||||
|
||||
// Create numerals to be used in model
|
||||
zeroNumeral = Z3_mk_int(ctx, 0, intSort);
|
||||
oneNumeral = Z3_mk_int(ctx, 1, intSort);
|
||||
twoNumeral = Z3_mk_int(ctx, 2, intSort);
|
||||
threeNumeral = Z3_mk_int(ctx, 3, intSort);
|
||||
fourNumeral = Z3_mk_int(ctx, 4, intSort);
|
||||
|
||||
// Add assignments to model
|
||||
// a == 1
|
||||
Z3_add_const_interp(ctx, m, aFuncDecl, oneNumeral);
|
||||
// b == 2
|
||||
Z3_add_const_interp(ctx, m, bFuncDecl, twoNumeral);
|
||||
|
||||
// Create a fresh function that represents
|
||||
// reading from array.
|
||||
arrayDomain[0] = intSort;
|
||||
cAsFuncDecl = Z3_mk_fresh_func_decl(ctx,
|
||||
/*prefix=*/"",
|
||||
/*domain_size*/ 1,
|
||||
/*domain=*/arrayDomain,
|
||||
/*sort=*/intSort);
|
||||
// Create function interpretation with default
|
||||
// value of "0".
|
||||
cAsFuncInterp =
|
||||
Z3_add_func_interp(ctx, m, cAsFuncDecl,
|
||||
/*default_value=*/zeroNumeral);
|
||||
Z3_func_interp_inc_ref(ctx, cAsFuncInterp);
|
||||
// Add [0] = 3
|
||||
zeroArgs = Z3_mk_ast_vector(ctx);
|
||||
Z3_ast_vector_inc_ref(ctx, zeroArgs);
|
||||
Z3_ast_vector_push(ctx, zeroArgs, zeroNumeral);
|
||||
Z3_func_interp_add_entry(ctx, cAsFuncInterp, zeroArgs, threeNumeral);
|
||||
// Add [1] = 4
|
||||
oneArgs = Z3_mk_ast_vector(ctx);
|
||||
Z3_ast_vector_inc_ref(ctx, oneArgs);
|
||||
Z3_ast_vector_push(ctx, oneArgs, oneNumeral);
|
||||
Z3_func_interp_add_entry(ctx, cAsFuncInterp, oneArgs, fourNumeral);
|
||||
|
||||
// Now use the `(_ as_array)` to associate
|
||||
// the `cAsFuncInterp` with the `cFuncDecl`
|
||||
// in the model
|
||||
cFuncDeclAsArray = Z3_mk_as_array(ctx, cAsFuncDecl);
|
||||
Z3_add_const_interp(ctx, m, cFuncDecl, cFuncDeclAsArray);
|
||||
|
||||
// Print the model
|
||||
modelAsString = Z3_model_to_string(ctx, m);
|
||||
printf("Model:\n%s\n", modelAsString);
|
||||
|
||||
// Check the interpretations we expect to be present
|
||||
// are.
|
||||
{
|
||||
Z3_func_decl expectedInterpretations[3] = {aFuncDecl, bFuncDecl, cFuncDecl};
|
||||
int index;
|
||||
for (index = 0;
|
||||
index < sizeof(expectedInterpretations) / sizeof(Z3_func_decl);
|
||||
++index) {
|
||||
Z3_func_decl d = expectedInterpretations[index];
|
||||
if (Z3_model_has_interp(ctx, m, d)) {
|
||||
printf("Found interpretation for \"%s\"\n",
|
||||
Z3_ast_to_string(ctx, Z3_func_decl_to_ast(ctx, d)));
|
||||
} else {
|
||||
printf("Missing interpretation");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Evaluate a + b under model
|
||||
Z3_ast addArgs[] = {aApp, bApp};
|
||||
Z3_ast aPlusB = Z3_mk_add(ctx,
|
||||
/*num_args=*/2,
|
||||
/*args=*/addArgs);
|
||||
Z3_ast aPlusBEval = NULL;
|
||||
Z3_bool aPlusBEvalSuccess =
|
||||
Z3_model_eval(ctx, m, aPlusB,
|
||||
/*model_completion=*/Z3_FALSE, &aPlusBEval);
|
||||
if (aPlusBEvalSuccess != Z3_TRUE) {
|
||||
printf("Failed to evaluate model\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
{
|
||||
int aPlusBValue = 0;
|
||||
Z3_bool getAPlusBValueSuccess =
|
||||
Z3_get_numeral_int(ctx, aPlusBEval, &aPlusBValue);
|
||||
if (getAPlusBValueSuccess != Z3_TRUE) {
|
||||
printf("Failed to get integer value for a+b\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("Evaluated a + b = %d\n", aPlusBValue);
|
||||
if (aPlusBValue != 3) {
|
||||
printf("a+b did not evaluate to expected value\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Evaluate c[0] + c[1] + c[2] under model
|
||||
Z3_ast c0 = Z3_mk_select(ctx, cApp, zeroNumeral);
|
||||
Z3_ast c1 = Z3_mk_select(ctx, cApp, oneNumeral);
|
||||
Z3_ast c2 = Z3_mk_select(ctx, cApp, twoNumeral);
|
||||
Z3_ast arrayAddArgs[] = {c0, c1, c2};
|
||||
Z3_ast arrayAdd = Z3_mk_add(ctx,
|
||||
/*num_args=*/3,
|
||||
/*args=*/arrayAddArgs);
|
||||
Z3_ast arrayAddEval = NULL;
|
||||
Z3_bool arrayAddEvalSuccess =
|
||||
Z3_model_eval(ctx, m, arrayAdd,
|
||||
/*model_completion=*/Z3_FALSE, &arrayAddEval);
|
||||
if (arrayAddEvalSuccess != Z3_TRUE) {
|
||||
printf("Failed to evaluate model\n");
|
||||
exit(1);
|
||||
}
|
||||
{
|
||||
int arrayAddValue = 0;
|
||||
Z3_bool getArrayAddValueSuccess =
|
||||
Z3_get_numeral_int(ctx, arrayAddEval, &arrayAddValue);
|
||||
if (getArrayAddValueSuccess != Z3_TRUE) {
|
||||
printf("Failed to get integer value for c[0] + c[1] + c[2]\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("Evaluated c[0] + c[1] + c[2] = %d\n", arrayAddValue);
|
||||
if (arrayAddValue != 7) {
|
||||
printf("c[0] + c[1] + c[2] did not evaluate to expected value\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Z3_ast_vector_dec_ref(ctx, oneArgs);
|
||||
Z3_ast_vector_dec_ref(ctx, zeroArgs);
|
||||
Z3_func_interp_dec_ref(ctx, cAsFuncInterp);
|
||||
Z3_model_dec_ref(ctx, m);
|
||||
Z3_del_context(ctx);
|
||||
}
|
||||
|
||||
/*@}*/
|
||||
/*@}*/
|
||||
|
||||
|
||||
|
||||
int main() {
|
||||
#ifdef LOG_Z3_CALLS
|
||||
Z3_open_log("z3.log");
|
||||
|
@ -2888,5 +3087,6 @@ int main() {
|
|||
substitute_example();
|
||||
substitute_vars_example();
|
||||
fpa_example();
|
||||
mk_model_example();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,16 @@ add_executable(c_maxsat_example maxsat.c)
|
|||
target_include_directories(c_maxsat_example PRIVATE ${Z3_C_INCLUDE_DIRS})
|
||||
target_link_libraries(c_maxsat_example PRIVATE ${Z3_LIBRARIES})
|
||||
|
||||
option(FORCE_CXX_LINKER "Force linker with C++ linker" OFF)
|
||||
if (FORCE_CXX_LINKER)
|
||||
# This is a hack for avoiding UBSan linking errors
|
||||
message(STATUS "Forcing use of C++ linker")
|
||||
set_target_properties(c_maxsat_example
|
||||
PROPERTIES
|
||||
LINKER_LANGUAGE CXX
|
||||
)
|
||||
endif()
|
||||
|
||||
if ("${CMAKE_SYSTEM_NAME}" MATCHES "[Ww]indows")
|
||||
# On Windows we need to copy the Z3 libraries
|
||||
# into the same directory as the executable
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue