Getting concrete values from a model containing "array-ext" - z3

When I combine arrays and quantifiers, Z3 often produces models containing applications of array-ext. For example, this test case produces the following model:
(define-fun pipeid () (Array Int Int)
(_ as-array k!2))
(define-fun valid () (Array Int Bool)
(_ as-array k!0))
(define-fun ispipe () (Array Int Bool)
(_ as-array k!1))
(define-fun pipeid_ab () Int
2)
(define-fun fd () Int
0)
(define-fun k!3 ((x!1 Int)) Int
(ite (= x!1 0) 0
(array-ext (_ as-array k!0) (_ as-array k!1))))
(define-fun k!0!4 ((x!1 Int)) Bool
(ite (= x!1 3) false
true))
(define-fun k!0 ((x!1 Int)) Bool
(k!0!4 (k!3 x!1)))
(define-fun k!1 ((x!1 Int)) Bool
true)
(define-fun k!2!5 ((x!1 Int)) Int
(ite (= x!1 3) 4
1))
(define-fun k!2 ((x!1 Int)) Int
(k!2!5 (k!3 x!1)))
First, what does the array-ext in k!3 mean? I've pieced together that (array-ext a b) is some index x for which a[x] != b[x], but either what I've pieced together is incorrect or I can't wrap my head around the circular definitions of k!0 and k!3 above.
Second, how can I extract concrete values from such models? I know that it's not in general possible to represent the concrete value of an array directly in the model, but I would like to at least understand what its concrete value is and be able to extract it in some form from the model. Even querying for individual array indices doesn't seem to help:
model.evaluate(pipeid[1]) => If(array-ext(as-array, as-array) = 3, 4, 1)
Thanks.

array-ext is an internal function symbol. It is used to implement array extensionality.
That being said, it should not appear in models. The model-based-quantifier-instantiation (MBQI) module accidentally "leaks" the array-ext into the model. I fixed the problem.
http://z3.codeplex.com/SourceControl/changeset/185f125f7a3d356192df272bfb2339ad36d3cdf9
The fix is already available in the unstable (work-in-progress) branch.
It will also be available in the nightly builds.
Here is the output after the bug fix:
(define-fun pipeid () (Array Int Int)
(_ as-array k!2))
(define-fun valid () (Array Int Bool)
(_ as-array k!0))
(define-fun ispipe () (Array Int Bool)
(_ as-array k!1))
(define-fun pipeid_ab () Int
2)
(define-fun fd () Int
0)
(define-fun k!3 ((x!1 Int)) Int
0)
(define-fun k!0!4 ((x!1 Int)) Bool
(ite (= x!1 3) false
true))
(define-fun k!0 ((x!1 Int)) Bool
(k!0!4 (k!3 x!1)))
(define-fun k!1 ((x!1 Int)) Bool
true)
(define-fun k!2!5 ((x!1 Int)) Int
(ite (= x!1 3) 4
1))
(define-fun k!2 ((x!1 Int)) Int
(k!2!5 (k!3 x!1)))
pipeid[0] => 1
pipeid[1] => 1

Related

Z3 Output of get-value

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.

How to extract from a bit-vector using parameters with "Int" datatype?

