Trace Function Rev

Embed Size (px)

Citation preview

  • 7/31/2019 Trace Function Rev

    1/34

    Module Interface Documentation -Using the Trace Function Method (TFM)

    David Lorge Parnas and Marius Dragomiroiu

    Software Quality Research Laboratory

    Faculty of Informatics and Electronics

    University of Limerick, Ireland

    AbstractA new approach to the professional documentation (description or specification) of

    interfaces for information hiding components, the Trace Function Method (TFM), isdescribed. The motivation and design assumptions behind the method are explained.The concepts of event, event descriptor, and trace are introduced. Basic functions onevent descriptors and traces are defined. The method is illustrated on a variety simpleexamples.

    trace function 1/34 21 01 2006 19:03

  • 7/31/2019 Trace Function Rev

    2/34

    1. .....................................................................................................Introduction

    32. . ..... .... ..... ..... ..... .... ..... ..... .... ..... ..... .... ..... ..... ..... .... ..... ..... ...Software Reference Documentation 33. ..........................................................................................................................Software Design 54. .........................................................Earlier approaches to module interface documentation 65. .............................................................................................................................On Readability 76. .....................................................................................................................Whats new in TFM 97. .....................................................Communication with Software Modules 108. ............................................................................................................Events 119. .........................................................................................Event descriptors 1110. ............................................................................................................Traces 1211. ...................Trace Function (TFM) Component Interface Documentation 1212. .........................................................................When is a trace-based document complete? 1313. .......................................................................When is a trace-based document consistent? 1314. ...................................................................................................What is a TFM specification? 1315. .....................................................................................................What is a TFM description? 1316. .................................................................When is an implementation of a module correct? 1317. ....................................................Determining theinputs and outputs 1418. ...............................................................Basic guidelines for selecting inputs and outputs 1419. ....................................................Formal inputs andoutputs vs. actual inputs and outputs 1420. .....................................................................Responsibilitiesof the Parties 1521. ...........................................................................................Responsibilities ofthe Specifiers 1522. .....................................................................................Responsibilities ofthe implementers 1523. .....................................................................Responsibilities ofthe user of the component. 1624. .................Dealing with problems outside the implementations control 1625. ................................Modules that create more than one object of a type. 1626. ........................................................................The remainder of this paper 1727. .................................................Primitive Functions on Event Descriptors 1728. ..................................................Basic functionsand predicates on traces 1729. ...............................................................................................................................L(T) (length) 1830. ......................................................................................................................r(T) (most recent) 1831. ...............................................................................................................................o(T) (oldest) 1832. .........................................................................................................................p(T) (precursor) 1833. .....................................................................................................................s(T) (subsequent) 1834. .............................................................................................................rn(n,T) (most recent n) 1835. ......................................................................................pn(n,T) (precursorof most recent n) 1936. .......................................................................................................................on(n,T) (oldest n) 1937. .............................................................................................................sn(n,T) (subsequent n) 1938. .......................................................................................................mrcall(pg,T) (mostrecent) 1939. .........................................................Useful functiongenerators on traces 2040. .........................................................................................................................ex(P)(T) (exists) 2041. .......................................................................................................rst(P)(T) (recent such that) 2142. ......................................................................................................ost(P)(T) (oldest such that) 2143. ..........................................................................................................et(P)(T) (extracted trace) 2144. ...........................................................................................irst(P)(T) (index recent such that) 2145. ...........................................................................................iost(P)(T) (index oldest such that) 2246. ....................................................Examples of theTrace Function Method 2247. ..............................................................................................................................Date module 2248. ...............................................................................................................Time storage module 2549. .........................................................................................A stack of limited range and depth 2750. ...............................................................................................A keyboard checking program. 2951. ..................................................................................................Conclusions 3052. ......................................................................................Acknowledgements 3153. .....................................................................................................References 31

    trace function 2/34 21 01 2006 19:03

  • 7/31/2019 Trace Function Rev

    3/34

    1. Introduction

    For many decades, project managers and software architects have complained thatthey have no precise way to tell a programmer what a product or component must do.unless they have an existing program with the desired function. Even using an existingprogram to say what you want will be unsatisfactory if the program at hand hasproperties that are not required. Moreover, the code tells you what the code does, notwhat it was intended to do.

    Even when a program already exists, asking the users to read the code to find outwhat it will do in all cases is often inappropriate. There may be some people who usethe program and either cannot, or should not, read the code. Even when the code isavailable it may be complex, making it difficult and time consuming to read. Using thecode to answer questions can have cost and delay implications, especially when thecode is being developed further or maintained. Participants in large projects oftenobserve that without precise interface descriptions, the integration of separately writtencomponents is an arduous, costly, and time-consuming task. It can only be achieved byan iterative cut and try process.

    Although many software interface documentation methods have been proposed in theresearch literature, none has proven entirely satisfactory for developers. Some methodshave worked well in projects but had serious limitations; others were theoreticallyadequate but found to be difficult for developers to use. A brief history of previous workon this topic is given under earlier approaches.

    This paper presents a new method, known as the Trace Function Method (TFM). TFMhas had limited trials in both industry and academia and has proven useful in thosetrials. It appears to overcome the theoretical limitations, and to be reasonably intuitive.

    We begin with some basic definitions and methodological observations that are thebasis for the paper.

    1.1. Software Reference Documentation

    We are studying methods of providing reference documents for professional softwaredevelopers. We are not providing introductory or overview documentation. We assumethat other documentation is available for those who are just becoming familiar with thegeneral nature of a product. In computer science circles, the word documentationoften refers to a collection of syntactic information and informal comments about code.In Engineering however, documents are usually precise specifications of requirementsor precise descriptions of the product as built. These documents are designed asinformation repositories and used for information retrieval. In this paper, we use theword, document in its Engineering sense.

    1.1.1. What should reference documents provide?

    Reference documentation should provide an easily accessed source of trustworthyand detailed information about the program and its behaviour. Using a referencedocument, one should quickly be able to answer questions such as:

    What will this component do if it receives ..? What are the circumstances that lead to the output of ..? How can I get this component to ..?

    trace function 3/34 21 01 2006 19:03

  • 7/31/2019 Trace Function Rev

    4/34

    1.1.2. Defining the required content of documents

    In [PM95] Parnas and Madey provided precise definitions of the content,not the formator notation, of documents that they consider essential for software projects. Eachdocument is viewed as a representation of a set of relations 1. A document is complete ifone can tell whether or not any particular pair is in that relation. No additionalinformation is desirable in these documents. .

    [PM95] suggests that the first internal design document be a Software Module Guideas illustrated in [PCW85], an informal document that describes the division of thesoftware into modules by stating the information that each hides.

    For each module listed in the software module guide, [PM95] calls for a moduleinterface document, a document that treats the module as a black-box, identifying onlythose programs and data structures intended to be accessed from outside the moduleand describing all externally-visible actions of the module. These documents shouldrefer only to information exchanged between the module and external programs

    1.1.3. Notation for precise documentation

    [PM95] does not discuss the representation of mathematical relations. Practicalexperience that began in 1977 lead us to use a tabular form of mathematicalexpressions ([Pa92], [JPZ97] to describe relations. This paper is not about tabularexpressions but uses such expressions in its definitions and examples.

    1.1.4. Specifications and other descriptions

    In discussions of engineering documents, it is important to distinguish betweenspecifications and descriptions; a method such as TFM can be used for either because

    the difference between a specification and other descriptions is one of intent, not form.The only way to tell if a description is intended as a specification is what is said aboutthe document, not its contents.

    A description states properties of a product; it may include both incidental andrequired properties.

    A specification2 is a description that states only required properties;

    afull specification is a specification that states all required properties.

    A specification imposes obligations on the implementers, the users, and anyone whorequests a product that meets the specification.

    When presented with a specification, implementers may either accept the task ofimplementing that specification, or report problems with the specification andpropose a revision; they may not accept the task and then (knowingly) build

    something that does not satisfy the specification.

    trace function 4/34 21 01 2006 19:03

    1 This paper assumes that readers understand the terms function, relation, domain, range,predicate, and representation in the way that those terms have long been used in Mathematics andEngineering. A standard text on discrete mathematics will explain those terms to those who do not.

    2 In this paper, we use the word specification as it is generally used in Engineering, which is differentfrom the way that it has become to be used in Computer Science. In Computer Science, the word is used,often without definition, to mean any formal model with some unspecified resemblance to a product.

  • 7/31/2019 Trace Function Rev

    5/34

    Users must be able to count on the properties stated in a specification; however,they must not base their work on any properties mentioned in any anotherdescription unless they are included in the specification.

    Purchasers are obligated to accept any product that meets the (full) specificationthat they provided to the supplier.

    Other descriptions may be useful for understanding particular implementations, forexample additional descriptive material may document the behaviour of animplementation in situations that were treated as dont care cases in the specification.

    1.2. Software Design

    This paper is part of a general approach to software design and must be seen as one

    of the tools to use in that approach. Here we review the main concepts and principles inthat approach.

    1.2.1. Programs, Components and Modules

    In this paper, program is used to denote any sequence of computer instructions that,when executed, will cause a sequence of state changes in the computer and attachedperipheral equipment. Programs are the constituents of components and modules.

    Component and module are used as near synonyms with a subtle difference.

    A module is a collection of programs to be implemented as a single work

    assignment by a programmer or group of programmers.

    A componentis a collection of programs that are distributed as a unit and used inlarger systems without modification.

    In other words, a module is a unit for software development while a component is aunit for software distribution and deployment purposes. A component may compriseseveral independently developed modules and a module (or parts of that module) maybe built using several components.

    In spite of these differences, any method suitable for documenting the interfaces ofwell-designed components is suitable for documenting well-designed module interfacesand vice versa. The method described in the sequel, is intended for both applications.

    1.2.2. Design Principles

    A collection of guidelines using such (now familiar) phrases as, separation ofconcerns [EWD68], information hiding [Pa72b], encapsulation, loose coupling, anddivide and conquer are widely accepted as the key to dealing with softwarecomplexity. These principles tell us that software products must be divided into workassignments (modules) whose interfaces are markedly simpler, and less likely to requirechange, than their implementations. Each module must be implemented using onlypublished interface information about the other components.

    A change to a module is considered internal or hidden if the interface to other modulesis unaffected by the change. In other words, internal changes to one component, can bemade without affecting other components.

    Software that adheres to these principles has been found to be easier to develop,debug and maintain than software without well-defined internal boundaries.

    trace function 5/34 21 01 2006 19:03

  • 7/31/2019 Trace Function Rev

    6/34

    However, applying these guidelines requires that we document the interfaceinformation precisely and without revealing any internal information. Only in this way,can we be sure that the implementers of other modules do not use information aboutthe internal structure (thereby making changes more difficult). Consequently, findinggood ways to prepare module interface documentation is essential to improving thequality of our software.

    1.2.3. Multiple-Interface Modules

    Papers on specification often ignore that fact that, in practice, modules must bethought of as having several interfaces. Modules have an upper-face and a lowerface. The upper-face is the face that the module shows to programs that use it. On thisinterface one sees programs (or methods) that provide services to other modules.However, there is also an interface between the module and the programs that it uses;we call it the lower-face. Changes in either of these part-interfaces cannot be confinedto a single module.

    The lower-face is usually hidden from the modules users; in fact, often the purpose ofthe module is to insulate its users from the details of the lower-face. However, aspecification for the implementer should include both interfaces so that the implementerknows what assumptions may be made about the support system. Further, wheninstalling the module, it is sometimes necessary to know such lower-face information asthe memory requirements, timing requirements, and operating system compatibility.Documentation of the lower faces is essential to understand how modules may affecteach other by their use of shared resources.

    The upper-face may also be divided for distinct sets of users. For example, a user whois writing hardware diagnostic programs will require information that should not beavailable to normal users. [BPP81]

    The fact that the full interface is described in several distinct documents, and someusers do not get all the documents, means that even a fully deterministic module mayappear non-deterministic to some of its users. This is discussed further in the section ondealing with problems outside the implementers control.

    Documents written using the method described in this paper can describe any of theseinterfaces. The examples in this paper deal only with the upper-face.

    1.3. Earlier approaches to module interface documentation

    Approaches to methods of writing module interface specifications can be divided intofour classes:

    pragmatic, such as [Pa72a], [CP84], [CPS84] algebraic, such as the pioneering work of Guttag[GH78]

    axiomatic, such as the pioneering proposal of Zilles[LZ75] mixtures of the above.

    1.3.1. Pragmatic approaches

    The pragmatic approaches have proven useful in many applications but are limited toa very specific class of modules - those in which all effects of an operation areimmediately visible externally. Some common objects such as stack and queue do not

    trace function 6/34 21 01 2006 19:03

    http://%23lz75/http://%23cp84/http://%23gh78/http://%23lz75/http://%23lz75/http://%23gh78/http://%23gh78/http://%23cp84/http://%23cp84/
  • 7/31/2019 Trace Function Rev

    7/34

    have this property. However, many common object classes do have this property.Pragmatic methods worked quite well when applied in some realistic problems (e.g.[CP84]) but their limitations are troubling.

    1.3.2. Algebraic and Axiomatic Approaches

    The algebraic and axiomatic approaches could describe many more types of modulesthan the pragmatic approaches but have not become as popular with developers. Agood introduction to these ideas is presented in [GM85].

    The algebraic approaches were more popular (with researchers) than the axiomaticapproaches. The set of possible values of objects of the type was considered the carrierset of an algebra; the programs were the operations. The behaviour was described by aset of equations. A huge literature was built up by researchers trying to enlarge the classof modules that could be specified. However, because algebraic approaches do notmake explicit statements about the objects of discourse (the carrier set in algebraicterms) limitations were always present. Although less restricted than the older pragmaticapproaches they were not widely used for practical problems [Wa02].

    In the axiomatic approaches, the behaviour of the programs was characterized by aset of axioms, which could be used, with some skill, to derive values. Although thephilosophical basis of algebraic approaches and axiomatic approaches was quitedifferent, the specifications tended to look quite similar.

    1.3.3. Trace Assertion Approaches

    The trace assertion approach, introduced in [BP77], was inspired by all three ofthese approaches; it attempted to remove the limitations in the algebraic models bymaking the carrier set of the algebra explicit, i.e. by talking explicitly about a set of

    possible histories. The set of possible histories was partitioned by defining canonicalrepresentatives of the partitions. It appeared that the limitations inherent in thepragmatic approaches were removed. Hoffman showed that trace approaches hadsome very nice properties. i.e. there are procedures for constructing complete andconsistent specifications [HS88]. This work was extended in [PW89] and[Wa94].

    The Trace Assertion Methods (TAM) inherited an equational/axiomatic style from theother approaches. It has been our experience that practitioners do not find this natural.Researchers at Warsaw University, McMaster and the University of Waterloo havelooked at the TAM in many ways but not improved their acceptability to developers[IMS95].

    Wang and Parnas introduced tabular notation into the TAM in [PW89] but it was a veryrestricted and specialized form of tabular notation. Although it helped in many ways, themethod remained unnatural for practitioners.

    A good recent study of the TAM can be found in [JS01].

    1.4. On Readability

    The motivation for our research has been to find a way to produce precise componentinterface documentation that is sufficiently useful that developers, reviewers, andmaintainers find it preferable to reading code, or asking someone else.

    trace function 7/34 21 01 2006 19:03

  • 7/31/2019 Trace Function Rev

    8/34

    In spite of their nice theoretical properties, algebraic, axiomatic, and trace assertionmethods have not seen much industrial use. Lack of take up is often attributed to lackof interest; but this is not correct. Practitioners do recognize the need for better interfacedocumentation, but it can be difficult to use axiomatic, assertion, or equation-baseddocuments to retrieve information because answering a question may require the manyrepeated applications of the rules (axioms, equations, or assertions). Even worse,usually interpretation of the document requires choosing the right rule to apply and thisrequires a deep understanding.

    Writing these documents requires the author to discover and express general lawsabout the objects that they are designing - something that seems to be difficult for many.Reading the documents, requires the reader to understand the implications of thosegeneral laws. When mathematics is applied in traditional engineering, engineers seekwhat they call closed form solutions3; these are solutions that tell you how to calculate

    the desired values in a very mechanical way. Equations that can be solved to find theanswers are always less desirable and less likely to be applied.

    We want to produce documentation for software professionals who have had trainingabout how to read such specifications. We believe that the equivalent of a closed formsolution, rather than equational or axiomatic documents will be more practical.

    Neither the TFM, nor any other method, can guarantee that a document is readable.An approach can allow writers to produce easily used documents, but the final resultdepends on issues of taste, disciplined organization, use of appropriate auxiliaryfunctions in the specification, and other factors that cannot be dictated by the method.

    In this section, we review some factors that contribute to readability and then discusshow the TFM helps.

    1.4.1. Directness

    Documentation that answers the readers questions directly is generally more suitablethan documentation that forces the reader to derive the answers they want frominformation that implies it.

    1.4.2. Abstraction

    Documentation that abstracts from details that are not relevant to the reader isgenerally preferable to documentation that uses irrelevant information to describe theinformation that the reader wants. Because there are many types of readers, each withdifferent information needs, we propose a set of complementary documents [PM95].Each of these documents provides a distinct view of a product by abstracting frominformation provided in code and other documents.

    1.4.3. Ability to distinguish the essential from incidental information

    Documents should not mix descriptions of incidental facts about an implementationwith essential requirements. Information that may change on short notice, should not bemixed with information that is considered permanent or long term.

    trace function 8/34 21 01 2006 19:03

    3 Engineers sometimes (incorrectly) call these exact solutions.

  • 7/31/2019 Trace Function Rev

    9/34

  • 7/31/2019 Trace Function Rev

    10/34

    more complex than the pragmatic ones would have been. They are however,different because the pragmatic approaches were organized by programwhereas TFM uses a the output based approach that has proven practical inthe requirements area [He80], [HPS78].[PM95].

    We are able to document modules that communicate through global variablesand even modules where the global variables are replaced by formal place-holders and may be chosen later. Earlier approaches were limited by the factthat they assumed that each module had a completely private data structure andcommunicated only through arguments in procedure calls. This may representgood design, but it is not realistic for describing legacy systems that were notdesigned using these rules.

    All of these changes are motivated by a desire to make the method more usable anduseful in practice. Theoreticians may find little new but the documents are dramatically

    different from those produced using older approaches.It is certainly possible to write TFM documents that are very difficult to read. Moreover,no general method will allow a simple description of something that is inherentlycomplex. However, the TFM:

    states the most often needed information (output values in specific cases)directly rather than indirectly,

    abstracts from internal implementation details clearly distinguishes the essential information (output values) from other

    information allows the use of standard mathematical concepts for avoiding repetition and

    achieving brevity dictates a strict organization for the information to ease retrieval

    A later section provides examples that illustrate the use of the TFM. The next section

    discusses some issues that arise when writing the specification.

    2. Communication with Software Modules

    Software modules may have access to two distinct data structures.

    a hidden (internal) data structure that stores the modules memory of its historybut is not directly accessed by users .

    a global data structure that must be accessed by the module to receive or transmitinformation. Global data items are mentioned in the specification.

    The global variables whose values may be changed by the module are called outputs.Those whose values may influence the behaviour of the modules are called inputs. Avariable may be both an output and an input.

    Note that:

    The value of a function program is treated as a global variable.

    When programs communicate using parameters, the arguments are placeholdersfor the shared/global variables that will eventually be used for communication.

    Often, the event is the invocation of one of the module s externally accessibleprograms. A global variable that contains the name of the program invoked at anevent, must be regarded as a global variable that is one of the inputs.

    Time and such things as cpu cycles consumed, which are often consideredspecial in some inexplicable way, are also easily considered as global variablesand require no special treatment.

    trace function 10/34 21 01 2006 19:03

  • 7/31/2019 Trace Function Rev

    11/34

    Shared/global variables are the fundamental way that modules communicate. All ofthe other mechanisms are implemented using global variables.

    Although the information hiding principle [Pa72b, PCW85] tells us that we shouldkeep most of our data in the internal data structures of modules, we are often requiredto write specifications or descriptions of modules that use global data structures tocommunicate with other modules. A practical approach to module interfacedocumentation must be able to describe such modules.

    3. Events

    A software module may be viewed as a finite6 state machine operating at discrete

    points in time, which we call events.

    At each event, the module will do some combination of the following:

    read some of the global variables (e.g. via input parameters), and change its internal state, and change the value of some of the global variables.

    4. Event descriptors

    Each element of the global data structure must have a unique identifier (i.e. there mustbe a 1:1 mapping between the variables and the identifiers)7 for use in eventdescriptors. Event descriptors use a variables unique name.

    For convenience, the name PGM is reserved for the name of a variable that stores theidentifier of any program that was invoked in the event and the name Value for thevariable that stores the computed values of function procedures.

    A full event descriptor specifies the values of every variable in the global data

    structure before and after the event. Abbreviated event descriptors contain only the before and after values and names

    of variables in the global data structure that are either read or changed duringthe event. The only variables that are not mentioned in an abbreviated eventdescriptor are those that are neither changed nor used to compute new valuesduring the event.

    The table below is a possible representation of a single event descriptor. The tableheader gives the name of the variable, the row below it contains the value of theindicated variable. The variable name contains or to differentiate between thevalue before the event and the value after the event. Variables that do not change needappear only once without either or

    trace function 11/34 21 01 2006 19:03

    6It is often remarked that much can be proven without the assumption of finiteness. We make thisassumption for several reasons: (1) we can only build finite modules and a specification that violates thisassumption cannot be implemented, (2) many issues need not be considered if we make this assumption,(3) since the assumption is true in fact, if you do not use it, you cant prove all that can be proven, (4)anyof the bugs that motivate our search for more effective design and documentation methods are caused byunexpected finite limits that must be documented. Note, however, that the number of states, and the otherfinite limits, can be parameters of the specification.

    7Unfortunately, most programming languages do not provide such names; one must adopt additionalnaming conventions in order to define a single, unique, name for each variable. These are used in thedocumentation and are not necessarily to be found in the program text.

  • 7/31/2019 Trace Function Rev

    12/34

    PGM io in io out

    name ofprogram invokedin event

    value of iobefore the event

    value of inbefore the event

    value of io afterthe event

    value of outafter the event

    5. Traces

    A trace is a finite sequence of event descriptors; it describes a sequence of events.

    A subtrace of a trace T is a sequence of the event descriptors that is contained within a

    trace T.

    A prefix of a trace T of length n is a subtrace of T that contains the first n elements of T.We call a trace a prefix of T if it is a prefix of T of any length.

    A suffix of a trace T of length n is a subtrace of T that contains the last n elements of T.We call a trace a suffix of T if it is a suffix of T of any length.

    The table below is a representation of a 5 element trace. Each column corresponds toone input or output variable. Each row corresponds to an event. Each cell contains thevalue of that variable for that event. If a variable is neither read nor written in an event,that cell may be left blank or the unchanged value provided. In the first row, valuesshould always be provided.

    PGM io1 in2 io1 out1name of program invoked value of io1 before the event value of in2 before the event value of io1 after the event value of out1 after the event

    name of program invoked value of io1 before the event value of in2 before the event value of io1 after the event value of out1 after the event

    name of program invoked value of io1 before the event value of in2 before the event value of io1 after the event value of out1 after the event

    name of program invoked value of io1 before the event value of in2 before the event value of io1 after the event value of out1 after the event

    name of program invoked value of io1 before the event value of in2 before the event value of io1 after the event value of out1 after the event

    Note that trace is a formal concept; any sequence of event descriptors is a trace.

    A history, a trace that accurately describes all of the events that affected a modulebeginning with its initialization.

    6. Trace Function (TFM) Component Interface Documentation

    A TFM component interface document comprises:

    a complete description of the components inputs (their type), and a complete description of the components outputs (their type) , and a description of a set of relations, each one describing the relation of the value

    of an output to the history of the values of the inputs. The range of each relationis the set of possible values for the associated output variable. The domain ofeach relation is a subset 8 of the set of all possible histories for that component.

    If the behaviour being documented is deterministic, the relations will be functions.

    Note that histories should include all past behaviour including the actual output valuesas well as the actual input values; in some methods, non-determinism causes difficultybecause one can only refer to input values.

    trace function 12/34 21 01 2006 19:03

    8 Some output values may not be defined for some histories; those histories are, strictly speaking, notincluded in the domain of the function that describes that value. To make it clear that these have notsimply been overlooked, the function definitions in the examples in this paper show such cases explicitly,indicating that no value is defined. This is indicated by an empty table cell with shaded background.

  • 7/31/2019 Trace Function Rev

    13/34

    6.1. When is a trace-based document complete?

    A TFM document is mathematicallycomplete if there is a relation for every output andthe complete set of possible traces for which the value of each output is defined isincluded in the domain of the corresponding relation. It is complete if all outputs areincluded and their type is properly specified.

    6.2. When is a trace-based document consistent?

    Because each output is defined separately (dependant only on inputs and earlier

    values of other outputs), the document is consistent if each individual relation isconsistently defined. Using tabular notation, consistency of a function/relation definitionis usually easy to establish.

    6.3. What is a TFM specification?

    A TFM specification of a component M is a complete and consistent TFM documentthat characterises the set of traces that are to be considered acceptable for M.

    If any of the behaviours described in the document as acceptable would beconsidered unacceptable by users, or if any user-acceptable behaviour is not described,the purported specification is incorrect.

    6.4. What is a TFM description?

    A TFM description of an implementation of a module M is a TFM document thatcharacterises the set of traces that are possible with that implementation.

    If the implementation exhibits any behaviour not included in a document proposed as

    a complete description, or if the description describes behaviour that never happens,that purported description is incorrect.

    6.5. When is an implementation of a module correct?

    Correctness is not something we can check mathematically. We can only check thatan implementation satisfies a specification. It takes knowledge about the application, toknow if the specification describes the actual requirements.

    Checking that an implementation satisfies a given TFM specification is best done intwo stages:

    Produce a TFM description of the behaviour of the implementation Compare the TFM description with the TFM specification

    In the comparison we determine:

    that the two documents match syntactically, i.e. that the inputs and outputsmatch in name and type,

    that each relation in the description is a subset of the corresponding relation inthe specification,

    that the domain of each relation in the description contains the domain of thecorresponding relation in the specification.

    trace function 13/34 21 01 2006 19:03

  • 7/31/2019 Trace Function Rev

    14/34

    7. Determining the inputs and outputs

    Every software component is created to compute and communicate specific values.Values that are computed and subsequently stored where other components can readthem are called outputs. Values that are stored internally, in hidden data structures, arenot outputs but may be used to compute the values of future outputs. All of thecomputations are based on values received from other components, known as inputsand any initial values of the internal variables.

    Any documentation of an interface must be based on a complete list of the inputs andoutputs. Preparing such a list is the first step in writing a TFM document. It is quitenormal however, that the first list will be incomplete or incorrect; it usually necessary torevise the list as documentation proceeds. Nonetheless, composing such a list shouldalways be the first step.

    7.1. Basic guidelines for selecting inputs and outputs

    Mathematics provides no firm rules to answer the question, What constitutes a singleoutput?. Any pair of outputs may be combined and considered to be a single output.Conversely, any output can be split but the result may be outputs that are notindependent. The only rule is that all information that is to be computed andcommunicated outside the module must be represented in the outputs.

    One should organize the output information in ways that simplify the description.

    If two output values have very similar descriptions, combining them may help.For example, if two output values give the sine and cosine of an angle,combining them to a single output of type angle usually leads to a simplerdocument.

    If an output consists of several independent pieces of information (e.g. age and

    nationality), separating them usually simplifies the document.

    7.2. Formal inputs and outputs vs. actual inputs and outputs

    The global variables to be used for communication with the module may bedetermined at several distinct times:

    at the time that a specification is written (by writing the variables unique name inthe document)

    at the time that the programs that compute the outputs are written at the time that the programs that invoke the programs are written during execution.

    In the first of the above alternatives, the name of the actual variable is used in the

    specification. For all other situations, a place holder (sometimes called a formal

    variable) is used in the specification and an actual variable is named later.

    Note that the use of the actual variables in the specification simplifies the situation inanother way. It has become customary to produce components with programs in theform of set/get pairs. The set program stores input information internally; the getprogram returns that value to its calling program. If we use fixed output variables, theget programme is not needed.

    trace function 14/34 21 01 2006 19:03

  • 7/31/2019 Trace Function Rev

    15/34

    If formal variables are used in the specification and the actual variables used foroutputs will not be determined until after the implementation, subtle difficulties mayarise.

    Specifiers, implementers, and the programmers who use these components must beaware of these difficulties. A specification written in terms of formal variables is

    considered a schema specification; the actual specification is produced by substitutingthe names of the actual parameters for the formal ones.

    The result of this substitution may have surprising, often undesired, properties whenanalysed. For example, if there are two formal output variables used in the specificationbut, later, the same actual variable is chosen for both, the actual specification may beimpossible to satisfy because two distinct values might be specified for a single actualvariable9.

    It is not generally practical to implement components that check for such situations

    and handle them correctly. Limitations on the selection of the actual input/outputvariables must be part of a specification. Some reasonable general restrictions wouldbe:

    All actual variables must be distinct. All actual variables must be selected before computation. Input values should be read before any output values are written. If array elements are to be used as input/output variables, the whole array

    should be regarded as a single variable, not as a set of individual elements.

    These problems will not be discussed further in this paper.

    8. Responsibilities of the Parties

    The professionals most concerned with these documents will be

    the authors of the specification the implementers of components that must satisfy the specification

    users of components that must satisfy the specification

    The specification documents an agreement between them and defines the responsibilityof all parties.

    8.1. Responsibilities of the Specifiers

    The main responsibility of the specifier is to capture all of the requirements accuratelyand to make sure that any product that satisfies the specification will be fit for theintended use.

    8.2. Responsibilities of the implementers

    The implementer must remember that the specification gives the values of the outputvariables after each event in terms of the values in the history and input variables beforethe event. The output values immediately after an event must be as specified and noother global variable values should be changed.

    trace function 15/34 21 01 2006 19:03

    9 In such a situation, the program cannot complete in a state that satisfies the specification and henceshould not terminate! Unfortunately, detecting such situations is often difficult.

  • 7/31/2019 Trace Function Rev

    16/34

    8.3. Responsibilities of the user of the component.

    Users of each component are expected to have read and understood the actualspecification, i.e. the one in which all formal variables have been replaced by the actualvariables.

    It may be necessary to lock global variables that are used during computation if theymight be accessed by other processes. Usually, inputs should be locked until theirvalues will not be read again and outputs should be locked between the time that theirvalue is set and termination of the component. If this is not done, the component cannotguarantee that the outputs on termination will be as specified. Because the lockingmechanism must be an external one, variables will be usually be locked throughoutthe event.

    9. Dealing with problems outside the implementations control

    On occasion, factors outside of a programmers control (e.g. hardware failure,inadequate resources) may cause a module to fail to satisfy its specification. The factorsleading to failure may not be visible to a components users, before the event, makingthe behaviour appear non-deterministic (i.e. not determined by information available). Aspecification that does not recognize that the behaviour may appear non-deterministicwill mislead its users and encourage them to ignore the failures instead of preparingfailure recovery procedures.

    Realistic specifications will have to use relations that are not functional. Generally, it isimportant to give informative error indications when there is a failure. The relation willhave to include both the desired answer and the failure behaviour as possibilities. Itmust be understood, that the implementation should exhibit the failure behaviour onlywhen it is unavoidable.

    10.Modules that create more than one object of a type.

    Every component can be viewed as creating a single object, but it is often useful toview a module as implementing a set of similar objects (a type) that can be created anddeleted during execution. For example, if a program has to store data about manydistinct angles, a set of objects (variables) of the abstract type can be moreconvenient than a single object containing a list or array of angles. This observation isone of the bases of the Object Oriented languages.

    Viewing a component as creating many objects is only useful if the objects areindependent of each other, i.e. if an operation only affects objects that are named asoperands, leaving the state of all other objects untouched.

    Under these circumstances, one can prepare much of the interface documentation as

    if the component created only one object.When there can be more than one object, each object must have an identifier. When

    the programs are used, the identifier is prepended to the name of the operation, toidentify the main operand.

    For operations that involve additional objects of the type, one of the objects is namedas above; any additional objects are named as operands in the same way as operandsof other types.

    trace function 16/34 21 01 2006 19:03

  • 7/31/2019 Trace Function Rev

    17/34

    There will also be additional operations that create and delete objects of the type.Each object has a separate trace, which we refer to as T .. Each trace beginswith the event that created the object and ends with the event that destroys it. In thespecification, if there is only one object involved, we will abbreviate this as T. If thereare two or more objects involved, the trace of the primary object (the one named as partof the operation name) is T.

    When an operation involves two or more objects, each objects trace contains anevent descriptor for that event. The event descriptor includes the before and aftervalues of all operands.

    This is illustrated later in this paper using the date module example later.

    11.The remainder of this paper

    The above sections state the basic principles behind the TFM and discuss how it isintended to be used. The remaining sections discuss detailed definitions of useful tracefunctions and provide examples. The material above is essential. The more detailedinformation below reflects our experience with this and earlier methods; many variationsthat would be consistent with the principles described above are possible. For example,additional functions on traces will be added for special applications or on the basis ofgrowing experience.

    We begin by describing functions on event descriptors. Next, we talk about functionson traces whose range is either traces or event descriptors. Finally, we will introducesome function-schema, classes of functions that can be used to generate a specificfunction by specifying a predicate argument.

    12.Primitive Functions on Event Descriptors

    Event descriptors are viewed a set of ordered pairs. The first element of each pairidentifies a variable as described above. The second element is the value immediatelybefore and immediately after the event being described.

    We will use the unique variable names as functions whose domain consists of eventdescriptions. Thus if e is an event descriptor and V is the unique name of a variable, V(e) denotes the value of V immediately before the event described by e, and V(e)denotes the value of V immediately after that event. If a value is read but does notchange during the event, we may use V for either V or V. PGM does not changeduring an event; PGM(e) is the name of the program invoked at that event (if any).

    Primitive functions may be combined in the usual ways to define other functions onevent descriptors.

    13.Basic functions and predicates on traces

    The functions defined below have been found useful for defining functions andpredicates on traces. The first functions are simple and taken as primitive. Theremaining functions are defined using the primitive ones.

    In the sequel, . is used to indicate concatenation, but . does not appear in a trace;similarly, _ denotes an empty trace, but never appears in a trace. The empty trace isan identity operand for concatenation, i.e. for any trace T, _.T = T._ = T

    trace function 17/34 21 01 2006 19:03

  • 7/31/2019 Trace Function Rev

    18/34

    13.1. L(T) (length)

    ( )10

    L(T) is the number of event descriptors in T; L(T) is 0 if T is empty.

    13.2. r(T) (most recent)

    ( )

    r(T) is the last (most recent) event descriptor in the trace; it is undefined if L(T) = 0.

    13.3. o(T) (oldest)

    ( )

    o(T) is the first (oldest) event descriptor in the trace; it is undefined if L(T) = 0.

    13.4. p(T) (precursor)

    ( )

    p(T)

    L(T) = 0

    L(T) = 1 _

    L(T) > 1 T2 | T = T2.r(T)

    13.5. s(T) (subsequent)

    ( )

    s(T)

    L(T) = 0

    L(T) = 1 _

    L(T) > 1 T2 | T = o(T).T2

    13.6. rn(n,T) (most recent n)

    ( )

    rn(n,T) is a suffix of T containing the n most recent elements in T. It can be defined asfollows.

    rn(n,T)

    trace function 18/34 21 01 2006 19:03

    10 This notation gives the signature of the function - in this case it maps from traces to integers. Thefunctions described here are partial functions (as described in [Pa92]); this means that the domain of thefunction may be a proper subset of the domain specified in the signature. For clarity, we sometimesinclude cells in the table that are grey and empty to indicate that the function is deliberately partial.

  • 7/31/2019 Trace Function Rev

    19/34

    n > L(T)

    n L(T))

    n < 1 _

    n = 1 r(T)

    n > 1 rn(n - 1, p(T)).r(T)

    13.7. pn(n,T) (precursor of most recent n)

    ( )

    pn(n,T)is a prefix of T such that T = pn(n,T).rn(n, T). It can be defined as follows.

    pn(n,T)

    n > L(T) n < 1

    n L(T)) n = 1 p(T)

    n > 1 pn(n-1, p(T))

    13.8. on(n,T) (oldest n)

    ( )

    on(n,) is a prefix of T consisting of the oldest n elements of T. It can be defined asfollows.

    on(n,T)

    n > L(T) n < 1

    n L(T))n = 1 o(T)

    n > 1 o(T) . on(n-1, s(T))

    13.9. sn(n,T) (subsequent n)

    ( )

    sn(n,) is a trace consisting of all of the elements of T subsequent to on(n,T) in the

    order in which they appear in T. It can be defined as follows.

    sn(n,T)

    n > L(T) n < 1

    n L(T))n = 1 s(T)

    n > 1 sn(n-1, s(T))

    13.10.mrcall(pg,T) (most recent)

    ( )

    trace function 19/34 21 01 2006 19:03

  • 7/31/2019 Trace Function Rev

    20/34

    mrcall(pg,T) returns the most recent event descriptor in which the program pg wasinvoked.

    mrcall(pg, T)

    L(T) = 0

    L(T) = 0 PGM((r(T)) = pg r(T)

    PGM((r(T)) = pg mrcall(pg, p(T))

    14. Useful function generators on traces

    The items defined below are not functions but schema describing a set of functiondefinitions. The domain of the generators is a predicate, P, that must be a predicatedefined on a domain of event descriptors. By varying P, one can define a family of

    functions useful for specific documents. The predicate will be evaluated each time thatthe generated function is evaluated .

    If X is the name of such a schema and P names an appropriate predicate, X(P)denotes a function and X(P)(T) denotes its application to T.

    The predicate must have a single event descriptor as argument. For example, if theevent descriptors have the variable PGM, then PGM(e) = PUSH is a predicate P(e) thatcould be used in the schema below.

    Any function with more than one argument can be reduced to a function of oneargument by binding all of the arguments but one. For example, if we define

    NAME(pg, e) PGM(e) = pg

    and PUSH is the name of a program in the document,

    NAME(PUSH, )

    is a predicate on the domain of event descriptors. The empty parameter positionindicates the parameter of NAME that has been omitted.11

    14.1. ex(P)(T) (exists)

    ( ( ))12

    ex(P)(T) is trueif and only if T contains an event descriptor that satisfies P. It can bedefined as follows.

    ex(P)(T)

    L(T) = 0 false

    L(T) > 0P(r(T)) true

    P(r(T)) ex(P) (p(T))

    trace function 20/34 21 01 2006 19:03

    11 This technique is often called Currying, though Schnfinkel seems to have used it earlier.

    12 This notation indicates that the generator maps from event predicates to functions; each of thosefunctions maps from traces to booleans.

  • 7/31/2019 Trace Function Rev

    21/34

    14.2. rst(P)(T)(recent such that)

    ( ( ))

    rst(P)(T)is the most recent event descriptor in T that satisfies P; it is undefined if thereis none. It can be defined as follows.

    rst(P)(T)

    ex(P)(T)

    ex(P)(T) P(r(T)) r(T)

    P(r(T)) rst(P)(p(T))

    14.3. ost(P)(T) (oldest such that)

    ( ( ))

    ost(P)(T) is the oldest event descriptor in T that satisfies P; it is undefined if there isnone. It can be defined as follows.

    ost(P)(T)

    ex(P)(T)

    ex(P)(T) P(o(T)) o(T)

    P(o(T)) ost(P)( s(T))

    14.4. et(P)(T)(extracted trace)

    ( ( ))

    et(P)(T) is a trace that contains the events from T that satisfy P in the order that theyappear in T. It can be defined as follows.

    et(P)(T)

    ex(P)(T) _

    ex(P)(T) P(o(T)) o(T).et(P)(s(T))

    P(o(T)) et(P)(s(T))

    14.5. irst(P)(T) (index recent such that)

    ( ( ))

    irst(P)(T)is the index of the most recent event in T that satisfies P.irst(P)(T)

    ex(P)(T) 0

    ex(P)(T) P(r(T)) length(T)

    P(r(T)) irst(P)(p(T))

    trace function 21/34 21 01 2006 19:03

  • 7/31/2019 Trace Function Rev

    22/34

    14.6. iost(P)(T) (index oldest such that)

    ( ( ))

    iost(P)(T)returns the index of the oldest event descriptor in T that satisfies P.

    iost(P)(T)

    ex(P)(T)

    ex(P)(T) P(o(T)) 1

    P(o(T)) 1+ iost(P)(s(T))

    15.Examples of the Trace Function Method

    15.1. Date module

    This example is a component for storing a date. For simplicity, the example assumesthat there are no illegal dates, i.e. we do not forbid 30 February 2344 as a date.Adding the arcane rules of our calendar would not enhance the tutorial value of thisintroductory example. This example exemplifies the most common type of object/component. These provide simple pairs of setters and getters.

    It should be noted that, contrary to what some have written, such interfaces do notimply that the external program pairs correspond to fields in the internal data structure.For example, we might implement this interface with an internal representation thatstored the number of days since an arbitrary date such as 10 February 1941 rather thanas two fields: month and year. This implementation would simplify many calculations(such as interest). As discussed in [Pa77], one could add further access programs such

    as one that calculated the number of days between two dates to make the interfaceproperly abstract.

    Although the internal data representation in this example is hidden, the state is not;the values of the output variables are sufficient to predict response to all future eventsequences. This means that we could have written a set of program-function tables13 todescribe its behaviour. The tables would be fundamentally different from those below;There would be one program-function table for each of the access programs and itwould show the effect of that program on all getter programs. In the method describedhere, there is one table for each output variable and the tables show the values of thosevariables. Later examples do have hidden state.

    Because the output of this component is determined by the most recent event thatchanged it, the output functions select that event from the trace and compute the valuethe input value had in that event. The TFM specification begins with the specification of

    the output variables and their types. It then describes the external programs that giveaccess to the data stored by the module and the corresponding event descriptors.Finally, it describes the value of each output variable as a function of the history.

    Output Variables

    Variable Name Type

    trace function 22/34 21 01 2006 19:03

    13 Pre/Post or predicate transformer notation could also be used to describe these functions.

  • 7/31/2019 Trace Function Rev

    23/34

    .day

    .month

    .year

    . Value

    Input Variables

    Variable Name Type

    PGM

    in1

    in2 date

    Access Programs

    In the following table, the column Oname (Object name) indicates whether thisprogram is a template for a class of object-specific programs. If Oname contains the of an object that has been created by NEWDATE and not destroyed byDELETEDATE, must be prepended to the name of the program. For example if we havecreated a date object, x, then to set the date of that object one must write x.SETDATEas the program name. Every objects trace begins with an event descriptor showing aninvocation of NEWDATE and ending eventually with an event descriptor showing aninvocation of DELETEDATE.

    Program Name Oname Value in1 in2 Abbreviated Event Descriptor

    SETDAY (PGM:SETDAY, in, day)

    SETMONTH (PGM:SETMONTH, in, month, )

    SETYEAR (PGM:SETYEAR, in, year)

    GETDAY (PGM:GETDAY, Value, day)

    GETMONTH (PGM:GETMONTH, Value, month)

    GETYEAR (PGM:GETYEAR, Value, year)

    NEWDATE (PGM:NEWDATE, , )

    DELETEDATE (PGM:DELETEDATE)

    COPYDATE (PGM:COPYDATE, )

    trace function 23/34 21 01 2006 19:03

  • 7/31/2019 Trace Function Rev

    24/34

    Auxiliary Functions

    day(T)

    (T = _) PGM(r(T) = NEWDATE 0

    (T = _)

    (PGM(r(T)) = SETDAY) in(r(T))

    (PGM(r(T)) = COPYDATE) day(in2(r(T))

    (PGM(r(T)) = DELETEDATE)

    (PGM(r(T)) = SETDAY

    PGM(r(T)) = COPYDATE

    PGM(r(T)) = DELETEDATE

    PGM(r(T) = NEWDATE )

    day(p(T))

    month(T)

    (T = _) PGM(r(T) = NEWDATE 0

    (T = _)

    (PGM(r(T)) = SETMONTH) in(r(T))

    (PGM(r(T)) = COPYDATE) month(in2(r(T))

    (PGM(r(T)) = DELETEDATE)

    (PGM(r(T)) = SETMONTH

    PGM(r(T)) = COPYDATE

    PGM(r(T)) = DELETEDATE PGM(r(T) = NEWDATE )

    month(p(T))

    year(T)

    (T = _) PGM(r(T) = NEWDATE 0

    (T = _)

    (PGM(r(T)) = SETYEAR) in(r(T))

    (PGM(r(T)) = COPYDATE) year(in2(r(T)))

    (PGM(r(T)) = DELETEDATE)

    (PGM(r(T)) = SETYEAR

    PGM(r(T)) = COPYDATE

    PGM(r(T)) = DELETEDATE

    PGM(r(T) = NEWDATE )

    year(p(T))

    trace function 24/34 21 01 2006 19:03

  • 7/31/2019 Trace Function Rev

    25/34

  • 7/31/2019 Trace Function Rev

    26/34

    Access Programs

    Program Name in Abbreviated Event Descriptor

    SET HR (PGM:SET HR, in, hr)

    SET MIN (PGM: SET MIN, in, min)

    INC (PGM:INC, hr, min)

    DEC (PGM:DEC, hr, min)

    Output Functions

    hr(T)

    PGM(r(T)) = SET HR 0 in(r(T)) < 24 in(r(T))

    (0 in(r(T)) < 24) hr((p(T)))

    PGM(r(T)) = SET MIN hr((p(T)))

    PGM(r(T)) = INC min(p(T))= 59

    hr(p(T))= 23 0

    hr(p(T))= 23 1+ hr((p(T)))

    (min(p(T))=59) hr((p(T)))

    PGM(r(T)) = DEC

    (min(p(T))= 0) hr((p(T)))

    min(p(T))= 0 (hr(p(T)))= 0 hr((p(T)))-1

    hr(p(T))= 0 23

    T= _ 0

    min(T)

    PGM(r(T)) = SET HR min(p(T))

    PGM(r(T)) = SET MIN 0 in(r(T)) 59 in(r(T))

    (0 in(r(T)) 59) min(p(T))

    PGM(r(T)) = INC min(p(T)) = 59 0

    (min(p(T))=59) min(p(T)) + 1

    PGM(r(T)) = DEC (min(p(T))= 0) min((p(T))) 1

    min(p(T))= 0 59

    trace function 26/34 21 01 2006 19:03

  • 7/31/2019 Trace Function Rev

    27/34

    T= _ 0

    15.3. A stack of limited range and depth

    This is a classic example of a module that is not state-apparent and the output candepend on events at the beginning of even the longest traces.

    The literature contains simpler specifications but they usually describe stacks withinfinite capacity and avoid some of the exception cases that make this example morerealistic. The stack described here can store a set of integer values between LB and UB(inclusive) and is limited to a depth d. If any invocation would violate these limits (e.g. topush an out of range value on a full stack or read a value from an empty stack), the

    event changes nothing except an exception class indicator.LB,UB, and d are integer parameters of the document. They must be assigned fixedvalues before realization of the component.

    While the output may depend on events that occurred far in the past, interveningevents may be irrelevant - either because they have no lasting effect in normal cases,because they were illegal program invocations, or because they were cancelled by alater event. Leaving these in the traces makes the specification more complex.Consequently, we have introduced a function, strip, from traces to traces, thatremoves such elements.

    Output Variables

    Variable Name Type

    top

    depth

    exc {none, range, depth, empty}

    Value

    Access Programs

    Program Name Value in Abbreviated Event Descriptor

    PUSH (PGM:PUSH, in, top, depth,exc)

    POP (PGM:POP, top, depth, exc)

    TOP (PGM:TOP, Value, exc)

    DEPTH (PGM:DEPTH, Value)

    Auxiliary Functions

    inrange(i) LB i UB

    noeffect(e)(PGM(e)=PUSH(inrange(in(e))) PGM(e)=TOP PGM(e) = DEPTH

    full(T) depth(T) = d

    empty(T) depth(T) = 0

    trace function 27/34 21 01 2006 19:03

  • 7/31/2019 Trace Function Rev

    28/34

    ps(T1,T2)

    T2 = _ T1

    (T2 _ ) noeffect(o(T2)) ps(T1,s(T2))

    (T2 _ )

    noeffect(o(T2))

    PGM(o(T2))=PUSH full(T1) ps(T1,s(T2))

    full(T1) ps(T1.o(T2),s(T2))

    PGM(o(T2))=POP empty(T1) ps(p(T1), s(T2))

    empty(T1) ps(T1, s(T2))

    strip(T) ps(_,T)

    Output variable functions

    top(T)

    strip(T) = _

    strip(T) _ in(r(strip(T)))

    Value(T)

    PGM(r(T))=TOP top(p(T))

    PGM(r(T))=DEPTH depth(p(T))

    PGM(r(T))=PUSH

    PGM(r(T))=POP

    depth(T)

    T = _ 0

    (T _)

    noeffect(r(T)) depth(p(T))

    noeffect(r(T))

    PGM(r(T))=POPdepth(p(T))= 0 0

    depth(p(T)) 0 depth(p(T)) - 1

    PGM(r(T))=PUSH

    depth(p(T))= d d

    depth(p(T)) d depth(p(T)) + 1

    trace function 28/34 21 01 2006 19:03

  • 7/31/2019 Trace Function Rev

    29/34

    exc(T)

    PGM(r(T))=PUSH

    inrange(in(r(T))) range

    inrange(in(r(T))) L(strip(p(T))) = d depth(L(strip(p(T))) = d) none

    (PGM(r(T))=POP

    PGM(r(T))= TOP)

    L(strip(p(T))) = 0 empty

    (L(strip(p(T))) = 0) none

    PGM(r(T))=DEPTH none

    15.4. A keyboard checking program.

    The following example, taken from [BPV05], describes a program designed to controlthe testing of keyboards before shipping. It has fairly complex logic because of the needto allow for human error and to test the keys in the sequence used to terminate the test.The behaviour is described completely by the tables below. The program output directsa human tester about the next key to strike. After each keystroke it may either indicate akey or declare that the keyboard has passed or failed.

    name meaning precise definition

    keyOK most recent key is theexpected one.

    r(T) = N(p(T))

    keyesc most recent key is the

    escape key

    r(T)=esc

    prevkeyOK the key preceding themost recent key was theexpected key

    r(p(T))=N(p(p(T)))

    prevkeyesc the key preceding themost recent key was theescape key

    r(p(T))=esc

    preprevkeyOK the key two keys beforethe most recent key wasthe expected key

    r(p(p(T)))=N(p(p(p ())))

    prevexpkeyesc. the key expectedprevious to the mostrecent key was the

    escape key

    N(p(p(T))) = esc

    The specification only covers traces during the test, not before it is started or after it isfinished. The empty cells in the table are cases that cannot arise because the conditionsin the column header and the row header cannot occur at the same time.

    The table below, which fits easily on one page, distils the contents of 20 pages thatwere found to be ambiguous, incomplete and inaccurate when we analysed them toproduce it.

    N(T) =

    trace function 29/34 21 01 2006 19:03

  • 7/31/2019 Trace Function Rev

    30/34

    T=_ (T= _)

    N(p(T))=1 1

  • 7/31/2019 Trace Function Rev

    31/34

    17.Acknowledgements

    We thank Tom Arbuckle, Adam Balaban, Darren Bane, Xin Feng, JiDong Huang,Zhiying Liu, Martin Maher, Julie Pichon, Colm Quinn, Elaine Roche, Assefa Semegnand Sergiy Vilkomir for numerous comments on earlier versions.

    18.References

    [BP77] Bartussek, W., Parnas, D.L., Using Assertions About Traces to Write AbstractSpecifications for Software Modules, UNC Report No. TR77-012, December1977, 26 pgs.

    [BPP 81] Britton, K.H., Parker, R.A., Parnas, D.L., A Procedure for Designing AbstractInterfaces for Device Interface Modules, Proceedings of the 5th International

    Conference on Software Engineering, March 1981, pp. 195-204.

    Reprinted as Chapter 15 in item [HW01]

    [BPV05] Baber, R., Parnas, D., Vilkomir, S., Harrison, P., O'Connor, T., "DisciplinedMethods of Software Specifications: A Case Study", Proceedings of theInternational Conference on Information Technology Coding and Computing(ITCC 2005), April 4-6, 2005, Las Vegas, NV, USA, IEEE Computer Society.

    [CP84] Clements, P.C., Parnas, D.L., Experience with a Module Interface SpecificationTechnique,Proceedings of International Workshop on Models and Languagesfor Software Specification and Design, 30 March 1984, Orlando, Florida, pp.70-73.

    [CPS84] Clements, P.C., Parker, R.A., Parnas, D.L., Shore, J., A StandardOrganization for Specifying Abstract Interfaces, NRL Report 8815, June 1984,19 pgs.

    [EWD68] 196: The structure of the 'THE'-multiprogramming system, Commun. ACM 11(1968), 5: 341346

    [GH78] Guttag, J. V., and Horning, J. J. "The Algebraic Specification of Abstract DataTypes", Acta Informatica 10, pp. 27-52, 1978

    [GM85] Gehani, N. & McGettrick A.D., Software Specification Techniques, AT&T BellTelephone Laboratories, 1985, (QA 76.6 S6437).

    [He80] Heninger, K.L., Specifying Software Requirements for Complex Systems: NewTechniques and their Application, IEEE Transactions Software Engineering, Vol.SE-6, January 1980, pp. 2-13.

    Reprinted as chapter 6 in [HW01]

    [HPS78] Heninger, K.L., Kallander, J., Parnas, D.L., Shore, J.E., SoftwareRequirements for the A-7E Aircraft, NRL Memorandum Report 3876, United

    trace function 31/34 21 01 2006 19:03

    http://www.sqrl.ul.ie/Papers/SQRLDell.pdfhttp://www.sqrl.ul.ie/Papers/SQRLDell.pdfhttp://www.sqrl.ul.ie/Papers/SQRLDell.pdfhttp://www.sqrl.ul.ie/Papers/SQRLDell.pdfhttp://www.sqrl.ul.ie/Papers/SQRLDell.pdf
  • 7/31/2019 Trace Function Rev

    32/34

    States Naval Research Laboratory, Washington D.C., November 1978, 523 pp.and subsequent versions published by the U.S. Naval Research Laboratory.

    [HS88] Hoffman, D., and Snodgrass, R. "Trace Specifications: Methodology andModels" IEEE Transactions on Software Engineering, Vol. 14, No. 9, pp.1243-1252, September 1988

    [HW01] Hoffman, D.M., Weiss, D.M. (eds.), Software Fundamentals: Collected Papersby David L. Parnas, Addison-Wesley, 2001, 664 pgs., ISBN 0-201-70369-6,.

    [IMS95] Iglewski, M., Mincer-Daszkiewicz, J., Stencel, K., "Case Study in Trace

    Specification of Non-deterministic Modules", in Proceedings of the CS&P'95

    Workshop, Warsaw, Poland, October 11-13,1995.

    [JPZ97] Janicki, R., Parnas, D.L., Zucker, J., Tabular Representations in RelationalDocuments, in Relational Methods in Computer Science, Chapter 12, Ed. C.Brink and G. Schmidt. Springer Verlag, pp. 184 - 196, 1997, ISBN3-211-82971-7.

    Reprinted as chapter 4 in item [HW01].

    [JS01] Janicki, R., Sekerinski, E., Foundations of the Trace Assertion Method ofModule Interface Specification, IEEE Transactions on Software Engineering,Vol. 27, No. 7, pp. 577-597, July 2001

    [LZ75] Liskov, B., and Zilles, S. "Specification Techniques for Data Abstractions" IEEETransactions on Software Engineering, Vol. SE-1, No. 1, pp. 7-19, March 1975

    [Pa72a] Parnas, D.L., A Technique for Software Module Specification with Examples,Communications of the ACM, 15, 5, May 1972, pp. 330-336.

    Republished in Writings of the Revolution, edited by Edward Nash Yourdon,Yourdon Press, 1982, pp. 5-18.

    Also in Software Specification Techniques edited by N. Gehani & A.D.McGettrick, AT&T Bell Telephone Laboratories, 1985, pp. 75-88 (QA 76.7S6437).

    Translated into Russian - book Danniye v yazikach programmirovaniaMoscow, Mir (Publishing House), 1984, pp. 9-24.

    [Pa72b] Parnas, D.L., On the Criteria to be Used in Decomposing Systems intoModules, Communications of the ACM, 15, 12, December 1972, pp.

    1053-1058.

    Translated into Japanese - BIT, vol. 14, no. 3, 1982, pp. 54-60.

    Republished in Classics in Software Engineering, edited by Edward NashYourdon, Yourdon Press, 1979, pp. 141-150.

    Republished in GreatPapers in Computer Science, edited by Phillip Laplante,West Publishing Co, Minneapolis/St. Paul 1996, pp. 433-441.

    Reprinted as Chapter 7 in [HW01]

    trace function 32/34 21 01 2006 19:03

  • 7/31/2019 Trace Function Rev

    33/34

    Reprinted in Software Pioneers: Contributions to Software Engineering,Manfred Broy and Ernst Denert (Eds.), Springer Verlag, Berlin - Heidelberg,2002, pp. 481 - 498, ISBN 3-540-43081-4.

    [Pa77] Parnas, D.L., Use of Abstract Interfaces in the Development of Software forEmbedded Computer Systems, NRL Report No. 8047, June 1977, 30 pgs.

    Reprinted in Infotech State of the Art Report, Structured System Development,Infotech International, 1979.

    [Pa92] Parnas, D.L., Tabular Representation of Relations, CRL Report 260, McMasterUniversity, Communications Research Laboratory, TRIO (TelecommunicationsResearch Institute of Ontario), October 1992, 17 pgs.

    [Pa93] Parnas, D.L., Predicate Logic for Software Engineering, IEEE Transactions onSoftware Engineering, Vol. 19, No. 9, September 1993, pp. 856 - 862

    Reprinted as Chapter 3 in [HW01]

    [PCW85] Parnas, D.L., Clements, P.C., Weiss, D.M., The Modular Structure ofComplex Systems, IEEE Transactions on Software Engineering, March 1985,Vol. SE-11 No. 3, pp. 259-266 (special issue on the 7th InternationalConference on Software Engineering).

    Also published in Proceedings of 7th International Conference on SoftwareEngineering, March 1984, pp. 408-417.

    Reprinted in IEEE Tutorial: Object-Oriented Computing, Vol. 2:Implementationsedited by Gerald E. Peterson, IEEE Computer Society Press,

    IEEE Catalog Number EH0264-2, ISBN 0-8186-4822-8, 1987, pp. 162-169. Reprinted as Chapter 16 in [HW01].

    [PM95] Parnas, D.L., Madey, J., Functional Documentation for Computer SystemsEngineering published in Science of Computer Programming(Elsevier) vol. 25,number 1, October 1995, pp 41-61.

    Also in Lecture Notes in Computer Science (75), Information SystemsMethodology, Proceedings ICS, Venice, 1978, Springer Verlag, pp. 211-236.

    Also in Software Specification Techniques edited by N. Gehani & A.D.McGettrick, AT&T Bell Telephone Laboratories, 1985, pp. 111-130 (QA 76.6S6437).

    Reprinted as Chapter 1 in [HW01].

    [PW89] Parnas, D.L., Wang, Y., The Trace Assertion Method of Module InterfaceSpecification, Technical Report 89-261, Queen's, Kingston, TRIO, October1989, 39 pgs.

    [Wa02] Wagner, E. C.. 2002 - Algebraic Specifications: Some Old History and NewThoughts. In Nordic Journal of computing, colume 9, pages 373 - 404.

    [Wa94] Wang, Y., "Specifying and Simulating the Externally Observable Behaviour ofModules", (Queens, Kingston Ontario, Ph.D. Thesis), CRL Report No. 292,

    trace function 33/34 21 01 2006 19:03

    http://www.ul.ie/http://www.ul.ie/http://www.ul.ie/http://%23hw09/http://%23hw09/
  • 7/31/2019 Trace Function Rev

    34/34

    McMaster University, CRL, Telecommunication Research Institute of Ontario(TRIO), Hamilton, Ontario, Canada, 1994.

    trace function 34/34 21 01 2006 19:03