Data groups: Specifying the modification of extended state

K. Rustan M. Leino Compaq Systems Research Center 130 Lytton Ave., Palo Alto, CA 94301, U.S.A. www.research.digital.com/SRC/people/Rustan-Leino [email protected]

Abstract not use the code in a method’scallers when reasoning about the methodimplementation, and one doesnot use the imple- This paper explores the interpretation of specificationsin the mentation when reasoningabout the calls. context of an object-oriented with To be useful to the caller, it is important that the postcon- subclassingand method overrides. In particular, the paper dition of a method detail what variables the method doesnot considersannotations for describing what variablesa method change. But since the scopeof the caller can include vari- may changeand the interpretation of theseannotations. The ables that are not visible in the scope where the method is paper showsthat there is a problem to be solved in the spec- declared and specified,it is not possible to explicitly list all ification of methodswhose overrides may modify additional unchangedvariables in the method’spostcondition. Instead, state introduced in subclasses. As a solution to this prob- the annotation languagemust include someform of syntactic lem, the paper introduces data groups, which enable mod- shorthand(“sugar”) whose interpretation as part of the post- ular checking and rather naturally capture a programmer’s condition is a function of the scopein which it is interpreted. design decisions. A nice construct for this is the modifies clause, which lists those variablesthat the methodis allowed to modify, thereby 0 Introduction specifying that the method does not modify any other vari- ables [GH93]. For example,suppose that the specification of Specifications help in the documentation of computer pro- a method m occurs in a scopewhere two variables, x and y , grams. Ideally, specificationscan be used by a mechanical are visible, and that the specification includes the modifies program analyzer to check the body of a method against its CIaUse specification, attempting to find errors. The Extended Static modifies x Checkers for -3 [DLNS98, L.N98b, Det961and for If m is called from a scopewhere, additionally, a variable z Java [ESC], which work on object-oriented programs, are is visible, then the caller’s interpretation (“desugaring”) of examplesof such program checkers. the specification says that the call may possibly modify x , This paper concerns the spectication of methods. A but leavesboth y and z unchanged. method specification is a contract between the implemen- The fact that a modifies clauseis interpreted differently tation of a method and its callers. As such, it includes a in different scopesraises a concern about modular sound- precondition, which documentswhat a caller must establish nem &ei95]. For the purposeof this paper, modular sound- before invoking the method. Consequently, the implemen- ness means that the implementation, which is checked to tation can assumethe precondition on entry to the method meet the specification as interpreted in the scope contain- body. A method specification also includes a postcondition, ing the method body, actually lives up to a caller’s expecta- which documents what the implementation must establish tions, which are basedon the specification as interpreted in on exit. Consequently,the caller can assumethe postcondi- the scopeof the call. A consequenceof modular soundness tion upon return from the method invocation. When reason- is that one can check a classeven in the absenceof its future ing about method implementations and calls, only the con- clients and subclasses. tract given by the specification is used. That is, one does This paper explores the interpretation of specifications in the context of an object-orientedprogramming language Permlssnn to make dlgttal or hard copies of all or part of this work for personal or classroom use ,s granted wlthout fee prowded that with subclassingand methodoverrides, for examplelike Java. copes are not made or distributed lor proflt or commercial advan- In particular, I consider annotations for describing what a tage and that copnes bear the notice and the full c~tat~o” on the first page. la copy otherwse. to republwh, to post on servers or to method may change and the interpretation of these annota- redlstnbute to Iwts, reqwres prwr specific perm~sston and/or a fee. tions. I show that there is a problem to be solved in the OOPSLA ‘98 lo/98 Vancouver, B.C. 0 1998 ACM l-581 13.005.8/98/0010...$5.00

