I am trying to use Z3 to talk about substrings, and have come across some unintuitive behavior. Z3 returns βsatβ when asked to determine if βxyβ appears inside βxyβ, but it returns βunknownβ when asked if βxβ is in βxβ or βxβ is in βxyβ "
I commented on the following code to illustrate this behavior:
(set-logic AUFLIA) (declare-sort Char 0) ;characters to build strings are _x_ and _y_ (declare-fun _x_ () Char) (declare-fun _y_ () Char) (assert (distinct _x_ _y_)) ;string literals (declare-fun findMeX () (Array Int Char)) (declare-fun findMeXY () (Array Int Char)) (declare-fun x () (Array Int Char)) (declare-fun xy () (Array Int Char)) (declare-fun length ( (Array Int Char) ) Int ) ;set findMeX = 'x' (assert (= (select findMeX 0) _x_)) (assert (= (length findMeX) 1)) ;set findMeXY = 'xy' (assert (= (select findMeXY 0) _x_)) (assert (= (select findMeXY 1) _y_)) (assert (= (length findMeXY) 2)) ;set x = 'x' (assert (= (select x 0) _x_)) (assert (= (length x) 1)) ;set xy = 'xy' (assert (= (select xy 0) _x_)) (assert (= (select xy 1) _y_)) (assert (= (length xy) 2))
Now that the problem is configured, we are trying to find the substrings:
;search for findMeX='x' in x='x' (push 1) (assert (exists ((offset Int)) (and (<= offset (- (length x) (length findMeX))) (>= offset 0) (forall ((index Int)) (=> (and (< index (length findMeX)) (>= index 0)) (= (select x (+ index offset)) (select findMeX index))))))) (check-sat) ;'sat' expected, 'unknown' returned (pop 1)
If instead search findMeXY in xy , then the solver returns 'sat', as expected. It would seem that since the solver can process this request for "xy", it should be able to process it for "x". Also, when searching for findMeX='x' in 'xy='xy' it returns "unknown".
Can someone suggest an explanation, or perhaps an alternative model for expressing this problem in the SMT solver?
smt z3
Katie
source share