Function with ordered arguments - z3

It seems that uninterpret functions treat arguments as unordered.
For example,
(declare-fun Lturn (Int Int Int) Bool)
(assert (forall ((x Int) (y Int) (z Int))
(not (= (Lturn x y z) (Lturn x z y)))))
(check-sat)
The result is UNSAT.
The above code is available here: http://rise4fun.com/Z3/hkpwO
To overcome this situation, I tried using array:
(declare-fun Lturn ((Array Int Int)) Bool)
(assert (forall ((A1 (Array Int Int)) (A2 (Array Int Int)))
(=> (and (= (select A1 1) (select A2 1))
(= (select A1 2) (select A2 3))
(= (select A1 3) (select A2 2)))
(not (= (Lturn A1) (Lturn A2))))))
(check-sat)
The result is "unknown."
The above code is available here: http://rise4fun.com/Z3/bdTL
Is there any method to let the Array version be SAT?

Function arguments are not unordered. Can you give a function Lturn that would make your assertion SAT? Here's a simpler case with just two arguments: http://rise4fun.com/Z3/Zsjs
For x == 0 && y == 0 && z == 0 there is no function such that f(x, y, z) != f(x, z, y) because f(0, 0, 0) != f(0, 0, 0) is always false.

Related

Z3 Checking whether all values in array are unique

So I'm trying to check whether all values in an array is unique with the following Z3 code.
(declare-const A (Array Int Int))
(declare-const n Int)
(assert (forall ((i Int) (j Int)) (and (and (and (>= i 0) (< i n)) (and (>= j 0) (< j n)))
(implies (= (select A i) (select A j)) (= i j)))))
(check-sat)
I'm quite new to Z3 so I don't quite understand the grammar and stuff, but can anyone tell me whether this code is right, and if not, where's the problem?
The problem as you wrote is unsat, because it says whenever 0 <= i < n and 0 <= j < n, if A[i] = A[j], then i = j. There is no array and a particular n you can pick to satisfy this constraint.
What you really want to write is the following instead:
(declare-const A (Array Int Int))
(declare-const n Int)
(assert (forall ((i Int) (j Int)) (implies (and (>= i 0) (< i n)
(>= j 0) (< j n)
(= (select A i) (select A j)))
(= i j))))
(check-sat)
(get-model)
The above says If it's the case that i and j are within bounds, and array elements are the same, then i must equal j. And this variant would be satisifiable for any n; and indeed here's what z3 reports:
sat
(
(define-fun n () Int
0)
(define-fun A () (Array Int Int)
((as const (Array Int Int)) 0))
)
But note that z3 simply picked n = 0, which made it easy to satisfy the formula. Let's make sure we get a more interesting model, by adding:
(assert (> n 2))
Now we get:
sat
(
(define-fun n () Int
3)
(define-fun A () (Array Int Int)
(lambda ((x!1 Int))
(let ((a!1 (ite (and (<= 1 x!1) (not (<= 2 x!1))) 7 8)))
(ite (<= 1 x!1) (ite (and (<= 1 x!1) (<= 2 x!1)) 6 a!1) 5))))
)
and we see that z3 picked the array to have 3 elements with distinct values at positions we care about.
Note that this sort of reasoning with quantifiers is a soft-spot for SMT solvers; while z3 is able to find models for these cases, if you keep adding quantified axioms you'll likely get unknown as the answer, or z3 (or any other SMT solver for that matter) will take longer and longer time to respond.

Three ways to assgin values to an array in z3

As far as I know, there are three ways to assgin values to an array in z3.
use assert to assgin values to some of the cells:
(declare-const a1 (Array Int Int))
(declare-const a2 (Array Int Int))
(assert (= 1 (select a1 0)))
(assert (= 2 (select a2 0)))
z3 returns unsat when the constraint (assert (= a1 a2)) is added.
use as const to initialize the array first and then assgin values to specific cells:
(declare-const a3 (Array Int Int))
(assert
(=
(store ((as const (Array Int Int)) 64) 0 3)
a3
)
)
(declare-const a4 (Array Int Int))
(assert
(=
(store ((as const (Array Int Int)) 64) 0 4)
a4
)
)
Add (assert (= a3 a4)) and we obtain unsat again.
define the array via a function:
(define-const a5 (Array Int Int)
(lambda ((i Int))
(ite (= i 0) 5 64)))
(define-const a6 (Array Int Int)
(lambda ((i Int))
(ite (= i 0) 6 64)))
But if we add (assert (= a5 a6)), z3 returns sat. Why?
By the way, is there any (better) way to assign values to an array in z3?
It's a bug. Check out this issue.

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)

How do I define for example a plus function on integers in Z3 using the .NET API?

Using the Z3 .NET API I'm trying to do something similar as the following example which I have taken from the Z3 Guide:
(define-sort A () (Array Int Int Int))
(define-fun bag-union ((x A) (y A)) A
((_ map (+ (Int Int) Int)) x y))
(declare-const s1 A)
(declare-const s2 A)
(declare-const s3 A)
(assert (= s3 (bag-union s1 s2)))
(assert (= (select s1 0 0) 5))
(assert (= (select s2 0 0) 3))
(assert (= (select s2 1 2) 4))
(check-sat)
(get-model)
How do I define the + function such that I can use it in MkMap?
MkMap expects a function declaration, so you need to get a reference to the + function declaration, which you can do by using MkAdd and getting a reference to its function declaration with .FuncDecl:
Context z3 = new Context();
Sort twoInt = z3.MkTupleSort(z3.MkSymbol("twoInt"), new Symbol[] { z3.MkSymbol("a"), z3.MkSymbol("b") }, new Sort[] { z3.IntSort, z3.IntSort });
Sort A = z3.MkArraySort(twoInt, z3.IntSort);
ArrayExpr x = z3.MkArrayConst("x", twoInt, z3.IntSort);
ArrayExpr y = z3.MkArrayConst("y", twoInt, z3.IntSort);
ArrayExpr map = z3.MkMap(z3.MkAdd(z3.MkIntConst("a"), z3.MkIntConst("b")).FuncDecl, x, y);

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)

Resources