[英]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.