为什么断言有效时 Z3 总是 return 未知?
Why Z3 always return unknown when assertions have power?
这是输入
示例 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)
它 returns 几乎瞬间未知。
你的问题属于不可判定的非线性整数运算片段。也就是说,没有决定程序来确定您的查询的可满足性。 (非线性意味着,基本上,有一个涉及至少两个变量的乘法项。)
话虽如此,大多数求解器确实具有 启发式 来回答涉及非线性算术的查询,Z3 也不例外。当然,作为一种启发式方法,它可能会或可能不会产生答案。这就是您所观察到的,唉,Z3 使用的默认策略似乎不足以解决您的问题。
作为一个常用技巧,您可以尝试使用 Z3 的非线性实数算术求解器来解决这类问题。代替 check-sat
,使用:
(check-sat-using qfnra-nlsat)
在这种情况下,Z3 假设输入是实数来尝试求解基准,并查看解是否实际上是整数。这个技巧可以成功地解决一些整数非线性算术查询,当然并非总是如此。例如,如果您在第一个示例中尝试 qfnra-nlsat
,您会发现它成功解决了问题,但对于第二个示例,它仍然会回答 unknown
。
有关非线性整数运算和 Z3 的详细信息,请参见此处:How does Z3 handle non-linear integer arithmetic?
这是输入
示例 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)
它 returns 几乎瞬间未知。
你的问题属于不可判定的非线性整数运算片段。也就是说,没有决定程序来确定您的查询的可满足性。 (非线性意味着,基本上,有一个涉及至少两个变量的乘法项。)
话虽如此,大多数求解器确实具有 启发式 来回答涉及非线性算术的查询,Z3 也不例外。当然,作为一种启发式方法,它可能会或可能不会产生答案。这就是您所观察到的,唉,Z3 使用的默认策略似乎不足以解决您的问题。
作为一个常用技巧,您可以尝试使用 Z3 的非线性实数算术求解器来解决这类问题。代替 check-sat
,使用:
(check-sat-using qfnra-nlsat)
在这种情况下,Z3 假设输入是实数来尝试求解基准,并查看解是否实际上是整数。这个技巧可以成功地解决一些整数非线性算术查询,当然并非总是如此。例如,如果您在第一个示例中尝试 qfnra-nlsat
,您会发现它成功解决了问题,但对于第二个示例,它仍然会回答 unknown
。
有关非线性整数运算和 Z3 的详细信息,请参见此处:How does Z3 handle non-linear integer arithmetic?