更改 Z3 定点查询的顺序会更改结果

Changing order of Z3 fixepoint queries changes the result

我试图找出为什么交换查询顺序可能会修改 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)。谢谢!

假设所有约束都是 UTVPI(每个不等式的双变量单元)。 UTVPI 模式通常是 比一般的线性算术快。它减少了 space 的搜索 候选不变量下降到 UTVPI 公式并使用基于流的 约束的决策程序。另一方面,它可能会错过 无法在 UTVPI 片段中表达的不变量。默认, PDR 引擎检查公式是否都属于 UTVPI 其中 如果它切换到 UTVPI 模式。

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

fixedpoint.pdr.utvpi=假

我会尽量让切换更优雅。谢谢你的例子。