Modal Logics for Reasoning about Object-based Component Composition

Component-oriented development of software supports the adaptability and maintainability of large systems, in particular if requirements change over time and parts of a system have to be modified or replaced. The software architecture in such systems can be described by components and their composition. In order to describe larger architectures, the composition concept becomes crucial. 
 
We will present a formal framework for component composition for object-based software development. The deployment of modal logics for defining components and component composition will allow us to reason about and prove properties of components and compositions.


Introduction
In order to achieve flexibility in the development of large scale software systems, we design software architectures that allow its software components to be adapted, composed and exchanged. A software development framework using a component-oriented approach usually consists of a library of (reusable) components and a component framework to describe the software architecture through the composition of components. Composing components, or plugging them together, is the key to a flexible composition framework [LS00].
Object-oriented programming languages are ideal for implementation. Drawbacks in these languages are deficiencies in concepts for composition. Reuse is typically considered too late in the development process. The architecture consisting of components and component compositions cannot be described explicitly. This paper addresses a formal foundation for object-based component composition. Our mathematical framework is modal logics. A formal semantics is a necessity to reason about a language construct. Building upon a formal semantics for object-based components, we present semantics for composition that will allow us to reason about the properties of a composition, e.g. proving the correctness of a composition. Modal logics are in particular suitable for reasoning about state-based systems. They also provide an abstract notation for the formulation of components. The idea of a contract between a service provider and a service user can be formalised usin modal logics.
Following Wegner's classification [Weg90], our approach is object-based. Objects are executable entities that provide services. They encapsulate a local state. Components are abstractions over objects. They are a means to construct object-based systems with explicit architectures. The use of components in software development supports reliability by dividing a system into separate elements In Section 2 we will present a formal object model. The foundations for specifying components will be laid in Section 3. In Section 4 we define two relations which will essentially capture the notion of component composition. These relations will help us to reason about a composition. Components will then be defined as parameterised specifications (see Section 5). Finally, we investigate the composition of components in Section 6. We conclude with some summarising remarks and related work. Proofs are omitted in the main part of the paper itself. They are presented in the Appendix.

A Simple Notion of Objects
Objects are the basic building blocks of our approach. Objects are state-based entities providing services in form of operations. A local state is encapsulated. We present objects in a typed framework. An early version of this object model has been presented in more detail in [Pah97]. There, we focused on the object notion and showed how this model of objects can also be used to model concepts of imperative programming languages.
The abstract syntax of an object shall be captured by a signature. We assume a set of sorts So rtand a set of identifiers I dfor variables and operation names. For each object signature , element of the class of object signatures Si g, we define a mapping sorts : Si g! P So rtwith state 2 sorts( ), a mapping fctn : Si g! P I dwith a signature sig(f) = s 1 : : : s n ! s for each function f 2 fctn( ) with s 1 : : : s n s 2 (sorts( ) ; f stateg) the state sort state as fctn( ) ! sig(fctn( )) a mapping proc : Si g! P I dwith a signature sig(p) = state s 1 : : : s m ! state s for each procedure p 2 proc( ).
The sorts sorts( ) include basic data sorts s 1 s 2 : : : representing data types and the distinguished sort state to represent the object state. A state is a dynamic (i.e. modifiable) mapping from function identifiers to functions. A variable (in the sense of programming languages) is modelled as a nullary function. There are two forms of operations: functions fctn( ) and procedures proc( ). Functions do not change the state, procedures might do. Procedures might modify function definitions. The operations constitute the services provided by the object.
-terms are permissable syntactic entities for a given signature . Let X = (X s ) s2sorts( ) be a sorts( )-sorted set of free variables. A -term of data sort s over X s is thus every x 2 X s , every F(t 1 : : : t n ) with f : s 1 : : : s n ! s, and every 2 (p(st t 1 : : : t n )) with p : state s 1 : : : s n ! state s and t i -term of data sort s i 2 S, i = 0 : : : n st : state 1 . -terms of state sort state over X s are identifiers st to denote the state, and every 1 (p(st a 1 : : : a m )) for p 2 proc( ) with p : state s 1 : : : s m ! state s, st : state and a i : s i . With T( X ) s we denote the set of -terms of sort s including variables.
A state signature morphism is a structure-preserving mapping between object signatures where So r t (state) is the identity. Signature morphisms will be needed later on to express how components in a composition can be adapted syntactically.
A structure is called a -object for an object signature , if it has a carrier set S including an undefinedness symbol ? for each sort s, a function of type S 1 : : : S n ! S for each function with signature s 1 : : : s n ! s, a carrier set State for sort state containing total assignments PI d! F if F is the set of functions that match the signatures of functions, a function of type (St a t e S 1 : : : S m ) ! (St a t e S) for each procedure symbol in proc( ) with the corresponding signature. This is object-based according to Wegner's classification [Weg90]. We have not modelled an object identity (which is considered optional by Wegner). Carrier sets for basic sorts and functions for function symbols form an algebra.
A state STof sort state can be modified by procedures. We need a substitution mechanism on states.
The expression substitute(ST x7 ! v) substitutes in the mapping STthe former binding for an identifier x by a binding of x to the value v. The value of an identifier x is stored in STremember that the state associates function symbols and functions.
We introduce a definedness predicate D for terms t: D(ST t ) = true, if v (ST t ) 6 = ? for some state ST. Termination of operations will be expressed using the definedness predicate. In the next section, we will introduce a simple state transition logic allowing us to specify functions and procedures in an abstract way.

