Python z3解决方案数
如何使用z3计算解决方案的数量?例如,我想证明,对于任何Python z3解决方案数,python,z3,solver,Python,Z3,Solver,如何使用z3计算解决方案的数量?例如,我想证明,对于任何n,方程组{x^2==1,y_1==1,…,y_n==1}有两个解。下面的代码显示了给定n的可满足性,这并不是我想要的(我想要任意n的许多解决方案) 如果有有限数量的解,可以使用不等于其指定模型值的常数(x_i)的间断来枚举所有这些常数。如果有无穷多个解(如果你想证明所有自然数n都有无穷多个解),你可以使用相同的技术,但当然不能全部列举,但可以使用它生成许多解,直到你选择的某个边界。如果你想证明所有n>1,你需要使用量词。我在下面添加了一个
n
,方程组{x^2==1,y_1==1,…,y_n==1}
有两个解。下面的代码显示了给定n
的可满足性,这并不是我想要的(我想要任意n
的许多解决方案)
如果有有限数量的解,可以使用不等于其指定模型值的常数(x_i)的间断来枚举所有这些常数。如果有无穷多个解(如果你想证明所有自然数n都有无穷多个解),你可以使用相同的技术,但当然不能全部列举,但可以使用它生成许多解,直到你选择的某个边界。如果你想证明所有n>1,你需要使用量词。我在下面添加了一个讨论 虽然你没有问这个问题,但你也应该看到这个问题/答案: 下面是您执行此操作的示例(这里的z3py链接:): 如果你想证明对于n的任何选择都没有其他的解决方案,你需要使用量词,因为之前的方法只适用于有限n(而且很快就会变得非常昂贵)。这是一个显示这个证明的编码。您可以对其进行概括,将上一部分中的模型生成功能结合起来,为更一般的公式提供+/-1解决方案。如果方程有许多与n无关的解(就像在你的例子中),这将允许你证明方程有一些有限的解。如果解的个数是n的函数,你必须算出这个函数。z3py链接:
哇,这是一个伟大的回应。不幸的是,我不能很好地使用第一部分:我在解算器之外得到数字解,所以我不能证明像这样的事情“解决方案的数量让我开始产生这样的印象,即在z3中无法做到这一点:-/您能提供一个您想要解决的示例吗?你可以用我答案的第一部分来找出一个特定n的解的数目。然后,您可以使用第二部分来说明对于n的任何选择都没有其他解决方案。在原始示例中,解决方案的数量与n无关。你有没有一个你感兴趣的具体例子?我不理解函数的域
n
,对于任何t_1,…t_n
,方程组{x_1^2==t_1
,x_2^2==t_2
,…,x_n^2==t_n
,至多有2^n
的解。”
#!/usr/bin/env python
from z3 import *
# Add the equations { x_1^2 == 1, x_2 == 1, ... x_n == 1 } to s and return it.
def add_constraints(s, n):
assert n > 1
X = IntVector('x', n)
s.add(X[0]*X[0] == 1)
for i in xrange(1, n):
s.add(X[i] == 1)
return s
s = Solver()
add_constraints(s, 3)
s.check()
s.model()
# Add the equations { x_1^2 == 1, x_2 == 1, ... x_n == 1 } to s and return it.
def add_constraints(s, n, model):
assert n > 1
X = IntVector('x', n)
s.add(X[0]*X[0] == 1)
for i in xrange(1, n):
s.add(X[i] == 1)
notAgain = []
i = 0
for val in model:
notAgain.append(X[i] != model[val])
i = i + 1
if len(notAgain) > 0:
s.add(Or(notAgain))
print Or(notAgain)
return s
for n in range(2,5):
s = Solver()
i = 0
add_constraints(s, n, [])
while s.check() == sat:
print s.model()
i = i + 1
add_constraints(s, n, s.model())
print i # solutions
x = Function('x', IntSort(), IntSort())
s = Solver()
n = Int('n')
# theorem says that x(1)^2 == 1 and that x(1) != +/- 1, and forall n >= 2, x(n) == 1
# try removing the x(1) != +/- constraints
theorem = ForAll([n], And(Implies(n == 1, And(x(n) * x(n) == 1, x(n) != 1, x(n) != -1) ), Implies(n > 1, x(n) == 1)))
#s.add(Not(theorem))
s.add(theorem)
print s.check()
#print s.model() # unsat, no model available, no other solutions