我最近在Z3中觀察到了幾個關於觸發的行爲,我不明白。不幸的是,這些例子來自大型的Boogie文件,所以我想我現在會抽象地描述它們,只是爲了看看是否有明顯的答案。但是,如果具體文件會更好,我可以附加它們。在Z3觸發問題
基本上有三個問題,雖然第三個可能是第二個的特例。據我的理解,沒有預期的行爲,但也許我錯過了一些東西。任何幫助將不勝感激!
首先:在我的程序瑣碎的等式似乎就觸發關切地被忽略。例如,如果t1
是應該匹配的模式進行量化公理,如果我加一條線的形式我的不羈程序
然後t1
不不似乎習慣作爲觸發一個術語用於量化的公理。我明確添加了該行,以便提供t1
作爲證明者的觸發器,我經常在Boogie程序中執行此操作。
如果不是我引入一個額外的功能,說
function f(x : same_type_as_t1) : bool
{ true }
和現在,而不是添加一行
assert f(t1);
到我的程序,然後t1
確實似乎被用來作爲觸發Z3。我已經檢查過前一個程序的Z3翻譯,並且t1
上的(平凡的)等式確實存在於布吉翻譯中(即,這不是布吉試圖做一些聰明的事情)。
其次:輔助模式似乎不能正常工作。例如,我有一個計劃,其中一個公理的形式
axiom (forall ... :: {t1,t2} {t3,t4,t5} .....);
和一種情況,即t3, t4
和t5
都發生了。該程序未能驗證,顯然是因爲該公理沒有實例化。但是,如果我將公理改寫爲
axiom (forall ... :: {t3,t4,t5} {t1,t2} .....);
然後程序驗證。在這兩種情況下,運行Boogie的時間大約是3秒,模式生存到Z3輸出。
三:這很可能是第二個問題的症狀,但是我對以下行爲感到驚訝:
我寫形式的公理
,並在發生t2
和t3
的情況下,第一個公理沒有被實例化(我預料它是,因爲在第二個公理的實例化後,發生了t1
)。但是,如果我重寫爲
axiom (forall .. :: {t2,t3} {t1,t2} ....);
axiom (forall ... :: {t2,t4} {t2,t3} ...some expression involving t1...);
那麼第一個公理就被實例化了。但是,如果由於某種原因二次模式沒有被普遍使用,那麼這也將解釋這種行爲。
如果明確的例子是有用的,我可以附加很長的例子,並可以嘗試減少它們(但當然,觸發問題有點微妙,所以我可能會失去行爲,如果我舉例說明太小)。
非常感謝您的任何意見!
亞歷夏天
編輯:這裏是部分地示出了上述第二和第三行爲的例子。我附加了Boogie代碼,使其更容易閱讀,但如果它更有用,我也可以複製或通過電子郵件發送Z3輸入。我已經刪除了幾乎所有原始的Boogie代碼,但似乎很難使其更簡單,而不會完全失去行爲。
已經低於代碼我原來的例子巧妙地表現不同,但我認爲這是足夠接近。基本上,下面標記爲(1)的公理未設法使其第二模式集合匹配。如果我將公理(1)註釋掉,而是用(兩個當前註釋的)公理(2)和(3)替換它們,這兩個公理(2)和(3)就是兩個模式集合中的每一個的原始副本,然後程序將進行驗證。事實上,在這個特殊情況下,有足夠的公理(2)。在我原來的代碼中(在我將它裁減之前),公理(1)中的兩個模式集合的順序也是足夠的,但在我的小代碼中似乎不再是這種情況。
type ref;
type HeapType;
function vals1(HeapType, ref) returns (ref);
function vals2(HeapType, ref) returns (ref);
function vals3(HeapType, ref) returns (ref);
function heap_trigger(HeapType) returns (bool);
function trigger1(ref) returns (bool);
function trigger2(ref) returns (bool);
axiom (forall Heap: HeapType, this: ref :: {vals1(Heap, this)} (vals1(Heap, this) == vals3(Heap,this)));
axiom (forall Heap: HeapType, this: ref :: {vals2(Heap, this)} trigger2(this));
// (1)
axiom (forall Heap: HeapType, this: ref :: {vals1(Heap, this)} {trigger1(this), heap_trigger(Heap), trigger2(this)} (vals1(Heap, this) == vals2(Heap, this)));
// (2)
// axiom (forall Heap: HeapType, this: ref :: {trigger1(this), heap_trigger(Heap), trigger2(this)} (vals1(Heap, this) == vals2(Heap, this)));
// (3)
// axiom (forall Heap: HeapType, this: ref :: {vals1(Heap, this)} (vals1(Heap, this) == vals2(Heap, this)));
procedure test(Heap:HeapType, this:ref)
{
assume trigger1(this); assume heap_trigger(Heap);
assert (vals2(Heap, this) == vals3(Heap,this));
}
尊敬的萊昂納多, 非常感謝您的快速回復。這是非常有用的知道 - 我敢肯定你知道,通過大型示例來追蹤觸發問題非常困難。有沒有可能配置你描述的行爲?據我所知,僅僅提到一個術語是匹配模式的充分標準,所以我們(錯誤地)認爲特定的編碼問題不是由於觸發引起的。其實,我讀了你的帖子http://stackoverflow.com/questions/10949633/z3-real-arithmetic-and-statistics,我完全同意 - 我真的不想失去觸發器:) – 2012-07-26 16:35:14
我想知道,因爲(就像你上面提到的那樣),爲了觸發更多模式而手動引入額外術語的方式都沒有保證永遠有效,有沒有可能有明確的語法來做到這一點?即,我們可以有一種方法來爲電子圖匹配添加候選詞,而不需要在原始問題中給出任何特定的邏輯含義。即使Z3從不改變其簡化行爲,它也會比引入額外的功能更簡單(特別是使用Boogie等類型的語言),並且可能也更易讀。 – 2012-07-26 16:53:29
p.s. repro在編輯中添加了上述內容。 – 2012-07-30 09:42:51