contains for two sets in Z3 - z3

If I want to check if a set has elements of another set is also possible?
For example (contains Set1 Set2):
contains [1,2] [3,5] -> is false
contains [1] [2,3, 1] -> is true
The sets are finite. And the maximum value of the sets is five and the minimum is 0, the sets may not have values greater than 5 neither smaller than 0.
For example:
[1,5,3] -> valid set
[1,8,2] -> invalid set
If it were only for a set and check whether a value exist in the set was easy. It was in the following way:
( declare-sort Set 0 )
( declare-fun contains (Set Int) bool )
( declare-const set Set )
( declare-const A Int )
( assert ( contains set A ))
( assert ( not (contains set 0 )))
( check-sat )
But for two sets I do not see how it's done.
Thank you for your attention.

The operation (contains S1 S2) that you describe in your message is the subset relation. If we encode sets of integers as functions from Int to Boolean (like in: max value in set z3), then S1 and S2 are declared as:
(declare-fun S1 (Int) Bool)
(declare-fun S2 (Int) Bool)
Then, we can say that S1 is a subset of S2 by asserting
(assert (forall ((x Int)) (=> (S1 x) (S2 x))))
We just saying that any element in S1 is also an element of S2.
EDIT
We can use the expression (exists ((x Int)) (and (S1 x) (S2 x))) to check whether the sets S1 and S2 have an element in common or not
END EDIT
The minimal element of a set can be encoded as we did in max value in set z3.
For example, suppose the minimal element of S1 is min_S1.
; Now, let min_S1 be the min value in S1
(declare-const min_S1 Int)
; Then, we now that min_S1 is an element of S1, that is
(assert (S1 min_S1))
; All elements in S1 are bigger than or equal to min_S1
(assert (forall ((x Int)) (=> (S1 x) (not (<= x (- min_S1 1))))))
If the minimal values of the sets you are encoding are known at "encoding time" (and are small). We can use yet another encoding based on Bit-vectors.
In this encoding, a set is a Bit-vector. If the sets only contain values between 0 and 5, then we can use a Bit-vector of size 6. The idea is: if bit i is true iff i is an element of the set.
Here is an example with the main operation:
(declare-const S1 (_ BitVec 6))
(declare-const S2 (_ BitVec 6))
(declare-const S3 (_ BitVec 6))
; set equality is just bit-vector equality
(assert (= S1 S2))
; set intersection, union, and complement are encoded using bit-wise operations
; S3 is S1 union S2
(assert (= S3 (bvor S1 S2)))
; S3 is S1 intersection of S2
(assert (= S3 (bvand S1 S2)))
; S3 is the complement of S1
(assert (= S3 (bvnot S1)))
; S1 is a subset of S2 if S1 = (S1 intersection S2), that is
(assert (= S1 (bvand S1 S2)))
; S1 is the empty set if it is the 0 bit-vector
(assert (= S1 #b000000))
; To build a set that contains only i we can use the left shift
; Here, we assume that i is also a bit-vector
(declare-const i (_ BitVec 6))
; S1 is the set that contains only i
; We are also assuming that i is a value in [0, 5]
(assert (= S1 (bvshl #b000001 i)))

Related

str.suffix in z3 API is unknown

I'm trying to use suffix API function in Z3 in the following script,
but Z3 complains it does not know str.suffix. Since I see it in the API
here I guess it exists but only called different (?)
Thanks!
(declare-const s String)
(declare-const s00 String)
(declare-const s1 String)
(declare-const s2 String)
(declare-const i Int)
(assert (= s "X2a2##aDD\x00444ppa800"))
(assert (= s00 (str.substr s 0 (str.indexof s "\x00" 0))))
(assert (str.suffixof s1 s00))
(assert (str.suffixof s2 s1))
(assert (= (str.len s1) (+ (str.len s2) 1)))
(assert (or (and (str.contains s00 "a")
(str.contains s1 "a"))
(not (str.contains s00 "a"))))
(assert (not (str.contains s2 "a")))
(assert (= i (ite (not (str.contains s00 "a")) -1
(- (str.len s00) (str.len s1)))))
(check-sat)
(get-value (s s00 s1 s2 i))
EDIT:
The script was fixed according to the answer. Here is the output from z3:
sat
((s "X2a2##aDD\x00444ppa800")
(s00 "X2a2##aDD")
(s1 "aDD")
(s2 "DD")
(i 6))
The correct call is: str.suffixof
(PS. Your file still doesn't load even with that fix since it has other issues; but that's besides the point of this question.)

Converting Z3 QBF formula directly to pcnf

I'm using Z3 theorem prover (using Z3Py: the Z3 API in Python) to create QBF (Quantified Boolean formula).
Is there any way in Z3 to directly convert your qbf formula into Prenex normal form ?
I don't think there's a tactic to convert to Prenex, but you can surely apply the quantifier-elimination tactic and further process your formulas. Note that the transformed formulas will not really look like the originals, as they are mechanically generated.
Here's an example:
from z3 import *
f = Function('f', IntSort(), IntSort(), IntSort())
x, y = Ints('x y')
p = ForAll(x, Or(x == 2, Exists(y, f (x, y) == 0)))
print Tactic('qe')(p)
Here qe is the quantifier elimination tactic. This produces:
[[Not(Exists(x!0,
Not(Or(x!0 == 2,
Exists(x!1,
And(f(x!0, x!1) <= 0,
f(x!0, x!1) >= 0))))))]]
For a nice tutorial on tactics, see here: http://ericpony.github.io/z3py-tutorial/strategies-examples.htm
You could use the skolemize tactic (snf) which will by definition be in prenex form. However it will also eliminate existential quantifiers which is not what you want. Here's an example.
(declare-fun a (Int) Bool)
(declare-fun b (Int) Bool)
(declare-fun c (Int) Bool)
(assert
(forall ((x Int))
(or
(exists ((y Int))
(a y)
)
(exists ((z Int))
(=>
(b z)
(c x)
)
)
)
)
)
(apply
(and-then
; mode (symbol) NNF translation mode: skolem (skolem normal form), quantifiers (skolem normal form + quantifiers in NNF), full (default: skolem)
(using-params snf :mode skolem)
)
:print_benchmark true
:print false
)
When Z3 is given the above it will responds with something like
(declare-fun c (Int) Bool)
(declare-fun b (Int) Bool)
(declare-fun a (Int) Bool)
(assert (forall ((x Int))
(or (exists ((y Int)) (a y)) (exists ((z Int)) (=> (b z) (c x))))))
(check-sat)
You can see the available tactics by running
echo "(help-tactic)" | ./z3 -in | less
from a bash shell.
Unfortunately I can't see one that states it does conversion to prenex.

Z3 invariant check

I want a way to, given an invariant and one or more operation's effects, check if, after the operation's execution, the invariant still holds.
Any ideas on how to accomplish this?
Using Z3 I was thinking of doing something similar to
(declare-const a Int)
(declare-const b Int)
(declare-const c Int)
(declare-const d Int)
(define-fun invariant () Bool
(= a b c d 2)
)
(assert invariant)
(assert (= a 1)) ;operation1
(assert (= b 2)) ;operation2
(assert (not invariant))
(check-sat)
If (check-sat) returns unsat then I conclude that the system's state is valid after the operations.
I obviously can't do the above since
(assert invariant)
(assert (not invariant))
always make the theorem unsat.
But I need to assert that the initial state is valid so that the parts of the system that aren't changed by the operations are valid when I run (assert (not invariant)).
I assume that your operations mutate some kind of state (local variables, a program heap, ...), and your invariant should therefore be a function of the state.
As a small example, consider this hypothetical imperative program with local variables:
var start: Int := 0
var end: Int := 0
var arr: Array[Int] := new Array(10) // Array of ints, size 10
fill(arr, 0) // Fill the array with zeros
def invariant() =
(0 < start <= end)
&& forall i in [start, end - 1) :: arr(i) < arr(i + 1) // Sorted
assert invariant() // holds
end := end + 1
assert invariant() // holds
end := end + 1
assert invariant() // fails
arr(start + 1) := arr(start + 1) + 1
assert invariant() // holds
It could be encoded as follows, where the mutated local variables are represented in static single assignment form:
(define-fun invariant ((start Int) (end Int) (arr (Array Int Int))) Bool
(and
(<= 0 start)
(<= start end)
(forall ((i Int))
(implies
(and (<= start i) (< i (- end 1)))
(< (select arr i) (select arr (+ i 1)))))))
(declare-const start0 Int)
(declare-const end0 Int)
(declare-const arr0 (Array Int Int))
(assert (= start0 0))
(assert (= end0 0))
(assert (= arr0 ((as const (Array Int Int)) 0)))
(push)
(assert (not (invariant start0 end0 arr0)))
(check-sat) ;; UNSAT --> Invariant holds
(pop)
;; Operation: end := end + 1
(declare-const end1 Int)
(assert (= end1 (+ end0 1)))
(push)
(assert (not (invariant start0 end1 arr0)))
(check-sat) ; UNSAT --> Invariant still holds
(pop)
;; Operation: end := end + 1
(declare-const end2 Int)
(assert (= end2 (+ end1 1)))
(push)
(assert (not (invariant start0 end2 arr0)))
(check-sat) ; SAT --> Invariant has been broken!
(pop)
;; Operation: arr[start + 1] := arr[start + 1] + 1
(declare-const arr1 (Array Int Int))
(assert (= arr1 (store arr0 (+ start0 1) (+ (select arr0 (+ start0 1)) 1))))
(push)
(assert (not (invariant start0 end2 arr1)))
(check-sat) ; UNSAT --> Invariant has been restored
(pop)

max value in set z3

I'm a new guy to work with the Z3.
Would like to know how I can calculate the maximum value of a set and two different sets.
For example:
[1, 6, 5] - The greater is 6
[1, 6, 5] e [10, 7, 2] - The greater is 6
I use the following code to set:
(declare-sort Set 0)
(declare-fun contains (Set Int) bool)
( declare-const set Set )
( declare-const distinct_set Set )
( declare-const A Int )
( declare-const B Int )
( declare-const C Int )
( assert ( = A 0 ) )
( assert ( = B 1 ) )
( assert ( = C 2 ) )
( assert ( distinct A C) )
( assert ( distinct set distinct_set ) )
(assert
(forall ((x Int))
(= (contains set x) (or (= x A) (= x C)))))
And now would like to know how can I calculate the largest value in the set (set) and the largest value in sets (set and distinct_set).
If it was for all integers was only because it was easy to do:
(define-fun max ((x Int) (y Int)) Int
(ite (< x y) y x))
But I can not leave with sets by their integers, ie, get the values ​​that have set.
Can you help me?
Thanks
Is the following encoding reasonable for your purposes? It is also available online here.
; We Enconde each set S of integers as a function S : Int -> Bool
(declare-fun S1 (Int) Bool)
; To assert that A and C are elements of S1, we just assert (S1 A) and (S1 C)
(declare-const A Int)
(declare-const C Int)
(assert (S1 A))
(assert (S1 C))
; To say that B is not an element of S1, we just assert (not (S1 B))
(declare-const B Int)
(assert (not (S1 B)))
; Now, let max_S1 be the max value in S1
(declare-const max_S1 Int)
; Then, we now that max_S1 is an element of S1, that is
(assert (S1 max_S1))
; All elements in S1 are smaller than or equal to max_S1
(assert (forall ((x Int)) (=> (S1 x) (not (>= x (+ max_S1 1))))))
; Now, let us define a set S2 and S3
(declare-fun S2 (Int) Bool)
(declare-fun S3 (Int) Bool)
; To assert that S3 is equal to the union of S1 and S2, we just assert
(assert (forall ((x Int)) (= (S3 x) (or (S1 x) (S2 x)))))
; To assert that S3 is not equal to S1 we assert
(assert (exists ((x Int)) (not (= (S3 x) (S1 x)))))
(check-sat)
; Now let max_S3 be the maximal value of S3
(declare-const max_S3 Int)
(assert (S3 max_S3))
(assert (forall ((x Int)) (=> (S3 x) (not (>= x (+ max_S3 1))))))
; the set of constraints is still satisfiable
(check-sat)
; Now, let us assert that max_S3 < max_S1.
; It should be unsat, since S3 is a super set of S1
(assert (< max_S3 max_S1))
(check-sat)

Modeling array assignment in Z3

I'm working on a project for program verification. I have the following statement to be modeled in Z3:
temp = a[i];
a[i] = a[j];
a[j] = temp;
All the variables are of integer type. Would someone give me some hints on how to build constraints to model the above statements?
Here is a general "recipe".
We represent array updates using (store a i v). The result is a new array equal to a, but at position i contains the value v.
An array access a[i] should be encoded as (select a i).
Assignments such as i = i + 1 are usually encoded by creating Z3 variables that represent the value of i before and after the assignment. That is, we would encode it as (= i1 (+ i0 1)).
Keep in mind that the formula (= i (+ i 1)) is equivalent to false.
Here is the example above encode in SMT 2.0 format.
http://www.rise4fun.com/Z3/G5Zk
Here is the script found in the link above.
(declare-const a0 (Array Int Int))
(declare-const a1 (Array Int Int))
(declare-const a2 (Array Int Int))
(declare-const temp0 Int)
(declare-const temp1 Int)
(declare-const i0 Int)
(declare-const j0 Int)
(assert (= temp0 (select a0 i0)))
(assert (= a1 (store a0 i0 (select a0 j0))))
(assert (= a2 (store a1 j0 temp0)))
(check-sat)
(get-model)

Resources