Z3, solver: push an empty level on assertion-stack, as defined in smtlib2: push(n=1) - z3

currently I am using Z3 with Python.
I want to create an assertion-stack, where I can push a level and pop it later.
It should work exactly like any other "stack" with push- and pop-operations.
Therefore the SMTLIB2-standard defines two functions "push(n)" and "pop(n)" with optional numbers n. In my case n would always be 1.
But there seems to be some strange behaviour in Z3.
Why does following code result in "index out of bounds"?
s = Solver()
s.push() # expected: one new level on the stack, reality: emtpy stack
s.pop(1) # expected: stack is empty, reality: exception (index out of bounds)
If I add an assertions, Z3 works as expected.
s = Solver()
s.push()
s.add(True) # now there is one level on the stack,
s.pop(1) # pop is successful
Even this works correct:
s = Solver()
s.add(True)
s.push() # now there is one level on the stack,
s.pop(1) # pop is successful
The problem is, that I do not know, how many levels and how many assertions are created in my program. It is possible, that there is no assertion at all and only one level. Then the program would crash (or catch the exception). A workaround would be adding some simple formula like "True" always as a first step, but this seems ugly.
Is this a bug in Z3 or is this behaviour correct?

This bug has been fixed in the unstable (working-in-progress) branch.
It will be available in the next official release. In the meantime, here are some instructions on how to compile the unstable branch. The fix is also available in the nightly builds available at codeplex.

Related

How to alter assertions in a solver without having to repeatedly create a new solver in z3 Python API

I am currently running into the problem that I create a large SMT formula (that I get from an external source) and I run Solver.check() with it. If the call fails I perform a rewrite on some assertions in the solver using the rewrite(s,f,t) presented here.
Now I am wondering how I can change the assertions in the solver that failed to the new ones obtained after the rewrite. That is assertions that still contain the same function defintions/declarations etc. as the previous solver except with the updated assertions that have been rewritten.
For example, this is how I would do it now. I wonder if there was a better/more efficient way:
solver = z3.Solver()
f = z3.Function(f, z3.Int(),z3.Int())
solver.add(f(3)== 5)
solver.check()
solver.model()
# I don't like the model let's rewrite
new_assertions = solver.assertions().rewrite(...)
new_solver = z3.Solver()
new_solver.add(new_assertions)
new_solver.check()
...
This is what the push, and pop statements are for:
push: Creates a back-tracking point that you can jump back to
pop: Goes back to the last push'ed point
That is, you push before you add your assertions, and when you want to change them pop back to where you were. You can create as many backtracking points as you want.
This style of solver usage is called "incremental" and is described in Section 4.1.4 of the SMTLib document. To simplify programming with your rewrite function, you might want to keep the assertions in a list of your own, so they are easy to manipulate; but that's more or less tangential to the discussion at hand here.

Updating z3 Variable or Linear Solving

