Presentation is loading. Please wait.

Presentation is loading. Please wait.

Program Analysis and Verification Spring 2014 Program Analysis and Verification Lecture 6: Axiomatic Semantics III Roman Manevich Ben-Gurion University.

Similar presentations


Presentation on theme: "Program Analysis and Verification Spring 2014 Program Analysis and Verification Lecture 6: Axiomatic Semantics III Roman Manevich Ben-Gurion University."— Presentation transcript:

1 Program Analysis and Verification Spring 2014 Program Analysis and Verification Lecture 6: Axiomatic Semantics III Roman Manevich Ben-Gurion University

2 Syllabus Semantics Natural Semantics Structural semantics Axiomatic Verification Static Analysis Automating Hoare Logic Abstract Interpretation fundamentals Lattices Galois Connections Fixed-Points Widening/ Narrowing Domain constructors Interprocedural Analysis Analysis Techniques Numerical Domains CEGARAlias analysis Shape Analysis Crafting your own Soot From proofs to abstractions Systematically developing transformers 2

3 Previously Hoare logic – Inference system – Annotated programs – Soundness and completeness Weakest precondition calculus 3

4 Axiomatic semantics for While 4 { 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 ] { b  P } S { P } { P } while b do S {  b  P } [while p ] { P’ } S { Q’ } { P } S { Q } [cons p ] if P  P’ and Q’  Q

5 Weakest precondition calculus 5

6 Weakest liberal precondition A backward-going predicate transformer The weakest liberal precondition for Q is   wlp(C, Q) if and only if for all states  ’ if  C,    ’ then  ’  Q Propositions: 1.  p { wlp(C, Q) } C { Q } 2.If  p { P } C { Q } then P  wlp(C, Q) 6

7 Weakest liberal precondition A backward-going predicate transformer The weakest liberal precondition for Q is   wlp(C, Q) if and only if for all states  ’ if  C,    ’ then  ’  Q 7 P C(P)C(P) Q C wlp(C, Q) C(wlp(C, Q))

8 Strongest postcondition A forward-going predicate transformer The strongest postcondition for P is  ’  sp(P, C) if and only if there exists  such that   P and  C,    ’ Propositions: 1.  p { P } C { sp(P, C) } 2.If  p { P } C { Q } then sp(P, C)  Q 8

9 Calculating Weakest preconditions 9 By Vadim Plessky (http://svgicons.sourceforge.net/) [see page for license], via Wikimedia Commons

10 Calculating wlp 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) = … ? hard to capture 10

11 Calculating the wlp of a loop 11 wlp( while b do S, Q) = Idea: we know the following statements are semantically equivalent while b do S if b do ( S ; while b do S ) else skip Let’s try to substitute and calculate on wlp( if b do ( S ; while b do S ) else skip, Q) = (b  wlp(S ; while b do S, Q))  (  b  wlp( skip, Q)) = (b  wlp(S, wlp( while b do S, Q)))  (  b  Q) LoopInv = (b  wlp(S, LoopInv))  (  b  Q)

12 Another variant for WP of loops Parametric in the loop invariant wlp( while b do {  } S, Q) =  where {b   } S {  } and  b    Q 12

13 Variable swap program – specify 13 { ? } t := x x := y y := t { ? }

14 Prove using weakest precondition 14 { y=b  x=a } t := x { ? } x := y { ? } y := t { x=b  y=a }

15 Prove using weakest precondition 15 { y=b  x=a } t := x { y=b  t=a } x := y { x=b  t=a } y := t { x=b  y=a }

16 Absolute value program 16 if x<0 then x := -x else skip if b then S is syntactic sugar for if b then S else skip The latter form is easier to reason about

17 Absolute value program – specify 17 { ? } if x<0 then x := -x else skip { ? }

18 Absolute value program – specify 18 { x=v } if x<0 then x := -x else skip { x=|v| }

19 Prove using weakest precondition 19 { x=v } { } if x<0 then { } x := -x { } else { } skip { } {x=|v| }

20 Prove using weakest precondition 20 { 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| }

21 Making the proof system more practical 21

22 Conjunction rule 22 Allows breaking up proofs into smaller, easier to manage, sub-proofs

23 More useful rules 23 { 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

24 Invariance + Conjunction = Constancy 24 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)={}

25 Today Strongest postcondition Extension for memory Proving termination 25