Component Specification
Modal logics are logics with a notion of state (or time). Modal logics allow us to specify and reason about states and state transitions. Dynamic logic is a modal logic which makes terms of the underlying object language explicit in the logic. We present a simplified dynamic logic which allows the abstract specification of objects by describing the behaviour of their operations. Abstraction of implementation details is the main requirement for a component notion.
Equations and the so-called modal box-operator will form the two basic constructs of the formula language. A -equation has the form t = s t 0 with t t 0 2 T( X ) s for a data sort s. A stateequation has the form t = state t 0 with t t 0 2 T( X ) state . The set of well-formed formulas WFF( ) is the smallest set with the following properties: if P a procedural term and 2 WFF( ), then P] 2 WFF( ).
The box operator P] distinguishes this simplified dynamic logic from a standard first-order logic. Assuming that P is a procedure application, its meaning is that, if P terminates, shall be a property of the state in which the procedure P terminates.
A notion of satisfaction relates formulas and -objects, i.e. it says when a formula is true (or holds in an object). Assume a -object A, a state ST2 State and a -formula . A satisfies in state ST, for a data sort s A ST j = t = state t 0 i v ( 1 (v (ST t )) f (a 1 :: a nc )) = v ( 1 (v (ST t 0 )) f (a 1 :: a nc )) for any term f(a 1 :: a nc ) A ST j = ! i : _ (with the usual definitions for : and _, omitted here) A ST j = P ] i D(P) ! A 1 (v (ST P)) j = ) Note that the definition of the equality for the state sort is observationally oriented. Two procedure applications are equal (observationally congruent) iff all function applications in the new states yield the same result for both procedures. The functions act as observers on the state. The behaviour of push is expressed by the 'observer' top. If the element b is pushed onto the stack st, then b will become the new top element. Now, we shall address the definition of a component. We use the definition from [NM95]. A component is an abstraction of a software structure that may be used to built bigger systems, while hiding the implementation details of the structure. We shall formulate components (abstracting objects) using the state transition logic as the specification notation. As a first step, we introduce an object specification as a pair h E i consisting of a signature and a set of well-formed -formulas E WFF( ).
Later on, we will formally define a component as a parameterised object specification.
Each object specification denotes a class of objects which satisfy the constraints formulated by the formulas, called the models of the specification. The class of all -objects is denoted with Obj( ). The models mod(h E i) of a specification h E i are denoted by their model class fA 2 Obj( ) j A j = for all 2 Eg.
We do not present a full inference system, but one inference rule shall be introduced. This rule will play a crucial role in our approach to reasoning about components and component composition. The consequence rule CONS helps to prove pre/postcondition specifications: This rule will be useful in the definition of a constructive variant of an implementation relation between object specifications. The validity of the rule should be clear from the definition of the satisfaction relation.

