我想自动证明以下有关任意大小整数的陈述:
forall base a b c d,
0 <= a < base ->
0 <= b < base ->
0 <= c < base ->
0 <= d < base ->
base * a + b = base * c + d ->
b = d
这应等同于以下说法为unsat
(假设生成此内容的crazy hacks是正确的):
(declare-const a Int)
(declare-const a0 Int)
(declare-const a1 Int)
(declare-const a2 Int)
(declare-const a3 Int)
(assert (not (or (not (and (<= 0 a0) (< a0 a)))
(or (not (and (<= 0 a1) (< a1 a)))
(or (not (and (<= 0 a2) (< a2 a)))
(or (not (and (<= 0 a3) (< a3 a)))
(or (not (= (+ ( * a a0) a1)
(+ ( * a a2) a3)))
(= a1 a3))))))))
(check-sat)
如果我将其输入Z3,即使看起来很简单,它也会返回unknown
。
所以我的问题是:自动证明这一点的正确方法是什么? Z3是否有配置选项可以使它工作?我应该进行其他预处理吗?还是这个问题属于Z3的“专业领域”之外的一类问题,我应该使用其他工具吗?
更新:这是同一查询的可读性更高的版本,使用(implies A B)
而不是(or (not A) B)
:
(declare-const a Int)
(declare-const a0 Int)
(declare-const a1 Int)
(declare-const a2 Int)
(declare-const a3 Int)
(assert (not (implies (and (<= 0 a0) (< a0 a))
(implies (and (<= 0 a1) (< a1 a))
(implies (and (<= 0 a2) (< a2 a))
(implies (and (<= 0 a3) (< a3 a))
(implies (= (+ ( * a a0) a1) (+ ( * a a2) a3)) (= a1 a3))))))))
(check-sat)
答案 0 :(得分:1)
由于您要进行乘法运算,因此问题是非线性的; SMT求解器通常无法处理非线性算法。 (Z3具有非线性推理引擎,但是由于不确定性,它肯定不能解决任意问题。)
如果您将base
设置为给定的值,那么z3
可以很轻松地解决您的问题。例如,添加:
(assert (= a 10))
使z3立即响应unsat
。
输入看起来也不必要地复杂;请记住,SMTLib具有隐含运算符,您可以只编写(or (not X) Y)
而不是(implies X Y)
来编写代码。