您编写的公式与问题的文字描述不符。特别是,您使用的含义并不能确保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