Hey there! I'm trying to play around with this crate on Windows, and z3-sys is failing to build when I try to do a static build. I'm super new to this and I don't really understand the build errors. Does anyone have any idea what I can do to get this working?
Error output
error: failed to run custom build command for `z3-sys v0.6.2`
Caused by:
process didn't exit successfully: C:\Users\zkat\src\orogene\target\release\build\z3-sys-6bf7b8d11a33477d\build-script-build
(exit code: 101)
--- stdout
running: "cmake" "C:\Users\zkat\.cargo\registry\src\github.com-1ecc6299db9ec823\z3-sys-0.6.2\z3" "-G" "Visual Studio 16 2019" "-Thost=x64" "-Ax64" "-DZ3_BUILD_LIBZ3_SHARED=false" "-DZ3_BUILD_EXECUTABLE=false" "-DZ3_BUILD_TEST_EXECUTABLES=false" "-DCMAKE_INSTALL_PREFIX=C:\Users\zkat\src\orogene\target\release\build\z3-sys-efa3561d0d5a5b66\out" "-DCMAKE_C_FLAGS= -nologo -MT -Brepro" "-DCMAKE_C_FLAGS_RELEASE= -nologo -MT -Brepro" "-DCMAKE_CXX_FLAGS= -DWIN32 -D_WINDOWS -nologo -MT -Brepro" "-DCMAKE_CXX_FLAGS_RELEASE= -DWIN32 -D_WINDOWS -nologo -MT -Brepro" "-DCMAKE_ASM_FLAGS= -nologo -MT -Brepro" "-DCMAKE_ASM_FLAGS_RELEASE= -nologo -MT -Brepro" "-DCMAKE_BUILD_TYPE=Release"
-- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.19041.
-- The CXX compiler identification is MSVC 19.25.28614.0
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Tools/MSVC/14.25.28610/bin/Hostx64/x64/cl.exe
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Tools/MSVC/14.25.28610/bin/Hostx64/x64/cl.exe - works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Z3 version 4.8.8.0
-- Failed to find git directory.
-- CMake generator: Visual Studio 16 2019
-- Available configurations: Debug;Release;MinSizeRel;RelWithDebInfo
-- Found PythonInterp: C:/Program Files/WindowsApps/PythonSoftwareFoundation.Python.3.8_3.8.752.0_x64__qbz5n2kfra8p0/python3.8.exe
-- PYTHON_EXECUTABLE: C:/Program Files/WindowsApps/PythonSoftwareFoundation.Python.3.8_3.8.752.0_x64__qbz5n2kfra8p0/python3.8.exe
-- Detected target architecture: x86_64
-- Platform: Windows
-- Not using libgmp
-- Not using Z3_API_LOG_SYNC
-- Thread-safe build
-- Performing Test HAS_SSE2
-- Performing Test HAS_SSE2 - Failed
-- Looking for C++ include pthread.h
-- Looking for C++ include pthread.h - not found
-- Found Threads: TRUE
-- Performing Test HAS__W3
-- Performing Test HAS__W3 - Success
-- C++ compiler supports /W3
-- Treating only serious compiler warnings as errors
-- LTO disabled
-- Performing Test HAS_MSVC_NO_OMIT_FRAME_POINTER
-- Performing Test HAS_MSVC_NO_OMIT_FRAME_POINTER - Success
-- Performing Test HAS__Gd
-- Performing Test HAS__Gd - Success
-- C++ compiler supports /Gd
-- Performing Test HAS__EHsc
-- Performing Test HAS__EHsc - Success
-- C++ compiler supports /EHsc
-- CMAKE_CXX_FLAGS: " -DWIN32 -D_WINDOWS -nologo -MT -Brepro"
-- CMAKE_EXE_LINKER_FLAGS: "/machine:x64 /STACK:8388608 /RELEASE"
-- CMAKE_STATIC_LINKER_FLAGS: "/machine:x64"
-- CMAKE_SHARED_LINKER_FLAGS: "/machine:x64 /SUBSYSTEM:WINDOWS /RELEASE"
-- CMAKE_CXX_FLAGS_DEBUG: "/MDd /Zi /Ob0 /Od /RTC1"
-- CMAKE_EXE_LINKER_FLAGS_DEBUG: "/debug /INCREMENTAL:NO /OPT:REF /OPT:ICF /TLBID:1 /NXCOMPAT"
-- CMAKE_SHARED_LINKER_FLAGS_DEBUG: "/debug /INCREMENTAL:NO /OPT:REF /OPT:ICF /TLBID:1"
-- CMAKE_STATIC_LINKER_FLAGS_DEBUG: " /INCREMENTAL:NO"
-- CMAKE_CXX_FLAGS_RELEASE: " -DWIN32 -D_WINDOWS -nologo -MT -Brepro"
-- CMAKE_EXE_LINKER_FLAGS_RELEASE: "/INCREMENTAL:NO"
-- CMAKE_SHARED_LINKER_FLAGS_RELEASE: "/INCREMENTAL:NO"
-- CMAKE_STATIC_LINKER_FLAGS_RELEASE: " /INCREMENTAL:NO"
-- CMAKE_CXX_FLAGS_RELWITHDEBINFO: "/MD /Zi /O2 /Ob1 /DNDEBUG"
-- CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO: "/debug /INCREMENTAL:NO "
-- CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO: "/debug /INCREMENTAL:NO "
-- CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO: " /INCREMENTAL:NO"
-- CMAKE_CXX_FLAGS_MINSIZEREL: "/MD /O1 /Ob1 /DNDEBUG"
-- CMAKE_EXE_LINKER_FLAGS_MINSIZEREL: "/INCREMENTAL:NO /OPT:REF /OPT:ICF /TLBID:1 /NXCOMPAT"
-- CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL: "/INCREMENTAL:NO /OPT:REF /OPT:ICF /TLBID:1"
-- CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL: " /INCREMENTAL:NO"
-- Z3_COMPONENT_CXX_DEFINES: $<$CONFIG:Debug:Z3DEBUG>;$<$CONFIG:Release:_EXTERNAL_RELEASE>;$<$CONFIG:RelWithDebInfo:_EXTERNAL_RELEASE>;-D_WINDOWS;-D_MP_INTERNAL;$<$CONFIG:Debug:_TRACE>;UNICODE;_UNICODE
-- Z3_COMPONENT_CXX_FLAGS: /W3;$<$CONFIG:Debug:/Oy->;$<$CONFIG:MinSizeRel:/Oy->;/Gd;/EHsc
-- Z3_DEPENDENT_LIBS:
-- Z3_COMPONENT_EXTRA_INCLUDE_DIRS: C:/Users/zkat/src/orogene/target/release/build/z3-sys-efa3561d0d5a5b66/out/build/src;C:/Users/zkat/.cargo/registry/src/github.com-1ecc6299db9ec823/z3-sys-0.6.2/z3/src
-- Z3_DEPENDENT_EXTRA_CXX_LINK_FLAGS:
-- CMAKE_INSTALL_LIBDIR: "lib"
-- CMAKE_INSTALL_BINDIR: "bin"
-- CMAKE_INSTALL_INCLUDEDIR: "include"
-- CMAKE_INSTALL_PKGCONFIGDIR: "lib/pkgconfig"
-- CMAKE_INSTALL_Z3_CMAKE_PACKAGE_DIR: "lib/cmake/z3"
-- Adding component util
-- Adding component polynomial
-- Adding rule to generate "algebraic_params.hpp"
-- Adding component dd
-- Adding component hilbert
-- Adding component simplex
-- Adding component automata
-- Adding component interval
-- Adding component realclosure
-- Adding rule to generate "rcf_params.hpp"
-- Adding component subpaving
-- Adding component ast
-- Adding rule to generate "pp_params.hpp"
-- Adding component rewriter
-- Adding rule to generate "arith_rewriter_params.hpp"
-- Adding rule to generate "array_rewriter_params.hpp"
-- Adding rule to generate "bool_rewriter_params.hpp"
-- Adding rule to generate "bv_rewriter_params.hpp"
-- Adding rule to generate "fpa_rewriter_params.hpp"
-- Adding rule to generate "poly_rewriter_params.hpp"
-- Adding rule to generate "rewriter_params.hpp"
-- Adding rule to generate "seq_rewriter_params.hpp"
-- Adding component normal_forms
-- Adding rule to generate "nnf_params.hpp"
-- Adding component model
-- Adding rule to generate "model_evaluator_params.hpp"
-- Adding rule to generate "model_params.hpp"
-- Adding component tactic
-- Adding rule to generate "tactic_params.hpp"
-- Adding component substitution
-- Adding component parser_util
-- Adding rule to generate "parser_params.hpp"
-- Adding component grobner
-- Adding component sat
-- Adding rule to generate "sat_asymm_branch_params.hpp"
-- Adding rule to generate "sat_params.hpp"
-- Adding rule to generate "sat_scc_params.hpp"
-- Adding rule to generate "sat_simplifier_params.hpp"
-- Adding component nlsat
-- Adding rule to generate "nlsat_params.hpp"
-- Adding component lp
-- Adding component core_tactics
-- Adding component subpaving_tactic
-- Adding component aig_tactic
-- Adding component solver
-- Adding rule to generate "combined_solver_params.hpp"
-- Adding rule to generate "parallel_params.hpp"
-- Adding rule to generate "solver_params.hpp"
-- Adding component sat_tactic
-- Adding component arith_tactics
-- Adding component nlsat_tactic
-- Adding component ackermannization
-- Adding rule to generate "ackermannization_params.hpp"
-- Adding rule to generate "ackermannize_bv_tactic_params.hpp"
-- Adding component cmd_context
-- Adding component extra_cmds
-- Adding component smt2parser
-- Adding component proofs
-- Adding component fpa
-- Adding rule to generate "fpa2bv_rewriter_params.hpp"
-- Adding component macros
-- Adding component pattern
-- Adding rule to generate "pattern_inference_params_helper.hpp"
-- Adding component bit_blaster
-- Adding component smt_params
-- Adding rule to generate "smt_params_helper.hpp"
-- Adding component proto_model
-- Adding component smt
-- Adding component bv_tactics
-- Adding component smt_tactic
-- Adding component sls_tactic
-- Adding rule to generate "sls_params.hpp"
-- Adding component qe
-- Adding component muz
-- Adding rule to generate "fp_params.hpp"
-- Adding component dataflow
-- Adding component transforms
-- Adding component rel
-- Adding component clp
-- Adding component tab
-- Adding component bmc
-- Adding component ddnf
-- Adding component spacer
-- Adding component fp
-- Adding component ufbv_tactic
-- Adding component sat_solver
-- Adding component smtlogic_tactics
-- Adding rule to generate "qfufbv_tactic_params.hpp"
-- Adding component fpa_tactics
-- Adding component fd_solver
-- Adding component portfolio
-- Adding component opt
-- Adding rule to generate "opt_params.hpp"
-- Adding component api
-- Adding component api_dll
-- Building documentation disabled
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/zkat/src/orogene/target/release/build/z3-sys-efa3561d0d5a5b66/out/build
running: "cmake" "--build" "." "--target" "install" "--config" "Release" "--"
Microsoft (R) Build Engine version 16.5.0+d4cbfca49 for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.
Checking Build System
Building Custom Rule C:/Users/zkat/.cargo/registry/src/github.com-1ecc6299db9ec823/z3-sys-0.6.2/z3/src/util/CMakeLists.txt
approx_nat.cpp
approx_set.cpp
bit_util.cpp
bit_vector.cpp
cmd_context_types.cpp
common_msgs.cpp
debug.cpp
env_params.cpp
fixed_bit_vector.cpp
gparams.cpp
hash.cpp
hwf.cpp
inf_int_rational.cpp
inf_rational.cpp
inf_s_integer.cpp
lbool.cpp
luby.cpp
memory_manager.cpp
min_cut.cpp
mpbq.cpp
Generating Code...
Compiling...
mpf.cpp
mpff.cpp
mpfx.cpp
mpn.cpp
mpq.cpp
mpq_inf.cpp
mpz.cpp
page.cpp
params.cpp
permutation.cpp
prime_generator.cpp
rational.cpp
region.cpp
rlimit.cpp
scoped_ctrl_c.cpp
scoped_timer.cpp
sexpr.cpp
s_integer.cpp
small_object_allocator.cpp
smt2_util.cpp
Generating Code...
Compiling...
stack.cpp
statistics.cpp
symbol.cpp
timeit.cpp
timeout.cpp
trace.cpp
util.cpp
warning.cpp
z3_exception.cpp
Generating Code...
LINK : warning LNK4044: unrecognized option '/INCREMENTAL:NO'; ignored [C:\Users\zkat\src\orogene\target\release\build\z3-sys-efa3561d0d5a5b66\out\build\src\util\util.vcxproj]
util.vcxproj -> C:\Users\zkat\src\orogene\target\release\build\z3-sys-efa3561d0d5a5b66\out\build\src\util\util.dir\Release\util.lib
Generating "C:/Users/zkat/src/orogene/target/release/build/z3-sys-efa3561d0d5a5b66/out/build/src/math/polynomial/algebraic_params.hpp" from "algebraic_params.pyg"
Access is denied.
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(231,5): error MSB6006: "cmd.exe" exited with code 5. [C:\Users\zkat\src\orogene\target\release\build\z3-sys-efa3561d0d5a5b66\out\build\src\math\polynomial\polynomial.vcxproj]
Building Custom Rule C:/Users/zkat/.cargo/registry/src/github.com-1ecc6299db9ec823/z3-sys-0.6.2/z3/src/math/automata/CMakeLists.txt
automaton.cpp
LINK : warning LNK4044: unrecognized option '/INCREMENTAL:NO'; ignored [C:\Users\zkat\src\orogene\target\release\build\z3-sys-efa3561d0d5a5b66\out\build\src\math\automata\automata.vcxproj]
automata.vcxproj -> C:\Users\zkat\src\orogene\target\release\build\z3-sys-efa3561d0d5a5b66\out\build\src\math\automata\automata.dir\Release\automata.lib
Building Custom Rule C:/Users/zkat/.cargo/registry/src/github.com-1ecc6299db9ec823/z3-sys-0.6.2/z3/src/math/dd/CMakeLists.txt
dd_bdd.cpp
dd_pdd.cpp
Generating Code...
LINK : warning LNK4044: unrecognized option '/INCREMENTAL:NO'; ignored [C:\Users\zkat\src\orogene\target\release\build\z3-sys-efa3561d0d5a5b66\out\build\src\math\dd\dd.vcxproj]
dd.vcxproj -> C:\Users\zkat\src\orogene\target\release\build\z3-sys-efa3561d0d5a5b66\out\build\src\math\dd\dd.dir\Release\dd.lib
Building Custom Rule C:/Users/zkat/.cargo/registry/src/github.com-1ecc6299db9ec823/z3-sys-0.6.2/z3/src/math/simplex/CMakeLists.txt
simplex.cpp
model_based_opt.cpp
bit_matrix.cpp
Generating Code...
LINK : warning LNK4044: unrecognized option '/INCREMENTAL:NO'; ignored [C:\Users\zkat\src\orogene\target\release\build\z3-sys-efa3561d0d5a5b66\out\build\src\math\simplex\simplex.vcxproj]
simplex.vcxproj -> C:\Users\zkat\src\orogene\target\release\build\z3-sys-efa3561d0d5a5b66\out\build\src\math\simplex\simplex.dir\Release\simplex.lib
Building Custom Rule C:/Users/zkat/.cargo/registry/src/github.com-1ecc6299db9ec823/z3-sys-0.6.2/z3/src/math/hilbert/CMakeLists.txt
hilbert_basis.cpp
LINK : warning LNK4044: unrecognized option '/INCREMENTAL:NO'; ignored [C:\Users\zkat\src\orogene\target\release\build\z3-sys-efa3561d0d5a5b66\out\build\src\math\hilbert\hilbert.vcxproj]
hilbert.vcxproj -> C:\Users\zkat\src\orogene\target\release\build\z3-sys-efa3561d0d5a5b66\out\build\src\math\hilbert\hilbert.dir\Release\hilbert.lib
Building Custom Rule C:/Users/zkat/.cargo/registry/src/github.com-1ecc6299db9ec823/z3-sys-0.6.2/z3/src/math/interval/CMakeLists.txt
interval_mpq.cpp
dep_intervals.cpp
Generating Code...
LINK : warning LNK4044: unrecognized option '/INCREMENTAL:NO'; ignored [C:\Users\zkat\src\orogene\target\release\build\z3-sys-efa3561d0d5a5b66\out\build\src\math\interval\interval.vcxproj]
interval.vcxproj -> C:\Users\zkat\src\orogene\target\release\build\z3-sys-efa3561d0d5a5b66\out\build\src\math\interval\interval.dir\Release\interval.lib
Building Custom Rule C:/Users/zkat/.cargo/registry/src/github.com-1ecc6299db9ec823/z3-sys-0.6.2/z3/src/math/subpaving/CMakeLists.txt
subpaving.cpp
subpaving_hwf.cpp
subpaving_mpf.cpp
subpaving_mpff.cpp
subpaving_mpfx.cpp
subpaving_mpq.cpp
Generating Code...
LINK : warning LNK4044: unrecognized option '/INCREMENTAL:NO'; ignored [C:\Users\zkat\src\orogene\target\release\build\z3-sys-efa3561d0d5a5b66\out\build\src\math\subpaving\subpaving.vcxproj]
subpaving.vcxproj -> C:\Users\zkat\src\orogene\target\release\build\z3-sys-efa3561d0d5a5b66\out\build\src\math\subpaving\subpaving.dir\Release\subpaving.lib
Generating "C:/Users/zkat/src/orogene/target/release/build/z3-sys-efa3561d0d5a5b66/out/build/src/math/realclosure/rcf_params.hpp" from "rcf_params.pyg"
Access is denied.
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(231,5): error MSB6006: "cmd.exe" exited with code 5. [C:\Users\zkat\src\orogene\target\release\build\z3-sys-efa3561d0d5a5b66\out\build\src\math\realclosure\realclosure.vcxproj]
--- stderr
CMake Warning at CMakeLists.txt:60 (message):
Disabling Z3_INCLUDE_GIT_DESCRIBE
Call Stack (most recent call first):
CMakeLists.txt:109 (disable_git_describe)
CMake Warning at CMakeLists.txt:64 (message):
Disabling Z3_INCLUDE_GIT_HASH
Call Stack (most recent call first):
CMakeLists.txt:110 (disable_git_hash)
CMake Warning (dev) at cmake/msvc_legacy_quirks.cmake:160 (message):
Skipping legacy linker MSVC options for x86_64 RELEASE
Call Stack (most recent call first):
CMakeLists.txt:429 (include)
This warning is for project developers. Use -Wno-dev to suppress it.
CMake Warning (dev) at cmake/msvc_legacy_quirks.cmake:160 (message):
Skipping legacy linker MSVC options for x86_64 RELWITHDEBINFO
Call Stack (most recent call first):
CMakeLists.txt:429 (include)
This warning is for project developers. Use -Wno-dev to suppress it.
CMake Warning at examples/CMakeLists.txt:24 (message):
Cannot set built type of external project when building with a
multi-configuration generator
CMake Warning:
Manually-specified variables were not used by the project:
CMAKE_ASM_FLAGS
CMAKE_ASM_FLAGS_RELEASE
CMAKE_BUILD_TYPE
CMAKE_C_FLAGS
CMAKE_C_FLAGS_RELEASE
thread 'main' panicked at '
command did not execute successfully, got: exit code: 1
build script failed, must exit now', C:\Users\zkat.cargo\registry\src\github.com-1ecc6299db9ec823\cmake-0.1.44\src\lib.rs:885:5
note: run with RUST_BACKTRACE=1
environment variable to display a backtrace
warning: build failed, waiting for other jobs to finish...
error: build failed
I'm getting an error assertion failed: !ast.is_null()
when running this code:
let cfg = Config::new();
let ctx = &Context::new(&cfg);
let x: ast::Dynamic = ast::Bool::new_const(ctx, "a").into();
let y: ast::Dynamic = ast::String::from_str(ctx, "a").unwrap().into();
x._eq(&y);
How should this be handled?
Currently when calling Solver::get_model()
without Solver::check()
(or Solver::check_assumption
) first or with Solver::check()
returning UnSat
, the process will just print out an error message and then exit, leaving users no room to do any error handling. Are there any workarounds to fix this?
For one workaround I can think of without handling the exception at the boundary of FFI, maybe we can maintain a status in Solver
, like
enum SolverStatus {
UnCheckedOrUnSat,
Checked
}
And Solver::get_model()
would return a Result<Model, [Some Error]>
instead of just letting the process exits.
AST node structs, like ast::Bool and ast::BV, contain reference to the Context. So if I want to store these nodes into my struct, Vec, or something like that, I have to transmute
the nodes into <'static>.
Therefore I think we can just implement some "owned" node structs, without lifetime annotations. Like this one:
pub struct OwnedBV {
pub(crate) ctx: Z3_context,
pub(crate) z3_ast: Z3_ast,
}
And when this struct drops, invoke Z3_dec_ref for both the context and the AST.
If you are ok with that, I'd like to try to implement this feature and make a PR for it. ๐
I have an integer minimization problem that gives different results depending on the order in which assertions are added. If I feed the generated SMT 2.0 code to the standalone z3 executable, the result is always correct.
Repro code: https://github.com/ancorehraq/z3_repro1/blob/master/src/main.rs (sorry it's so big, I tried to minimize it as much as I could)
Output:
...
bad: true, answer: 84
...
bad: false, answer: 51
"z3 -model" with either variant produces:
...
(define-fun used_ORE () Int
51)
...
I'm getting a reference error when I call list_subgoals
. I believe this can be fixed using a Box but it would be nice to have a more straightforward solution.
pub fn apply_result_error<'ctx>() {
let cfg = Config::new();
let ctx = &Context::new(&cfg);
let goal = Goal::new(&ctx, false, false, false);
let simplify = Tactic::repeat(
&ctx,
Tactic::new(ctx, "propogate-values"),
10,
);
let ar = simplify.apply(&goal, None);
let result: Vec<Vec<Goal>> = ar.list_subgoals()
.into_iter()
.map(|subgoal| {
simplify.apply(&subgoal, None)
.list_subgoals()
.collect()
})
.collect();
}
Any ideas?
Currently, calling Bool::pb_eq
(and similarly Bool::pb_lt
and Bool::pb_gt
) looks something like this:
let a = ast::Bool::new_const(&ctx, "a");
let b = ast::Bool::new_const(&ctx, "b");
let c = ast::Bool::new_const(&ctx, "c");
solver.assert(&a.pb_eq( &[&b, &c], vec![1, 2, 3], 3));
I don't like this for a few reasons:
- It makes it look like there is some order or precedence that makes
a
more important than the other Bool
s
- There isn't a clear matching between the booleans and the coefficients: the first coefficient is tied to
a
, but at a glance you would think it would be tied to b
since a
is outside of the list within the function call. Additionally, if you have many weights, it is unclear at a glance which weight applies to which
- It's even less ergonomic when applying to a list:
solver.assert(&bools[0].pb_eq( &bools[1..], vec![1; 10], 10));
I believe a more intuitive function signature would greatly benefit the usability of these functions.
The first change I would propose would be turning these methods into functions by removing the &self
reference. Based on the current implementation, we would need to pass in a context to replace this. This would change the above examples to:
solver.assert(Bool::pb_eq(&ctx, &[&a, &b, &c], vec![1, 2, 3], 3));
solver.assert(Bool::pb_eq(&ctx, &bools[..], vec![1; 10], 10));
Already we see a minor improvement in that we have removed the first problem of apparent arbitrary precedence. There's also much clearer matching between the coefficients and the Bool
s themselves now that the Bool
s are all grouped together too. We could stop here, but I would also like to propose one more change: if we look at the implementations from other languages like Python, we can see that instead of passing through a list of Bool
s and their coefficients separately, they are passed through as a single list of tuples containing both the Bool
and their coefficient. I would propose that this is also adopted into the new function signature for a couple of reasons:
- The coefficients are clearly aligned and matched with their corresponding
Bool
s
- It removes unclear/undefined behaviour that occurs when the list of coefficients and
Bool
s are of differing lengths: currently no error is thrown and I believe it defaults to 0 for missing coefficients and ignores extra ones. This isn't obvious or intuitive in my opinion. By changing the function signature in this way, we can make it so that you can't have extra/missing coefficients, as it would be caught by the compiler. I believe that this will lead to fewer bugs for users of the function.
- It is simple to use the
iter::zip
method to combine a list of Bool
s with a list of coefficients for use with this new function signature.
This would change the examples to:
solver.assert(Bool::pb_eq(&ctx, &[(&a, 1), (&b, 2), (&c, 3)], 3));
let values = bools.zip(iter::repeat(1));
solver.assert(Bool::pb_eq(&ctx, values.as_slice(), 10));
To summarise, I would propose that, for a number of ergonomic reasons, the methods Bool::pb_eq
, Bool::pb_lt
and Bool::pb_gt
be changed to functions with the signature
pub fn pb_xx(context: &Context, values: &[(&Bool, i32)], k: i32) -> Bool
Probe is a class in Z3 used to inspect goals and collect information. This would be a very useful addition.
It would be great if https://docs.rs/z3 had some top-level documentation with full usage examples for the crate, or linked to useful examples elsewhere. As it is, it's a bit intimidating to look at the whole crate without knowing where to start.
The following code works fine:
let cfg = Config::new();
let ctx = Context::new(&cfg);
let int_sort = ctx.int_sort();
let int_set_sort = ctx.set_sort(&int_sort);
let set = ctx.named_const("set", &int_set_sort);
let a = ctx.named_int_const("a");
let result = set.set_add(&a);
However, if you swap the let set...
and let a...
lines (so that a
is defined first), it crashes with SIGSEGV
. Oddly, running in lldb
doesn't crash: it prints Error: type error
and exits with return code 1.
I'm running z3 0.3.1
and z3-sys 0.4.0
.
I'm storing a fixed/known number of binary expressions in an array and solving for the index of an expression that evaluates to a specific result (i.e. pick the operator to "switch" on, given all expressions have the same operands). This works in Python, but I can't seem to translate it to the Rust bindings. Simplified example:
Below works fine in Python (package z3-solver
version 4.8.7.0
), solving for 8 (operator) 3 = 24
I get 2
, the index of operator *
, the correct result:
Python code:
from z3 import *
s = Solver()
result = IntVal(24)
x = IntVal(8)
y = IntVal(3)
A = Array ('A', IntSort(), IntSort())
A = Store(A, 0, x - y)
A = Store(A, 1, x + y)
A = Store(A, 2, x * y)
j = Int('j')
s.add(j >= 0)
s.add(j <= 2)
goal = (Select(A, j) == result)
s.add(goal)
print("Goal: {}".format(goal))
if s.check() == sat:
print("Model: {}".format(s.model()))
else:
print("Not found!")
Python output:
Goal: 24 == Store(Store(Store(A, 0, 8 - 3), 1, 8 + 3), 2, 8*3)[j]
Model: [j = 2]
However, trying to write the equivalent in Rust (crate z3
version 0.4
, Ubuntu libz3-dev
version 4.4.1
), I get 0
, the index of the -
operator, which is incorrect:
extern crate z3;
use z3::ast::Ast;
let config = z3::Config::new();
let ctx = z3::Context::new(&config);
let solver = z3::Solver::new(&ctx);
let result = z3::ast::Int::from_u64(&ctx, 24);
let x = z3::ast::Int::from_u64(&ctx, 8);
let y = z3::ast::Int::from_u64(&ctx, 3);
let A = z3::ast::Array::new_const(&ctx, "A", &z3::Sort::int(&ctx), &z3::Sort::int(&ctx));
A.store(
&z3::ast::Dynamic::from_ast(&z3::ast::Int::from_u64(&ctx, 0)),
&z3::ast::Dynamic::from_ast(&x.sub(&[&y])),
);
A.store(
&z3::ast::Dynamic::from_ast(&z3::ast::Int::from_u64(&ctx, 1)),
&z3::ast::Dynamic::from_ast(&x.add(&[&y])),
);
A.store(
&z3::ast::Dynamic::from_ast(&z3::ast::Int::from_u64(&ctx, 2)),
&z3::ast::Dynamic::from_ast(&x.mul(&[&y])),
);
let j = z3::ast::Int::new_const(&ctx, "j");
solver.assert(&j.ge(&z3::ast::Int::from_u64(&ctx, 0)));
solver.assert(&j.le(&z3::ast::Int::from_u64(&ctx, 2)));
let goal = A
.select(&z3::ast::Dynamic::from_ast(&j))
._eq(&z3::ast::Dynamic::from_ast(&result));
solver.assert(&goal);
println!("Goal: {}", goal);
if solver.check() == z3::SatResult::Sat {
println!("Model: {}", solver.get_model());
} else {
println!("Not found!");
}
Rust output:
Goal: (= (select A j) 24)
Model: A -> (_ as-array k!0)
j -> 0
k!0 -> {
0 -> 24
else -> 24
}
Any idea what might be going wrong here?
Thanks in advance!
(repeating some context from #137)
The issue with taking a reference to Sort
is that a pattern like the following no longer works:
// Translating my own type system into Z3, specifically structs
let my_name: String = ...;
let my_fields: Vec<(String, IrType)> = ...;
let z3_types: HashMap<IrType, DatatypeSort> = ...;
let builder = DatatypeBuilder::new(context, "foo");
let variants = my_fields
.iter()
.map(|(name, field)| {
let z3_ty = match field {
IrType::Bool => DatatypeAccessor::Sort(Sort::bool(context)),
// ... other simple types ...
not_simple_type => {
let z3_ty: &DatatypeSort = z3_types.get(not_simple_type).unwrap();
DatatypeAccessor::Sort(z3_ty.sort.clone())
}
};
(name.as_str(), z3_ty)
})
.collect();
let new_ty: DatatypeSort<'ctx> = builder.variant("foo_variant", variants).finish();
z3_types.insert(my_name, new_ty);
z3_ty
sometimes refers to a sort that lives on the stack, so it can't be returned from the map function. The fix is to make a single sort value outside of the loop (even if the sort will not be used by the variant) so it can be referred to in variants
, but can this be avoided? Switching back to the owned Sort
value and adding a Clone
impl would do this (clone impl was added in #137).
Hi,
I'm generating some assertions, but z3 complains type errors. I wanted to print out the details of the context. For example, print the SMTLib2 format. But z3-rs seems to have no support for any kind of inspection? I'd like to know what to do in this case...
I'm not familiar with z3-rs or z3-c++, so please forgive me if I make any mistakes.
I've been running into issues with the overhead of constructing Python objects of the Python API for Z3. Would z3.rs avoid these problems in the same way that the C API does (see linked discussion or here for a related Stack Overflow post)?
The exported functions from the C API have changed:
+ pub fn Z3_mk_set_has_size(c: Z3_context, set: Z3_ast, k: Z3_ast) -> Z3_ast;
+ pub fn Z3_get_seq_sort_basis(c: Z3_context, s: Z3_sort) -> Z3_sort;
+ pub fn Z3_get_re_sort_basis(c: Z3_context, s: Z3_sort) -> Z3_sort;
+ pub fn Z3_mk_lstring(c: Z3_context, len: ::std::os::raw::c_uint, s: Z3_string) -> Z3_ast;
+ pub fn Z3_get_lstring(
+ pub fn Z3_mk_str_lt(c: Z3_context, prefix: Z3_ast, s: Z3_ast) -> Z3_ast;
+ pub fn Z3_mk_str_le(c: Z3_context, prefix: Z3_ast, s: Z3_ast) -> Z3_ast;
+ pub fn Z3_mk_seq_nth(c: Z3_context, s: Z3_ast, index: Z3_ast) -> Z3_ast;
+ pub fn Z3_mk_seq_last_index(c: Z3_context, arg1: Z3_ast, substr: Z3_ast) -> Z3_ast;
+ pub fn Z3_mk_linear_order(
+ pub fn Z3_mk_partial_order(
+ pub fn Z3_mk_piecewise_linear_order(
+ pub fn Z3_mk_tree_order(c: Z3_context, a: Z3_sort, id: ::std::os::raw::c_uint) -> Z3_func_decl;
+ pub fn Z3_mk_transitive_closure(c: Z3_context, f: Z3_func_decl) -> Z3_func_decl;
- pub fn Z3_get_parser_error(c: Z3_context) -> Z3_string;
- pub fn Z3_apply_result_convert_model(
+ pub fn Z3_solver_get_trail(c: Z3_context, s: Z3_solver) -> Z3_ast_vector;
+ pub fn Z3_solver_get_levels(
+ pub fn Z3_solver_to_dimacs_string(c: Z3_context, s: Z3_solver) -> Z3_string;
- pub fn Z3_fixedpoint_push(c: Z3_context, d: Z3_fixedpoint);
- pub fn Z3_fixedpoint_pop(c: Z3_context, d: Z3_fixedpoint);
+ pub fn Z3_optimize_assert_and_track(c: Z3_context, o: Z3_optimize, a: Z3_ast, t: Z3_ast);
i'm currently working on changing z3-sys to use cxx.rs, would you be open to replacing this if I get the interface to match?
As can be shown from this simple failing test, the Set::del
operation does not work
#[test]
fn test_set() {
let cfg = Config::new();
let ctx = Context::new(&cfg);
let solver = Solver::new(&ctx);
let set = ast::Set::new_const(&ctx, "integer_set", &Sort::int(&ctx));
let one = ast::Int::from_u64(&ctx, 1);
solver.push();
solver.assert(&set._eq(&ast::Set::empty(&ctx, &Sort::int(&ctx))));
solver.push();
solver.assert(&set.member(&one));
// An empty set will never contain 1
assert_eq!(solver.check(), SatResult::Unsat);
solver.pop(1);
solver.push();
let set_with_one = set.add(&one);
// Adding 1 to the empty set means it does now contain 1
solver.assert(&set_with_one.member(&one));
assert_eq!(solver.check(), SatResult::Sat);
let set_without_one = set_with_one.del(&one);
// Removing 1 from the set means it no longer contains 1
solver.assert(&set_without_one.member(&one));
assert_eq!(solver.check(), SatResult::Unsat);
solver.pop(1);
}
I believe this can be fixed simply by changing ast.rs
/// Remove an element from the set.
///
/// Note that the `element` _must be_ of the `Set`'s `eltype` sort.
//
// We avoid the binop! macro because the argument has a non-Self type
pub fn del<A>(&self, element: &A) -> Set<'ctx>
where
A: Ast<'ctx>,
{
Set::new(self.ctx, unsafe {
let guard = Z3_MUTEX.lock().unwrap();
Z3_mk_set_add(self.ctx.z3_ctx, self.z3_ast, element.get_z3_ast())
})
}
to
Z3_mk_set_del(self.ctx.z3_ctx, self.z3_ast, element.get_z3_ast())
I'm currently developing a multi-threaded program, but it seems like almost every function call to the z3 library is mutex-guarded. My threads will frequently create expressions and eval() them, and each thread has its own Context (unsafe impl Send for Context)
I'm wondering if the Z3_MUTEX will slow down my code. If so, is it safe to remove the Z3_MUTEX in my code? Thanks :)
I'm not sure if this is a bug in Z3 or in these bindings, so I'm just filing the issue here to start.
The following minimal example produces a segmentation fault:
use z3::ast::{Ast, BV};
fn main() {
let ctx = z3::Context::new(&z3::Config::new());
let size = BV::from_u64(&ctx, 0, 64).extract(2, 0).get_size();
let x = BV::from_u64(&ctx, 0, 64).extract(2, 0);
}
Removing either the let size
or the let x
lines causes the segfault to go away; it is only present when both lines are there. Likewise, removing either of the extract()
s or the get_size()
also causes the segfault to go away.
Running in rust-lldb
appears to show that the segfault occurs inside Z3 during the call to Z3_del_context()
resulting from Context::drop()
.
Interestingly, adding the line
let x_size = x.get_size();
to the end of the example above produces the strange error Error: sort is not a bit-vector
during the call to Z3_get_bv_sort_size()
. I don't know if that's helpful or not.
System info:
z3
: current master (0a2523b
)
- Z3: 4.8.5 (installed via
brew
)
- Rust: 1.35.0
- OS: macOS 10.14.4
I am trying to write a simple verification backend using z3.rs, I have the statements below.
assertions: (= y (bvmul x #x0000000000000003))
assertions: (= x (bvadd x x))
negated goal: (not (= (bvadd x x) (bvmul x #x0000000000000003)))
So my expectation is that the solver comes up with SAT result, yet I get UNSAT.
I wanted to understand why it does that, so I tried extracting the proof, yet I could not find any useful method that proof uses which I can inspect the process. The code examples are not very useful either, if anyone could post anything allowing me to move forward, I would be grateful.
Any chance you can get this uploaded as a rust crate - I'm a bit concerned about pointing to github in our cargo.toml (outages etc.)
@julian-seward1 could you provide the output of running cargo build -vv --features static-link-z3
from within the z3-sys
directory here? Thanks!
The following code causes a stack overflow:
#[test]
fn mix() {
let cfg = Config::new();
let ctx0 = Context::new(&cfg);
let ctx1 = Context::new(&cfg);
let i0 = ast::Int::fresh_const(&ctx0, "a");
let i1 = ast::Int::fresh_const(&ctx1, "b");
ast::Int::add(&ctx0, &[&i0, &i1]);
}
thread 'mix' has overflowed its stack
The C++/Python/C# bindings check to make sure the contexts are the same before calling the Z3 functions. Rust might be able to get away without runtime checking by encoding this into the type system.
Forgive me, I'm new to Z3. I was experimenting and I wanted to create a program that solves a sorted list of variables from 0 to 100. My code runs and finds the solution, albeit slowly, when compiled in development mode, but Segfaults when compiled in release mode. I figured I'd raise an issue.
Here's my code:
extern crate z3;
use z3::ast;
use z3::*;
fn main() {
let cfg = Config::new();
let ctx = Context::new(&cfg);
let optimizer = Optimize::new(&ctx);
let mut v = Vec::new();
for i in 0..100 {
let c = ast::Int::new_const(&ctx, format!("cell-{}", i));
if i == 0 {
optimizer.assert(&c.gt(&ast::Int::from_i64(&ctx, 0)))
}
optimizer.minimize(&c);
v.push(c);
}
for (i, j) in v.iter().zip(v.iter().skip(1)) {
optimizer.assert(&j.gt(i));
}
assert!(optimizer.check());
let model = optimizer.get_model();
for i in v.iter() {
println!("{}: {}", i, model.eval(i).unwrap().as_i64().unwrap());
}
}
I'm trying to do math with bitvectors, and running into what seems like a missing API: I don't see any way to create a bitvector from an integer or bool array.
For example:
let cfg = Config::new();
let ctx = Context::new(&cfg);
let b = ctx.named_bitvector_const("bv", 4);
let s = Solver::new(&ctx);
s.assert(&b._eq(&ctx.from_u64(1)));
will print the error message
Error: Sorts (_ BitVec 4) and Int are incompatible
My suggested fix is to add pub fn from_u64(ctx: &'ctx Context, u: u64 -> Ast<'ctx>
to the Sort
type, with an implementation that calls Z3_mk_unsigned_int64()
using the given sort. This works for integer, bit-vector, and finite-domain sorts.
Is this something that you'd accept a PR for (or want to implement yourself)?
#![deny(missing_debug_implementations)]
It is quite nice when every type implements Debug
, and this enforces that at the crate level.
In particular, I just found that z3::Solver
doesn't implement Debug
.
This would allow setting a time limit on tactic execution. It should be a pretty simple wrapper around this function in z3-sys: I'll put up a pull request as well!
There is currently no abstraction on Tactic or Goal, which are useful for things like simplification. I started working on implementing them, but wanted to check if there had been some work on this in the past or any blockers for adding them to the library.
The substitute method on AST allows arbitrary rewriting while retaining (now inaccurate) types.
<Int as Ast>::substitute<Int, Real>
could internally rewrite the Ast to be of type Real
, but retain the rust type Int
.
for the function to be safe, we need the more restricted type:
substitute<T>(&self, substitutions: &[(&T, &T)]) -> Self
Or some extra machinery to handle the invalid or retyped ASTs that can be formed by arbitrary substitution.
I have an issue where a constant is evaluated to false when calling Model::eval
, even though the solver says that the constant is true
in the model.
Code
use z3::{Ast, Config, Context, Solver};
fn main() {
let config = Config::new();
let context = Context::new(&config);
let solver = Solver::new(&context);
let b = context.fresh_bool_const("b");
let true_ = Ast::from_bool(&context, true);
let expr = Ast::_eq(&b, &true_);
solver.assert(&expr);
assert!(solver.check());
println!("Solver: {}", solver.to_string());
let model = solver.get_model();
println!("b = {}", model.eval(&b).unwrap().as_bool().unwrap());
}
Expected behavior
After calling solver.check
, solver.to_string
returns:
(declare-fun b!0 () Bool)
(assert (= b!0 true))
(rmodel->model-converter-wrapper
b!0 -> true
)
I have no prior experience with Z3, but I read this as: a solution was found where b!0
is true
. Therefore, I expect model.eval(&b).unwrap().as_bool().unwrap()
to be true
Actual behavior
model.eval(&b).unwrap().as_bool().unwrap()
returns false
Your code expects a z3.lib and z3.dll:
|
#[link(name = "z3")] |
|
extern "C" { |
But building z3 outputs a libz3.lib and libz3.dll.
I checked how debian packs libz3, and they ship a libz3.so, not a z3.so. Why do you try to link against z3 instead of libz3, and on what platforms does that work?
In Cargo.toml I have:
z3 = {version="0.11.1", features = ["static-link-z3"]}
When I build I get the following:
error: failed to run custom build command for `z3-sys v0.7.0`
Caused by:
process didn't exit successfully: `/home/sadmac/coding/biat/target/debug/build/z3-sys-d5ede29e06b013d6/build-script-build` (exit code: 101)
--- stdout
running: "cmake" "/home/sadmac/.cargo/registry/src/github.com-1ecc6299db9ec823/z3-sys-0.7.0/z3" "-DZ3_BUILD_LIBZ3_SHARED=false" "-DZ3_BUILD_EXECUTABLE=false" "-DZ3_BUILD_TEST_EXECUTABLES=false" "-DCMAKE_INSTALL_PREFIX=/home/sadmac/coding/biat/target/debug/build/z3-sys-9c1a1749c10cc82d/out" "-DCMAKE_C_FLAGS= -ffunction-sections -fdata-sections -fPIC -m64" "-DCMAKE_C_COMPILER=/usr/bin/cc" "-DCMAKE_CXX_FLAGS= -ffunction-sections -fdata-sections -fPIC -m64" "-DCMAKE_CXX_COMPILER=/usr/bin/c++" "-DCMAKE_ASM_FLAGS= -ffunction-sections -fdata-sections -fPIC -m64" "-DCMAKE_ASM_COMPILER=/usr/bin/cc" "-DCMAKE_BUILD_TYPE=Debug"
--- stderr
CMake Error: The source directory "/home/sadmac/.cargo/registry/src/github.com-1ecc6299db9ec823/z3-sys-0.7.0/z3" does not exist.
Specify --help for usage, or press the help button on the CMake GUI.
thread 'main' panicked at '
command did not execute successfully, got: exit code: 1
build script failed, must exit now', /home/sadmac/.cargo/registry/src/github.com-1ecc6299db9ec823/cmake-0.1.45/src/lib.rs:894:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
/home/sadmac/.cargo/registry/src/github.com-1ecc6299db9ec823/z3-sys-0.7.0 contains:
build.rs Cargo.toml Cargo.toml.orig LICENSE.txt README.md scripts src tests wrapper.h
To implement the AllDifferent constraint on an ensemble of variables stored in a Vec
, I haven't found better than
s.assert(&vars[0].distinct(&vars[1..].iter().collect::<Vec<&_>>()));
It feels a bit strange to single out the first variable, considering they all play the same role in the constraint. Would it make sense to imagine something like
s.assert(ast::distinct(&vars));
This could probably apply to all of the functions defined by the varop
macro.
I appreciate the changes by @bumblepie in #83. However, there seems to be a crash (not a panic!) with an empty slice as the argument to varops:
#[test]
fn test_zero_args() {
let _ = env_logger::try_init();
let cfg = Config::new();
let ctx = Context::new(&cfg);
let _ = ast::Int::add(&ctx, &[]);
}
Results in
Error: no arguments supplied to arithmetical operator
Most Z3 C API functions require the list of operands to be nonempty.
A slight improvement might be to add an assert!
in the right places to guard against an empty slice so the panic can be caught.
My goal is to parse an AST, converting it to a representation used in another library. For example, if the other representation is of the form:
enum Node {
BoolLiteral(bool),
BoolVar(String),
And(Box<Node>, Box<Node>),
Or(Box<Node>, Box<Node>),
}
I'd like a z3 AST x and (y or true)
to be converted to (dropping boxes/etc)
And(BoolVar("x"), Or(BoolVar("y"), BoolLiteral(true)))
This requires being able to introspect the Ast types at the DeclKind granularity. In the Python/C++ API, they have functions such as Ast::kind() -> AstKind
, Ast::func_decl() -> FuncDecl
, FuncDecl::kind() -> DeclKind
, etc. My initial attempts to mimic those APIs to do this have been partially successful, but ultimately cause errors. The current issue is that my implementation FuncDecl::kind() -> DeclKind
(pasted below) is returning an invalid DeclKind (value 0, while Z3_decl_kind starts at 256), but I suspect the larger issue is that I am bad at C and I am monkey coding.
I'd be very interested in having the path of methods that lead to getting DeclKind
. I'm happy to send out PRs that may or may not work, but it's also possible that you could do this in your sleep and I'd just get in the way :).
Trying to combine Ast
s of different Sort
s often results in errors. For instance, you can't add
an integer and a bitvector, you can only select
on an array, etc. In fact, the Ast
type appears to have a number of distinct groups of methods, only one of which applies to any given Ast
(depending on its Sort
): the first group (add
, sub
, etc) which apply to integers (and maybe reals? Not sure as I never use reals); the second group (bv*
) which apply to bitvectors; select
and store
which apply to arrays; set_*
which apply to sets; and pb_*
(I'm not sure what these are either).
Since each of these groups of methods apply to different kinds of Ast
s, and rarely can different kinds of Ast
s be mixed without errors, I was wondering if any thought has been given to splitting Ast
into a number of subtypes, perhaps IntAst
, BVAst
, ArrayAst
, etc (obviously different names could be used). This would not only clarify exactly which Ast
operations apply to each type, it would also help prevent more errors statically at the Rust type level, thus making a safer set of high-level bindings.
I'm potentially willing to help implement this if it's desired and feasible, but I wanted to ask first if it's a reasonable suggestion, and get feedback from anyone with more experience with Z3 (and Rust) than me. Is there a reason this is a bad idea?
This is on a Debian 9.8, Z3 version 4.8.0 sourced using the package manager.
I have to mention that all other tests run OK if I comment out this one.
cargo test --color=always --no-run --package z3 --test lib test_pb_ops_model -- --exact
Compiling z3 v0.3.2 (/home/radu/0/projects/z3.rs/z3)
error: linking with `cc` failed: exit code: 1
|
= note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" "/home/radu/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.13dd3x295s8awfnw.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.19h6al6q14nvbfhb.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.1e9ot4xe6ilycje7.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.1pe8ip2a3dkr9sg9.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.1vc0xcsmhriab9df.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.1x1upuwbbt1zt99i.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.22p9fku1c9ek87o0.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.2432gt1jvesuh1vn.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.25o8adpxo2l52xeb.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.2acaigx4s0pjjcay.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.2k1dphs3573goxiu.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.2qk2gtem7q6y93i.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.2yvxyen20jhjmv2v.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.378i3vldmty6ledi.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.38pve3dupc8d2m8k.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.3ap9ddu6dxj22d40.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.3bxi37my4d1hepd8.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.3yedymlhbje2btu6.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.446qj83m3fpnn5sv.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.44b8xuojtmkc6wgs.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.4qufu8bkus73ftbn.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.4xccnx30stzz2l61.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.54uc5dpf4cspkl90.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.56he1twsapa0h32t.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.5glp2c7p9pdsqqvy.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.8cvmjeezs5a1rpn.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.emf72d8cocn5j5w.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.ikb7v8zgbakqyd9.rcgu.o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.usb4jfgo0nz3fyp.rcgu.o" "-o" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869" "/home/radu/0/projects/z3.rs/target/debug/deps/lib-698daf5a4a769869.34uw3afms39hceq4.rcgu.o" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro" "-Wl,-znow" "-nodefaultlibs" "-L" "/home/radu/0/projects/z3.rs/target/debug/deps" "-L" "/home/radu/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "/home/radu/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libtest-c3a0bad6f0180507.rlib" "/home/radu/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libterm-6540918622214377.rlib" "/home/radu/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libgetopts-50a203aae2e8a340.rlib" "/home/radu/0/projects/z3.rs/target/debug/deps/libz3-0952be98c4f45fce.rlib" "/home/radu/0/projects/z3.rs/target/debug/deps/libz3_sys-990f253237416b9c.rlib" "/home/radu/0/projects/z3.rs/target/debug/deps/libenv_logger-c117e4fd8606a2d6.rlib" "/home/radu/0/projects/z3.rs/target/debug/deps/libregex-c5e017f500ea85d7.rlib" "/home/radu/0/projects/z3.rs/target/debug/deps/libutf8_ranges-0918e619d385a370.rlib" "/home/radu/0/projects/z3.rs/target/debug/deps/libregex_syntax-f948a5a4f3a9565a.rlib" "/home/radu/0/projects/z3.rs/target/debug/deps/libucd_util-c7796064d62c625f.rlib" "/home/radu/0/projects/z3.rs/target/debug/deps/libthread_local-490b6783e7f5080a.rlib" "/home/radu/0/projects/z3.rs/target/debug/deps/liblazy_static-afc97fc38871e70e.rlib" "/home/radu/0/projects/z3.rs/target/debug/deps/libaho_corasick-27e3cb3682fb766a.rlib" "/home/radu/0/projects/z3.rs/target/debug/deps/libmemchr-3e1032aa5c7637ed.rlib" "/home/radu/0/projects/z3.rs/target/debug/deps/libatty-8d1d4b29dfd3e4e7.rlib" "/home/radu/0/projects/z3.rs/target/debug/deps/liblibc-49802dcd396439e8.rlib" "/home/radu/0/projects/z3.rs/target/debug/deps/libhumantime-90cdc19170c7d43f.rlib" "/home/radu/0/projects/z3.rs/target/debug/deps/libquick_error-7922e5169f66e962.rlib" "/home/radu/0/projects/z3.rs/target/debug/deps/libtermcolor-1c9ff6d92ed1f224.rlib" "/home/radu/0/projects/z3.rs/target/debug/deps/liblog-86bd3d03706a8200.rlib" "/home/radu/0/projects/z3.rs/target/debug/deps/libcfg_if-1e34a1283119a981.rlib" "-Wl,--start-group" "/home/radu/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-e39317eb74365d3c.rlib" "/home/radu/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-4d55a38564aae54a.rlib" "/home/radu/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libbacktrace_sys-f8521075e248b627.rlib" "/home/radu/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-7c91ffdc8da860d3.rlib" "/home/radu/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_demangle-0ad27b9879d551d3.rlib" "/home/radu/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-588f18eae3ea58be.rlib" "/home/radu/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-4ebf5caee903d98f.rlib" "/home/radu/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_core-8895b32baedb08c6.rlib" "/home/radu/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-6a9d233d01acc350.rlib" "-Wl,--end-group" "/home/radu/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-851bb3b5f6c4db49.rlib" "-Wl,-Bdynamic" "-lz3" "-lutil" "-lutil" "-ldl" "-lrt" "-lpthread" "-lgcc_s" "-lc" "-lm" "-lrt" "-lpthread" "-lutil" "-lutil"
= note: /home/radu/0/projects/z3.rs/target/debug/deps/libz3-0952be98c4f45fce.rlib(z3-0952be98c4f45fce.363hus1v0nu3dsvj.rcgu.o): In function `z3::ast::<impl z3::Ast<'ctx>>::pb_eq':
/home/radu/0/projects/z3.rs/z3/src/ast.rs:306: undefined reference to `Z3_mk_pbeq'
collect2: error: ld returned 1 exit status
error: aborting due to previous error
error: Could not compile `z3`.
We're trying to port a Python lib that uses the Python Z3 bindings to Rust. One functionality gap we came across is the ability to traverse the Ast by accessing a node's children. In python, there are functions for children
, num_args
, and arg
. I'd be very interested in those in z3.rs!
I've opened an RFC PR #105. Some reasons for caution:
- I don't really understand the Z3 C API and the right memory model to make sure my
unsafe
blocks are actually safe.
- I chose the more intuitive names of
num_children
and nth_child
rather than num_args
and arg
, but maybe it's better to keep the APIs similar?
- I've just done a few basic tests. I'm happy to do more, if you think I'm going in the right direction.
And thanks for making this crate, btw! It's very helpful to us.
May I suggest adding an high lvl api for floating point numbers? I am currently writing a compiler for a DSL whose static analysis heavily relies on making floating point assertions. I was considering just writing my own abstraction but I guess it makes more sense to just add it upstream.
Is there any interest in me writing this abstraction or would some already involved be willing to write it ( I do not have much experience with this project but from looking at sources I guess I should manage)?
Recommend Projects
-
-
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
An Open Source Machine Learning Framework for Everyone
-
The Web framework for perfectionists with deadlines.
-
A PHP framework for web artisans
-
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
Some thing interesting about web. New door for the world.
-
A server is a program made to process requests and deliver data to clients.
-
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Some thing interesting about visualization, use data art
-
Some thing interesting about game, make everyone happy.
-
Recommend Org
-
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Open source projects and samples from Microsoft.
-
Google โค๏ธ Open Source for everyone.
-
Alibaba Open Source for everyone
-
Data-Driven Documents codes.
-
China tencent open source team.
-
Jobs
Jooble