我有以下线性方程式。
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解决它?
谢谢。
答案 0 :(得分:1)
除位向量外:使用位向量时,所有操作均以2^N
为模,其中N
是位向量的大小。因此,z3并没有为您提供incorrect
的解决方案:如果对数学进行2^32
模运算,您会发现它找到的模型确实正确。
看来您的问题确实确实需要无界的整数,并且由于模量2^31-1
并不是真正的线性。 (线性意味着乘以常数;模数乘以常数会带您到另一个领域。)模数不容易推论;我认为z3不是解决此类问题的合适工具,也不是其他任何SMT解决方案。在这种情况下,像mathematica,wolfram-alpha等工具可能是更好的选择。例如,请参见:wolfram-alpha solution