程序驗證(十):演繹驗證(上)
基礎路徑(Basic Approach)
給定一個程序c,由以下specification註解:
{P}c{Q}
爲了證明這個三元組,我們構造一個驗證條件(verification condition, VC)的集合
- 每個VC都是某個理論的一階公式
- 如果所有的VC都是永真的,那麼{P}c{Q}就是永真的
謂詞轉換器
給定一個斷言Q和一個程序c,一個謂詞轉換器(predicate transformer)是一個函數,輸出另一個斷言
最弱前置條件(weakest precondition)謂詞轉換器產生一個wp(c,Q),使得
- [wp(c,Q)]c[Q]是永真的,且
- 對於任何滿足[P]c[Q]的P,P⇒wp(c,Q),也就是說,wp(c,Q)是這種斷言中最弱的。
廣義最弱前置條件(weakest liberal precondition)謂詞轉換器產生一個wlp(c,Q),使得
- {wlp(c,Q)}c{Q}是永真的,且
- wlp(c,Q)是這種斷言中最弱的
wlp爲我們提供了一種逆向的思路,這也符合我們的直覺。
wlp的定義
我們用霍爾三元組來定義wlp
比如wlp(y:=x+1,(∀x.x<z→x<y)→x+1≤y)=?
注意,答案並不是(∀x.x<z→x<x+1)→x+1≤x+1
因爲當我們用x+1替換y以處理(∀x.x<z→x<y)時,變量x是被捕獲的(captured)
捕獲避免代入(capture-avoiding substitution)
當我們擴展P[a/x]時,我們需要:
- 只代入x的自由形式(free occurence)
- 將a中不自由的變量重命名以避免捕獲
數組賦值規則
數組賦值的霍爾規則可以表示爲:
AsgnArr {Q[x⟨a1◃a2⟩/x]}x[a1]:=a2{Q}
相應的轉換器即爲
wlp(x[a1]:=a2,Q)=Q[x⟨a1◃a2⟩/x]
舉例:
計算wlp(b[i]:=5,b[i]=5)
wlp(b[i]:=5,b[i]=5)=(b⟨◃5⟩[i]=5)=(5=5)=true
計算wlp(b[n]:=x,∀i.1≤i<n→b[i]≤b[i+1])
進行代入
wlp(b[n]:=x,∀i.1≤i<n→b[i]≤b[i+1])=∀i.1≤i<n→(b⟨◃x⟩)[i]≤(b⟨n◃x⟩)[i+1]=(b⟨n◃x⟩)[n−1]≤(b⟨n◃x⟩)[n]∧∀i.1≤i<n−1→(b⟨n◃x⟩)[i]≤(b⟨n◃x⟩)[i+1]
序列(sequencing)
依據霍爾規則
Seq {P}c1;c2{Q}{P}c1{P′}{P′}c2{Q}
相應的謂詞轉換器即爲
wlp(c1;c2,Q)=wlp(c1,wlp(c2,Q))
條件
依據霍爾規則
If {P}if b then c1 else c2{Q}{P∧b}c1{Q}{P∧¬b}c2{Q}
相應的轉換器即爲
wlp(if b then c1 else c2,Q)=(b→wlp(c1,Q))∧(¬b→wlp(c2,Q))
while循環
依據等價關係
while b do c≡if b then c;while b do c else skip
相應的wlp即爲
此處略,最後轉了個圈又回來了。
近似最弱前置條件
一般來說,我們無法總是算出循環的wlp,比如上面的情況。
但是,我們可以藉助於循環不變式來近似它
下面,我們使用這種方式表示循環:
while b do{I}c
這裏I是由程序員提供的循環不變量
最爲直觀的想法是令
wlp(while b do{I}c,Q)=I
但此時I可能不是最弱的前置條件
如果我們草率地認爲wlp(while b do{I}c,Q)=I,我們漏了兩件事情:
- 沒有檢查I∧¬b得到Q
- 我們不知道I是否真的是一個循環不變式
所以我們需要構造一個額外的驗證條件(verification condition)的集合,
vc(while b do{I}c,Q)={I∧¬b⇒QI∧b⇒wlp(c,I)
爲了在執行循環後確保Q能夠實現,需要滿足兩個條件:
- vc(while b do{I}c,Q)中的每一個公式都是永真的
- wlp(while b do{I}c,Q)=I一定是永真的
構造vc
while是唯一一個引入額外條件的命令,但是其他的聲明可能也包含循環,所以:
- vc(x:=a,Q)=∅
- vc(c1;c2,Q)=vc(c1,wlp(c2,Q))∪vc(c2,Q)
- vc(if b then c1 else c2,Q)=vc(c1,Q)∪vc(c2,Q)
綜合
綜上,我們得到驗證{P}c{Q}的通用方法:
- 計算P′=wlp(c,Q)
- 計算vc(c,Q)
- 檢查P→P′的永真性
- 檢查每個F∈vc(c,Q)的永真性
若3,4檢驗均通過,那麼{P}c{Q}是永真的,但反之不一定成立,因爲循環不變式可能不是最弱的前置條件。