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
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)
©Arnd Poetzsch-Heffter et al. TU Kaiserslautern 482
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 ))
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
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 0 s −→ P s; ` { P } c { Q } ; ∀ s. Q s −→ Q 0 s ]] = ⇒ ` { P 0 } c { Q 0 }
| [[ V
s. P s = ⇒ P 0 s (f s); ∀ s. ` { P 0 s } c { Q ◦ (g s) } ]] = ⇒
` { P } LOCAL f;c;g { Q }
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 1 ELSE c 2 ↓ s
| [[ ¬ b s; c 2 ↓ s ]] = ⇒ IF b THEN c 1 ELSE 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
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)
©Arnd Poetzsch-Heffter et al. TU Kaiserslautern 490
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 0 s −→ P s; ` t { P } c { Q } ; ∀ s. Q s −→ Q 0 s ]] = ⇒
` t { P 0 } c { Q 0 }
| Local: (!!s. P s = ⇒ P 0 s (f s)) = ⇒ ∀ ps. ` t { P 0 ps } 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
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
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?
Formulas and validity
type-synonym 0 a assn = 0 a ⇒ state ⇒ bool
type-synonym 0 a cntxt = ( 0 a assn × com × 0 a assn)set definition
valid :: 0 a assn ⇒ com ⇒ 0 a assn ⇒ bool ( | = { (1-) } / (-)/ { (1-) } 50) where
| = { P } c { Q } ←→ ( ∀ s t. s − c → t −→ ( ∀ z. P z s −→ Q z t)) definition
valids :: 0 a cntxt ⇒ bool ( || = - 50) where
[simp]: || = C ≡ ( ∀ (P,c,Q) ∈ C. | = { P } c { Q } ) definition
cvalid :: 0 a cntxt ⇒ 0 a assn ⇒ com ⇒ 0 a 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 ⇒ 0 a assn ⇒ com ⇒ 0 a 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 ⇒ 0 a cntxt ⇒ bool ( || = 0 --/ - 50) where
|| =-n C ≡ ( ∀ (P,c,Q) ∈ C. | =n { P } c { Q } ) definition
cnvalid :: 0 a cntxt ⇒ nat ⇒ 0 a assn ⇒ com ⇒ 0 a assn ⇒ bool (- | =-/ { (1-) } / (-)/ { (1-) } 50) where
C | =n { P } c { Q } ←→ || =-n C −→ | =n { P } c { Q }
Rules
inductive
hoare :: 0 a cntxt ⇒ 0 a assn ⇒ com ⇒ 0 a 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 0 z s −→ Q 0 z 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 0 t) } ]] = ⇒ C ` { P } LOCAL f;c;g { Q }
©Arnd Poetzsch-Heffter et al. TU Kaiserslautern 498
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
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
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
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 "
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] }"
©Arnd Poetzsch-Heffter et al. TU Kaiserslautern 506