Is there any efficient way to extract the bit number i from a bit-vector, while i has Int datatype? In other words, is there any efficient smt script that can do what the following script does?
(declare-fun int-index () Int)
(assert (and (>= int-index 0) (<= int-index 21)))
(declare-fun bv1 () (_ BitVec 22))
(define-fun getbit ((x (_ BitVec 22)) (bv-index (_ BitVec 22))) (_ BitVec 1)
((_ extract 0 0) (bvlshr x bv-index)))
(assert (= #b1 (getbit bv1 ((_ int2bv 22) int-index))))
(check-sat-using (! smt :bv.enable_int2bv true) :print_model true)
Thank you in advance.
Not really, you need to create a "big" if-then-else term that does case analysis on bv-index and then uses the (_ extract index index) function, where
"index" has to be a constant.

Defining Set in z3

To create a Sets of 3 elements (1,2,3) in Z3, I am using the follows code:
(define-sort Set () ( Array Int Bool ) )
(declare-const s Set )
( assert ( and ( = ( select s 1 ) true ) ( = ( select s 2 ) true )
( = ( select s 3 ) true ) ) )
The Model I am getting is as follows :
(model
(define-fun s () (Array Int Bool)
(_ as-array k!0))
(define-fun k!0 ((x!1 Int)) Bool
(ite (= x!1 2) true
(ite (= x!1 3) true
(ite (= x!1 1) true
true))))
)
But instead how can I get a model of the form :
(model (define-fun s () (Array Int Bool)
(_ as-array k!0)) (define-fun k!0 ((x!1 Int)) Bool
(ite (= x!1 2) true
(ite (= x!1 3) true
(ite (= x!1 1) true
false)))) )
So that elements other than the set members are not included in the set.
You can achieve this by starting from the empty set, i.e. the array that is defined to be false everywhere.
Here is an example:
(declare-const s1 (Array Int Bool))
(assert (= s1
(store
(store
(store
((as const (Array Int Bool)) false)
1 true)
2 true)
3 true)
))
(check-sat)
(get-model)

Simplifying uninterpreted functions in Z3

Is there any way to apply simplifications to uninterpreted functions defined in z3, rather than the goals and subgoals ?
I have the following z3 code :
(declare-fun f (Bool Bool) Bool)
(assert (forall ((b1 Bool) (b2 Bool))
(implies b2 (f b1 b2))))
(assert (exists ((b1 Bool) (b2 Bool))
(not (f b1 b2))))
(check-sat)
(get-model)
And I get the following output:
sat
(model
(define-fun b1!1 () Bool
false)
(define-fun b2!0 () Bool
false)
(define-fun k!7 ((x!1 Bool)) Bool
false)
(define-fun f!8 ((x!1 Bool) (x!2 Bool)) Bool
(ite (and (= x!1 false) (= x!2 true)) true
false))
(define-fun k!6 ((x!1 Bool)) Bool
(ite (= x!1 false) false
true))
(define-fun f ((x!1 Bool) (x!2 Bool)) Bool
(f!8 (k!7 x!1) (k!6 x!2)))
)
It turns out that by applying rewrite rules to the definition of f, we can get that
f is equal to the second argument (x!2) by the following derivation:
(f!8 (k!7 x!1) (k!6 x!2))
= (f!8 false (k!6 x!2))
= (f!8 false x!2)
=(x!2)
Is there any way to get z3 to produce the following definition automatically ?
(define-fun f ((x!1 Bool) (x!2 Bool)) Bool
(x!2))
Thanks for your help.
Regards,
Oswaldo.
One option is to ask Z3 to evaluate the expression (f x y) where x and y are fresh Boolean constants. The eval command will evaluated (f x y) in the current model, and will produce y in your example. Here is the complete example (also available online here):
(declare-fun f (Bool Bool) Bool)
; x and y are free Boolean constants that will be used to create the expression (f x y)
(declare-const x Bool)
(declare-const y Bool)
(assert (forall ((b1 Bool) (b2 Bool))
(implies b2 (f b1 b2))))
(assert (exists ((b1 Bool) (b2 Bool))
(not (f b1 b2))))
(check-sat)
(eval (f x y))

soundness issue with integer/bv mixed benchmarks?

I've the following SMT-Lib2 script:
(set-option :produce-models true)
(declare-fun s0 () Int)
(declare-fun table0 (Int) (_ BitVec 8))
(assert (= (table0 0) #x00))
(assert
(let ((s3 (ite (or (< s0 0) (<= 1 s0)) #x01 (table0 s0))))
(let ((s5 (ite (bvuge s3 #x02) #b1 #b0)))
(= s5 #b1))))
(check-sat)
(get-model)
With Z3 v3.2 running on the Mac, I get:
sat
(model
;; universe for (_ BitVec 8):
;; bv!val!2 bv!val!3 bv!val!0 bv!val!1
;; -----------
;; definitions for universe elements:
(declare-fun bv!val!2 () (_ BitVec 8))
(declare-fun bv!val!3 () (_ BitVec 8))
(declare-fun bv!val!0 () (_ BitVec 8))
(declare-fun bv!val!1 () (_ BitVec 8))
;; cardinality constraint:
(forall ((x (_ BitVec 8)))
(and (= x bv!val!2) (= x bv!val!3) (= x bv!val!0) (= x bv!val!1)))
;; -----------
(define-fun s0 () Int
(- 1))
(define-fun table0 ((x!1 Int)) (_ BitVec 8)
(ite (= x!1 0) bv!val!0
(ite (= x!1 (- 1)) bv!val!3
bv!val!0)))
)
Which states that s0 = -1 is a model. However, with s0 = -1, we have s3 = 1 and s5 = #b0, which makes the assertion false. In fact, I'm quite sure the benchmark as stated is unsatisfiable.
One thing I noticed in the Z3 output is the quantified formula it gives for the cardinality constraint. It says:
;; cardinality constraint:
(forall ((x (_ BitVec 8)))
(and (= x bv!val!2) (= x bv!val!3) (= x bv!val!0) (= x bv!val!1)))
The assertion is a conjunction, which sounds rather weird; shouldn't that be a disjunction? I'm not sure if this is the root-cause of the problem, but it sure sounds fishy.
There are two problems in Z3.
First, you are correct, there is a typo in the model printer. It should be a "or" instead of an "and". The second problem is that Z3 did not install the bit-vector theory and treated (_ BitVec 8) as a uninterpreted sort. This was a bug in the preprocessor that is used to decide in which logic the problem is in. You can workaround this bug by adding the following command in the beginning of the file:
(set-option :auto-config false)
These bugs have been fixed, and the fix will be available in the next release.

Resources