370 likes | 478 Views
Local Reasoning. Peter O’Hearn John 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).
E N D
Local Reasoning Peter O’Hearn John 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} (Composition Rule) {Pb} c0 {Q} {P b} c1 {Q} {P} if b then c0 else c1{Q} (Conditional Rule) (Loop Rule) {Ib} c {I} {I} while b do c{Ib} P P’ {P’} c {Q’} Q’ Q {P} c {Q} (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 com1else com2 |while b do com|
Informal Semantics IMP++ Store: [x:3, y:40, z:17] Heap: empty • Allocation x := cons(y, z) • Heap lookup y := [x+1] • Mutation [x + 1] := 3 • Deallocation dispose(x+1) Store: [x:37, y:40, z:17] Heap: 37:40, 38:17 Store: [x:37, y:17, 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
First assertion language Aexpv 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 Reversal y: = nil ; while x nil do ( t := y y := x x := [x +1] [y+1] := t )
Assignment Axioms {?} [x] := z {[x] =y} {?} [t] := z {[x] =y} {?} [a1] := a2 {p}
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 y x
Separation Logic y x y x
Separation Logic x y * y x y x
42 10 x=10 y=42 10 42 Separation Logic x y y x
42 10 x=10 y=42 10 42 Separation Logic y x y x
42 10 x=10 y=42 10 42 Separation Logic x y * y x y x
Assertions in Separation Logic e _ l: e l ee0, e1, …, en-1 e e0* e+1 e1* … * e+n-1 en-1 ef e f * true
p * q p Weakening Unsound Axioms p p * p Contraction p= x1 p= x1 q= y 2
{true} {true} {x_ * p} [x] := 7 dispose(e) dispose(e) {?} {?} {p} In-Place Reasoning {x_ * p} [x] := 7 {x7 * p} if {p} c {q} holds then p describes the resources that c needs
s, h e = f s, h e f s, h emp s, h p * q es = fs {es} = dom(h) and h(e) = fs h=[] exist h1, h2: dom(h1)dom(h2)= s, h1 p s, h2 q h = h1 # h2 Semantics of separation logics
s, h false s, h p q s, h x. p never if s, h p then s, h q exists v: s[v/x], h p Semantics of separation logics(cont)
Three “Small” Axioms {e_} [e] := b {e b} {emp} x := cons(y, z) {x y, z} {e_} dispose(e) {emp}
{p} c {q} {p * r} c {q * r} Mod(c) free(r)={} The Frame Rule Mod(x := _) = {x} Mod([e]:=f) = Mod(dispose(e)) =
{p} c {q} {p * r} c {q * r} Mod(c) free(r)={} A simple application of the frame rule {(e_ )* p } dispose(e) {p}
Inductive Definitions • Define assertions inductively • Allows natural specifications list [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 Example y: = 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 {list(c, nil)} bool elem_delete(delval, c) prev=nil elem = c while (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)}
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 {x 3 * y 3} {y3} [y] :=7 {[y]= 7} {x3} [x] :=4 {[x]= 4} {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