Model :: ConstInterp和Model :: Eval有什么区别?

时间:2013-03-20 19:21:36

标签: z3

我一直在使用ConstInterp来获取expr中常量文字的值。

model.ConstInterp(lit)

然而我遇到了一个奇怪的错误

... <body of some loop>
let x = model.ConstInterp(lit)
if solver.Check() == Status.SATISFIABLE
then model.ConstInterp(lit)

对ConstInterp的第二次调用产生错误

Unhandled Exception: Microsoft.Z3.Z3Exception: invalid argument
   at Microsoft.Z3.Native.Z3_model_get_const_interp(IntPtr a0,IntPtr a1,IntPtr a2)
   at Microsoft.Z3.Model.ConstInterp(FuncDecl f)
   at Microsoft.Z3.Model.ConstInterp(Expr a)

然而与Eval相同的代码而不是ConstInterp它的罚款。我错误地使用了ConstInterp吗?

1 个答案:

答案 0 :(得分:1)

对model.ConstInterp()的第一次调用使用了在前一次调用Check()期间构造的模型,因此它可能包含不同的常量解释,但这只是次要问题。

并不要求所有常量在每个模型中都有解释,例如,当不需要赋值来满足所有约束时,它可以保持未分配(因此在模型中缺失)。例如,请考虑以下程序:

Solver s = ctx.MkSolver();
s.Add(ctx.MkOr(
    ctx.MkEq(x, ctx.MkTrue()),
    ctx.MkEq(x, ctx.MkFalse()))); // Assert x = false OR x = true
s.Add(ctx.MkEq(y, ctx.MkTrue())); // Assert y = false
s.Check(); // Returns Status.SATISFIABLE

此程序不会限制x,但会限制y。因此,模型将不包含x的值,而s.Model.ConstInterp(x)将抛出一个断言。对s.Model.Eval(x)的调用不会抛出断言,但也不会评估x;在这个例子中,我们得到s.Model.Eval(x) == x。通过将Eval()的第二个参数设置为true可以更改此行为,从而启用模型完成,即

s.Model.Eval(x, true)

将返回false

作为替代方案,数组s.Model.ConstDecls包含常量的所有函数声明,这些声明在模型中有解释。不在此集合中的常量没有解释,可以假设为“不关心”,即可以为其分配任何值。