Date post: | 15-Jan-2016 |
Category: |
Documents |
View: | 216 times |
Download: | 0 times |
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