简体   繁体   English

Z3 通过更改数组的范围排序在未知/未饱和之间切换

[英]Z3 switching between unknown/unsat by just changing the range sort of array

I am facing a weird result when using Z3.使用 Z3 时,我面临一个奇怪的结果。 Consider these two benchmarks written in smt-lib:考虑用 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)

and

(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)

Their only difference is in the range of a and b .他们唯一的区别是在ab的范围内。 In the first case, it is a bit-vector of size 32. While in the second case, it is a bit-vector of size 8.在第一种情况下,它是一个大小为 32 的位向量。而在第二种情况下,它是一个大小为 8 的位向量。

The interesting part is that (check-sat) is returning unsat for the first case, and unknown for the second one.有趣的部分是(check-sat)在第一种情况下返回unsat ,而在第二种情况下返回unknown

Is there an explanation for this?对此有解释吗? Here is a link where you can quickly run this experiment: https://people.csail.mit.edu/cpitcla/z3.wasm/z3.html这是一个可以快速运行此实验的链接: https://people.csail.mit.edu/cpitcla/z3.wasm/z3.html

This looks odd indeed.这看起来确实很奇怪。 I'd have expected you to get unknown regardless of which, since you have a quantified assert that ranges over an array.无论如何,我都希望您会变得unknown ,因为您有一个范围在数组上的量化断言。

The most likely reason is that there's some "internal" heuristic that kicks in for the first case, but fails to do so for the second.最可能的原因是有一些“内部”启发式方法在第一种情况下起作用,但在第二种情况下却没有这样做。 (So, in a sense, you're getting "lucky" for the first one, and the second one is the expected behavior given the quantified assert.) (所以,从某种意义上说,你对第一个“幸运”,第二个是给定量化断言的预期行为。)

Please report this at https://github.com/Z3Prover/z3/issues .请在https://github.com/Z3Prover/z3/issues报告此问题。 Even though this isn't strictly a bug, I'm sure the developers would appreciate taking a look to see what internal heuristic might be improved to handle both of these cases.尽管这不是严格意义上的错误,但我相信开发人员会很高兴看到可以改进内部启发式以处理这两种情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM