View
219
Download
0
Embed Size (px)
Citation preview
Local Reasoning
Peter O’HearnJohn Reynolds
Hongseok Yang
Outline• The ideal assertion language• Difficulties with pointers• Solutions• The separation logic• Concurrent Separation Logic
Hoare Proof Rules for Partial Correctness
{A} skip {A}
{B[a/X]} X:=a {B} (Assignment Rule)
{P} c0 {C} {C} c1 {Q}
{P} c0;c1{Q}
{Pb} c0 {Q} {P b} c1 {Q}
{P} if b then c0 else c1{Q}
{Ib} c {I}
{I} while b do c{Ib}
P P’ {P’} c {Q’} Q’ Q
{P} c {Q}
(Composition Rule)
(Conditional Rule)
(Loop Rule)
(Consequence Rule)
The Ideal Assertion Language
• Natural
• Succinct
• Expressive – Closed under WP for every command
• Efficient algorithm for entailment checking
IMP++
• Abstract syntaxcom::= X := a | X:= cons(a1, a2) | X := [a] |[a1] := a2 | dispose(a) | skip | com1 ; com2 | if b then com1 else com2 | while b do com|
Informal Semantics IMP++
• Allocation x := cons(y, z)
• Heap lookup y := [x+1]
• Mutation [x + 1] := 3
• Deallocation dispose(x+1)
Store: [x:3, y:40, z:17]
Heap: empty
Store: [x:37, y:40, z:17]
Heap: 37:40, 38:17
Store: [x:37, y:17, z:17]
Heap: 37:40, 38:3
Store: [x:37, y:17, z:17]
Heap: 37:40, 38:17
Store: [x:37, y:17, z:17]
Heap: 37:40
First assertion languageAexpv
a:= n | X | [a] | i | a0 + a1 | a0 - a1 | a0 a1
Assn
A:= true | false | a0 = a1 | a0 a1 | A0 A1 | A0 A1 | A |
A0 A1 | i. A | i. A
Destructive Pointer Reversaly: = nil ;
while x nil do (
t := y
y := x
x := [x +1]
[y+1] := t
)
Assignment Axioms
{?} [a1] := a2 {p}
{?} [x] := z {[x] =y}
{?} [t] := z {[x] =y}
Assignment Rule with Mutations• [Morris 1982] Characterize aliasing patterns with
assertions• [McCharthy ?] Define a logic for stores
• heap:locval • First order assertions over heap• {p} [a1] := a2 {p[a2 /heap(a1)]}
• [Burstall 1972] Local reasoning• Split the heap into disjoints parts• Contents can be shared
{x=37 z=x heap(37)=40}
[x] := 77
{x=37 z=x heap(37)=77}
Separation Logic
x y * y x
Separation Logic
x y
x y
Separation Logic
y x
x y
Separation Logic
x y * y x
x y
Separation Logic
x y
x y
42 10
10 42
x=10 y=42
Separation Logic
y x
x y
42 10
10 42
x=10 y=42
Separation Logic
x y * y x
x y
42 10
10 42
x=10 y=42
Assertions in Separation Logic
Syntax Intended Meaning
e=f Pure expression comparison
ef A heap with one location pointed to by e
with content f
emp Empty heap
p *q p and q hold in
disjoint heaps
true,false, pq, pq, x: p standard
e _ l: e l
ee0, e1, …, en-1 e e0 * e+1 e1* … * e+n-1 en-1
ef e f * true
Assertion Example state
x3,y Store: x:, y: Heap: : 3, +1:
y3,x Store: x:, y: Heap: : 3, +1:
x3,y * y3,x Store: x:, y: Heap: : 3, +1
: 3, +1: , +1, , and +1 disjoint
x3,y y3,x Store: x:, y: Heap: : 3, +1:
x3,y y3,x Store: x:, y: Heap: : 3, +1: : 3, +1:
Unsound Axioms
p p * p Contraction
p= x1
p * q p Weakening
p= x1
q= y 2
In-Place Reasoning
{x7 * p}[x] := 7{x_ * p}
{?}[x] := 7{true}
{?}dispose(e){true}
{p}dispose(e){x_ * p}
if {p} c {q} holds then p describes the resources that c needs
Semantics of separation logics
s, h e = f es = fss, h e f {es} = dom(h)
and h(e) = fs
s, h emp h=[]
s, h p * q exist h1, h2: dom(h1)dom(h2)=
s, h1 p
s, h2 q
h = h1 # h2
Semantics of separation logics(cont)
s, h false never
s, h p q if s, h p
then s, h q
s, h x. p exists v:
s[v/x], h p
Three “Small” Axioms
{e_} [e] := b {e b}
{emp} x := cons(y, z) {x y, z}
{e_} dispose(e) {emp}
The Frame Rule{p} c {q}
{p * r} c {q * r}
Mod(c) free(r)={}
Mod(x := _) = {x}
Mod([e]:=f) =
Mod(dispose(e)) =
A simple application of the frame rule
{p} c {q}
{p * r} c {q * r}
Mod(c) free(r)={}
{(e_ )* p } dispose(e) {p}
Inductive Definitions
• Define assertions inductively
• Allows natural specificationslist [r] x (r= x= nil emp) ( a, s, y: r=a.s xa, y * list [s] y)
list(x, y) (x=y emp) ( t: x_, t * list(t, y))
tree(r) (r=nil emp) (l, r: r_, l, r * tree(l) * tree(r))
The Reverse Exampley: = nil ;
while x nil do (
t := y
y := x
x := [x +1]
[y+1] := t
)
, . list [] y * list [] x rev(0)= rev().
The Delete Example
bool elem_delete(delval, c)prev=nilelem = cwhile (elem nil) ( if ([elem] = delval) then ( if (prev = nil) then c = [elem+1] else [prev+1] = [elem+1]; dispose(elem); return TRUE) prev=elem; elem = [elem+1]
prev=nil /\ list(c,nil) prev != nil /\ (list (c,prev) * (prev -,elem) * list (elem, nil))
list(x, y) (x=y emp)
t: x_, t * list(t, y)
{list(c, nil)}
{list(c, nil)}
Extensions
• For WP we need another operator
• “Fresh” implication p -* q– We can extend a heap in which p is true with an
additional disjoint heap such that q is true in the combined heap
Disjoint Concurrency
{p1} c1 {q1} {p2} c2 {q2 }
{p1 * p2} c1 || c2 {q1 * q2 }
Disjoint Concurrency
{p1} c1 {q1} {p2} c2 {q2 }
{p1 * p2} c1 || c2 {q1 * q2 }
{10_}
[10] := 5 || [10] := 7
{?}
Cannot prove racy programs
Disjoint Concurrency
{p1} c1 {q1} {p2} c2 {q2 }
{p1 * p2} c1 || c2 {q1 * q2 }
Preconditions can pick race free programs when they exist
{x3}
[x] :=4
{[x]= 4}
{y3}
[y] :=7
{[y]= 7}
{x 3 * y 3}
{x 4 * y 7}
Example: Parallel Dispose Tree procedure dispTree(p)
{
local l, r
if (p !=nil) then {
l = [p+1];
r = [p+2];
dispose(p) || dispTree(l) || dispTree(r)
}
}
Parallel Dispose Tree - Proof Sketch
{tree(p)} dispTree(p) {emp}
{p_, l, r}
dispose(p)
{emp}
{tree(l)}
dispTree(l)
{emp}
{tree(r)}
dispTree(r)
{emp}
p _, l, r * tree(l) * tree(r)
dispose(p) || dispTree(l) || dispTree(r)
emp * emp * emp
Extensions
• Hoare Conditional Critical Regions– with r when B do C
• Fine-Grained Concurrency– Combine with Rely/Guarantee
Summary
• Separation logic provides a solution for the heap– Limited aliasing– Dynamic ownership
• Concise specifications
• Elegant proofs for several examples