更改Z3 fixepoint查询的顺序会更改结果

时间:2016-07-26 15:34:46

标签: z3 smt fixed-point

我试图找出为什么交换查询命令可能会修改Z3定点引擎的答案:

(declare-rel fib (Int Int))
(declare-rel q1 ())
(declare-rel q2 ())
(declare-var n Int)
(declare-var tmp1 Int)
(declare-var tmp2 Int)

(rule (=> (< n 2) (fib n 1)))
(rule (=> (and (>= n 2)
               (fib (- n 1) tmp1)
               (fib (- n 2) tmp2))
       (fib n (+ tmp1 tmp2))))

(rule (=> (< n 2) q1))
(rule (=> (and (fib n tmp1) (<= tmp1 0)) q2))

(query q1)
(query q2)

第一个查询q1是一个虚拟查询,只是向引擎询问某些事情。 第二个查询q2与不变的不变量相矛盾,即斐波纳契数总是正数。

如果查询顺序是

(query q2)
(query q1)

一切正常,给出了正确的答案。但是在查询q2时,交换它们会产生下一个错误:

(smt.diff_logic: non-diff logic expression (+ fib_1_1 fib_1_0 (* (- 1) fib_1_n)))
unknown

有人可以解释原因吗?是Z3问题还是我做错了什么?如果首先,任何建议它(我使用.NET API)的建议将非常感激。谢谢!

1 个答案:

答案 0 :(得分:1)

假设所有约束都是有点激进的话 UTVPI(单位双变量不等式)。 UTVPI模式经常出现 比一般线性算术更快。它削减了搜索空间 候选不变量到UTVPI公式并使用基于流的 约束的决策程序。另一方面,它可能会错过 不能在UTVPI片段中表达的不变量。默认情况下, PDR引擎检查公式是否都属于UTVPI 如果它切换到UTVPI模式。

您可以使用选项禁用UTVPI模式。

fixedpoint.pdr.utvpi =假

我会尝试让开关更优雅。谢谢你的例子。