我有兴趣证明关于某些假设的陈述的有效性。然而,Z3 似乎默认采用“开放”模型。例如,假设我们假设
富(4)
关于这个陈述,我想表明“在” foo 中的东西是均匀的。所以我首先声明 foo
(declare-fun foo (Int) Bool)
接下来,因为我对假设很感兴趣。我构建了一个含义:
(implies (foo 4) (not (exists ((x Int)) (and (foo x) (not (= (mod x 2) 0))))))
最后,因为我对有效性感兴趣,而不是可满足性,所以我想检查这个陈述的否定的不可满足性。
(assert (not (implies (foo 4) (not (exists ((x Int)) (and (foo x) (not (= (mod x 2) 0))))))))
(check-sat)
不过 Z3 报道称,这个说法确实是可以满足的:
sat
(model
(define-fun x!0 () Int
(- 1))
(define-fun foo ((x!1 Int)) Bool
(ite (= x!1 4) true
(ite (= x!1 (- 1)) true
true)))
)
我大致了解这里发生了什么,但我不确定如何最好地表达 foo 在我的假设陈述下应该“关闭”。对于这个非常简单的示例,我可以通过告诉 Z3 foo 没有其他成员来做到这一点:
(assert (not (implies (and (foo 4) (not (exists ((x Int)) (and (not (= x 4)) (foo x))))) (not (exists ((x Int)) (and (foo x) (not (= (mod x 2) 0))))))))
然而,当我转向更复杂的假设时,似乎很难自动生成公式来定义那些不在 foo 中的东西。
我错过了什么愚蠢的东西吗?