Section 8.5
Reasoning about more expressive languages
©Arnd Poetzsch-Heffter et al. TU Kaiserslautern 480
Overview
• Abstract while-language with nondeterminism and local variables
• Total correctness
• Recursive procedure
©Arnd Poetzsch-Heffter et al. TU Kaiserslautern 481
8. Program Verification 8.5 Reasoning about more expressive languages
Literature
• T. Nipkow: Hoare Logics in Isabelle/HOL
• T. Nipkow: Hoare Logics for Recursive Procedures and Unbounded Nonterminism
• T. Nipkow: Abstract Hoare Logics (Archive of formal proofs)
8. Program Verification 8.5 Reasoning about more expressive languages
Abstract while-language
I Nondeterminism and local variables
I Shallow embedding of expressions and state transformers
typedecl state
type-synonym bexp = state ⇒ bool datatype com = Do (state ⇒ state set)
| Semi com com (-; - [60, 60] 10)
| Cond bexp com com (IF - THEN - ELSE - 60)
| While bexp com (WHILE - DO - 60)
| Local (state ⇒ state) com (state ⇒ state ⇒ state)
(LOCAL -; -; - [0,0,60] 60)
Semantics of abstract while-language
inductive
exec :: state ⇒ com ⇒ state ⇒ bool (-/ − - → / - [50,0,50] 50) where
t ∈ f s = ⇒ s − Do f → t
| [[ s0 −c1→ s1; s1 −c2→ s2 ]] = ⇒ s0 −c1;c2→ s2
| [[ b s; s −c1→ t ]] = ⇒ s −IF b THEN c1 ELSE c2→ t
| [[ ¬ b s; s − c2 → t ]] = ⇒ s − IF b THEN c1 ELSE c2 → t
| ¬ b s = ⇒ s − WHILE b DO c → s
| [[ b s; s − c → t; t − WHILE b DO c → u ]] = ⇒ s − WHILE b DO c → u
| f s − c → t = ⇒ s − LOCAL f; c; g → g s t
©Arnd Poetzsch-Heffter et al. TU Kaiserslautern 484
Discussion
I abstractness of the language allows to realize different concrete language constructs
I the LOCAL command can handle local variable declarations:
LOCAL(λ s.s(x := a s )); c; (λ s t.t(x := s x ))
©Arnd Poetzsch-Heffter et al. TU Kaiserslautern 485
8. Program Verification 8.5 Reasoning about more expressive languages
Formulas and validity for partial correctness
type-synonym assn = state ⇒ bool definition
hoare-valid :: assn ⇒ com ⇒ assn ⇒ bool ( | = { (1-) } / (-)/ { (1-) } 50) where
| = {P}c{Q} ←→ (∀ s t. s −c→ t −→ P s −→ Q t)
©Arnd Poetzsch-Heffter et al. TU Kaiserslautern 486
8. Program Verification 8.5 Reasoning about more expressive languages
Rules for partial correctness
inductive
hoare :: assn ⇒ com ⇒ assn ⇒ bool (` ({(1-)}/ (-)/ {(1-)}) 50) where
` { λs. ∀ t ∈ f s. P t } Do f { P }
| [[ ` { P } c1 { Q } ; ` { Q } c2 { R } ]] = ⇒ ` { P } c1;c2 { R }
| [[ ` { λs. P s ∧ b s } c1 { Q } ; ` { λs. P s ∧ ¬ b s } c2 { Q } ]]
= ⇒ ` {P} IF b THEN c1 ELSE c2 {Q}
| ` { λs. P s ∧ b s } c { P } = ⇒ ` { P } WHILE b DO c { λs. P s ∧ ¬ b s }
| [[ ∀ s. P
0s −→ P s; ` { P } c { Q } ; ∀ s. Q s −→ Q
0s ]] = ⇒ ` { P
0} c { Q
0}
| [[ V
s. P s = ⇒ P
0s (f s); ∀ s. ` { P
0s } c { Q ◦ (g s) } ]] = ⇒
` {P} LOCAL f;c;g {Q}
©Arnd Poetzsch-Heffter et al. TU Kaiserslautern 487
Soundness and completeness
theorem hoare-sound: ` { P } c { Q } = ⇒ | = { P } c { Q }
theorem hoare-relative-complete: | = { P } c { Q } = ⇒ ` { P } c { Q }
©Arnd Poetzsch-Heffter et al. TU Kaiserslautern 488
Termination
inductive
termi :: com ⇒ state ⇒ bool (infixl ↓ 50) where
f s 6 = {} = ⇒ Do f ↓ s
| [[ c
1↓ s
0; ∀ s
1. s
0−c
1→ s
1−→ c
2↓ s
1]] = ⇒ (c
1;c
2) ↓ s
0| [[ b s; c
1↓ s ]] = ⇒ IF b THEN c
1ELSE c
2↓ s
| [[ ¬ b s; c
2↓ s ]] = ⇒ IF b THEN c
1ELSE c
2↓ s
| ¬ b s = ⇒ WHILE b DO c ↓ s
| [[ b s; c ↓ s; ∀ t. s − c → t −→ WHILE b DO c ↓ t ]] = ⇒ WHILE b DO c ↓ s
| c ↓ f s = ⇒ LOCAL f;c;g ↓ s
©Arnd Poetzsch-Heffter et al. TU Kaiserslautern 489
8. Program Verification 8.5 Reasoning about more expressive languages
Formulas and validity for total correctness
definition
hoare-tvalid :: assn ⇒ com ⇒ assn ⇒ bool ( | =
t{ (1-) } / (-)/ { (1-) } 50) where
| =
t{P}c{Q} ←→ | = {P}c{Q} ∧ (∀ s. P s −→ c↓s)
8. Program Verification 8.5 Reasoning about more expressive languages
Rules for total correctness
inductive
thoare :: assn ⇒ com ⇒ assn ⇒ bool (`
t({(1-)}/ (-)/ {(1-)}) 50) where
Do: `
t{ λs. ( ∀ t ∈ f s. P t) ∧ f s 6 = {}} Do f { P }
| Semi: [[ `
t{ P } c { Q } ; `
t{ Q } d { R } ]] = ⇒ `
t{ P } c;d { R }
| If: [[ `
t{ λs. P s ∧ b s } c { Q } ; `
t{ λs. P s ∧ ¬ b s } d { Q } ]] = ⇒
`
t{P} IF b THEN c ELSE d {Q}
| While:
[[wf r; ∀ s
0. `
t{λs. P s ∧ b s ∧ s
0= s} c {λs. P s ∧ (s,s
0) ∈ r}]]
= ⇒ `
t{ P } WHILE b DO c { λs. P s ∧ ¬ b s }
| Conseq: [[ ∀ s. P
0s −→ P s; `
t{ P } c { Q } ; ∀ s. Q s −→ Q
0s ]] = ⇒
`
t{ P
0} c { Q
0}
| Local: (!!s. P s = ⇒ P
0s (f s)) = ⇒ ∀ ps. `
t{P
0ps} c {Q o (g ps)} = ⇒
`
t{ P } LOCAL f;c;g { Q }
Language with one procedure, no parameters
typedecl state
type-synonym bexp = state ⇒ bool datatype com = Do (state ⇒ state set)
| Semi com com (-; - [60, 60] 10)
| Cond bexp com com (IF - THEN - ELSE - 60)
| While bexp com (WHILE - DO - 60)
| CALL
| Local (state ⇒ state) com (state ⇒ state ⇒ state) (LOCAL -; -; - [0,0,60] 60)
consts body :: com
©Arnd Poetzsch-Heffter et al. TU Kaiserslautern 492
Semantics
inductive
exec :: state ⇒ com ⇒ state ⇒ bool (-/ − - → / - [50,0,50] 50) where
Do: t ∈ f s = ⇒ s − Do f → t
| Semi: [[ s0 − c1 → s1; s1 − c2 → s2 ]]
= ⇒ s0 − c1;c2 → s2
| IfTrue: [[ b s; s − c1 → t ]] = ⇒ s − IF b THEN c1 ELSE c2 → t
| IfFalse: [[ ¬ b s; s − c2 → t ]] = ⇒ s − IF b THEN c1 ELSE c2 → t
| WhileFalse: ¬ b s = ⇒ s − WHILE b DO c → s
| WhileTrue: [[ b s; s − c → t; t − WHILE b DO c → u ]]
= ⇒ s − WHILE b DO c → u
| s − body → t = ⇒ s − CALL → t
| Local: f s − c → t = ⇒ s − LOCAL f; c; g → g s t
©Arnd Poetzsch-Heffter et al. TU Kaiserslautern 493
8. Program Verification 8.5 Reasoning about more expressive languages
Fine-grain semantics
inductive
execn :: state ⇒ com ⇒ nat ⇒ state ⇒ bool (-/ −-−-→/ - [50,0,0,50] 50) where
t ∈ f s = ⇒ s − Do f − n → t
| [[ s0 − c1 − n → s1; s1 − c2 − n → s2 ]] = ⇒ s0 − c1;c2 − n → s2
| [[ b s; s − c1 − n → t ]] = ⇒ s − IF b THEN c1 ELSE c2 − n → t
| [[ ¬b s; s −c2−n→ t ]] = ⇒ s −IF b THEN c1 ELSE c2−n→ t
| ¬ b s = ⇒ s − WHILE b DO c − n → s
| [[b s; s − c − n → t; t − WHILE b DO c − n → u]] = ⇒ s − WHILE b DO c − n → u
| s −body−n→ t = ⇒ s −CALL−Suc n→ t
| f s −c−n→ t = ⇒ s −LOCAL f; c; g−n→ g s t
©Arnd Poetzsch-Heffter et al. TU Kaiserslautern 494
8. Program Verification 8.5 Reasoning about more expressive languages
Example program and adaptation
• Simple recursive program:
proc = IF i= 0 THEN SKIP ELSE i:=i -1; CALL; i :=i +1
• Specification:
{ i= N } CALL { i =N }
• Adaptation rules; how can we deduce { i=N -1 } CALL { i= N-1 } from specification?
©Arnd Poetzsch-Heffter et al. TU Kaiserslautern 495
Formulas and validity
type-synonym
0a assn =
0a ⇒ state ⇒ bool
type-synonym
0a cntxt = (
0a assn × com ×
0a assn)set definition
valid ::
0a assn ⇒ com ⇒
0a assn ⇒ bool ( | = { (1-) } / (-)/ { (1-) } 50) where
| = {P}c{Q} ←→ (∀ s t. s −c→ t −→ (∀ z. P z s −→ Q z t)) definition
valids ::
0a cntxt ⇒ bool ( || = - 50) where [simp]: || = C ≡ ( ∀ (P,c,Q) ∈ C. | = { P } c { Q } ) definition
cvalid ::
0a cntxt ⇒
0a assn ⇒ com ⇒
0a assn ⇒ bool (- | =/ {(1-)}/ (-)/
{ (1-) } 50) where
C | = { P } c { Q } ←→ || = C −→ | = { P } c { Q }
©Arnd Poetzsch-Heffter et al. TU Kaiserslautern 496
Formulas and validity for fine-grain semantics
definition
nvalid :: nat ⇒
0a assn ⇒ com ⇒
0a assn ⇒ bool ( | =- { (1-) } / (-)/ { (1-) } 50) where
| =n { P } c { Q } ≡ ( ∀ s t. s − c − n → t −→ ( ∀ z. P z s −→ Q z t)) definition
nvalids :: nat ⇒
0a cntxt ⇒ bool ( || =
0--/ - 50) where
|| =-n C ≡ ( ∀ (P,c,Q) ∈ C. | =n { P } c { Q } ) definition
cnvalid ::
0a cntxt ⇒ nat ⇒
0a assn ⇒ com ⇒
0a assn ⇒ bool (- | =-/ { (1-) }/
(-)/ { (1-) } 50) where
C | =n {P}c{Q} ←→ || =-n C −→ | =n {P}c{Q}
©Arnd Poetzsch-Heffter et al. TU Kaiserslautern 497
8. Program Verification 8.5 Reasoning about more expressive languages
Rules
inductive
hoare ::
0a cntxt ⇒
0a assn ⇒ com ⇒
0a assn ⇒ bool (- ` / ( { (1-) } / (-)/
{(1-)}) 50) where
C ` { λz s. ∀ t ∈ f s . P z t } Do f { P }
| [[ C ` {P}c1{Q}; C ` {Q}c2{R} ]] = ⇒ C ` {P} c1;c2 {R}
| [[ C ` { λz s. P z s ∧ b s } c1 { Q } ; C ` { λz s. P z s ∧ ¬ b s } c2 { Q } ]]
= ⇒ C ` { P } IF b THEN c1 ELSE c2 { Q }
| C ` {λz s. P z s ∧ b s} c {P}
= ⇒ C ` { P } WHILE b DO c { λz s. P z s ∧ ¬ b s }
| [[ C ` { P
0} c { Q
0} ; ∀ s t. ( ∀ z. P
0z s −→ Q
0z t) −→ ( ∀ z. P z s −→ Q z t) ]]
= ⇒ C ` { P } c { Q }
| { (P,CALL,Q) } ` { P } body { Q } = ⇒ {} ` { P } CALL { Q }
| { (P,CALL,Q) } ` { P } CALL { Q }
| [[ ∀ s
0. C ` { λz s. P z s
0∧ s = f s
0} c { λz t. Q z (g s
0t) } ]] = ⇒
8. Program Verification 8.5 Reasoning about more expressive languages
Final remarks on language extensions
• Nondeterminism and many other aspects can be handled without conceptual extensions
• Termination proofs need well-founded orderings
• Procedures need assumptions/contexts, logical variables and
adaptation rules
Section 8.6
Verifying procedural, heap-manipulating programs
©Arnd Poetzsch-Heffter et al. TU Kaiserslautern 500
General approach 1
• Specify programming language syntax and semantics in an interactive theorem prover for HOL
• Use HOL as specification language for program properties
• Use the HOL proof system for verification
©Arnd Poetzsch-Heffter et al. TU Kaiserslautern 501
8. Program Verification 8.6 Verifying procedural, heap-manipulating programs
Example: Verifying Simpl programs
Simpl (by N. Schirmer [Archives of formal proofs]):
A sequential imperative programming language:
• mutually recursive procedures
• abrupt termination and exceptions
• runtime faults
• local and global variables
• pointers and heaps
• expressions with side-effects
• pointers to procedures
• partial application and closures
• dynamic method invocation
• unbounded nondeterminism
©Arnd Poetzsch-Heffter et al. TU Kaiserslautern 502
8. Program Verification 8.6 Verifying procedural, heap-manipulating programs
Example program: Quicksort on heap lists
Illustrating:
• Handling of programming language aspects:
I
recursive procedures
I
local and global variables
I
pointers and heaps
• Handling of specification aspects:
I
heap-manipulation using abstraction
I
frame properties
• Problems of embedding
©Arnd Poetzsch-Heffter et al. TU Kaiserslautern 503
Modeling of a program specific state
Heap for singly-linked lists (sll-heaps):
record globals_heap = next_’ :: "ref ⇒ ref"
cont_ ’ :: "ref ⇒ nat"
A predicate to abstract sll-heaps:
primrec List :: ref ⇒ ( ref ⇒ ref) ⇒ ref list ⇒ bool where
List x h [] = (x = Null) |
List x h ( p# ps) = (x = p ∧ x , Null ∧ List ( h x) h ps )
©Arnd Poetzsch-Heffter et al. TU Kaiserslautern 504
Modeling of a program specific state (2)
The variables for procedures append and quickSort record ’g vars = "’g state" +
p_’ :: " ref "
q_’ :: " ref "
le_ ’ :: " ref "
gt_ ’ :: " ref "
hd_ ’ :: " ref "
tl_ ’ :: " ref "
©Arnd Poetzsch-Heffter et al. TU Kaiserslautern 505
8. Program Verification 8.6 Verifying procedural, heap-manipulating programs
Implementation and specification of procedure append
procedures append (p ,q| p) =
"IF ´p =Null THEN ´p :== ´q
ELSE ´p → ´next :== CALL append ( ´p → ´next , ´q) FI"
append_spec:
" ∀ σ Ps Qs. Γ `
{ σ. List ´p ´next Ps ∧ List ´q ´next Qs ∧ set Ps ∩ set Qs = {} }
´p :== PROC append ( ´p, ´q) { List ´p ´next (Ps @Qs) ∧
( ∀ x. x < set Ps −→ ´next x =
σnext x) }"
append_modifies:
" ∀ σ. Γ `
{ σ } ´p :== PROC append ( ´p, ´q)
{ t. t may_only_modify_globals σ in [next] }"
8. Program Verification 8.6 Verifying procedural, heap-manipulating programs