程序驗證(十):演繹驗證(上)

程序驗證(十):演繹驗證(上)

基礎路徑(Basic Approach)

給定一個程序cc,由以下specification註解:
{P}c{Q}\{P\}c\{Q\}
爲了證明這個三元組,我們構造一個驗證條件(verification condition, VC)的集合

  • 每個VC都是某個理論的一階公式
  • 如果所有的VC都是永真的,那麼{P}c{Q}\{P\}c\{Q\}就是永真的

謂詞轉換器

給定一個斷言QQ和一個程序cc,一個謂詞轉換器(predicate transformer)是一個函數,輸出另一個斷言
最弱前置條件(weakest precondition)謂詞轉換器產生一個wp(c,Q)wp(c,Q),使得

  • [wp(c,Q)]c[Q][wp(c,Q)]c[Q]是永真的,且
  • 對於任何滿足[P]c[Q][P]c[Q]PPPwp(c,Q)P\Rightarrow wp(c,Q),也就是說,wp(c,Q)wp(c,Q)是這種斷言中最弱的。
    廣義最弱前置條件(weakest liberal precondition)謂詞轉換器產生一個wlp(c,Q)wlp(c,Q),使得
  • {wlp(c,Q)}c{Q}\{wlp(c,Q)\}c\{Q\}是永真的,且
  • wlp(c,Q)wlp(c,Q)是這種斷言中最弱的
    wlpwlp爲我們提供了一種逆向的思路,這也符合我們的直覺。

wlpwlp的定義

我們用霍爾三元組來定義wlpwlp
比如wlp(y:=x+1,(x.x<zx<y)x+1y)wlp(y:=x+1, (\forall x.x<z\to x<y)\to x+1\le y)=?
注意,答案並不是(x.x<zx<x+1)x+1x+1(\forall x.x<z\to x<x+1)\to x+1\le x+1
因爲當我們用x+1x+1替換yy以處理(x.x<zx<y)(\forall x.x<z\to x<y)時,變量xx是被捕獲的(captured)

捕獲避免代入(capture-avoiding substitution)

當我們擴展P[a/x]P[a/x]時,我們需要:

  • 只代入xx的自由形式(free occurence)
  • aa中不自由的變量重命名以避免捕獲

數組賦值規則

數組賦值的霍爾規則可以表示爲:
AsgnArr {Q[xa1a2/x]}x[a1]:=a2{Q}AsgnArr~\frac{}{\{Q[x\langle a_1\triangleleft a_2\rangle /x]\}x[a_1]:=a_2\{Q\}}
相應的轉換器即爲
wlp(x[a1]:=a2,Q)=Q[xa1a2/x]wlp (x[a_1]:=a_2,Q)=Q[x\langle a_1\triangleleft a_2\rangle /x]
舉例:
計算wlp(b[i]:=5,b[i]=5)wlp(b[i]:=5,b[i]=5)
wlp(b[i]:=5,b[i]=5)=(b5[i]=5)=(5=5)=truewlp(b[i]:=5,b[i]=5)=(b\langle\triangleleft 5\rangle [i]=5)=(5=5)=true
計算wlp(b[n]:=x,i.1i<nb[i]b[i+1])wlp(b[n]:=x,\forall i.1\le i<n\to b[i]\le b[i+1])
進行代入
wlp(b[n]:=x,i.1i<nb[i]b[i+1])=i.1i<n(bx)[i](bnx)[i+1]=(bnx)[n1](bnx)[n]i.1i<n1(bnx)[i](bnx)[i+1]wlp(b[n]:=x,\forall i.1\le i<n\to b[i]\le b[i+1])=\forall i.1\le i<n\to (b\langle\triangleleft x\rangle)[i]\le (b\langle n\triangleleft x\rangle)[i+1]=(b\langle n\triangleleft x\rangle)[n-1]\le (b\langle n\triangleleft x\rangle)[n]\wedge \forall i.1\le i<n-1\to (b\langle n\triangleleft x\rangle)[i]\le (b\langle n\triangleleft x\rangle)[i+1]

序列(sequencing)

