Główną trudnością jest wymyślenie odpowiedniego niezmiennika pętli while. Tu, będzie to zdanie:
∀ i (1 ≤ i < m) ⇒ A[i] < 0 ∧
∀ j (m ≤ j < r) ⇒ A[j] = 0 ∧
∀ k (w < j ≤ N) ⇒ A[k] > 0 ∧
1 ≤ m ≤ r ∧
r-1 ≤ w ≤ N ∧
N > 0
oznaczane przez N(m,r,w). Poniżej znajduje się program wraz z anotacjami i dowody, że anotacje wraz z kodem który otaczają są poprawnymi trójkami Hoare'a.
// N > 0
1:m:=1; r:=1; w:=N;
// N(m,r,w)
2:while r <= w do
// N(m,r,w) ∧ r ≤ w
3: if A[r]=0 then
// N(m,r,w) ∧ r ≤ w ∧ A[r] = 0
// N(m,r+1,w)
4: r:=r+1
// N(m,r,w)
else
5: if A[r]<0 then begin
// N(m,r,w) ∧ r ≤ w ∧ A[r] < 0
6: pom:=A[r]; A[r]:=A[m]; A[m]:=pom;
// N(m+1,r+1,w) ∧ r ≤ w
7: m:=m+1; r:=r+1;
// N(m,r,w)
end
8: else begin
// N(m,r,w) ∧ r ≤ w ∧ A[r] > 0
9: pom:=A[r]; A[r]:=A[w]; A[w]:=pom;
// N(m,r,w-1) ∧ r ≤ w
10: w:=w-1;
// N(m,r,w)
11: end;
// N(m,r,w) ∧ r-1=w
- Korzystamy z reguły na przypisanie. N(m,r,w) z wartościami m=1, r=1, w=1 jest równe
∀ i (1 ≤ i < 1) ⇒ A[i] < 0 ∧
∀ j (m ≤ j < 1) ⇒ A[j] = 0 ∧
∀ k (N < j ≤ N) ⇒ A[k] > 0 ∧
1 ≤ 1 ≤ 1 ∧
0 ≤ N ≤ N ∧
N > 0
i jest trywialnie prawdziwe
- Korzystamy z reguły na while; trzeba pokazać, że N(m,r,w) jest niezmiennikiem ciała pętli, czyli że z N(m,r,w) ∧ r ≤ w po wykonaniu pętli zachodzi N(m,r,w)
- Korzystamy z reguły na if; trzeba pokazać, że z N(m,r,w) ∧ r ≤ w po wykonaniu każdej gałęzi if-a zachodzi N(m,r,w)
- Korzystając z reguły na przypisanie otrzymujemy, że N(m,r+1,w) powinno być prawdziwe przed instrukcją 4. A więc musimy dowieść implikacji
N(m,r,w) ∧ r ≤ w ∧ A[r] = 0 ⇒ N(m,r+1,w)
N(m,r,w) z wstawionym r+1 na miejsce r ma postać
∀ i (1 ≤ i < m) ⇒ A[i] < 0 ∧
∀ j (m ≤ j < r+1) ⇒ A[j] = 0 ∧
∀ k (w < j ≤ N) ⇒ A[k] > 0 ∧
1 ≤ m ≤ r+1 ∧
r+1-1 ≤ w ≤ N ∧
N > 0
z czego trywialnie wynika
∀ i (1 ≤ i < m) ⇒ A[i] < 0 ∧
∀ j (m ≤ j < r) ⇒ A[j] = 0 ∧ A[r]=0 ∧
∀ k (w < j ≤ N) ⇒ A[k] > 0 ∧
1 ≤ m ∧ w ≤ N ∧ r ≤w ∧ N > 0
Brakuje
co jest równoważne
∀ i (1 ≤ i < m) ⇒ A[i] < 0 ∧
∀ j (m ≤ j < r) ⇒ A[j] = 0 ∧ A[r]=0 ∧
∀ k (w < j ≤ N) ⇒ A[k] > 0 ∧
1 ≤ m ≤ r+1 ∧
r ≤ w ≤ N ∧
N > 0