Implementation and Refinement
The foundation for the composition framework shall be laid in this section. We present two relations between object specifications and how they relate to each other. The first relation, called a refinement, is closely related to the CONS rule presented in the previous section. The second relation, called an implementation, is based on the semantic concept of model class inclusion. The implementation will be used to define the internal correctness of components and also the correctness of component composition. The second relation is the more powerful one, but difficult to prove. We will show that the refinement is much easier to use in proofs. It is, as we will show, a good approximation to the implementation. Therefore, the combination of implementation and refinement constitutes a flexible and easy-to-use framework for specifying and reasoning about components and component composition. In [Pah00] we have presented an application of these two relations, implementation and refinement, in a slightly different framework. There, the underlying semantic structures are Abstract State Machines ASM, foundation of a specification notation developed to specify dynamic state-based systems [Gur93,Gur97]. [Pah00] develops a refinement calculus geared towards the development of ASMs.
Let us now define the refinement.
Definition 4.1 Let p 1 p 2 be procedural terms with p 1 ! p 1 ] p 1 and p 2 ! p 2 ] p 2 as their respective specifications. The refinement relation p 1 R op p 2 holds, if D(p 1 )^D(p 2 ) ! ( p 1 ! p 2^ p 2 ! p 1 ) We will assume terminating (defined) procedure applications for this definition such that by execution of the procedure the postcondition can always be established. This can be found in the literature as the combination of the 'weaker precondition' and the 'stronger postcondition' rule, see e.g. [Mor94]. A module specification shall be considered as correctly implemented, if all constituent procedures are correctly implemented. Note the difference between the consequence rule CONS, as presented earlier on, and the refinement rule here. CONS is a derivation rule guaranteeing partial correctness.  The implementation relation is based on the purely semantical criterion of model class inclusion. The implementation between specifications defined by model class inclusion is standard in algebraic specification, see [Wir90].
where is I or R and sp 1 s p 2 s p 3 are object specifications.
The transitivity of relations in the vertical dimension is called the vertical composition property. Vertical development means implementation. In general, more abstract specifications are made more concrete by making design decisions, which is on the semantical level reflected by a smaller model class. There are less models if requirements are added or strengthened.
With the following theorem we will establish a relationship between the refinement and the implementation. The constructive refinement relation R will be shown as a specialisation of the implementation relation I . In order to relate the two relations I and R , we assume the three simplifications.
There are no explicit invariants inv 2 . They will be associated to procedure definitions: reformulate ! P] to ! P] ^inv.
There are only procedures. Functions are specified by normal first-order formulas and can be treated as invariants.
Every procedure is defined by only one formula.
These constraints do not restrict the expressivity of the notation. We can always obtain a specification following these constraints from any specification by semantics-preserving reformulations (as indicated).
Theorem 4.1 Let be an object signature and sp 1 and sp 2 be -specifications under the assumptions mentioned above. Then sp 1 R sp 2 implies sp 1 I sp 2 .
The implication sp 1 R sp 2 implies sp 1 I sp 2 can not be established, if the models contain functions which may not terminate, those formulas describing states are not satisfiable, or pre-conditions describe states not reachable from a given initial state. Making these three conditions assumptions of the above theorem, we would get equivalence between the two relations. Thus, we see that R is a good criterion (a good approximation) for I .

Components
In the next section, we will explain how the implementation can be used to define concepts for compoment composition. In this section, we define components as parameterised specifications. Parameters will be constrained, i.e. input requirements can be specified abstractly. In order to describe an internal correctness notion for components, the implementation shall also be used. A parameterisation concept using formal import to specify requirements for actual parameters is the basis of the component concept presented here. The import will be a part of the component specification. The import will be separated from the component body. The relationship of the import to the body is characterised by a notion of correctness.
Horizontal development is a notion for structuring specifications in the large and techniques to make this structuring feasible [EM85, EM90, Wir90, Hen91, HN92, Wir95, Goe93]. Component composition is one possible technique. Other techniques (not investigated here) include operators on components [PPP94, AAZ93, CL94, CHC90]. Our central aim is to use the implementation in the definition of the component composition technique. We will adapt components to satisfy import requirements in compositions, using syntactic and semantic mechanisms.
Let us assume that a given system is decomposed, or modularised, into components. Each of these components can be realised by hand or by reusing appropriate components for implementation. If, on the level of more abstract specifications, a system of components is correctly composed, then this correctness shall be preserved on the level of implementations of these abstract specifications. The correctness of compositions on the horizontal level shall be preserved. Thus, this property is called the horizontal composition property. It shall now be illustrated. Let C 1 and C 2 be components. C 1 (C 2 ) expresses, that C 2 is the actual parameter of C 1 . The composition C 1 (C 2 ) is correct, if C 2 satisfies the requirements of the formal import of C 1 . Let us now assume two more abstract components S 1 and S 2 , and two less abstract (implemented) components I 1 and I 2 . If the composition of abstract components S 1 (S 2 ) is correct, then the horizontal composition property requires that, if S 1 I I 1 and S 2 I I 2 are implementations, then I 1 (I 2 ) is a correct composition. This important property shall be realised in our framework.

