I tried around a some time to get a rather simple requirement done:
I declared a new datatype
(declare-datatypes () ((A (mk_A (key Int) (var1 Int) (var2 Int)))))
where key should act like a primary key in a database, i.e., each different instance of A should have a different key value.
The container of the different instances (functions) looks like the following:
(declare-const A_instances (Array Int A))
So far so good. I tried to create an assertion, such that all instances in A_instances have a different key field. Thus, for each index i in A_instances (key (select A_instances i)) should be distinct. However it returns unknown.
Someone has any suggestions?
One possible solution is
(declare-datatypes () ((A (mk_A (key Int) (var1 Int) (var2 Int)))))
(declare-const A_instances (Array Int A))
(declare-fun j () Int)
(assert (forall ((i Int)) (implies (distinct i j)
(distinct (key (select A_instances i))
(key (select A_instances j))) ) ))
(check-sat)
and the corresponding output is
sat
Related
Suppose I have a Sort T and I declare an array indexed by T, what is the sort of mapping over it?
e.g
(declare-datatypes ()
((T ....))) ; some index, may be finite or infinite (as in Int)
(declare-const a (Array T Int))
(declare-const b (Array Int Int))
(define-fun foo ((x Int)) Int)
(define-fun bar ((y Int)) Bool)
What is the sort of mapping foo on a? And the sort of mapping foo on b? Is there any way to mess up with the indexes type and obtain from an array indexed by T an array indexed by another sort, say e.g. Int?
Usual sort-matching rules apply. That is, to map a function f : A -> B on an array, the array must have its range type A, and it'll turn it into a B, preserving the type of its domain.
Regarding your example: Regardless of what your T is, you'll simply have Array T Int as the final sort if you map foo, and Array T Bool as the result if you map bar. The following script type-checks without any issues:
(declare-datatypes ((T 0)) ((i Int)))
(declare-const a (Array T Int))
(declare-const b (Array Int Int))
(declare-fun foo (Int) Int)
(declare-fun bar (Int) Bool)
(define-fun e1 () (Array T Int) ((_ map foo) a))
(define-fun e2 () (Array T Bool) ((_ map bar) a))
(define-fun e3 () (Array Int Int) ((_ map foo) b))
(define-fun e4 () (Array Int Bool) ((_ map bar) b))
Note that you cannot change the type of the domain (which is what you mean by index I presume) by mapping a function over an array. It only changes the range type.
In z3, one can declare a fully-uninterpreted const like so:
(declare-const x Int)
Similarly, one can define a fully-interpreted one like this:
(define-fun y () Int 3)
; y == 3
Given an algebraic datatype, one can have a fully interpreted tuple like the following:
(declare-datatypes () ((Item (mk-item (size Int) (weight Int)))))
(define-fun z () Item (mk-item 3 4))
; z == Item(size=3, weight=4)
... Or a non-interpreted one like below:
(declare-const i1 (Item Int Int))
Now is it possible to have a partially-interpreted data type, so that, based on the previous example, weight would be fixed for each item and size could vary?
; (bad syntax, but I hope you get the idea)
; in this case the size is varying, but weight is fixed to 5
(declare-const i2 (Item Int 5))
You should simply declare it with declare-fun and assert an equality for the portions that you know:
(declare-datatypes () ((Item (mk-item (size Int) (weight Int)))))
(declare-fun x () Item)
(assert (= (weight x) 5))
(check-sat)
(get-model)
This produces:
sat
(model
(define-fun x () Item
(mk-item 0 5))
)
I have a problem with the generation of model values through get-value.
If I try to get the value of an array, I will get a value
containing internal z3 constants which are not printed. I know that
get-model would print those constants but I would like to stick
to using get-value.
Here is an example (I tried it on rise4fun):
(declare-const b (Array Int Int))
(declare-const a (Array Int Int))
(assert (= (store a 1 2) b))
(check-sat)
(get-value (b a))
returns:
sat ((b (_ as-array k!1)) (a (_ as-array k!0)))
The output with get-model is the following:
sat (model (define-fun b () (Array Int Int) (_ as-array k!1)) (define-fun a () (Array Int Int) (_ as-array k!0)) (define-fun k!0 ((x!1 Int)) Int 0) (define-fun k!1 ((x!1 Int)) Int (ite (= x!1 1) 2 0)) )
It contains the value of k!0 and k!1. Is it possible to substitute these in the values for a and b ?
This is a limitation with Z3's modeling of arrays.
get-value isn't guaranteed to give meaningful results for arrays.
I'm having some trouble using sorts in the SMTlib2 format. For example, I define an Interval as:
(declare-sort Pair 2)
(define-sort Interval () (Pair Int Int))
Now how can I return a new Interval from a function? e.g.:
(define-fun getInterval ((a Int) (b Int)) Interval
(Interval a b))
This doesn't work.
My question is: how can I construct and instantiate objects of a given sort, and how can I access their fields?
Right now I'm using 2 UFs that I created as field getters, but I still don't know how to have a constructor:
(declare-fun L (Interval) Int)
(declare-fun H (Interval) Int)
Thanks,
Nuno
You should look into Record subsection, Datatypes section in Z3 SMT guide. Basically, you can create a record type with a constructor mk-pair and two selectors first and second for accessing its fields.
Here is an examplerise4fun link:
(set-option :macro-finder true)
(declare-datatypes (T1 T2) ((Pair (mk-pair (first T1) (second T2)))))
(define-sort Interval () (Pair Int Int))
(define-fun getInterval ((a Int) (b Int)) Interval
(mk-pair a b))
(declare-const p1 Interval)
(declare-const p2 Interval)
;construct objects of a give sort
(assert (= p1 (getInterval 2 2)))
;accessing their fields
(assert (= (first p1) (second p2)))
(check-sat)
(get-model)
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)