SMT公式中的隐式与显式存在量化

时间:2016-02-09 09:56:45

标签: z3 smt z3py

给出以下代码:

from z3 import *
a,b,c = BitVecs('a b c', 32)
f1 = Exists([a, b, c], And(a + b == c, a < b, c == 1337))
f2 = And(a + b == c, a < b, c == 1337)
prove(f1 == f2)

在本例中,我假设z3隐式存在量化abc。为什么两个公式不相等,有什么区别?

1 个答案:

答案 0 :(得分:1)

您制定查询的方式并未真正检查f1是否等于f2。您的查询实际上是要求求解程序找到a, b, c,以便以下内容无法保留:

      Exists([a, b, c], And(a + b == c, a < b, c == 1337))
              =          
      And(a + b == c, a < b, c == 1337))

实际上,您可以实例化外部abc,以便右侧是假的;但左手边是一个真实的存在主义;因此,你所要求的等同性失败了。

通过一个更简单的例子可能更容易看到这一点;只有一个布尔变量。你基本上是在问:

     x == (Exists [x], x)

您看到那些x实际上是不同的,因此我们可以将内部重命名为(例如)y;我们得到:

      x == (Exist [y]. y)

现在,右侧显然是正确的,因为y使(Exist [y]. y)成立。所以,你基本上要求证明者确定无论你选择什么x,都是如此。当你选择x为假时,绝对不是这种情况。

事实上,您可以要求Z3为您提供它试图证明的公式,这就是它为您的原始查询返回的内容:

(set-info :status unknown)
(declare-fun c () (_ BitVec 32))
(declare-fun b () (_ BitVec 32))
(declare-fun a () (_ BitVec 32))
(assert
 (let (($x24 (exists ((a (_ BitVec 32)) 
                      (b (_ BitVec 32)) 
                      (c (_ BitVec 32)) )
      (and (= (bvadd a b) c) (bvslt a b) (= c (_ bv1337 32))))))
 (let (($x57 (= $x24 (and (= (bvadd a b) c) (bvslt a b) (= c (_ bv1337 32))))))
(and $x57))))
(check-sat)

通过上述推理,这显然是可以满足的。

(有关将z3-python查询转换为smt-lib的代码,请参阅Z3: convert Z3py expression to SMT-LIB2 from Solver object。)