Prerequisites
We need some basic constructs for our component composition approach. Essentially, we introduce the class of specifications as a complete partial ordering (cpo). The ordering relation on specifications is the implementation relation. Si gis the class of all signatures. ? Si g is the empty signature. The class Sp e ccomprises all possible models of specifications over Si g:

Components
A component is a parameterised object specification. A parameterised specification consists of a parameter restriction and a body. Elements of the formal parameter, or import restriction, are intended to be used in the specification of the body. Properties of the import specification should be preserved. An example could be a parameterised stack, where the import restriction describes the element type in its general properties, i.e. an ordering on the elements could be required, and should be preserved by the stack specification.
Definition 5.1 A parameterised specification C, called a component, is a pair C = hSP I S P B i of object specifications SP I and SP B . SP I is called import specification and SP B is called body specification.
A component C = hSP I S P B i can be formulated as a -expression X : SP I : S P B where SP I is a parameter restriction and SP B is a specification. X is a free variable. X can be used in SP B . X must not be used in SP I . The actual parameter will be assigned to X.  Note, that the implementation relation was used twice in the previous definitions: in the definition of the internal correctness of components and also in the correctness of the actualisation of an import restriction.
Example 5.1 Let C = hPair Stacki be a component specifying a stack of pairs. P a i r is a parameter restriction. It shall limit element to be stored on the stack to pairs of values. The signature of P a i r could look like: pair : e e ! p left: p ! e right: p ! e Additionally, P a i r will have some axioms such as left(pair(x y)) = x and right(pair(x y)) = y:

Composition of Components
We will introduce the composition of components in this section. Composition means plugging components together. Composition denotes here the actualisation of a formal import of one component by the service specifications of another. In the definition, C imports from C 0 . All imports from SP I have to be satisfied, but not all exports of SP 0 B have to be used. The signature morphism has to describe this adaptation. The actual import SP 0 B j has at least to fulfill the formal import SP I -or it can be better. We do not require an exact matching -neither syntactically nor semantically. This definition using a signature morphism for syntactical adaptation and an implementation for property preservation provides a high degree of flexibility in combining components.
Besides the flexibility in the relation between provided export of one component and actually required import of another component, composition also preserves correctness of components. Again, the definition is based on implementations SP B I I M B and I M I I SP I . This is illustrated in Figure 1.
Example 6.1 The parameter restriction Pair from the previous example can be actualised by, for instance, complex number providing a pairing operator complex : int int ! cplx and projections re: cplx ! int and im : cplx ! int. A standard specification of complex numbers, which shall be called C p l x , certainly satisfies the Pair-requirements. Additionally, arithmetic operations such as addition can also be provided by C p l x . In order to compose stacks with complex numbers, only the pairing operation and the projections are relevant. We need to actualise the formal parameter elements pair, leftand rightwith the actual parameter elements complex, reand im, respectively.
We can match the signatures easily. Under the assumption that complex numbers as constructed as pairs, the semantics also matches. An implemention between P a i r and C p l xrequires the same signatures (achieved by reducing C p l xto the signature of Pair) and model class inclusion. The reduct of C p l xshould have a smaller model class than P a i r , i.e. it should satisfy at least the Pairrequirements. Thus, the implementation Pair I C p l x j sig(P a i r ) holds, meaning that C p l xsatisfies the P a i r requirements. Thus, the composition is correct.
The correctness, which is essentially implementation, can be proven by a specifier using the refinement as an approximation to the implementation (as shown above in Section 4). The refinement is the tool for proving correctness notions in component specification and composition.
The following theorem formulates the central result of this section, the horizontal composition property for components. Elements of the horizontal composition property are illustrated in Fig. 2. The theorem guarantees that the correctness of compositions on the abstract level is preserved by their implementations. This allows components to be specified and composed on an abstract level and then implemented separately preserving the correctness of the whole system. There is no need to prove the correctness for implementations.

