当检查满足性时,有没有办法阻止Z3求解器绑定(=解释)某些变量(=常量)?
例如,在下面的C#程序中,可能有两种不同的解释:
`
Dictionary<string, string> settings = new Dictionary<string, string> {
{ "unsat-core", "true" }, // enable generation of unsat cores
{ "model", "true" }, // enable model generation
{ "proof", "false" } // enable proof generation
};
Context ctx = new Context(settings);
Solver solver = ctx.MkSolver();
BitVecExpr rax0 = ctx.MkBVConst("RAX!0", 64); // register values
BitVecExpr rax1 = ctx.MkBVConst("RAX!1", 64);
BoolExpr switch1 = ctx.MkBoolConst("switch_1_on"); // switch on/off instruction 1
BoolExpr switch2 = ctx.MkBoolConst("switch_2_on"); // switch on/off instruction 2
BitVecExpr immConst = ctx.MkBVConst("CONST1", 64); // imm const
//making rax0 inconsistent does not work
//solver.Assert(ctx.MkEq(rax0, ctx.MkBVAND(ctx.MkBV(0, 64), ctx.MkBV(0xFFFFFFFFFFFFFFFF, 64))));
// instruction 1: MOV RAX, immConst
solver.Assert(ctx.MkIff(switch1, ctx.MkEq(rax1, immConst)));
// instruction 2: NOP
solver.Assert(ctx.MkIff(switch2, ctx.MkEq(rax1, rax0)));
// atleast and atmost one instruction must be executed
solver.Assert(ctx.MkAtMost(new BoolExpr[] { switch1, switch2 }, 1));
solver.Assert(ctx.MkOr(new BoolExpr[] { switch1, switch2 }));
// after executing the ASM we want rax to be 0
solver.Assert(ctx.MkEq(rax1, ctx.MkBV(0, 64)));
`
问题:是否有一种自然的方法可以使第二种解释(switch2 = true)无效,以便在迭代所有解释时不会显示。
我试图通过断言ctx.MkEq(rax0, ctx.MkBVAND(ctx.MkBV(0, 64), ctx.MkBV(0xFFFFFFFFFFFFFFFF, 64))
来使rax0不一致,但这并没有帮助。
我可以检查解释是否以某种方式使用rax0
,但我不知道如何测试。我想这样的解释无效会更好。
答案 0 :(得分:1)
模型/解释通常被定义为从符号到值的总映射;因此,如果可以告诉求解器在作业中不包含某些符号,那么这似乎有点令人惊讶。
虽然这是一个想法:我解释你的目标是找到“忽略”某些符号的模型,因为找到的模型仍然是模型,无论哪个(其他)值分配给感兴趣的符号。也就是说,适用于这些符号的所有值的模型。因此,您可以对这些符号进行普遍量化,然后要求求解器具有可满足性。
考虑这个例子:
(declare-const b1 Bool)
(declare-const b2 Bool)
(declare-const i1 Int)
(declare-const i2 Int)
(assert
(or ; Admits several models
(not b1)
(< 0 i1)
(and b2 (= i1 i2))))
(check-sat)
(get-model)
它承认了几种型号,例如: i1 = 0, i2 = 0, !b1, !b2
。如果您要强制执行“忽略”i1
的模型,即无论i1
的值是哪个模型,那么只需量化i1
:
(assert
(forall ((i1 Int))
(or
(not b1)
(< 0 i1)
(and b2 (= i1 i2)))))
满足这些约束的唯一方法是满足第一个析取,i1
的值与此无关。实际上,将(assert b1)
添加到上述程序会使其不可满足:没有可以忽略i1
的模型。
对i2
进行量化会使解算器有更多可能的模型选择:i1
无关紧要(因为!b1
)和i1
{ {1}}是积极的。