144 specification of methodswhose overrides may modify addi- meetsits specificationcomes down to checking that it mod- tional state introduced in subclasses.As a solution to this ifies only those variables that it is permitted to modify. The problem, I introduce data groups, which adhere to modular implementationsof the updatePosition, updatecolor, soundnessand rather naturally capture a programmer’sde- and draw methodsare no-ops, so they trivially satisfy their sign decisions. specifications. The update method invokes the other two For simplicity, I restrict my attention to the operations updatemethods, whose modifies clausessay they may mod- on only one object, the implicit self parameter. Neverthe- ify x, y, and co1 . So update in effect modifies x, y, and less, becauseof inheritance and method overriding, the im- col, and this is exactly what its specification allows. We plementationsof the methodsof this object may be found in conclude that the methodsin class Sprite meet their spec- superclassesand subclassesof the classbeing checked. ifications. Let us now consider a subclass Hero of Sprite, rep- 1 Extending the state of a superclass resenting the hero of the game. The hero can move about, and hence the Hero class provides its own implementation To illustrate the problem, I introduce a simplified exampleof of the updateposition method by overriding this method. a computerarcade game--an excellent application of object- The next position of the hero is calculated from the hero’s oriented programming indeed. velocity and acceleration,which are representedas instance The design centersaround sprites. A sprite is a gameob- variables. The Hero class is declaredas follows: ject that appearssomewhere on the screen. In this simple class Hero extends Sprite { example, every sprite has a position, a color, and methods int dx, dy; to update these. The main program, which I will not show, int ddx, ddy; essentially consistsof a loop that performs one iteration per void updatePosition() video frame. Each iteration works in two phases. The fist { x += dx + ddx/2; y += dy + ddy/2; phaseinvokes the update methodon eachsprite, which up- dx += ddx; dy += ddy; dates the sprite’s position, color, and other attributes. The 1 secondphase invokes the draw methodon eachsprite, which . . . rendersthe sprite on the screen. 1 Here is the declaration of class Sprite, in which the methodshave been annotatedwith modifies clauses: The Hero implementation of updatePosition increases x and y by appropriateamounts (Ad = vo . t + l/z . a - t2 class Sprite { where r = 1). In addition, it updatesthe velocity according int x, y; to the current acceleration. (Omitted from this example is void updatePosition /* modifies x, y */ the updateof acceleration,which is computed according to ( 1 the gameplayer’s joystick movements.) It seemsnatural to int col; update the velocity in the method that calculates the new void updateColor() I* modifies co1 *I position, but the specilication of updatePosition (given I 1 in class Sprite) allows only x and y to be modified, not dx void update ( ) I* modifies x, y, co1 *I and dy which are not even defined in class Sprite. (If the { updatePosition(); updateColor( ); } updateof dx and dy instead took place in method update, void draw0 /* modifies (nothing) */ there would still be a problem, since the modifies clause of ( 1 update also does not include these variables.) 1 As evidencedin this example,the reasonfor overriding a The default update method invokes the updatePosition method is not just to changewhat the method doesalgorith- and updatecolor methods, whose default implementations micly, but also to change what data the method updates. In do nothing. Any of these methods can be overridden in fact, the main reasonfor designing a subclassis to introduce Sprite subclasses. For example, a moving sprite that subclass-specificvariables, and it is the usesand updatesof never changescolors would override the updateposition such variables that necessitatebeing able to override meth- method, a stationary sprite whose color changesover time ods. For example, class Sprite was designed with the in- would override the updatecolor method, and a sprite that tention that subclassesbe able to add sprite attributes and adds further attributes that need to be updatedoverrides the update thesein appropriatemethods. So how does one in a update method and possibly also the updatePos it ion and superclasswrite the specificationof a method such that sub- updateColor methods. classescan extend the superclass’sstate (that is, introduce Since the speciticationsI have given in the example show additional variables) and override the method to modify this only modifies clauses, checking that an implementation extendedstate?

145 2 Three straw man proposals constant,without taking up any per-object storage. This de- sign tradesquick accessof an attribute for flexibility in how In this section, I discuss three proposals that I often hear the attribute is represented. suggestedfor solving the problem of specifying the modifi- The following declaration shows class Monster, which cation of extended state. I show that these proposalsdon’t usesthe strengthattribute in updating the sprite position. work. This is what it meansfor a proposal to work: class Monster extends Sprite { l the proposal must provide a way to annotate classes int getStrength /* modifies (nothing) */ like Sprite and Hero such that the desired method ( return 100; } implementationsin theseclasses will meet their speci- void updatePosition fications, { if (getStrength < 10) ( x+=2; 0 the interpretation of specifications must be useful to } else { callers (for example, specifications should not all be x+=4; treatedas “can do anything whatsoever”), 11 l the annotations should not be unnecessarilytedious to 1 write down, and A particular Monster subclass is AgingMonster, which 0 the proposal must adhereto modular soundness. adds an age attribute and overrides the draw method so as to render the monsterdilferently according to its strength-to- Here is the first proposal: ageratio. Straw man 0. A subclasscan refine the specification of a class AgingMonster extends Monster { method when it overrides it. That is, a subclasscan int age; weaken the precondition of the method in the super- . . . class (that is, say that the overridden method imple- void draw( ) mentation will work in more situations) and sfrengfhen { int bitmapID; the postcondition (that is, be more specific about the if (age == 0) [ effect of the method). bitmapID = MONSTERINFANT; It is well known that this proposal is sound. However, it 1 eh I doesn’t solve the problem at hand. To strengthen the post- int s = getStrength( ); condition means to be more precise about the final values int relativestrength = s/age; of variables. This is just the opposite of what we’d like- if (relat ivestrength -z 5) ( we’d like the new postcondition to allow more variables to bitmapID = MONSTER-WIMPY; be modified, that is, to put no restrictions at all on the final } elsif (relativestrength -C IO) ( values of thesevariables. Stateddifferently, while shrinking bitmapID = MONSTERNORMAL; the list in the modifies clause is sound, enlarging it is what 1 eke I we want when specifying a subclass’smethod overrides. bitmapID = MONSTERSTRONG; Another straw man proposal is the following: 1 I Bitmap.Draw(x, y, bitmapID); Straw man 1. Let m be a method declaredand specifiedin a 1 class T . An implementation of m is allowed to modify 1 thosevariables listed in the modifies clause of m, plus any variable declared in any proper subtype of T . The name Bitmap.Draw denotes some procedure that can draw a bitmap given a screencoordinate and an ID. Although sound, this straw man is too liberal about the mod- The correctness of the AgingMonster implementation ification of variables in subclasses.In fact, a subclassloses of draw relies on the fact that the call to getstrength does the advantageof modifies clauseswith this proposal. To il- not modify age. In particulsr, if getstrength were to lustrate, I will show an example that builds on class Sprite. set age to 0, then the computation of relativestrength Consider a class of monsters with a strength attribute. would result in a division-by-zero error. The getstrength Rather than storing this attribute as an instance variable in methodis specifiedwith an empty modifies clause,but Straw every monsterobject, supposea class Monster has a method Man 1 gives implementations of getstrength permission that returns the value of the strength attribute. Thus, differ- to modify age, since age is declared in a proper subclass ent Monster subclassescan decide on their own represen- of Monster. Thus, the interpreted specification for method tation of the strength attribute. For example, if the strength getstrength is not strong enough for one to conclude that of a classof monstersis constant,the method can return that method draw will execute correctly.

146 There is a workaround. If a class is allowed to refine of updatePosition in turn results in a call to the imple- the specificationsof methodsdeclared in superclasses,class mentation of updatePosition given in class Hero (be- AgingMonster can strengthenthe postcondition of method causeof dynamic method dispatch). This implementationof getstrength with agepre == age,,,t. But this would updatePosition modifies the dx and dy variables. Thus, quickly get annoying, becauseprogrammers would then some- executionsof startNewLeve1 may well end with non-zero times rely on the absenceof age in the modifies clause to values for dx and dy , so the implementation of method conclude that age is not changed,and sometimesrely on an startNewLeve1 doesnot meet its specification. . . explicit postcondmon age,, == agepost to conclude the Unfortunately, the methodology proposedby Straw Man samething. Even worse, strengthening the specification of 2 does not allow one to catch the error in sta.rtNewLevel . all methodsdeclared in a superclasswhenever a class intro- The problem is that even though the interpretation of the duces new variables would quickly grow to be an unaccept- specificationof updatePosition in class Hero revealsthat ably tedious chore. dx and dy may be modified (since the also-modifies anno- The next straw man proposal seeksto alleviate this chore tation of updatePosition in class Hero lists these vari- by making the mentioned postcondition strengthening the ables), the update method is not overridden in Hero and default interpretation, and providing a new specificationcon- thus gets its specification solely from the one given in class struct also-modifies that can override the default interpreta- Sprite. Hence, the interpretation of the specification of tion: update shows dx and dy as being unchanged, so a pro- gram checker will not find anything wrong with the imple- Straw man 2. Let m be a method declared and specified in mentation of startNewLeve1. a class T. An implementation of m in a subclass U Note that the implementationsin class Sprite do meet of T is allowed to modify those variables listed in the their specifications under Straw Man 2. For example, the modifies clause of m as given in class T, plus any interpretation of the specification of updatePosition in variable declaredin any also-modifies clausefor m as class Sprite includes only x and y, both of which are al- given in somesuperclass of U. lowed to be modifled also by the implementation of update. This straw man seemsto solve the problem for the Hero Hence, there is no error for the checker to report in class example: One would simply annotatethe updatePosition Sprite either. override with In conclusion, StrawMan 2 seemspretty good at first, but also-modifies dx, dy since it allows the specificationsof different methods(in the example, updatePosition and update) to be extendedin This would give the updatePosition implementation in different ways (by having different also-modifies clauses,or Hero permission to modify not just x and y (as granted by none at all), the proposaldoes not adhereto modular sound- the original specification of updatePosition in Sprite), ness. The proposal in the next section provides annotations but also the variables dx and dy . (One could also add ddx for data rather than for methods, the effect of which is to and ddy to the also-modifies clause, if desired.) make specificationextensions apply in a uniform manner. Let us consider how Straw Man 2 stands up to modu- lar soundness.Suppose that the game uses one hero object throughout many gamelevels. As a new level starts,the pro- 3 Data groups gram will call a method sta.rtNewLevel on the hero object. This methodresets certain attributes of the hero object while In this section, I explain my proposal and demonstratehow leaving other attributes unchanged,preparing it to begin the it solves the problems with the examplesshown previously. new level. To this end, supposeclass Hero contains the fol- In Section 4, I show how a program checker can enforce the lowing methoddeclaration and specification, where the key- proposal,and in Section 5, I arguethat my proposalis sound. word ensures is used to expressa given postcondition: The idea is to introduce data groups, which representsets of variables. A data group is declaredin a class,just like an void startNewLevel() instancevariable is. The declaration of an instancevariable P modifies x, y, col, dx, dy, ddx, ddy is annotatedwith the namesof the data groups to which the ensures dxpost == 0 A dypost == 0 */ variable belongs. Data groups can be nested,that is, a group (dx = 0; dy= 0; can be declaredas a memberof anothergroup. A data group update( ); can be listed in a modifies clause, where it representsthe set 1 of all membersof the group. Using dam groups, the declaration of Sprite can be The given implementation of startNewLeve1 contains an error: The invocation of update results in a call to the update implementation in class Sprite, whose invocation

147 written as: void startNewLevel() /* modifies attributes class Sprite ( ensures dxpost == 0 A dypost == 0 *I r group attributes; *I ( dx = 0; dy = 0; p group position member-of attributes; *I update( ); int x /* member-of position *!; 1 int y /* member-of position *!; 1 void updatePosition() I* modifies position */ The override of updatePosition gets its permission I I to modify dx and dy from the fact that these variables are p group color member-of attributes; *I membersof the datagroup posit ion. This solves the prob- int co1 P member-of color *!; lem of how to specify updatePosition inclass Sprite so void updateColor() I* modifies color *I that a subclasslike Hero can modify the state it introduces. I 1 With data groups, the error in startNewLeve1 is de- void update ( ) /* modties attributes *I tected. Since dx and dy are membersof position, which ( updatePosition( ); updateColor( ); } in turn is a memberof attributes, a program checkerwill P group drawstate; */ know that dx and dy may be modified as a result of invok- void draw() /* modifies drawState *I ing update. Since the specification of update says noth- t 1 ing further about the final values of dx and dy , one cannot 1 conclude that they remain 0 after the call. This version of class Sprite declaresfour datagroups, at- As for the AgingMonster example, the data groups pro- tributes, position, color, and drawstate, and de- posal does allow one to infer that no division-by-zero er- clares position and color tobemembersof attributes, ror is incurred in the evaluation of s/age: The guarding x and y tobemembersof position,and co1 tobeamem- if else statementguarantees that age is non-zero before the ber of color. Class Sprite does not declare any members call to getstrength, and since age is not modified by getstrength, whose clause is empty, age re- of group drawState. modifies Since updatePosition is dcclarcd with the spccifica- mains non-zero on return from getstrength. tion modifies position, an implementation of this method I will give two more examples that illustrate the use of is allowed to modify x and y. In addition, an implementa- data groups. tion of this method is allowed to modify any variables de- First, note that the membersof two groups are allowed to clared in Sprite subclasses to hc members of position. overlap, that is, that a variable is allowed to be a memberof An implementation of updatePosition is not allowed to several groups. For example, if a Sprite subclass declares call method updatecolor, for example, since color is not a variable a memberof posit ion. int k I* member-of position, drawState *!; By introducing a data group drawState and listing it in the modifies clause of method draw, implementations then k can be modified by any of the methods update, of draw in Sprite subclasses are given a way to modify updatePosition, and draw. instancevariables (in particular, to modify variables that are Second,I give another example to illustrate that it is use- introduced as members of drawstate). ful to allow groups to contain other groups. Supposea sub- The following illustrates how one can use data groups to class of Sprite, Centipede, introduces a legs attribute. annotateclass Hero : Class Centipede declares a data group legs and a method updateLegs with license to modify legs, which implies class Hero extends Sprite { the license to modify the membersof legs. By declaring int dx I* member-of position *!; legs as a member of attributes, the update method int dy I* member-of position */; gets permissionto call method updateLegs : int ddx P member-of position *!; class Centipede extends Sprite ( int ddy /* member-of position *!; I* group legs member-of attributes; *I void updatePosition() int legcount P member-of legs *I; { x += dx + ddx/2; y += dy + ddy/2; void updateLegs( ) p modifies legs *I dx += ddx; dy += ddy; {legCount=...; } I void update() ( updatePosition( ); updateColor( ); updateLegs( );

148 4 Enforcing the data groups proposal 5 Soundness

This sectiondescribes more precisely how a program checker The key to making the data groupsproposal soundis that it is handlesdata groups. always known to which groupsa given variable or group be- For every data group g, the checker introduces a new longs, and that residue variables are used to representmem- variable gResidue . This so-called residue variable is used bers of the group that are not in scope. The data groups to representthose of g ‘s membersthat are not in scope-in proposal is, in fact, a variation of the use of abstract vari- a modular program, there is always a possibility of a future ables and dependenciesin my thesis [L&95]. I will explain subclassintroducing a new variable as a memberof a previ- the relation betweenthe two approachesin this section, and ously declaredgroup. relegate the proof of soundnessto that for dependenciesin To interpret a modifies clause my thesis. A data group is like an abstract variable. An abstract modifies w variable (also called a specification variable) is a fictitious variable introduced for the purposeof writing specifications. the checker lirst replaces w with the variables in the down- The value of an abstract variable is representedin terms ward closure of w, For any set of variables and data groups of program variables and other abstract variables. In some w, the downward closure of w, written down(w), is defined scopes,it is not possible, nor desirable,to specify the repre- as the smallest supersetof w such that for any group g in sentation of an abstractvariable becausenot all of the vari- down(w), gResidue and the variables and groups declared ables of the representationare visible. This tends to happen with often in object-orientedprograms, where the representation member-of g is often subclass-specific.However, if the abstract variable are also in down(w). and some of the variables of the representationare visible For example, computing the downward closure of the in a scope,then the fact that there is a dependencybetween modifies list attributes in class Hero as shown in Sec- these variables must be known to a program checker in or- tion 3 yields der to achieve modular soundness.Consequently, an anno- tation language that admits abstractvariables must also in- attributes, attributesResidue, clude someconstruct by which one can explicitly declarethe position, positionResidue, x, y, dx, dy, ddx, ddy, dependencyof an abstractvariable on a variable that is part color, colorResidue, co1 of its representation. For example, if position were an abstractvariable, then Thus, in that class, depends position on x modifies attributes would declare that variable x is part of the representation is interpreted as of position. My thesis introduced such dependencydec- larations. The correspondingnotion in this paper is the an- modifies attributesResidue, positionResidue, notation that declaresthat x is a memberof the data group x, y, dx, dy, ddx, ddy, position: colorResidue, co1 int x P member-of position */; By handling data groups in the way described,the Hero Using dependencies,one can give a precise definition of implementation of method startNewLeve1, for example, what the occurrence of an abstract variable in a modifies is allowed to modify dx and dy and is allowed to call method clause means. For dependencieslike the ones shown here, update (but the assignments to dx and dy must take place this interpretation is the sameas that defined for data groups @ter the call to update in order to establish the specified above: the downward closure. postcondition of startNewLeve1). The implementation of My thesis contains a proof that the use of dependencies startNewLeve1 would also be allowed to call, for example, in this way adheresto modular soundness, provided the pro- updateposition directly. But the checker would com- gram meetstwo requirements and provided the interpreta- plain if startNewLeve1 called draw, because the call to tion includes residuevariables. The two requirements, called draw would be treated as modifying the residue variable the visibility and authenticity requirements, togetherstate es- drawStateResidue, and that variable is not in the down- sentially that a dependencydeclaration ward closure of attributes. depends a on c should be placed near the declaration of c, that is, so that every scopethat includes the declaration of c also includes

149 the dependencydeclaration. Becausethe member-of anno- one could write tation is made part of the declaration of the variable whose bit x; group membershipit declares,the two requirementsare au- . . . tomatically satisfied. P group g contains x, . . . ; */ There is one other difference between data groups and abstract variables with dependencies. Supposean abstract Using contains in this way adheresto modular soundness variable a dependson a variable c , and that the downward (but declaring a group with both a contains and a member- closure of the modifies clause of a method includes c but of phrase does not). However, while introducing a group not a. The interpretation of such a modifies clausesays that containing previously declared variables is sound and may c may be modified, but only in such ways as to not change occasionally be convenient, it does not solve the problem the abstract value of a lLei951. This is called a side effect describedin this paper. constraint on a. But with datagroups, it would be meaninglessto use side 6 Concluding remarks effect constraints,since data groupsdon’t havevalues. Thus, if variable c is a member of a data group a and the down- In summary,this paperhas introduced data groups asa natu- ward closure of a method m includes c but not a, then the ral way to documentobject-oriented programs. Data groups modifies clause does not constrain the implementation of m representsets of variables and can be listed in the modties in how c is changed. Violations of modular soundnessre- clauses that document what methods are allowed to mod- sult from the deficiency that the different interpretationsof a ify. The license to modify a data group implies the license specification in different scopesare inconsistent. So by re- to modify the membersof the data group as defined by the moving side effect constraints in all scopes,modular sound- downward closure rule. nessis preserved. Since data groups are closely related to the use of ab- From our experience with writing specifications for ex- stract variablesand dependencies[Lei95], they adhereto the tended static checking, we have found it useful to introduce useful property of modular soundness, which implies that an abstract variable conventionally called state [LN98a]. one can check a program one class at a time, without need- This variable is declared to depend on variables represent- ing global program information. Although the literature has ing the state of a class or module. The state variable is dealt extensively with data abstraction and refinement, in- used in many modifies clauses,but not in pre- and postcon- cluding Hoare’s famous 1972 paper [Hoa72], it seemsthat ditions. Furthermore, state is never given an exact defini- only my thesis and my work with Nelson lLN98a] have ad- tion in terms of its dependencies.Thus, the type of state dressedthe problem of having abstractvariables in modifies is never important, so we declaredits type to be any, where clausesin a way that modem object-orientedprograms tend any is a new keyword that we added to the annotation lan- to use them. guage. The useof datagroups shown in this papercorresponds to The data groups proposal grew from a feeling that it was static, as opposedto dynamic, dependencies.Dynamic de- a mistake to apply the side effect constraint on variables like pendenciesarise when one classis implementedin terms of state whose type is any-after all, the exact value of such another.Achieving soundnesswith dynamic dependenciesis a variable is never defined and thus cannot be relied on by more difficult than the casefor static dependencies[LN98a, any part of the program. By changing the checking metbod- DLN981. ology to not apply side effect constraints on variables of Data groups can be combined with abstractvariables and type any, one arrives at the interpretation of data groups dependencies.This is useful if one is interested in the ab- presentedin this paper. stract valuesof someattributes and in the representationfunc- As a final note on modular soundness,I mention without tions defining theseabstract values. going into details that the absenceof side effect constraints A related methodological approachto structuring the in- makesthe authenticity requirementunnecessary. This means stance variables and methods of a class is method groups, that it would be sound to declarethe membersof a datagroup first describedby Lamping [Lam931and developedfurther at the time the group is declared,rather than declaring, at the by Stata [Sta97]. Method groups and data groups both pro- time a variable is declared,of which groups the variable is a vide ways to organizeand think about the variables declared member.For example, instead of writing in classes.Other than that, methodsgroups and data groups have different aims. The aim of method groups is to allow P group g; */ . . . the variablesdeclared in a superclassto be usedin a different way in a subclass,a feature achievedby the following disci- int x /* member-of g */; pline: The variables and methodsof a class are partitioned into methodgroups. A variable x in a methodgroup A is al- lowed to be modified directly only by the methodsin group

150 A; methods in other groups can modify x only via calls to where objectsare referencesto mutable data fields (instance methodsin group A. If a designer of a subclasschooses to variables)and methodinvocations are dynamically dispatched. replace a variable or method of a method group, all vari- However, except for Ecstatic lLei971, these logics have fo- ables and methods of the method group must be replaced. cused more on the axiomatization of language featuresand The use of method groups can complement the use of data object types than on the desugaring of useful specification groups, whose aim is to addressnot how variables are used constructs. but rather the more fundamentalquestion of which variables In the grand schemeof annotating object-oriented pro- are allowed to be changedby which methods. If one wants gramsin ways that not only help programmers,but that also to write specificationsin terms of abstractvalues and allow can be used by program analyzers, this paper has touched subclassesto change the representation functions of these only on the modification of extended state. Though they abstractvalues, then one can combine data groups, abstract sometimesseem like a nuisance in the specification of pro- variables, and dependencieswith method groups. grams, modifies clausesare what give a checker precision A related approach to specifying in a superclasswhat a acrossprocedure boundaries. Vandevoordehas also found subclassmethod override is allowed to modify is using re- modifies clausesto be useful in improving program perfor- gion promises [CBS98]. These are used in reasoning about mance[ Van94]. softwaretransformations. In contrastto data groups,the sets Other important methodannotations include pre- and post- of variables included in different regions are required to be conditions, of which useful variations have also been stud- disjoint. This restriction facilitates reasoning about when ied [Jongl, LB97J. As for annotating data, object invari- two method calls can be commuted, but burdens the pro- ants lMey88, LW94, LH94, Lea961is a concept useful to grammerwith having to invent a partition on the class vari- programmersand amenable as annotations accepted by a ables, which isn’t always as natural. program checker. Like the modification of extended state, The region promises are used in both modifies clauses achieving modular soundnesswith object invariants is an is- and so-called reads clauses,which specify which variables sue [LS97]. a method is allowed to read. Although not explored in this paper, it seemsthat data groups may be as useful in reads Acknowledgements clausesas they are in modifies clauses. A complementary technique for finding errors in pro- Raymie Stata, Greg Nelson, Mark Lilhbridge, and Martin grams is explored by Jacksonin his Aspect system [Jac95]. Abadi made useful commentson a draft of this paper. The To give a crude comparison,Aspect features annotations with paper has also benefitedfrom the workshop on Foundations which one specifies what a method must modify, whereas of Object-OrientedLanguages [Lei98b]. the modifies clausesconsidered in this paper specify what a method is allowed to modify. To specify what a method References must modify, one uses aspects, which are abstract entities that can be declaredto have dependences, consisting of vari- lAdB941 Pierre America and Frank de Boer. Reason- ables and other dependences.Such aspectsare analogousto ing about dynamically evolving process struc- data groups. tures. Formal Aspects of Computing, 6(3):269- There are many specification languagesfor documenting 316,1994. object-orientedsoftware, including Larch/C++ [Lea961and the specification languagessurveyed by Lana and Haughton [AL971 Martin Abadi and K. Rustan M. Leino. A logic lLH941. These specification languagesdo not, however,es- of object-oriented programs. In Michel Bidoit tablish a formal connection between specificationsand ac- and Max Dauchet, editors, Theory and Practice tual code. Without such a connection, one cannot build a of Software Development: Proceedings I TAP- programming tool for finding errors in implementations,As SOFT ‘97, 7th International Joint Conference soon as one becomesinterested in checking a method im- CAAPIFASE, volume 1214 of Lecture Notes in plementation against a specification that is useful to callers, , pages 682-696. Springer, one becomesconcerned with what the implementation is al- April 1997. lowed to modify. Add subclassingto the stew and one faces [CBS981 Edwin C. Chan, John T. Boyland, and the problem describedin this paper. William L. Scherlis. Promises: Limited speci- To motivate data groups in this paper,I spokeinformally fications for analysis and manipulation. In Pro- about the semanticsof the example code. There are sev- ceedings of the IEEE International Conference eral Hoare-like logics and axiomatic semanticsof object- on SofIware Engineering (ICSE’98), pages167- oriented programsthat define the semanticsformally [Lea89, 176. IEEE Computer Society, April 1998. AdB94, Nau94, AL97, Lei97, PHM98, Lei98a]. Four of these lAL97, Lei97, PHM98, Lei98a] deal with programs

151 [Det96] David L. Detlefs. An overview of the Extended [Lea891 Gary Todd Leavens. VerifLng Object-Oriented Static Checking system. In Proceedings of The Programs that Use Subtypes. PhD thesis, First Workshop on Formal Methods in Software MIT Laboratory for Computer Science, Febru- Practice, pages l-9. ACM SIGSOFI’, January ary 1989. Available as Technical Report 1996. MIT/LCS/TR-439. [DLN98] David L. Detlefs, K. Rustan M. Leino, and Greg [Lea961 Gary T. Leavens. An overview of Larch/C++: Nelson. Wrestling with rep exposure. Research Behavioral specifications for C+t modules. In Report 156, Compaq SystemsResearch Center, Haim Kilov and William Harvey, editors, Spec- 1998. ification of Behavioral Semantics in Object- Oriented Information Modeling, chapter 8, [DLNS98] David L. Dedefs,K. RustanM. Leino, GregNel- pages 121-142. Kluwer Academic Publishers, son, and JamesB. Saxe. Extended static check- 1996. ing. ResearchReport 159,Compaq Systems Re- searchCenter, 1998. To appear. IL&951 K. Rustan M. Leino. Toward Reliable Modu- lar Programs. PhD thesis,California Institute of mc1 Extended Static Checking home page, Compaq Technology, 1995. Available as Technical Re- Systems Research Center. Gn the Web at port Caltech-CS-TR-95-03. www.research.digital.com/SRC/esc /Esc.html. B&97] K. Rustan M. Leino. Ecstatic: An object- oriented programming language with an ax- [GH93] John V. Guttag and JamesJ. Homing, editors. iomatic semantics. In The Fourth Interna- Larch: Languages and Tools for Formal Spec- tional Workshop on Foundations of Object- ification. Texts and Monographs in Computer Oriented Languages, January 1997. Proceed- Science.Springer-Verlag, 1993. With StephenJ. ings available from www.cs.indiana.edu Garland, Kevin D. Jones, And& Modet, and /hyplan/pierce/fool/. JeannetteM. Wing. lLei98al K. Rustan M. Leino. Recursiveobject types in a [Hoa72] C. A. R. Hoare. Proof of correctnessof data logic of eject-orientedprograms. In Chris Han- representations.Acta Informatica, 1(4):271-81, kin, editor, Programming Languages and Sys- 1972. tems: 7th European Symposium on Program- ming, ESOP’98, volume 1381 of Lecture Notes [Sac951 Daniel Jackson.Aspect: Detecting bugs with ab- in Computer Science. Springer, April 1998. stract dependences.ACM Transactions on Soft- ware Engineering and Methodology, 4(2): 109- fLei98bl K. Rustan M. Leino. Specifying the modifi- 145, April 1995. cation of extended state. In The Fifth Inter- national Workshop on Foundations of Object- [Jon911 H. B. M. Jonkers. Upgrading the pre- and post- Oriented Languages, January 1998. Proceed- condition technique. In S. Prehn and W. J. ingsavailable from www.pauillac.inria Toetenel,editors, VDM’91 Formal Software De- .fr/Nremy/fool/program.html. velopment Methods, 4th International Sympo- sium of VDM Europe, Volume I: Conference IUW Kevin Lano and Howard Haughton, editors. Proceedings, volume 551 of Lecture Notes in Object-Oriented Specification Case Studies. The Computer Science, pages 428-456. Springer- Object-OrientedSeries. Prentice Hall, 1994. Verlag, October 1991. lLN98al K. Rustan M. Leino and Greg Nelson. Ab- [Lam931 John Lamping. Typing the specialization inter- straction and specification revisited. Internal face. ACM SIGPLAN Notices, 28(10):201-214, manuscript KRML 7 1, Digital Equipment Cor- October 1993. OOPSLA ‘93 conference pro- poration SystemsResearch Center. To appearas ceedings. CompaqSRC ResearchReport 160,1998. LB971 Gary T. Leavensand Albert L. Baker. Enhancing lLN98bl K. Rustan M. Leino and Greg Nelson. An ex- the pre- and postcondition technique for more tended static checker for Modula-3. In Kai expressivespecifications. Technical Report TR Koskimies, editor, Compiler Construction; Pro- #97-19, Departmentof Computer Science,Iowa ceedings of the 7th International Conference, StateUniversity, September1997. CC’98, volume 1383 of Lecture Notes in Com- puter Science, pages302-305. Springer, March 1998.

152 [LS97] K. Rustan M. Leino and Raymie Stata. Check- ing object invariants. Technical Note 1997- 007, Digital Equipment Corporation Systems ResearchCenter, April 1997. &W94] Barbara H. Liskov and JeannetteM. Wing. A behavioral notion of subtyping. ACM Transac- tions on Programming Languages and Systems, 16(6):1811-1841,November 1994. [Mey88] Bertrand Meyer. Object-oriented SoftwareCon- struction. Seriesin Computer Science.Prentice- Hall International, New York, 1988. [Nau94] David A. Naumann. Predicate transformer se- mantics of an Oberon-like language. In E.- R. Olderog, editor, Proceedings of the IFIP WG2.lIWG2.2lWG2.3 Working Conference on Programming Concepts,Methods, and Calculi, pages467487. Elsevier, June 1994. [pHM98] Amd Poetzsch-Heffterand PeterMthler. Logical foundationsfor typed object-orientedlanguages. In David Gries and WiIlem-Paul de Roever, editors, Programming Concepts and Methods, PROCOMET ‘98, pages404423. Chapman & Hall, 1998. [Sta971 Raymie Stata. Modularity in the presence of subclassing. ResearchReport 145, Digital Equipment Corporation SystemsResearch Cen- ter, April 1997. [Van941 Mark T. Vandevoorde. Exploiting Specifica- tions to Improve Program Performance. PhD thesis, MassachusettsInstitute of Technology, February 1994. Available as Technical Report MIT/LCS/TR-598.

153