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))
)
Related
I want to capture the assertion inside fac.
int f( x )
{
if( x == 1) return 1;
else{
assert( x > 0 );
return 2;
}
}
int g (x)
{ assert( x > 5 );
return f(x-1) + f(x-2);
}
I want an smt2 code for this.
I can do this by striping the argument and making it global with unique name (also rename inside f), then do this 3 times each with a different name for function. Like below :
( declare-const x1 Int )
(define-fun f1 () Int
( ite ( x1 > 0) 1 2 )
)
(assert (> x1 0))
( declare-const x2 Int )
(define-fun f2 () Int
( ite ( x2 > 0) 1 2 )
)
(assert (> x2 0))
( declare-const x3 Int )
(define-fun g1 () Int
( + f1 f2 )
)
(assert (> x3 5))
I don't want to this. Is there any other way to do this without repeating ?
EDIT
My purpose is to find values violating the asserts.
As far as I know, it is not possible to embed assertions within function definitions.
What I would try to do is to separate the expected behavior, the input assumptions and the output guarantees (if any).
Example:
(define-fun f ((x Int)) Int
(ite (= x 1) 1 2)
)
(define-fun f-helper ((x Int)) Bool
(< 0 x)
)
(define-fun g ((x Int)) Int
(+ (f (- x 1)) (f (- x 2)))
)
(define-fun g-helper ((x Int)) Bool
(and (< 5 x)
(f-helper (- x 1))
(f-helper (- x 2))
)
)
(declare-const x Int)
(declare-const y Int)
(assert (and (= y (g x))
(g-helper x)
))
(check-sat)
(get-model)
In this example we use f to model the behavior of the original function f, and f-helper to model the assumptions of f. The output, using the online Z3 tool, is as follows:
sat
(model
(define-fun x () Int
6)
(define-fun y () Int
4)
)
I would conclude saying that this approach could become tricky as soon as f and g are used inside both positive and negative contexts.. in this case one should pay extra attention that the polarity of the assertions is correct wrt. the expected result.
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.
The following z3 code picks elements from {x1..x6} in order to maximize the total weight, while satisfying total length less than 10.
(declare-datatypes () ((Item (mk-item (size Int) (weight Int)))))
(define-fun ee () Item (mk-item 0 0)); empty item
(define-fun i1 () Item (mk-item 4 2))
(define-fun i2 () Item (mk-item 4 2))
(define-fun i3 () Item (mk-item 1 4))
(define-fun i4 () Item (mk-item 5 5))
(define-fun i5 () Item (mk-item 3 2))
(define-fun i6 () Item (mk-item 1 9))
(define-fun x_props ((x Bool) (i Item)) Item (ite x i ee))
; each x defines whether an item is selected or not
(declare-const x1 Bool)
(declare-const x2 Bool)
(declare-const x3 Bool)
(declare-const x4 Bool)
(declare-const x5 Bool)
(declare-const x6 Bool)
(define-fun total_size () Int
(+
(size (x_props x1 i1))
(size (x_props x2 i2))
(size (x_props x3 i3))
(size (x_props x4 i4))
(size (x_props x5 i5))
(size (x_props x6 i6))
))
(define-fun total_weight () Int
(+
(weight (x_props x1 i1))
(weight (x_props x2 i2))
(weight (x_props x3 i3))
(weight (x_props x4 i4))
(weight (x_props x5 i5))
(weight (x_props x6 i6))
))
(assert (< total_size 10))
(maximize total_weight)
(check-sat)
(get-model)
However, I can imagine this scaling very bad as the number of item properties explode, and the number of items as well.
Would there be a different, more concise approach? In particular, can you think of a way to factorize the total_size and total_weight functions, as there is a lot of repetition there?
There's really nothing wrong with your encoding. Since you need to sum through a number of elements, the only way to do that is either being explicit about them, or use a recursive function. While SMT-Lib and Z3 both support recursive-functions, the implementation isn't quite strong yet, and you'd better stick to the explicit style.
The issue here is really trying to use SMT-Lib as a programming language, which it was not really intended for. I'd recommend looking into high-level language interfaces instead, such as those from Python, Scala, or Haskell; which would take care of the repetitive coding. Here's a good site for describing how to do model such things in Python: https://ericpony.github.io/z3py-tutorial/guide-examples.htm and here's an example of a similar problem in Haskell: https://hackage.haskell.org/package/sbv-7.4/docs/src/Data.SBV.Examples.Optimization.VM.html
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)