270 likes | 282 Views
This lecture discusses technologies for finding errors in object-oriented software, with a focus on tool architecture, source program analysis, and automatic theorem proving.
E N D
Technologies for finding errorsin object-oriented software K. Rustan M. LeinoMicrosoft Research, Redmond, WA Lecture 1Summer school on Formal Models of Software2 Sep 2003, Tunis, Tunisia
Review: Tool architecture Source program Sugared command Focus today Translator Primitive command Passive command Verification condition Automatic theorem prover Counterexample context Post processor Warning messages
Commands and their possible outcomes • Normal termination • terminates normally in some state • Erroneous termination • goes wrong, crashes the computer • Non-termination • diverges, fails to terminates, results in infinite recursion • Miraculous termination • fails to start, blocks (partial/miraculous commands) you breach contract,demon wins demon breaches contract,you win!
Commands C ::= w := E | assert P | assume P | var w in C end | C0 ; C1 | C0 [] C1
Semantics • Hoare logic • {P}C{R} says that if command C is started in (a state satisfying) P, then: • C does not go wrong, and • if C terminates normally, then it terminates in (a state satisfying) R • Weakest preconditions • for a given C and R, the weakest P satisfying {P}C{R} • written wp(C,R) or simply C.R
Command semantics—assignment • evaluate E and change value of w to E • (w := E).R ≡ R[w := E] • (x := x + 1).(x ≦ 10)≡ x+1 ≦ 10≡ x < 10 • (x := 15).(x ≦ 10)≡ 15 ≦ 10≡ false • (y := x + 3*y).(x ≦ 10)≡ x ≦ 10 • (x,y := y,x).(x < y)≡ y < x replace w by Ein R
Command semantics—assert • if P holds, do nothing, else go wrong • (assert P).R ≡ P ∧ R • (assert x < 10).(0 ≦ x)≡ 0 ≦ x < 10 • (assert x = y*y).(0 ≦ x)≡ x = y*y ∧ 0≦ x≡ x = y*y • (assert false).(x ≦ 10)≡ false logical AND, conjunction
Command semantics—assume logical NOT,negation • if P holds, do nothing, else block • (assume P).R ≡¬P ∨ R≡ P ⇒ R • (assume x < 10).(0 ≦ x)≡ 10 ≦ x ∨ 0 ≦ x≡ 0 ≦ x • (assume x = y*y).(0 ≦ x)≡ x = y*y ⇒ 0≦ x≡ true • (assume false).(x ≦ 10)≡ true logical OR,disjunction logicalimplication
Command semantics—local variable • introduce w with an arbitrary initial value,then do C • (var w in C end).R ≡(∀w ・ C.R) • (var y in y := x end).(0 ≦ x)≡ (∀y ・ (y := x).(0 ≦ x))≡ (∀y ・ 0 ≦ x)≡ 0 ≦ x • (var y in x := y end).(0 ≦ x)≡ (∀y ・ (x := y).(0 ≦ x))≡ (∀y ・ 0 ≦ y)≡ false provided w does not occur free in R
Command semantics—sequential composition • do C0, then C1 • (C0 ; C1).R ≡ C0.(C1.R) • (x := x+1 ; assert x ≦ y).(0 < x)≡ (x := x+1).( (assert x ≦ y).(0 < x) )≡ (x := x+1).(0 < x ≦ y)≡ 0 < x+1 ≦ y≡ 0 ≦ x < y • (assume 0 ≦ y+z ; x := y).(0 ≦ x)≡ (assume 0 ≦ y+z).( (x:=y).(0 ≦ x) )≡ (assume 0 ≦ y+z).(0 ≦ y)≡ 0 ≦ y+z ⇒ 0 ≦ y≡ -y ≦ z ⇒ -y ≦ 0≡ 0 ≦ z
Command semantics—choice composition • do either C0 or C1 (the demon chooses which) • (C0 [] C1).R ≡ C0.R ∧ C1.R • (x := x+1 [] x := x + 2).(x ≦ 10)≡ (x := x+1). (x ≦ 10) ∧ (x := x+2).(x ≦ 10)≡ x ≦ 9 ∧ x ≦ 8≡ x ≦ 8 • (assume false [] x := y).(0 ≦ x)≡ (assume false).(0 ≦ x) ∧ (x:=y).(0 ≦ x) ≡ true ∧ 0 ≦ y≡ 0 ≦ y
Convenient shorthands • skip = assert true = assume true • wrong = assert false • magic = assume false • P C = assume P; C • if P then C0 else C1 end = P C0 [] ¬P C1 • havoc w = var w’in w := w’end
Change such that • change w such that P = havoc w ; assume P • change x such that y = x+1≡ havoc x ; assume y = x+1 ≡ x := y-1 • change x such that y < x ≡ x := y+1 [] x := y+2 [] … • change x such that x = x+1 ≡ havoc x ; assume false ≡ magic • change r such that r*r = y ≡ y < 0 magic [] 0 ≦ y r := √y [] 0 ≦ y r := -√y
Specification statement w:[P, Q] = requires P modifies w ensures Q = assert P ;var w0 in w0 := w ; change w such that Qend • x:[true, x0=x+1] ≡ x := x-1 • r:[0 ≦ y, r*r = y] ≡ assert 0 ≦ y ; (r := √y [] r := -√y) • x:[0 ≦ x, x2 ≦ x0 < (x+1)2] ≡ ? • x,y,z,n:[1≦x≦y∧1≦z∧2≦n, xn+yn=zn] ≡ ?
Variables with internal structure: maps • x := a[i] = x := select(a, i) • a[i] := E = a := store(a, i, E) where (∀m,i,j,v ・i ≠j ⇒ select(store(m, i, v), i) = v ∧ select(store(m, i, v), j) = select(m, j))
Example: maps (a[5] := 12 ; a[7] := 14 ; x := a[5]).(x=12) = (a[5] := 12 ; a[7] := 14).(select(a, 5) = 12) = (a[5] := 12).(select(store(a, 7, 14), 5) = 12) = select(store(store(a, 5, 12), 7, 14), 5) = 12 = { select/store axiom, since 7 ≠ 5 } select(store(a, 5, 12), 5) = 12 = { select/store axiom, since 5 = 5 } 12 = 12 = true
Refinement command Bis refined bycommand C • C is “better” than B • “anyone who requests B would be happy with C” B ⊆ C = (∀R ・ B.R ⇒ C.R ) • change x such that y < x ⊆x := y+4 • assert x < 10 ⊆skip • skip ⊆assume x < 10 • wrong ⊆C • C ⊆magic
Compositions are monotonic with respect to refinement • if B ⊆ C then: • var w in B end ⊆ var w in C end • A;B ⊆ A;C • B;D ⊆ C;D • A [] B ⊆ A [] C • var x in ... change x such that y < x ... end⊆ var x in ... x := y+4 ... end
Commands form a lattice • Commands form a semi-lattice under ordering ⊆, with meet operation [], top element magic, and bottom element wrong • A lattice theorem: B ⊆ C0∧ B ⊆ C1 ≡ B ⊆ C0 [] C1 • Corollary: C0 [] C1 ⊆ C0
Example application of lattice theorem Let B = x:[true, x = |x0| ]. Then: • B⊆ assume 0 ≦ x = C0 • B⊆ assume x ≦ 0 ; x := -x = C1 • B⊆ assume x = -3 ; x := 3 = C2 • B ⊆ magic = C3 Therefore: B ⊆ C0[]C1[]C2[]C3
Procedures • proc P(x,y,z) returns (r,s,t) spec S • call to P: a,b,c := P(E0, E1, E2)= var x,y,z,r,s,t in x := E0 ; y := E1 ; z := E2 ; S ; a,b,c := r,s,t end
Example: procedure • proc Add(x) returns (r)specrequires 0 ≦ xmodifies kensures k = k0+x ∧ r = k0 • a := Add(k+25) = var x,r in x := k+25 ; k:[0 ≦ x, k = k0+x ∧ r = k0] ; a := r end
Procedure implementations • proc P(x,y,z) returns (r,s,t) spec S • impl P(x,y,z) returns (r,s,t) is CProof obligation: S ⊆ C • Let C0, ..., Cm-1be the declared implementations of P. Then, the language implementation of a call to P can replace S by:C0 [] ... [] Cm-1
Exercise • Redefine (in terms of the commands we've seen) the specification statement so that the postcondition mentions x,x’ instead of x0,x • Example: • old form:x:[0 ≦ x, x*x ≦ x0 < (x+1)*(x+1)] • new form:x:[0 ≦ x, x’*x’≦ x < (x’+1)*(x’+1)]
Exercise Define while {inv J} B do w: S end where: • B is the loop guard • S is the loop body • J is the loop invariant • w is the list of assignment targets in S in terms of the commands we've seen.
Loop (answer to exercise) while {inv J} B do w: S end = assert J ;change w suchthat J ;if B then S ; assert J ; magicelseskipend
Summary • Language is built up from 6 primitive commands • Semantics can be given by weakest preconditions • Partial (miraculous) commands are important and very useful • select/store handle “map” variables • Procedures are names for specifications • Procedure implementations are hints for compiler