【发布时间】:2021-07-26 01:38:05
【问题描述】:
我试图在 Z3 中对扩展欧几里得算法进行建模,但遇到了无限循环。
欢迎提出建议和建议。
第一个函数是用 Python 编写的 - 仅供参考。
第二个函数是z3分析时陷入死循环的函数。
在我将常规 Python 函数映射到相应的 Z3 语法的过程中,您发现有什么错误吗?
'''
Returns d, x, y such that a*x + b*y = d
d = gcd(a, b)
'''
def extended_euclid_rec(a, b):
if b == 0:
d = a; x = 1; y = 0 # y can be any int
return d, x, y
else:
d, x1, y1 = extended_euclid_rec(b, a % b)
q = a // b
x = y1
y = x1-y1*q
assert a*x + b*y == d
return d, x, y
这个函数进入一个无限循环。
def extended_euclid(a, b):
d = If(b == 0, a, extended_euclid(b, a % b)[0])
x1 = If(b == 0, 1, extended_euclid(b, a % b)[1])
y1 = If(b == 0, 0, extended_euclid(b, a % b)[2])
q = If(b == 0, 1, a // b)
x = If(b == 0, 1, y1)
y = If(b == 0, 0, x1-y1*q)
return d, x, y
a = Int('a')
b = Int('b')
s = Solver()
s.add(extended_euclid(a, b)[0] == 1)
print s.sexpr()
print s.check()
【问题讨论】:
-
好吧,你的函数无条件地调用自己,所以它有无限递归。你真的需要对这个算法的过程进行建模,还是只需要表示两个整数互质的约束?
-
谢谢。我需要对这个算法的过程进行建模。如果 b == 0,则递归应该停止,这是在 Python 中运行良好的第一个函数的情况 - 假设递归的深度设置正确。
-
b是一个形式变量,在您调用函数时它不能等于零,因为它当时没有值。而且你的函数无条件地调用自己,If实际上并没有在这里分支。