Question

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.

Was it helpful?

Solution

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)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top