为什么这段代码返回Unsat?

时间:2013-07-01 05:58:30

标签: z3 z3py

给定c == a + 4t == c + b,如果b == -4,则t == a。我试图做相反的事情,意思是给定上述2个等式和t == a,我试图找到b的值。

这与related question非常相似,但这次我只切换ab,我真的很困惑,代码会返回不同的结果。

按照上面链接发布的代码,我有以下代码(类似,只有ab swiched):

#!/usr/bin/python
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([t, a, c], Implies(t == a, g)))
if s.check() == sat:
    print s.model()[b]
else:
    print 'Unsat'

然而,在Ubuntu上,运行上述代码会返回意外结果 Unsat ,但不会返回值 -4 (或 0xfffffffc

知道为什么这是错的吗?

非常感谢。

1 个答案:

答案 0 :(得分:1)

Z3实际上正在返回unknown。方法check会返回:satunsatunknown。 这是一种自定义策略,表明公式确实不够。

#!/usr/bin/python
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 = Goal()
s.add(ForAll([t, a, c], Implies(t == a, g)))

T = Then("simplify", "der", "distribute-forall")
# print the simplified formula. Note that it is unsat
print T(s)

# Create a solver using the tactic above and qe

s = Then("simplify", "der", "distribute-forall", "qe", "smt").solver()
s.add(ForAll([t, a, c], Implies(t == a, g)))
print s.check()

<强>更新 该公式的格式为

forall t, a, c: t == a ==> c == (a + 4) and t == (c + b)

此公式在逻辑上等同于:

forall a, c: c == (a + 4) and a == (c + b)

在逻辑上等同于

(forall a, c: c == (a + 4)) and (forall a, c: a == (c + b))

两个子公式在逻辑上等同于假。 这就是公式不可满足的原因。

您撰写的评论表明您认为自己创建了略有不同的公式

forall t, a, c: t == a ==> c == (a + 4) ==> t == (c + b)

此公式为sat。要创建此公式,我们必须替换

g = True
g = And(g, c == (a + 4))
g = And(g, t == (c + b))

g = Implies(c == (a + 4), t == (c + b))

更新的示例可用here