我有兴趣证明某些假设的陈述的有效性。但是,默认情况下,Z3似乎采用“开放”模式。例如,假设我们假设
foo(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中的东西。
我有什么傻事吗?
答案 0 :(得分:1)
当且仅当x = 4时,为什么不说(foo x)? 你的第一个声明说(在反编译否定之后):
(assert (foo 4))
(assert (exists ((x Int)) (and (foo x) (not (= (mod x 2) 0))))
将foo映射到' true'的函数foo满足了这一点, 并且可以使用x = -1来满足存在性断言。 这是标准的一阶语义。
说foo最满意4的一种方式是:
(assert (forall ((x Int)) (=> (foo x) (= x 4))))
你也可以说foo只保留在4:
(assert (forall ((x Int)) (= (foo x) (= x 4))))