Z3 4.3: get complete model - z3

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

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

Incremental SMT solver with ability to drop specific constraint

Is there an incremental SMT solver or an API for some incremental SMT solver where I can add constraints incrementally, where I can uniquely identify each constraint by some label/name?
The reason I want to identify the constraints uniquely is so that I can drop them later by specifying that label/name.
The need for dropping constraints is due to the fact that my earlier constraints become irrelevant with time.
I see that with Z3 I cannot use the push/pop based incremental approach because it follows a stack based idea whereas my requirement is to drop specific earlier/old constraints.
With the other incremental approach of Z3 based on assumptions, I would have to perform check-sat of the format "(check-sat p1 p2 p3)" i.e. if I had three assertions to check then I would require three boolean constants p1,p2,p3, but in my implementation I would have thousands of assertions to check at a time, indirectly requiring thousands of boolean constants.
I also checked JavaSMT, a Java API for SMT solvers, to see if the API provides some better way of handling this requirement, but I see only way to add constraints by "addConstraint" or "push" and was unable to find any way of dropping or removing specific constraints since the pop is the only option available.
I would like to know if there is any incremental solver where I can add or drop constraints uniquely identified by names, or an API where there is an alternative way to handle it. I would appreciate any suggestion or comments.
The "stack" based approach is pretty much ingrained into SMTLib, so I think it'll be tough to find a solver that does exactly what you want. Although I do agree it would be a nice feature.
Having said that, I can think of two solutions. But neither will serve your particular use-case well, though they will both work. It comes down to the fact that you want to be able to cherry-pick your constraints at each call to check-sat. Unfortunately this is going to be expensive. Each time the solver does a check-sat it learns a lot of lemmas based on all the present assertions, and a lot of internal data-structures are correspondingly modified. The stack-based approach essentially allows the solver to "backtrack" to one of those learned states. But of course, that does not allow cherry-picking as you observed.
So, I think you're left with one of the following:
Using check-sat-assuming
This is essentially what you described already. But to recap, instead of asserting booleans, you simply give them names. So, this:
(assert complicated_expression)
becomes
; for each constraint ci, do this:
(declare-const ci Bool)
(assert (= ci complicated_expression))
; then, check with whatever subset you want
(check-sat-assuming (ci cj ck..))
This does increase the number of boolean constants you have to manage, but in a sense these are the "names" you want anyhow. I understand you do not like this as it introduces a lot of variables; and that is indeed the case. And there's a good reason for that. See this discussion here: https://github.com/Z3Prover/z3/issues/1048
Using reset-assertions and :global-declarations
This is the variant that allows you to arbitrarily cherry-pick the assertions at each call to check-sat. But it will not be cheap. In particular, the solver will forget everything it learned each time you follow this recipe. But it will do precisely what you wanted. First issue:
(set-option :global-declarations true)
And somehow keep track of all these yourself in your wrapper. Now, if you want to arbitrarily "add" a constraint, you don't need to do anything. Just add it. If you want to remove something, then you say:
(reset-assertions)
(assert your-tracked-assertion-1)
(assert your-tracked-assertion-2)
;(assert your-tracked-assertion-3) <-- Note the comment, we're skipping
(assert your-tracked-assertion-4)
..etc
etc. That is, you "remove" the ones you don't want. Note that the :global-declarations call is important since it'll make sure all your data-declarations and other bindings stay intact when you call reset-assertions, which tells the solver to start from a clean-slate of what it assumed and learned.
Effectively, you're managing your own constraints, as you wanted in the first place.
Summary
Neither of these solutions is precisely what you wanted, but they will work. There's simply no SMTLib compliant way to do what you want without resorting to one of these two solutions. Individual solvers, however, might have other tricks up their sleeve. You might want to check with their developers to see if they might have something custom for this use case. While I doubt that is the case, it would be nice to find out!
Also see this previous answer from Nikolaj which is quite related: How incremental solving works in Z3?

DLV Rule is not safe

