Download presentation
Presentation is loading. Please wait.
1
Spring 2016 Program Analysis and Verification
Lecture 5: Axiomatic Semantics III Roman Manevich Ben-Gurion University
2
Tentative syllabus Program Verification Program Analysis Basics
Operational semantics Hoare Logic Applying Hoare Logic Weakest Precondition Calculus Proving Termination Data structures Program Analysis Basics Control Flow Graphs Equation Systems Collecting Semantics Using Soot Abstract Interpretation fundamentals Lattices Fixed-Points Chaotic Iteration Galois Connections Domain constructors Widening/ Narrowing Analysis Techniques Numerical Domains Alias analysis Interprocedural Analysis Shape Analysis CEGAR
3
Previously Hoare logic Weakest precondition calculus
Inference system Annotated programs Soundness and completeness Weakest precondition calculus Strongest postcondition calculus
4
Weakest (liberal) precondition rules
wlp(skip, Q) = Q wlp(x := a, Q) = Q[a/x] wlp(S1; S2, Q) = wlp(S1, wlp(S2, Q)) wlp(if b then S1 else S2, Q) = (b wlp(S1, Q)) (b wlp(S2, Q)) wlp(while b do {} S, Q) = where {b } S {} and b Q Inv ((Inv b) wp(S, Inv)) ((Inv b) Q) Parameterized by the loop invariant Inv
5
Strongest postcondition rules
sp(skip, P) = P sp(x := a, P) = v. x=a[v/x] P[v/x] sp(S1; S2, P) = sp(S2, sp(S1, P)) sp(if b then S1 else S2, P) = sp(S1, b P) sp(S2, b P) sp(while b do {} S, P) = b where {b } S {} and P b Inv ((Inv b) wp(S, Inv)) ((Inv b) Q) Parameterized by the loop invariant Inv
6
Warm-up
7
Proof of swap by WP { y=b x=a }
t := x { y=b t=a } x := y { x=b t=a } y := t { x=b y=a }
8
Prove swap via SP { y=b x=a }
t := x { } x := y { } y := t { x=b y=a }
9
Prove swap via SP { 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 Quantifier elimination
10
Proof of absolute value via WP
{ x=v } { (-x=|v| x<0) (x=|v| x0) } if x<0 then { -x=|v| } x := -x { x=|v| } else { x=|v| } skip { x=|v| } { x=|v| }
11
Prove absolute value by SP
{ x=v } { } if x<0 then { } x := -x { } else { } skip { } { } { x=|v| }
12
Proof of absolute value via SP
{ 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 x0 } skip { x=v x0 } { x=-v v<0 x=v x0 } { x=|v| }
13
Agenda Some useful rules Extension for memory Proving termination
14
Making the proof system more practical
15
{ P } S { Q } { P’ } S { Q’ } { P P’ } S {Q Q’ }
Conjunction rule { P } S { Q } { P’ } S { Q’ } { P P’ } S {Q Q’ } [conjp] Allows breaking up proofs into smaller, easier to manage, sub-proofs
16
More useful rules [Invp]
Breaks if C is non-deterministic { P } C { Q } { P’ } C { Q’ } { P P’ } C {Q Q’ } [disjp] { P } C { Q } { v. P } C { v. Q } [existp] vFV(C) { P } C { Q } {v. P } C {v. Q } [univp] vFV(C) { F } C { F } Mod(C) FV(F)={} [Invp] Mod(C) = set of variables assigned to in sub-statements of C FV(F) = free variables of F
17
Invariance + Conjunction = Constancy
{ P } C { Q } { F P } C { F Q } [constancyp] Mod(C) FV(F)={} Mod(C) = set of variables assigned to in sub-statements of C FV(F) = free variables of F
18
Strongest postcondition calculus practice
By Vadim Plessky ( [see page for license], via Wikimedia Commons
19
Floyd’s strongest postcondition rule
{ P } x := a { v. x=a[v/x] P[v/x] } where v is a fresh variable [assFloyd] The value of x in the pre-state Example { z=x } x:=x+1 { ? }
20
Floyd’s strongest postcondition rule
{ P } x := a { v. x=a[v/x] P[v/x] } where v is a fresh variable [assFloyd] meaning: {x=z+1} 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
21
“Small” assignment axiom
First evaluate a in the precondition state (as a may access x) Create an explicit Skolem variable in precondition Then assign the resulting value to x [assfloyd] { x=v } x:=a { x=a[v/x] } where vFV(a) 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} [existp] {n. x=n} x:=y+1 {n. x=y+1} therefore {true} x:=y+1 {x=y+1} [constancyp] {z=9} x:=y+1 {z=9 x=y+1}
22
“Small” assignment axiom
[assfloyd] { x=v } x:=a { x=a[v/x] } where vFV(a) 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} [existp] {n. x=n} x:=y+1 {n. x=y+1} therefore {true} x:=y+1 {x=y+1} [constancyp] {z=9} x:=y+1 {z=9 x=y+1}
23
“Small” assignment axiom
[assfloyd] { x=v } x:=a { x=a[v/x] } where vFV(a) 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} [existp] {n. x=n} x:=y+1 {n. x=y+1} therefore {true} x:=y+1 {x=y+1} [constancyp] {z=9} x:=y+1 {z=9 x=y+1}
24
“Small” assignment axiom
[assfloyd] { x=v } x:=a { x=a[v/x] } where vFV(a) 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} [existp] {n. x=n} x:=y+1 {n. x=y+1} therefore {true} x:=y+1 {x=y+1} [constancyp] {z=9} x:=y+1 {z=9 x=y+1}
25
Prove using strongest postcondition
{ x=a y=b } t := x x := y y := t { x=b y=a }
26
Prove using strongest postcondition
{ x=a y=b } t := x { x=a y=b t=a } x := y y := t { x=b y=a }
27
Prove using strongest postcondition
{ 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 }
28
Prove using strongest postcondition
{ 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
29
Prove using strongest postcondition
{ x=v } if x<0 then { x=v x<0 } x := -x { x=-v x>0 } else { x=v x0 } skip { x=v x0 } { v<0 x=-v v0 x=v } { x=|v| }
30
Prove using strongest postcondition
{ x=v } if x<0 then { x=v x<0 } x := -x { x=-v x>0 } else { x=v x0 } skip { x=v x0 } { v<0 x=-v v0 x=v } { x=|v| }
31
{ x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) }
Sum program – specify { x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) } Define Sum(0, n) = 0+1+…+n { ? } x := 0 res := 0 while (x<y) do x := x res := res+x { ? } Background axiom
32
{ x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) }
Sum program – specify { x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) } Define Sum(0, n) = 0+1+…+n { y0 } x := 0 res := 0 while (x<y) do x := x res := res+x { res = Sum(0, y) } Background axiom
33
{ x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) }
Sum program – prove { x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) } Define Sum(0, n) = 0+1+…+n { y0 } x := 0 res := 0 Inv = while (x<y) do x := x res := res+x { res = Sum(0, y) }
34
{ x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) }
Sum program – prove { x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) } Define Sum(0, n) = 0+1+…+n { y0 } x := 0 { y0 x=0 } res := 0 Inv = while (x<y) do x := x+1 res := res+x { res = Sum(0, y) }
35
{ x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) }
Sum program – prove { x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) } Define Sum(0, n) = 0+1+…+n { y0 } x := 0 { y0 x=0 } res := 0 { y0 x=0 res=0 } Inv = while (x<y) do x := x+1 res := res+x { res = Sum(0, y) }
36
{ x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) }
Sum program – prove { x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) } Define Sum(0, n) = 0+1+…+n { y0 } x := 0 { y0 x=0 } res := 0 { y0 x=0 res=0 } Inv = { y0 res=Sum(0, x) xy } while (x<y) do x := x+1 res := res+x { res = Sum(0, y) }
37
{ x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) }
Sum program – prove { x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) } Define Sum(0, n) = 0+1+…+n { y0 } x := 0 { y0 x=0 } res := 0 { y0 x=0 res=0 } Inv = { y0 res=Sum(0, x) xy } while (x<y) do { y0 res=m x=n ny m=Sum(0, n) x<y } { y0 res=m x=n m=Sum(0, n) n<y } x := x res := res+x { res = Sum(0, y) }
38
{ x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) }
Sum program – prove { x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) } Define Sum(0, n) = 0+1+…+n { y0 } x := 0 { y0 x=0 } res := 0 { y0 x=0 res=0 } Inv = { y0 res=Sum(0, x) xy } while (x<y) do { y0 res=m x=n ny m=Sum(0, n) x<y } { y0 res=m x=n m=Sum(0, n) n<y } x := x { y0 res=m x=n+1 m=Sum(0, n) n<y } res := res+x { res = Sum(0, y) }
39
{ x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) }
Sum program – prove { x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) } Define Sum(0, n) = 0+1+…+n { y0 } x := 0 { y0 x=0 } res := 0 { y0 x=0 res=0 } Inv = { y0 res=Sum(0, x) xy } while (x<y) do { y0 res=m x=n ny m=Sum(0, n) x<y } { y0 res=m x=n m=Sum(0, n) n<y } x := x { y0 res=m x=n+1 m=Sum(0, n) n<y } res := res+x { y0 res=m+x x=n+1 m=Sum(0, n) n<y } { y0 res=Sum(0, x) x=n+1 n<y } // sum axiom { y0 res=Sum(0, x) xy } // cons { res = Sum(0, y) }
40
{ x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) }
Sum program – prove { x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) } Define Sum(0, n) = 0+1+…+n { y0 } x := 0 { y0 x=0 } res := 0 { y0 x=0 res=0 } Inv = { y0 res=Sum(0, x) xy } while (x<y) do { y0 res=m x=n ny m=Sum(0, n) x<y } { y0 res=m x=n m=Sum(0, n) n<y } x := x { y0 res=m x=n+1 m=Sum(0, n) n<y } res := res+x { y0 res=m+x x=n+1 m=Sum(0, n) n<y } { y0 res=Sum(0, x) x=n+1 n<y } // sum axiom { y0 res=Sum(0, x) xy } // cons { y0 res=Sum(0, x) xy xy } { y0 res=Sum(0, y) x=y } { res = Sum(0, y) }
41
{ x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) }
Buggy sum program 1 { x=Sum(0, n) } { y=n+1 } { x+y=Sum(0, n+1) } Define Sum(0, n) = 0+1+…+n { y0 } x := 0 { y0 x=0 } res := 0 { y0 x=0 res=0 } Inv = { y0 res=Sum(0, x) xy } while (x<y) do { y0 res=m x=n ny m=Sum(0, n) x<y } { y0 res=m x=n m=Sum(0, n) n<y } res := res+x { y0 res=m+x x=n m=Sum(0, n) n<y } x := x { y0 res=m+n x=n+1 m=Sum(0, n) n<y } { y0 res=Sum(0, n)+n x=n+1 n<y } { y0 res=Sum(0, x) xy } // cons { y0 res=Sum(0, x) xy xy } { y0 res=Sum(0, y) x=y } { res = Sum(0, y) }
42
Buggy sum program 2 { y0 } x := 0 { y0 x=0 } res := 0 { y0 x=0 res=0 } Inv = { y0 res=Sum(0, x) } = { y0 res=m x=n m=Sum(0, n) } while (xy) do { y0 res=m x=n m=Sum(0, n) xy ny } x := x { y0 res=m x=n+1 m=Sum(0, n) ny} res := res+x { y0 res=m+x x=n+1 m=Sum(0, n) ny} { y0 res-x=Sum(0, x-1) ny} { y0 res=Sum(0, x) } { y0 res=Sum(0, x) x>y } {res = Sum(0, y) }
43
Handling data structures
44
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? The rule works on a syntactic level unaware of possible aliasing between different terms (y and *x in our case)
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 } What should the precondition be?
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 } We split into cases depending on possible aliasing
47
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 Assignment A different approach: heaps as arrays Really successful approach for heaps is based on Separation Logic Employed by Dafny
48
Axiomatizing data types
S ::= x := a | x := y[a] | y[a] := x | skip | S1; S2 | if b then S1 else S2 | while b do S 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,
49
Axiomatizing data types
S ::= x := a | x := y[a] | y[a] := x | skip | S1; S2 | if b then S1 else S2 | while b do S We added a new type of variables – array variables Model array variable as a function y : Z Z We need the two following axioms: { y[xa](x) = a } { zx y[xa](z) = y(z) }
50
Array update rules (wlp)
S ::= x := a | x := y[a] | y[a] := x | skip | S1; S2 | if b then S1 else S2 | while b do S A very general approach – allows handling many data types Treat an array assignment y[a] := x as an update to the array function y y := y[ax] meaning y’=v. v=a ? x : y(v) [array-update] { P[y[ax]/y] } y[a] := x { P } [array-load] { P[y(a)/x] } x := y[a] { P }
51
Array update rules (wlp) example
Treat an array assignment y[a] := x as an update to the array function y y := y[ax] meaning y’=v. v=a ? x : y(v) [array-update] { P[y[ax]/y] } y[a] := x { P } {x=y[i7](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}
52
Array update rules (sp)
{ P } x := y[a] { v. x=y(a[v/x]) P[v/x] } [array-loadF] { y=g P } y[a1] := a2 { y=g[a1[g/y]a2[g/y]] } [array-updateF]
53
Small array update rules (sp)
[array-loadF] { y=g a=b } x := y[a] { x=g(b) } In both rules v, g, and b are fresh [array-updateF] { x=v y=g a=b } y[a] := x { y=g[bv] }
54
practice proving programs with arrays
55
Array-max program – specify
nums : array N : int // N stands for num’s length { N0 nums=orig_nums } x := 0 res := nums[0] while x < N if nums[x] > res then res := nums[x] x := x + 1 { x=N } { m. (m0 m<N) nums(m)res } { m. m0 m<N nums(m)=res } { nums=orig_nums }
56
Array-max program nums : array N : int // N stands for num’s length { N0 nums=orig_nums } x := 0 res := nums[0] while x < N if nums[x] > res then res := nums[x] x := x + 1 Post1: { x=N } Post2: { nums=orig_nums } Post3: { m. 0m<N nums(m)res } Post4: { m. 0m<N nums(m)=res }
57
Proof strategy Prove each goal 1, 2, 3, 4 separately and use conjunction rule to prove them all After proving {N0} C {x=N} {nums=orig_nums} C {nums=orig_nums} We have proved {N0 nums=orig_nums} C {x=N nums=orig_nums} We can refer to assertions from earlier proofs in writing new proofs
58
Array-max example: Post1
nums : array N : int // N stands for num’s length { N0 } x := 0 { N0 x=0 } res := nums[0] { x=0 } Inv = { xN } while x < N { x=k k<N } if nums[x] > res then res := nums[x] { x=k k<N } x := x { x=k+1 k<N } { xN xN } { x=N } Use frame rule
59
Array-max example: Post2
nums : array N : int // N stands for num’s length { nums=orig_nums } x := 0 res := nums[0] while x < N if nums[x] > res then res := nums[x] { nums=orig_nums } Use frame rule
60
Array-max example: Post3
nums : array { N0 0m<N } // N stands for num’s length x := 0 { x=0 } res := nums[0] { x=0 res=nums(0) } Inv = { 0m<x nums(m)res } while x < N { x=k res=oRes 0m<k nums(m)oRes } if nums[x] > res then { nums(x)>oRes res=oRes x=k 0m<k nums(m)oRes } res := nums[x] { res=nums(x) nums(x)>oRes x=k 0m<k nums(m)oRes } { x=k 0mk nums(m)<res } { (x=k 0m<k nums(m)<res) (res≥nums(x) x=k res=oRes 0m<k nums(m)oRes)} { x=k 0m<k nums(m)res } x := x { x=k+1 0mx-1 nums(m)res } { 0m<x nums(m)res } { x=N 0m<x nums(m)res} [univp]{ m. 0m<N nums(m)res }
61
Proving termination By Noble0 (Own work) [CC BY-SA 3.0 ( via Wikimedia Commons
62
Total correctness semantics for While
[ P[a/x] ] x := a [ P ] [assp] [ P ] skip [ P ] [skipp] [ P ] S1 [ Q ], [ Q ] S2 [ R ] [ P ] S1; S2 [ R ] [compp] [ b P ] S1 [ Q ], [ b P ] S2 [ Q ] [ P ] if b then S1 else S2 [ Q ] [ifp] [whilep] [ P(z+1) ] S [ P(z) ] [ z. P(z) ] while b do S [ P(0) ] P(z+1) b P(0) b [ P’ ] S [ Q’ ] [ P ] S [ Q ] [consp] if PP’ and Q’Q
63
Total correctness semantics for While
[ P[a/x] ] x := a [ P ] [assp] [ P ] skip [ P ] [skipp] [ P ] S1 [ Q ], [ Q ] S2 [ R ] [ P ] S1; S2 [ R ] [compp] [ b P ] S1 [ Q ], [ b P ] S2 [ Q ] [ P ] if b then S1 else S2 [ Q ] [ifp] Rank, or Loop variant [whilep] [ b P t=k ] S [ P t<k ] [ P ] while b do S [ b P ] P t0 [ P’ ] S [ Q’ ] [ P ] S [ Q ] [consp] if PP’ and Q’Q
64
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 [ ]
65
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 ]
66
Array-max – specify termination
nums : array N : int // N stands for num’s length x := 0 res := nums[0] Variant = [ ? ] while x < N if nums[x] > res then res := nums[x] x := x + 1 [ ? ]
67
Array-max – specify termination
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 [ ? ] [ true ]
68
Array-max – prove loop variant
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-x0 ] if nums[x] > res then res := nums[x] x := x // [ N-x<k N-x0 ] [ true ]
69
Array-max – prove loop variant
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-x00 ] if nums[x] > res then res := nums[x] x := x // [ N-x<k N-x0 ] [ true ] Capture initial value of x, since it changes in the loop
70
Array-max – prove loop variant
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-x00 ] if nums[x] > res then res := nums[x] [ x=x0 x0<N N-x0=k N-x00 ] // Frame x := x // [ N-x<k N-x0 ] [ true ]
71
Array-max – prove loop variant
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-x00 ] if nums[x] > res then res := nums[x] [ x=x0 x0<N N-x0=k N-x00 ] // Frame x := x + 1 [ x=x0+1 x0<N N-x0=k N-x00 ] // [ N-x<k N-x0 ] [ true ]
72
Array-max – prove loop variant
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-x00 ] if nums[x] > res then res := nums[x] [ x=x0 x0<N N-x0=k N-x00 ] // Frame x := x + 1 [ x=x0+1 x0<N N-x0=k N-x00 ] [ N-x<k N-x0 ] // cons [ true ]
73
Zune calendar bug while (days > 365) { if (IsLeapYear(year)) { if (days > 366) { days -= 366; year += 1; } } else { days -= 365;
74
Fixed code while (days > 365) { if (IsLeapYear(year)) { if (days > 366) { days -= 366; year += 1; } else { break; } else { days -= 365;
75
Fixed code – specify termination
[ ? ] while (days > 365) { if (IsLeapYear(year)) { if (days > 366) { days -= 366; year += 1; } else { break; } else { days -= 365;
76
Fixed code – specify variant
[ true ] Variant = [ ? ] while (days > 365) { if (IsLeapYear(year)) { if (days > 366) { days -= 366; year += 1; } else { break; } else { days -= 365; [ ? ]
77
Fixed code – proving termination
[ true ] Variant = [ t=days ] while (days > 365) { [ days>365 days=k days0 ] if (IsLeapYear(year)) { if (days > 366) { days -= 366; year += 1; } else { break; [ false ] } else { days -= 365; // [ days0 days<k ] Let’s model break by a small cheat – assume execution never gets past it
78
Fixed code – proving termination
[ true ] Variant = [ t=days ] while (days > 365) { [ days0 k=days days>365 ] -> [ days0 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; } else { [ k=days days>365 days366 ] break; [ false ] [ (days=k-366 days>0) false ] -> [ days<k days>0 ] } else { days -= 365; [ k-365=days days-365>365 ] -> [ k-365=days days0 ] -> [ days<k days0 ] [ days<k days0 ]
79
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 { b P } S { b } { P } while b do S { false } [while-ntp]
80
conclusion
81
Extensions to axiomatic semantics
Assertions for execution time Exact time Order of magnitude time Assertions for dynamic memory Separation Logic Assertions for parallelism Owicki-Gries Concurrent Separation Logic Rely-guarantee
82
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
83
See you next time
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.