我的問題來自large Boogie file。我會在這裏解釋相關的部分。觸發器,Z3中的#in
對於有7個字段tID, stype, bal, acc, mbal, mval, val
的消息,我聲明一個新類型Msg
。這些字段在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
和分配任意值到它的電場,使得m
等於M1
或M2
。我沒有明確地說m == M1 || m == M2
,但我們可以用上面的公理證明這個斷言(786行)。
assert (MsgComp(cMsg, M1) && MsgComp(cMsg, M2) && (cMsg == M1 || cMsg == M2));
但是,如果我要檢查是否m
是M1, ..., M72
之一,布吉顯示相應的聲明可能不成立。
assert (MsgComp(cMsg, M1) && ... && MsgComp(cMsg, M72) && (cMsg == M1 || ... || cMsg == M72));
我發現如果我檢查最多32個常量的斷言,布吉可以驗證它。爲什麼Boogie或Z3不能用更多的常量來驗證它?
AFAIK,SMTLib連詞不是短路的,因此可以並行處理。這可以解釋爲什麼觸發器'MsgComp(...)'不一定在原始編碼中可用,而是在你的編碼中。 –