依據霍爾規則
Seq {P}c1{P}{P}c2{Q}{P}c1;c2{Q}Seq~\frac{\{P\}c_1\{P'\}\qquad\{P'\}c_2\{Q\}}{\{P\}c_1;c_2\{Q\}}
相應的謂詞轉換器即爲
wlp(c1;c2,Q)=wlp(c1,wlp(c2,Q))wlp(c_1;c_2,Q)=wlp(c_1,wlp(c_2,Q))

條件

依據霍爾規則
If {Pb}c1{Q}{P¬b}c2{Q}{P}if b then c1 else c2{Q}If~\frac{\{P\wedge b\}c_1\{Q\}\qquad\{P\wedge\neg b\}c_2\{Q\}}{\{P\}\mathbf{if}~b~\mathbf{then}~c_1~\mathbf{else}~c_2\{Q\}}
相應的轉換器即爲
wlp(if b then c1 else c2,Q)=(bwlp(c1,Q))(¬bwlp(c2,Q))wlp(\mathbf{if}~b~\mathbf{then}~c_1~\mathbf{else}~c_2,Q)\\ =(b\to wlp(c_1,Q))\wedge (\neg b\to wlp(c_2,Q))

while循環

依據等價關係
while b do cif b then c;while b do c else skip\mathbf{while}~b~\mathbf{do}~c\equiv \mathbf{if}~b~\mathbf{then}~c;\mathbf{while}~b~\mathbf{do}~c~\mathbf{else}~\mathbf{skip}
相應的wlpwlp即爲
此處略,最後轉了個圈又回來了。

近似最弱前置條件

一般來說,我們無法總是算出循環的wlpwlp,比如上面的情況。
但是,我們可以藉助於循環不變式來近似它
下面,我們使用這種方式表示循環:
while b do{I}c\mathbf{while}~b~\mathbf{do}\{I\}c
這裏II是由程序員提供的循環不變量
最爲直觀的想法是令
wlp(while b do{I}c,Q)=Iwlp(\mathbf{while}~b~\mathbf{do}\{I\}c,Q)=I
但此時II可能不是最弱的前置條件
如果我們草率地認爲wlp(while b do{I}c,Q)=Iwlp(\mathbf{while}~b~\mathbf{do}\{I\}c,Q)=I,我們漏了兩件事情:

  • 沒有檢查I¬bI\wedge\neg b得到QQ
  • 我們不知道II是否真的是一個循環不變式

所以我們需要構造一個額外的驗證條件(verification condition)的集合,
vc(while b do{I}c,Q)={I¬bQIbwlp(c,I)vc(\mathbf{while}~b~\mathbf{do}\{I\}c,Q)=\begin{cases}I\wedge \neg b\Rightarrow Q\\I\wedge b\Rightarrow wlp(c,I)\end{cases}
爲了在執行循環後確保QQ能夠實現,需要滿足兩個條件:

  • vc(while b do{I}c,Q)vc(\mathbf{while}~b~\mathbf{do}\{I\}c,Q)中的每一個公式都是永真的
  • wlp(while b do{I}c,Q)=Iwlp(\mathbf{while}~b~\mathbf{do}\{I\}c,Q)=I一定是永真的

構造vc

while是唯一一個引入額外條件的命令,但是其他的聲明可能也包含循環,所以:

  • vc(x:=a,Q)=vc(x:=a,Q)=\empty
  • vc(c1;c2,Q)=vc(c1,wlp(c2,Q))vc(c2,Q)vc(c_1;c_2,Q)=vc(c_1,wlp(c_2,Q))\cup vc(c_2,Q)
  • vc(if b then c1 else c2,Q)=vc(c1,Q)vc(c2,Q)vc(\mathbf{if}~b~\mathbf{then}~c_1~\mathbf{else}~c_2,Q)=vc(c_1,Q)\cup vc(c_2,Q)

綜合

綜上,我們得到驗證{P}c{Q}\{P\}c\{Q\}的通用方法:

  1. 計算P=wlp(c,Q)P'=wlp(c,Q)
  2. 計算vc(c,Q)vc(c,Q)
  3. 檢查PPP\to P'的永真性
  4. 檢查每個Fvc(c,Q)F\in vc(c,Q)的永真性

若3,4檢驗均通過,那麼{P}c{Q}\{P\}c\{Q\}是永真的,但反之不一定成立,因爲循環不變式可能不是最弱的前置條件。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章