Z3 4.0: get complete model - z3

I need a complete model of an SMTLIB2 formula:
http://pastebin.com/KiwFJTrK
Z3 (version 3.2 and 4.0) returns values for all variables but not for var4. I tried some configuration settings like
MODEL_COMPLETION = true
but it did not seem to work. Does anybody have a suggestion? CVC3 in comparison returns a model (including var4), so it is not an issue of SMTLIB or my example.
The reason I need this is explained here in detail. In short: I want to use the C API for incremental solving. For this reason I have to use the function Z3_parse_smtlib2_string multiple times. This function needs previously declared functions and constants as parameters. I am unable to get this information via Z3_get_smtlib_decl because these kind of functions work just when z3_parse_smtlib_string is called, not Z3_parse_smtlib2_string.

You can avoid this problem by adding the following option in the beginning of your script.
(set-option :auto-config false)
I will fix it for the next release.
Here is a short explanation of what is going on.
Z3 has a solver for 0-1 integer problems. After preprocessing, your script is tagged as a 0-1 integer problem by Z3. The value of var4 is a "don't care" when the problem is viewed as a 0-1 problem, but it is not a "don't care" when the problem is viewed as an integer problem (var4 must be 0 or 1). By default, Z3 will not display the value of "don't care" variables.
The MODEL_COMPLETION=true will complete the model as you request values for constants that are not included in the model. For example, if we execute (eval var4), Z3 will produce an interepretation for var4.

Related

SAT queries are slowing down in Z3-Python: what about incremental SAT?

