Data Type (ADT) school by building on top of universal algebra and ... theories for (parallel) programming languages [eg, Barringer and Kuiper 84; ... Intuitively, the middle theory and the two morphisms identify sub-components in which the.
to appear in Formal Aspects of Computing
TEMPORAL THEORIES AS MODULARISATION UNITS FOR CONCURRENT SYSTEM SPECIFICATION J.Fiadeiro* and T.Maibaum Department of Computing Imperial College of Science, Technology and Medecine 180 Queen's Gate, London SW7 2BZ, UK
In this paper, we bring together the use of temporal logic for specifying concurrent systems, in the tradition initiated by A.Pnueli, and the use of tools from category theory as a means for structuring specifications as combinations of theories in the style developed by R.Burstall and J.Goguen. As a result, we obtain a framework in which systems of interconnected components can be described by assembling the specifications of their components around a diagram, using theory morphisms to specify how the components interact. This view of temporal theories as specification units naturally brings modularity to the description and analysis of systems. Moreover, it becomes possible to import into the area of formal development of reactive systems the wide body of specification techniques that have been defined for structuring specifications independently of the underlying logic, and that have been applied with great success in the area of Abstract Data Types. Finally, as a discipline of design, we use the object-oriented paradigm according to which components keep private data and interact by sharing actions, with a view towards providing formal tools for the specification of concurrent objects.
1 Introduction In 1977, two seminal papers established crucial landmarks in the process of formalising systems specification: in [Burstall and Goguen 77], R.Burstall and J.Goguen introduce the first specification language - CLEAR, and in [Pnueli 77] A.Pnueli initiates the use of temporal logic for specifying concurrent systems. The development of specification languages is closely associated with the need for achieving modularity in formal software development. A specification written directly in some logic is an unstructured collection of formulae from which it is difficult to extract its meaning. Instead, Burstall and Goguen argue that the structure of a specification is more connected to the way the specification as a theory can be expressed as a combination of smaller, more tractable theories. The basic message of [Burstall and Goguen 77] is that the purpose of a specification language is to provide tools for putting small theories together to make larger specifications. Category theory is used for formalising these notions following the principle that "given a category of widgets, the operation of putting a system of widgets together to form some super-widget corresponds to taking the colimit of the diagram of widgets that shows how to interconnect them" [Goguen 89]. This dogma first appeared in the context of General Systems Theory [Goguen and Ginali 78], and is applied in this case to specifications of systems rather than "mathematical models" of systems. This view of the nature of the specification process leads intrinsically to modularity in specification in the sense that the components of a system may be specified separately and later on brought together to form the specification of a more complex system. On the other hand, this view of theories as formal specification units also leads to modularity in the verification process in the sense that the structure of a specification can be used to break down proofs into lemmas that may be proved locally as theorems of a component, and later on composed into properties of the global system. Subsequent work by Goguen and Burstall on institutions [Goguen and Burstall 84] and of other authors in what could be called "abstract specification theory" (e.g. [Fiadeiro and Sernadas 88; Gergely * On leave from Departamento de Matemática, Instituto Superior Técnico, Lisboa, Portugal, as a grantee of the Comission of the European Communities.
2
J.FIADEIRO AND T.MAIBAUM
and Úry 88; Maibaum 86]) has shown that many aspects of specification in the large, namely the ability to put together small specifications to form the specification of a complex system, depend only on some properties of the underlying logic. For instance, if the underlying consequence relation satisfies some structural properties, the category of specifications (as theory presentations) will be finitely cocomplete and, hence, we will be able to understand the process of specifying a system of interconnected components through colimits of diagrams in the category of specifications [Goguen and Burstall 84]. If the logic has the Craig Interpolation Property, we know that we can equip ourselves with well behaved notions of implementation and parameterisation [Maibaum 86], etc. Although this work led to the definition of specification techniques that are independent of the underlying logic (as long as it defines an institution) [eg, Sannella and Tarlecki 88], and that thus may be applied to many logical systems, these ideas have been pursued mainly within the so-called Abstract Data Type (ADT) school by building on top of universal algebra and equational logic. ADT specifications are essentially functional in the sense that they concentrate on the specification of the function that the system is supposed to realise, transforming values (inputs) into other values (outputs). This view is, however, rather limiting when it comes to specifying reactive systems [Pnueli 86], i.e. systems whose main rôle is to maintain an interaction with their environment and that, hence, cannot be characterised in terms of relations between input and output values. Instead, since [Pnueli 77], temporal logics have proved to be better suited for modelling the reactive aspects of systems (and, hence, concurrency) because they allow systems to be described in terms of their on-going behaviour. However, the early approaches failed to provide the desired degree of modularity in description and analysis. And, although several proposals have been put forward in the quest for compositional proof theories for (parallel) programming languages [eg, Barringer and Kuiper 84; Barringer 87; de Roever 85; Lamport 83], no attempt to adopt the above mentioned techniques of using theories as modularisation units for specification is known to the authors. The aim of this paper is to bring the two views together, showing that temporal logics may be defined that satisfy, to some extent, the required structural conditions of institutions and, hence, that temporal theories may be used as modularisation units for concurrent system specification. The temporal logic we shall work with adopts a (global) discrete linear time structure that is fairly close to those that have been used since [Pnueli 77], namely in [Barringer 87], thus allowing an easier assessment of the support for modular specification that we shall illustrate herein. There are, we feel, good reasons for considering this integration as more than a mere exercise in showing that institutions also apply to concurrent systems1. Firstly, by doing so, we immediately make available to the community the wide range of specification techniques (the "CLEAR tricks") that have been developed in an institution-independent way [eg, Sannella and Tarlecki 88]. These include techniques for horizontal structuring of specifications, i.e. structuring the specification at a given level of the development process ("abstract machine"), and also for vertical composition, i.e. for "implementing" the specifications on a level in terms of the specifications of the level below [Goguen 86]. Indeed, this view of theories as modularisation units for specification is particularly appealing in that it provides a uniform view of the development process, and leads naturally to modular verification techniques that can be automated (as shown in [Sannella and Burstall 83]). Secondly, there are some important distinctions between this approach and existing approaches to concurrent systems development, not so much in the logics themselves, but in the way they are used to support system specification. The adopted view of concurrent system specifications as structures (diagrams) of temporal theories favours the definition of interaction between components by saying 1 Which, anyway, was something that all of "us" were confident about...
TEMPORAL THEORIES AS MODULARISATION UNITS FOR CONCURRENT SYSTEM SPECIFICATION
3
which components they share (i.e., how they "interfere" with each other), rather than prescribing their relative behaviour with the usual program composition primitives such as sequencing, iteration, parallelism, …. As we shall see, in the categorial approach, two components described by theories T1 and T2 are connected by building a "middle theory" T together with two morphisms σ1: T→T1 and σ2: T→T2. Intuitively, the middle theory and the two morphisms identify sub-components in which the given ones are required to synchronise, i.e. they identify behaviour that is common to the given components. A naïve analogy with circuit design could identify the middle theory with a "cable" (a more or less structured collection of "wires"), the morphisms identifying the "pins" in each "chip" to which the cable is to be connected. This process of interconnecting components can be iterated, new components being added to our system by enriching the diagram that describes the system with new nodes (theories) and edges (morphisms) in a modular way. Moreover, it is always possible to collapse such a diagram into a theory (through its colimit), which corresponds to making the system into a module that can be used as a component of a yet more complex system. Synchronisation by sharing sub-components (which encompasses sharing actions and sharing "variables") provides parallelism as a default and seems to be a general and powerful enough mechanism to support other forms of interaction, namely asynchronous communication (via a third component - a messenger - with which the communicating components synchronise independently), or sequential composition (by identifying the last action of the first component, its "death" event, with the first action of the second one, its "birth" event). Moreover, the categorial approach makes it possible to formalise disciplines for organising/decomposing specifications. The basic motto of the categorial approach is that the structuring mechanisms that we obtain for specifications are "coded" in the way we are allowed to establish morphisms between them. That is, structure arises from the way components may be connected to other components. Indeed, we shall see how morphisms between theory presentations will enable us to model interaction between components and, thus, how well known paradigms of interaction, such as "shared variables" and "distributed variables", can be made "logical", i.e. built into the formalism. Addressing such disciplines is, we feel, a step as important as any other one in the formalisation of system specification, and one that raises challenges in the way we structure our logics. One such discipline for system decomposition is object-orientation (which can be seen to correspond, to some extent, to the "distributed variables" paradigm). Indeed, the notion of object as an "entity" that has an identity independent of its state, that encapsulates a collection of attributes (its private memory) which it is able to manipulate according to a circumscribed set of actions, and that is able to interact with other objects, has emerged as one of the most powerful abstractions for structuring systems design. By incorporating states and behaviour, objects are much more than just data. Hence, the concepts being developed for concurrent systems are needed for giving a proper formalisation of the notion of object. Therefore, and thirdly, particularising our approach to object-oriented specification, i.e. choosing object-orientation as the underlying discipline for decomposing specifications, seemed to be particularly relevant and timely. Ultimately, in this way, it will be possible to lift temporal logic to a framework able to compete with the Abstract Data Type school in addressing the whole system development cycle. In fact, the work that we shall report is part of an integrated research effort on object-oriented systems design that started with [Sernadas et al 87, 89a], and which is also addressing the semantic fundamentals of the notion of object [eg, Ehrich et al 90] as well as methodological aspects of objectorientation [eg, Sernadas et al 89b]. The logics that we have been developing for supporting objectoriented specification are somewhat more complex, involving deontic notions as well as action modalities besides temporal operators [Fiadeiro and Maibaum 90; Fiadeiro et al 90]. However, as we
4
J.FIADEIRO AND T.MAIBAUM
have mentioned, the structuring mechanisms are, in a sense, independent of the underlying logic and, hence, it seemed worthwhile reporting on the formalisation of objects as structuring units for concurrent systems specification based on a simpler logic, without dragging in all the machinery that we think is more appropriate for object description. Neverthless, there are many similarities between these logics [ibidem] and the one adopted herein, and we shall use the word "object" throughout as a synonym of system component, stressing that under the distributed variables paradigm, our specifications units are objects in the object-oriented sense. The paper will proceed as follows: in section 2, we shall address the specification of individual components (objects). Following the "institutional way", we start by introducing the notions of object signature and, for each signature, interpretation structure, language and satisfaction (truth) relation between interpretation structures and formulae. The temporal fragment of the language is fairly well known and, as such, we do not provide an axiomatisation for the temporal operators, but just for the notion of locality (data abstraction, encapsulation of a set of attributes). Then, in section 3, we show how we can put descriptions together in order to form the description of more complex objects (aggregation). First, we show how to define a category of object descriptions that is finitely cocomplete. Then, we show how interaction between objects can be expressed through diagrams. And, finally, we illustrate the use of diagrams (in the categorial sense) to describe the joint behaviour of objects taking into account their interaction. The well known example of the dining philosophers is used for illustration, including examples of derivation of properties that highlight the intrinsic modularity of the specification/verification techniques.
2 Describing individual components In this section, we present the logic in which we shall formalise the specification of individual components of systems (objects). As we have already mentioned, we see each object description as being a theory presentation in this logic. That is to say, an object description will consist of a signature (defining the specific vocabulary symbols that are relevant for the description of the object), and a collection of formulae of the language generated from the signature (the non-logical or extra-logical axioms of the description). Recognising the rôle of signatures as components of descriptions is very important because the signature of a description defines the boundaries of the object in the sense that it will limit the "things" we may refer to during its specification: when reasoning about a component, we must use the language of that component. In other words, a "syntactical locality" is immediately enforced. Indeed, we shall see in section 3 that in order to specify interaction between two objects we shall have to relate the signatures of the two objects so that we may state what they have in common. Furthermore, we shall see how signatures play a fundamental rôle in the formalisation of locality (encapsulation). We must point out that we are not proposing a specification language but rather a formalism on top of which a language for the specification of systems may be defined. The point is that many of the "specifications" that we shall present may seem to contain too much unnecessary detail, that could perhaps have been kept implicit. However, because not every formalism is suitable for supporting modularity in specification, we have to concern ourselves first with choosing/defining the right formalism before we decide on which specification gimmicks are necessary from a pragmatic point of view. Naturally, there is an inherent pragmatics to every formalism, and we shall provide a flavour of the style of verification that it supports, especially in what concerns modularity when reasoning about complex systems.
TEMPORAL THEORIES AS MODULARISATION UNITS FOR CONCURRENT SYSTEM SPECIFICATION
5
2.1 Object signatures and interpretation structures An object signature must be comprised of at least three different parts: the universe, the attribute structures, and the action structures. The universe part includes the information that is stateindependent and that gives, so to say, the data context in which the object is placed. It can be seen as defining the frame of reference with respect to which change is to be measured. The attributes keep the information that is state dependent. Examples of these structures can be found under different names given according to the "nature" of the object: e.g., program variables, database attributes, or frame slots. The actions account for transformations on attributes ("methods") as well for interaction with other objects. Definition 2.1.1 (object signature): An object signature is a triple (Σ,Α,Γ) where • Σ=(S,Ω) is a signature (the universe signature) in the usual algebraic sense [Ehrig and Mahr 85], i.e. S is a set (of sorts) and Ω is a S*×S-indexed family (of function symbols). • Α is a S*×S-indexed family (of attribute symbols). In programming terms, a nullary attribute symbol corresponds to a program variable, whereas non-nullary attribute symbols can be associated with more complex data structures such as arrays. • Γ is an S*-indexed family (of action symbols). The parameters of an action symbol may stand, for instance, for the data that is necessary in order to define the effects of the actions on the attributes, or that is to be transmitted/received as part of a communication.
º
The families Ω, Α, and Γ are assumed to be disjoint and finite (i.e., there are only a finite number of function, attribute and action symbols). The fact that we have three separate components in a signature has a logical meaning in the sense that they will play different rôles in the logic: for instance, the universe parameters will be assigned a rigid interpretation (time-independent), whereas the attribute parameters will be non-rigid. On the other hand, actions will have a distinguished rôle in the formalisation of the notion of locality. Naturally, we could say that universe and attribute symbols are just function symbols, and action attributes are just boolean function symbols. However, by assigning them different categories in a signature, we shall be able to make their properties logical rather than require the specifier to axiomatise explicitly these properties (rigidity, etc). Indeed, the choice of the linguistic structures of a formalism is, in our opinion, one of the major activities when engineering a logic for supporting a discipline of system design. Comparing with [Barringer and Kuiper 84], this notion of signature provides the categories of symbols of the language used therein for specifying system components: the universe signature provides the constant and global symbols and the family Α provides the state variables. As in [Barringer 87; Hoare 85], Γ corresponds to the alphabet of the component (process, object). Still comparing with [Barringer 87], it is also interesting to point out that the notion of signature captures the notion of "ownership" of attributes that in [ibidem] is treated with a declaration owns. The treatment of the notion of ownership through signatures has the advantage of providing a "syntactical locality" in the sense that the reference to a symbol in a specification is only possible if that symbol is declared in the signature, which implies that any sharing must be explicitly indicated through morphisms (see section 3). That is, we bring a formal notion of scope into the formalism. As an illustration of our approach, we shall use a simplification of the famous example proposed by Dijkstra: the dining philosophers. Following our object-oriented way of specification, we would like to be able to obtain a description of the behaviour of a society of philosophers sharing forks around a
J.FIADEIRO AND T.MAIBAUM
6
table from the separate description of the behaviour of philosophers and forks through some kind of operation on descriptions. Looking at the local aspects that characterise philosophers and forks, we could be led to the definition of two signatures PHIL and FORK: PHIL
FORK
universe signature:
universe signature:
sorts: BOOL
sorts: BOOL
operations: true, false: BOOL
operations: true, false: BOOL
attribute symbols:
attribute symbols:
eating?, hungry?: BOOL
busy?: BOOL
action symbols:
action symbols:
bc-hungry, forks↑, forks↓
up, down
Intuitively, eating? indicates whether the philosopher is eating or thinking, and hungry? indicates whether the philosopher is hungry. These are attributes (non-rigid designators, "program variables"): their values depend on the current state. The action symbols are self-explanatory: a philosopher can become hungry, pick up the forks and put down the forks. For the sake of keeping the example simple, we are assuming that a philosopher picks up or puts down both forks simultaneously. This will prevent their joint behaviour from deadlocking but will still allow us to illustrate the detection of starvation. With respect to forks, the attribute busy? indicates whether the fork is being used. The action symbols are also intuitive: they stand for forks being picked up and put down. However, we should point out that these two signatures are, so far, independent and unrelated. We shall see in section 3 how they can be related through morphisms expressing how a philosopher uses a fork. Because the example is quite simple, we have only used nullary attribute and action symbols. However, in some cases [e.g. Fiadeiro and Maibaum 90], non-nullary symbols are useful as mentioned in 2.1.1: for instance, non-nullary attribute symbols are useful for modelling more complex data structures (arrays), and non-nullary action symbols for modelling exchange of values during interaction. A semantic interpretation structure for an object signature is given by an algebra that interprets the universe parameters, a mapping that gives the values taken by the attributes at each instant, and a mapping that gives the actions that will occur at each instant: Definition 2.1.2 (θ-interpretation structures): A θ− interpretation structure for a signature θ=(Σ,Α,Γ) is a triple (U,A,G) where: • U is a Σ-algebra, i.e. to each sort symbol s∈S a set sU is assigned, and to each function symbol f∈Ω,s a function fU: s1U ×...×snU → sU is assigned; • A maps f∈Α ,s to A (f): s1U ×...×snU × → sU ; We shall often use A(f)(i) for i∈ to denote the function λ(b1,…,bn).A(f)(b1,…,bn,i). • G maps g∈Γ to G(g): s1U ×...×snU → ℘( ).
¯
¯
¯
º
These interpretation structures are more or less standard. We take the natural numbers as the underlying temporal domain, i.e. we adopt linear and discrete time. The mapping A defines the "state" reached at each instant of time, i.e. it gives the value that the attributes take at each point in time. Finally, action symbols are interpreted as defining predicates over time instants. (The denotation of an
TEMPORAL THEORIES AS MODULARISATION UNITS FOR CONCURRENT SYSTEM SPECIFICATION
7
action symbol is the set of instants during which instances of the action occur.) The intended interpretation is that temporal succession is an abstraction of an atomic state transition according to some observer. The interpretation of the action symbols gives for each instant the set of actions that take place during that instant. We shall say that the actions in each such set occur concurrently during that instant. For instance, it is possible to define an interpretation structure such that every instant witnesses the occurrence of every action, corresponding to an observer that cannot discriminate between the actions that may occur. However, in most cases, such an observer will not provide a model of a specification. Indeed, as we shall detail later on, the ability of actions to occur concurrently is restricted through the axioms of a specification defining their effects on the attributes as well as restrictions and requirements on their occurrence. That is, the axioms of a specification define the notion of causality/interference that constrains the way the system may evolve in terms of the actions that it may perform. On the other hand, it is possible that an instant does not belong to any of the interpretations of the action symbols. These instants denote state transitions in which the object is not engaged. They may be seen to be performed by the "environment", i.e. by any other component in the system that was not required to synchronise with the object at that step. Indeed, using the terminology of [Barringer 87], we are dealing with open semantic structures in the sense that we are considering an object as embedded in a wider environment. This open semantics also justifies the adoption of an infinite temporal domain: even if the object has a finite lifetime, we may assume that the environment will always be able to progress (e.g., through some clock mechanism). Following [Barringer and Kuiper 84; Lamport 83], when specifying one module of a system, one must include constraints on what other parts of the system are allowed to do. In the object-oriented approach that we are adopting, this constraint is given by the locality requirement (encapsulation): as mentioned in the introduction, objects have an intrinsic notion of locality according to which only the actions declared for an object can change the values of its attributes. This notion of locality leads to the following definition: Definition 2.1.3 (loci): Given an object signature θ=(Σ,Α,Γ) and a θ-interpretation structure (U,A,G), let E ={i∈ i∈G (g)(a1,…,an) for some g∈Γ, (a1,…,an)∈s1U ×...×snU}. That is, E consists of those instants during which an action of the object occurs, i.e. these instants denote state transitions in which the object will be engaged. Those state transitions are said to be witnessed by θ. The θ-interpretation structure (U,A,G) is said to be a locus iff, for every instant i∉E and every f∈Α, A (f)(i) = A (f)(i+1).
¯
º
That is to say, the values of the attributes of the object can only be changed during witnessed transitions, i.e. due to the occurrence of one of the actions of the object. In other words, nonwitnessed transitions are silent in the sense that they have no effect in the local state of an object. Again, using the terminology of [Barringer 87], non-witnessed transitions are identity steps. Hence, although we are working with global instants of time (in the sense that the object is not necessarily engaged in every transition), we are requiring that to these global instants correspond "local" (private) states (identifying, as usual, states with the interpretations of the attribute symbols). Hence, the components (objects) that we specify are "context" independent in the sense that state information is localised rather than shared between components, a strategy for achieving high levels of modularity that can be traced back to [Parnas 72]. Naturally, this notion of θ-locus does not formalise locality per se: it must be understood in conjunction with the notion of object description and of morphism between descriptions to be given in
J.FIADEIRO AND T.MAIBAUM
8
section 3. Rather, our ultimate purpose is to provide a formalisation of locality as a criterion to have composable object descriptions as specification modules, for which the notion of θ-locus given above provides a correct model-theoretic basis. We shall see later on that the notion of morphism of object descriptions will indeed capture the desired notion of encapsulation so that an object cannot refer to the attributes of another object (for "read" or "write" purposes) without incorporating it as a component. This means that we are not allowing for attributes to be observed "outside" an object, only by objects of which it is a component. Hence, the adoption of a global notion of time is not violating our claims for capturing locality. Locality is, from our point of view, concerned with theories (descriptions, specifications) rather than models. It is the specification activity that we want to make modular and, hence, be disciplined by enforcing a notion of locality. A specifier will not actually manipulate models but theories. And it seems fairly natural that in order to achieve modularity at the theory level, models will have, dually, to be global as the work reported in [Barringer and Kuiper 84; Barringer 87] has shown. Finally, we should stress that we are abstracting from the internal structure of the actions and regarding them as indivisible units. Indeed, we shall be addressing only horizontal structuring, i.e. the structuring of specifications in a fixed layer of the development process by connecting objects via their abstract properties (descriptions) alone. Their internal structure, showing how objects are "implemented" in terms of "lower level" objects (i.e. "closer" to the intended implementation layer), is hidden for this purpose. Hence, connecting objects is done at each layer for the fixed granularity that is given by the actions that were declared for the objects. Naturally, formal techniques for supporting vertical structuring, i.e. for supporting the "implementation" of abstract objects on top of more concrete ones are necessary, but we shall not address them in this paper. See [Fiadeiro and Maibaum 90] for preliminary results in that direction.
2.2 Object descriptions In order to describe an object, we shall use a temporal language similar to those that have been used in the area. We shall assume a collection ξ of variables (distinct from the attribute and action symbols). Given an object signature, by a classification Ξ we mean a partial function ξ→S (S being the set of sorts of the universe signature). We shall also denote by Ξ the S-indexed set given by Ξ s={x∈ξ | Ξ(x)=s}. Definition 2.2.1 (terms) Given an object signature θ=(Σ,Α,Γ) and a classification Ξ, we define inductively the S-indexed set of terms TRθ(Ξ) as follows: • variables: if Ξ(x)=s, then x is a term in TRθ(Ξ)s; • if f∈Ω,s and ti are terms in TRθ(Ξ)si then f(t1,…,tn)∈TRθ(Ξ)s; • if f∈Α,s and ti are terms in TRθ(Ξ)si then f(t1,…,tn)∈TRθ(Ξ)s; • if t∈TRθ(Ξ)s then (Xt)∈TRθ(Ξ)s (Xt reads "t next"). Given a θ−interpretation structure S= (U,A,G ), a classification Ξ, and an assignment A for Ξ (mapping each set Ξ s to sU ) each term t∈TR θ (Ξ) s defines a mapping t S,A : → sU (its interpretation) as follows: – if x∈Ξ s, x S,A(i)=A(x); – if f∈Ω ,s, f(t1,…,t n) S,A (i) = fU ( t1 S,A (i),…, tn S,A (i)); – if f∈Α ,s, f(t1,…,t n) S,A (i) = A (f)( t1 S,A (i),…, tn S,A (i),i); – X t S,A (i) = t S,A (i+1);.
œ“
œ“
œ “
œ“
œ œ
“ “
œ “ œ “
œ “ œ “
¯
TEMPORAL THEORIES AS MODULARISATION UNITS FOR CONCURRENT SYSTEM SPECIFICATION
9
Notice how all the symbols belonging to the universe signature are rigid designators, i.e. their interpretation is state-independent (the interpretation of a symbol f in the algebra U is denoted by fU). In particular, variables are assigned a constant element of the domain: we recall that these are not meant as "program variables" (which are given herein through attributes) but as "logical variables". This is an important distinction: attributes are meant to represent the state component ("memory") of the object, and can be qualified with temporal operators, whereas variables provide us with a means of quantifying over values (data). Finally, Xt denotes at each instant the value that t denotes at the next instant. (See [Fiadeiro and Sernadas 90] for the application of other modal operators to terms.)
º
Definition 2.2.2 (formulae): Given a classification Ξ, we shall use as atomic formulae over Ξ: • g(t1,…,tn) for g∈Γ, and ti terms in TRθ(Ξ)si (action predicates); • (t1=st2) for t1 and t2 terms in TRθ(Ξ)s for some s∈S (equality) • BEG (denoting the beginning of time) As constructors of formulae we shall use the usual propositional connectives (→ will stand for implication), the first-order quantifiers, and the usual temporal (modal) operators. We shall not debate which temporal operators are necessary, as we shall not be concerned with expressive power. However, we shall assume that the temporal operator X ("next", or "tomorrow") is either primitive or derivable as it will be necessary in order to axiomatise locality. The temporal operator F ("eventually", "sometime in the future") will also be used in the examples. The satisfaction of a formula by a structure S and an assignment A at time i is defined as follows for the atomic formulae: – g(t1,…,tn) is satisfied by S and A at i iff i∈G (g)( t1 S,A(i),…, tn S,A(i)); – (t1=st2) is satisfied by S and A at i iff t1 S,A(i)= t2 S,A(i); – BEG is satisfied by S and A at i iff i is 0 The satisfaction of the non-atomic formulae is defined as usual. For instance, – Xp is satisfied by S and A at i iff p is satisfied by S and A at i+1; – Fp is satisfied by S and A at i iff p is satisfied by S and A at some j≥i;
œ“ œ“
œ“
œ“
Finally, a formula is true in a θ-structure iff it is satisfied by every assignment A and instant i.
º
We define the notion of object description as a theory presentation in this logic: Definition 2.2.3 (descriptions): An object description is a pair (θ,Φ) where θ is an object signature and Φ is a (finite) set of θ-formulae (the axioms of the description). We call a θ-locus that makes all the formula of Φ true a model of the description.
º
As an example, consider the description of philosophers. Besides the axioms on the (data) universe, such as (true ≠ false) we could have: p1)
bc-hungry → Xeating? = eating?
p8)
bc-hungry → hungry? = false
p2)
forks↑ → Xeating? = true
p9)
forks↑ → hungry? = true
p3)
forks↓ → Xeating? = false BEG → eating? = false
p10)
forks↑ → eating? = false
p4)
p11)
forks↓ → eating? = true
p5)
bc-hungry → Xhungry? = true
p12)
hungry?=true → Fforks↑
p6)
forks↑ → Xhungry? = hungry?
p13)
hungry?=false → Fbc-hungry
p7)
forks↓ → Xhungry? = false
J.FIADEIRO AND T.MAIBAUM
10
These axioms are more or less intuitive, and are to be regarded as holding at all times. For instance, with p1 we are expressing that the value of eating? does not change when a philosopher becomes hungry, and with p2 we are expressing that the value of eating? after picking up the forks is true. Also notice that p4 gives an "initialisation" condition: we are requiring that, at time zero, a philosopher be thinking (i.e., not eating). Axioms p8-p11 give safety conditions on the occurrence of the actions. For instance, with p9 we are saying that a philosopher may only grab the forks when he is hungry. On the other hand, p12 and p13 give liveness requirements: with p13 we are requiring that, when not hungry, a philosopher will eventually become hungry. In the same way, p12 requires that a hungry philosopher will eventually grab his forks. This theory presentation describes the behaviour we intend a philosopher to have whatever the environment he is put in, i.e. whatever the objects he is put in interaction with. However, we shall see in section 3 that, as could be expected, when putting several objects together to form a community, an object will tend to have more properties (i.e., less interpretation structures will be models of the community than of the object). In the extreme case, we may end up with an inconsistent specification meaning that the objects we have specified are not "sociable" (have an incompatible behaviour). The behaviour of a fork could be described as follows: f1)
down → Xbusy? = false
f4)
up → busy? = false
f2)
up → Xbusy? = true BEG → busy? = false
f5)
down → busy? = true
f3)
It is important to stress that the above descriptions of the behaviour of philosophers and of forks are totally independent from each other. Signatures define the vocabulary of the language that we have available for specifying an object, which implies that we are not allowed to refer to parts of the specification of another object unless these are reflected somehow in the signature of the former. The notion of morphism to be introduced in section 3 will clarify this point. Hence, each theory presentation is the description of a component per se. The only requirement with respect to the "environment" is given by the locality principle: attributes are local to an object. However, this requirement is built into the logic in the sense that it does not need to be explicitly given as part of each specification. We shall see in section 3 how we can compose theory presentations into descriptions of more complex systems consisting of several interconnected sub-components. We shall then see how concurrency between the different components is captured in our formalism. For the time being, notice that the specification of the effects of the actions on the attributes, and of restrictions and requirements on their occurrence, restricts their ability to occur concurrently. Indeed, the axioms of a specification may impose that two actions interfere with each other and, hence, that no observer may witness their concurrent execution. This is the case, for instance, of the up and down actions of forks. Because they have opposite effects on the attribute busy?, no instant may belong to both actions. That is, no time instant may witness their concurrent execution: the attribute busy? provides any observer with the means to discriminate their occurrences. This may be proved by deriving ¬(up ∧ down)
TEMPORAL THEORIES AS MODULARISATION UNITS FOR CONCURRENT SYSTEM SPECIFICATION
11
as a theorem of the description of forks. This can be done as follows: 1. up → busy?=false
f4
2. down → busy?=true
f5
3. ¬(up ∧ down)
1, 2, PC
For simplicity, by PC we are referring to a step that can be justified by a rule of the propositional calculus. Hence, the axioms of a description define the notion of causality/interference that constrains the way the system may evolve in terms of the actions that it may perform, rather than prescribe a specific thread of control. A (Galois) correspondence between causality and temporal evolution will thus be achieved in terms of the relationship between a description (causality) and its models (temporal evolutions). But what is important to stress is that, from this point of view, the specifier will provide a notion of causality through his description, and not directly a specific sequence of actions. Although a sequential behaviour may be obtained locally (as in the case of forks and, indeed, philosophers), these are the exceptions rather than the rule.
2.3 Reasoning about local descriptions In order to reason about the properties of an object description, it is convenient to have a syntactical counterpart of the "in a model" notion of consequence which can be given in terms of sequents of formulae over the same signature: Definition 2.3.1 (assertions): If Φ is a (finite) set of formulae over a signature θ, and p is also a formula over θ, (Φ ⇒θ p) is an assertion. Such an assertion is said to be valid iff every θ−locus that makes all the formulae in Φ true also makes p true.
º
We shall often use names to denote object descriptions and abbreviate assertions by using these names as in (PHIL ⇒ p) instead of (Φ(PHIL ) ⇒ θ(PHIL) p) where (θ(PHIL ),Φ(PHIL )) is the description of philosophers. The properties of an object description (θ,Φ) are just the formulae p for which we can prove that the assertion (Φ ⇒θ p) is valid, i.e. they are the theorems of the theory presentation (θ,Φ). Notice (2.2.2) that all the formulae in Φ are assumed to be satisfied at all times so that formulae p for which (Φ ⇒θ p) is valid state properties that hold at any time during the evolution of the object described by (θ,Φ). Because the notion of validity of an assertion is defined over loci and not over interpretation structures in general, an axiomatisation for this consequence relation must provide rules not only for the connectives used to build formulae, but also for the locality requirement. Again, we shall not discuss the axiomatisation of the temporal operators herein. With respect to the locality requirement, it is easy to see that it is captured by the following axiom: for every signature θ=(Σ,Α,Γ),
∨
∧
⇒θ (( g∈Γ (∃xg)g(xg)) ∨ (a∈Α(∀xa)(Xa(xa) = a(xa))))
J.FIADEIRO AND T.MAIBAUM
12
where for each symbol u, xu is a tuple of variables (all distinct) of the appropriate sorts. This formula tells us that either the next transition will be performed by one of the actions of the object, or else every attribute will remain invariant. In [Barringer 87], this last member of the disjunction (expressing invariance of the attributes) is used to replace the proposition denoting a transition not performed by the component (an identity step). Notice that this formula is finite because Α and Γ are also finite (cf definition 2.1.1). This rule also shows why it is important to index the symbol ⇒ with the signature: essentially, the rule relates the action and the attribute symbols of a signature. It also shows that action and attribute symbols have different logical rôles in the formalism, thus justifying the separation between action symbols and (boolean) attribute symbols. From this axiom, it is possible to derive a rule that will assist us in proving safety properties under locality. Define the set of local terms as follows: Definition 2.3.2 (local terms) Given an object signature θ and a classification Ξ, we define inductively the S-indexed set of local terms LTθ(Ξ) as follows: • if Ξ(x)=s, then x is a term in LTθ(Ξ)s; • if f∈Ω,s and ti are terms in LTθ(Ξ)si then f(t1,…,tn)∈LTθ(Ξ)s; • if f∈Α,s and ti are terms in LTθ(Ξ)si then f(t1,…,tn)∈LTθ(Ξ)s.
º
That is, we omit the temporal operator. Then, we have Let p be a formula, t1,…,tn local terms over Ξ. For each g∈Γ, let xg be a tuple of variables of the appropriate sorts, and assume that they do not occur in Ξ. Then, {(g(xg) → p) | g∈Γ}, (
∧ (Xt = t ) → p) ⇒
1≤i≤n
i
i
θ
p
That is to say, in order to derive a property, it is enough to derive it assuming that either the next state transition will be witnessed by the object, i.e. that the object will be engaged in the state transition through one of its actions (first set of premisses) or that a chosen set of local terms will be kept invariant (last premiss). Any set of local terms will do. Again, we stress that this rule is finitary because the set of action symbols Γ is finite. For instance, let us prove that ((eating?=true) → (hungry?=true)) is a property of the behaviour of philosophers. We shall often abbreviate propositions (b=true) where b is a boolean term to b alone and, hence, write (eating? → hungry?) instead. The idea is to prove this property by induction using the rule (p → Xp), (BEG → p) ⇒θ p which should be derivable from the temporal axiomatisation. This rule says that we may infer a property p from the fact that it is a temporal invariant and that it holds in the initial state. (We recall that ⇒ θ gives consequence "in a model", i.e. the premisses are assumed to be satisfied at any possible instant and we derive the satisfaction of the conclusion at any possible instant). By applying this rule, we are left to prove PHIL ⇒ ((eating?→hungry?) → X(eating?→hungry?)) PHIL ⇒ (BEG → (eating?→hungry?))
TEMPORAL THEORIES AS MODULARISATION UNITS FOR CONCURRENT SYSTEM SPECIFICATION
13
The second assertion is trivial to prove using p4. So, let us concentrate on the first one. We shall use the locality rule instantiating t1 to eating? and t2 to hungry?:
⇒PHIL
bc-hungry → ((eating?→hungry?)→X(eating?→hungry?))
(A)
forks↑ → ((eating?→hungry?)→X(eating?→hungry?))
(B)
forks↓ → ((eating?→hungry?)→X(eating?→hungry?))
(C)
((Xeating?=eating?)∧(Xhungry?=hungry?)) → ((eating?→hungry?)→X(eating?→hungry?))
(D)
((eating?→hungry?)→X(eating?→hungry?))
The last premiss (D) is trivial to prove. So, we are left to prove the first three: (A) 1. bc-hungry → Xhungry?=true
axiom p5
2. bc-hungry → (Xeating?→Xhungry?)
1, PC
3. bc-hungry → X(eating?→hungry?)
2, monotonicity of X
4. bc-hungry → ((eating?→hungry?)→X(eating?→hungry?))
3, PC
(B) 1. forks↑ → Xhungry?=hungry?
axiom p6
2. forks↑ → hungry?=true
axiom p9
3. forks↑ → Xhungry?=true
1, 2, transitivity of =
4. forks↑ → X(eating?→hungry?)
3, PC
5. forks↑ → ((eating?→hungry?)→X(eating?→hungry?))
4, PC
(C) 1. forks↓ → Xeating?=false
axiom p3
2. forks↓ → X(eating?→hungry?)
2, PC
3. forks↓ → ((eating?→hungry?)→X(eating?→hungry?))
3, PC
Safety properties are typically proved like this one, i.e. by combining temporal induction and locality. Notice the rôle of the action predicates under the locality principle: they allow us to analyse transitions by cases. Each action symbol gives us a case to analyse. The last case corresponds to silent transitions, i.e. to transitions in which the object is not involved. Several liveness properties may also be derived from p12 and p13. For instance, we shall have PHIL ⇒ (hungry?=true → F(eating?=true)) PHIL ⇒ (hungry?=false → F(hungry?=true))
and, PHIL ⇒ F(eating?=true)
This is a true liveness property: a philosopher will be recurrently eating!
14
J.FIADEIRO AND T.MAIBAUM
3 Putting components together We recall that our main motivation in this paper is to approach concurrent systems specification by, borrowing the famous motto of Burstall and Goguen [Burstall and Goguen 77], "putting theories together to make specifications". That is to say, our aim is to provide a modularisation unit for concurrent systems specification based on the theory presentations of any appropriate logic. In the previous section, we have defined the syntax and semantics of one such logic, and shown how a (primitive) system component could be described as a theory presentation. See [Fiadeiro and Maibaum 90] for a different logic of objects. In this section, we show how such descriptions can be put together in order to provide the specification of systems of interconnected components, and how concurrency in particular is supported.
3.1 The category of object descriptions From a formal point of view, we have already mentioned that we shall follow the dogma being preached by J.Goguen: "given a category of widgets, the operation of putting a system of widgets together to form a super-widget corresponds to taking a colimit of the diagram of widgets that shows how to interconnect them" [Goguen 89]. That is to say, having developed a collection of theories that act as descriptions of objects, we can use these theories to describe a more complex system by assembling as nodes of a diagram as many instances of these theories as required, and by using morphisms between these theories as edges of the diagram in order to establish the required interconnections. If the category is well behaved (is finitely cocomplete) such a diagram may be collapsed to another theory that provides the description of the complex system as an object itself, and that can then be used in order to derive properties of the global system, or as a node in another diagram, i.e. as a component of another system. Hence, in order to obtain the theory presentations of our logic as modularisation units for concurrent system specification, we have to provide a notion of morphism between theory presentations and prove that the resulting category allows for such colimits to be computed. Morphisms between theory presentations define the notion of structure that our formalism provides for specification. As structure-preserving mappings, morphisms establish the relationship that must exist between two object descriptions so that one of them may be considered as a component of the other. Intuitively, this corresponds to the notion of interpretation between theories used, for instance, in [Veloso and Pequeno 78]. Using the notion of institution put forward in [Goguen and Burstall 84], this relationship consists of a translation between the languages of the two descriptions (a signature morphism) such that the theorems of one of them are translated to theorems of the second one. That is, we take the preservation of theorems (the meaning of a theory presentation) as the criterion for considering that a theory presentation describes a component of a system described through another theory presentation. Naturally, it is possible to restrict the properties that we actually want to preserve along a morphism, namely only safety or liveness properties, leading to different notions of structure. Herein, we shall require the preservation of both safety and liveness properties. Definition 3.1.1: Given two object signatures θ 1=(Σ 1,Α 1,Γ 1) and θ 2=(Σ 2,Α 2,Γ 2), a morphism σ from θ1 to θ2 consists of • a morphism of algebraic signatures συ: Σ1→ Σ2; • for each f: s1,…,sn→s in Α1 an attribute symbol σα(f): συ(s1),…,συ(sn) → συ(s) in Α2; • for each g: s1,…,sn in Γ1 an action symbol σγ(g): συ(s1),…,συ(sn) in Γ2.
º
TEMPORAL THEORIES AS MODULARISATION UNITS FOR CONCURRENT SYSTEM SPECIFICATION
15
That is to say, we are merely requiring that a signature morphism identifies the symbols in θ2 that are used to interpret (implement) the symbols of θ1. This is the "obvious" notion of signature morphism. It is easy to prove: Proposition 3.1.2: Object signatures and signature morphisms constitute a category SIGN.
º
The translation of formulae associated with a signature morphism is defined as follows: Definition 3.1.3: Given a signature morphism σ: θ1→θ 2 • given x∈Ξs, σ(x) is x • if f∈Ω,s then σ(f(t1,…,tn)) is συ(f)(σ(t1),…,σ(tn)) • if f∈Α,s then σ(f(t1,…,tn)) is σα(f)(σ(t1),…,σ(tn)) • σ(Xt) is (Xσ(t)) • • • •
if g∈Γ then σ(g(t1,…,tn)) is σγ(g)(σ(t1),…,σ(tn)) σ(t1=t2) is (σ(t1)=σ(t2)) σ(Xp) is (Xσ(p)) and similarly for the other connectives
º
Based on these notions of signature morphism and formula translation, we would like to define a morphism between two descriptions (θ 1,Φ 1) and (θ 2,Φ 2) as a signature morphism that induces a property preserving translation, i.e. such that for every formula p for which (Φ 1 ⇒θ1 p) is valid, (Φ2 ⇒ θ2 σ(p)) is also valid. Because proving the existence of a morphism in this way requires the derivation of an infinite set of assertions (one for each formula), we would also like to be able to conclude the existence of a morphism between two descriptions by checking only that the axioms of the source description are "implemented" by the target description, i.e. by proving that (Φ2 ⇒θ2 σ(p)) is valid for every p∈Φ1. However, for this to be possible, we know [Fiadeiro and Sernadas 88] that the underlying consequence relation must be structural, i.e. that given an arbitrary set of θ1-formulae Φ and a θ1-formula p, if (Φ ⇒θ1 p) is valid then (σ(Φ) ⇒θ2 σ(p)) must also be valid (which also means that ⇒ θ 2 alone is able to "implement" ⇒ θ 1 ). And it is easy to see that, in our case, ⇒ θ is not structural: the translation of the locality formula
∨
∧
( g∈Γ (∃xg)g(xg)) ∨ (a∈Α (∀xa)(Xa(xa) = a(xa))) 1
1
which is a theorem of (θ1,Φ1), is not necessarily a theorem of (θ2,Φ2). That is to say, the fact that the axioms of a specification are preserved does not imply that the locality of the attributes is preserved. This can also be understood from a more "model-theoretic" point of view. The notion of reduct of interpretation structures along a signature morphism is easily defined as follows: Definition 3.1.4: Given two object signatures θ1=(Σ1,Α 1,Γ1) and θ2=(Σ2,Α 2,Γ2), and a morphism σ from θ1 to θ2, we define for every θ2-interpretation structure S=(U,A,G) its reduct along σ as the θ1-interpretation structure S |σ= (U |σ,A |σ,G |σ) where – for every s∈S1, sU |σ= συ(s)U. – for every f: s1,…,sn→s in Ω1 fU |σ= συ(f)U; – for every f: s1,…,sn→s in Α1, A |σ(f)(i) = A(σα(f))(i) – for every g: s1,…,sn in Γ1, G |σ(g) = G(σγ(g)).
º
It is straightforward to prove:
J.FIADEIRO AND T.MAIBAUM
16
Proposition 3.1.5 (satisfaction condition): Given a θ 2-interpretation structure S, a θ 1-formula p is true in S|σ iff σ(p) is true in S.
º
However, the same result does not hold if we take θ-loci instead of θ-interpretation structures as models because the reduct of a θ2-locus is not necessarily a θ1-locus: a transition that is witnessed by θ2 is not necessarily witnessed by θ1. Hence, when defining the notion of a morphism σ between two object descriptions (θ1,Φ1) and (θ2,Φ2) we cannot require only for every θ2-locus O validating Φ2 that O|σ validates Φ1 (as usual), but we must also require that O|σ be a θ1-locus. In other words, the structure of components must be preserved in a strong sense. Thus, given theory presentations (θ1,Φ1) and (θ2,Φ2), and a morphism σ between their signatures, besides requiring that the axioms of (θ 1 ,Φ 1 ) be translated to theorems of (θ 2 ,Φ 2 ), i.e. that (Φ2 ⇒θ2 σ(p)) be valid for every p∈Φ1, we have to require that the translation of the locality axiom also be a theorem of (θ2,Φ2) for σ to be a morphism of theory presentations (interpretation between theories). That is, we require that the locality of the "smaller" component be preserved. The need for this additional requirement is similar to what happens with interpretations of first-order theories [Enderton 72], where besides having to translate axioms to theorems we have to prove a certain number of closure and non-emptiness conditions. As we have mentioned in section 2.1, we can see this locality condition as specifying constraints on the environment in which the component is allowed to be placed. Hence, when placing the component in an environment (i.e. when connecting it via a morphism) we must prove that these constraints are satisfied (in this case, that the newly introduced actions do not have any effect on the "old" attributes). We shall abbreviate the translation of the locality axiom, i.e. the θ2-formula
∨
∧
σ(( g∈Γ (∃xg)g(xg)) ∨ (a∈Α (∀xa)(Xa(xa) = a(xa)))) 1
1
σ by θ 1→ θ2, i.e. by the signature morphism itself. Besides representing a notational convenience, the choice of this abbreviation was also made so as to relate the rôle of this formula with the extension of languages with signature morphisms as proposed in [Goguen and Burstall 84]. This extension is needed to express constraints on the interpretation structures when the language is not expressive σ enough to support them: a θ-interpretation structure makes θ'→ θ true iff its σ-reduct satisfies the desired constraint, in this case iff it is a θ'-locus.
In summary, Definition 3.1.6: Given object descriptions (θ 1 ,Φ 1 ) and (θ 2 ,Φ 2 ), a morphism σ : (θ1,Φ 1) → (θ2,Φ 2) is a signature morphism σ: θ1 → θ2 such that • (Φ2 ⇒θ2 σ(p)) is valid for every p∈Φ1, σ • (Φ2 ⇒ θ2 θ1→ θ2) is valid. Proposition 3.1.7: Object descriptions and their morphisms form a category DESC.
º º
Although the consequence relation is not structural, we do have the following property approximating structurality: Proposition 3.1.8: Given a signature morphism σ: θ1→θ 2
TEMPORAL THEORIES AS MODULARISATION UNITS FOR CONCURRENT SYSTEM SPECIFICATION
17
º
σ if (Φ ⇒θ1 p) is valid then (σ(Φ), θ1→ θ2 ⇒θ2 σ(p)) is also valid
This results in the inference rule: Proposition 3.1.9: Given a morphism σ: (θ 1,Φ 1) → (θ 2,Φ 2) from (Φ1 ⇒θ1 p) we may infer (Φ2 ⇒θ2 σ(p)) This rule allows us to "export" properties of a specification along a morphism. As we have already mentioned, the ability for theories (presentations) to be considered as specification modules depends on the (finite) cocompleteness of the category of theory presentations and their morphisms. Intuitively, a category is finitely cocomplete if every finite diagram (whose nodes are labelled with theory presentations and whose edges are labelled with morphisms) has a colimit, i.e. if we can define a minimal theory presentation that contains all the theories in the diagram and respects the interaction specified by the morphisms (the "amalgamated sum" of all the theories in the diagram). In order to prove cocompleteness of a category, it is sufficient to prove that the category admits an initial object (a theory that is contained in every other theory) and pushouts (see [Barr and Wells 90] for an account of Category Theory directed to computing scientists). Technically, in an arbitrary category, a pushout is a colimit of a diagram of the form b
f a
c g
«
It consists of another object b ac together with two morphisms h: b → b that, on the one hand, the diagram h b
b
«ac and k: c → b«ac such
«a c k
f a
c g
commutes, i.e. f;h=g;k (which means that only one "copy" of a is obtained in b "share" a) and, on the other hand, for every other commutative diagram h' d
b
k'
f a
c g
«ac → d such that h;j=h' and k;j=k'.
there is a unique morphism j: b
«ac, i.e. b and c
J.FIADEIRO AND T.MAIBAUM
18
d h' j
b
b h
«a c k'
k
f a
c g
That is, a pushout is a "minimal" combination of the objects that respects the interaction specified via the morphisms (what is usually called an "amalgamated sum"). Colimits just generalise this operation to arbitrary diagrams.
«
For instance, the category SIGN is finitely cocomplete. The signature θ1 θθ2 is obtained by taking the amalgamated sums of the components of θ1 and θ2, i.e. we take their disjoint union and identify the symbols that they share with θ. An example will be provided in section 3.3. On the other hand, the initial object signature is (Ø,Ø,Ø) (denoting also by Ø the initial algebraic signature). In terms of descriptions, we have: Proposition 3.1.10: The category DESC is finitely cocomplete. The initial description is (Ø,Ø) and a pushout of two description morphisms µ1: (θ,Φ) → (θ1,Φ1) and µ2: (θ,Φ) → (θ2,Φ2) is given by σ two morphisms σ 1 and σ 2 and an object description (θ 1 θ θ 2 ,σ 1 (Φ 1 )∪σ 2 (Φ 2 )∪{θ 1 →1 θ 1 θ θ 2 , σ2 θ2 → θ1 θθ2}) where θ1 θθ2, σ1 and σ2 are a pushout of µ1 and µ2 as signature morphisms.
«
«
«
«
º
In our setting, the importance of pushouts is that they express the most basic operation for combining two objects: putting them in parallel but requiring them to synchronise via a common sub-object. That is, a pushout as in the proposition above achieves the operation (θ 1 ,Φ 1 ) ||(θ,Φ) (θ 2 ,Φ 2 ) which generalises synchronisation at a set of actions. Indeed, comparing with [Barringer 87], if we take a set of formulae to denote the conjunction of all the formulae in the set, and interpret ∪ as conjunction, we see that the parallel composition is given by the conjunction of the formulae that correspond to the components. The extra formulae (the translations of the locality requirements of the components) appear because, as explained above, locality is a logical notion and, hence, it is not a requirement that needs to be explicitly made in a specification. Otherwise, they would appear as part of the translation of the axioms of the components. This extra requirements also have a counterpart in the formalism used in [Barringer and Kuiper 84]: the "matching rules". Indeed, it is easy to see that this extra condition "encodes" the paradigm (shared vs distributed variables vs synchronised actions vs...) that is being supported by the formalism. A similar phenomenon occurs in [Barringer 87] where the rule for parallel composition must be adapted to the paradigm that is being supported. Non-synchronised parallel composition of components is just a particular case: it corresponds to taking the shared object to be the empty one (Ø,Ø). That is, (θ1,Φ 1) || (θ2,Φ 2) is just the coproduct of the object descriptions. It is easy to see that the models (loci) of the coproduct are exactly those whose reducts (as defined in 3.1.5) are models of the component objects. On the other hand, it is easy to compose two models, one of each of the components, to form a model of the coproduct just by assigning to each instant the union of the sets of actions that occur in each of the components during that instant. Hence, as we mentioned in section 2, it is not a strict interleaving model that we are adopting for parallelism. Of course, in the case of pushouts, synchronisation at the shared actions must
TEMPORAL THEORIES AS MODULARISATION UNITS FOR CONCURRENT SYSTEM SPECIFICATION
19
be respected, meaning that not every composition of models is a model of the pushout. (These modeltheoretic considerations are amplified in [Fiadeiro et al 91].) As we have already mentioned, pushouts are just an example of combining objects by assembling them in a diagram and connecting them through the appropriate interfaces. In the remainder of the paper, we are going to illustrate such a construction by showing how we can define the interaction between philosophers and forks, and how we can define their joint behaviour from the local descriptions given in section 2.2. As we shall see, one advantage of working within this categorial framework based on theory presentations is that, on the one hand, operations of renaming of symbols and the specification of interaction in general may be left to categorial operations and, on the other hand, we have a tighter control on the structure of the specifications.
3.2 Morphisms and interaction Morphisms are the formal tools that we use to express interconnections between system components: as motivated by the pushout example above, two objects interact by sharing some other object, i.e. by having a common sub-component in which they synchronise. Naturally, this sub-object may be as simple as an action: ACTION universe signature:
attribute symbols:
Ø
Ø
action symbols:
a
axioms:
Ø
Such objects can be used to connect two other objects via a certain action in which they will be required to synchronise. We shall give examples below. However, we must stress that our definition of morphism requires that, if two objects are to have an attribute in common, then they must also share all the actions that update that attribute. Indeed, mere sharing of attributes is forbidden by the formalism because it is impossible to isolate an attribute as a sub-object. For instance, the object described through ATTRIBUTE universe signature:
attribute symbols:
Ø
a
action symbols:
Ø
axioms:
Ø
has the following locality axiom: (Xa = a) requiring the attribute to be invariant. This is due to the fact that we have specified an empty set of action symbols. Hence, only constant attributes may be isolated and shared. Otherwise, we need to surround the attribute with all the actions that update it. It is easy to see that, in the case of the isolated action, the locality requirement is vacuous due to the fact that there is an empty set of attribute symbols. Hence, any description admits ACTION as a sub-description as long as it contains an action symbol. It is in this sense that locality is "logical" in our framework: it is a structural property given by the morphisms of the category of theory presentations. Encapsulation means that attributes (state) cannot
J.FIADEIRO AND T.MAIBAUM
20
be separated from the actions that update them and, hence, imposes a discipline in the way we are allowed to structure our specifications, i.e. in the way we can interconnect components (draw morphisms between descriptions). Another advantage of the categorial approach is, indeed, the ability to formalise such disciplines or paradigms for structuring/decomposing specifications in terms of morphisms of theory presentations. Naturally, it could be argued that it would be useful to be able to declare that some action is local (internal) to an object in the sense that it cannot be shared with any other object. In the formalism that we are proposing, this can be done by constraining the specifier in the way he is allowed to use morphisms. That is, it is a constraint that can be enforced at the level of a specification language built on top of this formalism. However, we should stress that it is essential that such local actions be declared in the signature of an object because, otherwise, we would not be able to reason about the behaviour of the object in terms of proving properties of its attributes. Indeed, the signature of an object must declare all the actions that are "authorised" to manipulate the attributes that were declared, even if some are local to the object. Besides, notice that "hiding" of actions, a mechanism that is sometimes used for controlling the scope of program variables (cf [Barringer 87]), is not necessary here because the notion of scope is explicilty dealt with through the signatures (and signature morphisms). So, how can we establish the desired interaction between forks and philosophers? The immediate and naïve solution would be to say that two philosophers interact by sharing a fork. Let us see where this idea will lead us. First of all, notice that we may indeed establish a morphism between a fork and a philosopher. On the one hand, the signature morphism would be as follows: belongs: FORK → PHIL universe idbool: BOOL |→ BOOL true |→ true false |→ false
attributes busy? |→ eating actions up |→ forks↑ down |→ forks↓
That is to say, a fork goes up when it is picked-up and goes down went it is put down, and a fork is busy when the philosopher is eating. In order to prove that we have a morphism between the object descriptions, we have to prove that the axioms of fork are translated to theorems of philosopher, and that the philosopher preserves the locality of fork. On the one hand, axioms f1-f5 get translated, respectively, to p3, p2, p4, p10 and p11. On the other hand, we have to prove PHIL ⇒ (forks↑∨ forks↓∨ (Xeating=eating))
i.e., the translation of the locality axiom (up ∨ down ∨ (Xbusy?=busy?)). This can be done as follows: 1. (forks↑ ∨ forks↓ ∨ bc-hungry ∨ ((Xeating=eating) ∧ (Xhungry?=hungry?)))
locality axiom for PHIL
2. (forks↑ ∨ forks↓ ∨ bc-hungry ∨ (Xeating=eating))
1, PC
3. bc-hungry → (Xeating=eating)
axiom p1
4. (forks↑ ∨ forks↓ ∨ (Xeating=eating))
2, 3, PC
Hence, we do have a morphism linking forks to philosophers. This says that in each philosopher we may recognise a sub-object that corresponds to a fork (i.e., a pattern of behaviour that corresponds to a fork).
TEMPORAL THEORIES AS MODULARISATION UNITS FOR CONCURRENT SYSTEM SPECIFICATION
21
If we wanted to express that two philosophers share this fork component, we would do so through the following diagram: FORK
•
• PHIL
• PHIL
However, sharing an object means synchronising at that object, i.e. at each of the actions of that object. For instance, this diagram identifies the action forks↑ of each of the philosophers with the action up of the fork, and mutatis mutandis for forks↓ and down. Hence, the two philosophers would have to pick up the fork simultaneously (as well as free the fork simultaneously)! This is not what we want: we want the philophers to use the same fork (i.e. the same fork operations), but mutually exclusively! From an intuitive point of view, each action symbol in the signature of an object provides a port to which another object may be linked for communication. (The parameters of the action symbol provide for the data that is to be exchanged.) This port is fixed in the sense that every other object connected to that port must synchronise in order to communicate. Hence, if we want two objects to communicate independently with a third one, each via the same operation, we must make sure that they are assigned different ports. In our case, this means that we have to extend the fork signature in order to provide different ports for each of the philosophers. That is to say, we have to provide an interface through which we are able to connect independently two philosophers to one fork. Such an interface can be built as follows: X-FORK universe signature:
action symbols:
BOOL (as before)
up; down; left↑; right↑;
attribute symbols:
left↓; right↓
busy?: BOOL axioms x1)-x5): as f1) - f5) x6) left↑ → up
x8)
left↓ → down
x7) right↑ → up
x9)
right↓ → down
That is to say, we extend the signature with action symbols that allow for two different ways of using a fork: from the right and from the left. Notice how axioms x6)-x9) state that we are not introducing new forms of behaviour but merely specialising existing ones. Hence, locality is preserved and the extension does establish an 'object' or a locus preserving morphism between the two descriptions. Naturally, we should also specify that the left and right actions are not allowed to occur concurrently: x10)
¬(left↑ ∧ right↑)
x11)
¬(left↓ ∧ right↓)
J.FIADEIRO AND T.MAIBAUM
22
That is to say, we prevent any instant witnessing both left and right actions, i.e. we prevent any observer witnessing the "simultaneous" occurrence of both actions. On the other hand, because we want the fork to be used only through the given ports, we have to require: x12)
up → left↑ ∨ right↑
x13)
down → left↓ ∨ right↓
That is, we provide the "completion" of x6)-x9). Naturally, in a specification language, it would probably be convenient to leave these completions implicit and not require the specifier to state them explicitly. Having specified x12 and x13 in order to restrict interaction via the new ports, it seems only natural to "hide" the up and down actions from the signature, and derive a new description where these action symbols are not mentioned. D-FORK universe signature: BOOL (as before) attribute symbols:
action symbols: left↓; right↓; left↑; right↑
busy?: BOOL axioms d1) left↓ → Xbusy? = false
d6)
left↑ → busy? = false
d2) right↓ → Xbusy? = false
d7)
right↑ → busy? = false
d3) left↑ → Xbusy? = true
d8)
left↓ → busy? = true
d4) right↑ → Xbusy? = true d5) BEG → busy? = false
d9)
right↓ → busy? = true
d10)
¬(left↑ ∧ right↑)
d11)
¬(left↓ ∧ right↓)
It is easy to see that we do have a morphism (inclusion) between D-FORK and X-FORK because, on the one hand, all the axioms of D-FORK are theorems of X-FORK (which can be trivially checked) and, on the other hand, x12 and x13 ensure that the translation of the locality axiom relative to DFORK is a theorem of X-FORK (which is also trivial to check). Furthermore, D-FORK is the "biggest" description, in the sense that it contains as many theorems as possible, that is included in XFORK by forgetting up and down. (This is the semantics of derivation of a theory along a signature morphism used in CLEAR [Burstall and Goguen 81].) The relationship between these constructions around FORK can be summarised by the diagram: D-FORK
X-FORK
FORK
We should stress that the need for these extensions and derivations is not violating our claims for supporting modular specification. Having specified components separately, we have to provide adequate interfaces in order to connect them because they were defined without knowledge of which other components they were going to be connected to. Indeed, notice that our X-FORK description merely specialised existing behaviour, which implies that the extension is conservative in the sense that no new properties are added [Maibaum 86]. Naturally, X-FORK and D-FORK are already biased towards the desired configuration of philosophers and forks because it restricts the use of a fork to two "clients". But this is how it should be: if a different configuration was desired, a different interface would have to be built. Finally, it is only natural that the specifier wishes to hide the "old" action symbols once they have been specialised into different ports.
TEMPORAL THEORIES AS MODULARISATION UNITS FOR CONCURRENT SYSTEM SPECIFICATION
23
Although these operations on theory presentations may seem to be too cumbersome, they are trivial examples of well known constructions that are available in CLEAR-like specification languages [Burstall and Goguen 81]: going from FORK to X-FORK is an extension (a particular case of enrichment), and going from X-FORK to D-FORK is a derivation. Hence, any specification language would make these operations easy to apply. Finally, it is important to stress that whereas the final description D-FORK is the one that we want to use for interaction with philosophers, and hence the one that we shall use from now on, the original description FORK is the one that we want to give an implementor to work on, i.e. it is the one that we shall use for interfacing with the next lower layer of the vertical structuring process. The above diagram does correspond to a "design structure" as defined in [Maibaum 89], where D-FORK is the "user's view" of the object, FORK is the "implementor's view" of the object, and X-FORK is the "body" which tells how the two other views are related. We can now define the interaction between two philosophers and one fork. As we have already mentioned, the interaction between two objects is expressed by defining channels between them. These channels are themselves objects: CHANNEL universe signature: sorts: BOOL
action symbols: port1; port2
axioms
This signature contains two action symbols accounting for the two channels (up and down), and includes the booleans in the universe signature in order to express the fact that philosophers and forks will use the same version of the booleans. This object may be seen as the "cable" (with two wires!) that we shall use to connect philosophers and forks. We have two obvious morphisms (injections) that define the required interactions: left: CHANNEL → D-FORK
right: CHANNEL → D-FORK
universe: id bool actions
universe: idbool actions
port1 |→ left↑
port1 |→ right↑
port2 |→ left↓
port2 |→ right↓
That is, the morphisms say to which ports of fork the "cable" is to be connected. There are two different ways in which we want to do so, hence we define two morphisms. Finally, we have a morphism between CHANNEL and PHIL establishing the way a philosopher uses a fork: use: CHANNEL → PHIL universe : id bool actions port1 |→ forks↑ port2 |→ forks↓
J.FIADEIRO AND T.MAIBAUM
24
That is to say, a fork is picked-up and put-down when the philosopher grabs and frees the forks. Hence, through the left morphism, a philosopher is connected to the left ports of a fork, and through the right morphism it is connected to the right ports of a fork. This interaction between two philosophers and a fork is expressed through the diagram PHIL
PHIL
use
use D-FORK
CHANNEL
CHANNEL
right
left
Naturally, a specification language should provide the means for defining such diagrams.
3.3 Aggregation and concurrency Now that we know how to define the interaction between a philosopher and two forks, how can we obtain the joint behaviour of five philosophers sharing five forks around a table? The thesis is that it can be given in terms of the colimit in the category of object descriptions of the diagram that is depicted below2.
use
CH AN NE L
use PH
PH IL
use
left
rig ht
L NE AN CH
IL
D-FORK
b
C H AN NE L
use
b
L NE AN CH ht rig
left righ t CH AN NE L
D-F OR K
RK FO D-
left
ht rig
L NE AN CH
left
right PHIL
CHANNEL use
CHANNEL use
2 Some non-categorial elements were added to the diagram in order to enhance its structure...
CH AN NE L
D-FORK
left
use
b
D-FORK
use
IL
PH
PH
IL
b
use
b
use
L NE AN CH
Mandu Ergo C Ergo S
TEMPORAL THEORIES AS MODULARISATION UNITS FOR CONCURRENT SYSTEM SPECIFICATION
25
This diagram contains a node labelled with the theory presentation PHIL for each of the philosophers in the community, a node labelled with the theory presentation D-FORK for each of the forks, and the channels and corresponding morphisms establishing the desired interaction between the objects of the society, i.e. saying which philosophers share which forks. Notice that theories act as "types" in the sense that several instances of the same theory may be used in the same diagram to express the fact that there are several components of the system that are of the same "type" (follow the same pattern of behaviour). We shall see below how we can distinguish between them. A theory thus acts as a description of a "generic" object. The colimit of this diagram returns a new object description (call it SPAGHETTI): the description of the "minimal" object that admits the depicted ones as components, respecting their interaction as given by the morphisms. That is to say, it is the community of five philosophers sharing five forks considered as an object itself. Indeed, as we claimed in the introduction, the categorial approach provides us with a faithful notion of module in the sense that we can build complex modules out of simpler ones. The aggregation of a community of objects is still an object that can be used as a module for building yet more complex objects. So, what is the signature and what are the axioms of the description of this complex object? The signature of SPAGHETTI is obtained from the well known construction of colimits in the category of sets. Basically, we take the union of the component signatures after having renamed the symbols in each signature taking into account the morphisms expressing the sharing between the signatures. From the formal point of view, the actual names that are given are of no importance because a colimit is obtained up to isomorphism (meaning, in our example, that it is not the names of the philosophers that matter, but rather who is sitting next to whom). Essentially, what is important is that we can keep track of these names through the morphisms of the colimit. Naturally, a specification language should allow the specifier to rename the symbols as appropriate. We shall follow herein the following convention: symbols are renamed by prefixing their names in the components with the name of the morphism separated by a dot. For instance, we could name 1, 2, 3, 4 and 5 the five morphisms linking the nodes labelled D-FORK to SPAGHETTI. Thus, we would obtain among the attribute symbols of SPAGHETTI the translation of the attributes of each of the five copies of the signature D-FORK along the corresponding morphism. For instance, we could have 1.busy?, 2.busy?, 3.busy?, 4.busy? and 5.busy?. If we name the morphisms linking the nodes labelled with PHIL to SPAGHETTI Alice, March-Hare, Hatter, Dormouse, and Lewis (an honourary guest) we would obtain as attribute symbols in SPAGHETTI: Alice.hungry?, March-Hare.hungry?, Hatter.hungry?, Dormouse.hungry?, …. In order to see how sharing works, consider the more interesting case of the action of philosophers grabbing the forks. In virtue of the interaction as expressed through the diagram, we shall have in SPAGHETTI an action symbol, e.g. Alice.eat, which is the image of forks↑ along the morphism labelled Alice, the image of the symbol left↑ along the fork morphism labelled 1 (assuming that this is the fork placed at the left of Alice in the diagram), and the image of the symbol right↑ along the fork morphism labelled 5 (assuming that this is the fork placed at the right of Alice in the diagram): alice.eat
left ↑
forks↑
port1
right ↑
port1
J.FIADEIRO AND T.MAIBAUM
26
In the same way, we shall have a single action symbol, e.g. Alice.think, to which the action symbol forks↓ of PHIL is mapped along Alice, left↓ of D-FORK is mapped along 1 and right↓ of D-FORK is mapped along 5. This means that the actions at the different objects are identified in the colimit. Hence, interaction means synchronisation of the objects at the actions identified through the morphisms as being shared by the objects. In terms of the axioms of SPAGHETTI, we have the translations of the axioms present in the nodes of the diagram. Hence, we will have, for instance Alice.eat → Alice.hungry?=true Alice.eat → 1.busy?=false Alice.eat → 5.busy?=false
which are imported, respectively, from the descriptions of philosophers through the morphism Alice (axiom p9), and from the description of forks through the morphisms 1 (axiom d6) and 5 (axiom d7). Hence, by renaming actions from different components to the same name, the constraints specified locally add-up for the shared actions in a natural way. In other words, in the colimit object, we bring together the different rôles of the actions, whose specifications were distributed among the relevant object descriptions. However, we must stress that we do not obtain in SPAGHETTI non-interference axioms such as Alice.bc-hungry → XHatter.hungry? = Hatter.hungry?
requiring that actions from one object do not interfere with the attributes of another object. Intuitively, we could think that these axioms would be necessary, or left to some kind of frame rule, in order to express that the locality of the components is preserved in the global system. However, these formulae are not even theorems of the global system. Instead, we have as axioms of the colimit object the signature morphisms (i.e., the translations of the locality axioms) Alice
PHIL → SPAGHETTI Hatter
PHIL → SPAGHETTI
... 1
D-FORK → SPAGHETTI 2
D-FORK → SPAGHETTI
... expressing precisely the intended locality preservation requirement. We should point out that having the signature morphisms (i.e. the translations of the locality requirements of the components) instead of the non-interference formulae as axioms results from the fact that it is not a strict interleaving model that we are adopting for parallelism. Indeed, the locality preservation requirement expressed through the morphisms guarantees that each action from one component either occurs concurrently with an action of another component (i.e., the interpretations of two action symbols, one from each signature, have instants in common), or does not interfere with the attributes of the other component (i.e., it occurs in a silent step). That is to say, the signature morphism leaves open the possibility of having instants that belong simultaneously to the interpretation of action symbols inherited from different nodes and, hence, allows for concurrency between actions of the different components. For instance, we are allowing for the actions bc-hungry inherited from the different philosophers to occur concurrently, or for two philosophers on opposite sides of the table to grab the forks concurrently if
TEMPORAL THEORIES AS MODULARISATION UNITS FOR CONCURRENT SYSTEM SPECIFICATION
27
they are available. Although we are not imposing this kind of synchronisation, we might decide later on to require it explicitly in order to enforce some new specific form of behaviour. The noninterference formulae would prevent this by providing a way of discriminating between the actions inherited from different signatures. That is, by forcing their effects on the attributes, they would make them observationally different. For instance, the formula above would prevent having instants that belong simultaneously to the interpretations of Alice.bc-hungry and Hatter.bc-hungry because that would require the attribute Alice.hungry? to be set to true (axiom p5) and kept false (non-interference formula above). That is, the non-interference formula would prevent both actions from being observed to occur concurrently. Indeed, it is easy to see that they would force a strict interleaving discipline. The adopted semantics of parallelism/aggregation is also more akin to the notion of colimit as a minimal combination of the components: enforcing strict interleaving seems to be a design decision imposed on their joint behaviour. The general principle is that actions inherited from different components are usually unrelated and, hence, they should be allowed the maximum degree of freedom in terms of "occurring simultaneously" (i.e. any amount of parallelism, from strict interleaving to maximal parallelism, is allowed). Hence, basically, the signature morphisms identify sub-components of an object that should not interfere apart from the specified interfaces. In other words, concurrency is the default in this framework.
3.4 Deriving global properties Being an object description, the description of the joint behaviour of the five philosophers sharing the five forks, SPAGHETTI will have its own properties besides those inherited from its components. For instance, it is easy to see that ¬((Alice.eating? = true) ∧ (Hatter.eating? = true))
(A)
is a property of the society if the Hatter is sitting next to Alice: in order to grab her forks, Alice's forks must not be busy, which implies that her neighbours cannot be eating. In order to illustrate how modularity is achieved at the verification level, we are going to show that this property can be proved using only knowledge of the behaviour of Alice, the Hatter, and the fork they share (assume it to be 1, at Alice's right and the Hatter's left, for arguments sake). That is, we shall work only in the fragment of the colimit that is given by the sub-diagram SPAGHETTI
Alice
Hatter
PHIL
PHIL 1 use
use D-FORK
CHANNEL right
CHANNEL left
We shall abbreviate formula (A) to ¬(Alice.eating? ∧ Hatter.eating?)
(B)
J.FIADEIRO AND T.MAIBAUM
28
The idea is to use the temporal induction rule and the locality rule as shown at the end of section 2.4. From the induction rule, we have to prove BEG → ¬(Alice.eating? ∧ Hatter.eating?) ¬(Alice.eating? ∧ Hatter.eating?) → X¬(Alice.eating? ∧ Hatter.eating?)
(C)
The initialisation condition is trivially proved from the translations of axiom p4 (from philosophers) along Alice and Hatter. The induction step, which is equivalent to X(Alice.eating? ∧ Hatter.eating?) → (Alice.eating? ∧ Hatter.eating?)
will be proved using locality. As done in section 2.3, instead of using the translation of the locality axioms, we may use a derived inference rule: Let σ: θ 1 → θ 2 be a morphism between object signatures. Let p be a θ 2-formula and t1,…,tn be local terms of θ1. Then, σ θ 1→ θ2, {(σ(g(xg)) → p) | g∈Γ1}, (
∧ σ(Xt = t )) → p) ⇒
1≤i≤n
i
i
θ2
p
σ where θ1→ θ2 is the translation of the locality axiom of θ1. That is, we may infer any property over θ2 by proving that p holds when the next action to occur was imported from θ1 and that p holds when a designated set of local terms imported from θ1 is invariant. This is because the morphism preserves locality: only actions imported from θ1 may change the attributes imported from θ1. We should point out, however, that this is not the translation of the rule given in section 2.3 because we are allowing p to be any formula over θ2. Rather, it is that rule that can be derived from this one (using the identity morphism).
We can apply this rule along the morphism Alice in order to derive the invariance property above. We are left to prove: SPAGHETTI ⇒ Alice PHIL → SPAGHETTI
Alice.bc-hungry → (X(Alice.eating? ∧ Hatter.eating?) → (Alice.eating? ∧ Hatter.eating?))
(C1)
Alice.eat → (X(Alice.eating? ∧ Hatter.eating?) → (Alice.eating? ∧ Hatter.eating?))
(C2)
Alice.think → (X(Alice.eating? ∧ Hatter.eating?) → (Alice.eating? ∧ Hatter.eating?))
(C3)
(XAlice.eating? = Alice.eating?) → (X(Alice.eating? ∧ Hatter.eating?) → (Alice.eating? ∧ Hatter.eating?)) (C4)
Recall that Alice.eat is the translation of forks↑ along Alice, and Alice.think is the translation of forks↓ along Alice. The first assertion is trivial because PHIL Alice → SPAGHETTI is an axiom of SPAGHETTI, as we have argued above. Hence, we are left to prove the other four assertions. Let us show how (C1) could be proved: 1. bc-hungry → Xeating?=eating?
axiom p1
2. bc-hungry → hungry?=false
axiom p8
3. eating? → hungry?
derived in section 2.3
4. bc-hungry → eating?=false
2, 3, PC
5. bc-hungry → Xeating?=false
1, 4, equality
TEMPORAL THEORIES AS MODULARISATION UNITS FOR CONCURRENT SYSTEM SPECIFICATION
29
Hence, we have PHIL ⇒ (bc-hungry → Xeating?=false)
But, because Alice is a morphism between PHIL and SPAGHETTI, we know that this property is translated along Alice to a property of SPAGHETTI, i.e. we have through 3.1.9 SPAGHETTI ⇒ (Alice.bc-hungry → XAlice.eating?=false)
From this assertion, it is now trivial to derive (C1). This derivation shows how we can use the structure of the specification (given through the morphisms) to transfer the verification process to the components in order to prove "lemmas" that we may translate back to the global system. It is also trivial to derive (C3) from the translation of p3 along Alice (recall that Alice.think is the translation of forks↓ along Alice). However, it is easy to see that (C2) and (C4) cannot be derived without more premisses on the behaviour of the Hatter. Indeed, we shall have to apply again the locality rule to these premisses but now along the morphism Hatter. Hence, for instance, we shall break (C2) into SPAGHETTI ⇒ Hatter PHIL → SPAGHETTI
Hatter.bc-hungry → (Alice.eat → (X(Alice.eating? ∧ Hatter.eating?) → (Alice.eating? ∧ Hatter.eating?))) (C21) Hatter.eat → (Alice.eat → (X(Alice.eating? ∧ Hatter.eating?) → (Alice.eating? ∧ Hatter.eating?)))
(C22)
Hatter.think → (Alice.eat → (X(Alice.eating? ∧ Hatter.eating?) → (Alice.eating? ∧ Hatter.eating?)))
(C23)
(XHatter.eating? = Hatter.eating?) → (Alice.eat → (X(Alice.eating? ∧ Hatter.eating?) → (Alice.eating? ∧ Hatter.eating?)))
(C24)
The signature morphism is, again, an axiom of SPAGHETTI. Because the property that we are trying to prove (B) is symmetric with respect to Alice and the Hatter, it is easy to see that (C21) and (C23) are derived as (C1) and (C3), leaving (C22) and (C24) to prove. (C22) is also trivial to derive because axiom d10 of D-FORK is translated along the morphism 1 to ¬(Hatter.eat ∧ Alice.eat) Finally, (C24) can be proved assuming the formula (Alice.eating? ∨ Hatter.eating? → 1.busy?)
(D)
stating that fork 1 is busy when either Alice or the Hatter are eating. Using this formula as an additional premiss on the current state, we derive 1. Alice.eat → 1.busy?=false
translation of d6 along 1
2. Alice.eat → Hatter.eating?=false
1, formula above
from which (C24) follows trivially. Notice that in step 1 we have used the fact that left↑ is translated along 1 to Alice.eat. Assertion (C4) would have to undergo the same process, using (D) once more. Notice that formula (D) is only needed as an extra premiss on the current state and, hence, can be proved in conjunction with (B). That is, instead of (C) we shall have proved
J.FIADEIRO AND T.MAIBAUM
30
B ∧ D → X (B)
By further proving B ∧ D → X (D)
BEG → D
it follows by the induction rule that (B ∧ D) is a property of SPAGHETTI. These proofs would follow the same pattern as above. In summary, the verification process is modular in the sense that it can use the structure of the specification (as given through the morphisms) to import the relevant results from the components as lemmas which can then be composed to prove properties of the global system. Hence, it is not necessary to work within the global specification of the system. In fact, the derivation above showed how we could select the relevant fragment of the specification (the fragment consisting of Alice, the Hatter, and fork 1) in order to prove a property that does not involve all the constituents of the community. However, due to the fact that interaction with other objects restricts the way in which an object can behave, it is possible that an object will have more properties (less freedom) in the community than when analysed in isolation, i.e. we may be able to derive more properties in the colimit object than those imported from the nodes. For instance, because we can import along a morphism all the properties proved locally in a component (3.1.9), we shall also have in SPAGHETTI F(Alice.eating?=true)
which is the translation along the morphism Alice of the liveness property F(eating?=true)
that we met at the end of section 2.3. Using property (A), we derive immediately F(Hatter.eating?=false)
That is, during the behaviour of the society, the Hatter (and, indeed, any of the philosophers) will be recurrently thinking (not eating). It is easy to see why: for a philosopher to be recurrently eating, his neighbours must be recurrently thinking. What is interesting about this property is that it is not the translation of a property of the description of philosophers. Indeed, PHIL ⇒ F(eating?=false)
is not valid because there is nothing in the description of philosophers that requires a philosopher to put down his forks. This means that the morphisms are not conservative (there are models of PHIL, e.g. one where the philosopher never puts down his forks, that do not correspond to any model of the society). This indicates a situation of possible starvation (!): the behaviour of the society (according to which every philosopher will be recurrently eating) does not depend only on the behaviour of its component objects, but also on an overall cooperation (sociable behaviour of its components). We should perhaps include in the description of philosophers
TEMPORAL THEORIES AS MODULARISATION UNITS FOR CONCURRENT SYSTEM SPECIFICATION
31
(eating?=true) → F(forks↓)
if we want to avoid that risk of starvation (but still assuming some degree of fairness), or introduce a scheduler (footman) that coordinates the behaviour (appetite) of the philosophers. Notice that it is up to the specifier to interpret the absence of conservativeness along certain morphisms. For instance, the lack of conservativeness with respect to liveness properties along the fork morphisms should not worry the specifier because forks are intended to be passive objects and, hence, the satisfaction of liveness requirements is not their business. Other kinds of analysis that can be performed at this level concern the detection of deadlock situations that result from the lack of conservativeness with respect to safety properties (see [Sernadas et al 89a; Fiadeiro and Maibaum 89] for more details).
4 Concluding remarks In this paper, we have shown how the "categorial" approach to system specification that has been developed mainly by J.Goguen and R.Burstall can be applied to the specification of concurrency using temporal logic in the tradition initiated by A.Pnueli. Basically, this approach advocates the description of individual components of systems as theories in a certain logic, and the use of diagrams for expressing systems of interconnected components. The colimit of such a diagram returns the specification of the system that comprises the given components interacting as specified through the morphisms (edges) that connect them. This approach leads, in a natural way, to modularity in specification and verification as we hope to have demonstrated using the well known example of the dining philosophers. The work on institutions [Goguen and Burstall 84] has shown that the ability to support this view of specification depends only on some structural properties of the logic. Hence, in order to support this style of specification, it is sufficient to choose a logic according to the nature of the problem that we are trying to specify, and prove that it defines an institution. This is what we have done for a temporal logic fairly close to those that have been adopted in the area, namely [Barringer 87], in order to show how the dogma applies to concurrent system specification. Other logics might have been chosen, namely a logic that we have been developing for supporting object-oriented specification [Fiadeiro and Maibaum 90] and which, besides temporal qualification, also uses modal action operators and deontic predicates of permission and obligation. Although we feel that these additional features are useful for formalising objects, namely because they allow the separation of the definition of the effects of the actions on the attributes from the definition of the restrictions and requirements on their occurrence, and also to separate non-normative behaviour (e.g. failures and divergence) from inconsistency, the chosen logic has the advantage of being more "standard" in the area of concurrent systems specification, and is well suited to formalise the concurrency aspects of objects as specification units. In fact, we have not explored the institutional framework completely, as we have left out morphisms between interpretation structures. This model-theoretic dimension was not necessary for the purposes of this paper, but is being explored as a means for relating this approach to categorial process models such as [Costa and Sernadas 91], closer to other algebraic models of processes [e.g. Hennessy 88]. Preliminary results on this direction are reported in [Fiadeiro et al 91].
32
J.FIADEIRO AND T.MAIBAUM
The nature of the support that this approach provides for horizontal structuring, i.e. for structuring specifications within a fixed level of the development process, seems to be clear from what we have presented. Indeed, it seems clear that the adoption of this categorial framework provides a neat notion of specification module, namely by providing formal support for "syntactical locality" through the notion of signature associated with the specification of a component (formalising a notion of scope) and leading to operations that allow us to build complex modules out of simpler ones. Moreover, we obtain an explicit formalisation of interaction between components through sharing of subcomponents, allowing for the formalisation of disciplines/paradigms for the structuring/decomposition of specifications in terms of the morphisms that we can use to connect components, i.e. through the structure of the category of the theory presentations of the logic. This aspect was illustated in the paper through the adoption of an "object-oriented approach" - private variables (attributes) and shared actions. Hence, we claim that the same kind of support that equational formalisms have been providing for the specification of abstract data types can be provided for the specification of abstract object types based on temporal logics. Naturally, specification languages are needed which provide the specifier with higher-level constructs that ease the burden of providing every detail that is required by the logic. Hints on useful constructs have been given throughout the text, and a more serious attempt towards defining object-oriented specification constructs is given in [Fiadeiro et al 90]. It remains to look in more detail at the nature of the support that can be provided to vertical structuring, i.e. for the "implementation" of components in a level of the development process in terms of the components available in the next level (in a more concrete "abstract machine"). A model-theoretic account of object refinement can already be found in [Ehrich and Sernadas 89], and preliminary results on notions of refinement in the above mentioned logic of objects can be found in [Fiadeiro and Maibaum 90].
Acknowledgments We wish to thank our colleagues Hans-Dieter Ehrich, Udo Lipeck and Amílcar Sernadas for the many challenging discussions that we have had on these subjects, and which, together with suggestions, have helped to shape things to as they are. We are also grateful to Ian Hodkinson and Mark Ryan for valuable and detailed comments on this work.
References [Barr and Wells 90] M.Barr and C.Wells, Category Theory for Computing Science, Prentice-Hall International 1990 [Barringer 87] H.Barringer, "The Use of Temporal Logic in the Compositional Specification of Concurrent Systems", in A.Galton (ed) Temporal Logics and their Applications, Academic Press 1987 [Barringer and Kuiper 84] H.Barringer and R.Kuiper, "Hierarchical Development of Concurrent Systems in a Temporal Framework", in S.Brookes, A.Roscoe and G.Winskel (eds) Seminar on Concurrency, LNCS 197, Springer-Verlag 1984, 35-61 [Burstall and Goguen 77] R.Burstall and J.Goguen, "Putting Theories together to make Specifications", in R.Reddy (ed) Proc Fifth International Joint Conference on Artificial Intelligence, 1977, 1045-1058
TEMPORAL THEORIES AS MODULARISATION UNITS FOR CONCURRENT SYSTEM SPECIFICATION
33
[Burstall and Goguen 81] R.Burstall and J.Goguen, "An Informal Introduction to Specifications using Clear", in R.Boyer and J.Moore (eds) The Correctness Problem in Computer Science, Academic Press 1981, 185213 [Costa and Sernadas 91] J.-F.Costa and A.Sernadas, Process Models within a Categorial Framework, Research Report, INESC, 1991 [de Roever 85] W.deRoever, "The Quest for Compositionality - a survey of assertion-based proof systems for concurrent programs. Part1: concurrency based on shared variables", in E.Neuhold and G.Chroust (eds) Formal Models in Programming, North-Holland 1985, 181-205 [Ehrich and Sernadas 89] H.-D.Ehrich and A.Sernadas, "Algebraic View of Implementing Objects over Objects", in W.deRoever (ed) Stepwise Refinement of Distributed Systems: Models, Formalisms, Correctness, Springer-Verlag (in print) [Ehrich et al 90] H.-D.Ehrich, A.Sernadas and C.Sernadas, "From Data Types to Object Types", Journal of Information Processing and Cybernetics (in print) [Ehrig and Mahr 85] H.Ehrig and B.Mahr, Fundamentals of Algebraic Specification 1: Equations and Initial Semantics, Springer-Verlag 1985 [Enderton 72] H.B.Enderton, A Mathematical Introduction to Logic, Academic Press 1972 [Fiadeiro and Maibaum 89] J.Fiadeiro and T.Maibaum, Towards Object Calculi, Research Report, Imperial College, 1989 [Fiadeiro and Maibaum 90] J.Fiadeiro and T.Maibaum, "Describing, Structuring, and Implementing Objects", in J.deBakker, W.deRoever and G.Rozenberg (eds) Foundations of Object-Oriented Languages, Springer-Verlag (to be published) [Fiadeiro and Sernadas 88] J.Fiadeiro and A.Sernadas, "Structuring Theories on Consequence", in D.Sannella and A.Tarlecki (eds) Recent Trends in Data Type Specification, LNCS 332, Springer Verlag 1988, 44-72 [Fiadeiro and Sernadas 90] J.Fiadeiro and A.Sernadas, "Logics of Modal Terms for Systems Specification", Journal of Logic and Computation 1(2), 1990, 187-227 [Fiadeiro et al 90] J.Fiadeiro, C.Sernadas, T.Maibaum and G.Saake, "Proof-theoretic Semantics of ObjectOriented Specification Constructs", in W.Kent, S.Khosla and R.Meersman (eds) ObjectOriented Databases: Analysis, Design and Construction, North-Holland (to appear) [Fiadeiro et al 91] J.Fiadeiro, A.Sernadas, J.-F.Costa and T.Maibaum, (Terminal) Process Semantics of Temporal Logic Specifications, Research Report, Imperial College, 1991 [Gergely and Úry 88] T.Gergely and L.Úry, Constructive Specification Theory, Technical Report, Applied Logic Laboratory, Budapest 1988 [Goguen 86] J.Goguen, "Reusing and Interconnecting Software Components", IEEE Computer 19(2), 1986, 16-28
34
J.FIADEIRO AND T.MAIBAUM
[Goguen 89] J.Goguen, A Categorical Manifesto, Technical Report PRG-72, Programming Research Group, University of Oxford, March 1989 [Goguen and Burstall 84] J.Goguen and R.Burstall, "Introducing Institutions", in E.Clarke and D.Kozen (eds) Proc Logics of Programming Workshop, LNCS 164, Springer-Verlag 1984, 221-256 [Goguen and Ginali 78] J.Goguen and S.Ginali, "A Categorical Approach to General Systems Theory", in G.Klir (ed) Applied General Systems Research, Plenum 1978, 257-270 [Hennessy 88] M.Hennessy, Algebraic Theory of Processes, MIT Press 1988. [Hoare 85] C.A.R.Hoare, Communicating Sequential Processes, Prentice-Hall 1985 [Lamport 83] L.Lamport, "Specifying Concurrent Program Modules", ACM TOPLAS 6(2), 1983 [Maibaum 86] T.Maibaum, "Rôle of Abstraction in Program Development", in H.-J.Kugler (ed) Information Processing'86, North-Holland 1986, 135-142 [Maibaum 89] T.Maibaum, Design Structures, private communication, Imperial College, London 1989 [Manna and Pnueli 81] Z.Manna and A.Pnueli, "Verification of Concurrent Programs: The Temporal Framework", in R.Boyer and J.Moore (eds) The Correctness Problem in Computer Science, Academic Press 1981, 215-273 [Parnas 72] D.Parnas, "A Technique for Software Module Specification with Examples", Communications ACM 15, 1972, 330-336 [Pnueli 77] A.Pnueli, "The Temporal Logic of Programs", in Proc 18th Annual Symposium on Foundations of Computer Science, IEEE 1977, 45-57 [Pnueli 86] A.Pnueli, "Specification and Development of Reactive Systems", in H.-J. Kugler (ed) Information Processing 86, North-Holland 1986, 845-858 [Sannella and Burstall 83] D.Sannella and R.Burstall, "Structured Theories in LCF", in G.Ausiello and M.Protasi (eds) Proc. 8th Colloquium on Trees in Algebra and Programming, LNCS 159, Springer-Verlag 1983, 377-391 [Sannella and Tarlecki 88] D.Sannella and A.Tarlecki, "Building Specifications in an Arbitrary Institution", Information and Control 76, 1988, 165-210 [Sernadas et al 87] A.Sernadas, C.Sernadas and H.-D.Ehrich, "Object-Oriented Specification of Databases: An Algebraic Approach", in P.Hammersley (ed) Proc 13th VLDB Conference, Morgan Kaufmann 1987, 107-116 [Sernadas et al 89a] A.Sernadas, J.Fiadeiro, C.Sernadas and H.-D.Ehrich, "Abstract Object Types: A Temporal Perspective", in B.Banieqbal, H.Barringer and A.Pnueli (eds) Temporal Logic in Specification, LNCS 398, Springer-Verlag 1989, 324-349
TEMPORAL THEORIES AS MODULARISATION UNITS FOR CONCURRENT SYSTEM SPECIFICATION
35
[Sernadas et al 89b] A.Sernadas, J.Fiadeiro, C.Sernadas and H.-D.Ehrich, "The Basic Building Blocks of Information Systems", in E.Falkenberg and P.Lindgreen (ed) Information Systems Concepts: An In-depth Analysis, North-Holland, 1989, 225-246 [Veloso and Pequeno 78] P.Veloso and T.Pequeno, "Interpretations between Many-sorted Theories", in Proc. 2nd Brasilian Colloquium on Logic, 1978