如何使用Z3检查程序的可满足性?例如:
Boolean x, y
while(x is False) {
x = x or y
y = x & y
}
y = x or y
答案 0 :(得分:2)
您可以将程序表示为一组Horn子句。对于您的程序,您可以按如下方式表示:
(set-logic HORN)
(set-option :fixedpoint.engine bmc)
(declare-fun L0 (Bool Bool) Bool)
(declare-fun L1 (Bool Bool) Bool)
(declare-fun L2 (Bool Bool) Bool)
(declare-fun L3 (Bool Bool) Bool)
(assert (forall ((x Bool) (y Bool)) (L0 x y))) ; all values of x,y are possible at L0
(assert (forall ((x Bool) (y Bool)) (=> (L0 x y) (L1 x y)))) ; from L0 move to L1 without changing x, y
(assert (forall ((x Bool) (y Bool) (x1 Bool) (y1 Bool))
(=> (and (not x) (L1 x y) (= x1 (or x y)) (= y1 (and x1 y))) (L1 x1 y1)))); assignment in while loop
(assert (forall ((x Bool) (y Bool)) (=> (and x (L1 x y)) (L2 x y)))) ; exit while loop
(assert (forall ((x Bool) (y Bool)) (=> (L2 x y) (L3 x (or x y))))) ; assignment after while loop
(assert (forall ((x Bool) (y Bool)) (=> (L3 true true) false))) ; say x = true, y = true is unreachable.
(check-sat)
我添加了最后一个断言来制作可达性声明。 我还指示Z3使用BMC引擎展开Horn子句 有界模型检查。其他发动机也可用,例如PDR / IC3 engine(set-option:fixedpoint.engine pdr),不会展开转换关系。
现在可达性与可满足性的含义 对于Horn条款而言,与展开的结合相比将会有所不同 过渡关系: 以上条款是UNSAT。 这确实对应于从L0到(L3真实)的可行路径。 如果你将最后一个语句更改为(L3 true false),你会得到答案" sat" (BMC问题是UNSAT)。虽然BMC本身不会以这样的循环终止, 事实证明,最后一个转换和循环退出条件足以修剪掉 (L3真假)的可能性因此Z3通过预处理喇叭条款来解决这个问题。
你当然也可以写下你所拥有的程序陈述的过渡关系,并直接将其展开到一个逻辑公式中,以检查你的可满足性。