Z3 Prover返回错误的解决方案

时间:2017-10-08 21:05:33

标签: python z3 z3py

我正在尝试用Python中的Z3 Thoerem Prover解决方程。 但我得到的解决方案是错误的。

from z3 import *    
solv = Solver()
x = Int("x")
y = Int("y")
z = Int("z")
s = Solver()
s.add(x/(y+z)+y/(x+z)+z/(x+y)==10, x>0, y>0, z>0)
s.add()
print(s.check())
print(s.model())

我得到了这个解决方案:

[z = 60, y = 5, x = 1]

但是当您将这些值填入给定的等式时,结果为:10.09735182849937。但我想要找到的是一个确切的解决方案。 我做错了什么?

感谢您的帮助:)

2 个答案:

答案 0 :(得分:4)

简短的回答是该部门正在逐渐缩小,因此答案是正确的,但不是你所期望的。请注意,通过分配Z3,您可以:

1/65 + 5/61 + 60/6 = 10

因为前两个项向下舍入为0.您可以乘以公分母来展平方程式,并将其置于z3。但这也不太可能奏效,因为你将有一个非线性的丢番图方程,并且Z3没有该片段的决策程序。事实上,众所周知,非线性整数运算是不可判定的。有关详细信息,请参阅希尔伯特的第10个问题:https://en.wikipedia.org/wiki/Hilbert%27s_tenth_problem

事实上,对这种方程式有很多了解:它定义了一条椭圆曲线。对于奇数N,已知没有解。对于偶数N(即,N=10的情况),解决方案可能存在也可能不存在,当它们存在时,它们可能非常大。当我说大的时候,我的意思是:对于N=10,我们知道有一个解决方案,令人满意的值有190位!

这是一篇关于这个等式的好文章,其中包含所有血腥细节:http://ami.ektf.hu/uploads/papers/finalpdf/AMI_43_from29to41.pdf

还有一个quora讨论肯定更容易理解:https://www.quora.com/How-do-you-find-the-positive-integer-solutions-to-frac-x-y+z-+-frac-y-z+x-+-frac-z-x+y-4

长话短说,z3(或任何SMT求解器)根本不是解决/处理此类问题的正确工具。

答案 1 :(得分:2)

我尝试了您的代码和修改后的代码,我将整个等式乘以(x+y)*(x+z)*(y+z)以消除除法:

solv = Solver()
x = Int("x")
y = Int("y")
z = Int("z")
s = Solver()
# s.add(x/(y+z)+y/(x+z)+z/(x+y)==10, x>0, y>0, z>0)
s.add(x*(x+z)*(x+y) + y*(y+z)*(x+y) + z*(y+z)*(x+z) == 10*(x+y)*(x+z)*(y+z), x > 0, y > 0, z > 0)
s.add()
print(s.check())
print(s.model())

我在Z3 4.4.1下使用Windows

修订后的代码会返回"unknown",因为Z3无法解决问题。 可能没有解决方案,正如MiniZincExcel等其他求解器所证实的那样。

如果假定为整数除法,则原始代码返回[x=1, y=1, z=20],这是正确的:

x/(y+z) = 1/(1+20) is 0 for integer division
y/(x+z) = 1/(1+20) is 0 for integer division
z/(x+y) = 20/(1+1) is 10