Related Work
During the last decade, algebraic methods have been used to support state-based software development. The classical notion of algebraic signatures is extended by introducing hidden, non-observable sorts representing an internal state. One of the well-known approaches to these problems is the hidden algebra framework developed by the OBJ-group, see e.g. [Gog99,GM00]. There, an equational, behaviourally oriented framework for reasoning is established. A hidden signature [Gog99] is a signature with disjoint hidden and visible sorts. The signature ensures data encapsulation: a hidden signature can only be embedded into a visible one, if no new operations are added. Components and transitions depend on the state. Our state signatures are clearly hidden signatures in the sense of [GM00]. A hidden algebra is an algebra which satisfies a hidden specification based on a hidden signature. A hidden algebra should encapsulate an algebra as a substructure (reduct) which represents the data part. Our objects are hidden algebras in this sense. Our objects are slightly less general since we only provide one hidden sort, the state sort state. One the other hand, our definition is more flexible in defining procedures, which can have a result value in our framework. Goguen and Malcolm's work show the way how to move from an object-based towards and object-oriented framework. Order sorted algebras could be used to model inheritance.
The naming of one of the relations -refinement -indicates its similarity to rules in the Refinement Calculus [Bac88,Mor90,Mor94]. Our refinement is derived from the consequence rule for dynamic and Hoare logics, see [Fra92,Cou90]. The consequence rule is a rule for reasoning about partial correctness. We have realised a refinement rule for total correctness, i.e. partial correctness plus termination, in order to ressemble the rules in the Refinement Calculus. Therefore, we have introduced a definedness predicate to make this explicit, see [MB98] for a treatment of partiality, definedness and termination in the Refinement Calculus.
The use of formal methods in component specification and composition is not new [Nor98,BS97,Wec97]. Weck [Wec97] discusses contracts (pre-and postconditions) as a means for component composition. Büchi and Sekerinski [BS97] present an interface definition language for components based on pre-and postconditions. They explore the idea of using refinement in their work, but their framework is less general than ours. We have realised a notion of observable behaviour through our definition of equality on the sort state. A similar idea of making observable behaviour the basic notion of component composition is presented by Nordhagen in her thesis [Nor98].
We have provided a framework for component composition. Similar aims are pursued by Nierstrasz et.al. [LSNA97,LAN00]. The main difference is that Nierstrasz' group considers objects as processes, using process calculi in the formalisation of the component and composition framework.
Another approach which relates to our work is described in [Goe93] where a component framework is developed. There, components are defined as a very abstract notion which fits various kinds of abstractions such as procedural abstractions or module abstraction. This work also considers statebased systems, but it does not provide a proof support in the way we do.
In the area of algebraic specification, we can find various approaches to specification in the large and in particular the composition of specification and operators on specifications [EM90,Wir95,HN92,PPP94].

Conclusions
Most of the current object-oriented programming languages provide only an ad-hoc collection of mechanisms for constructing and composing objects. A more structured and formally defined approach is needed. The composition framework we have presented here can be used as the basic foundation for such an approach.
We have considered components as black-box entities that encapsulate service implementations behind a well-defined interface. An important feature of our approach is that implementation and composition are realised as orthogonal concepts, connected only by the horizontal composition property. Our approach to composition is flexible, since it requires neither an exact syntactical nor semantical match between component interfaces.
The main focus of our paper was on mechanisms for reasoning about component composition. We have used an implementation relation in the definition of various correctness notions, including an internal component correctness and a correctness for the composition. This powerful relation is supported by a so-called refinement relation. This relation has two important characteristics. Firstly, it is easy to handle since it reduces the complexity of proofs in dynamic logic to non-modal first-order logic. Secondly, it is also a good approximation of the implementation. These two properties together make it an ideal proof support tool for components and component composition.
In the future, we want to build up upon our formal foundations for a composition framework and develop a composition language. In order to support a full composition framework, more (different kinds of) connectors are sought. The composition mechanism we have been looking at is connecting interfaces via parameterisation. This is the standard way of composing software components. Nevertheless, other forms of composition could be looked at, e.g. including communication between components.
The state STATE is independent from concrete signatures, since it is defined as a total mapping on the domain I d . STATE is in this form contained in all -objects of all signatures.
Since the model semantics is very loose, all carrier sets can contain arbitrary non-reachable elements for sorts in S. The only requirement with respect to carrier sets is the possibility to interpret the formulas and of a procedure specification ! p] , i.e. the -terms in the formulas must be interpretable by carrier elements. This is guaranteed for both specifications sp 1 and sp 2 , since they have the same signature, i.e. the same terms can be formed.
Properties of attributes are part of the invariants and are, therefore, part of specifications of procedures ( ^inv ! P] ^inv).
Instead of arguing for specifications and -objects, we can now, according to the investigations above, restrict ourselves to operations. Then, we can apply the implication:    hold (see Definition 5.3) and the -expression defines a specification function, i.e. it is monotonous with respect to (Theorem 5.1).

By assumption.
u t