340 likes | 371 Views
Review of procedural language constructs, object-oriented programming notation, method declarations, type casts, and more. Includes examples and specifications for correct program execution. Strengthening specifications for method implementations discussed.
E N D
Technologies for finding errorsin object-oriented software K. Rustan M. LeinoMicrosoft Research, Redmond, WA Lecture 2Summer school on Formal Models of Software4 Sep 2003, Tunis, Tunisia
Review: Procedural language constructs • 6 primitive commands • Many shorthands • Arrays are variables with structure • Procedure declarations and specification
Object-oriented • o.f := E • o: T • o.m(y,z) Procedural • x := E • x: T • P(x,y,z)
Object types and subtyping • D set of type names • typeof : object D • <: partial order on D • istype(o, T) = typeof(o) <: T Note: T <: U ⇒ (istype(o, T) ⇒ istype(o, U))
An object-oriented programming notation C ::= w := E | assert P | var w in C end | C0 ; C1 | if P then C0else C1end | o.f := E | x := new(T) | w := o.m(E0, E1)
Object fields are maps • Java: class T extends U { ... f: X ... } • Here: T ∈ DT <: U f: T X • x := o.f = x := f[o] • o.f := E = f[o] := E = f := store(f, o, E)
Aliasing (pointer sharing) • (o.f := 12 ; p.g := 14 ;assert o.f = 12).true ≡ true • (o.f := 12 ; p.f := 14 ;assert o.f = 12).true ≡ o≠p
Allocation • alloc : object bool • x := new(T) =change x suchthat typeof(x) = T ∧ ¬alloc[x] ; alloc[x] := true
Example • (o.f := 12 ; p := new(T); p.f := 14 ;assert o.f = 12).true ≡ alloc[o]
Methods declarations and method implementations method T :: m(x,y,z) returns (r,s,t)requires P modifies w ensures Q = proc m(x,y,z) returns (r,s,t)specassert istype(x, T) ; w:[P, Q] mimpl U :: m(x,y,z) returns (r,s,t) is C = impl m(x,y,z) returns (r,s,t) isassume istype(x, U) ; C receiver parameter(“this”, “current”, “self”)
Method call • w := o.m(E0, E1) =w := m(o, E0, E1)
Example: union-find n element m b a c representative element k d p equivalence class q l o r e f i h j g
Example: union-find find(c) = a n m b a c k d p q l o r e f i h j g
Example: union-find n m b union(p, h): a c k d p q l o r e f i h h j g
Example, specification class UnionFind <: Object field nClasses, nElements, ... method UnionFind :: init(uf, size)requires 0 ≦ sizemodifies uf.nClasses, uf.nElements, ... ensures uf.nClasses = uf.nElements = size method UnionFind :: find(uf, c) returns (r)requires 0 ≦ c < uf.nElementsensures 0 ≦ r < uf.nClasses method UnionFind :: union(uf, c, d)requires 0 ≦ c ≦ uf.nElements ∧ 0 ≦ d ≦ uf.nElementsmodifies uf.nClassesensures uf.nClasses = uf.nClasses0∨ uf.nClasses = uf.nClasses0 - 1
Example, client var uf, r0, r1, r2 in uf := new(UnionFind) ; uf.init(12) ; uf.union(3, 8) ; uf.union(8, 6) ; uf.union(10, 11) ; r0 := uf.find(3) ; r1 := uf.find(5) ; r2 := uf.find(6) ; assert r0 ≠ r1 ;assert r0 = r2end
Example, implementation class StandardUnionFind <: UnionFind mimpl StandardUnionFind :: find(uf, c) returns (r) is … class FastUnionFind <: UnionFind mimpl FastUnionFind :: find(uf, c) returns (r) is …
What's missing? • null • type casts • types of parameters • types of fields • properties of allocation • ...
null New definitions: • istype(o, T) = o = null ∨ typeof(o) <: T • o.f := E =assert o ≠ null ; f[o] := E
Type casts • x := typecast(o, T)= assert istype(o, T) ; x := o
Example: binary method class T <: Object method T :: equal(x, y) returns (b)requires typeof(x) = typeof(y) class U <: T mimpl U :: equal(x, y) returns (b) isvar yy in yy := typecast(y, U) ; // compare x and yy ... end
Types of parameters method OutputStream :: putText(wr, s) … method print(t: T, wr: OutputStream) … method T :: print(t, wr)requires istype(wr, OutputStream)
Types of fields field T :: f: U // class T { … f: U … } (∀f, T, U ・ isField(f, T, U) (∀o ・ istype(f[o], U)))
Types of fields field T :: f: U // class T { … f: U … } (∀f, T, U ・ isField(f, T, U) (∀o ・istype(o, T) ⇒istype(f[o], U))) Initially: assume isField(f, T, U) Whenever f is changed: assume isField(f, T, U)
More about allocation • initially, for every parameter x:assume alloc[x] • mimpl T :: m(x) isvar y in y := new(T) ;assert x ≠ yend
Even more about allocation • mimpl T :: m(x) isvar y in y := new(T) ;assert x.f ≠ yend
Even more about allocation • mimpl T :: m(x) isvar y in y := new(T) ;assert x.f ≠ yend • isField(f, T, U, a) … ∧ (∀ o ・ a[o] ⇒ a[f[o]] ) • Initially and whenever f or alloc is changed:assume isField(f, T, U, alloc)
Exercise • Prove the following program correct:method p(x) modifies x.fmethod m(x) modifies x.fmimpl m(x) isvar y in x.p() ; y := new(T) ;assert x.f ≠ yend
Strengthening specifications class T <: Object method T :: m(x, y, z) requires P modifies w ensures Q class U <: T method U :: m(x, y, z) requires P modifies w ensures Q ∧ R ... u.m(y, z) ; assert R ... ?
Strengthening specifications class T <: Object method T :: m(x, y, z) requires P modifies w ensures Q class U <: T method U ::n(x, y, z) requires P modifies w ensures Q ∧ R mimpl U :: m(x, y, z) is x.n(y, z) ... u.n(y, z) ; assert R ...
Two-state postconditions • ensures x.f0 < x.f = ensures f0[x] < f[x] = ensures select(f0, x) < select(f, x)
Modifies and objects • modifies x.f =modifies fensures (∀o ・ o.f = o.f0∨ o = x)
Exercise class T <: Object field f method T :: m(x, y, z) requires P modifies x.f ensures Q class U <: T field g method U :: m(x, y, z) requires P modifies x.f, x.gensures Q ?
What else is missing? • Information hiding • Correctness of data representations • Programming methodology • ...