触发器,Z3中的#instances

时间:2017-08-29 13:10:05

标签: triggers z3

我的问题来自large Boogie file。我将在这里解释相关部分。

我为包含7个字段Msg的邮件声明了新类型tID, stype, bal, acc, mbal, mval, val。这些字段在Boogie中声明为函数。然后我声明了72个Msg常量M1, ..., M72和它们的字段的相应值。您可以看到以下示例:

type Msg;
const unique M1: Msg;

function tID (Msg) returns (int);
function stype (Msg) returns (Str);
function bal (Msg) returns (int);
function acc (Msg) returns (Proc);
function mbal (Msg) returns (int);
function mval (Msg) returns (Val);
function val (Msg) returns (Val);

axiom (tID (M1) == 1);
axiom (stype (M1) == s1a);
axiom (bal (M1) == 1);
axiom (acc (M1) == ProcNull);
axiom (mbal (M1) == -2);
axiom (mval (M1) == ValNull);
axiom (val (M1) == ValNull);

其中Proc, Str是某些类型,s1a, ProcNull, ValNull是一些常量。然后我宣布一个公理,说明当{且仅{}}的每个字段时,两条消息m1, m2是相等的。这个公理使用了触发器m1, m2

MsgComp(m1, m2)

然后,我声明一个新变量function MsgComp(m1, m2: Msg): bool { true } axiom (forall m1, m2: Msg :: {MsgComp(m1, m2)} m1 == m2 <==> (tID(m1) == tID(m2) && stype(m1) == stype(m2) && acc(m1) == acc(m2) && bal(m1) == bal(m2) && mbal(m1) == mbal(m2) && mval(m1) == mval(m2) && val(m1) == val(m2))); 并为其字段分配任意值,使m等于mM1。我没有明确说明M2,但我们可以用上述公理来证明这个断言(第786行)。

m == M1 || m == M2

但是,如果我想检查assert (MsgComp(cMsg, M1) && MsgComp(cMsg, M2) && (cMsg == M1 || cMsg == M2)); 是否为m之一,Boogie会显示相应的断言可能不成立。

M1, ..., M72

我发现,如果我检查最多32个常数的断言,Boogie可以验证它。为什么Boogie或Z3不能用更多的常量来验证它?

1 个答案:

答案 0 :(得分:2)

在我的机器上,即使是两个常量的情况,检查也不会成功。

我能够通过将它们更改为以下形式来检查两个检查

 assert MsgComp(cMsg, M1) && MsgComp(cMsg, M2) ==> (cMsg == M1 || cMsg == M2);

(请注意,中间的&&已更改为==>。)

这也适用于72值的断言。

我不知道为什么这种变化很重要。看起来在触发发生之前忽略或简化了合取。