为什么Z3总是在断言有能力时返回未知?

为什么Z3总是在断言有能力时返回未知?,z3,smt,Z3,Smt,这是输入 例1 (declare-var a Int) (declare-var b Int) (declare-var n Int) (assert (= b (* a a))) (assert (not (= b (^ a 2)))) (check-sat) 例2 (declare-var a Int) (declare-var b Int) (declare-var n Int) (assert (= b (* (^ a n) a))) (assert (not (= b (^ a (+

这是输入

例1

(declare-var a Int)
(declare-var b Int)
(declare-var n Int)
(assert (= b (* a a)))
(assert (not (= b (^ a 2))))
(check-sat)
例2

(declare-var a Int)
(declare-var b Int)
(declare-var n Int)
(assert (= b (* (^ a n) a)))
(assert (not (= b (^ a (+ n 1)))))
(check-sat)

它几乎在瞬间返回未知值。

您的问题属于称为非线性整数算术的片段,这是不可判定的。也就是说,没有决策过程来确定查询的可满足性。(非线性意味着,基本上,存在一个至少涉及两个变量的乘法项。)

话虽如此,大多数解算器都有启发式算法来回答涉及非线性算法的查询,Z3也不例外。当然,作为一种启发,它可能会也可能不会给出答案。这就是你所观察到的,唉,看来Z3使用的默认策略不足以解决你的问题

作为一个常见的技巧,您可以尝试Z3的非线性实数算术解算器来解决这类问题。使用以下选项代替检查sat:

(check-sat-using qfnra-nlsat)
在本例中,Z3尝试在假设输入为实数的情况下求解基准测试,并查看解决方案是否实际为整数。这个技巧可以成功地解决一些整数非线性算术查询,当然并不总是如此。例如,如果您在第一个示例中尝试
qfnra-nlsat
,您将看到它成功地解决了这个问题,但对于第二个示例,它仍然回答
unknown

有关非线性整数算术和Z3的详细信息,请参见此处: