[英]Eva method to compute intervals [frama-c]
我的目標是了解 Eva 如何縮小變量的區間。 例如:
unsigned int nondet_uint(void);
int main()
{
unsigned int x=nondet_uint();
unsigned int y=nondet_uint();
//@ assert x >= 20 && x <= 30;
//@ assert y <= 60;
//@ assert(x>=y);
return 0;
}
所以,我們有 x=[20,30] 和 y=[0,60]。 然而,來自 Eva 的結果將 y 縮小到 [0,30],這是域可能有效的地方。
[eva] ====== VALUES COMPUTED ======
[eva:final-states] Values at end of function main:
x ∈ [20..30]
y ∈ [0..30]
__retres ∈ {0}
我嘗試了 Eva 插件的一些選項,但沒有一個顯示它的步驟。 我可以請您提供有關如何計算這些值的方法或出版物嗎?
我嘗試了 Eva 插件的一些選項,但沒有一個顯示它的步驟。
跟蹤評估的最有效方法不是通過命令行選項,而是通過在代碼中添加Frama_C_show_each(exp)
語句。 這些是特殊的函數調用,在分析過程中,它們會發出包含在其中的表達式的值。 它們在循環中特別有用,例如查看何時觸發加寬,循環計數器值會發生什么變化。
請注意,即使對於非常小的程序,顯示所有中間評估和減少步驟也會非常冗長。 默認情況下,此信息不會公開,因為它太密集且很少有用。
首先,嘗試添加Frama_C_show_each
語句,並使用 Frama-C GUI 查看結果。 它允許關注代碼中的任何表達式,並在“值”選項卡中顯示給定表達式的值,在所選語句中,對於每個調用堆棧。 您還可以按Ctrl+E
並鍵入任意表達式以在該語句中計算其值。
如果您想了解有關這些值、它們的減少和整體機制的更多詳細信息,請參閱以下部分。
您的問題與 Eva 中抽象解釋引擎使用的值有關。
Eva 用戶手冊的第 3 章描述了引擎使用的抽象,它們是:
-eva-ilevel
修改,在 Frama-C 22 上默認設置為 8);[2..42],2%10
是包含{2, 12, 22, 32, 42}
的集合。 在簡單的情況下,例如[2..42]
,包括 2 到 42 之間的所有整數;為什么這一切都是必要的? 因為如果不了解其中的一些細節,您將很難理解為什么分析有時是精確的,有時是不精確的。
請注意,文檔中使用了術語減少,而不是收縮。 所以在尋找線索的時候,在Eva手冊中尋找與reduce相關的詞。
例如,在以下代碼中:
int a = Frama_C_interval(-5, 5);
if (a != 0) {
//@ assert a != 0;
int b = 5 / a;
}
默認情況下,分析將無法從if
內的區間中刪除 0,因為[-5..-1];[1..5]
不是區間,而是區間的不相交聯合。 但是,如果元素數量低於-eva-ilevel
,則分析會將其轉換為一個小集合,並獲得精確的結果。 因此,更改某些分析選項將導致不同的范圍和不同的結果。
在某些情況下,您可以強制 Eva 使用析取進行計算,例如通過添加拆分ACSL 注釋,例如//@ split a < b || a >= b;
//@ split a < b || a >= b;
. 但是您仍然需要為分析提供一些“燃料”,以便分別評估兩個分支。 最簡單的方法是使用-eva-precision N
,其中N
是 0 到 11 之間的整數。 N
越高,允許發生的分裂越多,但分析可能需要的時間越長。
請注意,為了確保分析的終止,使用了一些機制,例如加寬。 沒有它,一個簡單的循環可能需要數十億個評估步驟才能終止。 這種機制可能會引入額外的值,從而導致分析不太精確。
最后,還有一些抽象域(選項-eva-domains
)允許除上述默認值之外的其他類型的值。 例如,符號域允許在負值、零值和正值之間拆分值,並且可以避免上例中的不精確性。 Eva 用戶手冊包含每個域的使用示例,指示它們何時有用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.