非线性整数算法是不可判定的。这意味着没有决策过程可以决定任意非线性整数约束是否满足。这就是Z3在回答你的问题时告诉你的。
当然,这并不意味着个别案件不能得到解决。Z3有一定的策略,它适用于解决这类公式,但它在本质上是有限的,它可以处理。你的问题属于这一类:Z3无法解决的问题。
Z3有一个专用的NRA(非线性实数算法)策略,你可以利用。它本质上把所有变量都看作实数,解决了问题(非线性实数算法是可判定的,Z3可以找到所有代数实数解),然后检查结果是否是整数。如果不是,它会尝试另一种解决方案。有时这种策略可以处理非线性整数问题,如果您恰巧找到了正确的解决方案。您可以使用以下方法触发它:
(check-sat-using qfnra)
不幸的是,在我允许它运行的时候,它不能解决您的特定问题。(超过10分钟)它不太可能达到正确的解决方案。
你真的没有很多选择。SMT解算器并不能很好地解决非线性整数问题。事实上,正如我前面提到的,由于不确定性,没有一个工具可以处理任意的非线性整数问题;但是一些工具比其他工具更好,这取决于它们使用的算法。
当你告诉Z3什么
a
和
b
是的,你基本上消除了大部分的非线性,剩下的变得容易处理。你可能会找到一系列的策略来解决你原来的问题,但是这些技巧在实践中是非常脆弱的,而且不容易被发现;因为你本质上是在搜索中引入启发式方法,而你对它的行为没有太多的控制。
旁注:你的脚本可以稍作改进。要表示一组数字都不同,请使用不同的谓词:
(assert (distinct (a b c)))
(assert (distinct (d e f)))