使用Z3求解线性方程

时间:2018-12-22 01:11:06

标签: python z3py

我有以下线性方程式。

m = 2 ** 31 - 1

(207560540 ∗ a + b) modulo m = 956631177
(956631177 ∗ a + b) modulo m = 2037688522

求解这些方程式的最有效方法是什么?

我使用Z3,但是找不到任何解决方案。我为Z3解决上述方程式的代码是:

#! /usr/bin/python

from z3 import *

a = Int('a')
b = Int('b')

s = Solver()

s.add((a * 207560540 + b) % 2147483647 == 956631177)
s.add((a * 956631177 + b) % 2147483647 == 2037688522)

print s.check()
print s.model()

我知道解决方案是:a = 16807,b = 78125,但是,如何使Z3解决呢?

我尝试的另一种方法是将a和b设置为BitVec()而不是Integers,如下所示:

a = BitVec('a', 32)
b = BitVec('b', 32)

这给了我一个错误的解决方案,如下所示:

[b = 3637638538, a = 4177905984]

有没有办法用Z3解决它?

谢谢。

1 个答案:

答案 0 :(得分:1)

除位向量外:使用位向量时,所有操作均以2^N为模,其中N是位向量的大小。因此,z3并没有为您提供incorrect的解决方案:如果对数学进行2^32模运算,您会发现它找到的模型确实正确。

看来您的问题确实确实需要无界的整数,并且由于模量2^31-1并不是真正的线性。 (线性意味着乘以常数;模数乘以常数会带您到另一个领域。)模数不容易推论;我认为z3不是解决此类问题的合适工具,也不是其他任何SMT解决方案。在这种情况下,像mathematica,wolfram-alpha等工具可能是更好的选择。例如,请参见:wolfram-alpha solution