当我向Z3寻求其他解决方案时,结果很奇怪

时间:2013-03-24 08:00:03

标签: z3

我使用Z3作为一个简单的SAT求解器,断言命题术语如下:

let ctx = new Context()
let x = ctx.MkBoolConst("x")
let y = ctx.MkBoolConst("y")
let z = ctx.MkBoolConst("z")
let f = ctx.MkOr(ctx.MkAnd(x,y), ctx.MkAnd(ctx.MkNot(x),z))
let s = ctx.MkSolver()
s.Assert(f)
assert (s.Check() = Status.SATISFIABLE)
let r= [s.Model.Eval(x); s.Model.Eval(y); s.Model.Eval(z)]
printfn "%A" r

返回

[false; true; true]

正如所料。但是,当我尝试通过获取和找到的任务并将其否定并将其添加回Z3求解器时,向Z3询问进一步的解决方案

let mkB(z3_lit:BoolExpr,bvalue:Expr) = 
  if (bvalue:?> BoolExpr).IsTrue then z3_lit else ctx.MkNot z3_lit
let founds = List.map mkB (List.zip [x;y;z] r)
let and_founds = ctx.MkAnd (List.toArray(founds))
let negated = ctx.MkNot and_founds
s.Assert negated
assert (s.Check() = Status.SATISFIABLE)
let r2 = [s.Model.Eval(x); s.Model.Eval(y); s.Model.Eval(z)]
printfn "%A" r2

我得到一个奇怪的任务z。即:

[true; true; z]

为什么之前true的z分配更改为z

1 个答案:

答案 0 :(得分:1)

如果我没弄错,将变量作为自己的模型意味着它是“不关心”:z的任何值都会为您提供有效的模型。实际上,在这种情况下,xy已经满足该条款。

如果您希望Z3为您完成模型,可以查看this question

此外,C API至少为Z3_model_eval定义了一个额外的参数,您可以使用该参数向Z3指示您想要所有变量的值。