프로그램 증명 program verificationdreameye/pl/slide/pl10.pdf · 2011-05-12 · 1 if foo is...
TRANSCRIPT
프로그램 증명Program Verification•이 프로그램은 실행 중에 절대로 다음의 조
건을 만족해
assert(p!=NULL);*p = 10;
assert(0<=i && i<buffersize);buffer[i]=10;
예제 프로그램프로그램 bar는 어떤 일을
하도록 만들어졌나?
그 일을 제대로 수행하기 위한 초기조건은?
이 프로그램이 실제로 의도한바를 충실히 따르고 있는가?
n > 0 2n
F(�c) = �M
S(M,M�)
S(M1,M2)
log MinEntry
log(| M1 | + | M2 |)
2(2 · 1.0 + 2 · 1.0 + 1 · 0.5)/(6 + 5) = 0.82
a {(true,α)}count {(true,β)}r {(true,β + 1)}α.next {(α �= 0, �)}α.val {(α �= 0,β)}RETV {(α = 0,β + 1− 1), (α �= 0,β + 1)}
a {(true,α)}b {(true,β)}α.n {(α �= 0, �)}α.v {(α �= 0,β)}RETV {(α = 0,β), (α �= 0,β + 2)}
{}, {} � P ⇓ v,M
{}, {} � P : τ
type list = {int x, list next}
let list node = {x:=1, next:={}}in
node.next.x
let x := {a:=1, b:=2} in E
type list = {int x, list next}type tsil = {int x, tsil prev}
let ... {x:=1, next:={}}... {x:=1, prev:={}}
...
∆ � T ∗ : ∆�
Γ,∆ � E : τ
∅ � T ∗ : ∆ ∅,∆ � E : τ∅,∅ � T ∗ E : τ
1
증명해봐!
Example programs
int foo(int n) { int bar(int n) {local int k, int j; local int k, int j;k := 0; k := 0;j := 1; j := 1;while (k != n) { while (k != n) {k := k + 1; k := k + 1;j := 2*j; j := 2 + j;
} }return(j) return(j);
} }
Wish to prove:
1 If foo is called with parameter n greater than 0, it returns 2n
2 If bar is called with parameter n greater than 0, it returns 1 + 2n
Note: No heap manipulation by above programs.
Supratik Chakraborty (I.I.T. Bombay) A Short Introduction to Hoare Logic June 23, 2008 3 / 34
1 + 2n
{I ∧B} S {I}{I} while B S {I ∧ ¬B}
{P ∧B} S1 {Q} {P ∧ ¬B} S2 {Q}{P} if B then S1 else S2 {Q}
{y + 7 > 42} x := y + 7 {x > 42}
{y = x+ 10 ∧ x = 1} x := y + 7 {y = x� + 10 ∧ x� = 1 ∧ x := x� + 10 + 7}
{y = y + 7− 7 ∧ y + 7 = 18} x := y + 7 {y = x− 7 ∧ x = 18}
{P} x := E {P [x�/x] ∧ (x = E[x�/x])}
{y + 7 > 42} x = y + 7 {x > 42}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0 ∧ x ≥ 0 ∧ y ≥ 0}
{x = 5 ∧ y = 2} z := x+ y {x = 5 ∧ z = 7}
{n ≥ 0 ∧ n2 > 28} m := n+ 1;m := m ∗m {¬(m = 36)}
{∀i.a[i] = 10 ∧ k ≥ 0} a[k] = 0 {∀i.a[i] = 10 ∧ k ≥ 0}
F(�c) = �M
S(M,M�)
S(M1,M2)
log MinEntry
log(| M1 | + | M2 |)
2(2 · 1.0 + 2 · 1.0 + 1 · 0.5)/(6 + 5) = 0.82
a {(true,α)}count {(true,β)}r {(true,β + 1)}α.next {(α �= 0, �)}α.val {(α �= 0,β)}RETV {(α = 0,β + 1− 1), (α �= 0,β + 1)}
a {(true,α)}b {(true,β)}α.n {(α �= 0, �)}α.v {(α �= 0,β)}RETV {(α = 0,β), (α �= 0,β + 2)}
{}, {} � P ⇓ v,M
1
프로그램논리Program Logic
•프로그램과 프로그램 성질을 추론하는 논리
•Hoare Logic, 1969: axiomatic semantics를 정의하는 한 방법
C. A. R. Hoare
{P}S{Q}
F(�c) = �M
S(M,M�)
S(M1,M2)
log MinEntry
log(| M1 | + | M2 |)
2(2 · 1.0 + 2 · 1.0 + 1 · 0.5)/(6 + 5) = 0.82
a {(true,α)}count {(true,β)}r {(true,β + 1)}α.next {(α �= 0, �)}α.val {(α �= 0,β)}RETV {(α = 0,β + 1− 1), (α �= 0,β + 1)}
a {(true,α)}b {(true,β)}α.n {(α �= 0, �)}α.v {(α �= 0,β)}RETV {(α = 0,β), (α �= 0,β + 2)}
{}, {} � P ⇓ v,M
{}, {} � P : τ
type list = {int x, list next}
let list node = {x:=1, next:={}}in
node.next.x
let x := {a:=1, b:=2} in E
type list = {int x, list next}type tsil = {int x, tsil prev}
let ... {x:=1, next:={}}... {x:=1, prev:={}}
...
∆ � T ∗ : ∆�
Γ,∆ � E : τ
∅ � T ∗ : ∆ ∅,∆ � E : τ∅,∅ � T ∗ E : τ
1
Hoare Triple
precondition
program statement
postcondition
P 상태에서 S를 실행하고 끝나면 Q상태가 된다.
Hoare Logic{P}S{Q}
F(�c) = �M
S(M,M�)
S(M1,M2)
log MinEntry
log(| M1 | + | M2 |)
2(2 · 1.0 + 2 · 1.0 + 1 · 0.5)/(6 + 5) = 0.82
a {(true,α)}count {(true,β)}r {(true,β + 1)}α.next {(α �= 0, �)}α.val {(α �= 0,β)}RETV {(α = 0,β + 1− 1), (α �= 0,β + 1)}
a {(true,α)}b {(true,β)}α.n {(α �= 0, �)}α.v {(α �= 0,β)}RETV {(α = 0,β), (α �= 0,β + 2)}
{}, {} � P ⇓ v,M
{}, {} � P : τ
type list = {int x, list next}
let list node = {x:=1, next:={}}in
node.next.x
let x := {a:=1, b:=2} in E
type list = {int x, list next}type tsil = {int x, tsil prev}
let ... {x:=1, next:={}}... {x:=1, prev:={}}
...
∆ � T ∗ : ∆�
Γ,∆ � E : τ
∅ � T ∗ : ∆ ∅,∆ � E : τ∅,∅ � T ∗ E : τ
1
precondition statement postcondition
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0 ∧ x ≥ 0 ∧ y ≥ 0}
{x = 5 ∧ y = 2} z := x+ y {x = 5 ∧ z = 7}
{n ≥ 0 ∧ n2 > 28} m := n+ 1;m := m ∗m {¬(m = 36)}
{∀i.a[i] = 10 ∧ k ≥ 0} a[k] = 0 {∀i.a[i] = 10 ∧ k ≥ 0}
F(�c) = �M
S(M,M�)
S(M1,M2)
log MinEntry
log(| M1 | + | M2 |)
2(2 · 1.0 + 2 · 1.0 + 1 · 0.5)/(6 + 5) = 0.82
a {(true,α)}count {(true,β)}r {(true,β + 1)}α.next {(α �= 0, �)}α.val {(α �= 0,β)}RETV {(α = 0,β + 1− 1), (α �= 0,β + 1)}
a {(true,α)}b {(true,β)}α.n {(α �= 0, �)}α.v {(α �= 0,β)}RETV {(α = 0,β), (α �= 0,β + 2)}
{}, {} � P ⇓ v,M
{}, {} � P : τ
type list = {int x, list next}
let list node = {x:=1, next:={}}in
node.next.x
let x := {a:=1, b:=2} in E
type list = {int x, list next}type tsil = {int x, tsil prev}
let ... {x:=1, next:={}}... {x:=1, prev:={}}
...
1
invalid
Assignment{Q[E/x]} x := E {Q}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0 ∧ x ≥ 0 ∧ y ≥ 0}
{x = 5 ∧ y = 2} z := x+ y {x = 5 ∧ z = 7}
{n ≥ 0 ∧ n2 > 28} m := n+ 1;m := m ∗m {¬(m = 36)}
{∀i.a[i] = 10 ∧ k ≥ 0} a[k] = 0 {∀i.a[i] = 10 ∧ k ≥ 0}
F(�c) = �M
S(M,M�)
S(M1,M2)
log MinEntry
log(| M1 | + | M2 |)
2(2 · 1.0 + 2 · 1.0 + 1 · 0.5)/(6 + 5) = 0.82
a {(true,α)}count {(true,β)}r {(true,β + 1)}α.next {(α �= 0, �)}α.val {(α �= 0,β)}RETV {(α = 0,β + 1− 1), (α �= 0,β + 1)}
a {(true,α)}b {(true,β)}α.n {(α �= 0, �)}α.v {(α �= 0,β)}RETV {(α = 0,β), (α �= 0,β + 2)}
{}, {} � P ⇓ v,M
{}, {} � P : τ
type list = {int x, list next}
let list node = {x:=1, next:={}}in
node.next.x
let x := {a:=1, b:=2} in E
type list = {int x, list next}type tsil = {int x, tsil prev}
let ... {x:=1, next:={}}... {x:=1, prev:={}}
...
1
추론의 방향이 실행의 역방향이다.Q에 있는 x를 원래 값으로 돌린다.
{y = x+ 10 ∧ x = 1} x := y + 7 {y = x� + 10 ∧ x� = 1 ∧ x := x� + 10 + 7}
{y = y + 7− 7 ∧ y + 7 = 18} x := y + 7 {y = x− 7 ∧ x = 18}
{P} x := E{P [
{y + 7 > 42} x = y + 7 {x > 42}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0 ∧ x ≥ 0 ∧ y ≥ 0}
{x = 5 ∧ y = 2} z := x+ y {x = 5 ∧ z = 7}
{n ≥ 0 ∧ n2 > 28} m := n+ 1;m := m ∗m {¬(m = 36)}
{∀i.a[i] = 10 ∧ k ≥ 0} a[k] = 0 {∀i.a[i] = 10 ∧ k ≥ 0}
F(�c) = �M
S(M,M�)
S(M1,M2)
log MinEntry
log(| M1 | + | M2 |)
2(2 · 1.0 + 2 · 1.0 + 1 · 0.5)/(6 + 5) = 0.82
a {(true,α)}count {(true,β)}r {(true,β + 1)}α.next {(α �= 0, �)}α.val {(α �= 0,β)}RETV {(α = 0,β + 1− 1), (α �= 0,β + 1)}
a {(true,α)}b {(true,β)}α.n {(α �= 0, �)}α.v {(α �= 0,β)}RETV {(α = 0,β), (α �= 0,β + 2)}
{}, {} � P ⇓ v,M
{}, {} � P : τ
type list = {int x, list next}
let list node = {x:=1, next:={}}in
node.next.x
let x := {a:=1, b:=2} in E
1
{y + 7 > 42} x := y + 7 {x > 42}
{y = x+ 10 ∧ x = 1} x := y + 7 {y = x� + 10 ∧ x� = 1 ∧ x := x� + 10 + 7}
{y = y + 7− 7 ∧ y + 7 = 18} x := y + 7 {y = x− 7 ∧ x = 18}
{P} x := E{P [
{y + 7 > 42} x = y + 7 {x > 42}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0 ∧ x ≥ 0 ∧ y ≥ 0}
{x = 5 ∧ y = 2} z := x+ y {x = 5 ∧ z = 7}
{n ≥ 0 ∧ n2 > 28} m := n+ 1;m := m ∗m {¬(m = 36)}
{∀i.a[i] = 10 ∧ k ≥ 0} a[k] = 0 {∀i.a[i] = 10 ∧ k ≥ 0}
F(�c) = �M
S(M,M�)
S(M1,M2)
log MinEntry
log(| M1 | + | M2 |)
2(2 · 1.0 + 2 · 1.0 + 1 · 0.5)/(6 + 5) = 0.82
a {(true,α)}count {(true,β)}r {(true,β + 1)}α.next {(α �= 0, �)}α.val {(α �= 0,β)}RETV {(α = 0,β + 1− 1), (α �= 0,β + 1)}
a {(true,α)}b {(true,β)}α.n {(α �= 0, �)}α.v {(α �= 0,β)}RETV {(α = 0,β), (α �= 0,β + 2)}
{}, {} � P ⇓ v,M
{}, {} � P : τ
type list = {int x, list next}
let list node = {x:=1, next:={}}in
node.next.x
1
{y = x+ 10 ∧ x = 1} x := y {y = x� + 10 ∧ x� = 1 ∧ x := x� + 10}
{y + 7 > 42} x = y + 7 {x > 42}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0 ∧ x ≥ 0 ∧ y ≥ 0}
{x = 5 ∧ y = 2} z := x+ y {x = 5 ∧ z = 7}
{n ≥ 0 ∧ n2 > 28} m := n+ 1;m := m ∗m {¬(m = 36)}
{∀i.a[i] = 10 ∧ k ≥ 0} a[k] = 0 {∀i.a[i] = 10 ∧ k ≥ 0}
F(�c) = �M
S(M,M�)
S(M1,M2)
log MinEntry
log(| M1 | + | M2 |)
2(2 · 1.0 + 2 · 1.0 + 1 · 0.5)/(6 + 5) = 0.82
a {(true,α)}count {(true,β)}r {(true,β + 1)}α.next {(α �= 0, �)}α.val {(α �= 0,β)}RETV {(α = 0,β + 1− 1), (α �= 0,β + 1)}
a {(true,α)}b {(true,β)}α.n {(α �= 0, �)}α.v {(α �= 0,β)}RETV {(α = 0,β), (α �= 0,β + 2)}
{}, {} � P ⇓ v,M
{}, {} � P : τ
type list = {int x, list next}
let list node = {x:=1, next:={}}in
node.next.x
let x := {a:=1, b:=2} in E
type list = {int x, list next}type tsil = {int x, tsil prev}
1
정방향 추론은 복잡하다.
{y + 7 > 42} x := y + 7 {x > 42}
{y = x+ 10 ∧ x = 1} x := y + 7 {y = x� + 10 ∧ x� = 1 ∧ x := x� + 10 + 7}
{y = y + 7− 7 ∧ y + 7 = 18} x := y + 7 {y = x− 7 ∧ x = 18}
{P} x := E {P [x�/x] ∧ (x = E[x�/x])}
{y + 7 > 42} x = y + 7 {x > 42}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0 ∧ x ≥ 0 ∧ y ≥ 0}
{x = 5 ∧ y = 2} z := x+ y {x = 5 ∧ z = 7}
{n ≥ 0 ∧ n2 > 28} m := n+ 1;m := m ∗m {¬(m = 36)}
{∀i.a[i] = 10 ∧ k ≥ 0} a[k] = 0 {∀i.a[i] = 10 ∧ k ≥ 0}
F(�c) = �M
S(M,M�)
S(M1,M2)
log MinEntry
log(| M1 | + | M2 |)
2(2 · 1.0 + 2 · 1.0 + 1 · 0.5)/(6 + 5) = 0.82
a {(true,α)}count {(true,β)}r {(true,β + 1)}α.next {(α �= 0, �)}α.val {(α �= 0,β)}RETV {(α = 0,β + 1− 1), (α �= 0,β + 1)}
a {(true,α)}b {(true,β)}α.n {(α �= 0, �)}α.v {(α �= 0,β)}RETV {(α = 0,β), (α �= 0,β + 2)}
{}, {} � P ⇓ v,M
{}, {} � P : τ
type list = {int x, list next}
let list node = {x:=1, next:={}}in
node.next.x
1
Sequential CompositionHoare logic: Sequential composition rule
Program construct:
P ::= P;P Sequencing of commands
Hoare inference rule:
{ϕ} P1 {η} {η} P2 {ψ}
{ϕ} P1; P2 {ψ}
Example:
{y + z > 4} y := y + z− 1 {y > 3} {y > 3} x := y + 2 {x > 5}
{y + z > 4} y := y + z− 1; x := y + 2 {x > 5}
Supratik Chakraborty (I.I.T. Bombay) A Short Introduction to Hoare Logic June 23, 2008 15 / 34
{P} S1 {R} {R} S2 {Q}{P} S1;S2 {Q}
{y + 7 > 42} x := y + 7 {x > 42}
{y = x+ 10 ∧ x = 1} x := y + 7 {y = x� + 10 ∧ x� = 1 ∧ x := x� + 10 + 7}
{y = y + 7− 7 ∧ y + 7 = 18} x := y + 7 {y = x− 7 ∧ x = 18}
{P} x := E {P [x�/x] ∧ (x = E[x�/x])}
{y + 7 > 42} x = y + 7 {x > 42}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0 ∧ x ≥ 0 ∧ y ≥ 0}
{x = 5 ∧ y = 2} z := x+ y {x = 5 ∧ z = 7}
{n ≥ 0 ∧ n2 > 28} m := n+ 1;m := m ∗m {¬(m = 36)}
{∀i.a[i] = 10 ∧ k ≥ 0} a[k] = 0 {∀i.a[i] = 10 ∧ k ≥ 0}
F(�c) = �M
S(M,M�)
S(M1,M2)
log MinEntry
log(| M1 | + | M2 |)
2(2 · 1.0 + 2 · 1.0 + 1 · 0.5)/(6 + 5) = 0.82
a {(true,α)}count {(true,β)}r {(true,β + 1)}α.next {(α �= 0, �)}α.val {(α �= 0,β)}RETV {(α = 0,β + 1− 1), (α �= 0,β + 1)}
a {(true,α)}b {(true,β)}α.n {(α �= 0, �)}α.v {(α �= 0,β)}RETV {(α = 0,β), (α �= 0,β + 2)}
{}, {} � P ⇓ v,M
{}, {} � P : τ
1
모든 프로그램 S에 적용이 가능하다.
Strengthening precedent, Weakening consequentP ⇒ P � {P �} S {Q�} Q� ⇒ Q
{P} S {Q}
{y + 7 > 42} x := y + 7 {x > 42}
{y = x+ 10 ∧ x = 1} x := y + 7 {y = x� + 10 ∧ x� = 1 ∧ x := x� + 10 + 7}
{y = y + 7− 7 ∧ y + 7 = 18} x := y + 7 {y = x− 7 ∧ x = 18}
{P} x := E {P [x�/x] ∧ (x = E[x�/x])}
{y + 7 > 42} x = y + 7 {x > 42}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0 ∧ x ≥ 0 ∧ y ≥ 0}
{x = 5 ∧ y = 2} z := x+ y {x = 5 ∧ z = 7}
{n ≥ 0 ∧ n2 > 28} m := n+ 1;m := m ∗m {¬(m = 36)}
{∀i.a[i] = 10 ∧ k ≥ 0} a[k] = 0 {∀i.a[i] = 10 ∧ k ≥ 0}
F(�c) = �M
S(M,M�)
S(M1,M2)
log MinEntry
log(| M1 | + | M2 |)
2(2 · 1.0 + 2 · 1.0 + 1 · 0.5)/(6 + 5) = 0.82
a {(true,α)}count {(true,β)}r {(true,β + 1)}α.next {(α �= 0, �)}α.val {(α �= 0,β)}RETV {(α = 0,β + 1− 1), (α �= 0,β + 1)}
a {(true,α)}b {(true,β)}α.n {(α �= 0, �)}α.v {(α �= 0,β)}RETV {(α = 0,β), (α �= 0,β + 2)}
{}, {} � P ⇓ v,M
{}, {} � P : τ
1
Hoare logic: Strengthening precedent, weakening
consequent
Hoare inference rule:
ϕ ⇒ ϕ1 {ϕ1} P {ϕ2} ϕ2 ⇒ ψ
{ϕ} P {ψ}
ϕ ⇒ ϕ1 and ϕ2 ⇒ ψ are implications in base (predicate) logic
Applicable to arbitrary program P
Example:
((y > 4) ∧ (z > 1)) ⇒ (y + z > 5) {y + z > 5} y := y + z {y > 5} (y > 5) ⇒ (y > 3)
{(y > 4) ∧ (z > 1)} y := y + z {y > 3}
Supratik Chakraborty (I.I.T. Bombay) A Short Introduction to Hoare Logic June 23, 2008 16 / 34
프로그램 S와 상관없이 적용이 가능하다.
가장 약한 전제조건 P’을 구한다면,가장 강한 결과조건 Q’을 구한다면,
좋다. (어째서?)
Conditional Branch
{P ∧B} S1 {Q} {P ∧ ¬B} S2 {Q}{P} if B then S1 else S2 {Q}
{y + 7 > 42} x := y + 7 {x > 42}
{y = x+ 10 ∧ x = 1} x := y + 7 {y = x� + 10 ∧ x� = 1 ∧ x := x� + 10 + 7}
{y = y + 7− 7 ∧ y + 7 = 18} x := y + 7 {y = x− 7 ∧ x = 18}
{P} x := E {P [x�/x] ∧ (x = E[x�/x])}
{y + 7 > 42} x = y + 7 {x > 42}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0 ∧ x ≥ 0 ∧ y ≥ 0}
{x = 5 ∧ y = 2} z := x+ y {x = 5 ∧ z = 7}
{n ≥ 0 ∧ n2 > 28} m := n+ 1;m := m ∗m {¬(m = 36)}
{∀i.a[i] = 10 ∧ k ≥ 0} a[k] = 0 {∀i.a[i] = 10 ∧ k ≥ 0}
F(�c) = �M
S(M,M�)
S(M1,M2)
log MinEntry
log(| M1 | + | M2 |)
2(2 · 1.0 + 2 · 1.0 + 1 · 0.5)/(6 + 5) = 0.82
a {(true,α)}count {(true,β)}r {(true,β + 1)}α.next {(α �= 0, �)}α.val {(α �= 0,β)}RETV {(α = 0,β + 1− 1), (α �= 0,β + 1)}
a {(true,α)}b {(true,β)}α.n {(α �= 0, �)}α.v {(α �= 0,β)}RETV {(α = 0,β), (α �= 0,β + 2)}
{}, {} � P ⇓ v,M
{}, {} � P : τ
1
Hoare logic: Conditional branch
Program construct:
E ::= x | n | E + E | −E | . . . Heap-indepedent expr
B ::= E = E | E ≥ E | B ∧ B | ¬B Boolean condn
P ::= ifB thenP elseP Conditional branch
Hoare inference rule:
{ϕ ∧ B} P1 {ψ} {ϕ ∧ ¬B} P2 {ψ}
{ϕ} ifB thenP1 elseP2 {ψ}
Example:
{(y > 4) ∧ (z > 1)} y := y + z {y > 3} {(y > 4) ∧ ¬(z > 1)} y := y− 1 {y > 3}{y > 4} if (z > 1) then y := y+z else y := y-1 {y > 3}
Supratik Chakraborty (I.I.T. Bombay) A Short Introduction to Hoare Logic June 23, 2008 17 / 34
더 자세한 상태 y > 5를 알 수 있지만 weakening consequent를 적용해서
Q를 같도록 함.
Partial Correctness of Loops
•만약 loop이 끝나지 않으면 아무것도 이야기 하지 않는다. (partial correctness)
•반목문의 불변성질 (loop invariant)
{I ∧B} S {I}{I} while B S {I ∧ ¬B}
{P ∧B} S1 {Q} {P ∧ ¬B} S2 {Q}{P} if B then S1 else S2 {Q}
{y + 7 > 42} x := y + 7 {x > 42}
{y = x+ 10 ∧ x = 1} x := y + 7 {y = x� + 10 ∧ x� = 1 ∧ x := x� + 10 + 7}
{y = y + 7− 7 ∧ y + 7 = 18} x := y + 7 {y = x− 7 ∧ x = 18}
{P} x := E {P [x�/x] ∧ (x = E[x�/x])}
{y + 7 > 42} x = y + 7 {x > 42}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0 ∧ x ≥ 0 ∧ y ≥ 0}
{x = 5 ∧ y = 2} z := x+ y {x = 5 ∧ z = 7}
{n ≥ 0 ∧ n2 > 28} m := n+ 1;m := m ∗m {¬(m = 36)}
{∀i.a[i] = 10 ∧ k ≥ 0} a[k] = 0 {∀i.a[i] = 10 ∧ k ≥ 0}
F(�c) = �M
S(M,M�)
S(M1,M2)
log MinEntry
log(| M1 | + | M2 |)
2(2 · 1.0 + 2 · 1.0 + 1 · 0.5)/(6 + 5) = 0.82
a {(true,α)}count {(true,β)}r {(true,β + 1)}α.next {(α �= 0, �)}α.val {(α �= 0,β)}RETV {(α = 0,β + 1− 1), (α �= 0,β + 1)}
a {(true,α)}b {(true,β)}α.n {(α �= 0, �)}α.v {(α �= 0,β)}RETV {(α = 0,β), (α �= 0,β + 2)}
{}, {} � P ⇓ v,M
{}, {} � P : τ
1
Loop Invariants{I ∧B} S {I}
{I} while B S {I ∧ ¬B}
{P ∧B} S1 {Q} {P ∧ ¬B} S2 {Q}{P} if B then S1 else S2 {Q}
{y + 7 > 42} x := y + 7 {x > 42}
{y = x+ 10 ∧ x = 1} x := y + 7 {y = x� + 10 ∧ x� = 1 ∧ x := x� + 10 + 7}
{y = y + 7− 7 ∧ y + 7 = 18} x := y + 7 {y = x− 7 ∧ x = 18}
{P} x := E {P [x�/x] ∧ (x = E[x�/x])}
{y + 7 > 42} x = y + 7 {x > 42}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0 ∧ x ≥ 0 ∧ y ≥ 0}
{x = 5 ∧ y = 2} z := x+ y {x = 5 ∧ z = 7}
{n ≥ 0 ∧ n2 > 28} m := n+ 1;m := m ∗m {¬(m = 36)}
{∀i.a[i] = 10 ∧ k ≥ 0} a[k] = 0 {∀i.a[i] = 10 ∧ k ≥ 0}
F(�c) = �M
S(M,M�)
S(M1,M2)
log MinEntry
log(| M1 | + | M2 |)
2(2 · 1.0 + 2 · 1.0 + 1 · 0.5)/(6 + 5) = 0.82
a {(true,α)}count {(true,β)}r {(true,β + 1)}α.next {(α �= 0, �)}α.val {(α �= 0,β)}RETV {(α = 0,β + 1− 1), (α �= 0,β + 1)}
a {(true,α)}b {(true,β)}α.n {(α �= 0, �)}α.v {(α �= 0,β)}RETV {(α = 0,β), (α �= 0,β + 2)}
{}, {} � P ⇓ v,M
{}, {} � P : τ
1
Hoare logic: Partial correctness of loops
Hoare inference rule:
{ϕ ∧ B} P {ϕ}{ϕ} whileB P {ϕ ∧ ¬B}
Example:
{(y = x + z) ∧ (z �= 0)} x := x + 1; z := z− 1 {y = x + z}{y = x + z} while (z != 0){x := x+1; z := z-1} {(y = x + z) ∧ (z = 0)}
{(y = x + z) ∧ true} x := x + 1; z := z− 1 {y = x + z}{y = x + z} while (true){x := x+1; z := z-1} {(y = x + z) ∧ false}
{ϕ} while (true) P {ψ} holds vacuously for all ϕ, P and ψ
Supratik Chakraborty (I.I.T. Bombay) A Short Introduction to Hoare Logic June 23, 2008 19 / 34
변하지 않는 성질을 먼저 알아야한다!
Hoare logic: Partial correctness of loops
Hoare inference rule:
{ϕ ∧ B} P {ϕ}{ϕ} whileB P {ϕ ∧ ¬B}
Example:
{(y = x + z) ∧ (z �= 0)} x := x + 1; z := z− 1 {y = x + z}{y = x + z} while (z != 0){x := x+1; z := z-1} {(y = x + z) ∧ (z = 0)}
{(y = x + z) ∧ true} x := x + 1; z := z− 1 {y = x + z}{y = x + z} while (true){x := x+1; z := z-1} {(y = x + z) ∧ false}
{ϕ} while (true) P {ψ} holds vacuously for all ϕ, P and ψ
Supratik Chakraborty (I.I.T. Bombay) A Short Introduction to Hoare Logic June 23, 2008 19 / 34
결과조건이 거짓이면 프로그램이 종료하지 않는다.
Loop Invariantsi := 0;while i < 10
b := random_bool();if b then i := i + 1;
end
k = 0 j = 1k = 1 j = 2 + 1k = 2 j = 2 + 2 + 1... ...
{n ≥ 0} x = bar(n) {x = 1 + 2n}{I ∧B} S {I}
{I} while B S {I ∧ ¬B}
{P ∧B} S1 {Q} {P ∧ ¬B} S2 {Q}{P} if B then S1 else S2 {Q}
{y + 7 > 42} x := y + 7 {x > 42}
{y = x+ 10 ∧ x = 1} x := y + 7 {y = x� + 10 ∧ x� = 1 ∧ x := x� + 10 + 7}
{y = y + 7− 7 ∧ y + 7 = 18} x := y + 7 {y = x− 7 ∧ x = 18}
{P} x := E {P [x�/x] ∧ (x = E[x�/x])}
{y + 7 > 42} x = y + 7 {x > 42}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0 ∧ x ≥ 0 ∧ y ≥ 0}
{x = 5 ∧ y = 2} z := x+ y {x = 5 ∧ z = 7}
{n ≥ 0 ∧ n2 > 28} m := n+ 1;m := m ∗m {¬(m = 36)}
{∀i.a[i] = 10 ∧ k ≥ 0} a[k] = 0 {∀i.a[i] = 10 ∧ k ≥ 0}
F(�c) = �M
S(M,M�)
S(M1,M2)
log MinEntry
log(| M1 | + | M2 |)
2(2 · 1.0 + 2 · 1.0 + 1 · 0.5)/(6 + 5) = 0.82
1
i는 정수 0 ≤ i 0 ≤ i ≤ 10
(0 ≤ i < 10) ∨ (i = 10 ∧ b)
The strongest invariant
Hoare Rules
{I ∧B} S {I}{I} while B S {I ∧ ¬B}
{P ∧B} S1 {Q} {P ∧ ¬B} S2 {Q}{P} if B then S1 else S2 {Q}
{y + 7 > 42} x := y + 7 {x > 42}
{y = x+ 10 ∧ x = 1} x := y + 7 {y = x� + 10 ∧ x� = 1 ∧ x := x� + 10 + 7}
{y = y + 7− 7 ∧ y + 7 = 18} x := y + 7 {y = x− 7 ∧ x = 18}
{P} x := E {P [x�/x] ∧ (x = E[x�/x])}
{y + 7 > 42} x = y + 7 {x > 42}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0 ∧ x ≥ 0 ∧ y ≥ 0}
{x = 5 ∧ y = 2} z := x+ y {x = 5 ∧ z = 7}
{n ≥ 0 ∧ n2 > 28} m := n+ 1;m := m ∗m {¬(m = 36)}
{∀i.a[i] = 10 ∧ k ≥ 0} a[k] = 0 {∀i.a[i] = 10 ∧ k ≥ 0}
F(�c) = �M
S(M,M�)
S(M1,M2)
log MinEntry
log(| M1 | + | M2 |)
2(2 · 1.0 + 2 · 1.0 + 1 · 0.5)/(6 + 5) = 0.82
a {(true,α)}count {(true,β)}r {(true,β + 1)}α.next {(α �= 0, �)}α.val {(α �= 0,β)}RETV {(α = 0,β + 1− 1), (α �= 0,β + 1)}
a {(true,α)}b {(true,β)}α.n {(α �= 0, �)}α.v {(α �= 0,β)}RETV {(α = 0,β), (α �= 0,β + 2)}
{}, {} � P ⇓ v,M
{}, {} � P : τ
1
{P ∧B} S1 {Q} {P ∧ ¬B} S2 {Q}{P} if B then S1 else S2 {Q}
{y + 7 > 42} x := y + 7 {x > 42}
{y = x+ 10 ∧ x = 1} x := y + 7 {y = x� + 10 ∧ x� = 1 ∧ x := x� + 10 + 7}
{y = y + 7− 7 ∧ y + 7 = 18} x := y + 7 {y = x− 7 ∧ x = 18}
{P} x := E {P [x�/x] ∧ (x = E[x�/x])}
{y + 7 > 42} x = y + 7 {x > 42}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0 ∧ x ≥ 0 ∧ y ≥ 0}
{x = 5 ∧ y = 2} z := x+ y {x = 5 ∧ z = 7}
{n ≥ 0 ∧ n2 > 28} m := n+ 1;m := m ∗m {¬(m = 36)}
{∀i.a[i] = 10 ∧ k ≥ 0} a[k] = 0 {∀i.a[i] = 10 ∧ k ≥ 0}
F(�c) = �M
S(M,M�)
S(M1,M2)
log MinEntry
log(| M1 | + | M2 |)
2(2 · 1.0 + 2 · 1.0 + 1 · 0.5)/(6 + 5) = 0.82
a {(true,α)}count {(true,β)}r {(true,β + 1)}α.next {(α �= 0, �)}α.val {(α �= 0,β)}RETV {(α = 0,β + 1− 1), (α �= 0,β + 1)}
a {(true,α)}b {(true,β)}α.n {(α �= 0, �)}α.v {(α �= 0,β)}RETV {(α = 0,β), (α �= 0,β + 2)}
{}, {} � P ⇓ v,M
{}, {} � P : τ
1
P ⇒ P � {P �} S {Q�} Q� ⇒ Q
{P} S {Q}
{y + 7 > 42} x := y + 7 {x > 42}
{y = x+ 10 ∧ x = 1} x := y + 7 {y = x� + 10 ∧ x� = 1 ∧ x := x� + 10 + 7}
{y = y + 7− 7 ∧ y + 7 = 18} x := y + 7 {y = x− 7 ∧ x = 18}
{P} x := E {P [x�/x] ∧ (x = E[x�/x])}
{y + 7 > 42} x = y + 7 {x > 42}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0 ∧ x ≥ 0 ∧ y ≥ 0}
{x = 5 ∧ y = 2} z := x+ y {x = 5 ∧ z = 7}
{n ≥ 0 ∧ n2 > 28} m := n+ 1;m := m ∗m {¬(m = 36)}
{∀i.a[i] = 10 ∧ k ≥ 0} a[k] = 0 {∀i.a[i] = 10 ∧ k ≥ 0}
F(�c) = �M
S(M,M�)
S(M1,M2)
log MinEntry
log(| M1 | + | M2 |)
2(2 · 1.0 + 2 · 1.0 + 1 · 0.5)/(6 + 5) = 0.82
a {(true,α)}count {(true,β)}r {(true,β + 1)}α.next {(α �= 0, �)}α.val {(α �= 0,β)}RETV {(α = 0,β + 1− 1), (α �= 0,β + 1)}
a {(true,α)}b {(true,β)}α.n {(α �= 0, �)}α.v {(α �= 0,β)}RETV {(α = 0,β), (α �= 0,β + 2)}
{}, {} � P ⇓ v,M
{}, {} � P : τ
1
{P} S1 {R} {R} S2 {Q}{P} S1;S2 {Q}
{y + 7 > 42} x := y + 7 {x > 42}
{y = x+ 10 ∧ x = 1} x := y + 7 {y = x� + 10 ∧ x� = 1 ∧ x := x� + 10 + 7}
{y = y + 7− 7 ∧ y + 7 = 18} x := y + 7 {y = x− 7 ∧ x = 18}
{P} x := E {P [x�/x] ∧ (x = E[x�/x])}
{y + 7 > 42} x = y + 7 {x > 42}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0 ∧ x ≥ 0 ∧ y ≥ 0}
{x = 5 ∧ y = 2} z := x+ y {x = 5 ∧ z = 7}
{n ≥ 0 ∧ n2 > 28} m := n+ 1;m := m ∗m {¬(m = 36)}
{∀i.a[i] = 10 ∧ k ≥ 0} a[k] = 0 {∀i.a[i] = 10 ∧ k ≥ 0}
F(�c) = �M
S(M,M�)
S(M1,M2)
log MinEntry
log(| M1 | + | M2 |)
2(2 · 1.0 + 2 · 1.0 + 1 · 0.5)/(6 + 5) = 0.82
a {(true,α)}count {(true,β)}r {(true,β + 1)}α.next {(α �= 0, �)}α.val {(α �= 0,β)}RETV {(α = 0,β + 1− 1), (α �= 0,β + 1)}
a {(true,α)}b {(true,β)}α.n {(α �= 0, �)}α.v {(α �= 0,β)}RETV {(α = 0,β), (α �= 0,β + 2)}
{}, {} � P ⇓ v,M
{}, {} � P : τ
1
{Q[E/x]} x := E {Q}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0 ∧ x ≥ 0 ∧ y ≥ 0}
{x = 5 ∧ y = 2} z := x+ y {x = 5 ∧ z = 7}
{n ≥ 0 ∧ n2 > 28} m := n+ 1;m := m ∗m {¬(m = 36)}
{∀i.a[i] = 10 ∧ k ≥ 0} a[k] = 0 {∀i.a[i] = 10 ∧ k ≥ 0}
F(�c) = �M
S(M,M�)
S(M1,M2)
log MinEntry
log(| M1 | + | M2 |)
2(2 · 1.0 + 2 · 1.0 + 1 · 0.5)/(6 + 5) = 0.82
a {(true,α)}count {(true,β)}r {(true,β + 1)}α.next {(α �= 0, �)}α.val {(α �= 0,β)}RETV {(α = 0,β + 1− 1), (α �= 0,β + 1)}
a {(true,α)}b {(true,β)}α.n {(α �= 0, �)}α.v {(α �= 0,β)}RETV {(α = 0,β), (α �= 0,β + 2)}
{}, {} � P ⇓ v,M
{}, {} � P : τ
type list = {int x, list next}
let list node = {x:=1, next:={}}in
node.next.x
let x := {a:=1, b:=2} in E
type list = {int x, list next}type tsil = {int x, tsil prev}
let ... {x:=1, next:={}}... {x:=1, prev:={}}
...
1
Assignment
Seq. composition
Conditional branch
While loop
StrengtheningWeakening
A Hoare Logic ProofExample programs
int foo(int n) { int bar(int n) {local int k, int j; local int k, int j;k := 0; k := 0;j := 1; j := 1;while (k != n) { while (k != n) {k := k + 1; k := k + 1;j := 2*j; j := 2 + j;
} }return(j) return(j);
} }
Wish to prove:
1 If foo is called with parameter n greater than 0, it returns 2n
2 If bar is called with parameter n greater than 0, it returns 1 + 2n
Note: No heap manipulation by above programs.
Supratik Chakraborty (I.I.T. Bombay) A Short Introduction to Hoare Logic June 23, 2008 3 / 34
{n ≥ 0} x = bar(n) {x = 1 + 2n}{I ∧B} S {I}
{I} while B S {I ∧ ¬B}
{P ∧B} S1 {Q} {P ∧ ¬B} S2 {Q}{P} if B then S1 else S2 {Q}
{y + 7 > 42} x := y + 7 {x > 42}
{y = x+ 10 ∧ x = 1} x := y + 7 {y = x� + 10 ∧ x� = 1 ∧ x := x� + 10 + 7}
{y = y + 7− 7 ∧ y + 7 = 18} x := y + 7 {y = x− 7 ∧ x = 18}
{P} x := E {P [x�/x] ∧ (x = E[x�/x])}
{y + 7 > 42} x = y + 7 {x > 42}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0 ∧ x ≥ 0 ∧ y ≥ 0}
{x = 5 ∧ y = 2} z := x+ y {x = 5 ∧ z = 7}
{n ≥ 0 ∧ n2 > 28} m := n+ 1;m := m ∗m {¬(m = 36)}
{∀i.a[i] = 10 ∧ k ≥ 0} a[k] = 0 {∀i.a[i] = 10 ∧ k ≥ 0}
F(�c) = �M
S(M,M�)
S(M1,M2)
log MinEntry
log(| M1 | + | M2 |)
2(2 · 1.0 + 2 · 1.0 + 1 · 0.5)/(6 + 5) = 0.82
a {(true,α)}count {(true,β)}r {(true,β + 1)}α.next {(α �= 0, �)}α.val {(α �= 0,β)}RETV {(α = 0,β + 1− 1), (α �= 0,β + 1)}
a {(true,α)}b {(true,β)}α.n {(α �= 0, �)}α.v {(α �= 0,β)}RETV {(α = 0,β), (α �= 0,β + 2)}
{}, {} � P ⇓ v,M
1
증명해봅시다!
A Hoare Logic ProofA Hoare logic proof
Sequential composition rule will give us a proof if we can fill in the
template:
{n > 0} Precondition
k := 0{ϕ1} Midcondition
j := 1{ϕ2} Midcondition
while (k != n) { k := k+1; j := 2+j}{j = 1 + 2.n} Postcondition
How do we prove
{ϕ2} while (k != n) { k := k+1; j := 2+j} {j = 1 + 2.n}?Recall rule for loops requires a loop invariant
“Guess” a loop invariant (j = 1 + 2.k)
Supratik Chakraborty (I.I.T. Bombay) A Short Introduction to Hoare Logic June 23, 2008 23 / 34
Sequential composition 규칙을 적용해 쪼개봅시다.
A Hoare logic proof
Sequential composition rule will give us a proof if we can fill in the
template:
{n > 0} Precondition
k := 0{ϕ1} Midcondition
j := 1{ϕ2} Midcondition
while (k != n) { k := k+1; j := 2+j}{j = 1 + 2.n} Postcondition
How do we prove
{ϕ2} while (k != n) { k := k+1; j := 2+j} {j = 1 + 2.n}?Recall rule for loops requires a loop invariant
“Guess” a loop invariant (j = 1 + 2.k)
Supratik Chakraborty (I.I.T. Bombay) A Short Introduction to Hoare Logic June 23, 2008 23 / 34
loop을 증명할때는 어떤 것이 필요한가요?
Loop Invariant
•루프의 불변성질을 찾는데는 창의력이 필요
•우리가 알고싶은 성질과 연관지어 불변성을 유추해보자.
A Hoare logic proof
Sequential composition rule will give us a proof if we can fill in the
template:
{n > 0} Precondition
k := 0{ϕ1} Midcondition
j := 1{ϕ2} Midcondition
while (k != n) { k := k+1; j := 2+j}{j = 1 + 2.n} Postcondition
How do we prove
{ϕ2} while (k != n) { k := k+1; j := 2+j} {j = 1 + 2.n}?Recall rule for loops requires a loop invariant
“Guess” a loop invariant (j = 1 + 2.k)
Supratik Chakraborty (I.I.T. Bombay) A Short Introduction to Hoare Logic June 23, 2008 23 / 34
k = 0 j = 1k = 1 j = 2 + 1k = 2 j = 2 + 2 + 1... ...
{n ≥ 0} x = bar(n) {x = 1 + 2n}{I ∧B} S {I}
{I} while B S {I ∧ ¬B}
{P ∧B} S1 {Q} {P ∧ ¬B} S2 {Q}{P} if B then S1 else S2 {Q}
{y + 7 > 42} x := y + 7 {x > 42}
{y = x+ 10 ∧ x = 1} x := y + 7 {y = x� + 10 ∧ x� = 1 ∧ x := x� + 10 + 7}
{y = y + 7− 7 ∧ y + 7 = 18} x := y + 7 {y = x− 7 ∧ x = 18}
{P} x := E {P [x�/x] ∧ (x = E[x�/x])}
{y + 7 > 42} x = y + 7 {x > 42}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0}
{x ≥ 0 ∧ y ≥ 0} z := x+ y {z ≥ 0 ∧ x ≥ 0 ∧ y ≥ 0}
{x = 5 ∧ y = 2} z := x+ y {x = 5 ∧ z = 7}
{n ≥ 0 ∧ n2 > 28} m := n+ 1;m := m ∗m {¬(m = 36)}
{∀i.a[i] = 10 ∧ k ≥ 0} a[k] = 0 {∀i.a[i] = 10 ∧ k ≥ 0}
F(�c) = �M
S(M,M�)
S(M1,M2)
log MinEntry
log(| M1 | + | M2 |)
2(2 · 1.0 + 2 · 1.0 + 1 · 0.5)/(6 + 5) = 0.82
a {(true,α)}count {(true,β)}r {(true,β + 1)}α.next {(α �= 0, �)}α.val {(α �= 0,β)}RETV {(α = 0,β + 1− 1), (α �= 0,β + 1)}
1
initial statestate after 1 iterationstate after 2 iteration
...
A Hoare logic proof
Sequential composition rule will give us a proof if we can fill in the
template:
{n > 0} Precondition
k := 0{ϕ1} Midcondition
j := 1{ϕ2} Midcondition
while (k != n) { k := k+1; j := 2+j}{j = 1 + 2.n} Postcondition
How do we prove
{ϕ2} while (k != n) { k := k+1; j := 2+j} {j = 1 + 2.n}?Recall rule for loops requires a loop invariant
“Guess” a loop invariant (j = 1 + 2.k)
Supratik Chakraborty (I.I.T. Bombay) A Short Introduction to Hoare Logic June 23, 2008 23 / 34
A Hoare Logic ProofA Hoare logic proof
To prove:{ϕ2} while (k != n) k := k+1; j := 2+j {j = 1 + 2.n}using loop invariant (j = 1 + 2.k)
If we can show:ϕ2 ⇒ (j = 1 + 2.k)
{(j = 1 + 2.k) ∧ (k �= n)} k := k+1; j:= 2+j {j = 1 + 2.k}((j = 1 + 2.k) ∧ ¬(k �= n)) ⇒ (j = 1 + 2.n)
thenBy inference rule for loops
{(j = 1 + 2.k) ∧ (k �= n)} k := k+1; j:= 2+j {j = 1 + 2.k}{j = 1 + 2.k} while (k != n) k := k+1; j:= 2+j {(j = 1 + 2.k) ∧ ¬(k �= n)}
By inference rule for strengthening precedents and weakening consequentsϕ2 ⇒ (j = 1 + 2.k)
{j = 1 + 2.k} while (k != n) k := k+1; j:= 2+j {(j = 1 + 2.k) ∧ ¬(k �= n)}((j = 1 + 2.k) ∧ ¬(k �= n)) ⇒ (j = 1 + 2.n)
{ϕ2} while (k != n) k := k+1; j:= 2+j {(j = 1 + 2.n)}Supratik Chakraborty (I.I.T. Bombay) A Short Introduction to Hoare Logic June 23, 2008 24 / 34
A Hoare Logic ProofA Hoare logic proof
How do we show:
ϕ2 ⇒ (j = 1 + 2.k)
{(j = 1 + 2.k) ∧ (k �= n)} k := k+1; j:= 2+j {j = 1 + 2.k}((j = 1 + 2.k) ∧ ¬(k �= n)) ⇒ (j = 1 + 2.n)
Note:
ϕ2 ⇒ (j = 1 + 2.k) holds trivially if ϕ2 is (j = 1 + 2.k)
((j = 1 + 2.k) ∧ ¬(k �= n)) ⇒ (j = 1 + 2.n) holds trivially in integerarithmetic
Only remaining proof subgoal:{(j = 1 + 2.k) ∧ (k �= n)} k := k+1; j:= 2+j {j = 1 + 2.k}
Supratik Chakraborty (I.I.T. Bombay) A Short Introduction to Hoare Logic June 23, 2008 25 / 34
A Hoare Logic ProofA Hoare logic proof
To show:{(j = 1 + 2.k) ∧ (k �= n)} k := k+1; j:= 2+j {j = 1 + 2.k}
Applying assignment rule twice{2 + j = 1 + 2.k} j := 2+j {j = 1 + 2k}
{2 + j = 1 + 2.(k + 1)} k := k+1 {2 + j = 1 + 2.k}
Simplifying and applying sequential composition rule{1 + j = 2.k} j := 2+j {j = 1 + 2k}{j = 1 + 2.k)} k := k+1 {1 + j = 2.k}
{j = 1 + 2.k} k := k+1; j := 2+j {j = 1 + 2.k}
Applying rule for strengthening precedent(j = 1 + 2.k) ∧ (k �= n)} ⇒ (j = 1 + 2.k)
{j = 1 + 2.k} k := k+1; j := 2+j {j = 1 + 2.k}{(j = 1 + 2.k) ∧ (k �= n)} k := k+1; j := 2+j {j = 1 + 2.k}
Supratik Chakraborty (I.I.T. Bombay) A Short Introduction to Hoare Logic June 23, 2008 26 / 34
A Hoare Logic ProofA Hoare logic proof
We have thus shown that with ϕ2 as (j = 1 + 2.k){ϕ2} while (k != n) k := k+1; j := 2+j {j = 1 + 2.n} is valid
Recall our template:{n > 0} Preconditionk := 0{ϕ1} Midcondition
j := 1{ϕ2 : j = 1 + 2.k} Midcondition
while (k != n) k := k+1; j := 2+j{j = 1 + 2.n} Postcondition
The only missing link now is to show{n > 0} k := 0 {ϕ1} and{ϕ1} j := 1 {j = 1 + 2.k}
Supratik Chakraborty (I.I.T. Bombay) A Short Introduction to Hoare Logic June 23, 2008 27 / 34
A Hoare Logic ProofA Hoare logic proof
To show
{n > 0} k := 0 {ϕ1} and
{ϕ1} j := 1 {j = 1 + 2.k}
Applying assignment rule twice and simplifying:
{0 = k} j := 1 {j = 1 + 2.k}{true} k := 0 {0 = k}
Choose ϕ1 as (k = 0), so {ϕ1} j := 1 {j = 1 + 2.k} holds.
Applying rule for strengthening precedent:
(n > 0) ⇒ true
{true} k := 0 {ϕ1 : k = 0}{n > 0} k := 0 {ϕ1 : k = 0}
We have proved partial correctness of function bar in Hoare Logic !!!
Supratik Chakraborty (I.I.T. Bombay) A Short Introduction to Hoare Logic June 23, 2008 28 / 34
프로그램의 partial correctness를 증명완료!
Total Correctness of Loop
•n이 양수라는 사실은 partial correctness를 증명하는데에는 전혀 쓰이지 않았다.
•이는 루프가 항상 끝난다는 사실을 증명하는데 쓰일 수 있다. 끝나면서 옳다!
결론•Hoare-style 증명은 지난 몇십년간 복잡한
프로그램의 성질을 증명하는데 쓰였다.
•Loop Invariant는 일반적으로 자동으로 찾는 것이 불가능하기에 사람에게 의존한다.
•자동 증명기와 사용자의 주석을 가지고 작은 크기의 프로그램을 완벽히 증명하는 사례가 많다.
•Loop Invariant 마저 자동으로 찾는 방법의 관한 연구도 활발히 진행중이다.
•프로그램을 엄밀히 작성하는데 도움이 된다.