给出2个等式c == a + 4
和t == c + b
,如果a == -4
,则为t == b
。我试图做相反的事情,意思是给出上述2个等式,t == b
,我试图找到a
的值。
我有以下代码来执行此操作 ForAll 和隐含:
from z3 import *
a, b, c, t = BitVecs('a b c t', 32)
g = True
g = And(g, c == (a + 4))
g = And(g, t == (c + b))
s = Solver()
s.add(ForAll([c, t, b], Implies(g, t == b)))
if s.check() == sat:
print s.model()[a]
else:
print 'Unsat'
但是,运行上面的代码会返回 Unsat 。我希望这会返回-4(或0xfffffffc),所以很困惑。
知道我哪里错了吗?
谢谢!
答案 0 :(得分:3)
您编写的公式与您问题的文字说明不符。特别是,您使用的含义并不能确保t == b
必须为真,才能使公式满意。
根据您问题的文字说明,如果t == b
为真,那么这意味着t == c + b
成立的唯一方法是c == 0
。自c == 0
开始,c == a + 4
成立的唯一方法是a == -4
,如果需要的话。 t
和b
的分配是任意的。
以下是两种编码方式。在第一种情况下,z3将0
分配给t
和b
两者,因为它们是隐式存在量化的。在第二种情况下,我使用了b
和t
上的通用量词来突出显示赋值是任意的。基于刚才所述的讨论(因为c
必须为真),任意选择c == 0
的公式不能令人满意,所以c
不应该被普遍量化。以下说明了这一点(http://rise4fun.com/Z3Py/uGEV):
a, b, c, t = BitVecs('a b c t', 32)
g = True
g = And(g, c == (a + 4))
g = And(g, t == (c + b))
g = And(g, t == b)
s = Solver()
s.add(g)
s.check()
print s.model()
ma = s.model()[a]
s = Solver()
s.add(Not(ma == 0xfffffffc))
print s.check() # unsat, proves ma is -4
solve(g) # alternatively, just solve the equations
# illustrate that the assignments to t and b are arbitrary
s = Solver()
g = True
g = And(g, c == (a + 4))
g = And(g, t == (c + b))
g = ForAll([t, b], Implies(t == b, g))
s.add(g)
s.check()
print s.model()
ma = s.model()[a]
<强>更新强>
根据以下评论,我希望此示例有助于了解您需要Implies(t == b, g)
代替Implies(g, t == b)
的原因(使用z3py链接:http://rise4fun.com/Z3Py/pl80I):
p1, p2 = BitVecs('p1 p2', 4)
solve(Implies(p1 == 1, p2 == 2)) # gives p1 = 14, p2 = 13
solve(And(p1 == 0, Implies(p1 == 1, p2 == 2))) # gives p1 = 0, p2 unassigned
solve(And(p1 == 0, p1 == 1)) # no solution to illustrate that p1 can only be 0 or 1 in previous, but would be unsat is trying to assign both
solve(ForAll([p1], Implies(p1 == 1, p2 == 2))) # gives p2 == 2
solve(ForAll([p1], Implies(p2 == 2, p1 == 1))) # gives p2 = 0 and does not ensure p1 == 1 is true since the formula is satisfiable by picking p2 != 2