I've been using Z3 with the JAVA bindings for 2 years now.
For some reason, I've always generated the SMTLib2 code myself as a String and then used the parseSMTLib2String
to build the corresponding Z3 Expr.
As far as I can remember, every time I entered the exact same input twice with this method, I always got the same model.
But I recently decided to change and to use the JAVA API directly and build the expressions with ctx.mk...()
. Basically, I'm not generating the String and then parse it, but I let Z3 do the job of building the Z3 Expr.
What happens now is that I get different models while I've checked that the solver does indeed store the exact same code. My JAVA code looks something like this:
static final Context context = new Context();
static final Solver solver = context.mkSolver();
public static void someFunction(){
solver.add(context.mk...()); // Add some bool expr to the solver
Status status = solver.check();
if(status == SATISFIABLE){
System.out.println(solver.getModel()); // Prints different model with same expr
}
}
I'm making more than 1 call to "someFunction()" during runtime, and the checked expression context.mk...()
changes. But if I run my program twice, the same sequence of expression is checked and sometimes give me different models from one run to another.
I've tried disabling the auto-config parameter and setting my own random seed, but Z3 still produces different models sometimes. I'm only using bounded Integer variables and uninterpreted functions. Am I using the API in the wrong way?
I could add the whole SMTLib2 code to this question if needed but it isn't really short and contains multiple solver calls (I don't even know which of them will produce a different model from one execution to another, I just know that some do).
I must precise that I've read the following threads but found the answers to be either outdated or (if I understood correctly) in favour of "Z3 is deterministic and should produce the same model for the same input":
different run time for the same code in Z3
Edit: Surprisingly enough, with the following code I seem to always get the same models and Z3 now seems deterministic. However, the memory consumption is huge compared to my previous code since I need to keep the context in memory for a while. Any idea what I could do to achieve the same behaviour with less memory use ?
public static void someFunction(){
Context context = new Context();
Solver solver = context.mkSolver();
solver.add(context.mk...()); // Add some bool expr to the solver
Status status = solver.check();
if(status == SATISFIABLE){
System.out.println(solver.getModel()); // Seem to always print the same model :-)
}
}
Here is the memory consumption I get from calling the method "someFunction" multiple times: