0mer
0mer

Reputation: 45

Arrays and Quantifier

I'm trying to use array and quantifier in Z3 in order to find substring in a given text.

My code is the following:

(declare-const a (Array Int Int))
(declare-const x Int)

;; a|A
(assert (or (= (select a 0) 61) (= (select a 0) 41)))
;; b|B
(assert (or (= (select a 1) 62) (= (select a 1) 42)))
;; c|C
(assert (or (= (select a 2) 63) (= (select a 2) 43)))

(assert (>= x 0))
(assert (< x 3))

(assert (exists ((i Int)) (= (select a i) 72) ))
(check-sat)

Z3 say that is SAT when it shouldn't be. I'm rather new to Z3 and SMT theory, and I'm not able to figure out what is wrong with my code.

Upvotes: 4

Views: 539

Answers (1)

Taylor T. Johnson
Taylor T. Johnson

Reputation: 2884

In your example, it is actually satisfiable by taking i to be any natural number outside the range 0, 1, 2. So, if you let i = 3 for example, since you have not constrained the array at index 3 in any way, it is possible that a[3] is 72.

Here is a link showing the satisfying assignment (model) to your example at the Z3@Rise interface, along with the fix described next: http://rise4fun.com/Z3/E6YI

To prevent this from occurring, one way is to restrict the range of i to be one of the array indices you've already assigned. That is, restrict i to be between 0 and 2.

(declare-const a (Array Int Int))
(declare-const x Int)

;; a|A
(assert (or (= (select a 0) 61) (= (select a 0) 41)))
;; b|B
(assert (or (= (select a 1) 62) (= (select a 1) 42)))
;; c|C
(assert (or (= (select a 2) 63) (= (select a 2) 43)))

(assert (>= x 0))
(assert (< x 3))

(assert (exists ((i Int)) (= (select a i) 72)))
(check-sat)
(get-model) ; model gives i == 3 with a[i] == 72

(assert (exists ((i Int)) (and (>= i 0) (<= i 2) (= (select a i) 72) )))
(check-sat)

Upvotes: 2

Related Questions