Z3 SMT和Python的结果不正确

Z3 SMT和Python的结果不正确,z3,smt,z3py,Z3,Smt,Z3py,我正试图从这里复制另一个用户给出的脚本 我有我认为最适合python绑定的部分,但是我没有得到正确的答案。以下是python脚本: from z3 import * mask = BitVec('mask', 64) multiplicand = BitVec('multiplicand', 64) x = BitVec('x', 64) y = BitVec('y', 64) s = SolverFor("BV") F = [ ForAll(x, (y == (mask & x)

我正试图从这里复制另一个用户给出的脚本

我有我认为最适合python绑定的部分,但是我没有得到正确的答案。以下是python脚本:

from z3 import *

mask = BitVec('mask', 64)
multiplicand = BitVec('multiplicand', 64)
x = BitVec('x', 64)
y = BitVec('y', 64)

s = SolverFor("BV")
F = [
ForAll(x, (y == (mask & x) * multiplicand)),
And(Extract(63, 63, x) == Extract(63, 63, y),
    Extract(55, 55, x) == Extract(62, 62, y),
    Extract(47, 47, x) == Extract(61, 61, y),
    Extract(39, 39, x) == Extract(60, 60, y),
    Extract(31, 31, x) == Extract(59, 59, y),
    Extract(23, 23, x) == Extract(58, 58, y),
    Extract(15, 15, x) == Extract(57, 57, y),
    Extract(7, 7, x) == Extract(56, 56, y))
]

print F[0].sexpr()
print F[1].sexpr()

s.add(F)
if s.check() == sat:
    print "ok"
    print s.model()
我的结果如下:

(forall ((x (_ BitVec 64))) (= y (bvmul (bvand mask x) multiplicand)))
(and (= ((_ extract 63 63) x) ((_ extract 63 63) y))
     (= ((_ extract 55 55) x) ((_ extract 62 62) y))
     (= ((_ extract 47 47) x) ((_ extract 61 61) y))
     (= ((_ extract 39 39) x) ((_ extract 60 60) y))
     (= ((_ extract 31 31) x) ((_ extract 59 59) y))
     (= ((_ extract 23 23) x) ((_ extract 58 58) y))
     (= ((_ extract 15 15) x) ((_ extract 57 57) y))
     (= ((_ extract 7 7) x) ((_ extract 56 56) y)))
[掩码=0,被乘数=0,y=0,x=0]


这显然是错误的。我看到的主要区别是,我生成的SMT代码似乎对“y”赋值,而在另一个StackExchange答案中,他有一个let表达式。有人能给我指出正确的方向吗?

这里有一个技巧,您可以通过Python API使用parse_SMT2_string解析SMT2字符串:

输出为:

[mask = 9259542123273814144, multiplicand = 567382630219905]
0x8080808080808080L
0x2040810204081L
[mask = 9259542123273814144, multiplicand = 567382630219905]
0x8080808080808080L
0x2040810204081L
let表达式的编码有问题。对于主断言,您需要在所有x上使用通用量词,而您正试图使用它来定义let表达式。以下内容基本上适用于原始编码,只需创建一个指向相应表达式y的指针并复制它:

from z3 import *

mask = BitVec('mask', 64)
multiplicand = BitVec('multiplicand', 64)
x = BitVec('x', 64)
y = BitVec('y', 64)

y = ((mask & x) * multiplicand)

s = SolverFor("BV")
F = [
ForAll(x,
And(Extract(63, 63, x) == Extract(63, 63, y),
    Extract(55, 55, x) == Extract(62, 62, y),
    Extract(47, 47, x) == Extract(61, 61, y),
    Extract(39, 39, x) == Extract(60, 60, y),
    Extract(31, 31, x) == Extract(59, 59, y),
    Extract(23, 23, x) == Extract(58, 58, y),
    Extract(15, 15, x) == Extract(57, 57, y),
    Extract(7, 7, x) == Extract(56, 56, y)))
]

print F[0].sexpr()

s.add(F)
if s.check() == sat:
    print "ok"
    print s.model()
    m = s.model()
    print hex(m[mask].as_long())
    print hex(m[multiplicand].as_long())
输出为:

[mask = 9259542123273814144, multiplicand = 567382630219905]
0x8080808080808080L
0x2040810204081L
[mask = 9259542123273814144, multiplicand = 567382630219905]
0x8080808080808080L
0x2040810204081L

通过使用parse_SMT2_string通过Python API解析SMT2字符串,您可能会喜欢以下技巧:

输出为:

[mask = 9259542123273814144, multiplicand = 567382630219905]
0x8080808080808080L
0x2040810204081L
[mask = 9259542123273814144, multiplicand = 567382630219905]
0x8080808080808080L
0x2040810204081L
let表达式的编码有问题。对于主断言,您需要在所有x上使用通用量词,而您正试图使用它来定义let表达式。以下内容基本上适用于原始编码,只需创建一个指向相应表达式y的指针并复制它:

from z3 import *

mask = BitVec('mask', 64)
multiplicand = BitVec('multiplicand', 64)
x = BitVec('x', 64)
y = BitVec('y', 64)

y = ((mask & x) * multiplicand)

s = SolverFor("BV")
F = [
ForAll(x,
And(Extract(63, 63, x) == Extract(63, 63, y),
    Extract(55, 55, x) == Extract(62, 62, y),
    Extract(47, 47, x) == Extract(61, 61, y),
    Extract(39, 39, x) == Extract(60, 60, y),
    Extract(31, 31, x) == Extract(59, 59, y),
    Extract(23, 23, x) == Extract(58, 58, y),
    Extract(15, 15, x) == Extract(57, 57, y),
    Extract(7, 7, x) == Extract(56, 56, y)))
]

print F[0].sexpr()

s.add(F)
if s.check() == sat:
    print "ok"
    print s.model()
    m = s.model()
    print hex(m[mask].as_long())
    print hex(m[multiplicand].as_long())
输出为:

[mask = 9259542123273814144, multiplicand = 567382630219905]
0x8080808080808080L
0x2040810204081L
[mask = 9259542123273814144, multiplicand = 567382630219905]
0x8080808080808080L
0x2040810204081L

问题实际上是关于Z3 Python绑定的。但这是一个有趣的问题。在没有任何语言战争的情况下,我只是想将Haskell解决方案放在这里作为参考,再次使用Z3作为底层解算器:

导入数据.SBV main::IO
main=print=问题实际上是关于Z3 Python绑定的。但这是一个有趣的问题。在没有任何语言战争的情况下,我只是想将Haskell解决方案放在这里作为参考,再次使用Z3作为底层解算器:

导入数据.SBV main::IO
main=print=你的解释很有道理。我不知道parse_smt2_string方法,所以感谢您提醒我注意。您的解释非常有道理。我不知道parse_smt2_string方法,所以感谢您提醒我注意。