我正在嘗試使用Z3來推理子串,並且遇到了一些非直觀的行爲。當詢問確定'xy'是否出現在'xy'內時,Z3返回'sat',但當詢問'x'是'x'還是'x'是'xy'時,返回'未知'。Z3可以用來推斷子串嗎?
我的評論下面的代碼來說明這個問題:
(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))
現在的問題是建立,我們試圖找到字符串:
;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)
如果我們不是搜索findMeXY
在xy
,解決方案返回'sat',正如所料。看起來,由於求解器可以處理'xy'這個查詢,所以它應該能夠處理'x'。此外,如果在'xy='xy'
中搜索findMeX='x'
,則返回「未知」。
任何人都可以提出一個解釋,或者可能是在SMT解決方案中表達這個問題的替代模型?
我試圖重現您沒有成功所描述的問題。您使用的是哪個版本的Z3?我嘗試使用Z3 2.19(Windows和Linux)以及Z3 3.0(可在SMT-COMP網站上獲得),並且所有人都返回上面的查詢。謝謝,獅子座。 –
謝謝你的評論,Leo,你讓我意識到我留下了一些不可能的東西。看起來,我所經歷的行爲只發生在最後的斷言和check-sat出現在'push'和'pop'命令之間,我一直用這些命令在同一組斷言中嘗試各種實驗。我已經相應地修改了這個問題,但現在看來問題在於範圍界定。如果'push'和'pop'被遺漏了,那麼你是對的,'sat'會在所有情況下返回。 – Katie
您是否可能正在尋找:https://www.cs.purdue.edu/homes/zheng16/str/ – user