Program Analysis and Verification Spring 2015 Program Analysis and Verification Lecture 6: Axiomatic Semantics III Roman Manevich Ben-Gurion University
Tentative syllabus Semantics Natural Semantics Structural semantics Axiomatic Verification Static Analysis Automating Hoare Logic Control Flow Graphs Equation Systems Collecting Semantics Abstract Interpretation fundamentals LatticesFixed-Points Chaotic Iteration Galois Connections Domain constructors Widening/ Narrowing Analysis Techniques Numerical Domains Alias analysis Interprocedural Analysis Shape Analysis CEGAR Crafting your own Soot From proofs to abstractions Systematically developing transformers 2
Previously Hoare logic – Inference system – Annotated programs – Soundness and completeness Weakest precondition calculus Strongest postcondition calculus 3
Weakest (liberal) precondition rules 1.wlp( skip, Q) = Q 2.wlp( x := a, Q) = Q[a/ x ] 3.wlp(S 1 ; S 2, Q) = wlp(S 1, wlp(S 2, Q)) 4.wlp( if b then S 1 else S 2, Q) = (b wlp(S 1, Q)) ( b wlp(S 2, Q)) 5.wlp( while b do { } S, Q) = where {b } S { } and b Q 4 Use consequence rule here
Strongest postcondition rules 1.sp( skip, P) = P 2.sp( x := a, P) = v. x=a[v/x] P[v/x] 3.sp(S 1 ; S 2, P) = sp(S 2, sp(S 1, P)) 4.sp( if b then S 1 else S 2, P) = sp(S 1, b P) sp(S 2, b P) 5.sp( while b do { } S, P) = b where {b } S { } and P b 5 Use consequence rule here
Warm-up 6
Proof of swap by WP 7 { y=b x=a } t := x { y=b t=a } x := y { x=b t=a } y := t { x=b y=a }
Prove swap via SP 8 { y=b x=a } t := x { } x := y {} y := t { x=b y=a }
Prove swap via SP 9 { y=b x=a } t := x { v. t=x y=b x=a } x := y { v. x=y t=v y=b v=a } { x=y y=b v. t=v v=a } { x=y y=b t=a } y := t { v. y=t x=v v=b t=a } { y=t t=a v. x=v v=b } { y=t t=a x=b } { x=b y=a } Quantifier elimination (a very trivial one) Quantifier elimination
Proof of absolute value via WP 10 { x=v } { (-x=|v| x<0) (x=|v| x 0) } if x<0 then { -x=|v| } x := -x { x=|v| } else { x=|v| } skip { x=|v| } { x=|v| }
Prove absolute value by SP 11 { x=v } {} if x<0 then {} x := -x {} else { } skip {} { } { x=|v| }
Proof of absolute value via WP 12 { x=v } if x<0 then { x=v x<0 } x := -x { w. x=-w w=v w<0 } { x=-v v<0 } else { x=v x 0 } skip { x=v x 0 } { x=-v v<0 x=v x 0 } { x=|v| }
Agenda Some useful rules Extension for memory Proving termination 13
Making the proof system more practical 14
Conjunction rule 15 Allows breaking up proofs into smaller, easier to manage, sub-proofs
More useful rules 16 { P } C { Q } { P’ } C { Q’ } { P P’ } C {Q Q’ } [disj p ] { P } C { Q } { v. P } C { v. Q } [exist p ] v FV( C) { P } C { Q } { v. P } C { v. Q } [univ p ] v FV(C ) { F } C { F } Mod(C) FV(F)={} [Inv p ] Mod(C) = set of variables assigned to in sub-statements of C FV(F) = free variables of F Breaks if C is non- deterministic
Invariance + Conjunction = Constancy 17 Mod(C) = set of variables assigned to in sub-statements of C FV(F) = free variables of F { P } C { Q } { F P } C { F Q } [constancy p ] Mod(C) FV(F)={}
Strongest postcondition calculus practice 18 By Vadim Plessky ( [see page for license], via Wikimedia Commons
Floyd’s strongest postcondition rule Example { z=x } x:=x+1 { ?} 19 { P } x := a { v. x=a[v/x] P[v/x] } where v is a fresh variable [ass Floyd ] The value of x in the pre-state
Floyd’s strongest postcondition rule Example { z=x } x:=x+1 { v. x=v+1 z=v } This rule is often considered problematic because it introduces a quantifier – needs to be eliminated further on We will now see a variant of this rule 20 { P } x := a { v. x=a[v/x] P[v/x] } where v is a fresh variable [ass Floyd ] meaning: {x=z+1}
“Small” assignment axiom Examples: {x=n} x:=5*y {x=5*y} {x=n} x:=x+1 {x=n+1} {x=n} x:=y+1 {x=y+1} [exist p ] { n. x=n} x:=y+1 { n. x=y+1} therefore {true} x:=y+1 {x=y+1} [constancy p ] {z=9} x:=y+1 {z=9 x=y+1} 21 { x=v } x:=a { x=a[v/x] } where v FV(a) [ass floyd ] First evaluate a in the precondition state (as a may access x) Then assign the resulting value to x Create an explicit Skolem variable in precondition
“Small” assignment axiom Examples: {x=n} x:=5*y {x=5*y} {x=n} x:=x+1 {x=n+1} {x=n} x:=y+1 {x=y+1} [exist p ] { n. x=n} x:=y+1 { n. x=y+1} therefore {true} x:=y+1 {x=y+1} [constancy p ] {z=9} x:=y+1 {z=9 x=y+1} 22 { x=v } x:=a { x=a[v/x] } where v FV(a) [ass floyd ]
“Small” assignment axiom Examples: {x=n} x:=5*y {x=5*y} {x=n} x:=x+1 {x=n+1} {x=n} x:=y+1 {x=y+1} [exist p ] { n. x=n} x:=y+1 { n. x=y+1} therefore {true} x:=y+1 {x=y+1} [constancy p ] {z=9} x:=y+1 {z=9 x=y+1} 23 { x=v } x:=a { x=a[v/x] } where v FV(a) [ass floyd ]
“Small” assignment axiom Examples: {x=n} x:=5*y {x=5*y} {x=n} x:=x+1 {x=n+1} {x=n} x:=y+1 {x=y+1} [exist p ] { n. x=n} x:=y+1 { n. x=y+1} therefore {true} x:=y+1 {x=y+1} [constancy p ] {z=9} x:=y+1 {z=9 x=y+1} 24 { x=v } x:=a { x=a[v/x] } where v FV(a) [ass floyd ]
Prove using strongest postcondition 25 { x=a y=b } t := x x := y y := t { x=b y=a }
Prove using strongest postcondition 26 { x=a y=b } t := x { x=a y=b t=a } x := y y := t { x=b y=a }
Prove using strongest postcondition 27 { x=a y=b } t := x { x=a y=b t=a } x := y { x=b y=b t=a } y := t { x=b y=a }
Prove using strongest postcondition 28 { x=a y=b } t := x { x=a y=b t=a } x := y { x=b y=b t=a } y := t { x=b y=a t=a } { x=b y=a } // cons
Prove using strongest postcondition 29 { x=v } if x 0 } else { x=v x 0 } skip { x=v x 0 } { v<0 x=-v v 0 x=v } { x=|v| }
Prove using strongest postcondition 30 { x=v } if x 0 } else { x=v x 0 } skip { x=v x 0 } { v<0 x=-v v 0 x=v } { x=|v| }
Sum program – specify Define Sum(0, n) = 0+1+…+n 31 {?} x := 0 res := 0 while (x<y) do res := res+x x := x+1 {?} { x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) } Background axiom
Sum program – specify Define Sum(0, n) = 0+1+…+n 32 { y 0 } x := 0 res := 0 while (x<y) do res := res+x x := x+1 { res = Sum(0, y) } { x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) } Background axiom
Sum program – prove Define Sum(0, n) = 0+1+…+n 33 { y 0 } x := 0 res := 0 Inv = while (x<y) do res := res+x x := x+1 { res = Sum(0, y) } { x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) }
Sum program – prove Define Sum(0, n) = 0+1+…+n 34 { y 0 } x := 0 { y 0 x=0 } res := 0 Inv = while (x<y) do res := res+x x := x+1 { res = Sum(0, y) } { x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) }
Sum program – prove Define Sum(0, n) = 0+1+…+n 35 { y 0 } x := 0 { y 0 x=0 } res := 0 { y 0 x=0 res=0 } Inv = while (x<y) do res := res+x x := x+1 { res = Sum(0, y) } { x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) }
Sum program – prove Define Sum(0, n) = 0+1+…+n 36 { y 0 } x := 0 { y 0 x=0 } res := 0 { y 0 x=0 res=0 } Inv = { y 0 res=Sum(0, x) x y } while (x<y) do res := res+x x := x+1 { res = Sum(0, y) } { x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) }
Sum program – prove Define Sum(0, n) = 0+1+…+n 37 { y 0 } x := 0 { y 0 x=0 } res := 0 { y 0 x=0 res=0 } Inv = { y 0 res=Sum(0, x) x y } while (x<y) do { y 0 res=m x=n n y m=Sum(0, n) x<y } { y 0 res=m x=n m=Sum(0, n) n<y } res := res+x x := x+1 { res = Sum(0, y) } { x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) }
Sum program – prove Define Sum(0, n) = 0+1+…+n 38 { y 0 } x := 0 { y 0 x=0 } res := 0 { y 0 x=0 res=0 } Inv = { y 0 res=Sum(0, x) x y } while (x<y) do { y 0 res=m x=n n y m=Sum(0, n) x<y } { y 0 res=m x=n m=Sum(0, n) n<y } res := res+x { y 0 res=m+x x=n m=Sum(0, n) n<y } x := x+1 { res = Sum(0, y) } { x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) }
Sum program – prove Define Sum(0, n) = 0+1+…+n 39 { y 0 } x := 0 { y 0 x=0 } res := 0 { y 0 x=0 res=0 } Inv = { y 0 res=Sum(0, x) x y } while (x<y) do { y 0 res=m x=n n y m=Sum(0, n) x<y } { y 0 res=m x=n m=Sum(0, n) n<y } res := res+x { y 0 res=m+x x=n m=Sum(0, n) n<y } x := x+1 { y 0 res=m+x x=n+1 m=Sum(0, n) n<y } { y 0 res=Sum(0, x) x=n+1 n<y } // sum axiom { y 0 res=Sum(0, x) x y } // cons { res = Sum(0, y) } { x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) }
Sum program – prove Define Sum(0, n) = 0+1+…+n 40 { y 0 } x := 0 { y 0 x=0 } res := 0 { y 0 x=0 res=0 } Inv = { y 0 res=Sum(0, x) x y } while (x<y) do { y 0 res=m x=n n y m=Sum(0, n) x<y } { y 0 res=m x=n m=Sum(0, n) n<y } x := x+1 { y 0 res=m x=n+1 m=Sum(0, n) n<y } res := res+x { y 0 res=m+x x=n+1 m=Sum(0, n) n<y } { y 0 res=Sum(0, x) x=n+1 n<y } // sum axiom { y 0 res=Sum(0, x) x y } // cons { y 0 res=Sum(0, x) x y x y } { y 0 res=Sum(0, y) x=y } { res = Sum(0, y) } { x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) }
Buggy sum program 1 Define Sum(0, n) = 0+1+…+n 41 { y 0 } x := 0 { y 0 x=0 } res := 0 { y 0 x=0 res=0 } Inv = { y 0 res=Sum(0, x) x y } while (x<y) do { y 0 res=m x=n n y m=Sum(0, n) x<y } { y 0 res=m x=n m=Sum(0, n) n<y } res := res+x { y 0 res=m+x x=n m=Sum(0, n) n<y } x := x+1 { y 0 res=m+n x=n+1 m=Sum(0, n) n<y } { y 0 res=Sum(0, n)+n x=n+1 n<y } { y 0 res=Sum(0, x) x y } // cons { y 0 res=Sum(0, x) x y x y } { y 0 res=Sum(0, y) x=y } { res = Sum(0, y) } { x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) }
Buggy sum program 2 42 { y 0 } x := 0 { y 0 x=0 } res := 0 { y 0 x=0 res=0 } Inv = { y 0 res=Sum(0, x) } = { y 0 res=m x=n m=Sum(0, n) } while (x y) do { y 0 res=m x=n m=Sum(0, n) x y n y } x := x+1 { y 0 res=m x=n+1 m=Sum(0, n) n y} res := res+x { y 0 res=m+x x=n+1 m=Sum(0, n) n y} { y 0 res-x=Sum(0, x-1) n y} { y 0 res=Sum(0, x) } { y 0 res=Sum(0, x) x>y } {res = Sum(0, y) }
Handling data structures 43
Problems with Hoare logic and heaps { P[a/ x ] } x := a { P } Consider the annotated program { y=5 } y := 5; { y=5 } x := &y; { y=5 } *x := 7; { y=5 } Is it correct? 44 The rule works on a syntactic level unaware of possible aliasing between different terms (y and *x in our case)
Problems with Hoare logic and heaps { P[a/ x ] } x := a { P } {(x=&y z=5) (x &y y=5)} *x = z; { y=5 } What should the precondition be? 45
Problems with Hoare logic and heaps { P[a/ x ] } x := a { P } {(x=&y z=5) (x &y y=5)} *x = z; { y=5 } We split into cases depending on possible aliasing 46
Problems with Hoare logic and heaps { P[a/ x ] } x := a { P } {(x=&y z=5) (x &y y=5)} *x = z; { y=5 } What should the precondition be? Joseph M. Morris: A General Axiom of AssignmentA General Axiom of Assignment A different approach: heaps as arrays Really successful approach for heaps is based on Separation Logic Separation Logic 47
Axiomatizing data types 48 We added a new type of variables – array variables – Model array variable as a function y : Z Z Re-define program states State = Define operational semantics x := y [ a ], y [ a ] := x, S ::= x := a | x := y [ a ] | y [ a ] := x | skip | S 1 ; S 2 | if b then S 1 else S 2 | while b do S
Axiomatizing data types 49 We added a new type of variables – array variables – Model array variable as a function y : Z Z We need the two following axioms: S ::= x := a | x := y [ a ] | y [ a ] := x | skip | S 1 ; S 2 | if b then S 1 else S 2 | while b do S { y[x a](x) = a } { z x y[x a](z) = y(z) }
Array update rules (wlp) Treat an array assignment y[a] := x as an update to the array function y – y := y[a x] meaning y’= v. v=a ? x : y(v) 50 S ::= x := a | x := y [ a ] | y [ a ] := x | skip | S 1 ; S 2 | if b then S 1 else S 2 | while b do S [array-update] { P[y[a x]/y] } y[a] := x { P } [array-load] { P[y(a)/x] } x := y[a] { P } A very general approach – allows handling many data types
Array update rules (wlp) example Treat an array assignment y[a] := x as an update to the array function y – y := y[a x] meaning y’= v. v=a ? x : y(v) 51 [array-update] { P[y[a x]/y] } y[a] := x { P } {x=y[i 7](i)} y[i]:=7 {x=y(i)} {x=7} y[i]:=7 {x=y(i)} [array-load] { P[y(a)/x] } x := y[a] { P } {y(a)=7} x:=y[a] {x=7}
Array update rules (sp) 52 [array-update F ] { x=v y=g a=b } y[a] := x { y=g[b v] } [array-load F ] { y=g a=b } x := y[a] { x=g(b) } In both rules v, g, and b are fresh
practice proving programs with arrays 53
Array-max program – specify 54 nums : array N : int // N stands for num’s length { N 0 nums=orig_nums } x := 0 res := nums[0] while x res then res := nums[x] x := x { x=N } 2.{ m. (m 0 m<N) nums(m) res } 3.{ m. m 0 m<N nums(m)=res } 4.{ nums=orig_nums }
Array-max program 55 nums : array N : int // N stands for num’s length { N 0 nums=orig_nums } x := 0 res := nums[0] while x res then res := nums[x] x := x + 1 Post 1 : { x=N } Post 2 : { nums=orig_nums } Post 3 : { m. 0 m<N nums(m) res } Post 4 : { m. 0 m<N nums(m)=res }
Proof strategy Prove each goal 1, 2, 3, 4 separately and use conjunction rule to prove them all After proving – {N 0} C {x=N} – {nums=orig_nums} C {nums=orig_nums} We have proved – {N 0 nums=orig_nums} C {x=N nums=orig_nums} We can refer to assertions from earlier proofs in writing new proofs 56
Array-max example: Post 1 57 nums : array N : int // N stands for num’s length { N 0 } x := 0 { N 0 x=0 } res := nums[0] { x=0 } Inv = { x N } while x res then { x=k k<N } res := nums[x] { x=k k<N } { x=k k<N } x := x + 1 { x=k+1 k<N } { x N x N } { x=N }
Array-max example: Post 2 58 nums : array N : int // N stands for num’s length { nums=orig_nums } x := 0 { nums=orig_nums } res := nums[0] { nums=orig_nums } Inv = { nums=orig_nums } while x res then { nums=orig_nums } res := nums[x] { nums=orig_nums } { nums=orig_nums } x := x + 1 { nums=orig_nums } { nums=orig_nums x N } { nums=orig_nums }
Array-max example: Post 3 59 nums : array { N 0 0 m res then { nums(x)>oRes res=oRes x=k 0 m oRes x=k 0 m<k nums(m) oRes } { x=k 0 m k nums(m) res } { (x=k 0 m k nums(m) res) (oRes nums(x) res=oRes x=k res=oRes 0 m<k nums(m) oRes)} { x=k 0 m k nums(m) res } x := x + 1 { x=k+1 0 m k nums(m) res } { 0 m<x nums(m) res } { x=N 0 m<x nums(m) res} [univ p ] { m. 0 m<N nums(m) res }
Proving termination 60 By Noble0 (Own work) [CC BY-SA 3.0 ( via Wikimedia Commons
Total correctness semantics for While 61 [ P[a/ x ] ] x := a [ P ] [ass p ] [ P ] skip [ P ] [skip p ] [ P ] S 1 [ Q ],[ Q ] S 2 [ R ] [ P ] S 1 ; S 2 [ R ] [comp p ] [ b P ] S 1 [ Q ], [ b P ] S 2 [ Q ] [ P ] if b then S 1 else S 2 [ Q ] [if p ] [ P’ ] S [ Q’ ] [ P ] S [ Q ] [cons p ] if P P’ and Q’ Q [while p ] [ P(z+1) ] S [ P(z) ] [ z. P(z) ] while b do S [ P(0) ] P(z+1) b P(0) b
Total correctness semantics for While 62 [ P[a/ x ] ] x := a [ P ] [ass p ] [ P ] skip [ P ] [skip p ] [ P ] S 1 [ Q ],[ Q ] S 2 [ R ] [ P ] S 1 ; S 2 [ R ] [comp p ] [ b P ] S 1 [ Q ], [ b P ] S 2 [ Q ] [ P ] if b then S 1 else S 2 [ Q ] [if p ] [ P’ ] S [ Q’ ] [ P ] S [ Q ] [cons p ] if P P’ and Q’ Q [while p ] [ b P t=k ] S [ P t<k ] [ P ] while b do S [ b P ] P t0P t0 Rank, or Loop variant
Proving termination There is a more general rule based on well- founded relations – Partial orders with no infinite strictly decreasing chains Exercise: write a rule that proves only that a program S, started with precondition P terminates [] S [] 63
Proving termination There is a more general rule based on well- founded relations – Partial orders with no infinite strictly decreasing chains Exercise: write a rule that proves only that a program S, started with precondition P terminates [ P ] S [ true ] 64
Array-max – specify termination 65 nums : array N : int // N stands for num’s length x := 0 res := nums[0] Variant = [?] while x res then res := nums[x] x := x + 1 [?]
Array-max – specify termination 66 nums : array N : int // N stands for num’s length x := 0 res := nums[0] Variant = [ N-x ] while x < N [ ? ] if nums[x] > res then res := nums[x] x := x + 1 [ ? ] [ true ]
Array-max – prove loop variant 67 nums : array N : int // N stands for num’s length x := 0 res := nums[0] Variant = [ t=N-x ] while x < N [ x<N N-x=k N-x 0 ] if nums[x] > res then res := nums[x] x := x + 1 // [ N-x<k N-x 0 ] [ true ]
Array-max – prove loop variant 68 nums : array N : int // N stands for num’s length x := 0 res := nums[0] Variant = [ t=N-x ] while x < N [ x=x0 x0<N N-x0=k N-x0 0 ] if nums[x] > res then res := nums[x] x := x + 1 // [ N-x<k N-x 0 ] [ true ] Capture initial value of x, since it changes in the loop
Array-max – prove loop variant 69 nums : array N : int // N stands for num’s length x := 0 res := nums[0] Variant = [ t=N-x ] while x < N [ x=x0 x0<N N-x0=k N-x0 0 ] if nums[x] > res then res := nums[x] [ x=x0 x0<N N-x0=k N-x0 0 ] // Frame x := x + 1 // [ N-x<k N-x 0 ] [ true ]
Array-max – prove loop variant 70 nums : array N : int // N stands for num’s length x := 0 res := nums[0] Variant = [ t=N-x ] while x < N [ x=x0 x0<N N-x0=k N-x0 0 ] if nums[x] > res then res := nums[x] [ x=x0 x0<N N-x0=k N-x0 0 ] // Frame x := x + 1 [ x=x0+1 x0<N N-x0=k N-x0 0 ] // [ N-x<k N-x 0 ] [ true ]
Array-max – prove loop variant 71 nums : array N : int // N stands for num’s length x := 0 res := nums[0] Variant = [ t=N-x ] while x < N [ x=x0 x0<N N-x0=k N-x0 0 ] if nums[x] > res then res := nums[x] [ x=x0 x0<N N-x0=k N-x0 0 ] // Frame x := x + 1 [ x=x0+1 x0<N N-x0=k N-x0 0 ] [ N-x<k N-x 0 ] // cons [ true ]
Zune calendar bugbug while (days > 365) { if (IsLeapYear(year)) { if (days > 366) { days -= 366; year += 1; } } else { days -= 365; year += 1; } 72
Fixed code while (days > 365) { if (IsLeapYear(year)) { if (days > 366) { days -= 366; year += 1; } else { break; } } else { days -= 365; year += 1; } 73
Fixed code – specify termination [ ? ] while (days > 365) { if (IsLeapYear(year)) { if (days > 366) { days -= 366; year += 1; } else { break; } } else { days -= 365; year += 1; } [ ? ] 74
Fixed code – specify variant [ true ] Variant = [ ? ] while (days > 365) { if (IsLeapYear(year)) { if (days > 366) { days -= 366; year += 1; } else { break; } } else { days -= 365; year += 1; } [?] } [ true ] 75
Fixed code – proving termination [ true ] Variant = [ t=days ] while (days > 365) { [ days>365 days=k days 0 ] if (IsLeapYear(year)) { if (days > 366) { days -= 366; year += 1; } else { break; [ false ] } } else { days -= 365; year += 1; } // [ days 0 days<k ] } [ true ] 76 Let’s model break by a small cheat – assume execution never gets past it
Fixed code – proving termination [ true ] Variant = [ t=days ] while (days > 365) { [ days 0 k=days days>365 ] -> [ days 0 k=days days>365 ] if (IsLeapYear(year)) { [ k=days days>365 ] if (days > 366) { [ k=days days>365 days>366 ] -> [ k=days days>366 ] days -= 366; [ days=k-366 days>0 ] year += 1; [ days=k-366 days>0 ] } else { [ k=days days>365 days 366 ] break; [ false ] } [ (days=k-366 days>0) false ] -> [ days 0 ] } else { [ k=days days>365 ] days -= 365; [ k-365=days days-365>365 ] -> [ k-365=days days 0 ] -> [ days<k days 0 ] year += 1; [ days<k days 0 ] } [ days<k days 0 ] } [ true ] 77
Challenge: proving non-termination Write a rule for proving that a program does not terminate when started with a precondition P Prove that the buggy Zune calendar program does not terminate 78 { b P } S { b } { P } while b do S { false } [while-nt p ]
conclusion 79
Extensions to axiomatic semantics Assertions for execution time – Exact time – Order of magnitude time Assertions for dynamic memory – Separation Logic Separation Logic Assertions for parallelism – Owicki-Gries Owicki-Gries – Concurrent Separation Logic – Rely-guarantee 80
Axiomatic verification conclusion Very powerful technique for reasoning about programs – Sound and complete Extendible Static analysis can be used to automatically synthesize assertions and loop invariants 81
Next lecture: static analysis