在Most efficient way to represent memory buffers in Z3中,关于如何使嵌套存储操作更有效的问题得到回答,可以用({1}}中的选择替换(嵌套)存储操作。但是,我需要存储操作,因为先前的约束必须用新约束替换。
例如:以下约束模拟以下汇编程序:
(assert (= (select A i1) v1))
我想证明rbx和rcx是相等的,我断言(= RBX!2 RCX!2)并且期望模型可以满足。这非常有效。我断言(不是(= RBX!2 RCX!2))并且期望模型不能满足。当我将以下约束提供给Z3时(例如here),它给出了一个近乎即时的答案:UNSAT。但是,如果我在C#程序中证明了同样的问题(见下文),它就无法推断出UNSAT(在合理的时间内)。
问题:我可以尝试使C#程序与SMT2.0程序一样快?
mov qword ptr [rax], rbx
mov rcx, qword ptr [rax]
C#代码:
(declare-fun RAX!0 () (_ BitVec 64))
(declare-fun RAX!1 () (_ BitVec 64))
(declare-fun RAX!2 () (_ BitVec 64))
(declare-fun RBX!0 () (_ BitVec 64))
(declare-fun RBX!1 () (_ BitVec 64))
(declare-fun RBX!2 () (_ BitVec 64))
(declare-fun RCX!0 () (_ BitVec 64))
(declare-fun RCX!1 () (_ BitVec 64))
(declare-fun RCX!2 () (_ BitVec 64))
(declare-fun MEM!0 () (Array (_ BitVec 64) (_ BitVec 8)))
(declare-fun MEM!1 () (Array (_ BitVec 64) (_ BitVec 8)))
(declare-fun MEM!2 () (Array (_ BitVec 64) (_ BitVec 8)))
(assert (= RAX!1 RAX!0))
(assert (= RBX!1 RBX!0))
(assert (= RCX!1 RCX!0))
(assert (let ((a!1 (store (store (store MEM!0 RAX!0 ((_ extract 7 0) RBX!0))
(bvadd #x0000000000000001 RAX!0)
((_ extract 15 8) RBX!0))
(bvadd #x0000000000000002 RAX!0)
((_ extract 23 16) RBX!0))))
(let ((a!2 (store (store (store a!1
(bvadd #x0000000000000003 RAX!0)
((_ extract 31 24) RBX!0))
(bvadd #x0000000000000004 RAX!0)
((_ extract 39 32) RBX!0))
(bvadd #x0000000000000005 RAX!0)
((_ extract 47 40) RBX!0))))
(= MEM!1
(store (store a!2
(bvadd #x0000000000000006 RAX!0)
((_ extract 55 48) RBX!0))
(bvadd #x0000000000000007 RAX!0)
((_ extract 63 56) RBX!0))))))
(assert (= RAX!2 RAX!1))
(assert (= RBX!2 RBX!1))
(assert (= RCX!2
(concat (select MEM!1 (bvadd #x0000000000000007 RAX!1))
(select MEM!1 (bvadd #x0000000000000006 RAX!1))
(select MEM!1 (bvadd #x0000000000000005 RAX!1))
(select MEM!1 (bvadd #x0000000000000004 RAX!1))
(select MEM!1 (bvadd #x0000000000000003 RAX!1))
(select MEM!1 (bvadd #x0000000000000002 RAX!1))
(select MEM!1 (bvadd #x0000000000000001 RAX!1))
(select MEM!1 RAX!1))))
(assert (= MEM!2 MEM!1))
(assert (not (= RBX!2 RCX!2)))
答案 0 :(得分:1)
遗憾的是,我无法运行C#程序来使用它。但是我注意到你打电话给Simplify
:
solver.Assert(ctx.MkEq(mem1, memX7).Simplify() as BoolExpr);
我很好奇为什么你需要这个电话?也许那是罪魁祸首?
要尝试的另一件事是使用未解释的函数来表示内存,而不是Array
。 UF通常更容易处理,它们在我的个人经历中提供了大致相同的抽象。
查看C#界面生成的SMT-Lib可能是个好主意,看看翻译是否与你想象的有很大不同。我想你可以使用以下函数来做到这一点:https://github.com/Z3Prover/z3/blob/master/src/api/dotnet/AST.cs#L195