使约束更难于求解约束求解器?

时间:2019-01-28 17:23:07

标签: constraints z3 smt satisfiability constraint-satisfaction

我是SMT解决的新手,我写信询问一些建议和指针,以了解什么是真正的difficult constraint对于SMT求解器来说可以解决,例如Z3。

例如,我尝试通过以下方式调整位向量的长度:

>>> a = BitVec("a", 10000)
>>> b = BitVec("b", 10000)
>>> c = a >> 18 + 6 - 32 + 69 == b <<12 + 7 * 32
>>>
>>> s = Solver()
>>> s.add(c)
>>> s.check()

从直觉上讲,这可能会导致很大的搜索空间,但事实证明Z3仍然做得很好,并能迅速解决。

我知道一些加密哈希函数或数学公式(例如Collat​​z猜想)可能会使约束求解变得非常困难。但这似乎很极端。另一方面,例如,假设我有以下约束:

a * 4 != b + 5

如何使约束求解器更难求解?有什么通用的方法吗?我的印象是,某种程度上约束变成了“非线性”,这很困难。但是我仍然不清楚它是如何工作的。

================================

感谢您的亲切笔记和有见地的帖子。我非常感激!

因此,根据@usr的建议,以下是一些初步测试:

c = BitVec("c", 256)

for i in range(0, 10):
    c = c ^ (c << 13) + 0x51D36335;

s = Solver()
s.add(c == 0xdeadbeef)
print (s.check())
print (s.model())


➜  work time python test.py
sat
[c = 37865234442889991147654282251706833776025899459583617825773189302332620431087]
python test.py  0.38s user 0.07s system 81% cpu 0.550 total

2 个答案:

答案 0 :(得分:1)

位向量逻辑总是可判定的;因此,尽管事情可能要花很长时间,但z3可以解决所有位向量问题。当然,如果所涉及的位向量大小很大,则求解器可能会花费极长的时间,或者在找到解决方案之前会耗尽内存。乘法和加密算法是典型示例,随着位大小的增加,总是会造成困难。

在另一方面,我们有非线性整数问题。没有针对他们的决策程序,尽管z3“尽力而为”,但由于理论上的原因,此类问题通常超出了范围。您可以在堆栈溢出帖子中找到许多这些实例。这是最近的一个:Z3 returns model not available

答案 1 :(得分:1)

如果您只想看Z3的“努力工作”,可以尝试数字分解,例如a * b = constant并输入质数或大数。

或者,构建一个简单的哈希函数并获取原图像:

我所做的是看如何定义SHA-1。然后,我实现了一个简单的版本。 SHA-1由非常简单的操作组成,例如移位,加法或异或。从此模板,您可以构造一个简单的哈希函数以进行测试。然后您说y = hash(x) && y = 0x1234,Z3会给您x,这是原图像。

为娱乐起见,我将当场组成一个简单的哈希函数:

BitVec currentValue = input;

for (i = 0 to 10)
 currentValue = currentValue ^ (currentValue <<< 13) + 0x51D36335;

BitVec hash = currentValue;

这是一个实际起作用的哈希实现(但不安全)。您可以操作,轮数和位向量大小。您可以断言hash = someConstant以获得原像。例如,让Z3给您一个input,该哈希值为零。

您也可以应用更多的花哨约束,例如input == hashhash % 1234 == 0 && hash & 0xF == 7。只要给定足够的计算能力,Z3就能满足任何条件。

我个人觉得这种功能非常吸引人。