26 Strongest postcondition calculus 26 By Vadim Plessky (http://svgicons.sourceforge.net/) [see page for license], via Wikimedia Commons

27 Floyd’s strongest postcondition rule Example { z=x } x:=x+1 { ?} 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 27 { 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

28 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 28 { P } x := a {  v. x=a[v/x]  P[v/x] } where v is a fresh variable [ass Floyd ] meaning: {x=z+1}

29 “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} 29 { 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

30 “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} 30 { x=v } x:=a { x=a[v/x] } where v  FV(a) [ass floyd ]

31 “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} 31 { x=v } x:=a { x=a[v/x] } where v  FV(a) [ass floyd ]

32 “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} 32 { x=v } x:=a { x=a[v/x] } where v  FV(a) [ass floyd ]

33 Calculating sp 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   33

34 Prove using strongest postcondition 34 { x=a  y=b } t := x x := y y := t { x=b  y=a }

35 Prove using strongest postcondition 35 { x=a  y=b } t := x { x=a  y=b  t=a } x := y y := t { x=b  y=a }

36 Prove using strongest postcondition 36 { 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 }

37 Prove using strongest postcondition 37 { 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

38 Prove using strongest postcondition 38 { 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| }

39 Prove using strongest postcondition 39 { 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| }

40 Sum program – specify Define Sum(0, n) = 0+1+…+n 40 {?} 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

41 Sum program – specify Define Sum(0, n) = 0+1+…+n 41 { 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

42 Sum program – prove Define Sum(0, n) = 0+1+…+n 42 { 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) }

43 Sum program – prove Define Sum(0, n) = 0+1+…+n 43 { 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) }

44 Sum program – prove Define Sum(0, n) = 0+1+…+n 44 { 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) }

45 Sum program – prove Define Sum(0, n) = 0+1+…+n 45 { 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) }

46 Sum program – prove Define Sum(0, n) = 0+1+…+n 46 { 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) }

47 Sum program – prove Define Sum(0, n) = 0+1+…+n 47 { 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) }

48 Sum program – prove Define Sum(0, n) = 0+1+…+n 48 { 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) }

49 Sum program – prove Define Sum(0, n) = 0+1+…+n 49 { 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 { 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) }

50 Buggy sum program 50 { 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) }

51 Handling data structures 51

52 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? 52 The rule works on a syntactic level unaware of possible aliasing between different terms (y and *x in our case)

53 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? 53

54 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 54

55 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 55

56 Axiomatizing data types 56 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) }

57 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) 57 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

58 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) 58 [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}

59 Array update rules (sp) 59 [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

60 Example of proving program with arrays 60

61 Array-max program – specify 61 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 1.{ x=N } 2.{  m. (m  0  m<N)  nums(m)  res } 3.{  m. m  0  m<N  nums(m)=res } 4.{ nums=orig_nums }

62 Array-max program 62 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 }

63 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 63

64 Array-max example: Post 1 64 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 }

65 Array-max example: Post 2 65 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 }

66 Array-max example: Post 3 66 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 }

67 Proving termination 67

68 Total correctness semantics for While 68 [ 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

69 Total correctness semantics for While 69 [ 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  t0P  t0 Rank, or Loop variant

70 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 [] 70

71 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 ] 71

72 Array-max – specify termination 72 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 [?]

73 Array-max – specify termination 73 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 ]

74 Array-max – prove loop variant 74 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 ]

75 Array-max – prove loop variant 75 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

76 Array-max – prove loop variant 76 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 ]

77 Array-max – prove loop variant 77 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 ]

78 Array-max – prove loop variant 78 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 ]

79 Zune calendar bugbug while (days > 365) { if (IsLeapYear(year)) { if (days > 366) { days -= 366; year += 1; } } else { days -= 365; year += 1; } 79

80 Fixed code while (days > 365) { if (IsLeapYear(year)) { if (days > 366) { days -= 366; year += 1; } else { break; } } else { days -= 365; year += 1; } 80

81 Fixed code – specify termination [ ? ] while (days > 365) { if (IsLeapYear(year)) { if (days > 366) { days -= 366; year += 1; } else { break; } } else { days -= 365; year += 1; } [ ? ] 81

82 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 ] 82

83 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 ] 83 Let’s model break by a small cheat – assume execution never gets past it

84 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 ] 84

85 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 85 { b  P } S { b } { P } while b do S { false } [while-nt p ]

86 conclusion 86

87 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 87

88 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 88

89 Next lecture: static analysis


Download ppt "Program Analysis and Verification Spring 2014 Program Analysis and Verification Lecture 6: Axiomatic Semantics III Roman Manevich Ben-Gurion University."

Similar presentations


Ads by Google