私は部分文字列について推論するためにZ3を使用しようとしており、非直感的な振る舞いに遭遇しました。 Z3は、 'xy'が 'xy'内に現れるかどうかを尋ねられたとき 'sat'を返しますが、 'x'が 'x'であるか 'x'が 'xy'であるかを尋ねられたら 'unknown'を返します。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 Webサイトで利用可能)を使用してみましたが、これらのすべてが上記のクエリで返されました。ありがとう、レオ。 –
コメントをいただきありがとうございます、レオ、あなたは私が質問から何かを残したことに気づきました。私が経験していた振る舞いは、同じアサーションセット内でさまざまな実験を試みるために使用していた 'push'コマンドと' pop'コマンドの間に最終的なアサーションとチェック - 私はそれに応じて問題を修正しましたが、問題はスコープで表示されているようです。 'push'と' pop'が省略されていれば正しいと思いますが、すべての場合に 'sat'が返されます。 – Katie
あなたはこれを探しているかもしれません:https://www.cs.purdue.edu/homes/zheng16/str/ – user