【发布时间】:2012-11-02 15:20:14
【问题描述】:
我试图在微软的 SMT 求解器 Z3 中证明一个归纳事实。我知道 Z3 通常不提供此功能,如 Z3 guide(第 8 节:数据类型)中所述,但是当我们限制要证明事实的域时,这似乎是可能的。考虑以下示例:
(declare-fun p (Int) Bool)
(assert (p 0))
(assert (forall ((x Int))
(=>
(and (> x 0) (<= x 20))
(= (p (- x 1)) (p x) ))))
(assert (not (p 20)))
(check-sat)
求解器正确响应unsat,这意味着(p 20) 有效。问题是,当我们进一步放宽这个约束时(我们将前面示例中的20 替换为任何大于20 的整数),求解器会以unknown 响应。
我觉得这很奇怪,因为 Z3 解决最初的问题并不需要很长时间,但是当我们将上限增加 1 时,它突然变得不可能了。我试图向量词添加一个模式,如下所示:
(declare-fun p (Int) Bool)
(assert (p 0))
(assert (forall ((x Int))
(! (=>
(and (> x 0) (<= x 40))
(= (p (- x 1)) (p x) )) :pattern ((<= x 40)))))
(assert (not (p 40)))
(check-sat)
这似乎更好,但现在上限是 40。这是否意味着我最好不要使用 Z3 来证明这些事实,还是我的问题表述不正确?
【问题讨论】: