如果要分析的程序的语义是作为Horn子句给出的话,Z3现在支持求解归纳不变量(暗示所需的属性)。
z3.codeplex.com上Z3源代码的master
分支中的版本不支持此功能。由于Z3通过使用插值的PDR算法解决了这些Horn子句问题,因此编译了interp
分支(d8b31773b809
),它支持(set-logic HORN)
。
据我所知,Horn子句问题是用未知谓词表示不变量来指定的,而X×Y上的谓词只是从X×Y到Bool的函数。到目前为止一切都很好。
我尝试的第一个例子只是推断for(int i=0; i<=10; i++)
循环的归纳不变量的问题。
(set-logic HORN)
(declare-fun inv (Int) Bool)
(assert (inv 0))
(assert (forall ((I Int)) (or (> I 10) (not (inv I)) (inv (+ I 1)))))
(check-sat)
到目前为止一切顺利,得到sat
。现在刚刚添加了(assert (not (inv 15))
,我得到了unsat
。然后我尝试了
(set-logic HORN)
(declare-fun inv (Int) Bool)
(assert (inv 0))
(assert (not (inv 15)))
(check-sat)
得到unsat
。
我做错了什么?
答案 0 :(得分:2)
使用“不稳定”分支。 “interp”分支用于内部开发,并且该分支的状态可以波动。 我得到你的第二个问题“坐”的答案。
第一个问题的一个稍微有趣的版本是:
(set-logic HORN)
(declare-fun inv (Int) Bool)
(assert (inv 0))
(assert (forall ((I Int)) (or (> I 10) (not (inv I)) (inv (+ I 1)))))
(assert (forall ((I Int)) (=> (inv I) (<= I 11))))
(check-sat)
(get-model)
它产生明显的归纳不变量。 如果用
替换最后一个断言(assert (forall ((I Int)) (=> (inv I) (<= I 10))))
相反,你得到一个(难以阅读)的证据。