I am starting to work with DLV (Disjunctive Datalog) and I have a rule that is reporting a "Rule is not safe" error, when running the code. The rule is the following:
foo(R, 1) :- not foo(R, _)
I have read the manual and seen that "cyclic dependencies are disallowed". I guess this is why I am being reported the error, but I am not sure how this statement is so problematic to DLV. The final goal is to have some kind of initialization in case that the predicate has not been defined.
More precisely, if there is no occurrence of 'foo' with the parameter R (and anything else), then define it with parameters R and 1. Once it is defined, the rule shouldn't be triggered again. So, this is not a real recursion in my opinion.
Any comments on how to solve this issue are welcomed!
I have realised that I probably need another predicate to match the parameter R in the body of the rule. Something like this:
foo(R, 1) :- not foo(R, _), bar(R)
Since, otherwise there would be no way to know whether there are no occurrences of foo(R, _). I don't know whether I made myself clear.
Anyway, this doesn't work either :(
To the particular "Rule is not safe" error: First of all this has nothing to do with cyclic or acyclic dependencies. The same error message shows up for the non-cyclic program:
foo2(R, 1) :- not foo(R,_), bar(R).
The problem is that the program is actually not safe (http://www.dlvsystem.com/html/DLV_User_Manual.html#SAFETY). As mentioned in the section on negative rules (anchor #AEN375, I am only allowed to use 2 links in my answer):
Variables, which occur in a negated literal, must also occur in a
positive literal in the body.
Observe that the _ is an anonymous variable. I.e., the program
foo(R,1) :- not foo(R,_), bar(R).
can be equivalently written as (and is equivalent to)
foo(R,1) :- not foo(R,X), bar(R).
Anonymous variables (DLV manual, anchor #AEN264 - at the end of the section) just allow us to avoid inventing names for variables that will only occur once within the rule (i.e. for variables that only express "there is some value, I absolutely do not care about it), but they are variables nevertheless. And since negation with not is "negation" and not "true negation" (or "strong negation" as it is also often called), none of the three safety conditions is satisfied by the rule.
A very rough and high-level intuition for safety is that it guarantees that every variable in the program can be assigned to some finite domain - as it is now the case with R by adding bar(R). However, the same also must be the case for the anonymous variable _ .
To the actual problem of defining default values:
As pointed out by lambda.xy.x, the problem here is the Answer Set (or stable model) semantics of DLV: Trying to do it in one rule does not give any solution:
In order to get a safe program, we could replace the above problems e.g. by
foo(1,2). bar(1). bar(2).
tmp(R) :- foo(R,_).
foo(R,1) :- not tmp(R), bar(R).
This has no stable model:
Assume the answer is, as intended,
{foo(1,2), bar(1), bar(2), foo(2,1)}
However, this is not a valid model, since tmp(R) :- foo(R,_) would require it to contain tmp(2). But then, "not tmp(2)" is no longer true, and therefore having foo(2,1) in the model violates the required minimality of the model. (This is not exactly what is going on, more a rough intuition. More technical details could be found in any article on answer set programming, a quick Google search gave me this paper as one of the first results: http://www.kr.tuwien.ac.at/staff/tkren/pub/2009/rw2009-asp.pdf)
In order to solve the problem, it is therefore somehow necessary to "break the cycle". One possibility would be:
foo(1,2). bar(1). bar(2). bar(3).
tmp(R) :- foo(R,X), X!=1.
foo(R,1) :- bar(R), not tmp(R).
I.e., by explicitly stating that we want to add R into the intermediate atom only if the value is different from 1, having foo(2,1) in the model does not contradict tmp(2) not being part of the model as well. Of course, this no longer allows to distinguish whether foo(R,1) is there as default value or by input, but if this is not required ...
Another possibility would be to not use foo for the computation, but some foo1 instead. I.e. having
foo1(R,X) :- foo(R,X).
tmp(R) :- foo(R,_).
foo1(R,1) :- bar(R), not tmp(R).
and then just use foo1 instead of foo.

Z3 4.0: get complete model

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.

Is it possible to clone Z3_context?

I need it for incremental solving in the context of symbolic execution (Klee).
In points of branching of symbolic execution paths it is necessary to split solver context into 2 parts: with true and false conditions. Of course, there is an expensive workaround - create empty context and replay all constraints.
Is there a way to split Z3_context? Do you plan to add such functionality?
Note
splitting of context can be avoided if use depth-first symbolic exploration, that is exploring current execution path until it reaches "end" and hence this path won't be explored anymore in future. In this case it is enough to pop until branch point reached and continue to explore another condition branch. But in case of Klee many symbolic paths are explored "simultaneously" (exploration of true and false branches is interleaved), so you need solver context solver switching (there is Z3_context argument in each method) and branching (there are no methods for this, that is what I need).
Thanks!
No, the current version of Z3 (3.2) does not support this feature. We realize this is an important capability, and an equivalent feature will be available in the next release.
The idea is to separate the concepts of Context and Solver. In the next release, we will have APIs for creating (and copying) solvers. So, you will be able to use a different solver for each branch of the search. In a nutshell, the Context is used to manage/create Z3 expressions, and the Solver for checking satisfiability.
The approach I currently use for this sort of thing is to assert formulas like p => A instead of A, where p is a fresh Boolean literal. Then in my client I maintain the association between the list of guard literals that correspond to each branch, and use check_assumptions(). In my situation I happen to be able to get away with leaving all formulas allocated during each search, but YMMV. Even for depth-first explorations, I seem to get much more incremental reuse this way than by using push/pop.

Resources