[英]Z3 switching between unknown/unsat by just changing the range sort of array
使用 Z3 時,我面臨一個奇怪的結果。 考慮用 smt-lib 編寫的這兩個基准:
(declare-fun a () (Array (_ BitVec 32) (_ BitVec 32)))
(declare-fun b () (Array (_ BitVec 32) (_ BitVec 32)))
(assert (forall ((fqv (Array (_ BitVec 32) (_ BitVec 8))))
(= (select a
(concat (select fqv #x00000003)
(concat (select fqv #x00000002)
(concat (select fqv #x00000001)
(select fqv #x00000000)))))
(select b
(concat (select fqv #x00000003)
(concat (select fqv #x00000002)
(concat (select fqv #x00000001)
(select fqv #x00000000))))))))
(assert (= false (= (select a #x00000000) (select b #x00000000))))
(check-sat)
(get-model)
和
(declare-fun a () (Array (_ BitVec 32) (_ BitVec 8)))
(declare-fun b () (Array (_ BitVec 32) (_ BitVec 8)))
(assert (forall ((fqv (Array (_ BitVec 32) (_ BitVec 8))))
(= (select a
(concat (select fqv #x00000003)
(concat (select fqv #x00000002)
(concat (select fqv #x00000001)
(select fqv #x00000000)))))
(select b
(concat (select fqv #x00000003)
(concat (select fqv #x00000002)
(concat (select fqv #x00000001)
(select fqv #x00000000))))))))
(assert (= false (= (select a #x00000000) (select b #x00000000))))
(check-sat)
(get-model)
他們唯一的區別是在a
和b
的范圍內。 在第一種情況下,它是一個大小為 32 的位向量。而在第二種情況下,它是一個大小為 8 的位向量。
有趣的部分是(check-sat)
在第一種情況下返回unsat
,而在第二種情況下返回unknown
。
對此有解釋嗎? 這是一個可以快速運行此實驗的鏈接: https://people.csail.mit.edu/cpitcla/z3.wasm/z3.html
這看起來確實很奇怪。 無論如何,我都希望您會變得unknown
,因為您有一個范圍在數組上的量化斷言。
最可能的原因是有一些“內部”啟發式方法在第一種情況下起作用,但在第二種情況下卻沒有這樣做。 (所以,從某種意義上說,你對第一個“幸運”,第二個是給定量化斷言的預期行為。)
請在https://github.com/Z3Prover/z3/issues報告此問題。 盡管這不是嚴格意義上的錯誤,但我相信開發人員會很高興看到可以改進內部啟發式以處理這兩種情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.