z3不支持注入能力的解决方法

z3不支持注入能力的解决方法,z3,Z3,我想在z3中表示一个散列函数,类似于SHA(x)。在做了一些研究之后,z3似乎不太支持内射性,所以我不能有这样的约束(虽然我意识到这严格来说不是真的,因为碰撞,作为一种启发式,它对我的项目很有用) 并期望解算器终止 我的问题是,对于这个问题,有没有已知的最佳实践解决方法?例如,如果我在不使用量词的情况下为每对x和y添加了一个暗示(SHA(x)==SHA(y),x==y)约束,这能解决问题吗?对于未解释的函数,我们使用以下形式的编码: Forall([x],逆_f(f(x))=x) 所以当f是内射

我想在z3中表示一个散列函数,类似于SHA(x)。在做了一些研究之后,z3似乎不太支持内射性,所以我不能有这样的约束(虽然我意识到这严格来说不是真的,因为碰撞,作为一种启发式,它对我的项目很有用)

并期望解算器终止


我的问题是,对于这个问题,有没有已知的最佳实践解决方法?例如,如果我在不使用量词的情况下为每对x和y添加了一个暗示(SHA(x)==SHA(y),x==y)约束,这能解决问题吗?

对于未解释的函数,我们使用以下形式的编码:

Forall([x],逆_f(f(x))=x)

所以当f是内射时,我们可以引入一个函数,在f的范围内实现部分逆。带有等式对的量化公理非常常见,因此Z3查找它们并添加上述公理。 每次出现f时,它都会被实例化。
当然,对于通常使用位向量编码的SHA,引入一个未解释的函数意味着Z3不使用纯SAT解算器。在最好的情况下,它将恢复到Ackerman编码,即重新引入原始的成对编码。

使用部分逆,我仍然有完全相同的问题,即使用暗示(f(x)=f(y),x==y)的朴素方法,即解算器无法找到简单问题的解决方案。例如:
import z3 a=z3.BitVec('a',32)b=z3.BitVec('b',32)x=z3.BitVec('x',32)hash=z3.BitVecSort(32),z3.BitVecSort(32))hash\u inv=z3.Function('hash',z3.BitVecSort(32),z3.BitVecSort(32))hash\u pred=z3.ForAll([x],hash\u inv(hash)(hash)(x))=x)s=z3.Solver=3.set\u param=10.add hash(s)add hash=pred(hash)(hash)(hash=s)hash(s)hash(s)hash(s)hash(s)hash(s=z3s.add(a!=b)s.check()
forall([x, y],Implies(SHA(x)==SHA(y), x==y))