Z3 Model::concentrp和Model::Eval之间的区别是什么?

Z3 Model::concentrp和Model::Eval之间的区别是什么?,z3,Z3,我一直在使用concentrp来获取expr中常量文本的值 model.ConstInterp(lit) 然而,我得到了一个奇怪的错误 ... <body of some loop> let x = model.ConstInterp(lit) if solver.Check() == Status.SATISFIABLE then model.ConstInterp(lit) 但是,使用Eval而不是concentrp的相同代码很好。我是否错误地使用了Continterp?对模

我一直在使用concentrp来获取expr中常量文本的值

model.ConstInterp(lit)
然而,我得到了一个奇怪的错误

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

但是,使用Eval而不是concentrp的相同代码很好。我是否错误地使用了Continterp?

对模型的第一次调用。Continterp()使用的模型是在上一次调用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的值。concentrp(x)
将抛出断言。调用
s.Model.Eval(x)
不会抛出断言,但也不会计算
x
;在本例中,我们得到
s.Model.Eval(x)=x
。可以通过将
Eval()
的第二个参数设置为true来更改此行为,从而启用模型完成,即

s.Model.Eval(x, true)
将返回
false


或者,数组
s.Model.ConstDecls
包含在模型中具有解释的所有常量函数声明。不在此集合中的常数没有解释,可以假定为“不关心”,即可以为它们分配任何值。

第一次调用模型。concentrp()使用在上一次调用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的值。concentrp(x)
将抛出断言。调用
s.Model.Eval(x)
不会抛出断言,但也不会计算
x
;在本例中,我们得到
s.Model.Eval(x)=x
。可以通过将
Eval()
的第二个参数设置为true来更改此行为,从而启用模型完成,即

s.Model.Eval(x, true)
将返回
false


或者,数组
s.Model.ConstDecls
包含在模型中具有解释的所有常量函数声明。不在此集合中的常数没有解释,可以假定为“不在乎”,即可以为其分配任何值。

是否可以保证,如果变量可以不分配,它将被分配?我有一个连接词的析取,我想知道哪些连接词被“使用”。如果我向每个连词添加一个自由变量T_I,这很容易,因为如果连词不成立,它将被设置为true。一旦一个连接是sat,所有其他的T变量都是未赋值的吗?我尝试在析取中添加一组附加的连词,表示
T\u n->Conj\u n
,以便将未满足条件的连词强制设置为false,但这使得模型提取速度非常慢。哎呀,在发布后发现了一个具体的例子:否:),但我在“用于从N个对象中选择1的高效CNF编码”有助于保持速度。是否可以保证如果一个变量可以保持未赋值状态,它将保持不变?我有一个连词的析取,我想知道使用了哪些连词“。如果我向每个连词添加一个自由变量T_I,这很容易,因为如果连词不成立,它将被设置为true。一旦一个连接是sat,所有其他的T变量都是未赋值的吗?我尝试在析取中添加一组附加的连词,表示
T\u n->Conj\u n
,以便将未满足条件的连词强制设置为false,但这使得模型提取速度非常慢。哎呀,在发布后发现了一个具体的例子:否:),但我在“从N个对象中选择1的高效CNF编码”有助于保持速度。