在Z3上使用SMT约束时是否可以获得合法范围信息

时间:2018-12-07 19:52:19

标签: python constraints z3 smt z3py

因此,基本上,我正在尝试使用像Z3这样的通用约束求解器来解决以下SMT约束:

>>> from z3 import *
>>> a = BitVec("a", 32)
>>> b = BitVec("b", 32)
>>> c1 = (a + 32) & (b & 0xff)
>>> c2 = (b & 0xff)
>>> s = Solver()
>>> s.add(c1 == c2)
>>> s.check()
sat
>>> s.model()
[b = 0, a = 4294967199]

请注意,显然,只要sat落在b的范围内,约束就应该是[0x00000000, 0xffffff00]

这是我的问题,像Z3这样的SMT求解器提供具有可满足约束的“范围”信息在一般情况下是否可行?谢谢。

2 个答案:

答案 0 :(得分:2)

如果您要求一个有效的“最大”值范围,以使该范围内的所有所有数字都满足您的属性,那将是一个量化的优化问题。 (此外,在这种情况下“最广泛”的含义可能很难表达。)不幸的是,目前,z3或我所知的任何其他SMT求解器都无法处理此类问题。

但是,如果您正在寻找b的最小值和最大值以使您的媒体资源成立,那么您可以使用Optimize类:

from z3 import *

a = BitVec("a", 32)
b = BitVec("b", 32)
c1 = (a + 32) & (b & 0xff)
c2 = (b & 0xff)

s = Optimize()
s.add(c1 == c2)

min_b = s.minimize(b)
max_b = s.maximize(b)
s.set('priority', 'box')
s.check()

print "min b = %s" % format(min_b.value().as_long(), '#x')
print "max b = %s" % format(max_b.value().as_long(), '#x')

此打印:

min b = 0x0
max b = 0xffffffff

[此外:b的最大值不同于您的预期。但是z3所说的话对我来说看起来很不错:如果您选择a0x7fffffdf,那么a+32将为0x7fffffff,即所有1;因此c1c2对于b的任何值都是等效的。因此,这里没有任何内容以任何方式真正约束b。也许您的想法有所不同?]

但更重要的是,请注意,这不是 ,表示您的属性对于此范围内的b的所有值都是正确的:它的意思是{{ 1}}满足您的属性,这些是b可以假定的最小值和最大值。 (在这种情况下,事实证明该范围内的所有值都满足该条件,但这是我们自己推论得出的。)例如,如果添加一个约束b not { {1}},您仍将获得这些界限。我希望这很清楚!

答案 1 :(得分:2)

Levent Erkok 提供的答案通常是有效的,在大多数实际情况下,这是唯一值得考虑的答案。

但是,从技术上讲,这并不是 OMT 求解器无法完全解决的问题,至少在考虑的值域为有限时,可能是 small 。在这种情况下,可以简单地列举问题表述中的所有可能值。自然,不应期望这种方法可以很好地扩展。


示例。

该模型的目标是找到delta中包含的最大间隔[low, upp],以使该间隔内的所有值具有特定的 Boolean 属性{{ 1}}成立。

文件: test.smt2

Prop

简短说明。目标函数的目标是使间隔(set-option :produce-models true) (declare-fun low () (_ BitVec 4)) (declare-fun upp () (_ BitVec 4)) (declare-fun delta () (_ BitVec 4)) (declare-fun Prop () Bool) (assert (bvule low upp)) (assert (= delta (bvadd upp (bvneg low) (_ bv1 4)))) ; Put in relation a domain value with the desired Property (assert (=> (and (bvule low (_ bv0 4)) (bvule (_ bv0 4) upp)) Prop)) (assert (=> (and (bvule low (_ bv1 4)) (bvule (_ bv1 4) upp)) Prop)) (assert (=> (and (bvule low (_ bv2 4)) (bvule (_ bv2 4) upp)) Prop)) (assert (=> (and (bvule low (_ bv3 4)) (bvule (_ bv3 4) upp)) Prop)) (assert (=> (and (bvule low (_ bv4 4)) (bvule (_ bv4 4) upp)) Prop)) (assert (=> (and (bvule low (_ bv5 4)) (bvule (_ bv5 4) upp)) Prop)) (assert (=> (and (bvule low (_ bv6 4)) (bvule (_ bv6 4) upp)) Prop)) (assert (=> (and (bvule low (_ bv7 4)) (bvule (_ bv7 4) upp)) Prop)) (assert (=> (and (bvule low (_ bv8 4)) (bvule (_ bv8 4) upp)) Prop)) (assert (=> (and (bvule low (_ bv9 4)) (bvule (_ bv9 4) upp)) Prop)) (assert (=> (and (bvule low (_ bv10 4)) (bvule (_ bv10 4) upp)) Prop)) (assert (=> (and (bvule low (_ bv11 4)) (bvule (_ bv11 4) upp)) Prop)) (assert (=> (and (bvule low (_ bv12 4)) (bvule (_ bv12 4) upp)) Prop)) (assert (=> (and (bvule low (_ bv13 4)) (bvule (_ bv13 4) upp)) Prop)) (assert (=> (and (bvule low (_ bv14 4)) (bvule (_ bv14 4) upp)) Prop)) (assert (=> (and (bvule low (_ bv15 4)) (bvule (_ bv15 4) upp)) Prop)) ; These are just to make the solution "interesting" ; Your problem should already entail some values bvX for ; which Prop is false (assert (=> (and (bvule low (_ bv5 4)) (bvule (_ bv5 4) upp)) (not Prop))) (assert (=> (and (bvule low (_ bv6 4)) (bvule (_ bv6 4) upp)) (not Prop))) (assert (=> (and (bvule low (_ bv13 4)) (bvule (_ bv13 4) upp)) (not Prop))) (maximize delta) (check-sat) (get-objectives) (get-model) 的大小最大化,该间隔由[low, upp]度量。 delta的最大值是delta,它对应于间隔2^N

约束:

[0, 2^N - 1]

表示,如果值(assert (=> (and (bvule low (_ bv0 4)) (bvule (_ bv0 4) upp)) Prop)) 包含在当前间隔bv0中,则属性[low, upp]必须成立。

约束:

Prop

表示,对于值(assert (=> (and (bvule low (_ bv5 4)) (bvule (_ bv5 4) upp)) (not Prop))) ,属性bv5不成立。 Propbv6相同。这些限制只是使解决方案变得有趣。您的问题应该已经包含一些值bv13,而属性bvX不能为 true

最佳解决方案与所需值匹配:

Prop

自然,同样的公式也可以用~$ time ./optimathsat test.smt2 sat (objectives (delta (_ bv6 4)) ) ( (low (_ bv7 4)) (upp (_ bv12 4)) (delta (_ bv6 4)) (Prop true) ) real 0m0,042s user 0m0,029s sys 0m0,013s 来解决。