While loop for Z3 or Smt2 - z3

How to convert a simple while loop(c- code) to smt2 language or z3?
For ex :
int x,a;
while(x > 10 && x < 100){
a = x + a;
x++;
}

The input language to an SMT solver is first-order logic (with theories) and as such has no notion of computational operations such as loops.
You can
either use a loop invariant to encode an arbitrary loop iteration (and the pre- and post-state of the loop) and prove your relevant properties with respect to that arbitrary iteration, which is what deductive program verifiers such as Boogie, Dafny or Viper do
or, if the number of iterations is statically known, you unroll the loop and basically use single static assignment form to encode the different unrollings
For your loop, the latter would look as follows (not using proper SMT syntax here because I'm lazy):
declare x0, a0 // initial values
declare a1, x1 // values after first unrolling
x0 > 10 && x0 < 100 ==> a1 == a0 + x0 && x1 == x0 + 1
declare a2, x2 // values after second unrolling
x1 > 10 && x1 < 100 ==> a2 == a1 + x1 && x2 == x1 + 1
...

Related

Z3 solver: mapping boolean to integer and computing sums

I have a boolean expression
f(x1, x2, x3, ..., xn)
Let m(x) be a mapping from {true,false} to {1,0} and let
g(x1, x2, x3, ..., xn) = m(x1) + m(x2) + ... + m(xn)
g() is computing the number of its arguments that evaluate to true.
I have some constraints on k = g(x1, x2, ..., xn) such as leastsignificantbit(k) = 1.
How can I specify this in Z3?
As a concrete example: Let f1 = a OR b, f2 = c OR d OR e, c = leastsignificantbit(m(a) + m(b)) where m(x) is defined as above.
I am using the Z3 .net API, however, it is not necessary for the answer to use the .net API as long as it uses the Z3 concepts in any supported language binding.

add iteratively in z3

I want to check the value of a, b, c, and if value 'a' equals to 1, 'x' is added one. We continue the process for values 'b' and 'c'.
So if a=1, b=1, c=1, the result of x should be 3.
if a=1, b=1, c=0, so the result of x should be 2.
Any methods to be implemented in z3?
The source code looks like this:
from z3 import *
a, b, c = Ints('a b c')
x, y = Ints('x y')
s = Solver()
s.add(If(a==1, x=x + 1, y = y-1))
s.add(If(b==1, x=x + 1, y = y-1))
s.add(If(c==1, x=x + 1, y = y-1))
s.check()
print s.model()
Any suggestions about what I can do?
This sort of "iterative" processing is usually modeled by unrolling the assignments and creating what's known as SSA form. (Static single assignment.) In this format, every variable is assigned precisely once, but can be used many times. This is usually done by some underlying tool as it is rather tedious, but you can do it by hand as well. Applied to your problem, it'd look something like:
from z3 import *
s = Solver()
a, b, c = Ints('a b c')
x0, x1, x2, x3 = Ints('x0 x1 x2 x3')
s.add(x0 == 0)
s.add(x1 == If(a == 1, x0+1, x0))
s.add(x2 == If(b == 1, x1+1, x1))
s.add(x3 == If(c == 1, x2+1, x2))
# Following asserts are not part of your problem, but
# they make the output interesting
s.add(b == 1)
s.add(c == 0)
# Find the model
if s.check() == sat:
m = s.model()
print("a=%d, b=%d, c=%d, x=%d" % (m[a].as_long(), m[b].as_long(), m[c].as_long(), m[x3].as_long()))
else:
print "no solution"
SSA transformation is applied to the variable x, creating as many instances as necessary to model the assignments. When run, this program produces:
a=0, b=1, c=0, x=1
Hope that helps!
Note that z3 has many functions. One you could use here is Sum() for the sum of a list. Inside the list you can put simple variables, but also expression. Here an example for both a simple and a more complex sum:
from z3 import *
a, b, c = Ints('a b c')
x, y = Ints('x y')
s = Solver()
s.add(a==1, b==0, c==1)
s.add(x==Sum([a,b,c]))
s.add(y==Sum([If(a==1,-1,0),If(b==1,-1,0),If(c==1,-1,0)]))
if s.check() == sat:
print ("solution:", s.model())
else:
print ("no solution possible")
Result:
solution: [y = 2, x = 2, c = 1, b = 0, a = 1]
If your problem is more complex, using BitVecs instead of Ints can make it run a little faster.
edit: Instead of Sum() you could also simply use addition as in
s.add(x==a+b+c)
s.add(y==If(a==1,-1,0)+If(b==1,-1,0)+If(c==1,-1,0))
Sum() makes sense towards readability when you have a longer list of variables, or when the variables already are in a list.

How to represent binary logical in Three Address Code

In three address code a branch can only have a binary relational operator,
e.g.
if x relop y goto L1, where relop is (!=,==,>,>=,<,<=)
How would the following be represented as three address code format:
j = 0
while(j < 10 || j < 20)
{
System.out.println(i);
j++;
}
Here is my solution which is obviously incorrect:
main:
j = 1
sum = 0
L2:
if j < 10 || j < 20 goto L3
goto L4
L3:
mt2 = sum + 1
sum = mt2
mt3 = j + 1
j = mt3
goto L2
L4:
sum = 2
You break it down into two tests:
L2:
if j < 10 goto L3
if j < 20 goto L3
goto L4
L3:
(Did you mean j < 10 || j > 20? As written, the first test is redundant.)
In general, || and && are control flow operators and translate into individual branch instructions. Note that boolean not is often implemented by flipping labels.
Boolean operators are usually "short-circuiting" -- that is, the right-hand operation is not evaluated unless necessary -- precisely because of this translation style. Had the second computation been more complicated, it would have been done after the first if, which would lead to short-circuit behaviour.

How to define piece-wise functions in Z3py

I would like to define a piece-wise (linear) function in Z3py, for example, the function f(x) has the form
f(x) = a*x + b when 0 <= x <= 1
f(x) = exp(c*x) when 1 < x <= 2
f(x) = 1/(1+10^x) when 2 < x <= 3
etc.
where a, b and c are constants.
I guess the z3.If() function will be relevant, but as the number of pieces grows, the expression gets convoluted.
My questions is, does Z3pyprovides the if-else statement, or is there an elegant way to define piece-wise function in Z3py?
Yes, Z3 supports if-then-elses and in Python they can be constructed using the If function. An example from the documentation of If:
>>> x = Int('x')
>>> y = Int('y')
>>> max = If(x > y, x, y)
max = If(x > y, x, y)

Maxima: Simplify expressions containing minimum

I am trying to use Maxima to simplify mathematical expressions involving min(a, b). Say I have defined
z = min(x1, x2) and d = abs(x1 - x2), then the identities x1 * x2 = z*(z+d) and x1 + x2 = 2*z + d follow.
For example, take the following expression:
(2*z^3+(−3*x2−3*x1)*z^2+6*x1*x2*z)/6
If I manually apply the above identities, I can simplify it to
z^3 / 3 + (z^2 * d) / 2
In Maxima, naively trying
subst(min(x1, x2), v, ((6*v*x1−3*v^2)*x2−3*v^2*x1+2*v^3)/6), ratsimp
Produces a long expression.
How can I make Maxima find the occurrences of x1 * x2 and x1 + x2 buried deep inside the expression? I have tried various forms of tellsimp, let and letsimp, for example:
let(x1*x2, z * (z+d))
or
let(K * x1*x2, K * z * (z + d), K, integer)
or
matchdeclare(R, true)
let(R * x1*x2 * z, R * z * (z+d))
How can I make Maxima produce the nice short expression that I can manually arrive at? I need to work with much larger expressions.
May be this is helpful,
load("lrats");
lratsubst([x1*x2=z*(z+d),x1+x2=2*z+d],
(2*z^3+(−3*x2−3*x1)*z^2+6*x1*x2*z)/6)
(2*z^3+3*d*z^2)/6
Also if you want to test your identities, you could do
z(x1,x2):=min(x1,x2)$
d(x1,x2):=abs(x1-x2)$
Now put numerical values say, z(2,3)*(z(2,3)+d(2,3))=6. Apparently these don't help in simplifying your expression.

Resources