how to set timeout for z3_solver using C-API? - z3

I am using Z3_solver for nonlinear real arithmetics. I also want to set a timeout for the solver. I am using the following code but it looks like that the timeout does not work since the solver runs forever. Can anyone help me in finding out the problem?
Z3_solver solver;
cfg = Z3_mk_config();
ctx = Z3_mk_context(cfg);
Z3_symbol logic_symbol = Z3_mk_string_symbol(ctx, "QF_UFNRA");
solver = Z3_mk_solver_for_logic((Z3_context)ctx, logic_symbol);
Z3_solver_inc_ref(ctx, solver);
Z3_params params = Z3_mk_params(ctx);
Z3_params_inc_ref(ctx, params);
Z3_symbol r = Z3_mk_string_symbol(ctx, ":timeout");
Z3_params_set_uint(ctx, params, r, 10);
Z3_solver_set_params(ctx, solver, params);
Z3_params_dec_ref(ctx, params);
Z3_del_config(cfg);
....
Z3_solver_assert(ctx,solver,pred);
Z3_lbool b = Z3_solver_check(ctx, solver);

Are you using Z3 on Linux or FreeBSD? I recently fixed a timer setting problem that affected these two systems (commit: http://z3.codeplex.com/SourceControl/changeset/9674f511b3c1)
The fix is already available in the "work-in-progress" branch. You can retrieve it using
git clone https://git01.codeplex.com/z3 -b unstable
I tested it using the following python script. BTW, if you find problems with the "unstable" branch, please report them.
from z3 import *
a1, a2, t1, t2 = Reals('a1 a2 t1 t2');
s = SolverFor("QF_NRA")
s.add( a1 + a2 == 2,
a1*t1 + a2*t2 == Q(2,3),
a1*t1*t1 + a2*t2*t2 == Q(2,5),
a1*t1*t1*t1 + a2*t2*t2*t2 == Q(2,7) )
# On my machine, I get unknown when I set the timeout to 1ms.
s.set(timeout=1)
print s.check()
EDIT:
Here are instructions on how to build the Z3 unstable branch (aka "working-in-progress" branch):
Assumption: we will put Z3 source code in the directory ~/code, and that we will not perform a system-wide installation.
cd ~
mkdir -p code
cd code
git clone https://git01.codeplex.com/z3 -b unstable
cd z3
python scripts/mk_make.py
cd build
make
BTW, if you have a multi-core machine, you can speed up the compilation step by using
make -j N
instead of
make
where N is the number of cores in your machine.

Related

Creating a simple Rcpp package with dependency with other Rcpp package

I am trying to improve my loop computation speed by using foreach, but there is a simple Rcpp function I defined inside of this loop. I saved the Rcpp function as mproduct.cpp, and I call out the function simply using
sourceCpp("mproduct.cpp")
and the Rcpp function is a simple one, which is to perform matrix product in C++:
// [[Rcpp::depends(RcppArmadillo, RcppEigen)]]
#include <RcppArmadillo.h>
#include <RcppEigen.h>
// [[Rcpp::export]]
SEXP MP(const Eigen::Map<Eigen::MatrixXd> A, Eigen::Map<Eigen::MatrixXd> B){
Eigen::MatrixXd C = A * B;
return Rcpp::wrap(C);
}
So, the function in the Rcpp file is MP, referring to matrix product. I need to perform the following foreach loop (I have simplified the code for illustration):
foreach(j=1:n, .package='Rcpp',.noexport= c("mproduct.cpp"),.combine=rbind)%dopar%{
n=1000000
A<-matrix(rnorm(n,1000,1000))
B<-matrix(rnorm(n,1000,1000))
S<-MP(A,B)
return(S)
}
Since the size of matrix A and B are large, it is why I want to use foreach to alleviate the computational cost.
However, the above code does not work, since it provides me error message:
task 1 failed - "NULL value passed as symbol address"
The reason I added .noexport= c("mproduct.cpp") is to follow some suggestions from people who solved similar issues (Can't run Rcpp function in foreach - "NULL value passed as symbol address"). But somehow this does not solve my issue.
So I tried to install my Rcpp function as a library. I used the following code:
Rcpp.package.skeleton('mp',cpp_files = "<my working directory>")
but it returns me a warning message:
The following packages are referenced using Rcpp::depends attributes however are not listed in the Depends, Imports or LinkingTo fields of the package DESCRIPTION file: RcppArmadillo, RcppEigen
so when I tried to install my package using
install.packages("<my working directory>",repos = NULL,type='source')
I got the warning message:
Error in untar2(tarfile, files, list, exdir, restore_times) :
incomplete block on file
In R CMD INSTALL
Warning in install.packages :
installation of package ‘C:/Users/Lenovo/Documents/mproduct.cpp’ had non-zero exit status
So can someone help me out how to solve 1) using foreach with Rcpp function MP, or 2) install the Rcpp file as a package?
Thank you all very much.
The first step would be making sure that you are optimizing the right thing. For me, this would not be the case as this simple benchmark shows:
set.seed(42)
n <- 1000
A<-matrix(rnorm(n*n), n, n)
B<-matrix(rnorm(n*n), n, n)
MP <- Rcpp::cppFunction("SEXP MP(const Eigen::Map<Eigen::MatrixXd> A, Eigen::Map<Eigen::MatrixXd> B){
Eigen::MatrixXd C = A * B;
return Rcpp::wrap(C);
}", depends = "RcppEigen")
bench::mark(MP(A, B), A %*% B)[1:5]
#> # A tibble: 2 x 5
#> expression min median `itr/sec` mem_alloc
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt>
#> 1 MP(A, B) 277.8ms 278ms 3.60 7.63MB
#> 2 A %*% B 37.4ms 39ms 22.8 7.63MB
So for me the matrix product via %*% is several times faster than the one via RcppEigen. However, I am using Linux with OpenBLAS for matrix operations while you are on Windows, which often means reference BLAS for matrix operations. It might be that RcppEigen is faster on your system. I am not sure how difficult it is for Windows user to get a faster BLAS implementation (https://csgillespie.github.io/efficientR/set-up.html#blas-and-alternative-r-interpreters might contain some pointers), but I would suggest spending some time on investigating this.
Now if you come to the conclusion that you do need RcppEigen or RcppArmadillo in your code and want to put that code into a package, you can do the following. Instead of Rcpp::Rcpp.package.skeleton() use RcppEigen::RcppEigen.package.skeleton() or RcppArmadillo::RcppArmadillo.package.skeleton() to create a starting point for a package based on RcppEigen or RcppArmadillo, respectively.

How to make "at()" function evaluate en expression?

I tried function "at" with some function inside it and then give the output to some variable. Maxima successfully differentiated the expression, but then "at" fails and the output is "at( --some successfully done function--, z=l)=0". I need "at" to work properly, to give the result to a variable.
(%i34) a: 45*z^2*l-1; /*expression*/
eq1: at(diff(a, z, 1), z = l)=0; /*giving the meaning of the operations to eq1*/
at(diff(a, z, 1), z = l)=0; /*trying the same without giving the result to a variable*/
ev(eq1, eval); /*trying ev*/
(a) l*z^2* 45-1
(eq1)  at(2*l*z* 45,z=l)=0
(%o34) 2*l^2* 45=0
(%o35)  at(2*l*z* 45,z=l)=0
So when I don't give the result of at to other variables, it's fine but when I try to - it fails even with additional evaluation. How does that work? And also this was tried on Linux. On Windows I don't have the same problem.
I get the following output. Isn't %o3 what you are looking for?
(%i2) a: 45*z^2*l-1;
2
(%o2) 45 l z - 1
(%i3) eq1: at(diff(a, z, 1), z = l)=0;
2
(%o3) 90 l = 0
I am working w/ Maxima 5.42.2 on MacOS. What does build_info(); report on your Linux system? Some Linux distributions package an ancient version of Maxima; maybe you can get a newer version. It is actually pretty easy to build Maxima from a source tarball on a Linux system; I can help if you want to go down that road.

Save and reload z3py solver constraints

Can I save the constraints I created for a z3 solver and later reload them to continue looking for more solutions?
I have learned there is the SMT-LIB2 format for such things and that z3 and z3py have an API for saving and loading in that format. Unfortunately I cannot make it work.
Here's my example program which pointlessly saves and reloads:
import z3
filename = 'z3test.smt'
# Make a solver with some arbitrary useless constraint
solver = z3.Solver()
solver.add(True)
# Save to file
smt2 = solver.sexpr()
with open(filename, mode='w', encoding='ascii') as f: # overwrite
f.write(smt2)
f.close()
# Load from file
solver.reset()
solver.from_file(filename)
It fails with:
Exception has occurred: ctypes.ArgumentError
argument 3: <class 'TypeError'>: wrong type
File "C:\Users\Marian Aldenhövel\Desktop\FridgeIQ\z3\z3-4.8.4.d6df51951f4c-x64-win\bin\python\z3\z3core.py", line 3449, in Z3_solver_from_file
_elems.f(a0, a1, _to_ascii(a2))
File "C:\Users\Marian Aldenhövel\Desktop\FridgeIQ\z3\z3-4.8.4.d6df51951f4c-x64-win\bin\python\z3\z3.py", line 6670, in from_file
_handle_parse_error(e, self.ctx)
File "C:\Users\Marian Aldenhövel\Desktop\FridgeIQ\src\z3test.py", line 17, in <module>
solver.from_file(filename)
Is this a problem with my understanding or my code? Can it be done like this? Are sexpr() and from_file() the right pair of API calls?
I am using z3 and z3py 4.8.4 from https://github.com/z3prover/z3/releases on Windows 10 64bit.
More detail if required:
I am playing with z3 in Python to find solutions for a large disection-puzzle.
To find all solutions I am calling solver.check(). When it returns a sat verdict I interpret the model as image of my puzzle solution. I then add a blocking clause ruling out that specific solution and call solver.check() again.
This works fine and I am delighted.
The runtime to find all solutions will be on the order of many days or until I get bored. I am concerned that my machine will not be running continuously for that long. It may crash, run out of power, or be rebooted for other reasons.
I can easily recreate the initial constraints which is the whole point of the program. But the blocking clauses are a runtime product and a function of how far we have gotten.
I thought I could save the state of the solver and if at runtime I find such a file restart by loading that with the blocking clauses intact and go on finding more solutions instead of having to start over.
Thank you for taking your time reading and thinking.
Marian
With z3 4.4.1 and z3 4.8.5, I would dump (and reload) the constraints in smt2 format as follows:
import z3
filename = "z3test.smt2"
x1 = z3.Real("x1")
x2 = z3.Real("x2")
solver = z3.Solver()
solver.add(x1 != x2)
#
# STORE
#
with open(filename, mode='w') as f:
f.write(solver.to_smt2())
#
# RELOAD
#
solver.reset()
constraints = z3.parse_smt2_file(filename, sorts={}, decls={})
solver.add(constraints)
print(solver)
output:
~$ python t.py
[And(x1 != x2, True)]
file z3test.smt2:
(set-info :status unknown)
(declare-fun x2 () Real)
(declare-fun x1 () Real)
(assert
(and (distinct x1 x2) true))
(check-sat)
I have no idea whether the API changed in the version you are using. Feedback is welcome.

How to implement multi-user safe Linear Congruential Generator in Redis?

I use Linear Congruential Generators (http://en.wikipedia.org/wiki/Linear_congruential_generator) to generate IDs exposed to users.
nextID = (a * LastID + c) % m
Now I want to implement LCGs in Redis. Here's the problem:
Getting the current ID and generating the next ID outside Redis is not multi-user safe. Redis has 2 commands which can be used for simple counters: INCRBY and INCRBYFLOAT, but unfortunately Redis doesn't support modulo operation natively. At the moment the only way I see is using EVAL command and writing some lua script.
UPDATE1:
Some lua analog of
INCRBY LCG_Value ((LCG_Value*a+c)%m)-LCG_Value
seems to be a neat way to achieve this.
A server-side Lua script is probably the easiest and more efficient way to do it.
Now it can also be done using Redis primitive operations using a multi/exec block. Here it is in pseudo-code:
while not successful:
WATCH LCG_Value
$LastID = GET LCG_value
$NextID = (a*$LastID+c)%m
MULTI
SET LCG_value $NextID
EXEC
Of course, it is less efficient than the following Lua script:
# Set the initial value
SET LCG_value 1
# Execute Lua script with on LCG_value with a, c, and m parameters
EVAL "local last = tonumber(redis.call( 'GET', KEYS[1]));
local ret = (last*ARGV[1] + ARGV[2])%ARGV[3];
redis.call('SET',KEYS[1], ret);
return ret;
" 1 LCG_value 1103515245 12345 2147483648
Note: the whole script execution is atomic. See the EVAL documentation.

Z3 C API Changing Timeout at Runtime

Is it possible to change the timeout value of the solver at runtime using C API?
In order to set the timeout the following can be done -
Z3_config cfg = Z3_mk_config();
Z3_set_param_value(cfg, "SOFT_TIMEOUT", "10000") // set timeout to 10 seconds
Z3_context ctx = Z3_mk_context(cfg);
....
Z3_check_and_get_model(ctx);
....
....
Z3_check_and_get_model(ctx);
However, suppose we want to change the timeout for next query while retaining the context, is it possible to change the timeout value in between?
Consider moving to Z3 4.0. Z3 4.0 has new API that allows the user to create many solvers in the same Z3_context. You can set different timeouts for each solver, and update them whenever you want. Z3 4.0 also comes with a C++ layer that makes the C API much more convenient to use.
Here is an short example that sets a timeout. On my machine, Z3 will return unknown when the 1 millisecond timeout is used, and sat when the s.set(p) command is removed.
context c;
expr x = c.real_const("x");
expr y = c.real_const("y");
solver s(c);
s.add(x >= 1);
s.add(y < x + 3);
params p(c);
p.set(":timeout", static_cast<unsigned>(1)); // in milliseconds
s.set(p);
std::cout << s.check() << std::endl;

Resources