I'm new to Z3, so this is likely a silly question. I'm trying to model an execution flow of a program. Doing this through manual z3 calls for now. That said, I end up trying to model something like the following:
x = 1
x += 1
Performing the following commands gives me unsat, and I understand why.
x = z3.Int('x')
s.add(x == 1)
s.add(x == x + 1)
In small scale, it might be reasonable to manually change x == 1 to x == 2. My question is, is there a way to do this in z3 where I don't have to go back and attempt to modify the variables I put into the solver? The equations obviously would get much harrier than just +1, and attempting to work through that logic manually seems error prone and sloppy.
EDIT: After adjusting my program to use SSA as suggested, it works very easily now. I did opt to keep multiple versions of the variable, but that didn't turn into too much extra work.
You can rename variables such that they are in SSA form (https://en.wikipedia.org/wiki/Static_single_assignment_form).
Also, you probably don't need to introduce names for intermediate expressions. The only Z3 variables should be program inputs or things like that.

Describing a 'waiting' step on gherkin language

I'm trying to describe a scenario of my app on gherkin language so that I can use it as executable spec. The scenario is more less the following: There's a phase of a process in which a check is performed. If all conditions for the check are fulfilled then the process end. Otherwise, the process waits for any condition to change (it's notified about this) and the checks again, finishing if succesful. What I'm having trouble describin is this waiting part. My current version (simplified) is:
Given condition A
And not condition B
When the check is performed
Then the result is negative, pending condition B
What I'm trying to express with pending condition B is that the test will be repeated once condition B changes, but I don't particularly like this version, since it's hard to turn one to one to a test (the fact that condition B changes would be a new When).
Can anybody with more experience come up with a better formulation?
You can either link the two tests together, like this:
Scenario: When A and not B result is negative, but if B happens then result is positive
Given condition A
But not condition B
Then the check returns negative
But if condition B
Then the check returns positive
Which might not be best practice but is sometimes the pragmatic way of doing things, especially if the tests are slow running because of the system under test or your test environment etc.
Or you could make it into two scenarios with some repetition behind the scenes.
Scenario: When A and not B the result is negative
Given condition A
But not condition B
Then the check returns negative
Scenario: When A and B the result should be positive
Given the system has condition A but not B
And the check is returning negative
When condition B
Then the check returns positive
In your case I would say that which one to choose depends on how long your tests take to run. If they are slow then go for one big scenario. If they aren't, or it doesn't matter for some reason then go for the second suggestion. The second suggestion will give more information about the cause of the failure which is nice to have, but if the tests are slow then I think it would still be quite obvious why the the test was failing even if you are using one big scenario.

Does Z3 have support for optimization problems

I saw in a previous post from last August that Z3 did not support optimizations.
However it also stated that the developers are planning to add such support.
I could not find anything in the source to suggest this has happened.
Can anyone tell me if my assumption that there is no support is correct or was it added but I somehow missed it?
Thanks,
Omer
If your optimization has an integer valued objective function, one approach that works reasonably well is to run a binary search for the optimal value. Suppose you're solving the set of constraints C(x,y,z), maximizing the objective function f(x,y,z).
Find an arbitrary solution (x0, y0, z0) to C(x,y,z).
Compute f0 = f(x0, y0, z0). This will be your first lower bound.
As long as you don't know any upper-bound on the objective value, try to solve the constraints C(x,y,z) ∧ f(x,y,z) > 2 * L, where L is your best lower bound (initially, f0, then whatever you found that was better).
Once you have both an upper and a lower bound, apply binary search: solve C(x,y,z) ∧ 2 * f(x,y,z) > (U - L). If the formula is satisfiable, you can compute a new lower bound using the model. If it is unsatisfiable, (U - L) / 2 is a new upper-bound.
Step 3. will not terminate if your problem does not admit a maximum, so you may want to bound it if you are not sure it does.
You should of course use push and pop to solve the succession of problems incrementally. You'll additionally need the ability to extract models for intermediate steps and to evaluate f on them.
We have used this approach in our work on Kaplan with reasonable success.
Z3 currently does not support optimization. This is on the TODO list, but it has not been implemented yet. The following slide decks describe the approach that will be used in Z3:
Exact nonlinear optimization on demand
Computation in Real Closed Infinitesimal and Transcendental Extensions of the Rationals
The library for computing with infinitesimals has already been implemented, and is available in the unstable (work-in-progress) branch, and online at rise4fun.

understanding code coverage results

I have a strange coverage result in visual studio:
it appears as the if statement was not covered but since we did enter the block it must have been. Why are those results wrong? (those result cover many runs under many conditions)
screenshot
I suspect what you are seeing is branch coverage due to not testing all combinations that can result in going down each path. Logical AND (&&) allows early escape i.e. it only evaluates the second operator if the first is true.
e.g.
if (bool.TryParse(savePrep, out save) && save)
has 3 possibilities
savePrep = "true"
savePrep = "false"
savePrep = "neither-true-nor-false"
you have probably only exercised #1 and #2

Resources