Z3 使用unsat消除forall
我们知道,我们可以通过这样来证明一个定理的有效性:Z3 使用unsat消除forall,z3,Z3,我们知道,我们可以通过这样来证明一个定理的有效性: let Demorgan(x, y) = formula1(x,y) iff formula2(x,y) assert ( forall (x,y) . Demorgan(x,y) ) 或者,我们可以通过这样说来消除forall量词: let Demorgan(x, y) = formula1(x,y) iff formula2(x,y) ( assert (not Demorgan(x,y) ) ) 如果它返回unsat,那么我们可以说
let Demorgan(x, y) = formula1(x,y) iff formula2(x,y)
assert ( forall (x,y) . Demorgan(x,y) )
或者,我们可以通过这样说来消除forall量词:
let Demorgan(x, y) = formula1(x,y) iff formula2(x,y)
( assert (not Demorgan(x,y) ) )
如果它返回unsat,那么我们可以说上面的公式是有效的
现在,我想用这个想法从以下断言中删除forall量词:
assert ( exists x1,x2,x3 st .( forall y . formula1(x1,y) iff
formula2(x2,y) iff
formula3(x3,y) ) )
在Z3(使用C++ API或SMT-LIB2.0)中,我有什么方法可以断言如下:
assert (exists x1,x2,x3 st. ( and ((not ( formula1(x1,y) iff formula2(x2,y) )) == unsat)
((not ( formula2(x2,y) iff formula3(x3,y) )) == unsat)))
是的,当我们可以证明一个公式的有效性,证明它的否定是不可满足的。 例如,为了证明
Forall X.F(X)
是有效的,我们只需要证明not(Forall X.F(X))
是不可满足的。公式not(对于所有X.F(X))
等同于(Exists X.not F(X))
。公式(存在X。非F(X))
与公式非F(X)
相等,其中绑定变量X
被新常数X
替换。所谓公平可满足,我的意思是第一个是可满足的,如果第二个是。这个删除存在量词的步骤通常称为。
请注意,后两个公式不等价。
例如,考虑解释<代码> {x> 2 } <代码>,将<代码> x <代码>分配给<代码> 2 < /代码>。公式存在X。not(X=2)
在此解释中仍然计算为true,因为我们可以选择X
作为3
。另一方面,公式not(X=2)
在此解释中计算为false。
对于给定公式F
生成等效的无量词公式F'
的过程,我们通常使用术语量词消除过程。因此,skolemization不被视为量词消除程序,因为其结果不是等效公式
也就是说,我们不必一步一步地应用skolemization。Z3可以为我们做这件事。以下是一个示例(也可在线获取)
现在,让我们考虑一个公式<代码>存在x.fALL y.f(x,y)< /COD>。为了证明这个公式的有效性,我们可以证明否定
不存在,因为所有的Y.F(X,Y)
都是不可满足的。对于所有X.存在Y.而不是F(X,Y),该否定等价于。现在,如果对这个公式应用skolemization,我们得到所有X的,而不是F(X,Y(X))
。在这种情况下,绑定变量Y
被替换为Y(X)
,其中Y
是结果公式中的新函数符号。直觉是函数Y
是“选择函数”。对于每个X
,我们可以选择不同的值来满足公式F
。Z3为我们自动执行所有这些步骤。我们不需要手动应用skolemization。然而,在这种情况下,结果公式通常更难求解,因为它在skolemization步骤后包含一个通用量词
(declare-sort S)
(declare-fun F (S) Bool)
(declare-fun G (S) Bool)
(define-fun Conjecture () Bool
(forall ((x S)) (= (and (F x) (G x)) (not (or (not (F x)) (not (G x)))))))
(assert (not Conjecture))
(check-sat)