当断言有权时,为什么Z3总是返回未知?

时间:2016-04-23 15:40:01

标签: 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 (+ n 1)))))
(check-sat)

它几乎瞬间就会回归未知。

1 个答案:

答案 0 :(得分:3)

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

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

作为一种常见技巧,您可以针对这些类型的问题尝试Z3的非线性实数算术求解器。而不是check-sat,请使用:

(check-sat-using qfnra-nlsat)

在这种情况下,Z3尝试解决基准,假设输入是实数,并查看解是否实际上是整数。这个技巧可以成功地解决一些整数非线性算术查询,当然并不总是如此。例如,如果您在第一个示例中尝试qfnra-nlsat,您会看到它成功解决了它,但它仍然会回复unknown第二个示例。

有关非线性整数运算和Z3的详细信息,请参见此处:How does Z3 handle non-linear integer arithmetic?