当我向Z3询问其他解决方案时,出现了奇怪的结果

当我向Z3询问其他解决方案时,出现了奇怪的结果,z3,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

我使用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]
正如所料。然而,当我试图通过对找到的赋值取and并否定它并将其添加回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
我接到一个奇怪的任务。即:

[true; true; z]

为什么以前对z的赋值
true
更改为
z

如果我没有弄错,将变量作为自己的模型意味着它是“不在乎”:任何
z
的值都会给你一个有效的模型。事实上,在这种情况下,
x
y
为真,该子句已经满足

如果你想让Z3为你完成模型,你可以看看


此外,C API至少定义了一个额外的参数,您可以使用它向Z3指示您希望所有变量都有一个值。

您所说的当然有道理。我有点困惑,为什么在第一个模型中它没有返回一个dont care for
y
?它可能只是取决于Z3尝试为变量赋值的顺序。