next up previous
Next: Situations Up: Interface-Based Protocol Specification of Previous: Extending Interface Specification



An attribute (also known as a state function[38,33]) is an abstract property ascribed to zero or more role instances, and possibly assuming different values across time. In PSL, attributes are abstract functions of handle and/or other value type arguments. The relationship between abstract attributes and their implementations (if any) is outside the scope of PSL proper. For example, the attribute isOpen is a hypothetical function that might actually be computed or approximated as a side-effect-free procedure, a function whose value is deduced by an analytic tool, and/or a ``derived'' function that is symbolically definable or otherwise constrained in terms of other attributes. The use of an attribute in PSL does not commit implementations to ``know'' its values in any computational sense, and even if implemented, does not mandate that the value be computed by any component it describes.

In PSL/IDL, attributes are declared as auxiliary functions within the scope of a protocol module using normal IDL/C++ function syntax, and where all function arguments are explicit. (The IDL keyword attribute is not used in PSL to avoid conflict with its IDL usage in implicitly declaring ``get'' and ``put'' operations.) For example:

protocol module fm { boolean isOpen(File f); /*...*/ };

Event Predicates. A PSL event predicate is a special kind of attribute representing the issuance or reception of any kind of explicit communication among participants, including operation requests, operation replies, asynchronous messages, and exceptions. For each kind of message M possible in a system, we assume the existence of a corresponding record type MessageType that minimally includes fields describing the message ``selector'' (e.g., operation name) and arguments (if any). All messages are assumed to be handle-directed. A handle describing the intended receiver role is a required part of any communication. Similarly, messages corresponding to a procedural operation that returns a reply (or perhaps just a `` void'' completion indication) include a handle describing the ``return address'' of the caller. We also assume an abstract function reply[ msg ] that represents a reply message (not its issuance) of the appropriate type for a given procedural request msg, and a function throw[ msg ] that represents an exception reply message for a request.

Messages themselves are not used directly in PSL. Instead, PSL contains two families of special attribute functions, in and out. The construct in( m ) by( p ), where m is of some type MessageType and p is a handle value, denotes a context in which a particular message instance m has been received by participant p, and out( m ) by( p ) denotes a context in which m has been issued by p. The by( p ) suffixes are optional and seldom needed. When otherwise unconstrained, omission reflects lack of concern about which participant issues or receives a message.

PSL event predicates are otherwise treated as attribute functions that happen to have predefined characteristics. Event predicates are monotonic attributes, behaving as persistent ``latches''. Once out( m ) by( p ) is true for a particular m and p, it is true forever more; similarly for in( m) by( p ). This reflects the fact that events never ``unhappen''. Once a predicate describing the occurrence of an event becomes true, it never becomes false. Situations and rules may thus be phrased in terms of events that have occurred at any time [44].

PSL/IDL event predicates use IDL messages as arguments to in and out. PSL/IDL message types are abstractions of the CORBA Request type [51], with a shorthand handle-based message syntax delimited by angle-brackets:

m = < dest-> op( args) >

Here, m is an instance of an implicitly ``pattern-matched'' message type corresponding to the form of the message expression; dest is a handle indicating the destination role instance of the message; op is an operation name literal; and args are arguments, each of some value type as defined in a corresponding interface. Messages need not be named, and values are referenced directly rather than through the implicit fields of m. As a notational convenience, a reply or throw without a bracketed message argument refers to the most closely associated message whenever this is unambiguous. Examples:

 in( <aFile->write(c)> )          // write req received by aFile
 out( reply[<aFile->read()>](c) ) // c sent as reply to read 
 out( throw(exc) ) by(aFile)      // exc thrown by aFile

next up previous
Next: Situations Up: Interface-Based Protocol Specification of Previous: Extending Interface Specification

Doug Lea@Fri Mar 17 08:19:23 EST 1995