有没有办法告诉Z3逻辑公理可能适用于某种情况? 例如,P(x)==> \ exists x P(x)始终有效。但如果P足够复杂,那么Z3可能会混淆并说出未知。
(declare-const size Int)
(declare-const h (Array Int Int))
(assert (forall ((j Int) (k Int)) (=> (and (<= 0 k) (< k size) (<= 0 j) (< j size) (not (= k j))) (not (= (select h j) (select h k))))))
(assert (not (exists ((g (Array Int Int))) (forall ((j Int) (k Int)) (=> (and (<= 0 k) (< k size) (<= 0 j) (< j size) (not (= k j))) (not (= (select g j) (select g k))))))))
(check-sat)
第一个断言说h是一个数组,它将不同的整数从0..size-1映射到不同的整数。而第二个断言说这样的阵列不可能存在。 可以简单有效的公理,如P(x)==&gt; \存在x P(x)是否在SMT文件中提供以帮助Z3?可能是我误解了这个例子中发生的事情。但根据我的有限理解,如果Z3实例化我提到的公理,Z3可能会证明公式是不可靠的。
答案 0 :(得分:1)
这似乎是一个触发问题,即Z3没有实例化存在量化的公理(也可能不是普遍量化的公理)。看看下面的简化示例:
(set-option :AUTO_CONFIG false)
(set-option :SMT.MBQI false)
(declare-fun f (Int) Bool)
(assert (forall ((x Int))
(=> (<= 0 x) (f x))
))
(assert (not (exists ((x Int))
(=> (<= 0 x) (f x))
)))
; (assert (f -10))
(check-sat)
Z3(版本4.3.2,64位,构建哈希码96f4606a7f2d)报告unknown
,但如果您取消注释最后一个断言,则报告unsat
。因此,我假设Z3推导出两个公理的模式是:pattern ((f x))
,这意味着f x
必须在公理实例化之前在语法上发生。
您可以在z3指南中阅读有关quantifier patterns的更多信息。