我在Z3py中有以下代码
import z3
x = z3.BitVec('x', 32)
a = z3.BitVec('a', 32)
solver=z3.Solver()
solver.set(unsat_core=True)
d=z3.Bool('d')
solver.assert_and_track(x!=a,d)
solver.add(x==a)
print solver.check(d)
print solver.check(z3.Not(d))
我希望它能打印unsat
和sat
。但是它始终打印unsat
。呼叫solver.check(z3.Not(d))
是否应该有效地禁用断言x!=a
?
答案 0 :(得分:1)
assert_and_track
只是将答案文字d
与您示例中的公式x!=a
相关联。由于上下文同时包含x==a
和x!=a
,因此它是unsat
。没有任何假设会让它变得令人满意。
但我确实同意这很令人困惑。我认为这个问题可以追溯到这样一个事实:assert_and_track
请参阅此处的讨论:https://stackoverflow.com/a/14565535/936310
要真正实现自己想要的目标,只需自己断言。也就是说,使用:
solver.add(Implies(d, x!=a))
例如,以下脚本:
from z3 import *
x = z3.BitVec('x', 32)
a = z3.BitVec('a', 32)
solver=z3.Solver()
solver.set(unsat_core=True)
d=z3.Bool('d')
solver.add(Implies(d, x!=a))
solver.add(x==a)
print solver.check(d)
print solver.unsat_core()
print solver.check(z3.Not(d))
print solver.model()
产生
unsat
[d]
sat
[a = 0, d = False, x = 0]
这是你想要实现的目标。