In Z3 (Python) my SAT queries inside a loop are slowing down, can I use incremental SAT to overcome this problem?
The problem is the following: I am performing a concrete SAT search inside a loop. On each iteration, I get a model (of course, I store the negation of the model in order not to explore the same model again). And also, if that model satisfies a certain property, then I also add a subquery of it and add other restrictions to the formula. And iterate again, until UNSAT (i.e. "no more models") is obtained.
I offer an orientative snapshot of the code:
...
s = Solver()
s.add(True)
while s.check() == sat:
s.check()
m = s.model()
phi = add_modelNegation(m)
s.add(phi) #in order not to explore the same model again
if holds_property(m): #if the model holds a property
s = add_moreConstraints(s,m) #add other constrains to the formula
...
The question is that, as the formula that s has to solve gets greater, Z3 is starting to have more trouble to find those models. That is okay: this should happen, since finding a model is now more difficult because of the added restrictions. However, in my case, it is happening too much: the computation speed has been even halved; i.e. the time that the solver needs to find a new model is the double after some iterations.
Thus, I would like to implement some kind of incremental solving and wondered whether there are native methods in Z3 to do so.
I have been reading about this in many pages (see, for instance, How incremental solving works in Z3?), but only found this response in How to use incremental solving with z3py interesting:
The Python API is automatically "incremental". This simply means the ability to call the command check() multiple times, without the solver forgetting what it has seen before (i.e., call check(), assert more facts, call check() again; the second check() will take into account all the assertions from the very beginning).
I am not sure I understand, thus I make a simple question: that the response mean that the incremental SAT is indeed used in Z3's SAT? The point I think I am looking for another incrementality; for example: if in the SAT iteration number 230 it is inevitable that a variable (say b1) is true, then that is a fact that will not change afterwards, you can set it to 1, simplify the formula and not re-reason anything to do with b1, because all models if any will have b1. Is this incremental SAT of Z3 considering these kind of cases?
In case not, how could I implement this?
I know there are some implementations in PySat or in MiniSat, but I would like to do it in Z3.
As with anything related to performance of z3 solving, there's no one size fits all. Each specific problem can benefit from different ideas.
Incremental Solving The term "incremental solving" has a very specific meaning in the SAT/SMT context. It means that you can continue to add assertions to the system after a call to check, without it forgetting the assertions you added before hand. This is what makes it incremental. Additionally, you can set jump-points; i.e., you can tell the solver to "forget" the assertions you put in after a certain point in your program, essentially moving through a stack of assertions. For details, see Section 3.9 of https://smtlib.cs.uiowa.edu/papers/smt-lib-reference-v2.6-r2021-05-12.pdf, specifically the part where it talks about the "Assertion Stack."
And, as noted before, you don't have to do anything specific for z3 to be incremental. It is incremental by default, i.e., you can simply add new assertions after calling check, or use push/pop calls etc. (Compare this to, for instance, CVC4; which is by default not incremental. If you want to use CVC4 in incremental mode, you have to pass a specific command line argument.) The main reason for this is that incremental mode requires extra bookkeeping, which CVC4 isn't willing to pay for unless you explicitly ask it to do so. For z3, the developers decided to always make it incremental without any command line switches.
Regarding your particular question about what happens if b1 is true: Well, if you somehow determined b1 is always true, simply assert it. And the solver will automatically take advantage of this; nothing special needs to be done. Note that z3 learns a ton of lemmas as it works through your program such as these and adds them to its internal database anyhow. But if you have some external mechanism that lets you deduce a particular constraint, just go ahead and add it. (Of course, the soundness of this will be on you, not on z3; but that's a different question.)
One specific "trick" in speeding up enumerating "find me all-solutions" loops like you are doing is to do a divide-and-conquer approach, instead of the "add the negation of the previous model and iterate." In practice this can make a significant difference in performance. I think you should try this idea. It's explained here: https://theory.stanford.edu/~nikolaj/programmingz3.html#sec-blocking-evaluations As you can see, the all_smt function defined at the end of that section takes specific advantage of incrementality (note the calls to push/pop) to speed up the model-search process, by carefully dividing the search space into disjoint segments, instead of doing a random-walk. Using this might give you the speed-up you need. But, again, as with anything performance specific, you'll need to tell us more about exactly what problem you are solving: None of these methods can avoid performance problems caused by modeling issues. (For instance, using integers to model booleans is one common pitfall.) See this answer for some generic advice: https://stackoverflow.com/a/57661441/936310

Display all values from Z3 model (Python)

When I want to get the values of all variables in an SMT2 instance, I use the command (set-option :auto-config false). In Z3py, setting this option doesn't work - the model doesn't display variables that I define but do not use in any constraints. If I ask for the values of these variables, I get None. I have tried these options but none of them produce the result that I want:
set_option('model_evaluator.completion', True)
set_option('smt.auto-config', False)
set_option('auto-config', False)
What should I do to get concrete values for these variables?
The auto-config option does not tell Z3 to print or omit parts of models; it just enables or disables automatic configuration of the solver (based on static formula features).
When a variable is not assigned a value in a model, it is simply irrelevant, i.e., you can make up any value for it, and it will still be a correct model. Depending on which solvers/tactics you use, the option model_evaluator.completion may solve that problem, but the safest way is to enable model completion at the time of model evaluation, i.e., use the eval(..) function with model_completion=True

Using Z3 to return model with least value

I thought I read somewhere that Z3 has some option for returning the model with the "least" value eg given something like
x >= 2
Z3 would return 2. I could swear that I saw some reference to this recently, but I am unable to find it now. Can anyone confirm this?
No, Z3 does not produce 'least' models. However, a separate branch of Z3 that adds optimization features is being developed at the moment (the branch is called `opt'), and perhaps will later be integrated into Z3 proper. A tutorial for the current optimization features is available here: Z3Opt Guide

Z3 4.3: get complete model

This question is pretty much the same than this one, but the solution is not working for me. Sorry, I would like to comment on that answer instead of asking a new question, but I don't have enough reputation...
I'm modeling a simple state machine for an elevator. There are two floors and two buttons Up and Down. I've modeled a transition as a predicate Action x Elevator x Elevator (Elevator = State), such that T(a,s,s') holds iff the action a may cause the transition from s to s', where an action is pushing either the Up or the Down button. The satisfiability of the problem does not depend on the person who pushes a button, but I would like Z3 to assign some interpretation to the function subject : Action -> Person.
The goal is to find a k-trace for the state machine that may help understanding the behavior of the elevator.
I've tried different combinations of options, including auto-config=false and model-completion=true, with no success. I've also tried to force model completion asking for the value of (subject Action0), but Z3 still does not assign an interpretation to subject.
My Z3 version is 4.3.1 running on Linux amd64.
The problem with parameter :model-completion has been fixed. The fix is already available at http://z3.codeplex.com/SourceControl/changeset/a895506dac75.
The fix will be available in the next official release.
If you want you can download the unstable (work-in-progress) branch, and compile it. To download, you just have to clink the Download button in the link above.
BTW, the new Z3 has a new parameter setting framework that allows us to set internal module parameters. In the next release (and in the unstable branch). We have to use
(set-option :model_evaluator.completion true)
instead of
(set-option :model_completion true)
because we are setting a parameter of the module model_evaluator.
Moreover, we have to use
(eval <term> :completion true)
instead of
(eval <term> :model_completion true)
because we are setting the parameter completion of the model evaluator.
Good example.
The abstract sort Person does not appear in the assertions,
and the function that returns a Person is also not used in the
assertions.
You can force eval to complete the model by passing the parameter directly to the function:
http://rise4fun.com/Z3/Pslt4
In other words, use
(eval <term> :model-completion true)
instead of
(eval <term>)
A different, but hacky, way is to make sure that the terms you want to evaluate are included in the original model: http://rise4fun.com/Z3/Yukv

The "pull-nested-quantifiers" option seems to cause problems in the context for UFBV?

I am currently experimenting with Z3 as bounded engine for specifications written in Alloy (a relational logic/language). I am using the UFBV as target language.
I detect a problem using the Z3 option (set-option :pull-nested-quantifiers true).
For two semantically identical SMT specifications Spec1 and Spec2, Z3 times out (200 sec) for proving Spec1 but proves Spec2.
The only different between Spec1 and Spec2 is that they have different function identifiers (because I use java hash names). Can this be related to a bug?
The second observation I would like to share and discuss, is the "iff" operator in the context of UFBV. This operator is not supported, if (set-logic UFBV) is set. My solution was to use "=" instead but this do not work well if the operands contains deeply nested quantifiers and the "pull-nested-quantifiers" is set. The other saver solution is to use double implication.
Now the question:
Is there any other better solution for model "iff" in UFBV, because I think, that using double implication will in general loose maybe useable semantic information for improvement/simplifications.
http://i12www.ira.uka.de/~elghazi/tmp/
you can find: spec1 and spec2 the tow (I think) semantically identical SMT specifications, and spec3 an SMT specification using "=" to model "iff", for which z3 times out.
The default strategy for the UFBV logic is not effective for your problems. Actually, the default strategy solves all of them in less than 1 sec. To force Z3 to use the default strategy, you just need to comment the following lines in your script.
; (set-logic UFBV)
; (set-option :pull-nested-quantifiers true)
; (set-option :macro-finder true)
If the warning messages are bothering you, you can add:
(set-option :print-warning false)
That being said, I will try to address the issues you raised.
Does identifier names affect the behavior of Z3? Yes, they do.
Starting at version 3.0, we started using a total order on Z3 expressions for performing operations such as: sorting the arguments of associative-commutative operators.
This total order is based on the identifier names.
Ironically, this modification was motivated by user feedback. In previous versions, we used an internal ID for performing operations such as sorting, and breaking ties in many different heuristics. However, these IDs are based on the order Z3 creates/deletes expressions, which is based on the order users declare symbols. So, Z3 2.x behavior would be affected by trivial modifications such as removing unused declarations.
Regarding iff, it is not part of SMT-LIB 2.0 standard. In SMT-LIB 2.0, = is used for formulas and terms. To make sure Z3 is fully compliant with the SMT-LIB 2.0 standard, whenever users specify a SMT-LIB supported logic (or soon to be supported such as UFBV), Z3 only "loads" the symbols defined in it. When, a logic is not specified, Z3 assumes the user is using the "Z3 logic" that contains all supported theories in Z3, and many extra aliases such as: iff for Boolean =, if for ite, etc.

Resources