Lecture Notes in Computer Science Edited by G. Goos, J. Hartmanis and J. van Leeuwen Advisory Board:
W. Brauer
D. Grie...
36 downloads
811 Views
13MB Size
Report
This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
Report copyright / DMCA form
Lecture Notes in Computer Science Edited by G. Goos, J. Hartmanis and J. van Leeuwen Advisory Board:
W. Brauer
D. Gries
J. Stoer
943
Wolfgang Klas Michael Schrefl
Metaclasses and Their Application Data Model Tailoring and Database Integration
Springer
Series Editors Gerhard Goos Universit~t Karlsruhe Vincenz-Priessnitz-StraBe 3, D-76128 Karlsruhe, Germany Juris Hartmanis Department of Computer Science, Cornell University 4130 Upson Hall, Ithaca, NY 14853, USA J a n v a n Leeuwen Department of Computer Science, Utrecht University Padualaan 14, 3584 CH Utrecht, The Netherlands
Authors Wolfgang Klas Institut ftir Integrierte Publikations- und Informationssysteme (IPSI) GMD - - Forschungszentrum Informationstechnik GmbH Dolivostr. 15, D-64293 Darmstadt, Germany Michael Schrefl Institut ffir Wirtschaftsinformatik und Organisationsforschung Johannes- Kepler-Universit~it Linz Altenbergerstrasse 69, A-4040 Linz, Austria C a t a l o g i n g - i n - P u b l i c a t i o n D a t a a p p l i e d for Die Deutsche Bibliothek - CIP-Einheitsaufnahme Klas, Wolfgang: Metaclasses and their application : data model tailoring and d a t a b a s e i n t e g r a t i o n / W o l f g a n g Klas ; M i c h a e l S c h r e f l . Berlin ; Heidelberg ; New York ; Barcelona ; Budapest ; Hong K o n g ; L o n d o n ; M i l a n ; P a r i s ; T o k y o : S p r i n g e r , 1995 (Lecture no~es in computer science ; Vol. 943) ISBN 3-540-60063-9 NE: Schrefl, Michael:; GT
CR Subject Classification (1991): H.2, D.3.2-3, E.1, 1.2.3-4, H.4-5 ISBN 3-540-60063-9 Springer-Verlag Berlin Heidelberg New York This work is subject to copyright. All rights are reserved, whether the whole or part of the material is concerned, specifically the rights of translation, reprinting, re-use of illustrations, recitation, broadcasting, reproduction on microfilms or in any other way, and storage in data banks. Duplication of this publication or parts thereof is permitted only under the provisions of the German Copyright Law of September 9, 1965, in its current version, and permission for use must always be obtained from Springer-Verlag. Violations are liable for prosecution under the German Copyright Law. 9 Springer-Verlag Berlin Heidelberg 1995 Printed in Germany Typesetting: Camera-ready by author SPIN: 10486371 06/3142-543210 - Printed on acid-free paper
Preface
Conventional object-oriented data models are "closed". Although they allow users to define application-specific classes, they usually come with a fixed set of modeling primitives. This constitutes a major problem as different application domains have different requirements on a data model. For example, database integration requires the possibility to overcome different representations of the same data. Or, multimedia applications need special support in handling different sources of data and in organizing inter- and intra-multimedia document references. At a first glance there are two common solutions to the problem: (1) Use different special data models for different application domains. (2) Use a common data model covering all specific application needs to more or less extent. The first solution leads to disintegrated and isolated applications, each using a different data model. The second solution has to cope with two opposite goals of the common data model, simplicity and specific application support. If the model is kept simple providing only general modeling concepts, it will be easy to handle and to understand, but it will not fully meet the requirements of each specific application. If the model is overloaded with too many specialized concepts, it is hard to manage and hard to understand, as for each application only a subset of the concepts the model provides is actually needed. The solution to this problem is to provide an "open" object-oriented data model, which is simple but which can be extended in itself by additional modeling concepts for specific application needs. Such models have recently been termed "RISC models" in anology to reduced instruction set computers [MH93] and found very relevant in providing meta object protocols for object system interoperability [MAN93, MH93]. The approach towards an "open" object-oriented data model also goes beyond the approaches of static, closed models as, e.g., taken in the international ODMG [CAT93] standardization effort. In this book, we present a solution to develop a RISC model using an extended metaclass concept. Whereas metaclasses usually determine only the structure and behavior of classes, our metaclasses also determine the structure and behavior of individual objects, i.e., instances of classes which are instances of metaclasses. We show, using VODAK, how the extended metaclass concept can be integrated homogeneously into object-oriented data models. For this purpose we introduce the basic concepts of the VODAK model (types, properties, methods, inheritance, classes, and objects) as far as they are relevant for the definition of the metaclass concept. The extended metaclass concept leads to an open data model that provides mechanisms to tailor it for particular application needs. We show this using examples from semantic data modeling and database integration. The work reported in the following is based on the thesis "A Metaclass System for Open Object-Oriented Data Models" by Wolfgang Klas and on the thesis "Object-Oriented Database
VI Integration" by Michael Schrefl. This work served as the basis for the open object-oriented database management systems project V O D A K 1 and the database integration project KODIM 1,2, and, in consequence, plays a crucial role in many application-oriented projects at GMD-IPSI, e.g., G A M M A 3 (Globally Accessible Multimedia Archives), DOCKING-D 4 (Computation and Prediction of Receptor/Ligand Interactions), the system engineering technology project MUSE 5 (Multimedia Technologyfor System Engineering) at the Technical University of Darmstadt, the electronic journals project M M F 1 (Multimedia Forum), HyperStorM (Modeling and Storage of hypertext and SGML structured documents), POL A R 3 (Public Office and Longterm Archiving and Retrieval). All these projects have demonstrated the applicability and usefulness of the concepts presented in this book, but also contributed to their further evolution as reflected by the released V O D A K prototypes. For more details of the V O D A K prototype releases and the mentioned projects see, e.g., the D/MSYS division description at GMD-IPSI available via W W W URL http://www.darmstadt.gmd.de/-klas.
May 1995
Wolfgang Klas Michael Schrefl
1) The projects were funded partially by the German Ministry of Research and Technology under grant IDA 1600AO. 2) KODIMhas been supported partially by the Austrian Science Foundation ("Fonds zur F6rderung der wissenschaftlichenForschung") under project P5976P. 3) GAMMA and POLAR are funded by DeTeBerkomGmbH, Berlin, under grant 2038/2. 4) DOCKING-Dis funded partially by the German Ministry of Research and Technology under grant 413-4001-01 IB 302 E/3. 5) MUSEis funded partially by the German Research Association ("Deutsche Forschungsgemeinschaft DFG") under grant He 1170/5-1.
Contents 1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
1.1 P r o b l e m Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
1.2 Related Work
3
..................................................
1.3 F r a m e w o r k . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
1 4 Outline
6
.......................................................
2 F u n d a m e n t a l Principles of Object-Oriented Systems 2.1 Introduction
....................
...................................................
8 8
2.2 Object-Orientation - W h a t Does it M e a n ? . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8
2.3 The Object-Oriented Paradigm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
2.4 Motivation and History o f Object-Oriented Data M o d e l s . . . . . . . . . . . . . . . .
11
2.5 Terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
2.6 N a m i n g C o n v e n t i o n s and some Notes on the E x a m p l e s . . . . . . . . . . . . . . . . .
13
3 B a s i c C o n c e p t s f o r M e t a c l a s s e s in the O b j e c t - O r i e n t e d D a t a M o d e l . . . . . . . .
14
3.1 Introduction
...................................................
14
3.2 Postulates on the Data M o d e l . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
3.3 Preliminary Definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
3.4 Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
3.4.1 Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
3.4.2 Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
23
3.5 Semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
28
3.5.1 Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
28
3.5.2 Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
29
3.6 O w n - t y p e s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
32
3.7 Classes as Regular Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
34
3.8 Instance-instance-types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
37
3.9 The Basic M o d e l o f M e s s a g e Passing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
43
3.10 Specific M e t h o d Inheritance B e h a v i o r . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
47
3.10.1 Semantic Relationships as Modelling Primitives . . . . . . . . . . . . . . . . .
47
3.10.2 General Characterization o f Semantic Relationships . . . . . . . . . . . . . .
50
3.10.3 M e s s a g e Handler Support for Inheritance via S e m a n t i c Relationships
53
3.11 Short-Hand Notations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
56
3.12 Defining a S c h e m a . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
56
3.12.1 S c h e m a . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
56
VIII 3.12.2 The Initial Metaclass System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
58
3.12.3 How to Specify a Schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
65
4 Semantic Data Modelling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
71
4.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
71
4.2 Object Specialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
71
4.3 Aggregation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
74
4.4 Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
76
4.5 Hypertext Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
78
5 Metaclasses for Semantic Data Modelling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
82
5.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
82
5.2 General Approach of Defining Semantic Modelling Primitives . . . . . . . . . . .
82
5.2.1 Defining Semantic Relationships Through a Single Metaclass . . . . . . .
82
5.2.2 Defining Semantic Relationships Through Multiple Metaclasses . . . . .
83
5.3 Object Specialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
85
5.3.1 Role Specialization of a Single Class . . . . . . . . . . . . . . . . . . . . . . . . . . .
85
5.3.2 Category Specialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
91
5.4 Aggregations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
97
5.5 Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
102
5.6 Role-Specialized Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
108
5.7 Hypertext Nodes and Links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
112
6 Object Class Definition by Generalization . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
123
6.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
123
6.2 Name and Scale Differences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
i23
6.3 A First, Unsatisfactory Approach to Generalization . . . . . . . . . . . . . . . . . . . .
124
6.4 A Second, Satisfactory Approach to Generalization . . . . . . . . . . . . . . . . . . . .
125
6.5 The Concept of Object Coloring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
126
6.6 Solving Name Differences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
126
6.7 The Concept of Object Transformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
127
6.8 Solving Scale Differences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
127
6.9 Object Coloring vs. Object Transformation . . . . . . . . . . . . . . . . . . . . . . . . . . .
128
6.10 Upward Property Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
130
6.11 Different Types of Generalization Classes . . . . . . . . . . . . . . . . . . . . . . . . . . .
131
6.11.1 Semantic Relationships Between Object Classes . . . . . . . . . . . . . . . . .
131
6.11.2 Semantic Relationships Between Properties of Objects . . . . . . . . . . . .
133
6.11.3 The Representation of Semantic Relationships between Object Classes 136
IX 6.11.4 T h e R e p r e s e n t a t i o n of S e m a n t i c Relationships b e t w e e n Properties o f Objects
...............................................
140
6.11.5 M e s s a g e T r a n s f o r m a t i o n and U p w a r d Property P r o p a g a t i o n . . . . . . . .
141
6.11.6 Integration of Relationships . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
144
6.11.7 Integrating Data-Type-Classes and A b s t r a c t O b j e c t Classes . . . . . . . .
146
6.12 S u m m a r y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Metaclasses for Object Class Definition by Generalization ................ 7.1 Introduction 7.2 L o c a l Classes
149 150
...................................................
150
..................................................
150
7.3 G e n e r a l i z a t i o n Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.3.1 Category G e n e r a l i z a t i o n Classes
..............................
154 159
7.3.2 Role G e n e r a l i z a t i o n Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
160
7.3.3 Data Type G e n e r a l i z a t i o n Classes
166
7.4 O b j e c t C o l o r i n g
.............................
................................................
7.5 S u m m a r y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 M e t a c l a s s e s in o t h e r O b j e c t - O r i e n t e d S y s t e m s . . . . . . . . . . . . . . . . . . . . . . . . . . 8 1 Introduction
...................................................
166 168 172 172
8.2 S m a l l t a l k - 8 0 Metaclasses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
172
8.3 C L O S M e t a c l a s s e s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
176
8.4 L o o p s M e t a c l a s s e s
177
..............................................
8.5 M e t a c l a s s e s in O t h e r L a n g u a g e s and M o d e l s . . . . . . . . . . . . . . . . . . . . . . . . . .
177
9 Conclusion
.......................................................
178
10 L i t e r a t u r e
.......................................................
182
A p p e n d i x A: I n d e x to T y p e s a n d C l a s s e s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
191
A p p e n d i x B : I n d e x to F u n c t i o n s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
193
Appendix C: Summary of Formal Notation ...........................
194
A p p e n d i x D: T a b l e o f D e f i n i t i o n s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
195
Appendix E: Table of Figures .......................................
196
A p p e n d i x F: T a b l e s
201
...............................................
1 Introduction 1.1 Problem Description One major benefit claimed for object-oriented database systems is extensibility. Whereas traditional data models support only a small set of built-in types, object-oriented systems allow users to define their own types or classes. The class concept has been originally introduced in Simula [DAHL66] and reimplemented in Smalltalk [GR83]. A class describes the structure and behavior of a set of objects, called its instances. To support reusability and application development, classes can be organized in a class hierarchy in which subclasses inherit property definitions and methods of its superclasses. Although object-oriented data models allow users to define their own classes, they come with a fixed set of data model primitives. We consider this a major problem as different application domains have different requirements on a data model. For example, database integration requires the possibility to overcome different representations of the same data. Multimedia applications need support in handling different sources of data. Hypertext applications need flexible concepts for organizing inter- and intra-document references. If a data model is designed to cover many application domains, there are two dangers: On one hand, the data model may be kept too general and does not fully meet the requirements of specific applications. On the other hand, the data model may be overloaded with too many specialized concepts and is hard to understand. Alternatively, different data models may be developed for specific application domains and thus take into account their needs. This solution, however, leads to disintegrated and isolated applications, each using a different data model. In the following we describe the problem of data model tailoring in more detail. Information processing means to store, retrieve, manipulate, and interpret data with respect to what these data mean in reference to the world that is the source for this information. Database systems play a crucial role for applications which have to process large bulks of information. One of the primary goals of a database system is to isolate the representation of the information processed by application programs from these programs and to provide for the sharing of persistent data. Conventional database systems provide the isolation of data structures from the programs such that the application programs will become independent of the internal structure of data. But they do not support any control via the semantics of that data. That is, using a conventional database system for general information processing means doing all the procedural manipulations and interpretations of the data in such a way that the application program remains responsible for the correct access and manipulation of the internal structure of the data and for its interpretation. The high degree of complexity in very large systems requires the transfer of responsibility for applying operators to data (e.g., any kind of interpretation, manipulation, or transformation) from the application program to the data itself. Therefore, a second aim of the forthcoming generation of database systems is to support the isolation of the semantics, not just the struc-
ture of data from programs, making the application programs independent of the data and the operations involved and defined. In this case the correctness of the manipulation of complex structured information can be guaranteed independently of the application program, because they are decoupled from the applications to a larger extent. Several components of a database management system have to be taken into account in order to realize the requirements: the data model, the transaction management and the underlying model of concurrency control, the integration ofinferencing techniques, and distributed storage management. The role of a data model within that framework is to provide a mapping of a part of the real world to a model processed by a program. This is a crucial role since the data model determines the expressiveness for the representation of the information. Limitations reduce the possibility of the semantic based data management by a database system. The most important limitations of conventional database models can be summarized as follows:
1.
Structural representation: Data is represented by simple structures (e.g., relations in first normal form) determined by a fixed set of built-in types and type constructors. Therefore, complex structured data is split into several simple structured pieces which have to be bound together at run-time by the application program. For instance, if one wants to represent complex CAD-objects in a relational database system, the objects are modelled by several relations and can only be retrieved as entire objects by employing several joins in the application program. No constructors are provided to create complex structures on a more persistent basis.
2.
Operations: The data models neither support complex structured data types nor operations defined on such complex data types. The application programs interpret simple structures in a way that represent the meaning of them as part of the 'virtual' complex structure. For example, they have to manipulate the complex structures in a consistent way such that they do not violate the consistency constraints required for proper instances of these complex structures. No support cab be provided by the database systems for that crucial task. The application programs are only decoupled from simple data structures but they are not spared from the responsibility of a consistent and uniform interpretation and manipulation of complex structured data. In other words, the application programs are not made invarient to changes of the complex structured representation and its (procedural) interpretation and manipulation as the semantics of these data is not captured by the database system.
3.
Model extensibility: Even data models that handle complex structures and operations only support a limited number of modelling primitives. These built-in primitives cannot be changed since the models do not support any mechanisms which would allow the adaption of the model for special needs. Such "frozen" data models provide a fixed set of semantic modelling primitives and cannot be tailored for the needs of a specific application field.
It is the purpose of this work to integrate the necessary mechanisms for a solution of problem 3 with the concepts of a data model that has been defined to solve problems 1 and 2. 1.2 Related Work
Ongoing research focuses on solutions to overcome the limitations mentioned in the previous section. Next generation database projects like POSTGRES [SR87a, SR87b], DAMOKLES [ABR87], DASDBS [SW86, PSSW87], ORION [WKL86], ENCORE [ZW86], GEMSTONE [MSO86], O2 [BANC88, DEU90], VODAK [KAN94, KFA94, CTK94, AKF94, KN93, MRKN92, MR91, KN90, KNS90, RGN90, MKN90, KNS89a, KNS89b] try to develop concepts which reduce or overcome some of these limitations. Two major directions have to be distinguished: (i)
Projects like POSTGRES, DAMOKLES and DASDBS, which are based on the well known relational data model and on the entity relationship model, primarily extend these models with features like user-defined abstract data types, restricted procedural data types and simple rules systems (POSTGRES), user-defined complex structured object types (DAMOKLES) or nested relations (DASDBS). These kinds of extensions soften up some of the limitations, but they do not really solve the problems caused by the limitations. User-defined abstract data types as well as procedural types extend the set of available storage structures, but they do not extend the relational model itself. Similarly, complex structured object types provide more complex representations, but they do not support the needed complex operations and such do not extend the entity relationship model. None of the models provide any mechanism which allows its extension with additional modelling primitives.
(ii)
Projects like ORION, ENCORE, GEMSTONE, O2 are based on the object-oriented modelling approach. Their object-oriented data models have the advantage of uniform extensibility. That is, a user-defined type is indistinguishable from the built-in types. New types become part of the data model. Since the model is not fixed, it is only possible to talk about the kernel of the model. Again, these models do not provide any mechanism which allows the introduction of new semantic modelling primitives like special inheritance behavior or special semantic relationships.
Thus so far, only the first two limitations mentioned in the previous section are addressed by the projects mentioned above. Object-oriented database systems (ii) combined with elaborate conventional database management techniques may provide a satisfying solution for most of these addressed problems. They seem to be well suited to solve some of the problems of information management, because they support the capture of data and their semantics and it will facilitate the processing of information with respect to their meaning. In contrast, the projects following the direction (i) partially lack the capture of data semantics, since they do not provide the modelling of operations on complex structured data types. The third limitation can be overcome either by developing a "universal data model", which seems like a hopeless venture, or by providing a data model with appropriate instruments
which allow the extension of the model with additional user-definable modelling primitives. The latter approach leads to an open and flexible data model that can be tailored for particular needs by the user. Herein we propose an approach that can be used (1) to make an object-oriented database model an open and flexible model which can be tailored for particular uses and (2) to implicitly provide additional modelling principles as an extension of the built-in instantiation mechanism. For instance, the model can be enriched/extended with special semantic relationships and with different strategies for inheritance behavior. On the other hand, different abstraction levels of the real world to be modelled can be combined in a homogeneous way. The idea is to reapply the same principles as they are characteristic for object oriented data models to introduce the appropriate mechanism via the metaclass concept. We integrate the metaclass concept homogeneously with the fundamental object-oriented principles (see Chapter 2). The metaclass concept allows us to specify the "metaknowledge" needed to tailor the model or to introduce new modelling primitives in the same language in which we describe the real world domains. Metaknowledge has been used in AI in several areas (for a summary see [AL88]), e.g., proof strategies in automated deduction systems, increasing the expressive power of knowledge representation languages, control strategies for the user interaction with a knowledge base, and inference control in problem solving, where the use of metaknowlege has been strongly advocated. In general, our approach follows the direction which can also be found in the area of inference control in problem solving. The approach there was to try to describe processing strategies in a language at least as rich as that in which one can describe the external domains, and, for the purpose of good engineering, this should be the same language. The approach introduced in the subsequent chapters provides the specification of metaclasses in the same language in which the real world things are modelled. Hence, the model provides at least the same expressive power for the specification of the metaknowledge needed to tailor the data model as for the modelling of real world objects. 1.3 Framework The research described in this book is embedded into two research projects at the GMD institute 'Integrated Publication and Information Systems Institute' (GMD-IPSI), VODAK 7 and KODIM 6,8. VODAK has been established in order to develop object-oriented database technology. Within the framework of that project appropriate concepts for an open object-oriented data model, concurrency control, transaction management as well as a prototype have been developed [KAN94, KFA94, CTK94, AKF94, KN93, MRKN92, MR91, KN90, KNS90, RGN90, MKN90, KNS89a, KNS89b]. The motivation of VODAK is described beT) The projects were fundedpartially by the German Ministry of Research and Technologyunder grant No. IDA 1600AO. 8) The project KODIM has been supported partially by the Austrian ScienceFoundation ("Fonds zur F6rderung der wissenschaftlichenForschung")under Project No. P5976P
Object-oriented database model
I
theaatamodelt.rouo.Metacla 1
seman
multi-media object i database integration
Figure 1.1: Metaclasses allow to tailor the data model for specific needs. low. KODIM, (Knowledge Oriented Distributed Information Management) is intended to provide information management facilities to support homogeneous access to heterogeneous private and public databases [FHK94, BFN94, KDN89, NS88, SN88a, SN88b, FN92]. The tools under development include graphical systems to support dynamic global schema design on top of the VODAK environment. The primary goal of the VODAK project is to design a database management system (DBMS) which can be used in several specific application areas like database integration, structured document management, multimedia object modelling, or storage of large amounts of hypertext documents. Hence, the DBMS has to provide an open and flexible data model that can be tailored for specific needs. The concept of metaclasses we propose corresponds to the instrument which allows the definition of specific models for different application areas in a homogeneous way (Figure 1.1). The VODAK database management system provides a data model which can be enriched by specific modelling primitives designed e.g., for the representation of structured documents [ABH94, BAH94, BAH93], hypertext structures [KN90], multimedia information
[KNS90], and part relationships [HGP93]. Through appropriate metaclass definitions a database system may be adapted for a specific application domain. A conventional DBMS, e.g., a relational database system, does not provide mechanisms which would support any enrichment of the data model, e.g., the relational model. Hence, the DBMS serves as the DBS in several application domains. If the database management system belongs to the class of extendible database systems (e.g., POSTGRES), the user may extend the set of attribute types by user defined types. For instance, in POSTGRES a designer may define specific geometric abstract data types like box, circle, point, and line. These types extend the predefined set of attribute types and adapt the data model for the modelling of geometric applications. This is a first step to adapt the database model for special needs. More complex structures or special internal representations of data may be made available for the designer, although this extension is not supported by the internal features like indexing or clustering performed by the database management system. Specifically, it does not allow to change the constructors by which the complex data types can be defined. In our case, the underlying data model also provides user defined types. Therefore, it might be classified as an extendible data model. But the metaclass concept allows the extension of the data model with additional user defined modeling primitives. Hence, the model becomes an open data model, something like a construction system, where metaclasses are the tool to build a data model with specific modelling primitives. In this book we demonstrate in particular how metaclasses can be used to extend a kernel data model with various semantic data model primitives and object classes supporting database integration. [KAN94] describes how the data model can be extended to model hypertext and versioned documents. [BAH93, ABH94, BAH94] give an overview of modelling structured documents. [KFA94] illustrates the usage of metaclasses to realize the access to a relational database system by VODAK in the framework of interoperable database systems. [AKF94] shows how metaclasses can be used to adopt the VODAK system to particular requirements of user assisting query processing. [HGP93] reports on the design and implementation of a metaclass library for part relatinships. 1.4 Outline Chapter 2 introduces the fundamentals of object-oriented systems. It briefly explains the meaning of object-orientation and characterizes the object-oriented paradigm. The motivations, the major benefits and a partial history of object-oriented data models will be described. Furthermore, specific terms usually employed in this research area are summarized and the terminology and naming conventions used in the subsequent chapters are introduced. Chapter 3 presents the basic concepts of the object-oriented data model of VODAK that are relevant for the development of the metaclass concept. These concepts are types, properties and methods, type specialization (inheritance), objects, classes, and message passing. The uniform treatment of classes and instances of classes as objects leads to the concept of metaclasses, which is homogeneously integrated with the basic concepts of the data model. In ad-
dition, this chapter describes the general scheme of how the structure and behavior of objects are determined: A type associated as instance-type with a class determines the structure and behavior of the instances of the class, a type associated as own-type with an object extends the definitions for the object, and a type associated as instance-instance-type with a metaclass extends the definitions for the instances of the instances of the metaclass. These concepts and their definitions are introduced incrementally starting with a few postulates on the data model. Furthermore, the notion and a general characterization of semantic relationships are described. The model of message passing is extended in order to provide for the handling of method inheritance via semantic relationships. In addition, the concept of database schemas is introduced and some rules for specifying database schemas are stated. Chapter 4 introduces a few semantic modelling primitives which are useful for semantic data modelling. It informally describes the concepts of object specialization, aggregation, and components, as well as some specific modelling primitives needed to model a specific kind of argumentative networks based on hypertext structures. In Chapter 5 we first describe two alternatives of a general scheme of how to employ the concept of metaclasses to introduce semantic relationships as modelling primitives into the data model. Second, we show how the data model can be tailored such that it includes the modeling primitives which have been introduced in chapter 4. For each modelling primitive we give a more formal description and specify appropriate object types and metaclasses. In Chapter 6 we investigate how object classes of multiple object-oriented databases can be integrated to a global view [SL90, BLN86]. In particular we show how the principle of object class definition by generalization [BL84, DW84, NEL86] can be incorporated into objectoriented systems and how upward inheritance can simplify this task. To keep the integration effort small the user can choose among a set of different types of generalization classes, which combine the local subclasses using predefined semantics. Chapter 7 introduces the basic metaclasses for database integration. We show how the concepts described in the previous chapter can easily and efficiently be supported by metaclasses. Chapter 8 gives a brief overview of the usage of metaclasses in other object-oriented systems. Chapter 9 concludes the book with a summary and a short discussion of future research issues.
The reader interested in the concept ofmetaclasses and its usage for data model tailoring can independently read chapters 1 to 5. Database integration issues as another sample application of metaclasses are captured in chapters 6 and 7.
2 Fundamental
Principles of Object-Oriented
Systems
2.1 Introduction The term object-oriented seems to be the buzzword of the 1980s and 1990s. Everybody is using it, but with such a wide range of different meanings that no one seems to know exactly what the other is saying. It appears in several disciplines, including programing languages, databases and knowledge bases, artificial intelligence and computer systems in general. Without first precisely defining key terms, no understanding about terms like object, class, or inheritance can be expected. Hence, the following sections briefly focus on the questions: What does object-oriented mean (for us)? What are the fundamental principles of an objectoriented approach? What are the motivations for object-oriented data models, what are their benefits, and what is their history? An addition, a brief characterization of the object-oriented paradigm is given as well as an overview of terms used within this book. 2.2 Object-Orientation - What Does it Mean?
Object-orientation can be seen as a kind of technique of organizing a system in terms of objects. The foundation of the whole approach is encapsulation. This means that the properties of data and the procedures for the manipulation of this data are combined into an object. Encapsulation restricts the effects of change by placing a wall of code around pieces of data. The objects communicate through messages which invoke the objects procedures, usually called methods. Hence, manipulation of the data is provided by those methods only. By contrast, conventional programming makes the user of each operand responsible for choosing operators that are type-compatible with the operand. The philosophy of object-oriented programming moves this responsibility from the user to the operand and its designer. These encapsulated operands are called objects in the framework of object orientation. Whereas in a conventional programming language the user specifies how each operation should be performed by naming a specific piece of code, in an object-oriented language he specifies only what should be done by sending a message to the object. The object then chooses the code that is appropriate to its type. In [WEGN87a] six orthogonal dimensions of object-oriented languages are identified: object, type, inheritance, abstraction, concurrency, and persistence. Whereas the dimensions object and abstraction reflect the basic principle of encapsulation, which can be found in conventional languages like Modula-2 or Ada, inheritance is the more innovative part of the approach, because it is not provided by these conventional programming languages. It is a tool for (automatically) broadcasting definitions of attributes and methods from already defined pieces of data and operations to pieces developed separately and thus supports reusability. It has originally been introduced in the field of AI [e.g., BS81, GK76, COX87].
The dimension of concurrency introduces the term process. A process-based language extends the autonomy of objects to the autonomy in time, that is, operations may be executed concurrently or separately depending on the systems need or even started by these needs (triggers, daemons). Adding the dimension of persistency reflects the fact, that there is a trend toward extending object-oriented programming languages in the direction of databases, This occurs in parallel with the attempt of extending database systems with object-oriented ideas. However, objectoriented languages and object-oriented databases are natural complements of one another. The first one emphasizes processing, complex structuring and local data, the second one focuses on a more declarative approach, consistency, persistency, sharing, and support for very large amounts of data. The merger of these activities could be an object-oriented database programming language which combines the aspects of a programming language and a database model. Further essential object-oriented concepts are object-identity and polymorphism. The first one means that an object exists independent of the value it represents. This allows objects to share subobjects and to be cyclic. Furthermore, such objects can be updated without loosing their identity. The latter one provides the overloading of methods such that the same message elicits (semantically similar) responses depending on the class of the receiver object. Note, that this is facilitated by the message-passing paradigm as a message specifies only a method identifier for an object and not the code to be executed. In the field of database systems three levels of object orientation have been distinguished based on the power of the database model [DIT86]: (i)
A structural model allows to define data types of any complexity to represent structurally complex objects.
(ii)
An operational model as an extension of the structural model allows the definition of generic operators to handle the complex data types.
(iii) A behavioral model allows to define complex types together with specific operators for these types. Properties of an instance of such an object type can only be accessed by calling these operators. Only such a model is truly based on the object-oriented paradigm, but usually (i) and (ii) are also called object-oriented models. The data model described in Chapter 3 satisfies the requirements of a behavioral model.
2.3 The Object-Oriented Paradigm The object-oriented paradigm as the basis of the concepts proposed in this book can be characterized by the following principles: Encapsulation of data and methods: Encapsulation provides data abstraction. That is, the state of an object is accessible
10 only through its methods. The state of the object is generally represented by variables which are hidden from the clients. The implementation of the methods are not visible outside of an object. 9
Methods and message passing: A method is a piece of code that implements an operation on an object state. The set of methods defined for an object determine the behavior of the object. Objects communicate through message passing. A message consists of an addressee, a method selector, and possibly several actual parameters. In response to a message, the receiver invokes the method identified by the selector specified within the message.
9
Classification and instantiation: Objects are collected into classes. A class determines the structural and behavioral properties of its instances. The structural properties are specified by a set of variables, the behavioral properties by a set of methods.
9
Class taxonomy and inheritance: A class is interpreted as a template for the creation of the instances of the class, i.e., it defines both the type of these instances, and the way these instances are created as reflections of real world 'things'. Classes are organized in a lattice. A class may inherit operations from "superclasses" and may have its operations inherited by "subclasses". Inheritance is defined narrowly as a mechanism for resource sharing in class hierarchies.
These fundamentals, although defined and realized differently, are common to all object-oriented systems. For an overview and discussion of the principles of the object-oriented paradigm the reader is referred to e.g. [ABD89, KA90, ZM90, HEU92]. Object-orientation aids system understanding, i.e., analysis, design, construction and maintenance in general. But, the main advantages of the object-oriented approach are the following ones:
Extensibility, flexibility, and changeability: Most DBMSs provide a fixed set of data types (e.g., relational DBMSs provide relations and field types). An object-oriented system provides (1) predefined classes/ types, (2) mechanisms to define new classes/types, and (3) a uniform way of treating system and user defined classes/types. Hence, new object classes/types including their methods can be incorporated uniformly into the system. Changes of object types/classes and their methods are localized to the relevant types/classes and are much easier controlled than in conventional record-based systems, where many record types may be affected by a change.
Consistent interpretation of data: Because of encapsulation, the behavior associated with an object type is predetermined by a fixed set of operations. Therefore, the database operations are constrained to be within the specifications of these operations. This induces a more consistent interpretation of data by application programs.
11
Modelling power: Inheritance of both variables and methods is a very powerful tool for data modelling. It is a kind of modularization and supports the specification of reusable type definitions. In general, the modelling principles of generalization/specialization, identification, and aggregation are well supported in some object-oriented data models. The fundamental concepts of this paradigm will be extended and modified in several ways in the following chapters. This will lead to more precise definitions and it will avoid semantic overloading of concepts.
2.4 Motivation and History of Object-Oriented Data Models The motivation for object-oriented data models can be summarized by the following two isSUES:
9
Impedance mismatch: Applications using conventional database technology suffer under the need of two different languages, a database language (e.g., SQL) and a host language (e.g., COBOL, PL/1). Since the type systems of these languages differ data must be converted from one language environment to the other one, and often type checking is lost. Different processing strategies (sets vs. record-at-a-time) require concepts like a cursor to scan relations. In contrast to the host language the database language is incomplete with respect to computation and recursion. Furthermore, the database language usually is a declarative one, whereas the host language is procedural.
9
New applications require non-standard and complex objects and operations: The conventional database technology does not satisfy these special requirements e.g., in the field of AI, CAD/CAM, Engineering, CASE, or (multimedia) office automation, although database technology plays a crucial role in all these fields. New modelling techniques, the handling of complex structures and multimedia data are required as well as extensibility and flexibility, next to a high degree of modularity and reusability for building these complex applications.
Object-oriented programming languages have their root in SIMULA [DAHL66] which has been developed around 1966. The abstract data types introduced by SIMULA correspond to classes in object-oriented languages. This concept has been reimplemented in SMALLTALK [GK76, GR83]. In addition, several object-oriented programming languages have been introduced, e.g., C++ [STR87] and Objective-C [COX87], which are hybrid languages that provide object-oriented programming concepts on the basis of C. In parallel (1974 - 1985), several semantic data models e.g., the Entity Relationship Model [CHE76], SHM [SS77], RM/T [COD79], DAPLEX [SHI81], SDM [HM81], GEM [ZANI83], SHM+ [BR84], THM [SC83a], and TAXIS [NCLB87] have been developed. For a comparison and for further descriptions of these data models the reader is referred to [HK87]. Following the development of the first object-oriented programing language SMALLTALK many variants of object-oriented data models have been introduced, e.g., 0 2 [BANC88, DEU90], Vbase/ONTOS
12 [VBASE88, ONTOS91], GemStone [MSO86], ORION [BANE87], ODM [KB85], PDM [MD86]. There is still no agreement on the essential and relevant concepts, not to mention that there does not exist a common underlying theory. Only first attempts have been made of formalizing object-oriented data models and concepts (e.g., [BEE90, DKT88, RV87, AH87]). A major step towards a common understanding and agreement on object-oriented data modeling concepts is the ODMG proposal [CAT93] supported by almost all object-oriented database system vendors. The main difference between object-oriented languages and databases is that the latter focus on the persistency and sharingof objects stored permanently in secondary storage, whereas objects in an object-oriented programming language exist only during a program's execution.
2.5 Terminology Before we define the concepts of our data model, we give a summary of the terms as they are used in this book. More detailed descriptions of the meaning of these terms are given in the subsequent chapters.
Object
A data item represented by some private memory and a set of operations. The structure of the private memory is determined by property definitions, and the operations are specified by method definitions.
Class
An object that collects similar objects and determines the implementation of that set of objects. A class implies the structure and behavior for these objects.
Instance
An object collected into a class.
Metaclass
A class whose instances are classes.
Type
An abstract data type; a collection of definitions for the structure of an object and its methods. A type may be built on other types.
Subtype
A type built on other types (supertypes) such that it is a more specialized description.
Supertype
A type which is used by other types (subtypes) such that they are a more specialized description.
Instance-type
A type which is associated to a class and which is utilized to determine the structure and behavior of the instances of that class.
Instance-instance-type A type which is associated to a class and which is utilized to determine the structure and behavior of the instances of the instances of that class.
13
Own-type
A type which is associated to an object and defines the object's structure and behavior. Thereby it may be utilized to extend individually the structure and behavior of the object.
Method
A description of how to perform one of an object's operations. It is made up of a method signature, temporary variable declarations, and a sequence of statements that refer to the temporary variables and the properties of the object.
Message
A request for an object to carry out one of its methods.
Interface
The set of messages to which an object can respond.
Object-oriented data model A data model which is a behavioral model that follows the objectoriented paradigm.
Receiver
The object to which a message is sent.
2.6 Naming Conventions and some Notes on the Examples The examples in this book follow some conventions: Names or symbols in general contain a prefix or suffix which intuitively clarifies the meaning or usage of the symbol such that a better readability of the examples is provided. Consequently, e.g., names denoting a type are constructed by appending a suffix 'Type', '_InstType', or '_lnstlnstType'. Class names are all upper case, type names start with a capital letter, property names start with lower case letters. If several symbols are used to construct a name, the second symbol and the following symbols start with a capital letter, or they are combined via the ' - ' sign, e.g., 'severalSymbolsConcatenated' or 'several-symbols-concatenated' may be a property name. If the context within which a symbol is used is unmistakable, the prefix or suffix may be omitted. Names denoting a class are chosen such that they express the kind of instances of the class, e.g., the instances of a class STUDENT model students, or the instances of a class X-CLASS are classes themselves, which is expressed by the suffix CLASS. The examples which have been chosen to demonstrate the concepts described in this book illustrate only the concepts under consideration. This allows us to operate with simple clear examples. Details of an example which do not contribute to the illustration of a concept are omitted and are assumed to be self-understood by the reader.
14
3 Basic Concepts for Metaclasses in the Object-Oriented Data Model 3.1 Introduction This chapter incrementally introduces and describes the fundamental concepts of the objectoriented data model as far as these concepts are relevant for the introduction and definition of the metaclass concept. First, we characterize the data model by four postulates. Based on a few preliminary definitions the concepts of types, type specialization, instance-types and classes are introduced as well as the relationship between types and classes. Furthermore, we describe the semantics of class definitions, the definition of objects, and the interpretation of classes as objects. We incrementally introduce the concepts of own-types and instance-instance-types, and we describe the message passing mechanism. The symbols and the operators used for the formal notation of the concepts are summarized and explained in Appendix C.
3.2 Postulates on the Data Model The extensions of the fundamental principles of the object-oriented paradigm described in Section 2.3 will be introduced incrementally along the following postulates: (i)
Types: The structural and behavioral properties of objects are defined through types. A type can be defined as a subtype of other types. Types realize encapsulation and inheritance.
(ii)
Classes: A type is associated with every class. This type is referred to as instance-type. It defines the structural and behavioral properties of the instances of the class. Every class has an extension, the set of its actual instances. The separation of types and classes facilitates the definition of semantic relationships on objects. This will be explained in detail later.
(iii) Objects: Every object is instance of exactly one class 9. The instance-type of the class defines its properties. These definitions can be extended by associating another type to the object, the own-type. For integrity reasons, the own-type may only define additional properties but not alter properties of the instance-type. Again, the details will be given later. (iv) Classes are objects themselves. Hence, a class is an instance of another class, referred to as metaclass. The initial primitive metaclass is the class VML-CLASS, which is its own instance. These postulates impose features on the data model that allow us to integrate metaclasses homogeneously. Before the metaclass concept is presented itself, it is explained how these postulates are realized. 9) Note,that this postulate does not say anythingabout the mapping of real world objects to objects of the data model. It allows to represent a real world object by more than one object in the system.
15
3.3 Preliminary Definitions Before we present the definitions for types, objects, and classes, we need some preliminaries. The following sets, which serve as a resource for names of properties and methods, and identifiers for types and objects, are defined: PropName set of symbols (serve as names of properties), MethName set of symbols (serve as names of methods), VarName set of symbols (serve as names for method parameters, local names), OTypeld set of symbols (object type identifiers), DTypeld set of symbols (data type identifiers), OTypeld n DTypeld = 0. Objld set of symbols (object identifiers), Classld set of symbols (class identifiers), Classld c_ Objld.
3.4 Syntax 3.4.1 Types The structure and the procedural behavior of objects are defined through abstract data types which we call object types. The definition of an object type consists of a set of structural and behavioral property definitions. Every structural property definition consists of the name and the type of the property. Structural properties determine the structure of an object. The values of the structural properties constitute the state of an object. A behavioral property is defined by a method definition, where the name of the property constitutes the method selector and the type of the property constitutes the result type of the method. Optionally, a method definition may specify a set of formal parameters, i.e., the names and the types of the parameters. The structural properties of an object are defined with an object type. They can be read or manipulated only by executing an appropriate method defined with thesame object type. Every object type definition is identified by a unique type identifier T e OTypeld, and P ~ OTD is the map that assigns to an object type identifier an object type definition, where
OTD
=
OTypeld ~-~OTypeDef
and OTypeDefis the domain of object type definitions. As we will see later, object types are used to specify the structure and behavior of objects, which can uniquely be identified by object identifiers in the data base.
Property Definitions The types used for the definition of structural properties, formal parameters, and results of methods are either primitive types or complex types which can be built from predefined primitive types and object types by applying type constructors. We call such types data types as the values of these types are not stored as separate objects in the database, which could be identified by an object identifier.
16 The data model offers basically the following type constructors: union type, tuple type, reference type, substitution type, and general collection type constructors (e.g., set type, array type, etc.). Similar to an object type, a data type may be identified by a unique identifier t 9 DTypeld, and 119 DTD is the map that assigns to a data type identifier a data type definition which is a wellformed type expression, i.e.,
DTD
=
DTypeld ~-->TypeExpr.
In the following we define the set of predefined primitive types and the set of well-formed type expressions similar to the definitions given in [DKT88].
Definition 1: ( Primitive Types ) The set of primitive type identifiers PrimTypeld = { Integer, Float, Bool, Char, String, Oid, Sel, Void}. That is, PrimTypeldcontains the usual basic types of a programming language, where Oid is a pointer type used to refer to any object, Sel is the type of a method name (selector), and Void is a special type identifier used in methods which do not return any result. To each primitive type p 9 PrimTypeld we assign a predefined domain of values which is denoted by ] p ] . Every predefined domain except [ V o i d ] contains the element undefined. For instance, ] I n t e g e r ] = Z u {undefined}, ] F l o a t ] = R u {undefined}, the domain of Oid ] Oid] --- Objld u {undefined}, and the domain of Sel ] Sel ] = MethName u {undefined}, where Z denotes the set of integers, R denotes the set of reals, Objld denotes the set of object identifiers., and MethName denotes the set of method names. The domain of Void is the empty set, i.e., [ Void] = { }. In addition to the usual operators defined with the types Integer, Float, Bool, Char, and String, the boolean operator isNull is defined for each v 9 [ p ] , p 9 PrimTypeld: true, if v = undefined, isNull(v) = false, otherwise, w
Definition 2: ( Data types, type expressions ) DTD = DTypeld ~-->TypeExpr, and 9 DTD is the map that assigns to each data type identifier a data type definition which is a well-formed type expression. The set of well-formed type expressions TypeExpr is defined as follows: (i) p 9 TypeExpr, ifp 9 PrimTypeld- { Void}, (primitive type), (ii) t 9 TypeExpr, if t 9 DTypeld, (substitution type), (iii) T 9 TypeExpr, if T 9 OTypeld, (reference type) (iv) [Sl: tl; s2: t2; ... Sn: tn] 9 TypeExpr, if ti 9 TypeExpr, si 9 PropName, s i r sj if i ;~j for 1 -< i, j < n, (tuple type), (v) <Sl: tl, s2:t2 .... Sn: tn> 9 TypeExpr, if ti 9 TypeExpr, si 9 PropName, si r sj if i ~ j for 1 _
17 (vii) array[n 1 ... n2] t e TypeExpr,
if t e TypeExpr, n l , n2 e Z, n l < n2, (array type),
(viii) list-oft e TypeExpr, if t e TypeExpr, (list type) The set of well-formed type expressions including Void is defined as follows:
TypeExprV = TypeExpr u { Void} The example given in Figure 3.1 shows well-formed type expressions.
String, { [ a : Integer; b: { String } ] }, Date, if Date ~ DTypeldande.g., 11(Date) = [d : Integer; m : Integer; y: Integer] Person, if Person ~ OTypeld
Figure 3.1: Examples of well-formed type expressions
Based on the definition of well-formed type expressions, we can now define structural property definitions and behavioral property definitions.
Definition 3: ( Structural and behavioral property definition ) PropDef = PropName • TypeExpr, MethDef = MethName • ArgList • TypeExprV, and ArgList -- (VarName • TypeExpr) *. A well-formed structural property definition is a tuple (n, t) e PropDef, where n e PropName is the name of the property, t e TypeExpr is the type of the property. A well-formed behavioral property (method) definition is a tuple (m, a, t) e MethDef, where
m e MethName
a e ArgList
is the name of the behavioral property (method), is the formal argument list which consists of a (possible empty) list of pairs (v, t'), v e VarName, t' e TypeExpr, of parameters,
t e TypeExprV
is the result type. The specification of t is optional. If t is omitted it is assumed that t = Void and that the method does not return a value. A property (n, t) is called relationship, if its type is an object type, i.e., t e OTypeld, or t = {t'} or t = array[nl ... n 2] t' or t = list-oft' and t' e OTypeld. Note, that relationships can also be defined within a tuple or union type expression, i.e., a property Sk: tk specified in a tuple Is l: tl; s2: t2; ... Sn: tn] E TypeExpr or in a union type <Sl: tl, s2:t2 .... Sn: tn> e TypeExpr, where ti e TypeExpr, s i e PropName, si ~ sj if i ~ j for 1 < i, j, k < n, is called a relationship iff tk e OTypeld, or tk = {t' } or tk = array[nl ... n2] t' or tk = list-of t' and t' e OTypeld. Otherwise, a property (n, t) is called attribute.
18 We define an equality operator '=' on property and method definitions: Let (n, t), (n', t') e PropDef, and (m, a, t), (m', a', t') ~ MethDef Then (n,t) = (n',t') <:~ n = n ' , and t = t ' (m,a,t) = ( m ' , a ' , t ' ) r m=m',a=a',andt=t'.
Object Types As mentioned previously, the structure and behavior of objects is determined by object types. Based on previous definitions we can now define a well-formed object type definition.
Definition 4: ( Object type definition ) OTD = OTypeld ~-->OTypeDef, and p E OTD is the map that assigns to each object type identifier an object type definition, where OTypeDef = OTypeld +• set of PropDefx set of MethDef • sot of Impl. An object type definition is a tuple (st, props, meths, impl) ~ OTypeDef, where st c OTypeld + is a list of identifiers of supertypes (see type specialization below), is a set of property definitions, is a set of all method definitions, denotes the implementations of (a) the methods defined in meths and (b) possible reimplementations of methods defined with any supertype T ~ elems st. The properties and methods that are defined with an object type are called immediate props E sot of PropDef meths e set of MethDef impl ~ sot of Impl
properties and immediate methods. The data model provides an empty object type 0 ~ OTypeld such that p(O) = ((O), 0, 0, O), i.e., the empty type O does not define any structural property or method. The following auxiliary functions will be found useful: props: OTypeld --->set of PropDef with props(T) = p(T)[2] meths: OTypeld --> sot of MethDef with meths(T) = p(T)[3] i The concrete syntax for the definition of object types is given in Figure 3.2 as far as needed in our examples. If an object type is defined as subtype of the predefined type O the list of supertypes can be omitted. The details of the subtyping mechanism are given later. In our data modelling language the structural properties of an object type T, i.e., props(T), are defined under the keyword 'properties' within the interface section (interf-section) or within the implementation section (impl-section). For all structural properties specified within the interface section the compiler automatically defines appropriate default methods to read and to modify the properties. That is, for a property definition (xy, t) ~ PropDef the method 'xy0 returns t' to read the property's value and the method 'setXy(aValue : t)' to assign a value are defined automatically. Specifying a structural property within the interface section is a very convenient short hand notation if one needs only the default read and write methods for that property. Because of these automatically available access methods such structural properties are called public properties. Structural properties specified within the implementation section of an ob-
19 ject type T are called private properties as one has explicitly to define specific methods with type T if these properties shall be accessible from outside of type T. The behavioral properties of an object type T, i.e., meths(T), are defined under the keyword ' methods'. If a method does not return any result the specification of the result type is omitted in the concrete representation of a method definition. The implementation of a method is specified in a separate implementation section, which includes the specification of imported method signatures from other types which are used for the implementation of immediate methods. The specification of imported methods allows the compiler to check the signatures of methods which are not defined with an object type. t ~ OTypeld - object type identifiers d e DTypeld - data type identifiers e ~ TypeExpr - type expr. (type id's, tuple, set, and union types) e' e TypeExprV - type expressions (including Void) p e PropName - property names m e MethName - method names v ~ VarName - variable names data-type-def ::= d ':= ' e ; obj-type-def ::= Define type t [ subtypeOf type-list ] interf-section impl-section type-list ::= t ..... t inteff-section ::= prop-list meth-list prop-list ::= properties: p : e ; . . . ; p : e; meth-list ::= methods: m ( [ v : e ; "v:e])[returnse']; " m([v:e; "v:e])[returnse']; impl-section ::= Implementation t [ import-fist ] prop-fist imp/-/ist import-list ::= import m from s o u r c e ; ...; m from source; source :: = t I ... - the source where the method signature for m is found impl-list ::= meth-imp/.., meth-imp/ meth-impl ::= m ( [ v : e; " v : e] ) [ returns e' ] { var-dec/; expr; ...; expr; } var-decl ::= v:e; "v:e; expr ::= ass-expr I noass-expr ass-expr ::= assignment noass-expr ::= message I var-ref I prop-ref l ... message ::= '[' noass-expr meth-sel-expr [ ( [ arg-list ] ) ] ' ] ' meth-sel-expr ::= m l e v a l ( v ) arg-list :: . . . . - a list of noass-expr passed to the method as parameters assignment ::= var-ref <-- noass-expr I prop-ref e- noass-expr var-ref ::= v I doted-var-ref prop-ref : : = p I doted-prop-ref doted-var-ref ::= var-ref . var-ref - to access components of tuples, etc. doted-prop-ref ::= prop-ref . prop-ref - to access components of tuples, etc.
Figure 3.2: Syntax for the definition of types as far as needed in the examples (Symbols enclosed in '[ ]' are optional).
20 Methods defined with an object type are needed to operate on the properties defined with that object type. The properties can only be read or manipulated by executing methods provided by the object type. Within a method body the properties specified with the object type are treated like variables, i.e., they can be accessed by their name. Methods are executed by sending a message to an object. A message is of the form [object method(parameters)]. In the case of public properties the language provides a convenient short hand notation: I f p is a public property and PO is the automatically defined method to read p's value, one can write [object p] instead of [objectpO]. More details on messages and the execution of methods are given later. Operators defined for the data types of the programming language The programming language used for the implementation of the methods is based on the programming language C. We changed the notation for assignments ('~---', in C ' = ' ) and for some boolean operators ( ' = ' , ' ~ ' , in C ' = = ' , !=) in order to improve the readability of our examples. The element undefined (see Definition 1) is syntactically represented as 'NULL' in the programming language. For the primitive data types the usual operators are defined. Furthermore, we assume that the following operations are defined on sets:
insert(aSet, anElement) delete(aSet, anElement) isEmpty(aSet), isNonEmpty(aSet) hasElement( aSet, anElement) findElement( aSet, aPredicate ) cardinality( aSet) aSet union aSet aSet intersect aSet
inserts an element into a set, removes an element from a set, test whether a set is empty or not, tests whether an element is contained in a set, returns the (first) element for the given predicate, returns the number of elements of a set, constructs the union of two sets, constructs the intersection of two sets, In addition, we assume the following operations to be defined on lists: insert(aList, anElement) inserts an element into a list, delete(aList, anElement) removes an element from a list, reverse( aList) reverses the order of the elements of a list, isEmpty( aList), isNonEmpty( aList) test whether a list is empty or not, hasElement( aList, anElement) tests whether an element is contained in a list, first( aList), last( aList) return the first/l~t element of a list, findElement( aList, aPredicate ) returns the first element satisfying the predicate, aList \ anElement returns a copy of a list not containing an element We can iterate on a list or a set using the iterator 'for (aVariable in aList/ASet) { statements }'. An example of an object type definition is given in Figure 3.3. The properties name, socialSecNum, car, and address are defined as public properties within the interface section. This implies that the default methods to read and write these properties are implicitly defined by the compiler. Suppose O is an object of type Person_Type 1~ then we can read the value of the property name by the message [O name()] (or the short hand notation [O name]) as the access method 'name() returns String' is implicitly defined. A new value can be assigned to the property name with the message [O setName("anyString")], as the access method
21
Date := [day : Integer; month : Integer; year : Integer];
/* a data type
*/
Define type Person_Type /* an object type */ properties: name : String; /* interface section with public properties */ socialSecNum :Integer; car : Car_Type; address : [ street: String; city: String; country: String; zip: Integer ]; parents: [ mother : Person_Type; father : PersonType ]; methods: printName0; birthdate0; printAddress0; setAddress (str: String, city: String, ctry: String, zip: Integer); ss# 0 returns Integer; buyCar(value : Car_Type) returns Person_Type father() returns Person_Type mother() returns Person_Type Implementation Person_Type /*only partial implementation shown properties: birthdate : Date; /* private property methods: printName0 /* prints the value of the property name { [io_out << (name)]; } birthdate 0 /* prints the value of the property birthDate {[[[io_out << (birthdate.day)] << (birthdate.month)]<< ( birthdate.year)]; } setBirthdate (value : Date) /* assigns a new value to the property birthdate { birthdate ~- value; } printAddress0 /* prints the value of the property address { [self printName0]; [[[[io_out << (address.street)] << (address.city)] << (address.country)] << (address.zip)]; } ss# 0 returns Integer /* returns the value of the property socialSecNum { return(socialSecNum); } buyCar(value : Car_Type) returns Person_Type { car e- value; /* assigns a new value to the property car return(self); } /* return the identifier of the current receiver father() returns Person_Type /* return the father of a person { return( parents.father ); } mother() returns Person Type /* return the mother of a person { return( parents.mother ); }
*/ */ */ */ */ */
*/
*/ */ */ */
Figure 3.3: Example of an object type definition and its implementation
'setName(aValue:String)' is also defined implicitly. Note, that all the messages [ 0 ss#()], [0 socialSecNum()], and [ 0 socialSecNum] can be employed to read the value of the property socialSecNum. The property birthdate is an example for a private property. The only methods to operate on that property are birthdate (which prints the value) and setBirthdate (which as10) Details about the relationship between objects and object types are given later.
22 signs a new value to the property). Both methods are defined explicitly with the object type. As birthdate is a private property no method to read it is defined automatically.
I/O Streams In the following we assume that appropriate input and output streams are predefined. Let io_out be the default output stream and let io_in be the default input stream. These streams provide (polymorphic) operations << and >> for displaying and reading in all the primitive data types available in the language. These operations return the stream object to which they are applied. The streams can be used like regular instances of classes, e.g., [[io_out << ("This is a string displayear') ] << (" on the device associated with the output stream io_out") ]. We do not need to go in any details as we need these streams only in a few examples.
Type Specialization As mentioned in postulate (i) object types may be defined as subtypes of other object types. A subtype inherits properties and methods from its supertype(s). Subtyping or type specialization allows us to build more specialized object types by specifying how the new ones differ in their property and method definitions from the already defined more general ones, called supertypes. The object types form an acyclic semi-lattice, where the root of the subtype hierarchy is the predefined type O. Every object type is a direct subtype of | or a subtype of other object types. If an object type has two or more direct supertypes, this is also called multiple inheritance. In order to resolve conflicts in case properties are defined more than once, a total order on types and their supertypes has to be constructed by an appropriate algorithm. We do not prescribe an algorithm here, however, we assume in our examples a "depth-first up to joins" strategy 11to determine the type precedence list for an object type T c OTypeld, written as PT = (To, T1 ..... TN), TN = (~, To = T, T i 9 OTypeld. For this type precedence list the set of properties, P(T), and the set of methods, M(T), defined for an object of type T are determined as given in Definition 5. Note, that P(T) and M(T) include immediate and inherited properties and methods.
Definition 5: ( Type specialization - the computation of P(T) and M(T) ) (a)
Let P : OTypeld ~--->setof PropDef, and M: OTypeld ~-->set of MethDef. Let propdef : OTypeld x PropName ~ Bool with propdef(T, n) = if (n, t) e props(T) then TRUE else FALSE i.e., propdef is a total boolean function that returns TRUE for a given object type T 9 OTypeld and a given property name n 9 PropName if T defines a property n. Let methdef : OTypeld x MethName ~ Bool with mothdof(T, m) = if (m, a, t) 9 meths(T) then TRUE else FALSE i.e., mothdef is a total boolean function that returns TRUE for a given object type T 9 OTypeld and a given method name m 9 MethName if T defines a method m. Let T Obe an object type and let PT0 = (To, T1, T2 ..... TN), TN = |
11) e.g., CLOS [BDG88] is based on such a strategy.
be the type prece-
23 dence list determined as described above. The sets P(T0) and M(T0) defined for type TO are determined from PT0 such that the following holds for all i = 0 ... N:
Vn such that propdef(Ti, n) A (n, t) E props(Ti) holds : (n, t) E P(To) <:~ ~ 3 j < i : propdef(Tj, n) Vm such that methdef(Ti, m ) A (m, a, t) E
meths(T/)holds
:
(m, a, t) @ M(To) <:~ ~ 3 j < i : methdef(Tj, m) and these are all elements of P(T0) and M(T0). In other words, a property n or method m is defined for the object O if it is defined in a type Ti, i >__0, and if there does not exist a definition for the property n or method m in a type T j , j < i, which precedes type Ti in the type precedence list of type TO. (b)
For the empty type O holds: P(|
= M(O) = 0 , as props(O) = meths(|
= 0.
m
Note, that a method may be redefined with a different signature at subtypes. This does not cause any problems as the model does not support type substitutability [WEGN87] 3.4.2 Classes
Every class is identified by a unique identifier. ClassDefis the domain of class definitions and e CD is the map which assigns to each class identifier a class definition, i.e., CD = Classld w--~ClassDef. A class defines the structural and behavioral properties of its instances. This is accomplished by associating an object type as instance-type with a class. Let i-type : Classld ---) OTypeld be the function that returns for a given class identifier the identifier of the object type which is associated as instance-type with the class. Note, that several classes may share the same instance-type. Remember, we have distinguished between attributes and relationships. They differ as follows: The values of attributes do not constitute database objects, the values of relationships identify database objects. For example, the name of a person, represented as a string, is not considered as a separate database object; but his car is identified as an individual object. We have to constrain the value of a relationship to the extension of a specific class. For example, we have to require that a person can only own an existing car. This is accomplished by substituting a class for the object type that has been used in the definition of the relationship. Obviously, to preserve integrity, this object type must be the instance-type of that class. In our example given in Figure 3.3 the object type Cat_Type has to be substituted by a class, let us call it CAR, which has Cat_Type as its instance-type. The value of the relationship car is then restrained to identify instances of class CAR. In the following, we will call the substitution of object type identifiers by class identifiers type-to-class mapping.
24 Let us now consider a more formal description of the type-to-class mapping. The type expression Car_Type used for the definition of the property car and for the method buyCar can be interpreted as a formal type expression parameter which is substituted by a (concrete) class identifier when using the object type Person_Type as an instance-type of a class. In other words, the object type Person_Type can be said to be parameterized with a formal type expression which is replaced by a (concrete) class identifier when using Person_Type in a class definition. In order to handle these mappings we introduce a separate domain:
Definition 6: ( Object type - class map ) TC is the domain of mappings which assign to each T 9 OTypeld a class identifier C 9 Classld, i.e., TC = OTypeld ~->Classld. The type-to-class mapping transforms type expressions used in property or method definitions into domain expressions which must contain class identifiers instead of object types as domains. This mapping will be used to construct concrete property and method definitions from the one given with parameterized object type definitions. For that purpose we first define well-formed domain expressions according to well-formed type expressions as follows:
Definition 7: ( Domain expressions ) The set of well-formed domain expressions (i) p 9 DomExpr, (ii) d 9 DomExpr, (iii) [Sl: dl, s2:d2 .... Sn: dn] ~ DomExpr,
(v)
DomExpr is defined as follows: ifp 9 PrimTypeld- { Void}, if d 9 Classld, (reference expression), if di 9 DomExpr, si 9 PropName, s i r sj, if i r j for 1 < i, j < n, (tuple expression), <Sl: dl, s2: d2, ... Sn: dn> 9 DomExpr, if di 9 DomExpr, si 9 PropName, si ~ sj, ifi ~j for 1 < i,j < n, (disjoint union expr.), if d 9 DomExpr (set expression), { d } 9 DomExpr,
(vi)
array[n 1 ... n2] d 9 DomExpr,
(iv)
if d 9 DomExpr, n 1
(array), if d 9 DomExpr (list expr.). (vii) list-of d 9 DomExpr, The set of well-formed domain expressions including Void is defined as follows: DomExprV = DomExpr u {Void} The set of well-formed formal argument lists which contain domain expressions is defined as follows: DomArgList = ( VarName • DomExpr) * where every a ~ DomArgList consists of a (possible empty) list of pairs (v, d), v ~ VarName, d ~ DomExpr, of parameters v. 9
Type-to-Class Mapping In the following, we specify in detail how domain expressions have to be constructed from type expressions by applying the type-to-class mapping. A formal definition of the type-toclass mapping is given in Definition 8.
25 Definition 8: ( Type-to-Class Mapping ) i-type : Classld --> OTypeld is the function that returns for a given class identifier the identifier of the object type which is associated as instance-type with the class. TCP = set of (PropName x TypeExpr) ~--->setof (PropName x DomExpr) is the domain of type-to-class mappings which map the type expressions of structural property definitions to well-formed domain expressions. The function 'l;p used to construct m__g(tcp), tcp 9 TCP, is defined as follows (where the index p in 1;p indicates that it is used to construct a type-to-class mapping for structural property definitions): 1;p : set of (PropName x TypeExpr) x TC ---) set of (PropName x DomExpr) 1;p(S, IX) = { (n, ~(t, IX)) I (n, t) 9 s, n 9 PropName, t 9 TypeExpr } where ~ is a specific function with respect to the set s and the map Ix: : TypeExprV x TC---~ DomExprV
~(t, Ix) =
t.
if t 9 PrimTypeld,
X(q(t), Ix), Ix(t), such that i-type(Ix(t)) = t,
if t 9 DTypeld,
{ ~(t', IX) }, [nl : dl ..... nN : dN], di = ~(ti, Ix),
if t = {t' }, t' 9 TypeExpr,
if t 9 OTypeld, Ix(t) 9 Classld, ift = [nl : tl ..... nN : tN], ti 9 TypeExpr,
, di = ~(ti, IX), ift = , ti 9 TypeExpr, array[n I ... n2] d, d = ~(t', IX),
i f t = array[n 1 ... n2] t', t ' 9 TypeExpr,
list-of d, d = ~(t', Ix),
if t = list-of t', t ' 9 TypeExpr.
TCM = set of (MethName x ArgList x TypeExprV) v--->set of (MethName x DomArgList x DomExprV) is the domain of type-to-class mappings which map the type expressions used for the definition of methods to well-formed domain expressions. The function "[m used to construct rng(tcm), tcm e TCM, is defined as follows: 17m : set of (MethName x ArgList x TypeExprV) x TC --q set of (MethName x DomArgList x DomExprV) ~m(S,ix) = {(m, r(a, ix), ~(t,ix)) I (m,a,t) e s, m 9 MethName, a e ArgList, t 9 TypeExprV} where ~ and ~ are specific functions with respect to the set s and the map It: : ArgList x TC --+ DomArgList where for a = ( n 1 : tl ..... nN : tN) e ArgList, n i e VarName, ti 9 TypeExpr, i = 1.... N, ~(a, IX) = ( n l : ~(tl, IX)..... nN : ~(tN, IX)) : : TypeExprV • TC--) D o m E x p r V
as defined above.
9
Mappings "l;p 9 TCP and "Cm 9 TCM specify how type expressions are mapped to domain expressions: 9 A primitive type t 9 PrimTypeId is mapped to itself. 9
A d a t a t y p e t ' e DTypeldismappedto~(q(t), p.),whererl(t) 9 TypeExpristhedefinition of the data type t.
26 9
Aobjecttypeparameter t~ OTypeldismappedtoaclassidentifierkt(t)=c, c e Classld, to which the object type t has been associated as instance-type, i.e., i-type(c) = t.
9
The mappings of complex structured types like tuple types, union types, set types, array types, and list types are recursively defined on the previous rules.
Defining Classes After we have introduced domain expressions and the definition of the type-to-class mapping, we can now give a preliminary definition of a class definition, which we will expand later. Definition 9: ( Class Definition - p r e l i m i n a r y definition ) ClassDef = OTypeld x TC , CD
= Classld ~-> ClassDef, and
~ CD is the map which assigns to each class identifier a class definition.
A class definition is a tuple (T, 'C,) ~ ClassDef, where T E OTypeld identifies the instance-type provided for the instances of the class, is the map which assigns to each object type used in P(T) or M(T) a class identifier c E Classld The following auxiliary functions will be found useful12: i-typo : Classld --->OTypeld with i-type(cid) = ~(cid)[1]. i-re : Classld --->TC with i-tc(cid) = ~(cid)[2]. "C~ TC
'~p,i : Classld --->TCP
with "[p,i(cid)
=
[ P(i-type(cid)) ~ Zp(P(i-type(cid)), i-te(cid)) ]. "[m,i : Classld --> TCM
with "~m,i(cid)
=
[ M(i-typo(cid)) w-> ,Cm(M(i_type(cid)) ' i-te(cid))]. where the index i in'l;p, i and'~rn,i indicates that these functions return type-to-class mappings for an instance-type, the indices p and m indicate that the functions return type-toclass mappings for structural properties and behavioral properties, respectively, n Figure 3.4 gives the concrete syntax of a class definition. In this concrete representation the type-to-class mapping is defined by specifying mappings for each object type which occurs in the definition of the instance-type used for the class definition. This determines the map'[ E TC for a class definition. In our example (Figure 3.5), the object type Car_Type is mapped to class CAR and the object type Person_Type is mapped to class PERSON as the type-to-class mapping "CPERSON= [ Car_Type ~-->CAR, PersonType ~ PERSON ], 'I:PERSON 9 TC. Therefore, the formal class definition for class PERSON is given by PERSON ~ (Per-
son_Type, T,PERSON ).
12) Auxiliaryfunctionsalready defined earlier are included too.
27
t ~ OTypeld o ~ Classld
- type identifiers - class identifiers
class-definition ::= Define class o instance-type: t [ t y p e - c l a s s - m a p ] type-class-map::= '[' t ~ o ..... t --> o ']'
Figure 3.4: Syntax for the preliminary class definition (Symbols enclosed in '[ ]' optional).
Define class PERSON /* define the class PERSON instance-type: Person_Type [ Car_Type ~ CAR, Person_Type ~ PERSON ] Define class CAR instance-type: Car_Type;
*/
/* definition of Car_Type not further specified */
Figure 3.5: Example of class definitions with a type-to-class mapping specification.
Defining Instances of Classes For the creation of an instance of a class only the identifier of the class has to be specified. Hence, for the present, the abstract syntax for the creation of an object can be defined as follows (it will be expanded later): Definition 10: ( Object Definition - preliminary definition I ) ObjectDef = Classld is the domain of object definitions. OD = Objld ~-->ObjectDef, and gt e OD is the map which assigns to an object identifier its object definition. Every object definition d f e ObjectDefconsists of an identifier cid ~ Classld which identifies the class of the object. The following auxiliary function will be found useful: class : Objld --->Classld with class(oid) = ~(oid)[1]. = In the programming language the creation of an instance is accomplished by a "new-object" statement which specifies the class to be instantiated, e.g., [ PERSON new() ] is used to create a new instance of the class PERSON, where new() is a predefined method. More details on the creation of an object and the method new are given later.
Extension of Classes The extension of a class, i.e., the set of all instances defined for a class can be described formally as follows: extension: Classld --~ set of Objld with extension(cid) = { oid I oid e dom ~ ^ class(oid) = cid }. This definition of the extension of a class will not be invalidated by any subsequent definition.
28 3.5 Semantics
In this section we describe the semantics of the concepts of classes and objects. 3.5.1 Classes
As mentioned previously classes are used to define the structure and behavior of their instances. We now define the set of structural property definitions and the set of method definitions, which will be used to determine the structure and behavior of an instance of a class.
Definition 11: (pd(oid), Md(oid) ) The set of structural property definitions for an object is identified by the mapping pd: pd : Objld ~ set of (PropName x DomExpr). The set of method definitions for an object is identified by the mapping Md: M d : Objld ~ set of (MethName x DomArgList x DomExprV).
Definition 12: ( Determination of pd(oid) and Ma(oid) - preliminary definition I ) The set of structural property definitions defined for an object identified by oid is determined as follows: IXl(oid) = 1;p,i(class(oid)) (P(i-typo(class(oid)))) The set of method definitions defined for an object identified by oid is determined as follows: Md(oid) = 1;m, i(class(oid)) (M(i-typo(class(oid))))
Note, that the sets Pd(oid) and Md(oid) contain all structural property definitions and all method definitions specified for an object as (a) the computation of P(i-type(class(oid))) and M(i-type(class(oid))) considers all property and method definitions specified with any supertype of the instance-type i-type(class(oid)), and (b) the type-to-class mappings 1:p,i(class(oid)) and'l:m, i(class(oid)) map all these definitions to final definitions which contain well-formed domain expressions. Figure 3.6 shows how the sets pd and M d are defined for an individual person. Type Person_Type, associated as the instance-type with the class PERSON, determines the structure and behavior of the instances of class PERSON. The pairs (n, t), n ~ PropName, t ~ TypeExpr, specified with the instance-type Person_Type are mapped to pairs (n, c), n ~ PropName, c Classld, if the type t used for the definition of the property n is defined as an object type and associated as instance-type with the class c. In our example, type Car_Type has been used as instance-type of the class CAR. Any occurrence of Car_Type in the property and method definitions of type PersonType has been mapped to the domain expression CAR, and any occurrence of Person_Type has been mapped to PERSON. Before we will specify the semantics of property definitions we introduce the concept of objects.
29
i-type(class(oid)) = Person_Type ~ N , , ~ ~ ~ ~ ' N ~
c l as s(oid) = PERS ON instance-type
instance-of
Pd(~ ( ~ ~ o i d Md(oid)
= "Mr. Miller"
pd(oid) = { (name, String), (birthdate, [day:Integer; month:Integer; year:Integer]), (car, CAR), (SocialSecNum, Integer), (address, [ street: String; city : String; country: String; zip : Integer]), (parents, [father: PERSON; mother: PERSON) } Md(oid) = { (printName, 0, Void), (birthdate, 0, Void), (buyCar, (car:CAR), PERSON) (printAddress, 0, Void), (setAddress, (str: String; city : String; ctry: String; zip : Integer), Void), (ss#, 0 Integer), (father, 0, PERSON), (mother, 0, PERSON)] Figure 3.6: Example for the determination of the sets pd and M d for individual objects 3.5.2 Objects
Every object in the system has assigned a unique object identifier and is defined as an instance of exactly one class (instantiation principle). The relationship between an instance and its class is called instance-of, Let ObjectMem be the domain of maps which assign to an object identifier oid ~ Objld an object, i.e., ObjectMem= Objld ~--~ Object. Before we give a precise definition of an object we must specify the semantics of the structural property definitions provided by the object's class, and the semantics of domain expressions used for these property definitions. Semantics of Domain Expressions
We associate with each domain expression a set of values, the domain of the domain expression. Since domain expressions are defined recursively we may define the domains also recursively:
30
Definition 13: ( Domain of domain expressions ) Let d ~ DomExpr, then the domain I[ d]l of d is defined as follows: (i) I[ P If (predefined, see Definition 1), if d = p, p ~ PrimTypeld, (ii) I[d]l = { o i d l o i d E ObjldAclass(oid)=d}u {undefined}, i f d e Classld, (iii)
I[ [Sl: d l, s2:d2 .... Sn: dn] ]l = ( {Sl } • I[ d l ] ) • x ({ Sn} x I[ dn]] ) , if di ~ DomExpr, si E PropName, si ~ sj, if i ~ j for 1 < i, j < n,
(iv)
[[ <Sl: dl, s2:d2 .... Sn: dn>]] = U ( {si} • [[dill), i=0 if d i E DomExpr, si ~ PropName, si # sj, if i ~ j for 1 < i, j < n,
n
(v)
[{ d}]l = ~ f ( ~ d ] ] ) , if d e DomExpr,
(vi)
1[array[nl ... n2] d ] = [[d]IN,N = n 2 - n I + 1, if d ~ DomExpr,
(vii) [[list-ofd]] = l i d ] * ,
if d e DomExpr. I
In the above definition to each primitive type identifier p ~ PrimTypeId a predefined domain of values [[pl] is assigned (see Definition 1). For example, the domain [[ Integer ]l = Z, where Z denotes the set of integers. Furthermore, the set ~Pf([[ d ] ) denotes the set of all finite subsets of 1[d]l, and 1[d]l N denotes the N-dimensional cartesian product of n d ] , [[ d]l * denotes the union of all i-dimensional cartesian products, i = 0 ..... co, i.e., [[d]l * = 0 (1[ d ~i). i~0
Definition of a n O b j e c t Now, we can introduce a preliminary definition of objects which will be expanded later:
Definition 14: ( Object-preliminary definition I ) Object = set of (PropName • Value) Value = U I[ d ] d ~ DomExpr
is the domain of objects, and is the domain of all possible values of structural properties.
Every object o ~ Object consists of the set of factual properties representing the state of the object. Every object is identified by an object identifier: ObjectMem = Objld ~ Object is the domain of object memories, and ~ ObjectMem is the map which models the object memory and which we assume to be defined globally. For the state s 6 set of (PropName • Value) of an object identified by old holds: 'V' (n, d) ~ pd(oid) ~ (( 3 (n, v) ~ s : v ~ [d]] ) A (-,3 (n, v') ~ s : v' ~ v)) i.e., for every structural property definition in pd(oid) there exists one factual property in the state s. The following auxiliary function will be found usefull3: state : Object ~ set of (PropName • Value) with state(obj) = obj[1]. 9 13) The definition of Objectwill be extended later and additional auxiliary functions will be introduced.
31 The property values of an object identified by oid are represented by the set state(~(oid)). Note, that we started with type expressions specified within property definitions of object types. These object types are associated as instance-types with classes whereby the type expressions are transformed to domain expressions by applying the type-to-class mappings. These domain expressions are relevant for the actual definition of an object, i.e., the structure of an object.
Creating Objects An object can be created by specifying a 'new-object' expression (cf. Section 3.4.2) which consists of the specification of the class of which the new object should be an instance. For the creation of an object, i.e., for the allocation of memory in the object memory ~, we define the function createobject: For a given object definition df~ ObjectDefthe function createobject : ObjectDef--> Objld creates a new unique object identifier oid ~ Obfld, updates the map ~ with [ oid ~ df] such that ~/(oid) = df, and therefore, oid E extension(dJ[1]), and (iii) creates a new object O ~ Object and initializes the properties with the predefined value (i) (ii)
undefined, such that 9 ~(oid) = O, and 9
for the state s = state(~(oid)) holds: V(n,d)~ pd(oid)~((3(n,v)6 s:v~ Ud~)A(~3 (n,v')6 s:v'r i.e., for every structural property definition in IXl(oid) there exists one factual property in state(~(oid)).
Every object in the system is created by the predefined function createobjeet. In order to remove objects from the object memory ~, we define for a given object identifier oid the procedure destroyobject : Objld, (i)
which destroys the object identified by the argument and deallocates the object's memory in cy, i.e., cy = c~\ {oid}, and
(ii)
removes [oid ~
~(oid)] from the map ~, i.e., ~ = ~ \ {oid}, and therefore, oid ~ extension(d~l]), where df ~ ObjectDef and dj~l] = elass(oid) held before executing destroyobjeet(oid) 14.
In the following we will expand some of the former definitions. However, the definition of the state of an object, and therefore the representation of the current values of an object, will 14) We do not describe the handlingof danglingreferences here, i.e. how object identfiersas values of properties are handled, if they identifydestroyedobjects. There are several solutionsfor this, e.g., the system invalidatesa danglingreference when it tries to access the identifiedobject, or a daemonresolves the danglingreferences, or introducinggarbage collectionnot allowingto delete referencedobjects.
32 not be invalidated by any subsequent definition. That is, one can still represent the propertyvalue pairs of an object ~(oid) by the set stato(c(oid)) when all concepts for metaclasses will be introduced in the subsequent chapters.
3.6 Own-types Suppose, that we have thousands of instances of a specific class which model documents. All these instances are implemented by the same structure and demonstrate the same behavior. But as discussed in [KNS89a] there is a need to extend the definition of some individual objects, e.g., a specific expense voucher, beyond the "standard" definition provided by the object's class. The need to extend dynamically the behavior of a particular instance has also been recognized in other systems [HAL88, DEU90]. Of course, we could define these properties with the instance-type associated with the class. Then, we have to accept that storage may be wasted since the properties are unused for thousands o f instances, or the system must deal with a kind of dummy values or null values wherever these properties do not apply. Another solution would be to introduce a new object type, that contains the additional structurai property and method definitions, and, based on it, a new separate class. This leads to a very large number of types and classes that are used, in the average, very seldomly. A better solution is to provide a mechanism that allows the definition of these additional properties and methods individually for a specific object. We propose to extend the property and method definitions of an object by associating explicitly an object type with the object, called the own-type of the object. Similarly to the above, a type-to-class mapping has to be specified for an own-type. An object possesses the properties defined by its own-type in addition to properties of the instance-type specified with its class. For simplicity and integrity reasons (as we will see later), the own-type may only define additional properties but not alter properties of the instance-type. As described in Section 3.5.2, a new instance can be created by specifying the class of which the new object should be an instance. If an object has associated an own-type, additional information has to be considered for the creation of the object. This leads to the following preliminary object definition.
Definition 15: ( Object Definition -preliminary definition II, redefines Definition 10 ) ObjectDef = Classld x OTypeld • TC is the domain of object definitions, OD = Objld ~-->ObjectDef, and ~t ~ OD is the map which assigns to an object identifier its object definition.
33 Every object definition is a tuple (cid, T, ~) ObjectDef where cid c Classld identifies the class of the object, T ~ OTypeld identifies the own-type associated with the object,
~
TC
is the map which assigns to each object type T' used in P(T) or M(T), T' ~ OTypeld a class identifier c ~ Classld such that for all T' ~ dom(q;) : if T' ~ dom(i-tc(cid)) then
I;(T') = i-tc(cid) (T'). That is, the type-to-class mapping defined for the own-type and the type-to-class mapping defined for the instance-type of the object's class map every object type which is in the domains of both mappings to the same class. The following auxiliary functions will be found useful, where the function class has already been introduced in Definition 12: class : Objld --4 Classld with class(oid) = ~(oid)[1]. o-type : Objld --~ OTypeld with o-type(oid) = ~(oid)[2]. o-tc : Objld ---) TC with o-tc(oid) = ~(oid)[3]. "~p,o : Objld--~ TCP
with l:p,o(oid )
=
[ P(o-type(oid)) w-~ 1:p(P(o-type(oid)), o-tc(oid))]. 1;m,o : Objld ~ TCM
with 1:m,o(oid )
=
[ M(o-type(oid)) w-~ 17m(M(o-type(oid)),o-tc(oid))]. where the index o in 1;p, o and 1;m, o indicates that these functions return type-to-class mappings for an own-type, the indices p and m indicate that the functions return type-toclass mappings for structural properties and behavioral properties, respectively.
The sets of structural property and method definitions, which will be used to determine the structure and the behavior of an object, are computed from the definitions provided with the instance-type of the object's class and the own-type of the object. Consequently, we redefine the determination of the structure and behavior of an object as it has been given in Definition 12:
Definition 16: ( Determination of pd( oid) and Md( oid) -preliminary definition II) pd(oid) = 'l:p,o(oid) (P(o-type(oid))) u 1:p, i(class(oid)) (P(i-type(class(oid)))) Md(oid) = 1:m,o(oid ) (M(o-type(oid))) ~ 1:m, i(class(oid)) (M(i-type(class(oid)))) where it is required that (a) forallp, q ~ pd(oid): p [ 1 ] = q [ 1 ] ~ p = q , and (b) for all m, n c Md(oid): m[1] = n[1] ~ m = n holds.
9
Note, that it is required that the own-type (and its supertypes) of an object and the instancetype (and its supertypes) of the object's class give identical definitions of the same properties and method signatures to avoid ambiguities. This implies (according to requirement (a) in
34 Definition 16) that object types T, T' ~ O T y p e l d which are used to define a property p in the own-type and the instance-type, i.e., (p, T) ~ P(o-type(oid)) and (p, T') ~ P(i-type(class (oid))), are mapped to the same domain c ~ Classld. If a method is implemented with the own-type of an object and with the instance-type of the object's class the implementation given with the own-type overwrites the implementation given with the instance-type. Details are given later in Section 3.9. According to Definition 15 a new object can be created by specifying its class, the own-type, and the type-to-class mappings. An object and its state can be created as described in Section 3.5.2., no changes are necessary to the definitions there. Figure 3.7 shows how the sets pd and M d are defined for an instance to which an own-type has been associated. We will see later, that the definition of own-types is also a useful mechanism for the uniform handling of classes and objects.
i-typo(class(oid)) = P e r s o n _ T y p e
instance type
i
n
~
pd~(e~idd))
o-type(oid) /
,...__~...t
J
own-type
F i g u r e 3. 7: Example of the determination o f P d and M d of an object with an own-type, pd(o)
and Md(O) are determined from both the definitions of i-type(class(oid)) and o-type(oid).
3.7 Classes as Regular Objects Up to now, we have two separate concepts, the concept of classes and the concept of objects which are defined to be instances of a class. This distinction does not allow a uniform handling of both classes and objects. We cannot apply all the mechanisms available for objects to classes. We cannot design the structure or conceptual behavior of classes in the same way as we can do it for instances. Hence, according to the uniformity principle, we want to treat classes as regular objects. That is, a class must be an instance of another class, a metaclass. To achieve this goal we combine the preliminary definition of an object definition (see Definition 15) and the preliminary definition of a class definition (see Definition 9) to the definition an object definition that can be used uniformly for classes and instances. When a class is represented as an object one may want to have methods which are used to initialize this object. This initialization can now be specified with the object definition. It con-
35 sists of a set of methods which will be executed for the object representing the class in the order in which they have been specified. This allows us to set up an original state for a class object. The methods specified for the initialization must be defined for the class, i.e., the object representing the class. Hence, only those methods can be used for the initialization which are defined with the instance-type associated with the metaclass of the class, or with the owntype associated with the class itself.
Definition 17: ( Uniform Object Definition - preliminary definition III )
The uniform object definition for instances and classes is defined as follows: ObjectDef = Classld x OTypeld • TC • OTypeld x TC x Init, Init
= ( MethName x ActArgList) * , and
OD
= Objld w-> ObjectDef,
where ActArgList denotes the domain of actual parameter lists passed to a method. c OD is the map which assigns to an object identifier its object definition.
Every object definition is a tuple (cid, T 1, '171, T2, "C2, il) e ObjectDef where
cid E Classid
identifies the class of the object,
T 1 c OTypeld
identifies the own-type associated with the object,
T 2 ~ OTypeld
identifies the instance-type provided for potential instances of the object,
"r ~ TC, i = 1, 2 are the maps which assign to each object type T' c OTypeld
used in P(Ti) or M(Ti) a class identifier c e Classld such that for all T' e dom('Cl) : if T' e dom(i-tc(cid)) then "CI(T' ) = i-tc(cid) (T'). That is, the type-to-class mapping defined for the own-type and the type-to-class mapping defined for the instance-type of the object's class map every object type which is in the domains of both mappings to the same class. il e Init
a sequence of methods used for the initialization of the object.
The following auxiliary functions will be found useful. Some of them have already been given in Definition 15, those given in Definition 9 are redefined: class : Objld ---> Classld
with class(oid) = tg(oid)[1].
o-type : Objld --->OTypeld
with o-type(oid)= ~(oid)[2].
o-tc : Objld --->TC
with o-tc(oid)
= q/(oid)[3].
"Cp,o : Objld ---> TCP
with "Cp,o(oid)
=
[ P(o-type(oid)) w-> 'Cp(P(o-type(oid)), o-tc(oid))]. "~m,o : Objld --->TCM
with '~m,o(oid)
=
[ M(o-type(oid)) ~ "l;m(M(o-type(oid)), o-tc(oid))].
36 i-type : Objld ~ OTypeld i-tc : Objld ~ TC
with i-typo(oid) = ~(oid)[4]. with i-tc(oid) = ~(oid)[5].
"Cp,i : Objld --4 TCP
with "r
=
[ P(i-typo(oid)) ~ '~p(P(i-typo(oid)), i-te(oid))]. '~m,i : Objld ~ TCM
with '~m,i(oid)
=
[ M(i-type(oid)) ~ "~rn(M(i-type(oid)), i-tc(oid))].
Now, when oid ~ Objld identifies a class C, this class is an instance of another class, called metaclass MC. The structure and behavior of the class C is determined by the instance-type associated with the metaclass MC. In addition, the definition of an own-type for the class may extend the structure and behavior of the class. Therefore, several classes can be instances of the same (meta)class, although they differ in their behavior due to their different own-type definitions. If the structure and behavior of the class C is restricted to the specifications given by the instance-type of the (meta)class, then o-type(o/d) = O has to be specified. Note, that for objects which are not classes it is required that i-type(oid) = O. The sets of structural and behavioral property definitions tXl(oid) and Md(oid) of an object p(oid) are determined as stated previously: pd(oid) = '~p,o(oid) (P(o-type(oid))) u '~p, i(class(oid)) (P(i-type(class(oid)))) Md(oid) = "~m,o(oid) (M(o-type(oid))) u '~m, i(class(oid)) (M(i-type(class(oid)))) where it is required that (a) forallp, q ~ pd(oid): p [ 1 ] = q [ 1 ] ~ p = q , and (b) for all m, n ~ Md(oid): m[1] = n[1] ~ m = n holds.
9
The above constraint has already been given with Definition 16. It means that the own-type (and its supertypes) of an object and the instance-type (and its supertypes) of the object's class give identical definitions of the same properties and method signatures to avoid ambiguities. This implies (according to requirement (a)) that object types T, T' ~ OTypeld which are used to define a property p in the own-type and the instance-type, i.e., (p, T) ~ P(otype(oid)) and (p, T') ~ P(i-type(class(oid))), are mapped to the same domain c ~ Classld. If a method is implemented with the own-type of an object and with the instance-type of the object's class the implementation given with the own-type overwrites the implementation given with the instance-type. Details are given later in Section 3.9. The semantic meaning of an object definition is the creation of an object. That is, specifying an object definition always leads to a new object as an instance of a class. Note, that the object then will be created as described in Section 3.5.2. Our data model provides an initial predefined metaclass VML-CLASS which is the root of the instantiation hierarchy formed by the object definitions. Every class or metaclass defined by a user must be an instance of VML-CLASS or of another metaclass. Chapter 6 gives the details
37 of how the initial metaclass VML- CLASS is defined and it discusses the effects of user defined classes and metaclasses.
3.8 Instance-instance-types After the introduction of instance-types, own-types, and the uniform treatment of instances and classes, we introduce the concept of instance-instance-types in order to provide the full power of metaclasses needed for a flexible semantic model. As told before, a metaclass is a class whose instances are classes. Therefore, metaclasses can be employed to provide an explicit definition of the structure and the behavior of classes which one can define. However, one may not only define the structure and behavior of classes at the metaclass level, but also the common structure and behavior of instances of these classes. We will see later that this feature is used to tailor our data model to the needs of particular applications and it provides for a transparent definition of the properties and methods of classes and their instances. In order to specify the common properties and methods for the instances of the instances of a metaclass, we extend the object definition such that an instance-instance-type is specified next to the own-type and the instance-type associated with the object. Consequently, the properties of an object are defined by: (i) its own-type, (ii) the instance-type of its class, and (iii) the instance-instance-type of its class's class. Analogous to the constraints imposed on property and method definitions specified with both the own-type (and its supertypes) of an object and the instance-type (and its supertypes) of the object's class, the own-type (and its supertypes) of an object must give identical definitions of the same properties and method signatures specified also with the instance-instance-type of the class of the object's class in order to avoid ambiguities. Definition 18 completes the uniform object definition, which will be valid for instances, classes, and metaclasses. Definition 18: ( Uniform Object Definition - f i n a l definition IV ) The uniform object definition for classes and instances is finally defined as follows: ObjectDef = Classld • OTypeld • TC • OTypeld • TC x OTypeld • TC x Init, Init = ( MethName • ActArgList) * , and OD = Objld ~ ObjectDef, where ActArgList denotes the domain of actual parameter lists passed to a method. 9 OD is the map which assigns to an object identifier its object definition. An object definition is a tuple (cid, T1, "~1, T2, 172, T3, q:3, il) 9 ObjectDef where cid 9 Classld identifies the class of the object, T 1 9 OTypeld
identifies the own-type associated with the object,
T2 9 OTypeld
identifies the instance-type provided for potential instances of the object,
T 3 9 OTypeld
identifies the instance-instance-type provided for potential instances of instances of the object,
38 "q ~ TC, i = 1, 2, 3 are the maps which assign to each object type T' ~ OTypeld
used in P(Ti) or M(Ti) a class identifier c ~ Classld such that (a) for all T' c dom('l;1) : if T' ~ dom(i-tc(cid)) then Xl(T') = i-tc(cid) (T'), (b) for all T' ~ dom('~l) : i f T ' ~ dom(ii-tc(class(cid))) then '~I(T') = ii-tc(class(cid)) (T'), and (c) for all T' e dom('C2) : if T' ~ dom(ii-tc(cid)) then "~2(T') = ii-tc(cid) (T'). That is, the type-to-class mapping defined for the own-type and the type-to-class mapping defined for the instance-type of the object's class map every object type which is in the domains of both mappings to the same class. This rule applies also to the type-to-class mapping defined for the own-type and the one defined for the instance-instancetype of the class of the object's class (constraint (b)) and to the type-to-class mapping defined for the instance-type and the one defined for the instance-instance-type of the object's class (constraint (c)). il e Init a sequence of methods used for the initialization of the object. The following auxiliary functions will be found useful (some of them have already been given in Definition 17): class : Objld ~ Classld with class(oid) = ~(oid)[1]. o-type : Objld --~ OTypeld with o-type(oid)= ~(oid)[2]. o-tc : Objld --~ TC , with o-tc(oid) = ~I/(oid)[3]. "Cp,o : Objld ~ TCP
with "~p,o(oid)
=
[ P(o-type(oid)) ~ "~p(P(o-type(oid)), o-tc(oid))]. ~m,o : Objld --> TCM
with "Cm,o(oid )
=
[ M(o-type(oid)) ~ '~m(M(o-type(oid)), o-tc(oid))]. i-type : Objld ~ OTypeld i-to : Objld ~ TC
with i-type(oid) = ~(oid)[4]. with i-tc(oid) = ~(oid)[5].
"l;p,i : Objld ~ TCP
with '~p,i(oid)
=
[ P(i-type(oid)) ~
"l;p(P(i-type(oid)), i-tc(oid))].
'Cm,i : Objld ~ TCM
with '~m,i(oid)
ii-type : Objld ~ OTypeld ii-tc : Objld -~ TC
[ M(i-type(oid)) ~ '~m(M(i-type(oid)), i-tc(oid))]. with ii-type(oid) = ~(oid)[6]. with i-tc(oid) = ~(oid)[7].
"~p,ii : Objld --> TCP
with "~p,ii(oid)
=
=
[ P(ii-type(oid)) ~--->'Cp(P(ii-type(oid)), ii-tc(oid))].
39 "[m,ii: Objld---> TCM
with "l:m,ii(oid) = [M(ii-type(oid)) w->'l:m(M(ii-type(oid)), ii-tc(oid))].
The index ii in'l:p,ii and'l:m,ii indicates that these functions return type-to-class mappings for an instance-instance-type, g If the structure and behavior of an object (class) identified by oidis restricted to the specifications given by the instance-type of the object's class (metaclass), then o-type(o/d) = O. For objects identified by oid which are not classes, i-type(o/d) -- O and ii-type(oid) = O. For objects which are not metaclasses, ii-type(oid) = O. We can specify a metaclass associating an own-type, an instance-type, and an instance-instance-type. The own-type then extends the structure and behavior of a metaclass M as an object itself. The instance-type specifies the (common) structure and behavior of tile instances C/of the metaclass M. The instance-instance-type specifies the (common) structure and behavior of the instances of the Ci 's. Hence, a metaclass can be used to control the behavior of objects at two levels, at the class level and the corresponding instance level. This effect will be fully exploited to realize semantic relationships and it will be described and demonstrated in the subsequent chapters. According to Definition 18, the sets of structural and behavioral property definitions of an object are computed as follows:
Definition 19: ( Determination of pd(oid) and md(oid) -final definition ) pd(oid) = Sp,o(oid) (P(o-type(oid))) u q:p, i(class(oid)) (P(i-type(class(oid)))) u q:p,ii(elass(class(oid))) (P(ii-type(elass(class(oid))))) Md(oid) = "[m,o(oid)(M(o-type(oid))) u '[m,i(class(oid)) (M(i-type(class(oid)))) w 1:m,ii(class(class(oid))) (M(ii-type(class(class(oid))))) where it is required that (a)
forallp, q ~ pd(oid): p [ 1 ] = q [ 1 ] ~ p = q ,
(b)
for all m, n e Md(oid): m[1] = n[1] ~
and
m = n holds,
m
The above constraints (a) and (b) have already been given with Definition 16 and in Section 3.7. Here it means that the own-type (and its supertypes) of an object, the instance-type (and its supertypes) of the object's class, and, in addition, the instance-instance-type (and its supertypes) of the class of the object's class give identical definitions of the same properties and method signatures to avoid ambiguities. This implies (according to requirement (a)) that object types T, T', T" c OTypeld which are used to define a property p in the own-type, the instance-type, and the instance-instance-type, i.e., (p, T) e P(o-type(oid)), (p, T') P(i-type(class(oid))), and (p, T") e P(i-type(class(elass(oid)))) are mapped to the same domain c ~ Classld. If a method is implemented with the own-type of an object and with the instance-type of the object's class the implementation given with the own-type overwrites the
40 implementation given with the instance-type. Analogous, a method implementation given with the instance-type of a class overwrites the one specified with the instance-instance-type of the class's class if that methods is implemented in both object types. Details are given later in Section 3.9. The effect of Definition 19 is shown in Figure 3.8. According to this definition the structure and behavior of any object is determined by 9 its own-type, 9 its class's instance-type, and 9 its metaclass's instance-instance-type. Note, that the introduction of instance-instance-types and the treatment of classes as objects are straightforward extensions of the basic principles introduced at the beginning of this chapter. The creation of an object follows the same rules as described in Section 3.5.2 and is not further explained here. The concrete syntax for specifying a class definition according to Definition 18 is given in Figure 3.9. It redefines the syntax given in Figure 3.4. The definition of a new class (02) has to specify the metaclass (Ol), an instance-instance-type (optional) and the type-to-class mappings in addition to an own-type (optional), an instance-type, and the type-to-class mappings for these types.
ii-type(class(class(oid)))
y
~
_-4 instance-in~a~cT-t
-of
i-type(class(oid))
-.
@
instance-type
instance-of
~ o-type(old)
pd(oid) Ma(~
Figure 3.8: The general scheme of determining an objects structure and behavior.
41
t ~ OTypeld
- type i d e n t i f i e r s
o ~ Classld - class i d e n t i f i e r s c l a s s - d e f i n i t i o n ::= Define ol 02 [ own-type: t[ t y p e - c l a s s - m a p ]] instance-type: t [ t y p e - c l a s s - m a p ] [ instance-instance-type: t [ t y p e - c l a s s - m a p
]]
[init: re(v); ...;m(v); ] type-class-map::=
'[' t ~ o ..... t ~ o ']'
Figure 3.9: Syntax for the class definition statement (Symbols enclosed i n ' [ ]' are optional).
Type Specialization versus Instance-instance-types of Metaclasses Let us now briefly focus on the major difference between the usage of type specialization and metaclasses with instance-instance-types. Both mechanisms allow us to specify properties and methods for an object'indirectly'. Using type specialization, a property or a method of an object may be specified with a supertype of the instance-type associated with the object's class. This supertype or some of its subtypes could also be used as the instance-type of some other class, and therefore the property or the method may be defined also for instances of that class. Using metaclasses with instance-types, a property or a method of an object may be specified with the instance-instance-type (or one of its supertypes) associated with the object's metaclass. As different classes may be instances of the same metaclass, the property or the method may be defined for instances of different classes again. In both cases the property or method definition is shared by instances of different classes. Hence, one might conclude that the domain of the property or the signature of the method, respectively, is the same for the instances of the different classes in both cases. But this is not true. Let t e OTypeld be the instance-instance-type of the metaclass M e Classld, i.e., ii-type(M) = t. Let t' e OTypeld be the instance-type of the class C' ~ Classld, let t" ~ OTypeld be the instance-type of the class C" e Classld, i.e., i-type(C') = t', i-type(C") = t". Furthermore, let class( C') = class( C ' ) = M. Then, for object identifiers O', O" ~ Objld, such that class(O') = C' and class(O") = C", holds: ' v ' n ( 3 t (n,t) e P(t) ~ ( 3 d ' , d " ( n , d ' ) e p d ( o ' ) ^ ( n , d " ) c p d ( o " ) ~ lid'S=
~d"~ )) In other words, the domains of the properties specified with the instance-instance-type t of the metaclass M are identical for all objects which have the same metaclass M. This is, because the type-to-class mapping Xp,ii(M) for the instance-instance-type t is specified once with the definition of the metaclass M: (n, d') ~ Xp,ii (M)(P(t)). As this mapping is used for the computation of both (n, d') e pd(o') and (n, d") ~ pd(o"), d ' = d", and hence, [ d ' ] l = I[d"].
42 If the same properties specified with the instance-instance-type t are also specified with one or both instance-types t' and t ", then I[d' ] = I[d" ]l is still valid due to constraints (a) and (b) given in Definition 19. Note, that if d' e Classld the properties (n, d') of both objects cy(O') and c ( O " ) refer to instances of the Same class d'. That is, the specification of properties for an object at the corresponding metaclass forces the domains of these properties to be identical for all these objects. Figure 3.10 visualizes that effect.
M
.,jn s.t.an_c_e-!nstance-_~_p__ e . . ~ ~
/~instanceOf~'~
C,, instance-type
t . . . . ir_~.~u.r.~.e-~_e_~."-'~--~'-C' ~ instanceOfl
I instanceOf
O' ~ properties specified with ~ ~ v e identical d o m a t ~ ~ Figure 3.10:
t"
O"
iI~
d'=d"
Effect of property specifications with an instance-instance-type.
In contrast to the specification of properties through an instance-instance-type of a metaclass the usage of a supertype does not necessarily have the same effect.
Let t' ~ OTypeld be the instance-type of the class C' e Classld, and t" e OTypeld be the instance-type of the class C" ~ Classld, i:e., i-type(C') = t', i-type(C") = t". Let t' and t" be subtypes of type t ~ OTypeld. Then, we have to distinguish two cases: 1.
The types t' and t" could redefine a property (n, t) specified with type t, such that the domain of the property differs for instances of class C' and instances of class C".
2.
Both t' and t" do not redefine any property specified with type t. Then, for object identifiers O', O" ~ Objld, such that class(O') = C' and class(O") = C", we can only say: 'fin (q -t (n, t) e P(t) ~ (3 d', d" (n, d') ~ pd(o') ^ (n, d") ~ pd(o") )) In other words, the domains of the properties specified with the common supertype t need not to be identical for the objects c ( O ' ) and ~(O"). Different type-to-class mappings may be specified for (n, t) with the definition of C' and C". The mapping for C' may map (n, t) into (n, d'), i.e., (n, d') ~ "~p,i(C') (P(t')), and the one for C" may map (n, t) into (n, d"), i.e., (n, d") ~ Xp,i (C") (P(t")). Hence, the domains [ d'~ and I[d"]l may be different. If d' ~ Classld the properties (n, d') and (n, d") of both objects ~(O') and ~(O") may refer to instances of different classes (see Figure 3.11).
43
subtypeOf
"
..-''"*"
~ i i i i i ~
t' . . . . . . . . . . . . ~. C' instance-type l instanceOf
-~-.
" - . subtypeOf
C"~ . . . . . . . . . . ' : "t" instanceOf I instance-type
O'
0"
properties specified with t may have different domains
t-d " ~
Figure 3.11:
Effect of property specifications with supertypes.
Here is the major difference to the usage of instance-instance-types. If a user wants the domains of the properties specified with a supertype to be identical, he has to specify that with the type-to-class mappings of each class. Using the instance-instance-type mechanism this is implicitly enforced by the type-to-class mapping for the metaclass. In other words, if identical semantics, i.e., identical mappings are needed for common properties and methods specified with the types associated with the classes C' and C", such behavior will be automatically enforced by the system if instance-instance-types are used, otherwise it would be up to the discipline of the designers of the type/class scheme. In addition, using an instance-instancetype of a metaclass guarantees that the methods defined with the instance-instance-type can be applied only to instances of classes. This is not the case if one uses supertypes because they (or their subtypes) can be associated with any object.
3.9 The Basic Model of Message Passing As described in Section 2 objects communicate through message passing. A message consists of a receiving object, a method name, and possibly several actual parameters. It depends on the type associated with the object, its class, and its metaclass, which method body will be executed. The identification of the method body can conceptually be seen as a mapping cO: Objld x MethName w-> MethDen where MethDen = Objld x Value * --> Value is the domain of method denotations. A method denotation models a method defined with an object type as a function which takes the receiving object and actual parameters as its arguments, computes a result, possibly updates the state of the object, and may have side effects on other objects.15 The receiving object and the method name identify the implementation of the method body. The mapping q) can be explicitly derived from a class definition. For each class a table (usually called dispatch table) can be generated which is indexed by the names of the methods de-
44 fined for all instances of the class. Actually, for every class C this table can be derived from the sets M(i-type(C)) and M(ii-type(class(C))). That is, for every method defined in M(itype(C)) and M(ii-type(class(C))) there has to be an entry in the dispatch table of class C. Note, that if an own-type has been associated with an object identified by oid, such a dispatch table has to be constructed for the object ~(oid) itself. It can be derived from the set M(o-type(oid)). As classes and instances are treated uniformly as objects, we extend the preliminary definition of an object (cf. Definition 14) by adding a component which represents the dispatch tables for the object.
Definition 20: ( Object - f i n a l definition H ) Object = set of (PropName x Value) x DispTbls , Value
=
U
lid] ,
d E DomExpr
DispTbls
= (MethName~--~MethDen) x (MethName~'-~MethDen) x (MethName ~ MethDen ),
MethDen = Objld • Value --~ Value. Every object is a tuple (s, dt) e Object where s e set ef (PropName x Value) is the set of factual properties representing the state of the object, is the dispatch table for the object, i.e., it is a triple of maps which assign to a method name its method denotation. Every object is identified by an object identifier: ObjectMem = Objld ~-~ Object is the domain of object memories, and ~ ObjectMem is the map which models the object memory and which we assume to be defined globally. For the state s of an object identified by oid holds: V (n,d)~ pd(oid)~((3(n,v)~ s:vE Gd])^(~3 (n,v') ~ s:v'~v)) i.e., for every structural property definition in pd(oid) there exists one factual property in the state s. dt ~ DispTbls
The following auxiliary functions will be found useful (some of them have already been given in Definition 14): state : Object -o set of (PropName x Value) state(obj) = obj[1]. disptbl : Object ~ DispTbls disptbl(obj) = obj[2]. ewnMeths : Disp Tbls --o (MethName ~'*MethDen ) o w n M e t h s ( d t ) = dt[1]. instMeths : Disp Tbls ~ (MethName ~--~MethDen ) instMeths(dt) = dr[2]. instinstMeths : Disp Tb ls ~ (MethName ~--~MethDen ) instinstMeths(dt) = dt[3]. 15) As we assumed that the object memory c e ObjectMem is defined globally, the object memory is not considered in the definition of MethDen.
45 For the construction of a dispatch table of a class C the following holds: V m ~ MethName: (m, a, t) c M(i-type(C) ~ m e dora instMeths(disptbl(a(C))) V m ~ MethName: (m, a, t) c M(ii-type(C) ~ m c dora instinstMeths(disptbl(t~(C))) V m ~ MethName: (m, a, t) ~ M(o-type(C) ~ m ~ dom ownMeths(disptbl(~(C))). Figure 3.12 shows the conceptual scheme of dispatch tables which may be used if messages are sent to an object.
dispatch tables
associated types
objects
sel )(class(class(O)), sel) ,
own-type -instance-type ................. -..1~ c~lass(class(O)~) i n s t a._nce-instance_~,,...~ ,
,
l instance-of sel
cp(class(O), sel)
YffffJJJJJfJffJ~
own-type
~
~
in_sta_nce-ty_.pe_._.l~k~.~_~
l instance-of
own-type
Figure 3.12:
~ ~
0
Dispatch tables for the determination of method bodies
In order to understand the execution of a message, we have to investigate the scheme with respect to message passing first. Every message expression is compiled to a call of the message handling system (or short message handler). That is, the statement [ receiver-did method-name (argumentl ..... argumentN) ] is compiled to a function call on the message handler: send ( receiver-did, method-name, argumentl .... , argumentN). The function send determines the method body which has to be executed using a selection logic based on the mapping tp described above and executes the method. The algorithm for the message handler can be defined conceptually as follows: Definition 21: ( Basic message handler )
The message handler is defined through the function send: send : Objld • MethName • Value* ---) Value
46 send(oid, m, args) = if old = undefined then undefined else if (m . . . . ) 1 6 9 then selection(oid, m) (oid, args) else error_handling ("Method not found")
The function selection called by the message handler determines the method body to be executed: selection : Objldx MethName ~ MethDen selection(oid, m) = let class = classid(~(oid)) in let metaclass = classid(~(class)) in let o-meth = ownMeths(disptbl(~(oid))) in let i-meth = instMeths(disptbl(a(class))) in let ii-meth = instinstMeths(disptbl(~(metaclass))) in if rn e dora o-meth then o-meth(rn) else if rn 9 dom i-meth then i-meth(m) else if m 9 dom ii-meth then ii-meth(m)
Up to now this model follows essentially the model proposed in [COX87] which is utilized in several object-oriented systems like Vbase [VBASE88] or Objective-C [COX87], except that it considers methods defined with the own-type of an object or with the instance-instance-type of the metaclass of the object. For the different kinds of optimizations and variants of this standard method inheritance model the reader is referred to [COX87]. The selection logic implemented by the function selection first checks the dispatch table defined for the receiver object. This is the case if an own-type has been associated with the object. The method name is used as index for the dispatch table to get the corresponding body of the method. If no dispatch table is defined at the receiver object (i.e., no own-type has been associated), or if no method body is found for the given method name (i.e., the method is not defined with the own-type), the dispatch table defined for the class of the object is checked. If the appropriate method body is found, i.e., the method is defined with the instance-type associated with the class of the receiver object, the method code is executed. Otherwise, no such method has been specified for this kind of object with the instance-type associated with the class of the object. In this case, the dispatch table defined for the metaclass of the object's class is checked. If the method body can be found, i.e., the method is defined with the instance-instance-type associated with the metaclass of the object's class, the method is executed. Otherwise, no such method is defined for the receiving object and an error has to be signaled. 16) The use of an underscore in this tuple indicates that the value of that particular field is not of interest for the comparison.
47 Note, that the three dispatch tables consulted by the selection logic contain together all method bodies of any method which has been defined either with the own-type of the object and the own-type's supertypes, the instance-type of the object's class and the instance-type's su-' pertypes, or the instance-instance-type of the object's metaclass and the instanc-instancetype's supertypes. That is, any method defined for the object can be found via these dispatch tables.
3.10 Specific Method Inheritance Behavior AI-based systems utilize "inheritance" by delegating methods, e.g., in KnowledgeCraft [KNCR86] different kinds of inheritance may be defined for different kinds of relationships. Similarly, specific inheritance mechanisms can be introduced in the object-oriented data model of V O D A K by metaclasses defining the inheritance strategy for the instances of their class instances. Assume, a message is sent to an object O, and the method which handles that message has not been specified for O. That is, no method to handle the message has been defined by its owntype, neither by the instance-type of its class, nor by the instance-instance-type of its metaclass, nor by one of the supertypes of these types. Then the message fails and the system signals an error. But, if the object O is related to an object O' through some semantic relationship, O may delegate the message to O ' and inherit the answer from O'. Before we describe more details about the underlying message handler system we introduce the concept of semantic relationships and give a brief general characterization in the subsequent sections.
3.10.1 Semantic Relationships as Modelling Primitives Modelling an application means to define an appropriate representation of "real world entities" and the relationships between them. That is, real world entities are classified and represented as instances of classes which stand for different real world concepts. For example, persons may be represented as instances of a class PERSON which provides the definition, i.e., the structure and behavior, for its instances. In the real world one and the same object may appear in different situations (or contexts). In each of these different situations the object may be represented by different information with respect to the situation. That is, the object may have a different structural representation, different or additional properties, and different or additional methods which determine the behavior of the object in the specific situation. The general mechanism to handle this problem by the introduced data model is to represent the real world object by different classes, where one of the classes represents the real world object in general, and each other class stands for a specific situation/context. The classes representing the object in a specific situation/context are related to the class which represents the object in general by a relationship which we call semantic relationship. Such a relationship states that an instance of a class which stands for a specific context and an instance of the class which represents the object in general represent
48 the same real world object. Semantic relationships reflect real world semantics and they do not depend on any structural relationship between instances of different classes representing the different situations/contexts. The structure and behavior of the instances in the different contexts may have a completely different representation from each other (see also [NPGT89]). An example of a semantic relationship is the principle of object specialization. Object specialization is an appropriate mechanism in cases where a real world object appears in different situations, or is gradually specified more extensively, or is modelled over its life cycle by different classes. In this example, a real world object is represented as an instance of a general class (also called superclass) and as an instance of a specialized class (also called subclass). The instance o f the general class models only the properties and methods defined with the general class, a specialized instance models only the properties specified with the specialization class. The object specialization relationship, which can be defined to hold between the general class and the specialization classes and thus between an instance of the general class and instances of specialization classes, has been introduced with different semantics: (i)
It may be used for the modelling the different roles a real world object may play. In this case every instance of a specialized class, called role specialization class, models a real world object which is also modelled by an instance of the general class. The instance of the specialized class models the real world object in a specific situation which has not been considered explicitly in the general class. Note, that for a real world object several roles may be modelled, i.e., instances of two or more specialized classes may exist for one instance of a general class. For an example, assume we have a person who may be a student, an employee, a father, or a legal person. In each of these roles this person may have different addresses and salaries. As a student the person may have the address of the student dormitory; as an employee the person's address may be the department of his company; as a father and a legal personality the address may be the home address. But general information about a person, e.g., his name, the social security number, the marital status and the sex, are always the same in each of the person's roles (see Figure 3.13).
(ii)
It may be used to specialize a more general representation of a real world object according to some categorization criterion into a more detailed representation. In this case the more detailed instances can be collected into a class, called category specialization class of the class collecting the general representations of those objects. Every instance in such a category specialization class models a real world object that is modelled also by an instance of the general class. Furthermore, the real world object cannot be represented in any other category specialization class of the general class. An object belongs only to one category as for reasons of our understanding of the phrase "add more detail to a description" we assume that the categorization is disjoint with respect to the criterion of the categorization.
49
(
~
~
role-speci~ole~pecialization
context o f a person as an employee; typical information about an employee, e.g., its own company address.
context o f a person as a student; provides typical information about a student, e.g., the student dormitory's address, enrollment no.
Figure 3.13:
general context o f a person; provides e.g., the name, home address, sex, social security no., marital status, whiCconthxmaye~_be shared by several role
~
role-speci~
context o f a person as a father; provides typical information o f a father, but shares e.g., the home address o f the general context.
context o f a person as a legal person; provides typical information o f a legal person, but shares e.g., the home address o f the general context.
Different roles modelled as separate classes.
For an example, assume we categorize parts into simple parts and complex parts. In this case, the representation of a simple part is just a more specialized description of the part in general. Of course, a part can either be specialized into a simple or a complex part. It never can be both simple and complex with respect to the categorization criterion "composition of a part". Of course, if one talks about a specialized instance, e.g., a person in the role of an employee, one wants to have access to some of the general information (e.g., the name, the social security number, and the marital status of a person, but not his ownership of a home or his IRS information) in addition to the specific information available in the specific role (e.g., the department name, the office number). The common information like the name of a person should be defined only once in the system, because this would require the maintenance of redundant information. In the case of object specialization, method inheritance takes place between, e.g., a role environment like the one of a student and the general environment like the one that represents common information about a person. Method inheritance via object specialization differs from the subtype inheritance between types which has been discussed in Section 3.4. Subtype inheritance considers structural information, i.e., structural properties and methods are inherited from a supertype. But the method inheritance via object specialization considers the semantics in the real world, i.e., common information of, e.g., a person is made available in a
50 specific situation of, e.g. a student as it will be described later in chapter 4. Section 3.10.3 describes how method inheritance via semantic relationships is realized in our model. Other examples of semantic relationships originate from utilizing the generalization principle for the integration of classes of different databases. Generalization classes are proposed to integrate previously defined classes into a homogeneous global view. The principles thereof and the general rules of integrating heterogeneous databases are treated in detail in chapters 5 and 6. The relationships defined between local classes and the integrating global class can be treated as semantic relationships.
3.10.2 General Characterization of Semantic Relationships In the previous section an example of a semantic relationship, the role specialization relationship, has been described. We now will focus on the inheritance behavior associated with a semantic relationship and its realization. It will be explained by the same example, where a person was modelled in different roles, e.g., in the role of a student, an employee, a father, and a legal person. The general model for realizing the different contexts which arise from the different roles is to map every role to a separate class. That is, a class STUDENT may model the role of a person as a student, and a class EMPLOYEE may represent the person in the role of an employee. The general context of a person which represents the most general information of a person may be represented by a class PERSON. Note, that one real world object is now represented by several instances of different classes. The classes and their corresponding instances are related by the semantic relationship (in our example the role specialization relationship). Appropriate definitions of a metaclass will be used to control the connections between the objects (i.e., between the classes and between the corresponding instances) and coordinate the behavior of the instances according to the detailed semantics of the relationship. The following sections describe how such metaclasses can be defined. But first, we have to look on how the inheritance behavior associated with a semantic relationship can be characterized in general. Assume, a message msg is sent to an object O, and the method selector m used in msg has not been specified for O. That is, m has not been defined by either the own-, the instance-, the corresponding instance-instance-type, or any of their supertypes for O. Then, according to the message passing semantics described in Section 3.9, the message handler would signal an error. But, if the object O was related to an object O ' with respect to some semantic relationship, it could make sense to find out whether O ' would be able to return a semantically meaningful response by executing the method m. For our example, suppose one has defined some methods for instances of a class PERSON, e.g., methods like printName, setSocialSecurityNumber, to manipulate the most general information of a person. Then these methods are contained in the corresponding set M d of persons. In addition, one has defined some other methods on the different roles, e.g., methods like setEnrollmentNumber for the role as a student. These methods will be contained in the
51 corresponding set M d of instances representing students. Then one may distinguish between the following four cases for role specialization: (i)
A method contained in Md(O1) is sent to an instance 01 of the class STUDENT. Then the method can be executed for this instance 01.
(ii)
A method contained in Md(O2) is sent to an instance 02 of the class PERSON. Then the method can be executed for this instance 02.
(iii) A method contained in Md(O2) of an instance 02 of the class PERSON is sent to an instance 01 of the class STUDENT, where the method is not contained in Md(o1). Then we can distinguish two cases as indicated below: 9
If method inheritance is defined, the method is executed for object 02 if the instance 01 is the role specialization of instance 02, i.e., 01 and 02 represent the same real world object in different contexts. This causes a context switch, i.e., during the execution of the method the object 02 is the current context. The inheritance of further methods starts at this context.
9
(iv)
If method inheritance is not defined, the method is not executed and an error occurs.
A method contained in Md(Ol) of an instance 01 of the class STUDENT is sent to an instance 02 of the class PERSON, where O1 is the role specialization of 02, i.e., 01 and 02 represent the same real world. Then the method cannot be executed and an error occurs.
This example shows which kind of inheritance for a semantic relationship has to be defined. Definition 22 and Definition 23 give a formal definition of how the inheritance behavior of a semantic relationship is determined in general. If a semantic relationship is defined between two classes, it is also defined between two corresponding instances of that classes. In our example, the definition of role specialization between the classes STUDENT and PERSON leads to the definition of role specialization between the instance 01 of class STUDENT and the instance 02 of class PERSON, if O1 and 02 represent the same real world object. Definition 22 introduces the notation of semantic relationships at the class and at the instance level.
Definition 22: ( Notation of semantic relationships ) Let A and B be two classes, let a be an instance of class A, b an instance of class B, and let R denote a semantic relationship. Then BR A
denotes the definition (existence) of the semantic relationship R between the class B and the class A. It is also said, B is R-related to A;
bRa
denotes the definition (existence) of the semantic relationship R between the corresponding instances a and b.
52 In the following it is defined how the result of a message is determined in consideration of the inheritance behavior via a semantic relationship.
Definition 23: ( Method inheritance via a semantic relationship ) Let A and B be classes, let a be an instance of class A, b an instance of class B, and let R be a semantic relationship. Let co(m) be the predicate such that f
true,
if (m, a, t) ~ Md(o),
m e MethName, t ~ DomExprV, a e DomArglist, o ~ Objld,
co(m ) = false otherwise.
Let v o denote the result of a message [o m(arg)] if the method m has been executed for object o. Then, the result v of a message [b m(arg)] is determined by the inheritance behavior matrix IR of the semantic relationship R as follows: =
~" v b,
if cb(m ) = true,
L inhR(b, m, arg),
if cb(m) = false
V
The function inhR implements the handling of the message [b m(arg)] with respect to the semantics of the relationship R if the method m is not defined, i.e., it cannot be executed for object b.
Definition 23 specifies, that the result of a message [b m(arg)] is either the result Vb which is achieved if the method m is executed on the structure of the object b, or the result is computed by the function inhR which has to be defined with respect to the semantics of R. For example, inhR may compute the result by executing the message [a m(arg)] if there exists an object a such that b _R a. That is, the message is propagated to the corresponding R-related object a. Note, that the result of [a m(arg)] is also determined according to Definition 23, i.e., inhR may be applied recursively. An inheritance matrix IR can be represented as a table like the one shown in Figure 3.14. It covers two different cases represented by two columns.
cb(m)
Figure 3.14:
True
False
Vb
[a m (arg) ], if 3a: b R a error, otherwise
IR, the method inheritance table for a sample semantic relationship R.
53 The second column in Figure 3.14, i.e. cb(m ) = True, expresses that the method m is defined for the receiver object b, and therefore, the method is executed for the object b, i.e. v = v b. The third column, i.e. cb(m ) = False, is the more interesting one. The method m is not defined for the receiving object, but it could be defined for an object a which is R-related to the object b. Depending on the semantics of the relationship R it might make sense that a semantically meaningful result of the message is achieved by executing the method for the object a. Hence, as shown in the sample table of Figure 3.14 the result v is computed through the message [a m(arg)]. In this example, the function inhR would implement the propagation of the message from b to a. If more than one semantic relationship is defined for object b the function inhR has to implement a strategy which selects the appropriate related object a ' such that the method can be executed for a'. As we will see in Section 3.12.2, a system predefined metaclass VML-CLASS exists. It defines a semantic relationship ~ between instances of classes which are instances of VMLCLASS. This semantic relationship is a trivial one, because it does not define a specific semantics for relationships between these objects, and, hence, no special inheritance behavior via f~ is specified. But note, that the table in Figure 3.15 can still be interpreted as inheritance matrix I ~ of the metaclass VML-CLASS. It reflects the default method inheritance behavior for objects that do not participate in a semantic relationship. A method can be executed only for the receiver object if it is defined for that object (second column) and not for any other object (third column). cb(m)
True
False
V
vb
error
Figure 3.15:
Ifb the method inheritance table for VML-CLASS
In the following section we show how method inheritance via semantic relationships can be realized by adapting the model of message passing described in Section 3.9.
3.10.3 Message Handler Support for Inheritance via Semantic Relationships As described in the previous sections semantic relationships carry specific inheritance behavior. The standard selection logic as specified in Section 3.9 does not support method inheritance via semantic relationships. We now describe how that model of inheritance can be extended with a simple mechanism such that it provides for the inheritance behavior specified by a semantic relationship. In order to support a uniform specification of different inheritance semantics we use polymorphism: We introduce a single predefined method signature. Different implementations may be specified for that method signature and may be used to process the different inheritance strategies.
54 This method signature is defined as follows: inheritanceBehavior (message-selector : Sel, argList : Arglist) returns Result where the domain of the type Sel is the set of method names, i.e., [ Sell] = MethName, and the domain of the type Arglist is the set of all possible actual argument lists, i.e., [[Arglist]] = Value*, and the domain of the type Result is the set of possible result values, i.e., [Result]] = Value, where Value =
U
]]d l , according to Definition 20.
d E DomExpr
If we model the method inheritanceBehavior as a method denotation, which considers also the receiving object (el. Section 3.9), we can write: inheritanceBehavior: Objld x Value * ~ Value. Then the semantics of a message is defined as follows: In case some message [receiver-oid m(arglist)] fails, because the method m is not defined for the receiver, the result is defined by the message [receiver-oid inheritanceBehavior(m, arglist)]. The method inheritanceBehavior implements the inheritance strategy of a semantic relationship R, i.e., it implements inhR. The message handler given in Section 3.9 has to be extended in order to support this kind of inheritance (see Definition 24). In case the method body cannot be determined for the receiving object the message handler has to execute the appropriate implementation of inheritanceBehavior. In order to facilitate the implementation of the method inheritanceBehavior (or other methods using type Result) boolean operators are defined for type Result to test against a concrete data type. For instance, the operator islnteger: Result ---) Bool tests whether a value of type Result is an integer. Other operators are isFloat, isBool, isString, isChar, isOid, and operators testing against constructor types, e.g., isSet, isTuple. Furthermore, the operator isSet: Result • PrimitiveTypeld ~ Bool tests whether a value of type Result is a set of a specific primitive type, e.g., {Oid}. The boolean operator isNull (as introduced in Definition 1) is also defined for type Result. Definition 24: ( Extended message handler ) The message handler which supports method inheritance via semantic relationships is defined through the function send which redefines that one given in Definition 21: send : Objld x MethName x Value*-~ Value send(oid, m, args) =
if oid = undefined then undefined else if (m . . . . )17e Md(oid) then selection(oid, m) (oid, args) else if (m r then send(oid, inheritanceBehavior, bldargs(m, args)); else printMsg ("Method not defined"); return("Method not defined");
55 where the function bldargs expands an existing argument list: bldargs : M e t h N a m e x Value * ~ Value * bldargs(m, args) = (m) + args;
/* concatenation of two tuples */
The function selection is defined as given in 3.9: selection : O b j l d • M e t h N a m e ~ M e t h D e n selection(oid, m)
=
let class = classid(~(oid)) in let metaclass = classid(~(class)) in let o-meth = ownMeths(disptbl(~(oid))) in let i-meth = instMeths(disptbl(~(class))) in let ii-meth = instinstMeths(disptbl(~(metaclass))) in if m e d o m o-meth
then o-meth(m)
else if m 9 d o m i-meth
then i-meth(m)
else if m ~ d o m ii-meth
then ii-meth(m)
where MethDen = O b j l d • Value * ~ Value (already introduced in Definition 20). The function send first tries to determine and to execute the method for the receiver object as it has already been described in Section 3.9. If this fails, the inheritance mechanism via semantic relationships that may be defined for the receiver object is invoked automatically by calling the function send recursively. In that case, the method selector inheritanceBehavior is passed as the identifier for the new method to be executed, the original method selector is passed together with the original arguments as arguments for the method inheritanceBehavior.
If the method inheritanceBehavior is defined for the receiver object did, i.e., (inheritanceBehavior . . . . ) ~ M d (did), the body of inheritanceBehavior, which implements a specific inher-
itance strategy, is executed. If the method inheritanceBehavior is not defined for the receiver object, no method inheritance has been defined for the object, and thus the original method cannot be executed. In this case the function send returns a predefined error code represented as "Method not defined". This allows the calling method to distinguish between the successful execution of a method and the failure of a message. Note, that we only predefined the method signature for inheritanceBehavior. The implementation of this method has to be specified by the user. It can be specified differently and therefore different inheritance strategies can be exploited. It can be specified with instance-instance-types of metaclasses, with instance-types of classes, or with own-types of individual objects. All three alternatives allow to define a method inheritance strategy for terminal instances. 17) The use of an underscorein this tuple indicatesthat the value of that particularfield is not of interest for the comparison.
56 3.11 Short-Hand Notations As a short-hand notation one can define the object types associated with a class together with the class definition statement. In that case, one has to specify class identifiers instead of using object types for the definition of relationships. Type-to-class mappings cannot be used and, hence, the object types cannot be reused for the definition of other classes. For example, one can define the class PERSON given in Figure 3.5 as shown in Figure 3.16.
Date := [day : Integer; month: Integer; year : Integer];
/* a data type
*/
Define class PERSON /* define the class PERSON */ instance-type: Person_lnstType properties: name : String; /* interface section with public properties */ socialSecNum :Integer; car : CAR; address : [ street: String; city: String; country: String; zip: Integer ]; parents: [ mother : PERSON; father : PERSON ]; methods: printName0; birthdate0; printAddress0; setAddress (str: String, city: String, ctry: String, zip: Integer); ss# 0 returns Integer; buyCar(value : CAR) returns PERSON father() returns PERSON mother() returns PERSON Implementation Person_lnstType /* only partial implementation shown */ properties: birthdate : Date; /* private property */ methods:/* Implementation of methods as shown in Figure 3.3 like these:*/ buyCar(value : CAR) returns PERSON { car ~ value; /* assigns a new value to the property car */ return(self); } /* return the identifier of the current receiver */ father() returns PERSON /* return the father of a person */ { return( parents.father ); } mother() returns PERSON /* return the mother of a person */ { return( parents.mother ); }
Figure 3.16: Class definitions including the definitions of the object types 3.12 Defining a Schema After the basic data model concepts have been introduced in the previous sections the rules of how to use these concepts to build a database schema are given now. 3.12.1 Schema A database schema consists of type and class definitions. It can be divided conceptually (see Figure 3.17)
57 9 into a type schema and a class schema, and 9 into a meta layer and an application layer. The type schema contains all type definitions, and the class schema contains all class definitions. The meta layer consists of (a), the initial predefined type and metaclass definitions provided by the system, and (b), the user defined metaclasses and the types associated with these metaclasses. The application layer consists of the user defined classes (also called application classes) and types associated with these classes which are used to model real world situations.
type definitions
I
I
class definitions predefined
ml
la user definable
)lication er
The conceptual parts of a database schema.
Figure 3.17:
Before we describe the definition of the initial predefined metaclass and how to construct a schema, we give a definition of a database schema. D e f i n i t i o n 25: ( D a t a b a s e S c h e m a ) DBSchema
where
= D T D x O T D x OD ,
(introduced in Definition 2) (introduced in Definition 4) O D = O b j l d ~ O b j e c t D e f (introduced in Definition 18). Every database schema definition is a tuple (q, p, ~ ) e D B S c h e m a , where 11 e D T D is the map of data types expressions (cf. Definition 2) p e O T D is the map of object type definitions (cf. Definition 4), and gt e OD is the map of class (object) definitions (cf. Definition 18). The following auxiliary functions are defined on a database schema: datatypes: D B S c h e m a --~ D T D datatypes(dbs) = dbs[1] objecttypes: D B S c h e m a --+ O T D objecttypes(dbs) = dbs[2] objectdefs: D B S c h e m a ---) OD objectdefs(dbs) = dbs[3]. DTD = DTypeld ~
TypeExpr
O T D = O T y p e l d w-~ O T y p e D e f
58 For a database schema Y ~ D B S c h e m a the following functions are used to build up the schema ( O denotes the map overwrite operator):
defdatatype: D B S c h e m a • D T D ---) D B S c h e m a defdatatype(E, dtd) = (datatypes(Z) ~ dtd, objecttypes(E), objectdefs(Z)) defobjtype: DBSchema x OTD --) DBSchema defobjtype(E, otd) = (datatypes(E), objecttypes(Y~) ~ otd, objectdefs(T.)) defclass: DBSchema x O D ~ DBSchema defclass(T,, cd) = (datatypes(T,), objecttypes(T_.), objectdefs(T,) 9 cd) The last three functions given in Definition 25 correspond to the data type, object type, and the class definition statements (see Figure 3.2 and Figure 3.9), though in these statements the specification of Z is omitted and assumed to be given implicitly. The semantic meaning of a database schema is based on the semantic meaning of class definitions. Every class definition leads to the creation and initialization of an object which represents the class. Hence, the definition of a database schema leads to the creation and initialization of the objects which represent the classes specified with the schema.
3.12.2 The Initial Metaelass System The initial metaclass system of VML consists of a few predefined metaclasses and the types used to define them. These metaclasses are 9 the system internal classes like VML-CLASS, VML-TYPE, including the classes used to represent the data dictionary of a database, 9 the class METACLASS at the root level, and 9 the metaclass KERNEL-APPLICATION-CLASS at the metaclass level.
Define VML-CLASS VML-CLASS instance-type VML-Class_lnstType instance-instance-type VML-Class_lnstlnstType Define VML-CLASS METACLASS instance-type Metaclass_lnstType instance-instance-type Metaclass_lnstlnstType Define METACLASS KERNEL-APPLICATION-CLASS instance-type KernelApplicationClass InstType instance-instance-type KemelApplicationClass_lnstlnstType Figure 3.18:
The definitions of the initial predefined metaclasses
In Figure 3.19 the initial metaclass system is identified by the shadowed boxes. The system internal classes provide the basic structures and behavior in order to deal with classes, objects, and the data dictionary of a database. The class METACLASS serves as the root for any
59 metaclass introduced and defined by a system administrator. The class KERNEL-APPLICATION-CLASS is the default metaclass for user defined application classes. Figure 3.18 shows the definitions of these classes.
Figure 3.19: The initial metaclass system of VML
60 Every database schema contains this initial metaclass system which constitutes the predefined part of the meta layer of the schema (see Figure 3.17). All object types, application classes and metaclasses are built up using this initial metaclass system. In the following, more details on the object types and classes constituting the initial metaclass system are given.
Object Type Hierarchy Figure 3.20 shows the initial object type hierarchy. All object types in the system are organized by that type hierarchy. The root of this subtype hierarchy is the type O~ This type does not define any properties and methods. Every object type is either a direct subtype of O or it is a subtype of another object type, i.e., it is an indirect subtype of O.
Figure 3.20: The initial subtype hierarchy
61 A predefined subtype of | is the object type VML-Object_Type. It defines properties and methods which are in common for all objects. For instance, since every object is defined to be an instance of a class, every object O must be able to respond to the message [ O class() ] which returns the identifier of the object's class, i.e., the method class must be defined for every object. This method is defined with the type VML-Object_Type. The defintion of this type is given in Figure 3.21.
Define type VML-Object Type subtype 0 methods: class() returns Oid; setClass (obj: Oid);
Implementation VML-Object Type properties: hasClass: Oid;
/* holds the identifier of that object which */ /* represents the class of an object */
methods: class 0 returns Oid { return (hasClass); } /* returns the value of hasClass */ setClass (obj: Old) { hasClass ~- obj; } /* assign a value to hasClass */
Figure 3.21: Definition of the type VML-Object_Type The predefined object type VML-Class_InstType implements, e.g., a built-in method new which allows to create a new object. Other methods defined by VML-Class_InstType are typical methods for the management of a set of object identifiers, which stands for the actual set of instances of a class. These methods allow to add a new object identifier to the set of actual instances (needed for the creation of a new object), to remove an object identifier from the set of actual instances (needed for the deletion of an object), to test whether a given object identifier identifies an instance of the class. The definition of the type VML-Class_lnst_Type is given in Figure 3.22. The predefined object type VML-Class_InstlnstType is defined as a subtype of VML-Object_Type but implements no further public methods. However, it provides for a homogeneous object type hierarchy and for further extensions. The definition of the type VMLClass_InstlnstType is given in Figure 3.22. The predefined object type MetaclasslnstType is the supertype of the instance-type of any user-defined metaclass, the object type Metaclass_InstlnstType is the supertype of the instance-instance-type of any user-defined metaclass. Both types inherit the definitions given with VML-Object_Type, VML-Class_InstType and VML-Class_lnstlnstType respectively, which guarantees that predefined system functions such as object creation and deletion are available for user-defined metaclasses. The definitions of Metaclass_InstType and Metaclass lnslnsttType are given in Figure 3.23. The predefined types KernelApplicationClass_InstType and KernelApplicationClass InstlnstType are examples of object types defined for a metaclass. VML provides them for the definition of the default metaclass KERNEL-APPLICATION-CLASS for simple applica-
62
Define type VML-Class_lnstType subtypeOf VML-Object_Type methods: new() returns Oid; /* creates and returns a new object alllnstances 0 returns {Oid}; /* returns the set of instances islnstance (obj: Oid) returns Bool; /* test of being an instance addlnstance (obj: Oid); dellnstance (obj: Oid);
/* adds a new instance /* removes an instance from the set
Implementation VML-Class_lnstType properties: haslnstances: {Old}; /* refers to the instances of a class methods: new() returns /* creates and returns a new object of the class { obj: Old; obj <- createobject(self); /* a predefined function that allocates memory [self addinstance(obj)]; /* cf. Section 3.5.2 [obj setClass(self)]; /* ... some other initialization steps depending on the actual internal implementation of objects */ return(obj); } alllnstances 0 returns {Old} {return(haslnstances)}; islnstance (obj: Oid) returns Bool {return(hasElement(haslnstances, obj));} addlnstance (obj: Oid) {insert(haslnstances, obj);} dellnstance (obj: Old) {delete(haslnstances, obj); destroyobject(obj);} /* a predefined function, cf. Section 3.5.2
Define type VML-Class_lnsUnstType subtypeOf VML-Object_Type
Figure 3.22: Definition of the types VML-Class InstType and VML-Class_InstInstType
tion classes. They inherit the definitions given with VML-Object_Type,VML-Class_lnstType and VML-Class_InstlnstTypevia Metaclass_InstType and Metaclass_InslnsttType respectively, which guarantees that predefined system functions such as object creation and deletion are available as default behavior for every user-defined application class. The definitions of the types KernelApplicationClass_InstType and KernelApplicationClass_InstlnstType are given in Figure 3.23. The hierarchy of instance-types and own-types of application classes, and the hierarchy of own-types of metaclasses form lattices with type O as their common root. Note, that the object types needed for application classes are defined independently of object types used for the definition of metaclasses.
63
Define type Metaclass_lnstType subtypeOf VML-Class_lnstType Define type Metaclass_lnstlnstType subtypeOf VML-Class_lnstlnstType Define type KernelApplicationClass_lnstType subtypeOf Metaclass_lnstType Define type KernelApplicationClass_lnstlnstType subtypeOf Metaclass_lnstlnstType
Figure 3.23: Definition of Metaclass_InstType, Metaclass_InstlnstType, KernelApplicationClass_InstType, KernelApplicationClass_InstlnstType The scheme in Figure 3.24 visualizes the mechanism of determining the sets of properties and methods of an object O independent of whether O is a metaclass, an application class or a terminal instance. It shows how the definitions specified with the object types of the initial metaclass system affect the structure and the behavior of an object. For example, the definitions specified with the internally defined type VML-Class_lnstlnstType associated with VML-CLASS affect the structure and behavior of the class KERNEL-APPLICATIONCLASS. The marking of the class KERNEL-APPLICATION-CLASS with the pattern means that all the definitions specified with the type VML-Class_InstlnstType (which has assigned the same pattern) and with its direct or indirect supertypes determine the structure and behavior of the object representing this class. Note, that according to the meaning of the patterns the definitions given by the type VML-Class_InstType affect the objects VML-CLASS, METACLASS, KERNEL-APPLICATION-CLASS, and the application class PERSON. KERNEL-APPLICATION-CLASS is affected by the definitions specified with VML-Class_InstType as this type is an indirect supertype of the instance-type of METACLASS. Class PERSON is affected by the definitions specified with VML-Class_lnstTypeas this type is an indirect supertype of the instance-type of KERNEL-APPLICATION-CLASS.
64
internally defined meta level
VML-Object Type
A
subtypeOf "/L ~stance-instance-type
instance-of
~VML-Class_InstType ~,,~...... r~ nstance'type
/
Figure 3.24: The effects of the initial metaclass system on the determination of the structure and behavior of an object through own-types, instance-types, and instance-instancetypes of the initial metaclass system.
65 3.12.3 How to Specify a Schema According to the conceptual structure of a database schema (see Figure 3.17) the specification of a database schema can be characterized by the following general steps: 9
specification of object types and data types,
9
specification of classes.
As the metaclass concept is homogeneously integrated with the other concepts of the data model, these steps are applied for the specification of the meta level as well as the application level of a schema. In the following we specify the rules to be followed in more detail:
(1) Specification of types and classes at the meta level. As mentioned previously the meta layer of a database schema consists of a predefined initial metaclass system. Any (user defined) metaclass must be specified either as an instance of the initial metaclass METACLASS or as an instance of another metaclass. This leads to an instantiation hierarchy of metaclasses with VML-CLASS as its root. Every metaclass must have associated an instance-type, an instance-instance-type, and an own-type. The instance-type of a metaclass must be defined as a direct or indirect subtype of the predefined type Metaclass_InstType. This guarantees that all instances of a metaclass can behave as regular classes as the (indirect) supertype VML-Class lnstType specifies the default behavior of classes. The instance-instance-typeof a metaclass must be defined as a direct or indirect subtype of the predefined type Metaclass_InstInstType. This guarantees that all the instances of the instances of a metaclass can behave at least as regular objects as the (indirect) supertype VML-Object_Type specifies the common behavior of all objects in a database (see Figure 3.20). The own-type ofa metaclass must be defined as a direct or indirect subtype of the empty type | but it must not be a direct or indirect subtype of VML-Object_Type. Furthermore, if one does not want to specify any specific properties or methods for a metaclass the empty type | itself can be identified as the own-type.
(2) Specification of types and classes at the application level Any class specified at the application level (also called application class) must be an instance of a class specified at the meta level 3, i.e., the predefined initial metaclass KERNEL-APPLICATION-CLASS or another metaclass at this level. Every application class must have associated an instance-type, an instance-instancetype, and an own type. The instance-type and the own-type of an application class must be defined as direct or indirect subtypes of the empty type | but they must not be direct or indirect subtypes of
66
RNEL-APPLICATION~CLASS
ii
J '
predefined metaclasses
user
defined metaclasses
user defined application classes
GQG GQG
(a)
(b)
Figure 3.25: Alternatives of the instantiation hierarchy of classes.
VML-Object_Type. An instance-type should always define some properties and methods. Otherwise, the state and the behavior of an instance of such an application class consists only of the properties and methods defined through the instance-instance-type of the class's metaclass. In analogy to the definition of the own-type of a metaclass the empty type O can be used as the own-type of an application class. Note, that the property and method definitions specified with the instance-types of application classes can be specified independently of any type definitions given with the meta level. The instance-instance-type of an application class usually is the empty type O as an application class is not intended to be used as a metaclass. If one wants to associate an instance-instance-type different from the type O to an application class one must follow the rules specified for the definition of classes at the meta layer. This is, because the application class then becomes a metaclass whose definition must follow the rules given under (1) . Note, that the concept applies recursively and one can theoretically build up an instantiation hierarchy of any depth. The general outline of the subtype hierarchy that satisfies all the rules above has already been given in Figure 3.20. Figure 3.25 shows two general alternatives of the instantiation hierarchy of classes. In case (a) the initial metaclass KERNEL-APPLICATION-CLASS is powerful enough for "naive" use. That is, no additional metaclasses are needed for the specification of the application classes. All application classes are defined as instances of KERNELAPPLICATION-CLASS. In case (b) additional metaclasses have been specified which provide additional common semantics through appropriate property and method definitions for
67 the classes and their instances at the application level. The following three situations characterize the usage of metaclasses in general: a)
Definition of c o m m o n structure and behavior for a subset of the classes in the schema:
Let us remember the definition of the initial metaclass METACLASS. This metaclass provides a default behavior for classes through appropriate property and method definitions inherited from VML-Class_InstType via its instance-type Metaclass_InstType. According to these definitions classes collect their instances by means of a set of object identifiers. If one wants to change this kind of collection, one can define a new metaclass such that classes collect their instances in a different manner. For example, if the identifiers of the instances of a class should be organized by means of a list which reflects the sequence of creations of the instances, one has to provide the behavior of a list instead of a set for the class object. If an implementation wants to support hashed access to the instances of a class, an appropriate hash function can be made available for accessing the identifiers stored in the property haslnstances of the object representing the class. If one wants to provide implementation information on specific indexing techniques, e.g., indexing of complex structured objects [TD93], an index and appropriate algorithms for manipulating the index must be defined for the object that represents the class. In contrast to conventional relational database systems, where only a specific kind of indexing techniques is available for the realization of an index on a relation different indexing techniques (e.g., B-tree, R-tree, R+-tree, Cell-tree [CO79, BMC72, SRF87, GB91]) could be defined for classes. In all these cases, the appropriate definitions can be provided by a metaclass at the meta level 3 (see Figure 3.26): Specify a new object type as a subtype of Metaclass_InstType, such that 9 it redefines the appropriate properties (haslnstances) and methods (e.g., addlnstance, dellnstance) of the indirect supertype VML-Class InstType in order to provide an implementation of a list instead of a set, or 9 it defines the appropriate properties and algorithms for hashed access to the set of object identifiers, or 9 it defines the appropriate properties and methods for a specific indexing technique (e.g., B-tree, R+-tree) on the instances of a class. Associate this new object type as the instance-type to a new metaclass. Use the predefined type Metaclass_InstInstType as the instance-instance-type of the new metaclass.
68 Then, the instances of this new metaclass, which are classes, provide for organizing their instances by means of the creation sequences, for hashed access to their instances, or a specific indexing technique.
VML-Class_InstType
I --
Metaclass_InstTyp~e
instance-instance-type ~ ~ ~ c e - ~ y ~ J Metaclass InstInstType// -
" L_
instance-of
I [ su'~btypeOf
subtypeOf t ~.~~'~ defineslists,
~ ~~''~ ( M ~'~"--~-,'~'~'~'~.'~'~'~1implements instance-instance-type ~ instance-type hashing, _~__~ etc.indexing' [
instance-of
Q~elassesprovidinglistsofOid's, indexedaccess, etc. Figure 3.26: b)
Using metaclasses to specify the common behavior of classes.
Definition of c o m m o n structure and behavior o f the instances of a subset of the classes in the schema:
As discussed in Section 3.8, instance-instance-types associated with metaclasses can be used to provide common structure and behavior of instances of different classes. For instance, this can be employed if one wants to provide specific links between objects, e.g., links between hypertext documents. In this case, one could specify with an instance-instance-type of a new metaclass a relationship "next" and appropriate methods which allow to navigate in the graph built up by these "next"-relationships. Then, all instances of differentclasses defined as instances of such a new metaclass provide the same behavior with respect to the "next"-relationship (see Figure 3.27).
69 VML-Class_InstInstType
[Metaclass_InstInstType l~ subt,,,,eOf av
~
..... "-~ ~ ' instance-instance-type
, , instance-type 9 "-,,,, T 9 ~ ~ ",,, Metaclass InstType j lnstance-oi ,,~ instance-instance-type [ [
implements the relationship and methods navi2,atiofor n the
~ ' ~ k
~
M ) ~
"~------t
instance-type
instance-of
.....
I
I
instance-type
instance-of Q_~ Figure 3.27:
in;/hn2es;'2~tvidthC~176 bh;avi~
Using metaclasses to specify common behavior for instances of different
classes
c)
Definition of reconciled common behavior for classes and their instances
If (a) and (b) are combined and the definitions (properties and methods) specified with the instance-type and the instance-instance-type of a metaclass are reconciled with each other common behavior for different classes and their instances can be defined at the meta level (Figure 3.28). Examples of such a usage of metaclasses are the definitions of semantic relationships between real world objects. The notion of semantic relationships has beeen discussed more precisely in Section 3.10. Examples of such semantic relationships and their definition through metaclasses are given in the subsequent chapter. The combination of (a) and (b) is the most powerful usage of the concept of metaclasses. It provides for the common specification of structural properties and methods for sets of classes and their instances at the meta level, independent of any specifications at the application level. Other modelling concepts could be realized by employing the metaclass concept in this way. In [KNS90] the usage of metaclasses in order to tailor the data model for specific needs of multimedia applications is discussed. Chapter 5 illustrates how the model can be tailored such that it provides for a few modelling primitives introduced in chapter 4.
70
Metaclass_InstlnstType
I
~.....
~
.
-,.C M~,
Metaclass_InstType
~s~).,
t
instance-instance-type~ instance-type subtypeOf I instance-of
~nstance-instance-typ~
I subtypeOf
instance-t_yj~e..._~~'~
9 , -- . . . . . "~( M "~'~"----'-implementscommonbehavior tmptements common \ ] ....... behavior reconciled with ~ reconcuea wtth the mstance~------I instance-typeofM the instance-type of M instance-of
( ~ i
e ~
nstanc
classes and their instances provide common behavior which is reconciled to each other
Figure 3.28: Usingmetaclasses to specify common behavior for classes and their in-
stances.
4 Semantic Data Modelling
4.1 Introduction The overall goal of semantic data models is to capture more meaning of data by integrating relational concepts with more powerful abstraction concepts known from the Artificial Intelligence field. The idea is to provide high level modelling primitives as integral parts of a data model in order to facilitate the representation of real world situations. In this chapter we informally introduce a few modelling primitves as they can also be found in some semantic data models [STW84, UD86]: object specialization, aggregation, components. In addition, we describe simple primitives to model hypertext based argumentative networks [TOU58, S HT89] which primarily consist of specific kinds of nodes and links. These semantic modeling primitives are then used in the subsequent chapter to show how the data model described in chapter 3 can be extended in a way that these abstractions become part of the resulting model. We illustrate some of the modelling primitives by an example which is developed incrementally and summarized in Figure 4.5. We only characterize the primitives by briefly describing some basic functionality. Furthermore, we use a pseudo notation for the examples in this section in order to clearly distinguish between the informal description of the concepts and the concrete realization shown in the subsequent chapter.
4.2 Object Specialization In a type (or class) specialization hierarchy, as it is found in object-oriented programming languages like SMALLTALK [GR83], FLAVORS [MOO86], OBJECTIVE-C [COX87], C++ [STR87], and CommonObjects [SNY86], real world objects are represented as instances of the most specialized class in which they can be classified. This is appropriate if the real world objects to be modelled can be classified into a set of disjoint object classes, and the objects never change their class. It is more appropriate to apply the principle of specialization at the instance level when objects change their class dynamically. This is the case if the type of a real world object is uncertain and specialized gradually, or if a real world object appears in different roles, or if a real world object is modelled over its life cycle by different object classes. Therefore the principle of object specialization is introduced. Contrary to type specialization, object specialization is applied at the instance level. A real world object which is represented as an instance of a particular class is also represented as an instance of a related superordinate class. The instance of the superordinate class models the properties defined at the superordinate class, and the instance of the subordinate class models only the properties defined at the subordinate class. The principle of object specialization can be used with different semantics:
72 (i)
It may be used to specialize more general representations of real world objects according to some category into more special representations. In this case every instance of a subordinate class, or category-specialization-class, models a real world object that is modelled also by an instance of its superordinate class. Furthermore the instance is not represented in any other category-specialization-class of the superordinate class.
(ii) It may be used to model different roles of, one and the same, real world object. In this case every instance of the role-specialization-class models a real world object which is also modelled by an instance of a related superordinate class. But the instance of the role-specialized class models the real world object in a specific situation or context which has not been considered explicitly in the superordinate class.
Example: In Figure 4.1 the class PART has the category-specialization-classes SIMPLE-PART and COMPLEX-PART. An individual part can either be a complex part or a simple part, but never both. In Figure 4.2 classes STUDENT and EMPLOYEE are role-specialization-classes of class PERSON. An individual person can appear as both a Student and an employee. Furthermore, one could define classes UCB-STUDENT and TU-STUDENT
~ casMPLE-PART i ,,,~;~,:~
class PART attributes:
~~:~ ~
~ PartNo: STRING ~' ManufacturedFirst: YEAR
methods"
Weight:KILO BasCost: POUND end SIMPLE-PART class COMPLEX-PART
I
Cost: POUND end PART
~
category-specialization-of: PART attributes:
~~
Figure 4.1: Category specialized classes
category-specialization-of: PART components: Subparts: set of SUBPART methods: Cost: POUND
|:ii! !!~ i:~] l~ t~
73
. . . . . . . . . . . . .
methods: Age : I N T E G E R Address : STRING end PERSON
r v .
Department : DEPARTMENT methods: Income : INTEGER Address : STRING end EMPLOYEE
Figure 4.2: Role specialized classes as role-specialization-classes of class STUDENT given the fact that an individual student can study at different universities. Between an instance of a (superordinate) class and an instance of a category-specialization-class (role-specialization-class)that models the same real world object, the has-category-specialization (has-role) relationship holds. Its inverse is the category-specialization-of (role-oJ) relationship. The message of type [ category-specialization-of()] is defined for instances of category-specialization classes. The addressed will return the instance of the superordinate class that represents the same real world object. Furthermore, it will be assumed that every object can respond to the message of type [ has-category-specialization ()] by returning that instance of the subordinate class which represents the same real world object than ; if no such instance exists, the null-object is returned. Instances of role-specialization classes return to a message of type [ role-of()] the instance of the superordinate class that represent the same real world object. Furthermore, it will be assumed that every object can respond to the message of type [ has-role (
74 )] by returning those instances of the subordinate class which represent the same real world object than . An instance of a (subordinate) class inherits the attribute and relationship values and the methods from that instance of the superordinate class which represents the same real-world object. However a (subordinate) class may override inherited attribute values and methods. The predefined category-specalization-of(rsp, role-of) message is used to retrieve the corresponding instance in the superordinary class.
Example: If'p541-COMPLEX-PART' is an instance of the class COMPLEX-PART, the message ['p541-COMPLEX-PART' PartNo0] will be transformed to [['p541-COMPLEXPART' category-specialization-of()] PartNo0]. If 'p007-EMPLOYEE' is an instance of the class EMPLOYEE, the message ['p007-EMPLOYEE' Age()] will be transformed to [['p007-EMPLOYEE' role-of()] Age()]. In contrast, the message ['p007-EMPLOYEE' Address()] will not lead to the execution of the method Address defined for persons but to the execution of the method Address defined for employees. That is, the method Address defined for employees overrides the method Address defined for persons. Here it is assumed that every specialization class has exactly one superordinate class. But it is easy to see that one can define various combinations and variants of object specialization.
4.3 Aggregation Aggregation [SS77] is an abstraction principle in which a relationship between several constituent objects is considered a single higher level object that is dependent on its constituent objects. However, the constituent objects are independent of the aggregate object. They participate only in the relationship which is represented by the aggregate object and may not be considered private parts of the aggregate object. They must already exist when the aggregate object is created and they continue to exist when the aggregate object is deleted. Traditionally, the term "component object" has been used instead of "constituent object". But the term "component object" is semantically overloaded. It has been widely used to refer to private parts of a complex object. We believe that the term"constituent object" is more appropriate in the case of an aggregation. Such an object must exist in order to constitute a new relationship object. Between an aggregate object and a constituent object the has-constituent relationship holds. It can be named; its inverse is the constituent-of relationship.
Example: In Figure 4.3 the class ORDER has been specified as an aggregate class. The constituent relationships have been named "OrderingCustomer" and "OrderedPart".
75
Figure 4.3: Aggregation classes For instances of aggregate classes the message type [ has-constituent ()] is defined. An aggregate object responds to such a message by returning the value of the constituent-relationship with the range-class . Furthermore, it will be assumed that every object can respond to the message of type [ constituent-of()] by returning those instances of the aggregate class which have the as a constituent.
Example: If 'o 15-ORDER' is an instance of class ORDER with its constituents 'c47-CUSTOMER' (representing an ordering customer) and 'p541-PART' (representing an ordered part), the message ['ol5-ORDER' has-constituent(PART)] will return 'p541-PART'. The message ['p541-PART' constituent-of(ORDER)] will return all instances of class ORDER the part 'p541-PART' is a constituent of, i.e., it will include the order 'o 15-ORDER'. In Figure 4.3 the class ORDER has been specified as an aggregate class. The constituent relationships have been named "OrderingCustomer" and "OrderedPart". Note: it is assumed that for a given aggregate class the range classes of its has-constituent relationships are different.
76
4.4 Components Components are used to model the structure of complex objects. A component object is related by a component-of relationship to its complex object. The inverse relationship is the has-component relationship. Contrary to the constituents of an aggregate object, component objects will be considered as private parts of the complex object. It is required that every component object belongs to exactly one complex object. A component object is considered subordinate to the complex object, or superordinate ob-
ject, it describes. The relationship between a subordinate object and a superordinate object has the following characteristics: the existence of the subordinate object is dependent on the existence of the superordinate object. Therefore the following design principles should be followed: (i)
If some object can exist independently of another object, the relationship between these objects should not be modelled by means of a component-of relationship, but by an ordinary relationship.
(ii) If a component object has a property whose value is independent of the superordinate object, then the component-class should be modelled as a role-specialization-class of some other more general class. The instance of that more general class shall model the properties whose values are independent of the superordinate object, and the component-class shall represent those properties whose values are dependent on the superordinate object. In other words, the more general class represents the properties that are "'context-free", and the role-specialization-class models the properties that are "context-sensitive", with respect to the superordinate object. The has-component relationship can be named and may be set-valued.
Example: Consider the class COMPLEX-PART in Figure 4.4. It has the set-valued component "Subparts" which represents the set of a part's subparts. The class SUBPART models a member of such a set, i.e., a real world part in the role of being a subpart of some more complex part. The attribute "AssemblingCost" gives the cost needed to assemble the subpart into its superpart. Those properties of a part which are independent from its role of being a subpart of a specific superpart, e.g., "PartNo", "ManufacturedFirst", and "Weight", are modelled by classes PART and SIMPLE-PART. The message of type [ has-component ()] is defined to retrieve the component objects of that are instances of . The message of type [ component-of()] is defined to retreive the superordinate object of .
77
class PART attributes: PartNo: STRING ManufacturedFirst: methods: Cost: POUND end PART
YEAR
attributes: AssemblingCost: POUND end SUBPART class COMPLEX-PART category-specialization-of: PART components: Subparts: set of SUBPART methods: Cost: POUND end COMPLEX-PART
Figure 4.4: Role specialized class as component It is assumed that every component-class appears exactly once as range-class of a has-component relationship.
78
class PERSON attributes: Name: STRING Birthdate: DATE Ss#: INTEGER Address: STRING methods: Age: INTEGER Address: STRING end PERSON
class EMPLOYEE role-of: PERSON attributes: Salary: INTEGER Address: STRING relationships: Department:DEPARTMENT methods: Income : INTEGER Address: STRING end EMPLOYEE
class PART attributes: PartNo: STRING ManufacturedFirst: YEAR methods: Cost: POUND end PART class SIMPLE-PART category-specialization-of: PART attributes: Weight: KILO BaseCost: POUND end SIMPLE-PART class COMPLEX-PART category-specialization-of: PART components: Subparts: set of SUBPART methods: Cost: POUND end COMPLEX-PART class SUBPART role-of: PART /* component of: COMPLEX-PART */ attributes: AssemblingCost: POUND end SUBPART class ORDER aggregation-of: OrderingCustomer: CUSTOMER OrderedPart: PART attributes: OrderDate: DATE Number: INTEGER end ORDER
class CUSTOMER attributes: Name: STRING Address: STRING Credit: POUND relationships: ResponsibleSalesman: SALESMAN end CUSTOMER
Figure 4.5: Sample order database of a company. 4.5 H y p e r t e x t Structures In contrast to the modelling primitives described in the previous sections, which are also known from classical semantic data models, we introduce now a simplified version of the concepts of nodes and links as they are needed for the representation of hypertext based argumentative networks. Such networks are used to support and control the creation of argumentative texts as a special case of writing. In our example, we choose a schema proposed by
79 Toulmin [TOU58] for the representation of arguments, which has been adapted and extended for SEPIA [SHT89], a system for structured elicitation and processing of ideas for authoring. Figure 4.6 shows some elements of an argument which consists of a datum, a claim, a warrant, a backing, and a rebuttal. D a t u m and claim are related via a so-link stating the argument: "The farmer who does without fertilizer and herbicides in the field and without hormones and tranquilizers in the pigsty has to work much harder than a chemistry f a r m e r " - - s o ~ "it is not worthwhile to produce natural food". A w a r r a n t like "Any additional work without additional return is not profitable" is given in our example in order to support the legitimation of the so relationship between the d a t u m and the claim. The w a r r a n t is related to the so relationship via the since relationship and it provides a general rule justifying the so conclusion. The validity of this general rule is supported by a backing like "Economical theory", which is related to the w a r r a n t via the on account__ofrelationship. The element rebuttal is used to handle exceptions which question the claim. Writing an argumentative text means building up arguments, relating them to others, or constructing abstractions like positions, i.e., arguments contribute to or contradict specific positions. This leads to an argumentative network which conceptually consists of nodes, links, and units constructed from interconnected nodes. In [SHT89] an overview of the general structure of argumentative networks and of the operations defined on such networks is given.
Figure 4.6: Example of an adopted Toulmin argumentation schema [SHT89].
80 The essential concepts used herein to illustrate how to build up an argumentative network are the following ones: A node represents a statement which is interpreted either as a datum, a claim, a warrant, a
backing, or a rebuttal. A link relates two nodes or a node and a link. If the type of the link is so, it relates a datum with a claim, if the type is
since, unless, on_account_of, contradicts,
it relates a warrant with a so-link, if the type is it relates a rebuttal with a claim, if the type is it relates a backing with a warrant, and if the type is it relates a datum or claim with another datum or claim.
The following operations specific to the underlying semantics of such argumentative networks are examples of operations defined on nodes or links: A so-link between a datum and a claim which is supported by that datum can be created by a message of type [ support ()]. A message of type [justify (, <warrant>, )] creates a new so-link from a supporting node (which must be a datum) to the supported node (which must be a claim) by specifying a node which serves as a warrant and an optional node which serves as a backing. The warrant is related via a since-link to the newly created so-link, and the backing (if specified) is related to the specified warrant via a
on,accound_of-link. A message of type [ negate ()] relates a datum or claim via a contradicts-link with another datum or claim. In addition to the methods used to construct an argumentative network one needs methods to navigate through the network like the following ones18: A message of type [facts()] retrieves all data the is supported by. A message of type [ rational()] retrieves all data supporting the and, if available, the evidence (warrants) for this data as well as the support for the evidence, i.e. the backings. A message of type [ allConclusionsO] retrieves all claims which are supported by directly or indirecty. A message of type [ conclusions(n)] retrieves all claims which are supported by directly or indirecty up to level n. 18) We do not introducethe whole spectrumof navigationalmethods which might be usefulfor reasoning on an argumentativenetworkbut rather focus on a few representativeones. Furthermore,on top of the concepts introducedhere one can build more complex structures like arguments and definerelated inference and reasoningoperations.
81
A message of type [ contradictsToO] retrieves those data which is in conflict to . A message of type [ unless()] retrieves the information which rebuts . The basis for the behavior pointed out above is formed by common navigational operations on a network. So far we did not describe such basic navigational operations. As we do not want the application designer to be responsible for the realization of these navigational operations we want the data model to provide them together with the modelling primitives nodes and links. The subsequent chapter shows how the data model can be extended with these primitives.
5 Metaclasses for Semantic Data Modelling 5.1 Introduction In this chapter we describe how the VODAK data model can be tailored by metaclasses such that is subsumes the data modelling primitives presented in the previous chapter. We show first how the data model can be adapted by the definition of metaclasses in general. Then we define several metaclasses supporting object specialization, aggregation, components, and hypertext based argumentative networks as described in chapter 4. The specifications of the types and classes used in the examples have been chosen such that they can be read and understood easily, and such that they demonstrate the flexibility and modularity of the concepts. The specifications often could be implemented more efficiently (e.g. by making use of the query language and of indexes which are not considered in this context) or should include checking of obvious consistency constraints (e.g., the range of an array index), but this would overload the examples with non-relevant specifications and make them harder to read and to understand. Note also that there always exist several variants of implementing the concepts. The ones chosen should also illustrate the diversity of conceptual solutions.
5.2 General Approach of Defining Semantic Modelling Primitives This section demonstrates how metaclasses can be utilized to tailor a data model for specific applications by introducing semantic relationships through appropriate metaclass definitions. Two alternatives of how to use metaclasses to define semantic relationships are compared. One of these alternatives is used then for the concrete definition of a few semantic relationships which tailor the data model for the integration of heterogeneous databases. The concepts of metaclasses, instance-instance-types, instance-types, and the definition of specific inheritance behavior through the definition of a method inheritanceBehavior can be used to tailor the data model to the needs of particular users and applications. In Section 3.12.3 the general rules for defining metaclasses have been given. For the representation of semantic relationships through metaclasses we have two alternatives:
5.2.1 Defining Semantic Relationships Through a Single Metaclass Let us consider the first alternative, i.e., all semantic relationships needed for an application are defined through a single metaclass. In this case, the semantics of the different kinds of semantic relationships must be specified with the instance-type (and/or its supertypes) and the instance-instance-type (and/or its supertypes) associated with the metaclass. Every instance of the metaclass, i.e., every application class which is an instance of the metaclass, supports all semantic relationships provided by the metaclass. Thus, every instance of such an application class can participate in all semantic relationships. Figure 5.1 shows the type and class hierarchy for this alternative.
83 The advantages of this solution are that only one metaclass is needed to introduce all semantic relationships and that all classes which are instances of that metaclass may participate in all semantic relationships. As the structure and behavior definitions for all semantic relationships are available for such a class and its instances, the participation in a specific relationship need not be known at the time of the definition of the class. One disadvantage of this alternative is that all semantic relationships are made available through a single metaclass. No other metaclasses defining semantic relationships exist. As a consequence, one cannot select for an application class a single semantic relationship or a particular combination of semantic relationships. Furthermore, one has to investigate all possible combinations of semantic relationships in before hand and analyze whether a combination is legal. There is no other way to prevent useless combinations of semantic relationships. Hence, the definition of such a metaclass will be very complex, as other new semantic relationships may effect all classes.
5.2.2 Defining Semantic Relationships Through Multiple Metaelasses The second alternative is that a metaclass provides only one semantic relationship or a specific combination of semantic relationships. In the first case, the instance-type (or its supertypes) and the instance-instance-type (or its supertypes) associated with a metaclass specify only one semantic relation-
-of
Figure 5.1: Defining semantic relationships through a single metaclass
84
,) ~f one ombizntic
cification oj specific c~ ion of sema~ ~tionships
Lance-type Lce-type
-
instance-instance-type
" ~ ~
.. instance-o'er "
S
nstance-Of
METACLASS
Figure 5.2: Defining semantic relationships through multiple metaclasses
ship. Hence, the instances of the metaclass and their instances can behave according to only one semantic relationship. In the second case, a specific combination of semantic relationships is specified with the instance-type (or its supertypes) and the instance-instance-type (or its supertypes) associated with a metaclass. Application classes which are instances of that metaclass can behave according to them. Figure 5.2 shows a type and class hierarchy for this alternative. The advantage of this alternative is a modular specification of semantic relationships through several metaclasses. An application designer can choose those metaclasses providing the relationships really needed. In contrast to alternative (a) one does not have do consider all possible combinations of relationships as one can restrict the definition and usage of metaclasses to useful combinations. As not all semantic relationships are available for a class and its instances through their metaclass, one cannot define easily additional kinds of semantic relationships for a class and its instances. This is a disadvantage in contrast to alternative (a) which provides all semantic relationships for an object and thus additional relationships may be specified at any time. But this problem is strongly connected to the problem of schema evolution. Any change (modification or additional definition) with respect to
85 the semantic relationships defined between existing classes and between their instances corresponds to a change in modelling real world things. For example, defining an additional new semantic relationship between classes and between their instances may effect the strategy of method inheritance via the semantic relationships, because the inheritance semantics of the new relationship must be integrated and adjusted with the inheritance strategy of the already defined relationships. In addition, new properties and methods are needed for the existing classes and their existing instances in order to take into account the additional new semantic relationship. This is a classical problem of schema evolution which is not further discussed in the framework of this thesis. In the following, the second alternative will be employed for the definition of several semantic relationships and specific useful combinations. It is illustrated how semantic relationships can be introduced into the data model in practice. We follow the rules and methodologies introduced in this chapter and use the modelling features described in Chapter 3.
5.3 Object Specialization In this section we show how the data model presented in chapter 3 can be extended such that it provides the object specialization primitives as introduced in chapter 4. 5.3.1 Role Specialization of a Single Class Real world objects may appear in different roles, e.g., a person may appear in the role of a student or an employee. Classes which represent specific roles like the one for students can be defined by specifying appropriate role specialization relationships to the more general class person. A class representing a specific role can participate in only one role specialization relationship to a more general class. For example, a class representing a person in the role of a student can only participate in the role specialization relationship to the more general class person and not to another general class. In the following, we give a definition of the role specialization relationship according to the general characteristics of semantic relationships discussed in section 3.10.2 and specify its implementation through a metaclass.
Definition 26: ( Role specialization of a single class ) Let rolespec denote the semantic relationship role specialization. Then for objects a, b ~ ObjId and classes A, B ~ ClassId holds: 9 9
B rolespec A ~ --,3 C E Classld ( B rolespec C ^ C ~ A ), and (BrolespecAA binstanceOfB)~3a(ainstanceOfAA br~
The inheritance semantics for role specialization is determined by the matrix Irolespec as shown in Figure 5.3. It shows how the result v of a message [b m(args)] is determined.
86 cb(m)
True
Fa~e
V
Vb
[a m(args)]
Figure 5.3: Irolespec : It defines the inheritance semantics for role specialization. In the following we introduce the metaclasses ROLE-SPECIALIZATION-CLASS and SINGLETON-CLASS which provides the semantic relationship role-specialization-of. Figure 5.4 shows the general connections and relationships between the metaclass and some application classes. Persons are represented as instances of a class PERSON which is defined as an instance of the metaclass SINGLETON-CLASS. The classes STUDENT and EMPLOYEE are used to model two roles of a person. Hence, both classes are defined as instances of the metaclass ROLE-SPECIALIZATION-CLASS which provides the role-semantics for these classes and their instances. If one wants to define further roles for students, e.g., students of UCB and/or TU, one may define appropriate classes like UCB-STUDENT and TU-STUDENT as instances of the metaclass ROLE-SPECIALIZATION-CLASS. The reason why we introduce the metaclass SINGLETON-CLASS is the requirement given in section 4.2. Every object should be able to respond to a message of type [ hasrole ()]. The method has-role is defined with the instance-instance-type of SINGLETON-CLASS, and, hence, every instance of PERSON can respond to such a message. Figure 5.5 shows the definitions of SINGLETON-CLASS and its object types Singleton-
ClassjnstType and SingletonClass_InstlnstType 19. The definition of the metaclass ROLE-SPECIALIZATION-CLASS is shown in Figure 5.6. The definitions of its instance-type RoleSpec_InstType and its instance-instance-type RoleSpec_InstlnstType are shown in Figure 5.7a-b. Note, that type RoleSpec_InstType imple-
Figure 5.4: Relationships between role specialized classes and between the metaclasses
87
Define METACLASS SINGLETON-CLASS instance-type: SingletonClass_lnstType instance-instance-type: SingletonClass_lnstType Define type SingletonClass_lnstType subtypeOf Metaclass_lnstType Define type SingletonClass__lnstlnstType subtypeOf Metaclass_lnstlnstType properties: methods: has-role(roleSpecClass : Oid) returns {Oid}; Implementation SingletonClass_lnstlnstType methods: has-role(roleSpecClass : Oid) returns {Oid}; { roleObjs : { Oid }; o : Oid; roleObjs <-- {}: if ( [self class()] = [roleSpecClass role-class-of()] )//if roleSpecClassis a valid then for (o in [roleSpecClass alllnstances0]) //role specialization class if ( [o role-of()] = self ) then insert(roleObjs, o);//collect the corr. objects return(roleObjs); }
Figure 5.5: Definition of the metaclass SINGLETON-CLASS
Define METACLASS ROLE-SPECIALIZATION-CLASS instance-type: RoleSpec_lnstType instance-instance-type: RoleSpec_l nstlnstType
/* see Figure 5.7a */ /* see Figure 5.7b */
Figure 5.6: Definition of the metaclass ROLE-SPECIALIZATION-CLASS, which provides the role specialization relationship. ments the relationship rolespec between classes, and that type RoleSpec_InstlnstType implements the relationship rolespec between instances of these classes. The instance-type RoleSpec_lnstType (Figure 5.7a) specifies the property roleOf. For a particular role-specialization class, e.g., STUDENT, it holds the identifier of that class whose instances are to be considered in a specific role, e.g., PERSON. The method defRoleClass is used to initialize that property. The method create creates a role specialized instance 01 for a given instance O such that 01 rolespec O. An instance 01 is created if class(01) rolespec
class(O) holds. This constraint is checked by the method isValidRoleSpecClassOf. In addition, the method create initializes the property roleOfwhich is defined with the instance-instance-type RoleSpec_InstlnstType. 19) The definitions of the object types SingletonClass_lnstTypeand SingletonClass_InstlnstTypeare extended later in this and the subsequent chapters.
88
Define type RoleSpec_lnstType subtypeOf SingletonClass_lnstType properties: roleOf : Oid; /* holds the object identifier of the generic class */ methods: defRoleClass (genericClass : Oid);/* defines a class as a role of a generic class */ create(genericlnstance : Oid) returns Oid; /* creates a role of a generic */ /* instance */ isValidRoleSpecClassOf(genericClass: Oid) returns Bool;/*tests whether a class */ /* is a role of a generic class or not */ role-class-of0 returns Oid; /* returns the value of roleOf */ Implementation RoleSpec_lnstType methods: defRoleClass(genericClass : Old) {roleOf <--- genericClass;} /* assign the role-related generic class */ create (genericlnstance : Old) returns Old {roleObj : Old; if ( NOT [self isValidRoleSpecClassOf([genericlnstance class()])]) then { signal("failed: Such a role cannot be created for this object."); return(NULL); } roleObj <-- [self new()]; /* create the new instance */ [roleObj initRoleOf(genericlnstance)]; /* connect it to the generic object */ return(roleObj);} isValidRoleSpecClassOf(genericClass: Oid) returns Bool {return(roleOf = genericClass);} role-class-of0 returns Old {return(roleOf);]
Figure 5.7a: Specification of the instance-type RoleSpec_InstType of the metaclass ROLE-SPECIALIZATION-CLASS. The type RoleSpec_InstType is defined as a subtype of type SingletonClass_InstType given in Figure 5.5. The method new, which creates a new object, is inherited from the indirect supertype VML-Class_InstType. The method class, which returns the identifier of the object's class, is inherited from type VML-Object_Type. The instance-instance-type RoleSpec__lnstlnstType (Figure 5.7b) specifies a property roleOf, which identifies for a role specialized object, e.g., a specific student, the corresponding more general object, e.g., the person represented by the student. The method initRoleOfis utilized for the initialization of the roleOfproperty, whereas the method role-of is used to get the identifier of the object referred to by that property. The inheritance behavior specified for role-specialization is implemented with the method
inheritanceBehavior specified with the type RoleSpec_InstlnstType according to Irolespec. If inheritanceBehavior is called, the original method sent to the role specialized object is sent to the object referred to by the roleOfproperty.
89
Define type RoleSpec_lnstlnstType subtypeOf SingletonClass_lnstlnstType properties: roleOf: Old; /* holds a reference to the generic instance */ methods: initRoleOf (genericlnstance : Old); /* initialize the roleOf relationship */ inheritanceBehavior(m: Sel, arglist: Arglist) returns Result; /* implements the inheritance behavior */ role-ofO returns Old; /* returns the roleOf property */ Implementation RoleSpec_lnstlnstType methods: initRoleOf (genericlnstance : Old) {roleOf ~- genericlnstance;} inheritanceBehavior(m: Sel, arglist: Arglist) returns Result {return([roleOf eval(m) (arglist)]);} /* apply the method referred to by m */ /* to the object referred to by roleOf */ role-ofO returns Old {return(roleOf);}
Figure 5.7b: Specification of the instance-instance-type RoleSpec_InstlnstType for the metaclass ROLE-SPECIALIZATION-CLASS.
The instance-instance-type RoleSpeclnstlnstType is defined as subtype of SingletonClass_InstlnstType, and therefore, it is an indirect subtype of VML--Object_Type.As a consequence, the property and method definitions specified with VML-Object_Type affect the structure and behavior of 9 the individual instances of the class PERSON via the instance-instance-type SingletonClass InstlnstTypeassociated with SINGLETON-CLASS, the metaclass of PERSON, and 9 the instances of the metaclass ROLE-SPECIALIZATION-CLASS, e.g., STUDENT, EMPLOYEE, UCB-STUDENT, and TU-STUDENT, via the instance-instance-type Metaclass_InstlnstTypeassociated with METACLASS, the metaclass of ROLE-SPECIALIZATION-CLASS. Defining RoleSpec_InstlnstTypeas subtype of SingletonClass_InstlnstTypeguarantees that role specialized objects like students for which further role specializations like UCB-students are defined can also respond to a message of type [ has-role()]. Figure 5.8 shows the definition of class STUDENT as a role specialization of class PERSON.
90
Define SINGLETON-CLASS PERSON instance-type: Person_Type properties: name : String; address : String; birthdate : String; methods: name() returns String; setAddress(a : String); setBirthdate(b: String); printName0; printAddress0; printBirthdate0;
/* /* /* /* /* /* /* /* /*
stores the person's name stores the person's address stores the person's birthdate returns the name of a person assigns a new address assigns a birthdate prints the name of a person prints the address of a person prints the birthdate of a person
Define ROLE-SPECIALIZATION-CLASS STUDENT instance-type: Student_Type properties: enrollmentNo: Integer; /* storesthe enrollment number address: String; /* stores the student's address methods: setEnrollmentNumber (no: Integer); /*assigns the enrollm, no. printEnrollmentNumber 0; setAddress (addr : String); printAddress 0; init: defRoleClass(PERSON); /* define
/* prints the enrollment no. /* assigns the student's address /* prints the student's address STUDENT as a role of PERSON
*/ */ */ */ */ */ */ */ */
*/ */ */ */ */ */ */
Figure 5.8: Definition of a class as instance of the metaclass for role specialization In the example below (Figure 5.9 shows a fragment of a program) Mr. Frank Miller becomes a new student. The inheritance behavior, as defined by the method inheritanceBehavior of the instance-instance-type of the metaclass ROLE-SPECIALIZATION-CLASS according to the inheritance semantics shown in Figure 5.3, is demonstrated by the messages [s printBirthDate()] and [s printName0]. No methodprintBirthDate is defined for instances of STUDENT. Hence, the method inheritanceBehavior is utilized to retrieve this date through a message to the corresponding instance of class PERSON. The same applies to the method printName. It is inherited via the rolespec relation from the corresponding instance of class PER-' SON. In order to provide a better understanding of the examples the result of a message is printed in quotes in Figure 5.9. Note, that the implementation of rolespec through the type RoleSpec_InstType and the implementation of rolespecthrough the type RoleSpec_InstlnstType allows us to model roles of classes and their instances which already represent roles. That means, the metaclass can be used for building up a tree of role specialized classes and instances of any depth.
91
p: PERSON, s: STUDENT /* define variables p +-- [PERSON select("name = "Frank Miller"')] /* select the person F. Miller [p setAddress("1001 Shattuck Avenue, Berkeley")] /* assign an address s e- [STUDENT create(p)] /* create a student role for Mr. Miller" [s setAddress("Student House, 2300 Telegraph Avenue, Berekely")] [s printName0] /* accesses the name of the person
*/ */ */ */ */
"Frank Millef' [p printAddress0]
/* returns the address as person
*/
/* returns the address as student
*/
"1001 Shattuck Avenue, Berkeley" [s printAddress0]
"Student House, 2300 Telegraph Avenue, Berekely" [s printBirthDate0]
"07-03-64"
/* access the birthdate defined at person p */ /* the result of the message */
Figure 5.9: Method inheritance via the role specialization relationship.
5.3.2 Category Specialization Real world objects may be categorized into disjoint sets with respect to some specific classification criterion, e.g., parts may be categorized into simple parts and complex parts with respect to their composition. Classes which represent categories like complex parts can be defined by specifying appropriate category specialization relationships to a general class PART. Then the classes representing categories of objects reflect a more specialized description of those objects, i.e., they model some properties of the real world object which have been neglected in the general representation. We already introduced a simpler version of this category_specialization_of relationship in section 4.2. In the following, we give the definitions of metaclasses for a slightly more powerful version of that relationship as we include the feature of classification criteria which are used to categorize objects into disjoint sets. Definition 27: ( Categqry specialization ) Let catspec(o~) denote the category specialization relationship with respect to the classification criterion ~. Then for objects a, b, c ~ Objld, classes A, B, C ~ Classld, and criteria ~, ~ e Symbol holds: 9
B catspec (~) A ~ 7 3 C c Classld--,3 ~ c Symbol ( B catspec (~) C A C ~ A ), and
9
( Bcatspec(~)A A b instanceOfB A 3 a ( a instanceOf A A b catspec(o~) a A 9 3 C ( C instanceOf C A C catspec(ao a )).
Ceatspec(eOa)
The inheritance semantics for category specialization is determined by the matrix Icatspe c as shown in Figure 5.10. Note, that Icatspec is identical to Irolespec. It shows how the result v of a message [b m(args)] is determined, i
92
cb(m)
True
False
V
vb
[a m(args)]
Figure 5.10: lcatspec:= Irolespec; It defines the inheritance semantics for category specialization.
We introduce the metactass CATEGORY-SPECIALIZATION-CLASSand extend the metaclass SINGLETON-CLASS in order to provide this semantic relationship. Figure 5.11 shows the relationships and connections between the different classes. Both metaclasses CATEGORY-SPECIALIZATION-CLASS and SINGLETON-CLASS are instances of METACLASS. Any class which serves as a category specialization of another (general) class must be defined as instance of CATEGORY-SPECIALIZATION-CLASS. Any class which serves as the general class for category specialized classes must be an instance of class SINGLETON-CLASS. In our example, the classes SIMPLE-PART and COMPLEX-PART are instances of CATEGORY-SPECIALIZATION-CLASS, and the class PART is an instance of SINGLETON-CLASS. Figure 5.12 shows the definition of the metaclasses SINGLETONCLASS and CATEGORY-SPECIALIZATION-CLASS.
Figure 5.11: Relationships between category specialized classes and the metaclasses
93
Define METACLASS SINGLETON-CLASS /* extensions to Figure 5.5 instance-type: SingletonClass_lnstType /* see Figure 5.13 instance-instance-type: SingletonClass_lnstlnstType /* see Figure 5.13
*/ */ */
Define METACLASS CATEGORY-SPECIALIZATION-CLASS instance-type: CategorySpec_lnstType /* see Figure 5.14a */ instance-instance-type: CategorySpec_lnstlnstType /* see Figure 5.14b */
Figure 5.12: Definition of SINGLETON-CLASS and CATEGORY-SPECIALIZATIONCLASS The extensions of the definitions of the instance-type and the instance-instance-type of the metaclass SINGLETON-CLASS are shown in Figure 5.13. The instance-type SingletonClass lnstTypespecifies the property hasCategory,which holds for a specific classification criterion the set of category classes for a general class, e.g., SIMPLE-PART and COMPLEX-PART for the general class PART according to the criterion 'composition of a part'. The method defHasCategoryinitializes that property. The criteria are realized through constants which are used as indices for the array stored in the property hasCategory. The method criterionForClassreturns the criterion identifier for a given category specializatin class, e.g., [ PART criterionForClass(SIMPLE-PART)] will return the identifier of the criterion 'composition of a part'. The instance-instance-type SingletonClasslnstlnstType defines also a property hasCategory, which holds for a specific classification criterion the object identifier of the category instance for a general instance. The methods defined with the type are used to initialize that property, to retrieve the identifier of a category specialized object, and to test the existence of a category instance which is needed in order to satisfy the constraints given in Definition 27. It tests whether there exist some category classes for a given classification criterion or not. The definition of the instance-type and the instance-instance-type of the metaclass CATEGORY-SPECIALIZATION-CLASS is shown in Figure 5.14a-b. The instance-type CategorySpec_lnstTypespecifies the property categoryOf,which holds a specific general class for a category specialization class, e.g., the general class PART for the category specialization classes SIMPLE-PART and COMPLEX-PART. The method defCategory initializes the properties and is only used within the 1NIT-clauses of definitions of category specialization classes. The method createCategory creates for a given general instance a corresponding category instance if there does not already exist one within the given category specialization. The instance-instance-type CategorySpec__InstlnstTypedefines also a property categoryOf, which refers to a general instance for a category instance. The methods defined with that type are used to initialize the property, to implement the inheritance behavior specified in Figure 5.10, and to check the constraints given in Definition 27. In order to provide the capability that a category specialized class can have further category specializations (as indic ated in Figure 5.11), the structure and behavior provided by the meta-
94
/* Only the extensions to the definitions given in Figure 5.5 are shown below Criterionld := Integer; criterionMin = 1; criterionMax = 10;
*/
/* define a data type Criterionld /* define the constant criterionMin /* define the constant criterionMax
Define type SingletonClass_lnstType subtypeOf Metaclass_lnstType properties: hasCategory: array[criterionMin.,.criterionMax] of {Old}; methods: defHasCategory (categoryClass: Oid; criterion: Criterionld); /* defines the category class criterionForClass(catSpecClass: Old) returns Criterionld; /* returns the index of that criterion which has catSpecClass as a category class Implementation SingletonClass_lnstType methods: defHasCategory (categoryClass: Old; criterion: Criterionld); { insert(hasCategory[criterion], categoryClass); } criterionForClass(catSpecClass: Oid) returns Criterionld; {for ( i <-- criterionMin to criterionMax ) if (hasElement(hasCategory[i], catSpecClass)) then return(i); return(0); } Define type SingletonClass_ InstlnstType subtypeOf Metaclass_lnstlnstType properties: hasCategory: array[criterionMin...criterionMax] of Oid; methods: checkHasCategory? (criterion: Criterionld) returns Boolean; /* checks whether there exists a categorization for self with respect to criterion initHasCategory (categoryObj: Oid; criterion: criterionld); /* relates self to categoryObj with respect to criterion has-category-specialization(catSpecClass: Oid) returns Oid; /* returns the category specialized object which is an instance of catSpecC/ass Implementation SingletonClass_lnstlnstType methods: checkHasCategory? (criterion: criterionld) returns Boolean; { return ( hasCategory[criterion] ~ NULL); } initHasCategory (categoryObj: Oid; criterion: Criterionld); { hasCategory[criterion] +-- categoryObj; } has-category-specialization(catSpecClass: Oid) returns Old; {criterion <- [[self class()] criterionForClass(catSpecClass)]; if ( criterion > criterionMin ) then return(hasCategory[criterion]); else return(NULL); }
Figure 5.13: Extensions of the instance-type and the instance-instance-type of the metaclass SINGLETON-CLASS for general category objects
*/ */ */
95 class SINGLETON-CLASS must be made available also for category specialized classes. This is accomplished by defining CategorySpec_InstType as a subtype of SingletonClass InstType, and CategorySpec_InslnsttType as a subtype of SingletonClass_InstlnstType. This allows to build a tree of category specialized classes of any depth.
Define type CategorySpec_lnstType subtypeOf SingletonClass_lnstType properties:
categoryOf: Oid; criterionld: Criterionld; methods:
defCategory(generalClass: Oid; criterion: Criterionld); createCategory (generallnstance: Oid) returns Oid; checklsCategoryOf? (generalClass: Oid) returns Boolean; category-class-ofO returns Oid; Implementation CategorySpec_lnstType methods:
defCategory(generalClass: Oid; criterion: Criterionld); { categoryOf <-- generalClass; criterionld ~-- criterion; [generalClass defHasCategory(self, criterion)]; } createCategory (generallnstance: Oid) returns Oid; { categoryObj: Oid; if (NOT [self checklsCategoryOf?([generallnstance class()])]) then { signal("failed: Such a category cannot be created for this object."); return(NULL);} if ([generallnstance checkHasCategory?(criterionld)]) then { signal("failed: category for this object already exists."); return(NULL); } categoryObj ~- [self new()]; [categoryObj initCategoryOf(generallnstance)]; [generallnstance initHasCategory(categoryObj, criterionld)]; return(categoryObj); } checklsCategoryOf? (generalClass: Oid) returns Boolean; { return (categoryOf = generalClass); } category-class-of 0 returns Oid; { return(categoryOf); }
Figure 5.14a: Definition of the instance-type CategorySpec_InstType of the metaclass for category specialized objects
96
Define type CategorySpec_lnstlnstTypesubtypeOf SingletonClass_lnstlnstType properties: categoryOf: Oid; methods: initCategoryOf (generallnstance: Old); inheritanceBehavior (m: Sel; arglist: Arglist) returns Result; category-specialization-of0 returns Oid; Implementation CategorySpec_lnstlnstType methods: initCategoryOf (generallnstanoe: Oid) { categoryOf ~-- generallnstance; } inheritanceBehavior (m: Sel; arglist: Arglist) returns Result { return([categoryOf eval(m) (arglist)]); } category-specialization-ofO returns Oid; { retum(categoryOf); }
Figure 5.14b: Definition of the instance-instance-type CategorySpec_InstlnstType of the metaclass for category specialized objects Figure 5.15 shows the definition of some application classes. The classes SIMPLE-PART and COMPLEX-PART are defined to be category specialization classes of class PART with respect to the criterion 'composition'. The classes LICENSED-PART and UNLICENSEDPART are defined to be category classes of the class PART with respect to the criterion 'licensed'. Note, that for class PART two different categorizations have been specified at the same time. The instance-types of the application classes are not further specified since they do not contribute to the demonstration of the category specialization relationship. We assume, that the identifiers 'composition' and 'licensed' have been defined as constants such that they can be used as indices for the property hasCategory specified with the type Single-
tonClass_InstType. Figure 5.16 shows an example of how to deal with category specialized objects. Let us assume, that there exists an instance of class PART, e.g., a drilling derrick, referred to by the variable p-PART. Then the message [COMPLEX-PART createCategory(p-PART)] creates an instance of class COMPLEX-PART which is treated as a category specialized object of the drilling derrick. The subsequent message [SIMPLE-PART createCategory(p-PART)] fails, because a category object for part p-PART already exists with respect to the classification criterion 'composition'.
97
Define SINGLETON-CLASS PART instance-type: PART_Type Define CATEGORY-SPECIALIZATION-CLASS SIMPLE-PART instance-type: SIMPLE-PART_Type init: defCategory(PART, composition); Define CATEGORY-SPECIALIZATION-CLASS COMPLEX-PART instance-type: COMPLEX-PART_Type init: defCategory(PART, composition); Define CATEGORY-SPECIALIZATION-CLASS LICENSED-PART instance-type: LICENSED-PART_Type init: defCategory(PART, licensed); Define CATEGORY-SPECIALIZATION-CLASS UNLICENSED-PART instance-type: UNLICENSED-PART_Type init: defCategory(PART, licensed);
Figure 5.15: Definition of some category specialized application classes. (the definitions of the instance-types are not further specified here). But the next message [LICENSED-PART createCategory(p-PART)] successfully returns the identifier of a new instance of class LICENSED-PART, because it is the first category specialized object with respect to the classification criterion 'licensed'. Now the object referred to by p--PART is modelled once as an instance of the class COMPLEX-PART with respect to its composition, and once as an instance of a class LICENSEDPART with respect to its license status. The inheritance behavior via the category specialization relationship, i.e., the inheritance from the object referred to by p-PART to its category specialized objects is equivalent to the one of role specialization (see section 5.3.1).
p-PART ~-- [PART new() ] /* creates a new part o ~ [COMPLEX-PART createCategory(p-PART)] /* creates a category object /* with respect to the criterion composition o ~-- [SIMPLE-PART createCategory(p-PART)] /* fails, category already exists o ~- [LICENSED-PART createCategory(p-PART)] /* creates a category object /* with respect to the criterion 'licensed'
*/ */ */ */ */ */
Figure 5.16: Example of processing category specialized objects 5.4 Aggregations Real world objects may be aggregations from other objects (see section 4.3). While the constituents of an aggregation object can exist as separate stand-alone objects, the aggregation
98 object itself can only exist if all its constituent objects exist. For example, an order can be modelled as an aggregation of a customer, the items, e.g., parts, ordered by that customer, and an agreement the business relationship with that customer is based on. An object can be constituent of several aggregation objects of the same or of a different aggregation class, e.g., a specific customer can be a constituent of several orders, but also a constituent of a consortium. In the following we give a definition of this kind of relationship as introduced in section 4.3 according to the general characteristics of semantic relationships discussed in section 3.10.2 and specify its implementation through a metaclass. Definition 28: ( Aggregation ) Let hasConstituent(~) denote the semantic relationship defined between an aggregation and its constituents, whereas et denotes the name of this relationship. Then for objects a, b ~ Objld, classes A, B ~ Classld, and o~ e PropNames holds: 9
A hasConstituent(OOB ~ ~ 3 C 6 Classld(AhasConstituent(O 0 C A C r
9
(AhasConstituent(00 B A a i n s t a n c e O f A ) ~ 3 b ( b instanceOf B ^ a hasConstituent(~) b ).
A
-~3 ~ ~ PropName ( A hasConstituent(~) B A ~ ~ ~ )
No inheritance behavior is defined via the hasConstituent(oO relationship.
9
We specify a new metaclass AGGREGATION-CLASS (see Figure 5.18) which provides for aggregations of objects. Figure 5.17 shows the relationships and connections between the different classes. AGGREGATION-CLASS is defined as an instance of METACLASS. Any class which collects aggregation objects consisting of other objects must be defined as an instance of AGGREGATION-CLASS. The constituent classes can be defined in any way, i.e., they can be instances of SINGLETON-CLASS or of AGGREGATION-CLASS as in our example: The aggregation class ORDER has the classes CUSTOMER, PART, and AGREEMENT as its constituent classes, CUSTOMER is also a constituent class of CONSORTIUM, and AGGREEMENT is assumed to be an aggregation class itself (not further shown). Each relationship between an aggregation class and its constituent classes is named. With the instance-instance-type Aggregation_InstlnstType (see Figure 5.19) of the new metaclass we specify a property constituents whose type is a set oftuples. Such a tuple is defined as a pair of a selector (a name for the constituent in the context of the aggregation) and an object identifier (for the constituent object): constituents : { [sel : String; obj: Oid] }; Furthermore, we define methods to manipulate this property, i.e., we specify 9 a method get : String ---) Oid which takes a string and returns that object identifier which is stored in the tuple together with the string, and 9 a method set : String • Oid which takes a string s and an object identifier o and updates the property constituents with the element (s, o), (i.e., it updates an element (s, o') in the set iff such an element exists, otherwise it inserts the element into the set) if the object identified by o is allowed to be recorded.
99
Figure 5.17:
Relationships between aggregate and constituent classes and the meta-
classes 9 a method has-constituent : Oid ~ Oid (as required in section 4.3) which returns the constituent object which is an instance of the class passed as parameter. According to these definitions an instance of a class defined as an instance of the new metaclass can record constituent objects through the property constituents. In order to define and control which classes of constituent objects are allowed to be recorded, we define a property that holds that information. That is, we define the property classesOfConstituents with the instance-type Aggregation_lnstType (see Figure 5.20 ) of the metaclass. The type of this property is a set of tuples, where such a tuple is a pair of a selector (the name of a constituent relationship) and the identifier of a constituent class object:
classesOfConstituents : { [sel : String; constClass: Oid] }; In addition, we define methods to access this property:
Define METACLASS AGGREGATION-CLASS instance-type: Aggregation_lnstType /* see Figure 5.20 instance-instance-type: Aggregation_lnstlnstType/* see Figure 5.19 Figure 5.18:
Specification of the metaclass AGGREGATION-CLASS.
*/ */
100
A method defConstituent : String • Oid which takes a string and a class identifier and inserts this pair as an element into the set. This method is used to specify which class of constituent objects are allowed to be recorded. 9 A method testClassOfConstituent : String x Oid ~ Bool which takes a string and an object identifier and returns true iff the object identifier identifies an instance of the class whose identifier is stored in the tuple with the passed string as the value of the sel-property, otherwise false. This method is used to check whether an object is allowed to be recorded as a constituent or not. It is called by the method set specified with the instance-instance-type of the metaclass. 9 A method getSelForConstClass : Oid ~ String which takes the identifier of a constituent class and returns that string which is stored in the set classesOfConstituents together with the identifier of the constituent class passed as parameter. That is, this method retrieves the name of the has-constituent relationship defined between the aggregation class and the class passed as parameter.
9
As required in section 4.3 every object must be able to respond to the message of type [ constituent-of()], which returns those instances of the aggregation class which have as a constituent. This is realized by extending the objct
Define type Aggregation_lnstlnstType subtypeOf SingletonClass_lnstlnstType properties: constituents : { [sel : String; obj: Oid] }; methods: get(s : String) returns Oid; set(s : String, o : Old); has-constituent( classld : Oid ) returns Oid; Implementation Aggregation_lnstlnstType methods: get(s : String) returns Oid { " Implementation of an algorithm which - selects that element e of the set stored in the property constituents, which has the string s as the value of its se/-property, and - returns the value of e's obj-property.'} set(s : String, o : Old); { if ([[self class()] testClassOfConstituent(s, o)])/* constituent allowed */ then "Implementation of an algorithm which updates that element e of the set stored in the property constituents which has the string s as the value of its se/-property with the new identifier o, iff such an element exists; otherwise a new element e = [s, o] is inserted into the set." else "signal an error as such a constituent is not allowed to be stored."}
has-constituent( classld : Oid ) returns Oid; { return([self get( [ [self class()] getSelForConstClass(classld)] ) ]); } Figure 5.19: Specification of the instance-instance-type of the metaclass AGGREGATION-CLASS
101
Define type Aggregation_lnstType subtypeOf SingletonClass_lnstType properties: classesOfConstituents : { [sel: String; constClass: Oid] }; methods: defConstituentClass(s : String, o : Oid); testClassOfConstituent(s : String, o : Old) returns Bool; Implementation Aggregation_lnstType methods: defConstituentClass(s : String, o : Oid) { "Implementation of an algorithm which inserts an element e = [s, o] into the set stored in the property c/assesOfConstituents, iff such an element does not already exist."} testClassOfConstituent(s : String, o : Old) returns Bool { "Implementation of an algorithm which returns true, if the object identified by o is an instance of the class which is stored in the constClass-property of that element e of the set stored in the property c/assesOfConstituents which has the string s as the value of its se/-property, otherwise return fa/se."}
getSelForConstClass(classld : Oid) returns Old; {
"Implementation of an algorithm which selects that pair e from the set stored with the property classesOfConstituents which has c/ass/c/ as the value of its constClass property, and returns the value of the se/property of this pair e." }
Figure 5.20: Specification of the instance-type and instance-instance-type of the metaclass AGGREGATION-CLASS
types used to define the metaclass SINGLETON-CLASS. We extend the instance-instancetype SingletonClass_InstlnstType by adding the method constituent-of, which computes the set of aggregate objects the receiver object is a constituent of (see Figure 5.21). If one wants to handle the information of being a constituent class of an aggregation class at the class level, we could extend the object type SingletonClass_InstType in a similar way as we extended it for the purpose of handling the information about having category specializations (see section 5.3.2, Figure 5.13, method defHasCategory). We would have to introduce a new method defConstituentClassOfand to extend the method defConstituentClass defined with Agregation_InstType such that it sends the new method defConstituentClassOfto the class passed as parameter to the method defConstituentClass (as done similarly in the method defCategory, see Figure 5.14). As the implementation scheme is so similar we do not show it in detail. In order to allow that aggregate objects itself can be constituents of other aggregation objects, we defined Aggregation_InstType as a subtype of SingletonClass_InstType and Aggregation_lnstlnstType as a subtype of SingletonClass_lnstlnstType. Hence, an instance of the aggregation class AGREEMENT (see Figure 5.17) can also respond to, e.g., the message [a 15-AGREEMENT constituent-of (ORDER)].
102
/*Only the extensions to the prev. def. in Figure 5.5 and in Figure 5.13 are given*/
Define type SingletonClass__ InstlnstType subtypeOf Metaclass_lnstlnstType properties: methods: constituent-of(aggregateClass: Oid) returns { Oid }; /* returns the set of instancs of aggregateClassthe receiver is a constituent of Implementation SingletonClass_lnstlnstType methods: constituent-of(aggregateClass: Oid) returns { Oid }; {aggregateObjs :{Oid}; o :Oid; aggregateObjs <-- {}: for ( o in [aggregateClass alllnstancesO] ) if ( [o has-constituent([self class()])] = self ) then insert(aggregateObjs, o); return(aggregateObjs);}
Figure 5.21: Extension of the instance-instance-type of the metaclass SINGLETONCLASS for constituents of aggregations
With these definitions one can now define an application class ORDER, which is an aggregation of CUSTOMER, PART, and AGREEMENT, as an instance of the new metaclass (see Figure 5.22). As a consequence of the execution of the initialization clause of class ORDER, an instance of ORDER can only record constituent objects which are instances of CUSTOMER, PART, or AGREEMENT. The functionality of recording constituents has been specified at the meta level independent of any concrete definitions for orders. We did not show how to implement the creation-method for aggregation objects. But it can easily be seen from the sample statements given in Figure 5.22 how this can be done. The only important point is that all the constituent objects must exist before or have to be created at the same time an aggregation object is created.
5.5 Components Real world objects may be of a complex structure and, hence, may be modelled as composite objects. As outlined in section 4.4 the components of a complex object are treated as a kind of private parts of the composite object. Components of an object can only exist for the life time of the composite object. Components disappear if the composite object is destroyed. According to the semantics described in section 4.4 it is not required that all components of a composite object exist during its lifetime. In the following we give a definition of the componentof relationship according to the general characteristics of semantic relationships discussed in section 3.10.2 and specify its implementation through a metaclass. We will expand the definition of the metaclass in the subsequent section such that it will provide for a combination of two semantic relationships, component-of and role-of
103
Define SINGLETON-CLASS CUSTOMER /* not further specified here Define SINGLETON-CLASS PART /* not further specified here Define AGGREGATION-CLASS ORDER instance-type: Order_Type /* not further specified here init: defConstituentClass("orderingCustomer", CUSTOMER); defConstituentClass("ordered Part", PART); defConstituentClass("basedOnAgreement", AGREEMENT); Define AGGREGATION-CLASS AGREEMENT instance-type: Agreement_Type /* not further specified here init: defConstituentClass( ... ); /* define constituent classes Define AGGREGATION-CLASS CONSORTIUM instance-type: Consortium_Type /* not further specified here init: defConstituentClass("consortiumMember", CUSTOMER);
*/ */ */
*/ */ */
/* sample statements dealing with constituents of orders */ p ~ [PART new()]; /* create a part object */ c ~- [CUSTOMER new()]; /* create a customer object */ a ~ [AGREEMENT new()]; /* create an agreement object */ o ~- [ORDER new()]; /* create an order object */ [o set("orderingCustomer", c)]; /* define c as a constituent object of o */ [o set("orderedPart", p)]; /* define p as a constituent object of o */ [o set("basedOnAgreement", a)]; /* define a as a constituent object of o */ Figure 5.22:
Specification of aggregation classes and their constituent classes
Definition 29: ( Components ) Let componentOfdenote the semantic relationship defined between a component and its
superordinate object, the composite object. Then for objects a, b ~ Objld, classes A, B ~ Classld holds: 7 3 C ~ Classld ( A componentOf C A C ~ B ), and
9
A componentOf B ~
9
( A componentOf B A a instanceOf A) ~ 3 b ( b instanceOf B A a componentOf
b). No inheritance behavior is defined via the componentOf relationship.
In the following we introduce the metaclass COMP-CLASS and extend the metaclass SINGLETON-CLASS in order to provide the component-of relationship. Figure 5.23 shows a fragment of a schema consisting of a class COMPLEX-PART and a class SUBPART which is defined as component class of COMPLEX-PART. Every class which represents components of another class must be defined as instance of the metaclass COMP-CLASS. Classes like COMPLEX-PART which represent superordinate objects can be defined as instances of arbitrary metaclasses whose object types are subtypes of the object types used to define SINGLETON-CLASS (as described later in more detail). As we want to extend our example later on, we defined COMPLEX-PART as a category-specialization of another class not further specified here. In the subsequent section this example will be extended to the examples given
104 in sections 5.3.2 and 4.4. in order to meet the design requirement (ii) described in section 4.4. Figure 5.24 shows the definition of the metaclass COMP-CLASS. The realization of the metaclass COMP-CLASS follows a similar scheme as used in the previous sections. As we define a property componentOfwith the instance-instance-type CompClass_InstlnstType (see Figure 5.25) every component object can store a reference to its superordinate object. The method component-of retrieves the superordinate object (as required in section 4.4), and the method setComponentOfis used to assign a value to the property componentOf At the class level we define for every component class a property isComponentClassOfwhich refers to the superordinate class. In addition to the methods to access this property Figure 5.26 illustrates how to define a creation method for component classes. The method create takes the superordinate object for which a component has to be created as a parameter. It first checks whether the receiver object, i.e., a class, is a valid component class of the superordinate object's class or not. Then it checks the case whether the component-of
Figure 5.23: Relationships between component classes and metaclasses
Define METACLASS COMP-CLASS instance-type: CompClass_lnstType /* see Figure 5.26 instance-instance-type: CompClass_lnstlnstType /* see Figure 5.25
Figure 5.24: Specification of the metaclass COMP-CLASS.
*/ */
105 relationship between instances of the superordinate class and instances of the component class is single valued and there exists already a component object for the given superordinate Define type CompClass_lnstlnstType subtypeOf SingletonClass_lnstlnstType methods: component-of0 returns Oid; setComponentOf(o : Oid); Implementation CompClass_lnstlnstType properties: componentOf : Oid; methods: component-ofO returns Oid; { return(componentOf);} setComponentOf(o : Oid); {componentOf ~- o;}
Figure 5.25: Specification of the instance-instance-type of the metaclass COMPCLASS
Define type CompClass_lnstType subtypeOf SingletonClass_lnstlnstType methods: componentClassOf0 returns Old;//returns the class SELF is a component of defCompClassOf(aClass : Oid); //defines SELF to be a component class create(superOrdOb : Oid) returns Oid; // create a component for a given obj. isValidCompClassOf(cls : Oid) returns Bool;//check on valid comp. class singleValuedCompExistsFor(obj : Oid) returns Bool; // TRUE, if comp. exists Implementation CompClass_lnstType properties: isComponentClassOf : Oid; //stores the superordinate class methods: componentClassOf0 returns Oid; {return(isComponentClassOf);} defCompClassOf(aClass : Oid); {isComponentClassOf ~- aClass;} isValidCompClassOf(cls : Oid) returns Bool; { return(hasElement([cls hasComponentClasses0], self)); } singleValuedCompExistsFor(obj : Oid) returns Bool; { return([isComponentClassOf hasSingleValuedComponent(self)] and cardinality([obj hasComponents(self)]) = 1 ); } create(superOrdObj : Oid) returns Oid; { newObj : Oid; //check if such a component class is defined for the given object if ( [self isValidCompClassOf([superOrdObj class()]) ] ) then //check against multiplicity of relationship if ( [self singleValuedCompExistsFor(superOrdObj) ) then//single-valued relationship & component exists already signal("failed: Such a component exists already"); return(NULL); else { newObj ~- [self new()]; [newObj setComponentOf(superOrdObj)]; return(newObj); } else { signal("failed: Creation of component not allowed"); return(NULL);i
Figure 5.26: Specification of the instance-instance-type of the metaclass C O M P CLASS
106
//Only the extensions to the definitions given in Figure 5.5 and Figure 5.13 //are shown below
Define type SingletonClass_lnstType subtypeOf Metaclass_lnstType methods: defComponentClass (name : String; compClass : Oid; multiValued : Bool); //defines the class to be a component class of SELF hasComponentClasses0 returns {Oid};//returns the set of component classes hasSingleValuedComponent(compClass : Old) returns Bool; //returns TRUE if sel! //has a single-valued component relationship with Implementation SingletonClass_lnstType properties: compDesc: { [n : String; cls : Oid; multi : Bool] };//stores the name, // class, and multiplicity of hasComponent relationships methods: defComponentClass (name : String; compClass : Oid; multiValued : Bool); { insert(compDesc, [name, compClass, multiValued]); [compClass defCompClassOf(self)];} hasComponentClasses0 returns {Oid}; { r : {Oid}; e : [n : String; cls : Oid; multi : Bool] }; r ~- {}: for ( e in compDesc ) insert(r, e.cls); return(r); } hasSingleValuedComponent(compClass : Oid) returns Bool; {/* Algorithm which returns TRUE if there exists an element e in compDesc such that e.cls is equal compClassand e.multiis equal FALSE, otherwise returns FALSE. */}
Figure 5.27: Extensions of the instance-type of the metaclass SINGLETON-CLASS for classes which may have component classes
object. If this is not the case a new component object is created which refers to the given superordinate object. In order to guarantee that every class can have component classes we extend the definitions of the instance-type and instance-instance-type of the metaclass SINGLETON-CLASS. Extending SingletonClass_lnstType and SingletonClass_InstlnstType is more useful as the object types of the other metaclasses are subtypes of these two types and, hence, inherit all the extensions automatically.
SingletonClass_InstType (see Figure 5.27) is extended by defining a property compDesc which describes all the has-component relationships a class may have. As such relationships can be named this property stores tuples consisting of the name of the relationship, the domain class, and a boolean value which is TRUE in case the relationship is set-valued, FALSE otherwise. The method defComponentClass can be used to define these relationships. The
107 method hasComponentClasses computes the set of component classes, and the method hasSingleValuedComponent checks whether a given relationship is single-valued or set-valued.
SingletonClass_InstlnstType (see Figure 5.28) is extended by defining the methods hascomponent (as required in section 4.4) and delete which guarantees that when deleting a superordinate object all its component objects are deleted too. On the basis of these definitions we can now define an application class SUBPART, which represents components of instances of class COMPLEX-PART. SUBPART is defined as instance of the metactass COMP-CLASS. COMPLEX-PART is assumed to be defined as instance of the metaclass CATEGORY-SPECIALIZATION-CLASS (see Figure 5.22). As a consequence of the execution of the initialization clause of class COMPLEX-PART, an instance of COMPLEX-PART can only record components which are instances of SUBPART. The functionality of recording components has been specified at the meta level independent of any concrete definitions for complex parts. Note, that due to the fact that the component-of
//Only the extensions to the prev. definitions in Figure 5.5, Figure 5.13, //and Figure 5.21 are given Define type SingletonClass__lnstlnstType subtypeOf Metaclass_lnstlnstType properties: methods: has-component(compClass: Oid) returns { Old }; //returns the set of component objects the receiver object consists of delete(); // delete operation which considers components of an object Implementation SingletonClass_lnstlnstType methods: has-component(compClass: Oid) returns { Oid }; {compObjs : {Oid}; o : Oid; compObjs ~- {}: for ( o in [compClass alllnstancesO] ) if ( [o component-of()] = self ) then insert(compObjs, o); return(compObjs);} delete(); {//first, delete all components as they can exist only as long as <self> exists compObjs : { Oid }; o : Oid; compObjs ~- {}: for ( o in [[self class()] hasComponentClassesO] ) union(compObjs, [self has-component(o)] ); for ( o in compObjs ) [[o class()] dellnstance(o)]; //delete, comp. VML-Class_lnstType, Figure 3.22 //second, delete myself [[self class()] dellnstance(self)]; }
Figure 5.28: Extension of the instance-instance-type of the metaclass SINGLETONCLASS for objects which may have components
108
MultiValued = TRUE; /* define the constant MultiValued */ Define CATEGORY-SPECIALIZATION-CLASS COMPLEX-PART instance-type: COMPLEX-PART_Type init: defCategory(PART, composition); /* as in Figure 5.15 */ defComponentClass("SubParts", SUBPART, MultiValued);
Define COMP-CLASS SUBPART instance-type: SUBPART_Type /* not further specified here */ /* sample statements dealing with components of objects */ p e- [PART new()]; /* create a part object */ cp ,-- [COMPLEX-PART createCategory(p)]; /* create a composite object */ ol ~ [SUBPART create(cp)]; /* create a component object */ /* ... do some initialization of the first component object */ o2 ~ [SUBPART create(cp)]; /* create a component object */ /* ... do some initialization of the second component object */ mySubParts : { Oid }; mySubParts ,-- [cp has-component(SUBPART)]; /* get all subparts of cp */ [io_out << mySubParts]; /* print the set of subparts for cp, i.e., print {oi, 02}*/
Figure 5.29: Specification of a component class and some sample messages relationship with SUBPART is multi-valued one can create several component objects for a single complex part. Note: The method defComponentClasstakes the name of the has-componentrelationship as its first parameter. But we did not show the definition of an access method which allows to retrieve components by specifying the name of the has-componentrelationship instead of specifying the domain class as required by the method has-component. Such an alternative access method has to be defined with SingletonClass_InstlnstType, and the implementation is very simple: Given the has-componentrelationship name one has to select the corresponding component class using the description stored with the property compDesc of the receiver's class, and then has to apply the method has-component passing the selected component class as parameter.
5.6 Role-Specialized Components In the previous section we introduced the metaclass COMP-CLASS which provides for the component-ofrelationship. The definitions given for COMP-CLASS ignore the fact that the usage of components should follow a specific design principle stated already in section 4.4 and which we repeat here: Ifa component object has a property whose value is independent of the superordinate object, then the component-class should be modelled as a role-specialization-class of some other more general class. The instance of that more general class shall model the properties whose values are independent of the superordinate object, and the component-class shall represent those properties whose values are dependent on the super-
109
ordinate object. In other words, the more general class represents the properties that are "context-free", and the role-specialization-class models the properties that are "context-sensitive", with respect to the superordinate object. Following this design rule means to be able to specify a class as both a role-specialization class and a component class, because component objects participate in a role-of and a component-of relationship. The metaclass COMP-CLASS does not allow to declare the component class SUBPART to be a component class of COMPLEX-PART and to be a role-specialization class of another class. In the following we introduce a new metaclass ROLESPEC-COMP-CLASS which combines both semantic relationships role-of and component-
of. The definition of the combination of the semantic realtionships role-of and component-of according to the general characterization of semantic relationships discussed in section 3.10.2 can simple be derived from Definition 26 and Definition 29.
Definition 30: ( Role-specialized components ) Let roleCompOfdenote the combination of the semantic relationships role-of and component-of, that is z roleCompOf(x,y) ::= z rolespec x A Z componentOfy . Then for objects a, b, c e Objld, classes A, B, C e Classld holds: 9 B roleCompOf (A, C) ~ (A, C)) 9
7 3 X, Y e Classld ( B roleCompOf (X, Y) A (X, Y)
( B roleCompOf (A, C) A b instanceOf B ) 3 a, c ( a instanceOf A A C instanceOf C A b r~176
c) ).
The inheritance semantics for roleCompOfis identical to the one of role specialization (see Figure 5.30). It shows how the result v of a message [b m(args)] is determined i cb(m)
True
False
V
vb
[a m(args)], where a rolespecb
Figure 5.30:
IroleCompOf: Inheritance semantics for role-specialized components.
Figure 5.31 shows the connections and relationships between a role-specialized component class SUBPART, a class COMPLEX-PART representing complex objects, and a class PART representing parts in general. A specific subpart or a composite part is always represented by a role of its generic representation PART. An instance of PART (representing a particular kind of parts) can serve as a component of different composite parts if we create more than one instance of class SUBPART for a specific instance of PART. The new metaclass ROLE-SPEC-COMP-CLASS is defined on the bases of the existing definitions given with the object types of the metaclasses ROLE-SPECIALIZATION-CLASS and COMP-CLASS. The instance-instance-type RoleCompClass InstlnstType of ROLE-SPEC-COMP-CLASS is simply defined as a subtype of the already defined types CompClass_InstlnstType and Ro-
110
Figure 5.31: Relationships between role-specialized component classes and metaclasses
leSpec_InstlnstType (see Figure 5.33). The instance-type RoleCompClass_lnstType is defined as a subtype of the existing types CompClass_InstType and RoleSpec__InstType (see Figure 5.33). It redefines the methods create given with both supertypes such that role-specialized components are created according to the rules of role-specialized objects and component objects. The implementation of create combines the implementation of the old creation methods. In the following we will present a more complex example which makes use of a categoryspecialization, a role-specialization, and a component-of relationship. The example models parts which are categorized into complex and simple parts. Complex parts consist ofsubparts which can either be complex parts or simple parts. Figure 5.34 shows the definitions of the classes PART representing parts, COMPLEX-PART representing complex parts, SIMPLEPART representing simple parts, and SUBPART representing component parts of complex parts. This also corresponds to the scenario shown in Figure 5.31.
Define METACLASS ROLE-SPEC-COMP-CLASS instance-type: RoleCompClass_lnstType /* see Figure 5.33 instance-instance-type: RoleCompClass_lnstlnstTy#e/* see Figure 5.33 Figure 5.32: Specification of the metaclass ROLE-SPEC-COMP-CLASS.
*/
111
Define type RoleCompClass_lnstlnstType subtypeOf CompClass_lnstlnstType, RoleSpec_lnstlnstType; Define type RoleCompClass_lnstType subtypeOf CompClass_lnstType, RoleSpec_lnstType methods: create(genericlnst : Old; compOfObj : Oid) returns Oid; /* create a role-specialized component for given objects /* overwrites existing create methods defined with supertypes Implementation RoleCompClass_lnstType methods: create(genericlnst : Oid; superOrdObj : Oid) returns Oid; { newObj : Oid; /* check if such a component class is defined for the given object /* check if its allowed to create such a role for generic/nst if ( [self isValidCompClassOf([superOrdObj class()])] and [self isValidRoleSpecClassOf([genericlnst class()])] ) then /* check against multiplicity of relationship if ( [self singleValuedCompExistsFor(superOrdObj)] ) then/* single-valued relationship & component exists already signal("failed: Such a component exists already"); return(NULL); else { newObj ~- [self new()]; //create the role spec. component [newObj setComponentOf(superOrdObj)]; [newObj initRoleOf(genericlnst)]; return(newObj); } else {signal("failed: Creation of component not allowed"); signal("failed: Creation of role not allowed."); return(NULL);} }
Figure 5.33: Specification of the object types of the metaclass ROLE-SPEC-COMPCLASS Figure 5.35 shows partial definitions of object types for all these classes. Only those properties and methods are shown which are needed to demonstrate the implementation of the cost method for parts. The cost for an individual part is computed by the method cost defined with the object type PART_Type. It's computation depends on the category of the part, i.e., on whether the part is a complex part or a simple part. This is realized by utilizing the hasCategory method to retrieve the appropriate category-specialized object and then applying the method cost which is defined for complex objects as well as for simple objects. In this example the cost of a simple part is computed from a given base cost. Hence, the method cost defined with the object type SIMPLE-PART_Type just returns the value of the property baseCost,
112
MultiValued = TRUE; /* define the constant MultiValued composition = 1 ; /* define the constant composition Define SINGLETON-CLASS PART instance-type: PART_Type /* not further specified here Define ROLE-SPEC-COMP-CLASS SUBPART instance-type: SUBPART_Type P not further specified here init: defRoleClass(PART); /* define it as a role of PART Define CATEGORY-SPECIALIZATION-CLASS COMPLEX-PART instance-type: COMPLEX-PART_Type /* not further specified here init: defCategory(PART, composition); /* as in Figure 5.15 defComponentClass("SubParts", SUBPART, MultiValued); Define CATEGORY-SPECIALIZATION-CLASS SIMPLE-PART instance-type: SIMPLE-PART_Type /* not further specified here init: defCategory(PART, composition); /* as in Figure 5.15
Figure 5.34:
*/ */ */ */ */ */ */
*/ */
Specification of a role-specialized component class and sample messages
The total cost of a complex part is computed by the method cost implemented with the object type COMPLEX-PART_Type. It computes the total cost of a complex part as the sum of the total cost and the individual assembling cost of each component. The individual assembling cost of a component is stored with the instances of SUBPART as this is a specific property of a part when it is used as a component of another part. Or in other words, the property "assembling cost" of a part is context sensitive as it makes only sense in the context of being a subpart, which is expressed by modelling SUBPART a role of PART. The individual assembling cost is computed by the method assemblingCost specified with the object type SUBPARTType. The total cost of a component is computed by applying the cost method to the component object, i.e., to an instance of class SUBPART. As no such cost method is defined for such component objects (because type SUBPART_Type does not provide an implementation for a method cost), the method inheritanceBehaviour defined for role-specialized objects is called and, hence, the cost method defined for instances of PART is executed. Note, that this scheme inherently takes into account that a subpart can be either a complex part or a simple part. Computing the cost of a subpart is best done by computing its cost as a part. And computing the cost of a part is based on the category of the part as described above. Figure 5.36 shows a few sample statements creating the instances of classes PART, COMPLEX-PART, SIMPLE-PART and SUBPART as shown in Figure 5.37 and the statements which compute the cost for each part.
5.7 Hypertext Nodes and Links In this section we introduce object types and metaclasses which allow to model argumentative networks. Rather than specifying all the operations one can think of in the context of ar-
113 gumentative networks we introduce only a few specific methods which are needed to demonstrate how the model can be extended to support hypertext structures and how the additional modeling primitives node and link and their associated behavior can be used in an application. As outlined in section 4.5 an argumentative network consists of nodes like datum, claim, warrant, backing, and rebuttal, and of links like so, since, on_account_of, and unless. These links can be defined only between specific types of nodes. Every node and link plays a specific role
Define type PART_Type properties: partNo : String; /* ... and other properties for parts methods: cost(): return Real; Implementation PART Type methods: cost() : return Real; { return [[self hasCategory(composition)] cost()]); }
*/
Define type COMPLEX-PART_Type methods: cost(): return Real; Implementation COMPLEX-PART_Type methods: cost() : return Real; { totCost : Real; totCost ~ 0; /* for all kindof component objects, i.e., for all component classes */ for (cls in [[self class()] hasComponentClasses0]) */ /* for all individual components of a component class for (comp in [self has-component(cls)]) totCost +- totCost + [comp cost()] + [comp assemblingCost0]; return (totCost);} Define type SIMPLE-PART_Type methods: cost(): return Real; setBaseCost(v : Real); Implementation SIMPLE-PART_Type properties: baseCost : Real; methods: cost() : return Real; setBaseCost(v : Real);
/* the base cost of a simple part { return (baseCost);} {baseCost ~- v;}
*/
Define type SUBPART Type methods: assemblingCost0: return Real; setAssemblingCost(v : Real); Implementation SUBPART_Type properties: costForAssembling : Real;/* individual assembling cost */ methods: assemblingCost0 : return Real; { return (costForAssembling);} setAssemblingCost(v : Real); { costForAssembling ~- v;} Figure 5.35:
Fragments of object type definitions with simple cost methods
114
Figure 5.37: Example of role-specialized components of parts within an argumentative network. Clusters of these nodes and links, may form other con-
/* sample statements dealing with role-specialized components of objects pl, p2, p3 : PART; cpl, cp2 : COMPLEX-PART; spl : SIMPLE-PART; sub1, sub2 : SUBPART; */ pl ~- [PART new()]; /* create part object Nr. 1 */ p2 ~ [PART new()]; /* create part object Nr. 2 */ p3 ~ [PART new()]; /* create part object Nr. 3 cpl ~ [COMPLEX-PART createCategory(pl)];/* make pl a complex part */ sub1 ~ [SUBPART create(p2, cpl)]; /* make p2 a component of cpl*/ cp2 ~ [COMPLEX-PART createCategory(p2)];/* make p2 a complex part */ sub2 ~- [SUBPART create(p3, cp2)]; /* make p3 a component of cp2*/ */ spl ~ [SIMPLE-PART createCategory(p3)]; /* make p3 a simple part [spl setBaseCost(1000)]; [sub1 setAssemblingCost(700)]; [sub2 setAssemblingCost(100)]; [p3 cost()];
lp2 cost0J; [pl cost()];
Figure 5.36:
/* assign the base cost */ /* assign the assembling cost*/ /* assign the assembling cost*/
/* results in ~ 1000 /" results in ~ 1000 + 100 = 1100 /* results in -, 1100 + 700 = 1800
Sample messages computing the cost of any kind of parts
*/ */ */
115
cepts, e.g., an argument, which in turn can be represented by specific node types, e.g., a node type argument. The operations associated with an argumentative network are based on navigational operations in a network consisting of these kinds of nodes and directed links. Our approach to tailor the data model for argumentative networks is: First, we define object types which capture the general semantics of nodes and links and provide all basic navigational operations. Second, we introduce object types by combining those defined in the first step with object types introduced earlier in this chapter in order to capture semantics which is specific to Toulmin networks. Third, we specify metaclasses for Toulmin nodes and Toulmin links. Fourth, we introduce some object types and classes which provide for the individual properties and methods associated with the concepts like datum, claim, warrant, backing, rebuttal, so, since, on_account_of, and unless. This layered approach allows us to reuse, e.g., the general specifications of nodes and links in other applications which have to deal with general networks. As the first step we introduce the object types NodeClass_InstType and NodeClass_InstlnstType (see Figure 5.38). NodeClasslnstType, which is intended to be used as a supertype of an instance-type of a metaclass for nodes, defines only a simple method create to create objects. NodeClass_InstlnstType, intended to be used as supertype of an instance-instance-type of a metaclass for nodes, provides a general referred-to-by-link semantics for objects representing concrete nodes in a network. It defines a property inLinks, which refers to the set of links which point to a node, and a property outLinks referring to the set of links for which the node is the source. Furthermore, it defines several methods which are used to compute the set of nodes which can be reached in one step from a single node by following all the links of a specific type. Method dirPointedToByNodesViaLink computes the set of predecessors with respect to a specific link type, i.e., it computes the set of nodes from which the receiver object can be reached in one step by following links of a specific type passed as parameter. Method dirPointingToNodesViaLink computes the set of successors with respect to a specific link type, i.e., it computes the set of nodes which can be reached in one step from the receiver object by following all links of a specific type passed as parameter. Methods incomingLinks and outgoingLinks compute the set of links of a specific link type for which the receiver object serves as target node or source node, respectively. In addition, NodeClass_InstlnstType provides methods to add links to and delete links from the sets stored with the properties inLinks and outLinks. Figure 5.39 shows the definitions of the object types LinkClass lnstType and LinkClass_InstlnstType, which implement a generalfrom-node-to-node-or-link semantics. LinkClass_InstType, which will be used as a supertype of an instance-type of a metaclass for links, specifies two methods: defFromTo allows to specify the node classes whose instances are allowed to serve as source and target nodes of a specific link type. Method createLink implements an algorithm which creates a valid link between two nodes and updates also the properties inLinks and outLinks of both nodes. LinkClass_lnstlnstType defines the properties fromObject and toObject for each link. These properties refer to the objects which serve as target or source nodes. The methods from and to are used to access these properties.
116 Define type NodeClass_lnstType subtypeOf SirtgletonClass_lnstType methods: create() returns Oid; /* creates a new node object Implementation NodeClass_lnstType methods: create() returns Oid; { return( [self new()] ); }
*/
Define type NodeClass_lnstlnstType subtypeOf SingletonClass_lnstlnstType methods:
dirPointedToByNodesViaLink(linkCIs: Old) returns {Old}; dirPointingToNodesViaLink(linkCIs: Old) returns {Oid}; incomingLinks(linkCIs: Oid) returns {Oid}; outgoingLinks(linkCIs: Old) returns {Old}; addlnLink(link: Old); addOutLink(link: Oid); deletelnLink(link: Oid); deleteOutLink(link: Oid); Implementation NodeClass_lnstlnstType properties: inLinks: {Oid}; /* refers to incoming links outLinks: {Oid}; /* refers to outgoing links
*/ */
methods:
dirPointedToByNodesViaLink(linkCIs: Oid) returns {Oid}; ( result : {Oid}; result ~- {}; for ( o in inLinks) if ([o class()] = linkCls) then insert(result, [o from()]); return(result);} dirPointingToNodesViaLink(linkCIs: Oid) returns {Oid); { result : {Oid); result ~- {}; for ( o in outLinks) if ([o class()] = linkCIs) then insert(result, [o to()]); return(result);} incomingLinks(linkCIs: Oid) returns {Oid}; { result : {Oid}; result <-- {}; for ( o in inLinks) if ([o class()] = linkCIs) then insert(result, o); return(result);} outgoingLinks(linkCIs: Oid) returns {Oid}; { result : {Old}; result ~- {}; for ( o in outLinks) if ([o class()] = linkCIs) then insert(result, o); return(result);} addlnLink(link: Oid); { insert(inLinks, link);) addOutLink(link: Oid); { insert(outLinks, link);) deletelnLink(link: Oid); { delete(inlinks, links);} deleteOutLink(link: Oid); { delete(outLinks, links);} Figure 5.38:
Object types for metaclasses providing node semantics
With the object types specified so far we can model classes representing nodes and links. Each node is of exactly one node type, and each link is defined between two nodes. When looking at the argumentative network described in section 4.5 one can easily see that these specifications do not capture all the cases which can occur in an argumentative network. For example, since-links are defined between nodes representing warrants and so-links. The ob-
117 ject types above do not support the specification of a link between a node and a link, because the refered-to-by-link semantics implemented with the object type NodeClass InstlnstType is not available with the object types for links. In order to overcome this limitation we introduce a new type ToulminLinkClass_InstlnstType by combining the object types LinkClass InstlnstType and NodeClass_InstlnstType (see Figure 5.40). Another limitation is related to the representation of nodes: NodeClass_InstlnstType does not specify how information associated with a node is stored. Hence, we introduce the object type
Define type LinkClass_lnstType subtypeOf SingletonClass_lnstType methods: defFromTo (from: Old, to: Oid);
/* specify the source class and */ /* target class for a link */ createLink (from: Oid, to: Oid) returns Oid; /* creates a new link */ Implementation LinkClass_lnstType properties: fromClass : Oid; /* identifier of the source class */ toClass : Oid; /* identifier of the target class */
methods: defFromTo (from: Oid, to: Oid) { /* implementation of an algorithm which (1) tests whether the values of the parameters 'from' and 'to' identify valid classes (not shown in detail), and (2), if (1) is guaranteed, assigns the parameters to the properties 'fromClass' and 'toClass' respectively. */} createLink (from: Oid, to: Oid) returns Oid; { /* implementation of an algorithm which (I) tests whether the value of the parameters 'from' ('to') identify an instance of the class which is recorded in property 'fromClass' ('toClass') of the receiver object, and (2), if (1) is guaranteed, creates a new object 'newObj' representing the new link, ant (3) assigns the values of the parameters to the properties 'fromObject' and "toObject' of the new object, respectively, and (4) executes the messages [from addOutLink(newObj)] and [to addlnLink(newObj)], and (5) returns the identifier 'newObj' of the newly created object. */}
Define type LinkClass_lnstlnstType subtypeOf SingletonClass_l nstlnstType properties: fromObject : Oid; /* source object of a link */ toObject : Oid;
methods: from() returns Oid; to() returns Old;
/* target object of a link
*/
/* returns the source object /* returns the target object
*/ */
Implementation LinkClass_instlnstType methods: from() returns Oid; { return(fromObject); } to() returns Oid; { return(toObject); }
Figure 5.39: Object types for metaclasses providing link semantics
118 Define type ToulminNodeClass_lnstType subtypeof NodeClass_lnstType Define type ToulminNodeClass_lnstlnstType subtypeof NodeClass_lnstlnstType, ContentType Define type ToulminLinkClass_lnstType subtypeof LinkClass_lnstType Define type ToulminLinkClass_lnstlnstType subtypeof LinkClass_lnstlnstType, NodeClass_lnstlnstType Define type RoleSpecToulminNodeClass_lnstType subtypeof ToulminNodeClass_lnstType, RoleSpec_lnstType methods: create() : Oid; /* creates a role specialized Toulmin node */
Implementation methods: create() returns Old;
/* creates a role specialized Toulmin node */ {roleObj : Old; genericlnstance : Oid; genericlnstance <-- [[self role-class-of()] new()]; roleObj <-- [self new()]; /* create the new instance */ [roleObj initRoleOf(genericlnstance)]; /* connect both objects */ retum(roleObj);}
Define type RoleSpecToulminNodeClass_lnstlnstType subtypeof ToulminNodeClass_lnstlnstType, RoleSpec_lnstlnstType Define METACLASS TOULMIN-NODE-CLASS instance-type: ToulminNodeClass_lnstType instance-instance-type: ToulminNodeClass InstlnstType Define METACLASS TOULMIN-LINK-CLASS instance-type: ToulminLinkClass_lnstType instance-instance-type: ToulminLinkClass_l nstlnstType Define METACLASS ROLE-SPEC-TOULMIN-NODE-CLASS
instance-type: RoleSpecToulminNodeClass_lnstType instance-instance-type: RoleSpecToulminNodeClass_lnstlnstType Figure 5.40: Metaclasses TOULMIN-NODE-CLASS and TOULMIN-LINK-CLASS, ROLE-SPEC-TOULMIN-NODE-CLASS
ToulminNodeClass_InstlnstType which combines the object types NodeClass_InstlnstType and Content_Type. The definition of the latter one is shown in Figure 5.41. It specifies properties and methods needed to store some text and additional information about the author, the last modification date, etc. Using these new object types we can now define two metaclasses (Figure 5.40): TOULMINNODE-CLASS, which will be the metaclass for classes representing Toulmin nodes, and TOULMIN-LINK-CLASS, which will be the metaclass for classes representing Toulmin links.
119
Define type Content_Type properties: author : String; creationDate : DateTime; lastmodification : DateTime; text: String; methods: assignAuthor(a: String); readAuthor 0; edittext 0; assigntext(t: String); displaytext0;
//the author of the text //creation date & time of the text // modification date & time of the text //represents some text //assign the author //get the author //edit the text //assign text t passed as argument //display text on the output device
/* Implementation not further specified here. */ Figure 5.41: Object type used to specify the contents of a node. Before we define the classes representing the different nodes and links, we have to solve an additional problem which is related to the roles of data and claims within an argumentative network. Usually one can build up an argumentation chain which starts with some facts which support a claim, and, in turn, this claim may serve as a datum supporting other claims. That is, claims can also be used as facts for other claims. The previous definition of nodes does not allow to interprete a claim as a datum. But this limitation can easily be resolved by declaring claim as a kind of role of datum. Hence, we define a new object type RoleSpecToul-
minNodeClass_InstlnstType which has the object types ToulminNodeClass_InstlnstType and RoleSpec_InstlnstType - already introduced in section 5.3.1 - as its supertypes WarRes:= {[warrant: WARRANT; backing : {BACKING}]} RatRes := {[datum: DATUM; warrants : WarRes]} Define type Claim_Type methods: rational() returns RatRes; facts()) returns {DATUM}; Implementation Claim Type methods: rational() returns RatRes; {s : SO; w : WARRANT; rationalRes : RatRes; warRes : WarRes; rationalRes ~ {}; for (s in [self incomingLinks(SO)]) { warRes ~ {}; for ( w in [s dirPointedToByNodesViaLink(SINCE)] ) insert(warRes, [ warrant: w; backing: [w dirPointedToByNodesViaLink(ON_ACCOU ND_OF)]); insert(rationalRes, [datum: [s from()]; warrants: warRes]); } retum(rationalRes); } facts()) returns {DATUM}; {return( [self dirPointedToByNodesViaLink(SO)]); Figure 5.42:
Instance-type of class CLAIM
120 Define type Datum_Type methods: conclusions(level: Integer) returns { CLAIMS }; allConclusions(level: Integer) returns { CLAIMS }; justify(c: CLAIM; w: WARRANT; b: BACKING); Implementation Datum_Type methods:
allConclusions0 returns { CLAIMS }; {result: {CLAIMS}; directClaims : {CLAIMS}; o : CLAIM; directClaims ~- [self dirPointingToNodesViaLink(SO)]; result ~ {}; for ( o in directClaims ) result ~- result union [o allConclusions0]); return( directClaims union result ); } conclusions(level: Integer) returns { CLAIMS }; {result: {CLAIMS}; directClaims : {CLAIMS}; o : CLAIM; directClaims ~- [self dirPointingToNodesViaLink(SO)]; result ~ {}; if (level > 1) then for (o in directClaims) result<--- result union [o conclusions(level-I)]); return( directClaims union result ); } justify(c: CLAIM; w: WARRANT; b: BACKING); {[SINCE createLink(w, [SO createLink(self, c)])]; [ON_ACCOUNT_OF createLink(b, w)]; }
Figure 5.43: Instance-type of class DATUM (Figure 5.40). This has the effect that the inheritance behavior defined for role-specialized objects is made available for objects whose structure and behavior are defined according to RoleSpecToulminNodeClass_InstlnstType. In addition, we define a new type RoleSpecToulminNodeClass_InstType as a subtype of ToulminNodeClass_InstType and RoleSpec_InstType, and redefine the create method given with RoleSpec_InstType such that whenever a role specialized Toulmin node is created, its general representation is created too. For instance, if we declare a claim to be a role of datum, and if we create a claim object by executing the new create method specified with RoleSpecToulminNodeClass_lnstType, a corresponding object representing the claim as a datum is created automatically. The automatic creation of a datum object for every claim object makes it easier to build up argumentative chains. Using the object types RoleSpecToulminNodeClass_InstType and RoleSpecToulminNodeClass_InstlnstType we introduce the additional metaclass ROLE-SPEC-TOULMINNODE-CLASS (Figure 5.40). It will be the metaclass for those Toulmin node classes whose instances can also serve as other kinds of nodes. Now, having resolved all the problems related to the differences between general nodes and links and Toulmin nodes and links, we can define the object types and classes for all concepts needed in our example, i.e., for datum, claim, warrant, backing, rebuttal, so, since, on_account_of, and unless. Figure 5.42 shows the definition of the object Claim_Type which introduces two methods: rational computes for a given claim the set whose elements consist
121
Define TOULMIN-NODE-CLASS DATUM instance-type: Datum_Type Define ROLE-SPEC-TOULMIN-NODE-CLASS CLAIM instance-type: Claim_Type init: defRoleClass(DATUM); Define TOULMIN-NODE-CLASS BACKING instance-type: Backing_Type /* not furher specified Define TOULMIN-NODE-CLASS WARRANT /* not furher specified instance-type: Warrant_Type Define TOULMIN-NODE-CLASS REBUTTAL instance-type: Rebuttal_Type /* not furher specified Define TOULMIN-LINK-CLASS SO instance-type: So_Type /* init: defFromTo(DATUM, CLAIM); Define TOULMIN-LINK-CLASS SINCE instance-type: Since_Type /* init: defFromTo(WARRANT, SO); Define TOULMIN-LINK-CLASS ON_ACCOUNT_OF instance-type: OnAccoundOf_Type /* init: defFromTo(BACKING, WARRANT); Define TOULMIN-LINK-CLASS UNLESS instance-type: Unless_Type /* init: defFromTo(REBUTTAL, CLAIM); Figure 5.44:
*/ */ */
not furher specified
*/
not furher specified
*/
not furher specified
*/
not furher specified
*/
Database schema for a sample Toulmin schema.
of a supporting datum, its related warrants and backings, i.e., it collects the reasons behind a claim. The method facts computes the set of data which support a given claim. Figure 5.43 shows the definition of type Datum_Type. It introduces three methods: conclusions computes the set of claims which are directly or indirectly supported by a given datum. The parameter specifies the level of indirection, e.g., specifying 1, the result will contain only those claims which are directly supported by the datum, specifying 2, the result will also include those claims which are directly supported by the claims contained in the result of the previous case. The method allConclusions computes all claims supported by a datum. The method justify is used to establish all links between a given datum, a claim, a warrant, and a backing. Figure 5.44 shows the definition of the classes needed in our example. Note, that class CLAIM is defined as role-specialized class of class DATUM. The class definitions for links also specify the target classes and source classes for links. Note, that for class SINCE the target class is not a Toulmin node class, but the Toulmin link class SO. The program fragment shown in Figure 5.45 illustrates how the sample argumentative network given in Figure 4.6 can be created using these classes. It first creates instances representing a datum, a claim, a warrant, and a backing. Then, using the method justify, it esta-
122 blishes all links between these nodes. Furthermore, it creates a rebuttal which is linked to the claim. After these steps we have exactly the situation as given in Figure 4.6. Fragments (A), (B), and (C) show how this cluster consisting of a datum, a claim, a warrant, a backing, and a rebuttal can be processed. (A) prints the texts of each datum which supports the claim directly. (B) prints the texts of all claims which are supported directly or indirectly by the datum. And (C) prints the entire argumentative structure which stands behind the claim,
dl: DATUM; c1: CLAIM; wl: WARRANT; bl, b: BACKING; rl, e: REBUTTAL r : RatRes; w : WarRes 1/data types defined in Figure 5.42 dl ~ [DATUM create()]; //create a datum [dl assigntext("The farmer who does without fertilizer and herbicides ...")]; cl ~ [CLAIM create()]; //automatically creates the new claim also as a datum [cl assigntext("lt is not worthwhile to produce natural food ...")]; wl ~ [WARRANT create()]; //create a warrant [wl assigntext("Any additional work without additional return is not profitable.")]; bl <-- [BACKING create()]; //create a backing [bl assigntext("Economical therory")]; [dl justify(c1, wl, bl)]; //establish a so-link between d l and cl, / / a since-link between wl and the so-link, and //an on_account_of-link between b l and w l rl ~ [REBUTTAL create()]; //create a rebuttal [rl assigntext("But in the long run nat. food farmers expect a rise in income...")]; [UNLESS createLink(rl, cl)] //establish an unless-link between r l and c l (A) //print the text of each fact supporting claim cl for (f in [cl facts()]) [f displaytext0]; "The farmer who does without fertilizer and herbicides ..." dl
(B) //print all conclusions for datum for (c in [dl allConclusions0])
(c)
{ [c displaytext0]; };
It is not worthwhile to produce natural food ..." //print the arguments for claim c l [cl displaytextO]; [io_out << '~nis supported by: "];
for (r in [cl rational()] ) { [r.datum displaytextO]; [io_out << '~nsince: "]; for (w in r.warrants) { [w.warrant displaytextO]; [io_out << '~nwhich is based on: "]; for (b in w.backing) { [b displaytextO];} ) }; [io_out << "~nunless: "]; for (e in [cl unless()]) {[e displaytextO];); "It is not worthwhile to produce natural food ... is supported by: The farmer who does without fertilizer and herbicides ... since: Any additional work without additional return is not profitable. which is based on: Economical thero~ unless: But in the long run natural food farmers expect a rise in income..."
Figure 5.45: Sample Toulmin schema and some sample statements
6 Object Class Definition by Generalization 6.1 Introduction The principle of object class definition by object class refinement is one of the prominent features used in object-oriented data models to achieve reusability of code and data. Object classes are defined as specializations of more general ones and inherit those object classes' properties. In a dual model, like VODAK, inheritance applies to types as well as classes. Inheritance from supertypes to subtypes is implicit to the V O D A K model, inheritance between instances of semantically related classes is explicit and must be specified during the data model tailoring process at the meta class level. Whenever prefined object classes have to be combined, the inverse to specialization, generalization is needed. We encounter such a situation in a centralized system when it is developed bottom up using already designed object classes, or in a distributed system when a multidatabase view has to be provided as a homogeneous interface to a set of predefined heterogeneous databases. The principle of generalization has been used in semantic data models to integrate semantically [SL90, BLN86] similiar entity types into a global entity type [BL84, DW84, NEL86]. In this chapter we show how object class definition by generalization can be incorporated into object-oriented systems in general. To provide for a uniform treatment of abstract objects, such as persons, and data values, such as numbers, we consider data values to be objects themselves. They are instances of classes, refered to as data type classes, and can respond to messages. In the subsequent chapter we show how V O D A K metaclasses can be used to provide support for object class definition by generalization.
6.2 Name and Scale Differences The usability of a system depends on the degree to which similar object classes can be treated uniformly. For independent object classes homogeneity can only be assured when the system development is coordinated. But this cannot be assumed for the database integration problem where independently designed subdatabases are presumed to exist. Consider the object classes OIL-PLANT and C O A L - P L A N T which model power plants fired with oil and coal, respectively. (Figure 6.1 and Figure 6.22~ Assume that in future oil and coal plants should be operated jointly. Consequently the differences in attributes and methods will become burdensome. A single set of messages usually called aprotocol [SB86] should be available. Any plant should start and stop operating with 20) It is assumed that for every attribute and for every relationship p:D an access method p():D for retrieving the attribute's value or relationship's value, respectively, exists.
124
class OIL-PLANT attributes: PlantName : STRING Produced : MWh /* energy produced */ OilUsed :BARRELofOIL methods: FireOn0 PowerOff 0 FillOil0 end OIL-PLANT
Figure 6.1: Object class OIL-PLANT class COAL-PLANT attributes: PlantName : STRING Produced : MWh /* energy produced */ Consumed : TONofCOAL method: Start() PowerOff 0 PutCoal 0 end COAL-PLANT
Figure 6.2: Object class COAL-PLANT the commands "PowerOn" and "PowerOff'. The energy produced should be returned by "Produced" in MWh, the energy consumed by a plant should be retrieved with "Consumed" in M Joule. To integrate the classes OIL-PLANT and COAL-PLANT name differences and scale differences have to be overcome. Different method selectors are used for starting oil and coal plants; different "scales" are used for the energy consumed: Barrels of oil and tons of coal have to be converted into M Joule. Possible solutions to the problem are a local change of the object classes, or the definition of additional views for these classes. Local changes, however, are prohibited if local design autonomy has to be respected. Local view object classes will lead to an explosion of the number of object classes to be handled in each of the subsystems.
6.3 A First, Unsatisfactory Approach to Generalization A simple approach to integration is to define a new object class in the global view whose extension is defined as the union of the extensions of the local classes. Then POWER-PLANT defined as "union of OIL-PLANT and C O A L - P L A N T " (Figure 6.3) simply states that the extension of POWER-PLANT is the union of the extensions of O K - P L A N T and C O A L PLANT. Idle plants can now be selected and assigned to the variable idles by "idles ~ [POWERPLANT select(Produced = 0)]". Since the variable "idles" now contains a set of objects, which are either oil or coal plants, and oil and coal plants know how to respond to the message "PlantName", the names of idle plants can be accessed by "for i in idles [i PlantName0]". But
125 it is not possible to start plant operation of the idle plants with a single command: "for i in idles [i FireOnO]" will not work for coal plants, "for i in idles [i Start()]" will not work for oil plants.
class POWER-PLANT union of: OIL-PLANT, COAL-PLANT end POWER-PLANT
Figure 6.3: Power plants as union of oil and coal plants
6.4 A Second, Satisfactory Approach to Generalization The term generalization class will be used for an object class that is defined by a generalization. The generalization class P O W E R - P L A N T is defined as generalization of the classes O I L - P L A N T and C O A L - P L A N T (Figure 6.4). The object class definition of P O W E R PLANT states in the method specification "PowerOn" that oil plants are started by the message "FireOn" and coal plants by the message "Start". Furthermore the attribute specification for "Consumed" states that energy is to be presented uniformly in M Joule. The corresponding energy values are found for oil plants with the messages "OilUsed", and for coal plants with the message "Consumed". The "corresponding" clause will be explained later. A detailed knowledge of this clause is not relevant for the example at this time.
class POWER-PLANT generalization-of: OIL-PLANT, COAL-PLANT attributes: Consumed: MJOULE corresponding: OIL-PLANT->OilUsed COAL-PLANT->Consumed methods: PowerOnO corresponding: OIL-PLANT->FireOn COAL-PLANT->Start end POWER-PLANT
Figure 6.4: Object class definition by generalization Once again "idles ~ [POWER-PLANT select (Produces = 0)]" can be employed with the semantics that the union of idle O I L - P L A N T and C O A L - P L A N T instances are retrieved. One problem, however, remains when starting the idle plants with "for i in idles [i PowerOn()]" and printing their energy consumed with "for i in idles [i Consumed()]". The problem is how one can distinguish between the local behavior of an object - e.g., its behavior as a C O A L - P L A N T - and the global behavior of an object - e.g., its behavior as P O W E R PLANT.
126
6.5 The Concept of Object Coloring In order to be able to distinguish between the local and the global behavior of an object the new concept of object coloring is introduced. Assume there is one color for every object class. One can now tell an object to follow the behavior of a certain object class by painting its internal identifier with that object class's color. To implement this feature a special message type, [ as()], is introduced. Every object has to respond to such a message by painting its object identifier with the color of the identified object class and returning the colored identifier. For example, the coal plant identifier 'cp I=COAL-PLANT' will receive by [ ' c p l - C O A L - P L A N T ' as(POWER-PLANT)] the color of the object class POWER-PLANT and follow in the future the behavior of power plants. The color of an object identifier will be denoted by a superscript to the identifier, e.g., ' c p l - C O A L PLANT P~ Note: the as-message is similar to the "qua" of Simula [BDM73]. Object class coloring does not require any changes to local object classes and local subsystems, except that the as-method has to be introduced. Due to inheritance this can be easily done by defining it with the most general object classes in each subsystem. This will be shown in chapter 7. We will introduce the following message types for colored object identifiers. The first message type is [ )] by returning the uncolored object identifier, if it belongs to the local class . E.g., [ ' c p l - C O A L - P L A N T P~ as(COAL-PLANT)] will return ' c p l - C O A L - P L A N T ' . The message is undefined and returns null, otherwise.
6.6 Solving Name Differences Returning to the example of starting the idle plants and printing the energy they have consumed, assume that all the object identifiers in the variable "idles" are painted with the POWER-PLANT's color. The idle plants are started by "for i in idles [i PowerOn0]". Without loss of generality let the coal-plant 'cp1-COAL-PLANT PowER-PLANT, be one of these plants. When it receives the message [ ' c p l - C O A L - P L A N T P~ PowerOn0] it will re-
127
trieve the color attached to the object identifier in the message and thus follow the behavior of POWER-PLANT. The method description "PowerOn" defined with the class P O W E R PLANT, tells that an object can behave either as an O I L - P L A N T and invoke the method "FireOn" or, as a C O A L - P L A N T and invoke the method "Start". The ground-class of 'cp 1 - C O A L - P L A N T P~ is COAI~PLANT. Therefore, the object will select the second alternative and transform the message ['cp 1 - C O A L - P L A N T P~ PowerOn0] to [['cpl-COAI_~PLANT P~ a s ( C O A I r P L A N T ) ] Start()].
6.7 The Concept of Object Transformation In section 6.5 object coloring has been used to set an object's behavior to that of the object class identified by the color. In order to change between different representations of data values the concept of transforming an instance of one data type class to an instance of another data type class is introduced in this subsection. To implement this feature it is assumed that every instance of a data type class can respond to a message of type [ in()]. Such a message transforms the in an equivalent data-value of the indicated data type class, and returns this data-value. In bottom up design changes to local object classes have to be avoided. Therefore the appropriate transformation methods can only be specified with the global object classes, and an asymmetric approach results for the treatment of a message of type [ in()] (1)
If the is an instance of a local data type class the/n-message is transformed to [ TransformFrom ()]
(2)
If the is an instance of a global data type class the/n-message is transformed to [ TransformTo()].
To facilitate this concept of object transformation only the/n-method has to be introduced with the most general class(es) of each subsystem. No other changes to the subsystems are necessary as the actual transformation methods are specified with the global object classes.
6.8 Solving Scale Differences Returning to our example, the concept of object transformation is used to overcome scale
differences when printing the energy consumed by each previously idle plant. Consider Figure 6.5. The data-type-generalization class MJOULE has been defined to integrate the local data type classes BARRELofOIL and TONofCOAL. In order to calculate the energy equivalent of any number BARRELofOIL and of any number TONofCOAL in MJoule the transformation methods "From-BARRELofOIL" and "From-TONofCOAL" have been associated with the data type class M JOULE, as well as, their inverses "To-BARRELofOIL" and "To-TONofCOAL".
128 It is assumed that every data-type-generalization class can respond to the message type [ TransformFrom()].The TranformFrom-methoduses the from-transformation method given with the class that is appropriate for the . Furthermore it is assumed that every data value of a data-type-generalization class can respond to the message type [ TransformTo()]. The TransformTo-method uses the to-transformation method given with the class of the that is appropriate for the data type generalization class .
class MJOULE
data-type-generalization of: BARRELofOIL, TONofCOAL from-transformation-methods: BARRELofOIL: From-BAR RELofOIL-to-MJOULF TONofCOAL: From-TONofCOAL-to_MJOULE to-transformation-methods: BARRELofOIL: From-MJOULE-To-BARR ELofOI L TONofCOAL: From-MJOU LE-To-TONofCOAL end MJOULE
Figure 6.5: Integration of data type classes The transformation of data values will be explained with the example ['5_TONofCOAL' in(MJOULE)]. The/n-message will be transformed to: [MJOULE TransformFrom('5_TONofCOAL')]. The method "TransformFrom" will search at the class M JOULE for the transformation method appropriate for the data value to be transformed. In this case the object '5 TONofCOAL' belongs to the class TONofCOAL and the transformation method "From-TONofCOALto_MJOULE" is selected. The result will be an instance of M JOULE representing the energy equivalent of 5 tons of coal. Using the above mechanism the energy consumed by each previously idle plant can be accessed by "for i in idles { energyOfi <---[i Consumed()]; ... }" uniformly in MJoule. For the example concering the coal plant 'cpl-COAL-PLANT' colored as POWER-PLANT the message ['cpl-COAL-PLANTP~ Consumed()] will be transformed into [[['cpl-COAI~PLANTPOwER-PLANT' as(COAL-PLANT)] Consumed()] in(MJOULE)] and return the energy consumed in M Joule.
6.9 Object Coloring vs. Object Transformation So far object coloring has been introduced for instances of abstract classes. Instances of a local class can be colored with the name of a generalization class to change their behavior to that of the generalization class. Object transformation has been introduced for instances of
129
data type classes. Data values (instances) of a local class can be transformed into equivalent data values (instances) of a data type generalization class. We will now extend the concept of object transformation to generalization classes of abstract classes. For this purpose generalization classes are given instances. In order to relate an instance of a generalization class to an instance of a local class that represents the same real world object every instance of a generalization class has a special relationship named gen-of. Its value is the corresponding instance of the local class. The message type [ gen-ofO] will be used to retrieve the value of the gen-ofrelationship. Analogously to data type classes the/n-message is used to transform an instance of a local class into an instance of a generalization class which represents the same real world object, and vice versa. Again, a message of type [ in()] is transformed (i)
into [ TransformFrom()], if is the instance of a local object class, and
(ii) into [ TransfromTo()], if is an instance of a global object class (generalization class) It is assumed that every generalization class can respond to a message of type [ TransformFrom()] as follows: (i)
If the generalization class has already an instance that has as value of the gen-ofrelationship, then this instance is returned.
(ii)
Otherwise a new instance of the generalization class is created that has as value of its gen-of relationship.
It is assumed that every instance of a generalization class can respond to a message of type [ TransformTo()] (i)
by returning the value of the gen-ofrelationship, if this value is an instance of the local class of the class of the
(ii) by returning null, otherwise. Note: here the implicit assumption has been made that an instance of a generalization class is the generalization of exactly one instance of one local class. Generalization classes that share this property are called category-generalization classes. (The different types of generalization classes will be discussed later in detail). In the case of category-generalization classes, object-coloring and object transformation are equivalent concepts. A quasi-instance q and an instance p of a generalization class representing the same real world object, i.e. [q decolorO] = [p gen-ofO], show exactly the same behavior, except for the messages instance-of quasi-instance-of as, ground-class, in and gen-of.
130
The messages quasi-instance-of, as, and ground-class are not defined for instances of a generalization class; the messages instance-of, in, and gen-ofare not defined for quasi-instances of a generalization class. In order to hide whether some real world object is represented as quasi-instance or as instance of a category-generalization class, we extend the definition of the messages quasi-instance-of, as, and ground-class to instances of category-generalization classes. The semantics of such a message is given by the semantics of the same message sent to the equivalent quasi-instance. Furthermore, we extend the definition of the messages instance-of, in and gen-ofto quasi-instances of generalization classes. The semantics of such a message sent to a quasi-instance is defined by the semantics of the same message sent to the equivalent instance of the generalization class.
6.10 Upward Property Inheritance Assume one wants to stop the previously started plants by "for i in idles [i PowerOff0]". Consider the coal plant 'cp 1-COAL-PLANT P~ No method for the message "PowerOff' will be found with the object class POWER-PLANT. The usual property inheritance (from more general classes to more special classes) will not solve the problem. Instead the concept of upward property inheritance is introduced. Upward inheritance means that methods and attributes not found at the generalization class have to be searched for in the appropriate local classes, in our example local class COAL-PLANT. To finalize the discussions it has to be explained how the objects representing idle power plants will actually be assigned to the variable "idles". The statement "idles ~ [POWERPLANT select(Produced = 0)]" has been used. The object class POWER-PLANT has no method "Produced" specified and upward property inheritance comes into effect. According to the generalization structure of POWER-PLANT the above message will be transformed to [[OIL-PLANT select(Produced = 0)] as(POWER-PLANT)] union [[COAL-PLANT select(Produced = 0)] as(POWER-PLANT)]]. This means that idle coal and oil plants are retrieved and colored as power plants before the union is formed. Thus far it is possible to send messages to (quasi-)instances of generalization classes. These messages will be automatically transformed according to the generalization class's method specifications into messages for instances of the local classes. The process to have the properties of the generalization class generated from the properties of the local classes will be referred to as upward property propagation. In addition, if no appropriate method is found within the generalization class upward property inheritance comes into effect. These features support the integration of separately created subsystems in a way which maximizes the reusability of methods and attributes already defined in the subsystems. However, a closer analysis shows that the treatment of generalization as explained so far will only work when its local classes represent distinct sets of real world entities. An extension of this generalization concept will be discussed in the next section.
131
An alternative to upward inheritance would be to require that all methods are to be predefined in the generalization class. These methods then would activate the appropriate methods from the lower level classes and combine the returned results properly. Our approach is motivated by the desire to achieve a very high degree of reusability with a minimum effort invested in the definition of generalization classes.
6.11 Different Types of Generalization Classes In this section different types of generalization classes will be identified that require a different treatment with respect to upward property propagation and upward inheritance. Their respective behaviors reflect the different semantic relationships that can hold between the involved local classes. When such a generalization class is defined using upward property propagation and upward property inheritance it is often sufficient to identify the semantic relationship type that holds between the local classes, and the semantic relationship types that hold between their properties. The correct message transformations and property propagations to be used for the instances of the generalization class then can be automatically inferred.
6.11.1 Semantic Relationships Between Object Classes Two objects which model the same real world object are called equivalent. But this definition is not sufficient as it must also be stated how such equivalent objects are represented in different object classes. Furthermore, objects that model different real world objects may still be semantically related to each other if the real world objects have some common properties. Both situations are investigated in the following.
The Identity-relationship The real-world extension of an object class is the set of all real world objects modeled as instances of that object class. The identity-relationship holds between two object classes iff their real-world extensions are identical at all point in time. This identity-relationship which is based on the current extensions of object classes has been used to merge identical object classes in many schema integration methodologies (e.g., [NEL86]). The identity-relationship as defined above is well suited to capture the informal notion of "sameness" of two object classes under the closed world assumption [MAI83]. However, for distributed systems the open world assumption is more realistic. Real world objects which would belong to a certain object class, may not yet be modeled as instances of that class but may already be modeled as instances of the "same" object class in another database or subsystem. To capture the notion of sameness of two object classes in open worlds one must refer to the intension and not to the extension of object classes. The intension of an object class is the set of all real world objects that exist at a point of time and could belong to that object class, had they actually been modeled as instances of that class. In open worlds the identity-relationship holds between two object classes iff their real
132
world intensions are identical. In order to distinguish between the extension based object class identity for closed worlds, and the intension based object class identity for open worlds, the identity-relationship is marked with"E" and 'T', respectively.
The Role-relationship Two objects may model the same real world object in a different situation or context. Such objects will be classed role-related. For example, the objects 'University Employee Miller' and 'Company Employee Miller' model the person Mr. Miller in different roles. The role-relationship holds between two object classes iff every instance of one class that is equivalent to an instance of the other class is role-related to this instance. Note: that the real world extensions of two role-related classes need not be identical. In Figure 6.6 the object classes UNIV-EMPLOYEES, COMP-EMPL are role-related. In both classes the person Mr. Miller is represented, in one class he is considered in the role of university employee and in the other in the role of a company employee.
class UNIV-EMPL /* university employees */ attributes: SS# : INTEGER /* Social Security Number*/ Salary : DM BirthDate : DATE Courses : TEXT /* Courses taught */ end UNIV-EMPL class COMP-EMPL /* company employees*/ attributes: ID# : INTEGER /* Social Security Number*/ Salary : US$ DateOfBirth : DATE Courses : TEXT /* Courses taken */ end C O M P - E M P L
Figure 6.6: Role-related object classes The History-relationship Two objects may represent the same real world object at different real world times. Such objects will be called history-related. The history-relationship holds between two object classes iff every instance of one class that is equivalent to an instance of the other class is history-related to this instance. E.g., the classes APPLICANT and EMPLOYEE are history-related.
The Counterpart-relationship Two non-equivalent objects, i.e., objects not representing the same real world object, can be regarded as counterpart-related iff they share some common properties but represent alternate situations in the real world. The counterpart-relationship holds between two object
133 classes iff every instance of a class that shares the common properties with some instance of the other class is counterpart related to this instance. In Figure 6.7 the object classes AIR-CONNECTION and TRAIN-CONNECTION are counterpart related. Both object classes model traffic connections between two cities (common properties), but differ with respect to the means of transport. Two instances are counterparts to each other if they model the same traffic connection.
class AIR-CONNECTION attributes: From: CITY To: CITY Fare: US$ methods: Schedule()/* prints air schedule for this connection */ end AIR-CONNECTION class TRAIN-CONNECTION attributes: From: CITY To: CITY Fare: DM methods: Schedule()/* prints train schedule for this connection */ end TRAIN-CONNECTION
Figure 6. 7: Counterpart-related object-classes The Category-relationship Two non-equivalentobjects can be regarded as category-related iff they share some common properties. The category-relationship holds between two object classes iff every instance of one class is category-related to every instance of the other class. The object classes C O A L PLANT and OIL-PLANT of the example in Figure 6.4 are category-related in that coal and oil plants share the common property being a power plant. The category-relationship is the most general way a relationship between two object classes can be defined. Note: it is a matter of personal view - which will depend on the particular application environment - whether one regards object classes category-related or counterpart-related. The difference is that in the case of counterpart-related classes different real world objects are regarded as single objects at a higher level of abstraction. The instances of category-related object classes are assumed to be not related to each other. The view that is chosen becomes manifest in the type of generalization class used to integrate given classes. This issue will be discussed in Section 6.11.3.
6.11.2 Semantic Relationships Between Properties of Objects Attributes (relationships, methods) which model the same type of property of real world objects will be called corresponding. Examples of corresponding attributes are "SS#" of
134
UNIV-EMPL and "ID#" of COMP-EMPL, since both model a person's social security number; "Fare" of TRAIN-CONNECTION and "Fare" of FLIGHT-CONNECTION, since both model the fare of a trip. "FireOn" of OIL-PLANT and "Start" of COAL-PLANT are corresponding methods, since both model the starting of the plant. In this section different types of semantic relationships that can hold between two corre, sponding attributes are identified. They are considered in the scope of the semantic relationships that hold between the objects they describe. After the discussion of the different situations a table of possible semantic relationships between the attributes of related objects will be presented. It has been argued previously that it is not sufficient to just identify two objects as being equivalent. The two objects may have been modeled in different roles and at different point in time. In the following discussion of semantic relationships between related objects it is assumed that a every object models one real world object in a single role and at one point of time. This means that it is not allowed that one attribute models a property of the real world object in one role and another attribute models a property of the real world object in another role. Nor it is allowed that different attributes model the real world object at different points in time. In the following discussion let 01 and 02 be equivalent objects, and let al be an attribute/relationship/method of ol and a2 an attribute/relationship/method of 02.
Relationships between the Properties of Identical Objects Let Ol and 02 be identical. Then between the attributes/relationships/methods al and a2 of the identical objects Ol and 02 the identity-relationship holds iff they model the same property of the real world object which Ol and 02 represent. Under the closed world assumption the values of two identical attributes must be identical. Under the open world assumption the values of single-valued attributes must be either identical or one (or both) of the attributes is (are) null-valued. Set-valued attributes may have different sets of values.
Relationships between the Properties of Role-related Objects Let Ol and o2 be role-related. Then the attributes/relationships/methods al and a2 are identical iffthey model the same property of the corresponding real world object which ol and 02 represent, and the value of the property does not depend on the role in which Ol and o2 model the corresponding real world object. As an example take the attributes "SS#" of UNIV-EMPL and "ID#" of COMP-EMPL (Figure 6.6) which both model the property "Social Security Number". The property "Social Security Number" does not depend on the fact whether a specific employee is seen as a "university employee" or as a "company employee". The attributes/relationships/methods al and a2 are role-related iff each of them models only a portion of a property of the real world object in dependence on the specific role of Ol and o2 respectively. As an example take the attributes "Salary" of UNIV-EMPL and "Salary" of COMP-EMPL. For the specific person Mr. Miller both attributes model a portion of his "Salary".
135
The attributes/relationships/methods al and a2 are counterpart-related iff they model the same type of property and the specific properties which al and a2 represent may not be regarded independent of the specific environments of Ol and o2. For example consider the object classes PRODUCT1 and PRODUCT2. Both have the attributes ProductId, Color, Weight, NoSold, NoOrdered, and RetailPrice. Their instances represent the products of one company as the are sold by two different retailers. An instance of PRODUCT1 and an instance of PRODUCT2 with the same ProductId are equivalent objects. An instance of PRODUCT 1 (PRODUCT2) represents a product in the role of being sold by retailer 1 (retailer2). The attributes "Color" of PRODUCT1 and "Color" of PRODUCT2 are identical-related. The attributes "NoSold" of PRODUCT1 and "NoSold" of PRODUCT2 are role-related, since both attributes model a portion of the property "NoSold" of a product. The same holds for the attributes "NoOrdered". However, the prices at which the same product is offered by the two retailers are counterpart-related. Both model the same type of property - the price of a product - but the price is solely valid with respect to the specific retailer.
Relationships between the Properties of History-related Objects Let ol and 0 2 be history-related. The attributes/relationships/methods al and a2 are identical iffthey model the same real world property and the value of the property does not depend on the point in time at which Ol and o2 model the real world object. The attributes/relationships/methods al and a2 are history-related iff they model the same real world property and the value of the property depends on the point in time at which ol and o2 model the real world object.
Relationships between the Properties of Counterpart-related Objects Between the attributes/relationships/methods of counterpart-related objects the identity-relationship, or the counterpart-relationship may hold. For example, the identity-relationship holds between the attributes "From" or "To" of AIR-CONNECTION and "From" or "To" of TRAIN-CONNECTION respectively; the counterpart-relationship holds between the attributes "Fare" of AIR-CONNECTION and "Fare" of TRAIN-CONNECTION.
Relationships between the Properties of Category-related Objects The corresponding attributes/relationships/methods of category-related objects model properties which can be perceived to belong to a common category when differences are neglected and commonalities are emphasized. Therefore, they are category-related, e.g., the methods "Fireon" of O I I ~ P L A N T and "Start" of C O A L - P L A N T are category-related. In Table 6.1 the possible semantic relationships between two attributes/relationships/methods of two objects are depicted. The semantic relationship between the two objects is identified by the column header. The semantic relationship between two attributes/relationships/ methods is identified by the line header. A "+" ("-") entry indicates that two properties, which are related by the semantic relationship identified by the line header, can (cannot) occur with two objects, which are related by the semantic relationship identified by the column header.
136
identical
role-related
history-r,
counterpart-
category-r.
r.
identical
+
+
+
+
-
role-related
(+)
+
-
-
-
history-r.
(+)
(+)
+
-
-
counterpart-r.
(+)
+
-
+
-
category-r.
-
-
-
-
+
Table 6.1: Possible semantic relationships between two attributes/methods of two objects
In our discussions the assumption was made that an object models a real world object in a single role at exactly one point of time. If this assumption is dropped, or if role-related objects are allowed to model properties of the real world object at different points in time, additional semantic relationships between the properties of two "identical" or two "role-related" objects may occur. These cases have been indicated in the table by putting the "+"-entry in parenthesis.
6.11.3 The Representation of Semantic Relationships between Object Classes The semantic relationship type that holds between two local classes of a generalization class identifies the type of the generalization class. The type of generalization is indicated in the generalization-of clause in the definition of a generalization class. The possiblities are: iden-
ticalE-generalization-of, identicalI-generalization-of, role-generalization-of, history-generalization-of and category-generalization-of. For example the object class P O W E R PLANT should then be defined as category-generalization-of the classes C O A L - P L A N T and O I L - P L A N T instead of "generalization-of' only (see: Figure 6.11, Figure 6.12, and Figure 6.10). In order to facilitate queries which refer to the membership of an object in a particular local class a category-attribute named Type is defined implicitly for every category-generalization class; it is not shown with the class definition. The value of this attribute is derived. Its value is the name of the local class to which a real world object belongs which is represented by an instance (quasi-instance) of the category-generalization class. For example the category-attribute Type for the class P O W E R - P L A N T (see: Figure 6.10) has either either " C O A L PLANT" or "OIL.--PLANT" as value. The coal plant named "Steamy" can now be retrieved by the following query: [POWER-PLANT detect(PlantName = "Steamy" and Type = "COAL-PLANT")]. Note: that the query [POWER-PLANT detect(PlantName = "Steamy")] might not be sufficient. We have assumed that the classes C O A L - P L A N T and O I L - P L A N T were designed independently of each other. Therefore there might also exist an oil-plant named "Steamy". An alternative way to pose the same query - which has to be used if no category-attribute were d e f i n e d - is [[COAL-PLANT detect(PlantName = "Steamy")] as(POWER-PLANT)].
137
The concepts of object coloring and object transformation have already been discussed for category-generalization classes above. The main characteristic of an instance of a category generalization class is that it is the generalization of exactly one instance of one local class. However, this is different for the other types of generalization classes. There an instance of the generalization class may be the generalization of several instances of the local classes. How object coloring and object transformation is handled in such cases will be discussed in the remainder of this Section. In order to relate instances of the local classes which are generalized into the same instance of the generalization class, object correspondence rules are associated with generalization classes. An object correspondences rule is a predicate over the properties of two instances. If the predicate is true for two instances, they are generalized to the same instance of the generalization class. For example, the object correspondence rule "AIR-CONNECTION.From = T R A I N - C O N NECTION.From and AIR-CONNECTION.To = TRAIN-CONNECTION.To", associated with the counterpart generalization class TRAFFIC-CONNECTION (Figure 6.8), states when two instances are to be considered as counterpart traffic connections. Another example is the object correspondence rule, "UNIV-EMPI.SS# = COMP-EMPL.ID#", of the role-generalization class TAXPAYING-EMPL (Figure 6.9).
class TRAFFIC-CONNECTION counterpart-generalization-of: AIR-CONNECTION, TRAIN-CONNECTION object correspondence rules: AIR-CONNECTION.From = TRAIN-CONNECTION.From & AIR-CONNECTION.To = TRAIN-CONNECTION.To attributes: Fare: oeS end TRAFFIC-CONNECTION
Figure 6.8: Generalization of counterpart-related object classes class TAXPAYING-EMPL role-generalization-of: UNIV-EMPL, COMP-EMPL object correspondence rules: UNIV-EMPL.SS#=COMP-EMPL.ID# attributes: BornOn identical: UNIV-EMPL->BirthDate COMP-EM PL->DateOfBirth Courses homonyms: UNIV-EMPL.CoursesTaught COM P-EM PL.CoursesTaken Salary: oeS end TAXPAYING-EMPL
Figure 6. 9: Generalization of role-related object classes We first explain'the extended concept of object transformation. Because an instance of a generalization class can be the generalization of several instances of the local classes, the gen-of
138
relationship is set-valued for instances of generalization classes, other than category-generalization classes. The/n-message is defined the same way for the other types of generalization classes. A message of type [ in()] is transformed into [ TransformFrom()],if the belongs to a local class, and it is transformed into [ TransformTo()],if the is an instance of a generalization class. It is assumed that every generalization class can respond to a message of type [ TransformFrom()] as follows: (i)
If the generalization-class has already an instance which contains the in the set of values of the gen-ofrelationship, then this instance is returned
(ii)
If the generalization-class has already an instance which contains one value of the gen-ofrelationship that corresponds to the , according to the object-correspondence rules given with the generalization-class, then this instance is returned; the is added to the set of values of the gen-ofrelationship.
(iii) Otherwise a new instance of the generalization class is created and returned. Its gen-of relationship has the as value. It is assumed that every instance of a generalization class can respond to a message of type [ TransformTo()].Such a message is handled by the : (i)
by returning that instance of which corresponds to one value of the 's gen-ofrelationship, according to the object-correspondence rules given with the class of the ,
(ii) by returning
null, if no such object exists.
The behavior of instances of generalization classes will be explained in Section 6.11.5. Let us now consider object coloring. The semantics of the as-message is the same for the other types of generalization classes as for the category-generalization class. For example the message ['Meier-UNIV-EMPL' as(TAXPAYING-EMPL)] will retrieve the colored object identifier 'Meier-UNIV-EMPLTAXPAYING-EMPb, and the message ['Meier-UNIVE M P L TAxPAYING-EMPL' as(UNIV-EMPL)] will retrieve the uncolored object identifier 'Meier-UNIV-EMPL'. However, the message ['Meier-UNIV-EMPLTAxPAYING-EMPL' as(COMPANY-EMPL)] will be undefined and return null; the uncolored object identifier is not an instance of the class COMPANY-EMPL given as parameter to the as-message. Note: that the real world object Mr. Meier may be represented by an instance 'Meier-UNIVEMPL' of UNIV-EMPL, by an instance 'Meier-COMP-EMPL' of COMP-EMPL, by an instance 'Meier-TAXPAYING-EMPL' of TAXPAYING-EMPL, and by the quasi-instances 'Meier-UNIV-EMPL TAxPAYING-EMPL' and 'Meier-COMP-EMPL TAxPAYING-EMPL' of TAXPAYING-EMPL.
139
In Section 6.11.5 it will be explained in detail how the behavior of quasi-instances and of instances of a generalization class is defined. However, the general idea will be explained now by the message "Salary" sent to the different objects representing Mr. Meier (compare: Figure 6.6 and Figure 6.9) (i)
['Meier-UNIV-EMPL' Salary()] will return Mr. Meier's salary as a university employee in DM, according to the attribute specification "Salary: DM" of the class U N I V EMPL.
(ii)
['Meier-COMP-EMPL' Salary()] will return Mr. Meier's salary as a company employee in US$, according to the attribute specification "Salary: US$" of the class COMP-EMPL.
(iii) ['Meier-UNIV-EMPL TAXPAYJNG-EMPL'Salary()] will return Mr. Meier's salary as a university employee in oeS. The addressee of the message represents the universityemployee Meier in the behavior of the class TAXPAYING-EMPL where oeS has been specified as range class of the attribute Salary. (iv) ['Meier-COMP-EMPL TAXPAYrNG-EMPL'Salary()] will return Mr. Meier's Salary as a company employee in oeS, because the addresse of the message represents the company employee Meier in the behavior of the class TAXPAYING-EMPL. (v)
['Meier-TAXPAYING-EMPL' Salary()] will return Mr. Meier's salary as a university employee and as a company in oeS. The object 'Meier-TAXPAYING-EMPL' is a generalization of the objects 'Meier-UNIV-EMPL' and 'Meier-COMP-EMPL'. The attributes "Salary" of UNIV-EMPL and "Salary" of COMP-EMPL are role-related. Therefore the sum of both salaries will be returned in oeS.
As an alternative to object coloring one could specify two additional generalization classes, UNIV-EMPL' and COMP-EMPL', with each having a single local class, UNIV-EMPL and COMP-EMPL respectively. But these additional "view" classes should be avoided, as far as possible, to limit the global view definition effort and to keep the number of global classes small. The additional message types, [ qua()] and [ qua()], are introduced to facilitate changes between different object-identifiers. The result of a message of type [ qua()] is given by: (i)
[[ in()] as([ instance-of()])], if the is an instance of a generalization class with the local class ; e.g., ['Meier-TAXPAYING-EMPL' qua(UNIV-EMPL)] will return 'Meier-UNIVEMPLTAXPAYING-EMPL,.
(ii)
null otherwise
The result of a message of type [)] is given by:
140
(iii) [[<•bject-id> as([ <•bject-id> <••••r> gr•und-class•]) ] in( )]• if <•b ject-id> ; e.g., ['Meier-UNIV-EMPLrAxPAvIN~-EMPL'qua(TAXPAYING-EMPL)] will return the object 'Meier-TAXPAYING-EMPL'. (iv) null, otherwise. Table 6.2 summarizes the methods to change between instances and quasi-instances of a generalization-class C and the corresponding instances in its local classes A and B. It is assumed that all generalization classes can respond to the message of type [ select()] ( [ detect()] ) by retrieving the instances (that instance) of the local classes that satisfy (satisfies) the given condition, and by transforming these instances (that instance) into (an) instance(s) of the generalization class . from \ to
o-A
o-A
-
o-B o-C
in A
o-Ac
as A
o-B C
o-B
o-C
o-A C
in C
as C
-
in C
in B
-
qua A
qua C
-
as B
qua C
o-B c as C qua B -
Table 6.2: Methods to change between object identifiers
6.11.4 The Representation of Semantic Relationships between Properties of Objects Corresponding attributes/relationships/methods of the local classes are related to each other in an attribute specification oftbe generalization class. Identically named attributes/relationships/methods of related object classes are by default assumed to correspond. That correspondence needs not be stated in an attribute specification. For example the methods "Schedule" of AIR-CONNECTION and "Schedule" of TRAFFIC-CONNECTION agree on names and are by default assumed to correspond. (Figure 6.7 and Figure 6.8). Two corresponding attributes/relationships/methods have been given synonym names, if their names are different. Corresponding attributes/relationships/methods of related object classes with synonym names are related in an attribute/relationship/method specification of the generalization class. This has been done for example for the method "PowerOn" of POWER-PLANT (Figure 6.4). Two properties which do not correspond have been given homonym names, if their names are equal. Homonymy named attributes/relationships/methods of related object classes must be differentiated in an attribute/relationship/method description of the generalization class. In
141
Figure 6.4 the homonym specification "Courses" states the name "Courses" is used for the courses taken in the company employee role and for the courses taught in the university employee role. The effect of this "homonym" clause is explained in Subsection 6.11.5. In Subsection 6.11.2 different semantic relationships between corresponding properties have been identified. The semantic relationship that holds between corresponding properties is specified in the property specification with the generalization class. Properties used in equality expressions of object correspondence rules are by default assumed to be identical, and the semantic relationship must therefore not be explicitly specified. By default properties of the same name of identical, role-related, history-related, category-related, or counterpart-related object classes are assumed to be identical, role-related, history-related, category-related or counterpart-related, respectively. Exceptions from this default assumption have to be explicitly specified. For example, in Figure 6.4 the attributes "BirthDate" of UNIV-EMPL, and "DateOfBirth" of COMP-EMPL are specified as identical under the open world assumption in the attribute description "BornOn" of the role generalization class TAXPAYING-EMPL. The propagation of the semantic relationship between two object classes to the attributes of their instances simplifies the effort in the design of generalization classes considerably. If the designer has grasped the semantic relationship between the local classes correctly, only a few exceptions to the default assumption for the semantic relationship between the attributes have to be specified explicitly. This is especially true when every object models a real world object, in a single role, at exactly one point of time (compare: Table 6.1). For example, if almost all properties of two classes are identical-related, and only a few properties are role-related, they should be integrated by an identical-generalization class, rather than a role-generalization class; the role-related properties have to be listed explicitly with the generalization class.
6.11.5 Message Transformation and Upward Property Propagation In the subsequent subsections we investigate how message transformation and upward property propagation must be handled for instances of the different types of semantic relationships. Upward property propagation refers to derivation of the values of properties of generalization class instances from the values of properties of local class instances. For a quasi-instance of generalization classes only the value(s) of the properties of the decolored quasi-instance are propagated upward.
Identical Properties Under the closed world assumption one of the identical-related properties is propagated upward. Under the open world assumption one of the non-'null'-valued properties is propagated upward. In case of set-valued properties the set-union of their values is propagated upward. For example, to respond to ['Meier-TAXPAYING-EMP' BornOn0] the message is transformed (arbitrarily) either to [['Meier-TAXPAYING-EMP' in(UNIV-EMPL)] Birth-
142
Date()] or to ]['Meier-TAXPAYING-EMP' in(COMP-EMPL)] DateOfBirth0]. If the response is 'null' the other choice is attempted.
Role-related Properties All role-related properties are by default propagated upward and (a) the sum of their values is returned if the addition operator '+' is defined on their domains, otherwise (b) the union of their values is retrieved. For example, the message ['Meier-TAXPAYING-EMPL' Salary()] will be transformed to [['Meier-TAXPAYING-EMPL' in(UNIV-EMPL)] Salary()] in(oeS)] + [[['Meier-TAXPAYING-EMPL' in(COMP-EMPL)] Salary()] in(oeS)]. For quasi-instances, only the property of the instance of its ground class is propagated upward and transformed into the range class of the generalized property. For example the message ['Meier-UNIV-EMPL TAXPAYING-EMPL'Salary()] is transformed to [[['Meier-UNIVEMPL TAXPAYING-EMPL'as(Meier-UNIV-EMPL)] Salary()] in(oeS)].
History-related Properties In the description of a history-generalization class a precedence order is specified on the local classes. The precedence order is given by the listing of the classes from left (oldiest) to right (most-up-to-date) in the history-generalization-ofclause. A precedence order is again specified with the property description of corresponding properties, when they are identified as history related. According to this precedence order the most up-to-date value is propagated upward. The others can be retrieved in combination with the qua-message. For example, assume that PERSON is the generalization class of the history-related classes APPLICANT and EMPLOYEE. Then the salary of Mr. Miller at the time he was an applicant can be retrieved by [['Miller-PERSON' qua(APPLICANT)] Salary()].
Counterpart-related Properties Contrary to role-related properties the values of counterpart-related properties may not be unioned. For example the prices two retailers charge for the same product (remember the example in Subsection 6.11.2) or the fares of two counterpart traffic connections may not be simply added to a single price of the product, nor to a single fare of the traffic connection. Therefore, they are not propagated upward to the instances of the generalization class. But they are propagated upward to quasi-instances. Then in our example the train-fare of the travel from Frankfurt to Vienna can be retrieved in oeS by: [['fra-vie-TRAVEL-CONNECTION' qua(TRAIN-CONNECTION)] Fare()]. To contrast, if the message [['fra-vieTRAVEL-CONNECTION' in(TRAIN-CONNECTION)] Fare()] were used, the Fare would be retrieved in DM, as DM is the range class of the attribute description "Fare" of the local class TRAIN-CONNECTION.
Category-related Properties Category-related properties have been covered above in the power plant example. Every instance of a category-generalization class is the generalization of exactly one instance of a local class. The value of the property of that instance is propagated upward.
143
Arbitrary Relationships between Properties We believe that the different types of relationships between object classes (rsp. properties) presented in this Section cover frequently encountered situations. Therefore, they deserve a special support in the integration process such that the integration effort can be minimized. In case properties have to be generalized in a way which is not covered by the introduced relationship types and their upward property propagation rules, a new method which takes care of this "arbitrary" relationship has to be defined at the generalization class. E.g., consider the TAXPAYING-EMPL example. If different tax-rates apply to the salary of a university employee and to the salary of a company employee, the total taxable salary of a TAXPAYINGEMPL must be calculated by an explicitly defined method from both salaries.
Homonymy Named Properties and Upward Inheritance Upward inheritance means that in the case an attribute/relationship/method is not found with an instance, (rsp. quasi-instance) of a generalization class, the attribute/relationship/method is searched for with the corresponding instances of the local classes. It is important to distinguish between generalization classes with and generalization classes without upward inheritance. In the case of generalization classes with upward inheritance care must be taken about homonymy named properties, such that there values are not inherited upward and retrieved undifferentiatedly intermingled. The homonym specification (e.g., "Course" in Figure 6.9) is used to suppress upward property inheritance. Without the homonym specification the message ['Meier-TAXPAYINGEMPL' Course] would retrieve the courses taught and the courses taken undifferentiatedly intermingled. Because of the name equality of the attributes "Course" of UNIV-EMPL and "Course" of COMP-EMPL, the attributes will be treated by default as corresponding and role-related. The original attributes may be either retrieved by the differentiated names in the homonym specification (e.g., ['Meier-TAXPAYING-EMPL' CoursesTaken]), or by changing the object's behavior to that of the relevant local class (e.g., ['Meier-TAXPAYINGEMPL' qua(COMP-EMPL)] Course()]). Note: the homonym problem may not only occur with identical-, role-, counterpart-, or history-generalization classes, but also with category-generalization classes. For example, consider the attribute "InOperationSince" of the class OIL-PLANT (see: Figure 6.10). Its value is the date on which plant operation was resumed after the last shutdown. And consider the attribute "InOperationSince" of COAL-PLANT. Its value is the date on which the plant was put for the first time on power. Assume that a list of all POWER-PLANTs is to be printed and that the attributes are inherited upward by default. Then semantically different dates will appear, which is misleading, under the same column header "InOperationSince". Therefore, it is required that generalization classes with upward inheritance are specified completely, in the sense that, all homonymly named properties are suppressed by a homonym specification.
144
However, in case a generalization class is specified only partially, or in case the specifications of the local classes are unstable and may undergo some revisions, generalization without upward inheritance is to be used. In this case at least the name of equally named corresponding properties must be listed in the property specifications of the generalization class, in order to be available there. Then this name will be used, unless other ones have been specified, to retrieve the corresponding properties of the local classes. (Compare: the attribute "Fare" of TRAVEL-CONNECTION, or the attributes "PlantName" and "Produced" of POWERPLANT in Figure 6.10). If classes with and without upward inheritance are included to the global view, they must be properly distinguished. In the following we will only consider generalization classes without upward inheritance.
6.11.6 Integration of Relationships In the examples thus far it has been only demonstrated how attributes and methods can be integrated. Remember that attributes have been integrated by specifying the common attribute-name and the common data-type-class at the generalization class. The/n-message has been used to convert the value of a local attribute into the value of the global attribute, e.g., the message ['cpl-POWER-PLANT' Consumed()] is transformed to [[['cpl-POWER-PLANT' in(COAL-PLANT)] Consumed()] in(MJOULE)]. Relationships are treated analogously, but instead of a data-type-class an abstract class is specified as range for the global relationship. Consider the classes in Figure 6.10. The local relationships "Ownership" of OIL-PLANT (Figure 6.11) and "OwnedBy" of COAL-PLANT (Figure 6.12) have been integrated to the global relationship "Owner" of POWER-PLANT. The range classes of the local relationships, POWER-COMPANY and POWER--CORPORATION, have been integrated to the role-generalization class COMPANY. There it is defined that the profit of a corporation should be given uniformly in oeS instead of in US$ or DM. For example, consider that one is interested in the total profit the owner of the coal-plant named "Steamy" makes. Then the query [[[POWER-PLANT detect(PlantName = "Steamy" and Type = "COAL-PLANT")] Owner()] Profit()] will do the job. It was previously explained that the second condition Type= "COAL-PLANT" is necessary, as there might also exist a oil-plant named "Steamy". The first subexpression will evaluate to 'cpSteamy-POWER-PLANT,, i.e., the instance of POWER-PLANT which is a generalization of 'cpSteamy-COAI.,--PLANT,. The next subexpression, ['cpSteamy-POWER-PLANT' Owner()] will be substituted, according to the specification of the global relationship "Owner", by the expression [[['cpSteamy-POWERPLANT' in(COAL--PLANT)] OwnedBy0] in(COMPANY)]. The first subexpression will evaluate to 'cpSteamy-COAL-PLANT'. Then the second one will retrieve the owner
145
class POWER-PLANT category-generalization-of: OIL-PLANT, COAL-PLANT attributes: PlantName Produced Consumed: MJOULE corresponding: OIL-PLANT->OilUsed COAL-PLANT->Consumed relationships: Owner: COMPANY corresponding: OIL-PLANT->Ownership COAL-PLANT->Ownedby end POWER-PLANT
class COMPANY role-generalization of: POWER-COMPANY, POWER-CORPORATION object correspondence rules: POWER-COMPANY.Name = POWER-CORPORATION.Name attributes: Name Address Profit: oeS end COMPANY
class oeS data-type-generalization-of: US$, DM end oeS
Figure6.10: Integration of relationships
class OIL-PLANT attributes:
PlantName : STRING Produced : MWh /* energy produced */ OilUsed : BARRELofOIL InOperationSince : DATE/* first operation after shutdown */ relationships: Ownership : POWER-CORPORATION end OIL-PLANT
class POWER-CORPORATION attributes:
Name : STRING Profit : US$ Address : STRING end POWER-CORPORATION
/* profit from oil plants */
Figure 6.11: Class OIL-PLANT with relationship "Ownership" 'steam&co-POWER-COMPANY'. The subsequent/n-message retrieves the corresponding instance in the generalization class, i.e.,'steam&co-COMPANY'. Then the message ['steam&co-COMPANY' Profit()] will be transformed to "[[['steam&co-COMPANY'
146
class COAL-PLANT attributes: PlantName : STRING Produced : MWh /* energy produced */ Consumed : TONofCOAL InOperationSince : DATE/* first time on power */ relationships: OwnedBy: POWER-COMPANY end COAL-PLANT
class POWER-COMPANY attributes: Name : STRING Profit : DM
/* profit from coal plants */
end POWER-COMPANY
Figure 6.12: Class C O A L - P L A N T with relationship "OwnedBy" in(POWER-CORPORATION)] Profit()] in(oeS)] + [[['steam&co-COMPANY' in(POWER-COMPANY)] Profit()] in(oeS)]" and return the total profit in oeS. An alternative form to pose the same query, if the category-attribute Type is not been used, is: [[[COAL--PLANT detect(PlantName = "Steamy")] OwnedBy0] in(COMPANY)] Profit()]. But in this case the user must take care about the usage of local and global names, and about the necessary transformations between local and global instances.
6.11.7 Integrating Data-Type-Classes and Abstract Object Classes In this subsection the frequent situation in which a real world object is represented in one system by an abstract object and in another system by a data value will be discussed. As an example take the relationship "OwnedBy" of OIL-PLANT, and the attribute "Owner" of HYDRO-PLANT (Figure 6.13). In the first example the company owning the power plant is represented by an internal non-printable object identifier, an instance of the class POWERCOMPANY. In the second the company is represented by a printable data value; a data value of the class COMPANY-NAME. (It will be discussed later what is to be done should the range class of the relationship "OwnedBy" be STRING, instead of OWNER-NAME.) It has been stated that (i) the characteristic feature of a data value is that it stands for itself, e.g., the string "Steam&Co" for the name of a company, and that (ii) an object identifier stands for an abstract object; i.e., the instance 'Steam&Co-POWER-PLANT' for a company: However, a data value may be "misused" to stand not only for itself, but also for an abstract object which it uniquely identifies. This is the case in the example above, where the names of cornpanics have been used to represent the companies themselves. We propose a simple solution to the problem as follows: A data value which is used to rcpresent an abstract object is treated as an abstract object identifier that has a single property, the data value. In order to facilitate referencing the data value a new message of type [ itself()] is introduced. Such a message is handled by a by returning itself.
147
In our example, the role-generalization class COMPANY has been extended by the additional local class O W N E R - N A M E - whose instances are treated as abstract object identifiers and the additional object-correspondence rule OWNER.itself = POWER-COMPANY.Name has been specified. The attribute "Owner" of H Y D R O - P L A N T can now be integrated with the relationships "Ownership" of O I L - P L A N T and "OwnedBy" of C O A L - P L A N T to the relationship "Owner" of P O W E R - P L A N T (See: Figure 6.14). For example the address of the owner of a the hydro-plant ' h p l - H Y D R O - P L A N T ' can be retrieved by the message [ [ [ ' h p l - H Y D R O PLANT' Owner()] in(COMPANY)] Address()]. The above conversion concept for data values is sufficient, if the following assumptions are made:
class HYDRO-PLANT attributes: PlantName : STRING end
Owner : OWNER-NAME HYDRO-PLANT
data type class OWNER-NAME value: STRING
end OWNER-NAME class COMPANY role-generalization-of: POWER-COMPANY, POWER-CORPORATION, OWNER-NAME
object-correspondence-rules: POWER-COMPANY.Name = POWER-CORPORATION.Name OWNER-NAME.itself = POWER-COMPANY.Name attributes: Name corresponding: POWER-COMPANY->Name POWER-CORPORATION->Name OWNER-NAME->itself Address
end COMPANY class POWER-PLANT category-generalization-of: OIL-PLANT, COAL-PLANT, HYDRO-PLANT relationships: Owner: COMPANY corresponding: OIL-PLANT->Ownership COAL-PLANT->OwnedBy HYDRO-PLANT->Owner
end POWER-PLANT
Figure6.13:
Conversion between data values and abstract objects
148
(1)
Every data value that also stands for a real world object, is instance of a data type class that is unique for the type of real world object the data value represents. This requirement corresponds to the unique role assumption in universal relation databases (compare [MU83]). For example, it is allowed to use the range STRING for the attribute "Name" of the class POWER-COMPANY. This is possible, because a value of that attribute is used only to represent the name of a power company, but not the company itself. The company itself is represented by an instance of the class POWER-COMPANY. To the contrary it will be forbidden to use simply the range STRING instead of OWN E R - N A M E for the attribute "Owner" of the class PLANT-TYPE. This is not allowed because a value of that attribute is used not only to represent the name of a power company, but also to represent the company itself. (see: Figure 6.13).
(2)
Several attributes may not be used instead of a relationship to model a relationship between real world objects. For example, it is forbidden to represent the taxpayer of a TAX-STATEMENT by the attributes "NameOfraxpayer" and "AddressOfTaxpayer". (see: class TAXSTATEMENT in Figure 6.14). Instead, the taxpayer of a tax statement should be modeled by a relationship "TaxStatementOr' with the range TAXPAYER. The class TAXPAYER then has the attributes "Name" and "Address". (see: class TAXSTATEMENT' in Figure 6.14).
class TAX-STATEMENT attributes: NameOfTaxpayer : STRING AddressOfTaxpayer : ADDRESS end TAX-STATEMENT class TAX-STATEMENT' relationships: TaxStatementOf : TAXPAYER methods: NameOfTaxpayer 0 : STRING /* TaxStatementOf.Name */ AddressOfTaxpayer0 : ADDRESS/* TaxStatementOf.Address */ end TAX-STATEMENT' class TAXPAYER attributes: Name : STRING Address : ADDRESS end TAXPAYER
Figure 6.14: "Normalized" database design Both assumptions can always be satisfied by introducing a new data type class in the first case, and a new abstract class in the second case. If databases are designed independently, these assumptions should be taken as design guidelines in order to facilitate a possible integration with other databases. Note: that according to these design principles one would intro-
149
duce for example a data type COLOR to represent colors instead of using simply instances of STRING. If these guidlines have not been followed, the necessary extensions will be made in first phase of the database integration process, when the object-oriented export schemata for the databases to be integrated are built. Note: this will not change the world of the local database itself, because an export schema is only a view on the local database containing the database parts to be shared.
6.12 Summary The principle of generalization has been used in the database world for schema integration [BL84, DW84, NEL86, LR82, MK85]. Schema integration may refer to the integration of individual user views to a single conceptual schema, or to the integration of preexisting database schemas into a global view schema. In this chapter, we have been interested in the the second aspect and we have shown how the process of object class definition by generalization can be incorporated into object-oriented systems. The presented approach for the definition of new object classes on existing previously defined ones is applicable whenever predefined object classes have to be combined, be it in bottom-up design in centralized systems or in the integration of distributed systems. Upward inheritance is used to achieve a maximum of reusablity of methods and attributes of previously defined object classes. The distinction of different types of generalization classes and different types of semantic relationships between attributes reduces the integration and development effort to a minimum. In a great number of cases only the types of semantic relationships that hold between object classes to be integrated and that hold between object class's attriutes have to be specified for a successful integration of predefined object classes. Based on the type of semantic relationship the correct property propagations from the local instance(s) to the generalized instance can be automatically infered.
7 Metaclasses for Object Class Definition by Generalization 7.1 Introduction In this chapter we show how VODAK metaclasses can be used to support the principle of object class definition by generalization. Object class definition by generalization is usually not supported by ordinary data models. It is left to the application developer to define the semantics of generalization classes with every single generalization class. Using metaclasses the semantics of the various types of generalization classes introduced in the previous chapter need only be defined once at the metaclass level. For simplicity, we restrict our discussion to category generalization, role generalization, and data type generalization. Furthermore, we always consider only two (and not more) local classes for generalization, and we assume that none of the classes to be generalized is already a generalization class. These simplifications have been mainly made for reasons of readability and instructive purposes. The size of the implementation could be kept small allowing us to present the entire implementation of the metaclasses for the reduced problem. In the first section of this chapter, we discuss the minimum structure and behavior for metaclasses of local classes. In the second section, we show the definition and implementation of metaclasses for category generalization classes, role generalization classes, and data type generalization classes. In the third section, we explain a solution for object coloring. The fourth and last section summarizes the chapter and outlines an alternative to the presented implementation in VODAK.
7.2 Local Classes We refer to classes which can be combined into a generalization class as local classes. Instances of local classes must exhibit a minimum behavior in order for generalization to work. As explained in the previous chapter, every instance of a local class should understand the messages "instance-of", "as", and "in". This behavior is provided by the type "LocalClass_InstlnstType". It serves as supertype of the instance-instance-type of metaclasses for local classes. Figure 7.1 shows the definition and implementation of the type "LocalClass_InstlnstType". The method "instanceOf0" returns the class of the receiver. If the receiver has already been deleted, in which case it does no more belong to the extent of its class, the null object is returned. This kind of behavior is needed for the following reason: Instances of a generalization class may refer to instances of local classes that have already been deleted. Such dangling references can occur, if local classes are administered autonomously from generalization classes. This is usually the case if a global view on classes of autonomously administered databases is defined. Local classes do not know about the existence of generalization classes.
151
Define type LocalClass_lnstType subtypeOf Metaclass_lnstType Define type LocalClass_lnstlnstType subtypeOf Metaclass_lnstlnstType methods: instance-of0 returns Oid; //returns the class of the receiver as(genClass: Oid) returns Oid; //returns receiver colored with genClass in(genClass: Oid) returns Oid; //returns receiver transformed into genClass Implementation LocalClass_lnstlnstType methods: instance-of 0 returns Oid; {if isNull([[self class()] detect:[ol[o=self]} then return(NULL)/* the instance has been removed from its class */ else return([self class()]}; as(genClass: Old) returns Oid; {return([COLORED-OBJECTS colorObject(self,genClass) ] ); } in(genClass: Oid) returns Oid; { return([genClass transformFrom( self } ]; } Figure 7.1: Definition of the object types LocalClass_InstType and LocalClass_InstInstType
Hence, deleting an instance of a local class does not cascade to the corresponding instance of a generalization class. The method "in(genClass: Oid)" is used for transforming a local object into an instance of "genClass". Its implementation corresponds to the conceptual explanation given in chapter 6. The method "as(genClass: Oid)" is used for coloring a local object with the color "genClass". This task is delegated to the predefined object class COLORED-OBJECTS, which will be explained later. A major difference between the conceptual model used in the discussion of object class definition by generalization in the previous chapter and the V O D A K data model, is in the treatment of data values, In the former, data values have been considered ordinary objects such that the concept of object transformation applies the same way for instances of object classes, representing real world entities, and instances of data type classes, representing data values. In the latter, data values are not considered ordinary objects. Thus, they can be manipulated only by predefined operators. Furthermore, unlike classes, data types define only the structure and behavior of their instances but do not have an extensible structure and behavior of their own. One way of bridging this gap is to represent data values as objects in VODAK. For this, we introduce metaclasses for object classes as well as for data type classes. Type "ObjectClass InstType" - shown in Figure 7.2 - defines the common structure and behavior of object classes and is used as supertype of the instance-type of any metaclass representing object classes. It provides for a meta description of the properties of the instances of an object class. For every property, its name, its domain, its multiplicity, and its classification into "attribute", "relationship", or "method" are recorded.
152
TPropDesc:= [ propName : Sel; domain : Oid; singleValued: Bool; propType: String;
//the name of a property //oid of the class which is domain of the property //true iff single valued, false iff multi valued //"attr", "relship" or "method"
Define type ObjectClass_lnstType properties: propDescS : { TPropDesc }; //meta description for properties methods: addPropDesc(propDesc: TPropDesc); //record a new property description getPropDesc(propName: Sel) returns TPropDesc; //select the propDesc identified by propName initializePropDesc0; //builds up the propDesc and methDesc sets from the //data dictionary, which contains the info needed select (condition : TCond) returns {Oid}; // returns a set of instances of the //receiver satisfiying the boolean predicate condition detect (condition : TCond) returns Oid; // returns an instance of the receiver //satisfying the boolean predicate condition isDataTypeClass0 returns Bool; // returns false Define type ObjectClass_lnstlnstType;
Figure 7.2: Definition of the object types ObjectClass_InstType and ObjectClass_Instlnst-
Type Object type "ObjectClass_InstlnstType" defines the common structure and behavior of instances of object classes, which in the current design correspond to the structure and behavior already defined in "Metaclass_InstlnstType" The types "DataTypeClass_InstType" and "DataTypeClass_InstlnstType" - shown in Figure 7.3 and Figure 7.4 - identify the common structure and behavior of data type classes (as objects themselves) and their instances. "DataTypeClass InstType" defines property "dataType" for holding the VODAK type the data type class represents and method "init" for its initialization. Method "isDataTypeClass0", which is also provided by type "ObjectClass_InstType", is defined for checking whether the receiver is a data type class or not. Method "dvObjectFor(v: Result)" returns that instance of a data type class which represents the given data value as an object. If the extension of the data type class already contains such an object, it is returned. Otherwise, a new object representing the given data value is created providing the data value is an instance of the data type the class represents.
"DataTypeClass_InstlnstType" has single property "value" for holding the data value an object represents, method "init" is used for initializing this property. Method "itSelf" returns the receiver and is needed for integrating a data type class, whose values are unique keys of real world entities, and an object class (see: chapter 6). Operator "==, is defined for checking whether two objects represent the same value.
153
Define type DataTypeClass_lnstType subtypeOf Metaclass_lnstType properties: dataType: Sel; methods: init(d: sel); /* initializes property "dataType" isDataTypeClass0 returns Bool; /* returns true dvObjectFor(v: Result) returns Oid; /* returns an instance of the receiver /* representing v
Implementation DataTypeClass_lnstType methods: init(d: Sel); { dataType <-- d) }; dvObjectFor(v: Result) returns Oid; /* returns an instance of the receiver { o: Oid; /* representing v o <-- [self detect([:i I [i value0=v]])]; if isNull(o) then return([[self new()] init(v)]) }; else return(o) }; isDataTypeClass0 returns Bool; { return(True) };
*/ */ */ */
*/ */
Figure 7.3: Definition of the object types LocalClass_InstType and LocalClass_InstlnstType
Define type DataTypeClass_lnstlnstType subtypeOf Metaclass_lnstlnstType properties: value: Result; methods: init(v: Result): Oid; /* initializes property "value" itself() returns Oid; /* returns the object itself */ operator == (aDataType :Oid);
Implementation DataTypeClass_lnstlnstType methods: init(v: Result): Old; { if hasType(v)=[[self class()] dataType0] then value ~ v; else signal(ERROR,"$v can not be represented by $self') }; itself() returns Oid { return(self) }; operator == (aDataType : Oid); { return([self value()] == [aDataType value() ]);}
Figure 7.4: Definition of the object types LocalClass_InstType and LocalClass_InstlnstType Figure 7.5 and Figure 7.6 show the metaclasses for local object classes, LOCAL-OBJECTCLASS, and for local data type classes, LOCAL-DATA-TYPE-CLASS.
154
Define type LocalObjectClass_lnstType subtypeOf ObjectClass_lnstType, LocalClass InstType Define type LocalObjectClass_lnstlnstType subtypeOf ObjectClass_lnstlnstType, LocalClass_lnstlnstType Define METACLASS LOCAL-OBJECT-CLASS instance-type: LocalObjectClass_lnstType instance-instance-type: LocalObjectClass_lnstlnstType Figure 7.5: Definition of the metaclass LOCAL-OBJECT-CLASS
Define type LocalDataTypeClass_lnstType subtypeOf LocalClass InstType, DataTypeClass_l nstType; Define type LocalDataTypeClass_lnstlnstType subtypeOf LocalClass_lnstlnstType, DataTypeClass_lnstlnstType; methods: as(genClass: Old) returns Oid; Implementation LocalDataTypeClass_lnstlnstType; methods: as(genClass: Oid) returns Oid; { return( [self in(genClass)] ); } */ /* "as" and "in" for instances of local data types are the same Define METACLASS LOCAL-DATATYPE-CLASS instance-type: LocalDataTypeClass_lnstType instance-instance-type: LocalDataTypeClass_lnstlnstType Figure 7.6: Definition of the metaclass LOCAL-DATATYPE-CLASS
7.3 Generalization Classes
Type "GenClass_InstType" defines the common structure and behavior of generalization classes (see: Figure 7.7). As already stated above, we consider only generalizations of two local classes here. The properties "genOfClass 1" and "genOfClass2", which are initialized by the method "defAsGenClassFor(localClassl: Oid, localClass2: Oid)", reference these classes. The method "transformFrom(localObject: Oid) returns Oid" is used to transform a local object into a generalization class. The method needs to be implemented differently for the different kinds of generalization classes. Instance types of meta classes whose instances are generalization classes must have "GenClass_InstType' in their supertype chain. Type"GenClass_InstlnstType" defines the common behavior of instances of generalization classes (see: Figure 7.8). The methods "instance-of()", "in(localClass: Oid)", "as(localClass: Oid)", and "qua(localClass: Oid)" and their implementations need no further explanations in addition to those given in chapter 6. The method "transformTo(localClass: Oid)" is used for transforming the receiver into an instance of "local Class". Similarly to the method "transformFrom" of "GenClass_InstType", it must be implemented differently for instances of different kinds of generalization classes. Instance-instance types of meta classes
155
Define type GenClass_lnstType subtypeOf Metaclass_lnstType properties: genOfClassl: Old; genOfClass2: Oid; methods: defAsGenClassFor(IocalClassl Old, IocalClass2: Oid); /* initialize genOfClassl and genOfClass2 transformFrom(IocalObject : Oid) returns Oid; /* transform IocalObject into an instance of the receiver Implementation GenClass_lnstType methods: defAsGenClassFor(IocalClassl Oid, IocalClass2: Oid); {genOfClass ~- IocalClassl; genOfClass2 +- IocalClass2)}; transformFrom(IocalObject : Oid) returns Oid; {/* subtype responsibility */} /* should never run
*/
Figure 7. 7: Definition of the object type GenClass_InstType
Define type GenClass_lnstlnstType subtypeOf Metaclass_lnstType methods: instance-of () returns Oid; //returns the class of the receiver in(IocalClass: Oid) returns Oid; //transform rec. into an instance of IocalClass as(IocalClass: Oid) returns Oid; // transform rec/into an instance of IocalClass qua(IocalClass: Old) returns Oid; // transform rec. into a quasi-instance of the //receiver's class whose ground-instance is from IocalClass transformTo(IocalClass: Oid ) returns Old; //transform receiver into an instance of IocalClass Implementation GenClass_lnstlnstType methods: instance-of0 returns Oid; { return([self class()]); } in(IocalClass: Oid) returns Old; { return([self transformTo(IocalClass)]);} as(IocalClass: Oid) returns Oid; { return([self in(IocalClass)]); } qua(IocalClass: Old) returns Oid; { return [[self in(IocaIClass)] as([self instance-of()])]; } transformTo(IocalClass: Oid ) returns Oid; {/* subtype responsiblity */}
Figure 7.8: Definition of the object type GenClass_InstlnstType whose instances are generalization classes must have "GenClass_InstlnstType' in their supertype chain. Type "ObjectGenClass_InstType" defines the common structure and behavior of generalization classes of object classes (or object generalization classes) (see Figure 7.9 and Figure 7.10). It provides for a meta description of the properties of instances of object generalization classes consisting of the global name of the property, its global domain, its multiplicity, its classification into "attribute", "relationship", or "method", its correspondence type such as "role-related" or "general-related", and the names of the corresponding local
156
TGIobPropDesc := [propName : Sel; /* the name of a property /* the oid of the class which is the domain domain: Oid; /* true iff single valued, false iff multi valued singleValued: Bool; propType: String; /* one of "attr", "relship", "method" /* "role-related", "general-related", etc. corrType: String; combinationMethod: Sel;/* combination method for local props IocalPropNamel: Sel; IocalPropName2: Sel; ] Define type ObjectGenClass_lnstType subtypeOf ObjectClass_lnstType, GenClass_lnstType methods: addPropDesc(propDesc: TGIobPropDesc); /* insert a new description of a global property getPropDesc(propName: Sel) returns TGIobPropDesc; /* select property description identified by propName getLocalPropVal(IocalObj: Oid, globalPropName: Sel) returns Result; /* retrieves the value of that property of IocalObj which corresponds /* to globalPropName; the value is returned in the local domain upwardPropagateFrom(IocalObj: Oid, globalPropName: Sel) returns Result; /* retrieves the value of that property of IocalObj which corresponds /* to globalPropName, converted into the global domain of the property
*/ */ */ */ */ */
*/ */ */ */ */ */
Figure 7.9: Definition of the object type ObjectGenClass_InstType properties. This information is needed by the methods "getLocalPropVal(localObj: Oid, globalPropName: Sel)" and "upwardPropertyPropagate(localObj: Oid, globalPropName: Sel)". Their semantics and implementations are explained below. Method "getLocalPropVal(localObj: Oid, globalPropName: Sel)" is used to access a property of a local object "locaiObj" by its global name, i.e., the name for the property given at the generalization class, rather than by its original local name. Before accessing the property, the method implementation checks whether the accessed object has not been deleted before. Remember the discussion on dangling references from above. - If the accessed object has not been deleted, the set of property descriptions is consulted to determine the corresponding local name for the given global name. Then the property is accessed and its value is returned in the local domain. Method "upwardPropagateFrom(localObj: Oid, globalPropName: Sel)" is used to access a property of a local object "localObj" by its global name, but unlike method "getLocalPropVal" it retrieves the property value transformed into the global domain, i.e., the domain given for the property at the generalization class. The implementation consults the set of property descriptions to determine the global domain, uses the method "getLocalPropVal" to retrieve the property in its local domain, and transforms the retrieved value into the global domain.
157
Implementation ObjectGenClass_lnstType properties: propDescs : { TGIobPropDesc }; methods:
addPropDesc(globalProp: TGIobPropDesc) { insert(propDescs,globalProp); } getPropDesc(globalPropName: Sel) returns TGIobPropDesc; { findElement(propDescs,[ele.propName=globalPropName]); } getLocalPropVal(IocalObj : Oid, globalPropName : Sel) returns Result; {IocalSel : Sel; propDesc: TGIobPropDesc; classOfLocalObj: Old; classOfLocalObj ~ [IocalObj instance-of()]; if isNull(classOfLocalObj) then {/* the local instance has already been deleted */ signal(ERROR, "instance $1ocalObj no longer exists"); return(NULL)} propDesc <-- getPropDesc(globalPropName); if isNull(propDesc) then {signal(ERROR, "no entry in propDesc for $globalPropName") return(NULL); else {if (classOfLocalObj == genOfClassl ) then IocalSel ~- propDesc.localPropNamel; if ( classOfLocalObj == genOfClass2 ) then IocalSel ~- propDesc.localPropName2; if ( classOfLocalObj != genOfClassl and classOfLocalObj != genOfClass2 ) then signal(ERROR,"database corrupted: $1ocalObj of wrong type"); return ( [ IocalObj eval(IocalSel)0 ] ); } upwardPropagateFrom(IocalObj: Oid, globalPropName: Sel) returns Result; { IocalResult: Result; globalResult: Result; globalPropDesc: Old; globalDom: Oid; if isNull(IocaIObj) return(NULL); globalPropDesc ~ [self getPropDesc(globalPropName)]; globalDom ~- globalPropDesc.domain; IocalResult ~- [self getLocalPropVal(IocalObj,globaIPropName)]; if isSet(IocalResult) then if globalPropDesc.singleValued then {signal(ERROR, "incompatible schema definition") globalResult ~- NULL;} else {globalResult ~- {}; for o in IocalResult { gtobalResult ~- globalResult union {o in(globalDom)}}} else if globalPropDesc.singleValued then if isNull(IocalResult); then globalResult <-- NULL: else globalResult <-- [IocalResult in(globalDom)]; return(globalResult); } Figure 7.10: Implementation of the object type ObjectGenClass_InstType
158 Type "ObjectGenClass_InstlnstType" defines the common structure and behavior of instances of object generalization classes (see Figure 7.11). The method "globalDomainOf(globalPropName: Sel)" retrieves the domain of the property identified by "globalPropName" of the receiver by accessing the list of property descriptions of its class. The method "upwardPropertyPropagate(globalPropname)" retrieves the value of the property identified by "globalPropName" through upward property propagation as explained in chapter 6. Because upward property propation must be handled differently for different kinds of generalization classes, the method is not implemented at "ObjectGenClass_InstlnstType" - which defines the structure and behavior of all kinds of object generalization classes- but only at its subtypes which serve as instance-instance types of metaclasses for object generalization classes. Property values of instances of generalization classes are not stored, but determined from the property values of their corresponding local objects through upward propagation. The method "inheritanceBehavior(m: Sel, argList: ArgList)" is used to make upward property propagation run. Every method not directly understood by an instance of a generalization class which will usually be every method not predefined at the meta level - is handled by upward property propagation. For this, the method "inheritanceBehavior(m: Sel, argList: ArgList)" invokes the already explained method "upwaredPropertyPropagate(m)".
Define type ObjectGenClass_lnstlnstType subtypeOf ObjectClass_lnstlnstType, GenClass_lnstlnstType properties: methods: globalDomainOf(globalPropName: Sel) returns Oid; /* retrieves the class which is domain of the property globalPropName upwardPropagate(globalPropName: Sel) return Result; /* retrieves the value of the property identified by globalPropName inheritanceBehavior(m: Sel, argList: ArgList) returns Result; /* handle every method not directly understood by the receiver /* through upward property propagation Implementation ObjectGenClass_lnstlnstType methods: qua(IocalClass : Oid) returns Old; { return([[self in(IocalClass)] as([self instance-of()])) } globalDomainOf(globalPropName: Sel) returns Oid {return([[self instance-of()] getPropDesc(globalPropName)].domain)}; upwardPropagate(globalPropName: Sel) returns Result; { "subtype responsiblity" } inheritanceBehavior(m: Sel, argList: ArgList) returns Result; { return([self upwardPropagate(m)]) };
Figure 7.11: Definition of the object type ObjectGenClass_InstlnstType
*/ */ */ */
159 7.3.1 Category Generalization Classes Instances of category generalization classes have a corresponding local object in one of the local classes of the generalization class. A private property of global objects, "genOf", is used to hold the reference to the corresponding local object. Object transformation is always from or to, and upward property propagation is always from that object. CATEGORY-GENERALIZATION-CLASS is the metaclass for category generalization classes (see Figure 7.12). Its instance-type "CatGen InstType" and its instance-instance type "CatGen_InstInstType" provide the behavior that is specific to category generalization classes and their instances, respectively. Type "CatGen_InstType" (see Figure 7.13), a subtype of "ObjectGenClass_InstType" implements method "transformFrom(localObj: Oid)" for transforming a local object into an instance of a category generalization class. A local object can be transformed into an instance of a generalization class only if it belongs to a local classes of the generalization class. If a corresponding instance for the local object exists already in the generalization class, this instance is returned. Otherwise, an instance of the generalization class is created and an internal reference to the local object is set. Type "CatGen_InstType" reimplements the methods "select(condition: TCond)" and "detect(condition: TCond)" inherited from "ObjectClass_InstType" such that the provided condition - in which global names for properties have been substituted by appropriate local names - is evaluated over instances of each local class of the receiver and such that the global instances corresponding to the local instances satisfying the given condition are returned. Type "CatGen_InstInstType" (see Figure 7.14), a subtype of "ObjectGen_InstInstType, provides method "setGenOf(localObj)" for initializing the reference from a global object to its corresponding local object and method "type()" for returning the class of the local object corresponding to a global object, and method "transformTo(localObj)" for returning the local object of a global object, and "upwardPropertyPropagate(globalPropName)" for retrieving the property identified by "globalPropName" through upward property propagation from the single local object corresponding to a global object. As explained in chapter 6, the distinction between object transformation and object cloring is not relevant for category generalization classes. Therefore, methods "quasi-instance-of()", "ground-class()" and "decolor0" are provided by type "CatGen_InstInstType" for compabitibility with colored objects.
Define METACLASSCATEGORY-GENERALIZATION-CLASS instance-type: CatGen_lnstType instance-instance-type: CatGen_lnstlnstType Figure 7.12: Definition of the metaclass CATEGORY-GENERALIZATION-CLASS
160
Define type CatGen_lnstType subtypeOf ObjectGenClass_lnstType; Implementation CatGen_lnstType methods: select(condition: TCond) returns {Oid}; {/* reimplementation of the method inherited from ObjectClass-lnstType such that the condition - in which global property names have been subsituted by local property names - is evaluated over the instances of each local class of the reciever. The instances satisfying the condition are returned transformed into instances of the receiver */ ..... } detect(condition: TCond) returns Oid; {/* same as select, but only the first matching object is returned */ ..... } transformFrom (IocalObj: Oid) returns Oid {globalObj : Oid; classOfLocalObj : Oid; classOfLocalObj ~ [ IocalObj instance-of0 ]; if (classOfLocalObj == genOfClassl or classOfLocalObj == genOfClassl ) then {/* the local object can be generalized */ globalObj ~- [self detect([:il[i genOf0] = IocalObj)]; if isNull(globalObj) then {/* a global object for IocalObj does not yet exist */ globalObj ~-- [ self new() ]; [ globalObj setGenOf(IocalObj) ];} return(globalObj);} } else { signal(ERROR, "$self is no generalization class for $1ocalObj"); return( NULL ) }};
Figure 7.13: Definition of the object type CatGen_InstType 7.3.2 Role Generalization Classes Instances of role generalization classes have a corresponding local object in none - if the local object(s) has (have) been deleted - one, or both of the local classes of the generalization class. An object corresponding rule of the role gneralization class states when two instances of local classes are equivalent. Object transformation is from a global object to one of its local objects, or from a local object to the global object. Upward property propagation is from one or both of the local objects, depending on how the local properties are related. ROLE-GENERALIZATION-CLASS is the metaclass for role generalization classes (see Figure 7.15). Its instance-type "RoleGen_InstType" and its instance-instance type "RoleGen_InstlnstType" define the structure and behavior that is specific to role generalization classes and their instances, respectively. Before discussing these types in detail, we outline the general approach taken for the implementation.
161
Define type CatGen_lnstlnstType subtypeOf ObjectGenClass_lnstlnstType; methods: setGenOf(IocalObj: Oid); // initialize the property "genOf' type() returns Old; //class of the Ioc. inst. that corresponds to self quasi-instance-of0 returns Oid;//same as instance-of0 for //instances of category gen. classes ground-class0 returns Oid; //for compatibility with colored //objects: same as type() //for compatibility with colored decolor0 returns Oid; //objects: same as genOf0 Implementation CatGen_lnstlnstType properties: genOf: Oid; methods: transformTo (IocalClass: Oid) returns Oid {if ([ genOf instance-of0 ] == IocalClass) then return(genOf); // self can be transformed into an instance of Iocalclass else return(NULL); }//the local object is not an instance of local class quasi-instance-of0 returns Oid; { return([self instance-of0 ]); } ground-class0 returns Oid; { return([genOf instance-of0 ]); } decolor0 returns Oid; { return( genOf ); } type() returns Old; { return([genOf instance-of()]); } setGenOf(IocalObj: Oid) {genOf ~- IocalObj; } upwardPropagate(globalPropName: Sel) returns Result; {return([[self instance-of0]upwardPropagateFrom(genOf,globalPropName)];};
Figure 7.14: Definition of the object type CatGen_InstlnstType
Define METACLASS ROLE-GENERALIZATION-CLASS instance-type: RoleGen_lnstType instance-instance-type: RoleGen_lnstlnstType
Figure 7.15: Definition of the metaclass ROLE-GENERALIZATION-CLASS Instances of role generalization classes reference their corresponding local objects via two private properties "genOfl" and "genOf2". Only one reference needs to be stored when a global object is created. The other one can be located via the object correspondence rule given at the generalization class. But, once located, also the second reference is stored. For simplicity, we consider only object correspondence rules of the form ".= .". Such a rule can be represented by recording the global name for the corresponding local property names. Type "RoleGen_InstType" (see Figure 7.16) defines the private property "corrProp" for holding the global name of the property used for testing equivalence of two local objects; method "defCorrProp" is provided for initializing property "corrProp", and methods "1o-
162
Define type RoleGen_lnstType subtypeOf ObjectClass_lnstType, GenClass_lnstType methods: defCorrProp(globalPropName: Sel); // def. the property which is used to relate //corresponding instances of local classes combineRoleRelated(globalObj: Oid, propName: Sel) returns Result; combineldentialERelated(globalObj: Oid, propName: Sel) returns Result; Figure 7.16: Definition of the object type RoleGen_InstType calCorrPropl" and "localCorrProp2" are defined for retrieving the corresponding local property names. Method "transformFrom(localObj)" is used to transform a local object into an instance of a generalization class. The general idea of the implementation shown in Figure 7.17 for instances of role generalization classes is as follows: First, it must be determined, whether a corresponding global object to the given local object already exists. This is either the case, if an instance of the generalization class exists referencing the local object via one of its properties "genOfl" or "genOf2", or if an instance of the generalization class exists referencing a local object that is equivalent to the given local object via the object correspondence rule given at the generalization class. If the corresponding global object exists, it is returned, otherwise, a new instance of the generalization class is created and its reference to the given local object is set. The indicated algorithm applies for the two possible symmetrical cases: (a) the given local object is instance of the first local class, and (b) the given local object is an instance of the second local class of the generalization class. The methods "combine<X>related(globalObj, propName)" specify how upward property propagation proceeds for "<X>-related" properties, where "<X>" stands for "identicalRelated", "roleRelated", etc. These methods implement the semantics for combining corresponding properties of equivalent objects as outlined in the previous chapter (see Figure 7.18). As for category generalization classes, the methods "select(condition: TCond)" and "detect(condition: TCond)" must be reimplemented by means of query modification. The condition, in which global property names have been substituted by local property names, is evaluated for each local class in turn. The objects in the local results are transformed into instances of the generalization class such that corresponding local objects are represented by a single global object only. Type "RoleGen_InstlnstType" (see Figure 7.19 and Figure 7.20) defines the private properties "genOfl" and "genOf2" for holding references to the local objects corresponding to a global object; methods "setGenOfl" and "setGenOf2" are defined for initializing these properties.
163
Implementation RoleGen_lnstType; properties: corrProp : Sel; methods: select(condition: TCond) returns {Oid}; {/* reimplementation of the method inherited from ObjectClass_lnstType such that the condition - in which glob. prop. names have been subsituted by Ioc. property names - is evaluated over the instances of each Ioc. class of the reciever. The inst. satisfying the condition are returned transformed into instances of the receiver such that corresponding local instances are represented by a single global instance */ ..... } detect(condition: TCond) returns Oid; {/* same as select, but only the first matching object is returned */ ..... } defCorrProp(globalPropName : Sel); { corrProp <-- globalPropName }; IocalCorrProplO returns Sel; {[self getPropDescr(corrProp)].localPropNamel }; IocalCorrProp20 returns Sel; {[self getPropDescr(corrProp)].localPropName2 }; transformFrom (IocalObj: Oid) returns Old {globalObj : Oid; classOfLocalObj : Oid; equiObj : Oid; classOfLocalObj <-- [IocalObj instance-of()]; if (classOfLocalObj = genOfClassl) then {/* the local object can be generalized, if-then statement (1) */ globalObj <-- [self detect([:i I [i genOflO] = IocalObj)]; if isNull((globalObj) then {/* no global obj. refering to IocalObj exists; check, if a global obj. exists that refers to a Ioc. obj. of genOfClass2 which is equivalent to IocalObj */ equiObj~-[genOfClass2 detect([il[i eval([self IocalCorrProplO])O]= [IocalObj eval([self IocalCorrProp20])O]])]; if not isNull(equiObj) then {/* an equivalent local object exists */ globalObj ~- [self detect([il[i genOf20]=equiObj])]; if not isNull(globalObj) then {/* a global object for IocalObj exists, record the reference to IocalObj */ [globalObj setGenOfl (IocalObj)]; return(globalObj);}} /* no global object exists, it has to be created */ globaIObj ~ [ self new() ]; [globalObj setGenOfl(IocalObj)];} return(globalObj); } if (classOfLocalObj = genOfClass2) then {/* the local object can be generalized */ /* this is symmetrical to the algorithm within the if-then statement (1) */ 9 ..
else
}
{/* the local object cannot be generalized */ signal(ERROR, "$self is no generalization class for $1ocalObj"); return(NULL)); }}; /* end of method transformFrom */
Figure 7.17: Implementation of the object type RoleGen_InstType
164
combineRoleRelated(globalObj: Oid; propName: Sel) returns Result; {globalResultl: Result; globalResult2: Result; globalResult: Result; globalResultl [self upwardPropagateFrom([globalObj in(genOfClassl)],propName)]; globalResult2 [self upwardPropageFrom([globalObj in(genOfClass2)],propName)]; if [self getPropDesc(propName)].propType="attr" and [self getPropDesc(propName)].isSingleValued then globalResult:= globalResultl + globalResult2 else globalResult:= globalResultl u globalResult2; return(globalResult)} combineldenticalERelated(globalObj: Oid, propName: Sel) returns Oid; {result: Result; result ~-- [self upwardPropagateFrom([globalObj in(genOfClassl)], propName)]; if isNull(result) then result ~[self upwardPropagateFrom([globalObj in(genOfClass2)],propName)]; return(result);} combineGeneralRelated (globalObj: Oid; propName: Sel) returns Result; { combMeth: Sel; combMeth ~- [self getpPropDesc(propName)].combinationMethodpropDescr return([globalObj eval(combMethod)O]; } combineDefaultRelated(globalObj: Oid; propName: Sel) returns Oid; { genClass: Oid; genClass:= [globalObj instance-of()]; if ( [ genClass corrPropO ] = propName ) then return([ genClass combineldenticallRelated(globalObj, propName) ] ); else return([genClass combineRoleRelated(globalObj,propName)]);}; Figure 7.18: Implementation of the object type RoleGen InstType (continued)
Define type RoleGen_lnstlnstType subtypeOf ObjectClass_lnstlnstType, GenClass_lnstlnstType methods: setGenOfl(IocalObj: Old);
setGenOf2(IocalObj: Old); transformTo (IocalClass: Oid) returns Oid; upwardPropagate(globalPropName: Sel) returns Result; Figure 7.19: Definition of the object type RoleGen_InstInstType In contrast to category generalization classes, the implementation of the method "transformTo(localClass)" for role generalization classes must take into account that a reference to the local object of the given local class is not stored with the global object. There are two possibilities for this to occur:
165
Implementation RoleGen.lnstlnstType; properties: genOfl : Oid;
genOf2 : Oid; methods:
setGenOfl(IocalObj: Oid) {genOfl ~-- IocalObj}; setGenOf2(IocalObj: Old) {genOf2 ~- IocalObj}; transformTo (IocalClass: Oid) returns Oid; {globalClass: Oid; IocalObjl: Oid; IocalObj2: Old; globalClass <-- [self class()]; class1 <-- [globalClass genOfClassl 0 ]; class2 <-- [globalClass genOfClass20 ]; prop1 <-- [globalClass IocalCorrPropl0 ]; prop2 <-- [globalClass IocalCorrProp20 ]; if (IocalClass = class1) then {/* self may be transformed into an instance of class1 */ if isNull(genOfl) then {/* global obj. doesn't refer to an instance of class1, but it refers to an instance of class2, determine the instance of class1 */ genOfl <-- [class1 select([il [i eval(propl)0 ] = [ genOf2 eval(prop2)0 ] ]) ]; } return(genOfl); } if (IocalClass = class2) then {/* self may be transformed into an instance of class1, this is symmetrical to the algorithm within the if-then statement (1) */ ...
}};
upwardPropagate(globalPropName: Sel) returns Result; { corrType: String; class: Old; class ~ [self instanceOf0]; corrType <-- [class getPropDescr(globalPropName)].corrType; if corrType = "role-related" then return([class combineRoleRelated(self,globalPropName)]; if corrType = "identicalE-related" then return([class combineldenticalERelated(self,globalPropName)]; if corrType = "General-related" then return([class combineGeneralRelated(self,globalPropName)]; if corrType = "default-related" then return([class combineDefaultRelated(self,globalPropName)]; };
Figure 7.20: Implementation of the object type RoleGen_InstlnstType
(l) A corresponding local object in the given local class does exist, but it has not yet been recorded with the global object, and (2) no such object exists. In both cases, the object correspondence rule given at the generalization class is used to search for the desired local object. If one is found, it is returned and recorded with the global object for a fast future reference.
166
Again, the indicated algorithm applies for two symmetrical cases. The given local class may be the first or the second local class of the generalization class of the global object to be transformed. The method "upwardPropertyPropagate(globalPropName: Sel)" for instances of role generalization classes proceeds as follows. First, it consults the property description list of the role generalization class to determine the property correspondence type. Depending on the property correspondence type, it activates the appropriate property combination method of the generalization class. 7.3.3 Data Type Generalization Classes Metaclass DATATYPE-GEN-CLASS defines the common structure and behavior of generalization classes of data type classes and their instances (see: Figure 7.21). "DataTypeGen_InstType" (see Figure 7.22), a subtype of "DataTypeGen_InstType" and "DataTypeClass_InstType", is instance-type of metaclass DATATYPE-GEN-CLASS. The private properties "fromTransFormMethod 1" and "fromTransFormMethod2" store references to the methods used for transforming a data value from one of its local representations to the global representation. Conversely, the private properties "toTransFromMethod 1" and "toTransFormMethod2" store references to the methods used for transforming a data value in its global representation to one of its local representations. Method "transformFrom(localObj)" is implemented for data type classes as follows: If the local object represents a local data type of the first local class of the data type generalization class, the method "fromTransformMethodl" is invoked for converting the data value. Otherwise, the method "fromTransformMethod2" is used. Similarly, type "DataTypeGen_InstlnstType" (see Figure 7.23), a subytpe of "GenClass_InstlnstType" and "DataTypeClass_InstlnstType", implements method "transformTo(localClass)" by invoking the respective "toTransformMethod" of the data type generalization class of the data value to be converted.
7.4 Object Coloring Object cloring refers to tagging object identifiers with the name of a class specifying the behavior to be followed by the colored object. Object coloring is simulated as follows in our implementation. Colored objects are repre;ented as instances of a predefined class COLORED-OBJECTS (Figure 7.24 ). Private prop-
Define METACLASS DATATYPE-GEN-CLASS instance-type: DataTypeGen_lnstType instance-instance-type: DataTypeGen_lnst!nstType Figure 7.21: Definition of the metaclass DATATYPE--GEN-CLASS
167
Define type DataTypeGen_lnstType subtypeOf GenClass_lnstType, DataTypeClass_lnstType methods: defineTransMethods(ftml : Sel, ftm2: Sel, toTml : Sel, toTm2: Sel); transformFrom(IocalObj: Oid) returns Old; Implementation DataTypeGen_lnstType
properties:fromTransformMethodl: Sel ; fromTransformMethod2: Sel; toTransformMethodl: Sel ; toTransformMethod2: Sel; methods:
defineTransMethods(ftml: Set, ftm2: Sel, toTml: Sel, toTm2: Sel); { fromTransformMethodl <-- ftml; fromTransformMethod2 ~- ftm2; toTransformMethodl <-- toTrnl ; toTransformMethod2 ~- toTm2; } transformFrom(IocalObj: Oid) returns Oid; {if [ IocalObj instance-of0 ] == genOfClassl ) then return([ self eval(fromTransformMethodl)(IocalObj) ]); if [ IocalObj instance-of0 ] == genOfClass2 ) then return([ self eval(fromTransformMethod2)(IocalObj) ]); signal(ERROR,"$1ocalObj does not belong to a local datatype of Sself");};
Figure 7.22: Definition and Implementation of the object type DataTypeGen_InstType Define type DataTypeGen_lnstlnstType subtypeOf GenClass_lnstlnstType, DataTypeClass_lnstlnstType methods: transformTo(IocalClass: Oid) returns Oid; Implementation DataTypeGen_lnstlnstType methods: transformTo(IocalClass: Oid) returns Oid;
{convMeth: Sel; if ( IocalDataTypeClass == genOfClassl ) then convMeth ~- [[ self instance-of0 ] toTransformMethodl 0 ]; if (IocalDataTypeClass == genOfClass2 ) then convMeth ~- [[ self instance-of0 ] toTransformMethod2 0 ]; if (IocalDataTypeCtass != genOfClassl and IocalDataTypeClass != genOfClass2 ) then signal(ERROR,"$1ocalDataTypeClass is no local class of Sself"); return([[self instance-of()] eval(convMeth)(self)]) };
Figure 7.23: Definition and Implementation of the object type DataTypeGen InstlnstType erty "groundlnst" of its instance-type "ColObj_InstType" (Figure 7.25) holds the object identifier of the colored object and private property "color" holds the class by which the object identifier is to be tagged.
168
Define KERNEL-APPLICATION-CLASSCOLORED-OBJECTS own-type: ColObj_OwnType instance-type: ColObj_lnstType Figure 7.24: Definition of the class COLORED-OBJECTS Method "init(localObj: Oid, genclass: Oid)" is used for initializing these properties by "localObj" and "genClass", respectively. Method "decolor0" returns the uncolored object, and method "groundClass0" the class of the uncolored object. Method "as(col: Oid)" returns the uncolored object identifier, if it is an instance of class "col", and method "quasiInstanceOf0" returns the class by which the colored object is tagged. For a detailed explanation of the semantics of these methods see chapter 6, where also method "qua(genClass: Oid)" is introduced for switching between quasi-instances and instances of a generalization class. Method "inheritanceBehavior" makes a colored object to follow the behavior described by the class in its color. It handles every message to a colored object other than those defined above by upward property propagation from the ground object according to the property description of the generalization class in the object's color. More specifically, it uses method "getLocalPropVal" provided by every generalization class (see above) to retrieve the local property value given the global property name. Then, it consults the property description list of the generalization class for the global domain of the property and colors the object(s) in the result by this domain using method "as(propDomain)". This brings us to the discuss the implementation of method "as(genClass: Oid)" for local objects which we had postponed above. The method delegates object coloring to class COLORED-OBJECTS using method "colorObject(localObj: Oid, genClass: Oid)". This method is defined at own-type "ColObj_OwnType" (see Figure 7.26) of COLORED-OBJECTS. It checks whether an instance of COLORED-OBJECTS exists representing the given ground-instance "loca1Obj" with the given color "genClass". If so, this instance is returned. Otherwise, a new instance of COLORED-OBJECTS is created, initialized by the given ground-instance and color, and returned.
7.5 Summary In this chapter we have examplified how VODAK metaclasses can be used to extend the VODAK kernel model with object class definition by generalization as a new modelling concept. Preferably, the system administrator will provide a set of metaclasses with a set of integration methods which cover the most frequently encountered situations as the kind of semantic relationships between local classes and between local properties is concerned. They deserve special attention such that the integration effort is minimized and only the integration of properties with atypical correspondences have to be hand-coded by the application developer. Comparing our approach to database integration using metaclasses with an approach using the well-known subclass mechanism like that one of Smalltalk[GoRo83], reveals a signifi-
169
Define type ColObj_lnstType subtypeOf | methods: init(IocalObj: Old, genClass: Old); groundClass0 returns Old; //returns the class of the ground instance decolor0 returns Old; //returns the decolored object identifier as (col: Old) returns Old;/* returns the ground inst. of the addressee colored with , or the ground inst. if it is an instance of */ quasi_Instance_Of0 returns Old;//returns color of the colored object qua( genClass: Old) returns Old; inheritanceBehavior(m: Sel, argList: ArgList) returns Result; Implementation ColObj_lnstType properties: color: Old; //the color of the object identifier, a class groundlnst: Old; //the uncolored object identifier methods: init(IocalObj: Old, genClass: Old); { groundlnst e- IocalObj; color e- genClass }; groundClass0 returns Old; /* returns the class of the ground instance */ { return([groundlnst instanceOf0] } decolor 0 returns Old; /* returns the decolored object identifier */ { return(groundlnst);} as (col: Old) returns Old; /* returns the ground instance of */ { if ([self groundClass0] = col) /* the addressee colored with ,*/ then return([self groundlnst0]) /* or the ground instance if */ else return( NULL );} /* it is an instance of */ quasi_Instance_Of0 returns Old;/* returns the color of the colored object */ { return(color);} qua( genClass: Old) returns Old; //TABLE 5.2, rows(cols) 4 and 5 */ { if ([ self quasi-instance-of0 == genClass ) then return([[ self decolor 0 ] in(color) ]); else return(NULL)] ;} inheritanceBehavior(m: Sel, argList: ArgList) returns Result; {/* use upward property propagation */ IocalResult, globalRes: Result; propDomain : Old; IocalResult <-- [color getLocalPropVal( groundlnst, m) ]; propDomain ~- [color getPropDescr(m)].domain; if isNull(IocalResult) then return(NULL); if isSet(IocalResult) then {globalRes <-- {}; for o in IocalResult { globalRes +- gtobalRes union { [o as(propDomain)}; }; eturn(globalRes); }; else return([ IocalResult as(propDomain) ] ); }
Figure 7.25: Definition and Implementation of the object type ColObj_InstType cant advantage: When using subclasses alone, it is not possible to specify the common properties of generalization classes and the common properties of these class's instances once and
170
Define type ColObj_OwnType subtypeOf O methods: colorObject(IocalObject: Oid; genClass: Oid) returns Oid; /* returns the colored object */; Implementation ColObj_OwnType methods: colorObject(IocalObject: Oid; genClass: Oid) returns Oid; {/* implementation of an algorithm which tests whether for (IocalObject, genClass) there exists already an instance (which represents a colored object), if so return that instance, otherwise, create a new one, and initialize the properties color and groundlnstance with genClass and IocalObject, respectively and return the new object. */ coloredObj: Oid; coloredObj <-- [COLORED-OBJECTS detect([ol[o decolor0=localObject and [o color0=genClass])]; if isNull(coloredObj) then {coloredObj ~- [COLORED-OBJECTS new()]; [coloredObj init(IocalObj,genClass)] } return(coloredObj); }
Figure 7.26: Definition and Implementation of the object type ColObj_InstType for all in a single place. In Smalltalk, class variables are shared among a class and all its subclasses. Thus, the apparent solution to define a class GENERALIZATION-SUPERCLASS with two class variables "genOfClass 1" and "genOfClass2" and to use them at several application-specific generalization classes, which are defined as subclasses of GENERALIZATION-SUPERCLASS, does not work. The values of the class variables "genOfClass 1" and "genOfClass2" are different for every generalization class and, hence, can not be shared. To solve the problem, class variables "genOfClassl" and "genOfClass2" must be defined with every generalization class. But this is not enough. Class methods of GENERALIZATION-~SUPERCLASS accessing class variables "genOfClassl" and "genOfClass2" must be implemented at every generalization class, too, as, if inherited, they refer to the class variables of GENERALIZATION-SUPERCLASSand not to the class variables of the respective subclass. Thus, it is the application developer's responsibility to ensure that all generalization classes are defined homogeneously as their structure and behavior is concerned. Using metaclasses, the structure and behavior of generalization classes and their instances need only be defined once by the system administrator at the metaclass level. To conclude this chapter, we revisit our decision of representing data values by objects. Two arguments support this decision: (I) Abstract objects, such as persons, and data values, such as numbers, can be treated homogenously. (2) Object transformation between local objects (data values) and global objects (data values) is symmetrical as seen from the application developer, because the "in"-method can be used in either direction.
171
But, if a dual model is used, two substantial arguments speek in favor of keeping objects and data values apart: (1) Local design autonomy and (2) efficiency. If local design autonomy is respected, local schema designers should not be forced into using data type classes instead of data types just to plan in for possible future integrations. Representing data values by objects may impose a significant performance overhead. Thus, the design of the metaclasses for object class generalization as introduced in this chapter appeals mainly to monolithic models. The changes necessary for supporting a dual model, however, are very simple, if we give up the symmetrical "in"-methods and use the assymmetrical methods "transformFrom" and "transformTo" instead. We shortly outline these changes below.
a)
Local data values are represented immediately by instances of types, rather then by instances of local data type classes, i.e., metaclass LOCAL-DATATYPE-CLASS can be dropped.
b)
Data type generalization classes are still needed for holding information on which local data types they integrate and on transformation methods, which are applied to and return values rather than objects. Data type generalization classes exhibit only a class structure and class behavior; instances of them are never created.
c)
Minor corrections have to be made to the implementation of method "upwardPropagateFrom" of ObjectGenClass_InstType (see: Figure 7.9), because data values cannot receive messages. The messages "[o in(globalDom)]" and "[localResult in(globalDom)]" have to be replaced by the messages "[globalDom transformFrom(o)]" and "[globalDom tranformFrom(localResult)]". A similar change must be done in the implementation of method "inheritanceBehaviour" of type ColoObj_InstType (see Figure 7.25). If "propDomain" is an instance of DATA-TYPE-GENCLASS the message "[o as(propDomain)]" cannot be used; message "[propDomain transformFrom(o)]" must be used instead.
d)
Special care must be taken for the integration of data types and object classes, as the method "itself' defined for instances of data type classes, which are objects, cannot be applied to instances of data types, which are values. The problem can be solved by defining another metaclass for handling that type of integration.
8 Metaclasses in other Object-Oriented Systems 8.1 Introduction In most common object-oriented languages, despite the uniformity principle, classes are not really objects. Some object-oriented systems however, like SMALLTALK-80 [GR83], Loops [BS81], and CLOS [BDG88] introduced the concept of metaclasses to allow the description of a class by another class. In fact, this principle of describing conceptual information (like a schema and its constituents like classes, types, etc:) by other information (often called metadata, metaschema, etc.) using the same concepts for the description has been widely used also in artificial intelligence. In general, one can distinguish between an explicit support for metaclasses and an implicit support [KA90]. Explicit support gives the user (schema designer, model designer) the opportunity to control the behavior (inheritance, object and class creation) specified at the meta level. Implicit support for metaclasses (like the one provided in SMALLTALK-80, GEMSTONE [SER90], ORION [BANE87], and some semantic data models like TAXIS [MW80, NIX84] and RM/T [COD79]) is very restrictive and often not applicable in real complicated applications. Another example of using metaclasses in an object-oriented database model is the approach presented in [GH93]. It is a more system-controlled approach than the explicit support approach, but more flexible than implicit support. [PDB93] reports on an interesting combination of active rules and metaclasses in object-oriented systems to achieve extensibility of the model and to overcome the respective weaknesses of metaclasses and active rules. In this chapter a few interesting concepts of metaclasses in other models and systems and the differences to our approach are briefly described. We have not intended to describe the systems in detail. For such a description the reader is referred to the corresponding literature mentioned above. We only address those issues that are relevant to metaclasses in these systems. The most prominent representative of such systems is SMALLTALK-80. Systems like Loops or Objective-C provide a metaclass concept which is close to the SMALLTALK scheme. In CLOS a meta-object-protocol provides for the definitions of new metaclasses which describe important systems features like the combination of before-, primary-, and after-methods. In general, metaclasses provide a way to design the self-descriptive architecture of a system and the supply hooks to extend this architecture. Hence, the usage of metaclasses leads to a kind of open and adaptable system architecture. In our approach metaclasses lead to an open and tailorable data model. To our knowledge there does not exist any other object-oriented database management system which includes a metaclass concept that provides for the tailoring of the system for particular needs.
8.2 Smalltalk-80 Metaclasses The original implementation of SMALLTALK-72, an early forerunner of SMALLTALK-80, did not realize classes as regular objects. Classes were a separate concept. The invention of the metaclasses in SMALLTALK-76 allows for the system to treat classes as objects. That is,
173
classes become able to handle message passing. All classes are instances of a single metaclass called Class, i.e., the system contains only one metaclass which determines the same behavior for all classes. Consequently, it is impossible to act on the structure of a class, because it is identical for all classes and only the methods implementing the common behavior for all classes can be provided by the metaclasses. SMALLTALK-80 implicitly associates with each class a separate metaclass for the first time. These metaclasses implement all methods that can be sent to a class. For instance, the method new sent to a class and used for the creation and initialization of new instances is defined with the metaclass of that class. The first implementation of SMALLTALK-80 does not support the definitions of instance-variables at the metaclass level. Consequently, the predefined structure of a class cannot be expanded with additional variables. Hence, SMALLTALK-80 metaclasses are seldom used to control or describe the structure of classes themselves. Figure 8.1 shows the class architecture of SMALLTALK-80. In contrast to Figure 16.5 in [GR83], which does not distinguish between explicit and implicit instantiation and subclassing respectively, Figure 8.1 shows which classes are implicitly established by the system when an application class is created (for a more detailed description of the SMALLTALK metaclasses see [CO1N88]). The complex class architecture can be understood best by discussing the instance-of and the subclass-of trees separately. The Instantiation Tree The creation of an application class like Line automatically leads to the generation of its metaclass Line class. Note, that all metaclasses are anonymous and a metaclass of a class M is referred to by the message M class sent to the class M, i.e., Line class denotes the metaclass of class Line. For treating Line class as an object it is considered an instance of Metaclass which is defined to be an instance of Metaclass class. Metaclass class itself is defined as an instance of Metaclass. This class architecture distinguishes five different levels: (i)
The instance level defined by the leaves of the tree. Objects of the instance level cannot serve as classes, i.e., they cannot be instantiated.
(ii) The class level which describes the behavior and structure of the instance level. Classes theoretically can organize an infinite set of instances. (iii) The metaclass levelis implicitly created isomorphic to the class level. A class at the metaclass level defines the structure and behavior of only one instance at the class level. (iv) The metametaclass level consisting only of the single class Metaclass which organizes all SMALLTALK classes. (v)
The metametametaclass level reduced to the root of the instantiation tree.
174
user specified ....
I~ .~-
implicit inheritance (subclass-of) explicit inheritance (subclass-of)
~-
explicit instantiation
--------i~
implicit instantiation
~ ~
implicitly defined meta level for user defined classes predefined meta level predefined classes
Figure 8.1: The class architecture of Smalltalk-80 Note, that the class concept is defined differently for the metaclass level and the other levels. The metaclass level is defined implicitly, and a metaclass can have only one instance. The user has no control over the metaclass level which is automatically handled by the system, because the definition of classes and metaclasses are strongly coupled. The Subclass Tree
The subclass tree in SMALLTALK realizes the inheritance of methods and properties. It provides a single inheritance mechanism, i.e., a class can inherit directly from only one super-
175 class. Figure 8.1 shows that the inheritance of metaclasses is parallel to the inheritance of classes: Line is explicitly defined as a subclass of Object. The corresponding metaclasses then are implicitly also defined as subclasses. Note, that the different treatment of classes and instances is also reflected by the way how they are created. The general statement used to create an instance differs from the one used to establish a class. A class is defined by specifying the subclass relationship instead of the instantiation relationship:
Object subclass: Line instanceVariableNames: 'x y' classVariableNames: '...' poolDictionaries: '...' category: '...' An instance is created by specifying the instantiation relationship in a message, e.g., 'Line new'. It would be more uniform to create a class by sending new to its metaclass. But, because that metaclass does not yet exist, i.e., it is created implicitly just before the class is created, this scenario is impossible in SMALLTALK. This is the reason why classes have to be defined by the SMALLTALK-method subclass:instanceVariableNames:classVariableNames:poolDictionaries:category: that has to be specified with the class Class. This method calls the primitive object allocator new twice, the first time for the metaclass, the second time for the class. The major difference between the approach presented in this thesis and the SMALLTALK metaclass system is the treatment of classes as regular objects, such that a metaclass can organize a set of classes. This is a fundamental mechanism which allows that a metaclass can be used to specify the common structure and behavior of several classes. In SMALLTALK all the semantic relationships defined in chapter 5 would have to be specified with every class which we want to be able to behave according to these relationships. Assume, we want to define the role generalization principle in SMALLTALK. Then, the metaclass ROLE-GENERALIZATION-CLASS will be defined as a subclass of another class, let us say Object:
Object subclass: ROLE-GENERALIZATION-CLASS instanceVariableNames: 'roleGenOfObjlnClassl roleGenOfObjlnClass2' classVariableNames: 'RoleGenOfClassl RoleGenOfClass2' poolDictionaries: '...' category: '...'
176
Now, let us define a global class GLOBAL-STUDENT which generalizes the classes LOCAI~STUDENT-1 and LOCAL-STUDENT-2: ROLE-GENERALIZATION-CLASS subclass: GLOBAL-STUDENT
with the property values RoleGenOfClassl = L O C A L - S T U D E N T - I RoleGenOfClass2 = LOCAL-STUDENT-2 of the class variables. The problem arises if one tries to define another role generalization class, e.g., G L O B A L EMPLOYEE which should generalize LOCAL-EMP1 and LOCAL-EMP2: ROLE-GENERALIZATION-CLASS subclass: GLOBAL-EMPLOYEE with the property values RoleGenOfClassl = LOCAL-EMP1 RoleGenOfClass2 = LOCAL-EMP2
of the class variables.
This definition is not possible as the class variables RoleGenOfClassl and RoleGenOfClass2 need to have the same values for both classes GLOBAI_~EMPLOYEE and G L O B A L STUDENT ([GR83, p.219]). A solution would be to define the variables RoleGenOfClassl and RoleGenOfClass2 with every class GLOBAL-EMPLOYEE and GLOBAL-STUDENT and not with the class ROLE-GENERALIZATION-CLASS. Another alternative (as proposed in [GR83]) would be to define a method RoleGenOfClassl for the classes GLOBAI_~ EMPLOYEE and GLOBAL-STUDENT which returns the constant values ' L O C A L E M P I ' and 'LOCAI_~-STUDENT-I' respecively. But both solutions have the weighty disadvantage of mixing up definitions for the semantic relationship rolegeneralization and definitions for the application. In contrast, our approach provides a clean separation ofmeta definitions and application definitions as shown in Chapter 5.
8.3 CLOS Metaclasses CLOS (Common Lisp Object System) [BDG88] is an object-oriented extension to Common Lisp as defined in [STEE84]. Classes in CLOS are represented as objects which are instances of the class standard-class, the default metaclass that is appropriate for most programs. In addition, a meta object protocol provides for defining and using new metaclasses. This means, that the structure and behavior of entities like methods, slots, generic functions, types, and structures are described at the language level by predefined classes. So far the metaclasses reflect the architecture of the kernel of CLOS. But the concept of metaclasses does not provide for the realization and predefinition of semantic relationships as described in this thesis.
177
8.4 Loops Metaclasses The scheme for metaclasses in Loops [BS81 ] is very close to the one of SMALLTALK. There are three levels corresponding to instances, classes, and metaclasses. In contrast to SMALLTALK a metaclass in Loops can be created explicitly. Every metaclass must be an instance of the predefined metaclass MetaClass. Hence, the depth of the instantiation tree is restricted to three. Furthermore, despite the uniformity principle, classes and their instances are represented nonuniformly. Somewhat surprisingly, the predefined metaclass MetaClass is not modelled as an instance of itself. Therefore, the notion of metaclasses is not completely utilized in the system neither for a uniform self-description of the model nor to provide for a uniform extension of the model features.
8.5 Metaclasses in Other Languages and Models The hybrid object-oriented programming language C++ [STR87] does not provide for metaclasses in any sense. In C++ classes are not treated as objects as they internally define just C-structures. There is no way of tailoring the system for particular needs. Objective-C [COX87] follows the concepts of SMALLTALK. Hence, the metaclass system is restricted in the same way as the one of SMALLTALK-80. TAXIS [MW80], a conceptual programming language, allows more than two levels in the instantiation hierarchy. That is, one can attach properties to classes themselves. But as TAXIS does not provide the encapsulation of methods and properties its metaclass concept is limited to the definition of structural properties. Hence, it does not support any mechanisms which would allow us to define semantic relationships like specialization or generalization through metaclasses or to tailor the model, because procedural behavior needs to be defined with such relationships. GemStone [MSO86], which is based on SMALLTALK, suffers from the same restrictions and limitations of metaclasses as SMALLTALK. Furthermore, the other prominent object-oriented database systems 0 2 [BANC88, DEU90] and Vbase/ONTOS [VBASE88, ONTOS91] are based on C++ and do not support a metaclass concept. 0 2 and Vbase do not even handle classes as regular objects. As far as the author knows, there does not even exist a (fully) object-oriented database system that would provide for the tailoring of its data model for specific needs of an application. Of course, most systems provide a kind of meta-data which corresponds to a meta description of data model concepts or to a data dictionary. But this is different to the metaclass system as it does not allow to uniformly tailor a data model.
9 Conclusion The goal of this work was not to present a completely specified data model language, but to show how the concept of metaclasses can be utilized to get an open, flexible, and tailorable data model, and to illustrate this for particular problems in database integration. We have investigated the fundamental principles which form the basis of the metaclass concept. We have introduced the concept of types, classes, and objects according to the object-oriented paradigm. The requirements of uniformity have been satisfied by treating classes as regular, real objects such that they are instances of other classes which constitute a meta level. Furthermore, we have introduced the concept of instance-instance-types among the concept of instance-types. Instance-types correspond to the role of classes as a template for their instances as used in other object-oriented languages: An instance-type associated with a class is used to determine the structure and behavior of instances of the class. An instance-instancetype associated with a metaclass is used to determine the structure and behavior of the instances of the classes which are instances of the metaclass. This mechanism allows us to specify the behavior on both the class and the instance level in a way that allows the behavior at both levels to be reconciled. Consequently, this concept is fundamental for modelling semantic relationships as they are defined both between different classes and between the instances of these classes. Another important mechanism, the inheritance behavior defined with a semantic relationship, has been realized by extending the classic model of message passing. Only the signature of a method inheritanceBehavior, which is called by the message handling system in case the method to be executed is not defined for the receiver object, is predefined by the system. The message handler passes a method to be executed together with its parameters as parameters to the method inheritanceBehavior, which implements a definable strategy of how to execute the method for an appropriate object. The implementation of the method inheritanceBehavior can be specified by the model designer. Using these mechanisms together we have demonstrated how semantic relationships like role specialization, category specialization, role generalization, and category generalization can be introduced as modelling primitives through the definitions of appropriate metaclasses. Furthermore, we have illustrated how the data model can be tailored for specific cases of integrating local classes into a global class according to the integration concepts originally investigated in [SCH88]. We have defined appropriate metaclasses which combine several semantic relationships such that objects (classes as well as their instances) may participate in different semantic relationships in parallel. As examples we have presented the definition of metaclasses which provide for the integration of role specialized or category specialized c/asses. All these examples demonstrate how the data model can be extended with specific modelling primitives. Contrary to other object-oriented languages or models which include the concept of metaclasses our approach distinguishes itself by
179
*
the uniform treatment of classes and instances as real objects without any restrictions,
9
the introduction of the concept of instance-instance-types; which allows to specify a reconciled behavior at two levels, the class level and the instance level,
9
the homogeneous embedding of the metaclass concept within the basic object-oriented data model concepts,
9
the simple extension of the message handling model such that it considers any application defined inheritance behavior required by a specific application area via semantic relationships, and
9
the clean separation of application and meta definitions, because the latter ones are always specified with metaclasses and never with application classes.
Current and (future) research addresses the topics like those indicated below: 9
Instance-instance-types and instance-types can be used only to adjust the definitions at two corresponding levels, a class level and its instance level. The concept of instance-instance-types could be generalized to the concept of instanceN-types such that N different levels can be influenced by this mechanism. This would allow us to specify the structure and behavior of objects at the meta level N-1. Our approach is restricted to N = 2.
9
Herein we only have demonstrated the realization of semantic relationships like role and category specialization, role and category generalization, and useful combinations of these relationships for the integration of local classes. But the metaclass concept can also be used for the definition of object versioning [KAN94]. That is, different new relationships like version-of and alternative-of could be introduced as modelling primitives through appropriate metaclasses.
9
Similar to introducing versioning through metaclasses, concepts like aggregation, grouping, and components can be provided by metaclasses similar to the proposal of introducing part relatinships [HGP93].
9
The mapping of concrete schemata of external databases to local schemata which may be integrated to a (partial) global schema can be realized through metaclasses [KFA94]. More precisely, one can define a metaclass that provides the functionality of a relation of an external relational database. For each relation specified with the relational schema a corresponding class can be defined as instance of that metaclass. Hence, the access to an external database can be supported by appropriate metaclasses.
We illustrated the usage of the concepts presented by tailoring the data model for semantic modelling and for database integration. In the framework of the latter application scenario we investigated how independently created and administered object-oriented databases can be integrated and how structural differences between different local systems can be overcome.
180
The global view approach has been chosen to provide a homogeneous interface to preexisting databases. Several related object classes of different systems are integrated by a generalization class in the global view. The generalization class defines the global behavior (rsp. representation) of the objects of the classes in the local databases. In order to change between the local and the global behavior (rsp. representation) of objects, the concept of object coloring (rsp. object transformation) has been introduced. Furthermore, several types of generalization classes have been defined. They allow the combination of classes with a particular semantics such that the integration effort can be kept small. To overcome structural differences between the classes of different databases the concept of message forwarding has been introduced. Message forwarding plans are used to describe how a message that can not be handled directly by an object itself, is forwarded to related objects, which can contribute to an answer. Context coloring has been introduced to remember with an object that has been retrieved by a forwarded message the environments the message has visited in its forwarding process. Then the environment in which the object has been retrieved is remembered by the object and can be reflected in the subsequent behavior of the object. Contrary to previous approaches to global view definition, one is allowed to access incompletely defined objects in the global view. Partially defined generalization classes are completed dynamically, if needed, to answer a user query. For this purpose a dynamic knowledge acquisition approach to develop an appropriate message fowarding plan has been presented. The same approach can be used to make the global view self-adaptive to local schema changes. If a message forwarding plan has become obsolete, because of a subsequent local schema change, a new one is developed dynamically. The presented concepts for object-oriented database integration fit in the greater framework of a distributed knowledge based management system which provides access to private and public databases. During a knowledge extraction process the existing databases are provided with object-oriented interfaces, called export-schemata. In some preintegration phase the database administrators o f the different systems meet to come up with the definition of an initial global view. The principle of generalization will be used to integrate at least the basic data types and the most important classes. Then the individual users can define their personal global views which are extensions of the initial global view. In order to locate relevant classes to be integrated the users will be assisted by a knowledge navigator. Global view classes need not be defined completely. The interactive query processor will switch into the knowledge acquisition mode, if some message is not recognized by the addressed object. Then it is tried to develop dynamically a message forwarding plan which answers the message. If the problem why the message was unanswerable is more profound, for example if the definition of a whole class is missing in the global view, the user will seek the help of the knowledge navigator and browse through the different database schemata. Once the appropriate classes have been located they can again be integrated by generalization.
181
In this book we have presented basic principles on how object-classes of multiple object-oriented databases can be integrated, and how structural differences between the local systems can be overcome. The following issues are topic of future research: (1)
The underlying data model for the conceptual schema has been presented informally. Future research should provide a formal definition of the data model and the integration concepts used.
(2)
Retrieval messages have been considered only. Future research should address the problem of updates over the global view.
(3)
Only methods without parameters have been considered for integration. The concept of object class definition by generalization could be extended to methods having several actual parameters.
(4)
It has been assumed that the schemata to be integrated do not contain generalization classes. If the introduced concepts are extended to schemata with generalization classes, it will become possible to define global views of global views.
(5)
Message forwarding plans have been defined always over one local schema. The concepts could be extended to message forwarding plans ranging over several local schemata and the global view.
10 Literature Abbreviations ACM
Association for Computing Machinery
COMPDEC
Computer and Data Engineering Conference
GI
Gesellschaft fuer Informatik
IEEE
Institute of Electrical and Electronics Engineers
IFIP
International Federation for Information Processing
PODS
International Conference on Principles of Database Systems
SIGACT
Special Interest Group for Automata and Computability Theory
SIGMOD
Special Interest Group for the Management of Data
SIGPLAN
Special Interest Group for Programming Languages
TODS
Transactions on Database Systems
TOOIS
Transactions on Office Information Systems
VLDB
Very Large Data Bases
[ABD89]
Atkinson, M., EBancilhon, D.DeWitt, K.Dittrich, D.Maier, and S. Zdonik: The object-oriented database system Manifesto. In: W.Kim, J.-M.Nicolas, and S.Nishio (Eds.): Proceedings of the lst Int. Conference on Deductive and Object-Oriented Databases, Kyoto, Elsevier, pp. 40-57. December 1989.
[ABR87]
Abramovicz, K., et al.: DAMOKLES - Entwurf und Implementierung eines Datenbanksystems fuer den Einsatz in Software-Produktionsumgebungen; Software Engineering, pp. 2-21, 1987.
[ABH94]
Aberer, Karl, Klemens B/Shm, and Christoph Hiaser: The Prospects of Publishing Using Advanced Database Concepts. Proceedings of the International Conference on Electronic Publishing, Document Manipulation and Typography, EP'94, Darmstadt, Germany, April 1994.
[AH87]
Abiteboul Serge and Richard Hull: I F O - A Formal Semantic Database Model, ACM Transactions on Database Systems, Vol 12, Nr. 4, December 1987
[AKF941
Aberer, Karl Wolfgang Klas, and Antonio L. Furtado: User-Oriented Query Modification in Metaclasses Systems, Proceedings of CAiSE*94, Utrecht, June 1994.
183
[AL88]
Aiello, Luigia and Giorgio Levi: The Uses of Metaknowledge in AI Systems, in [MN88], 1988.
[BAH93]
B6hm, Klemens, Karl Aberer, and Christoph Hiaser: Extending the Scope of Document Handling: The Design of an OODBMS Application Framework for SGML Document Storage. GMD Technical Report No. 811, GMD Sankt Augustin, Germany, December 1993.
[BAH94]
B6hm, Klemens, Karl Aberer, and Christoph Htiser: "Introducing D-STREAT - The Impact of Advanced Database Technology on SGML Document Storage" The SGML Newsletter, Volume 7, Number 2, SGML Associates, Inc., Aurora, CO USA, February 1994, pp. 1-4
[BANC88]
Bancilhon, F., et al.: The design and implementation of 02, an Object-Oriented Database System, in [DIT88], Sept. 1988.
[BANE87]
Banerjee J., et al.: Data Model Issues for Object-Oriented Applications, ACM Transactions on Office Information Systems, Vol. 5, No. 1, 1987, pp.3-26.
[BDG88]
Bobrow, D.G., L.G. DeMichiel, R.P. Gabriel, S.E. Keene, G. Kiczales, D.A. Moon: Common Lisp Object System Specification X3JI3, Document 88-002R, SIGPLAN Notices, Vol. 23, Sept. 1988.
[BDM73]
Birtwistle, G.M., O.J. Dahl, B. Myhrharry, K. Nygaard: Simula Begin. Van Nostrand Reinhelt, New York, 1973.
[BEE90]
Beeri C.: A formal approach to object-oriented databases, Data & Knowledge Engineering 5, pp. 353-382, 1990.
[BFN941
Busse, Ralph, Peter Fankhauser, and Erich J. Neuhold: Federated Schemata in ODMG, To appear in Proceedings of the Second International East-West Database Workshop; September 25-28, 1994, Klagenfurt, Austria.
[BL841
Batini, C. and M. Lenzerini: A Methodology for Data Schema Integration in the Entity-Relationship Model. IEEE Transactions on Software Engineering, Vol. 10, No. 6, 1984, pp. 650-664.
[BLN86]
Batini, C., M. Lenzerini, S.B. Navathe: A Comparative Analysis of Methodologies for Database Schema Integration. ACM Computing Surveys, Vol. 18, No.4, 1986, pp. 323-364.
[BMC72]
Bayer, R. and E.M. McCreight: Organization and maintenance of large ordered indices, Acta Informatica, Vol. 1, No. 3, 1972
[BR84]
Brodie, M.L. and D. Ridjanovic: On the Design and Specification of Database Transactions, in [BMS84], revised and republished in [MB88]
[BS81]
Bobrow, D.G. and M. Stefik: The Loops manual, Technical Rep. KBVLSI-81-13, Xerox Palo Alto Research Center, 1981.
184
[CAT93]
Cattell, R.G.G, Ed.: Object Databases: The ODMG-93 Standard, Morgan Kaufmann, 1993.
[CHE76]
Chen, P.P.-S.: The Entity-Relationship Model: Towards A Unified View of Data. ACM Transaction on Database Systems, Vol. 1, No. 1, March 1976, pp. 9-36.
[CO79]
Comer, D.: The ubiquitous B-tree, ACM Computing Surveys, Vol. 11, No. 2, April 1979,
[COD79]
Codd, E.E: Extending the Database Relational Model to Capture More Meaning, ACM Transactions on Database Systems, Vol. 4, No. 4, December 1979, pp. 377-387.
[COIN88]
Cointe E: A Tutorial Introduction to Metaclass Architecture as provided by Class Oriented Languages, Proc. of the Int. Conf. on 5th Generation Computer Systems, Tokyo, Japan, 1988.
[cox87]
Cox J.B.: Object-Oriented Programming - An Evolutionary Approach, Addison-Wesley, Reading, MA, 1987.
[CTK94]
Chen, Weimin, Volker Turau, Wolfgang Klas: Efficient Dynamic Look-up Strategy for Multimethods, Proceedings of the 8th European Conference on Object-Oriented Programming (ECOOP'94), Bologna, Italy, July 4 - 8, 1994.
[DAHL661
Dahl, O.J. and Nygaard K.: SIMULA - an algol-based simulation language, Communications of the ACM, No. 9, 1966.
[DEU90]
O.Deux et al.: The Story of 02. IEEE Transactions on Knowledge and Data Engineering, Vol. 2, No. 1, March 1990, pp.91-108.
[DIT86]
Dittrich, K.R. and U.Dayal: Object-oriented Database systems: the Notion and the Issues, Proc. Int. Workshop on Object-Oriented Database Systems, Washington, IEEE Conmputer Society Press, 1986.
[DKT88]
Duchene, H., M.Kaul, V.Turau: VODAK kernel data model, in [DIT88], Sept. 1988
[DW84]
Dayal, U. and H. Wang: View Definition and Generalization for Database Integration in a Multidatabase System. IEEE-Transactions on Software Engineering, Vol. SE-10, No. 6, November 1984, pp. 628-644.
[FHK941
Fankhauser, Peter, Gerald Huck, and Wolfgang Klas: IRO-DB - An objectoriented approach towards federated and interoperable DBMS, Proceedings of the International Workshop on Advances in Databases and Information Systems (ADBIS'94) ACM SIGMOD, Moscow, May 23-26, 1994.
185
[FN92]
Fankhauser, P. and Neuhold, Erich J.: "Knowledge Based Integration of Heterogeneous Databases". Proceedings of lFIP Conference DS-5 Semantics of Interoperable Database Systems, November 1992.
[GB91]
Giinther, O. and J.Bilmes: Tree-Based Access Methods for Spatial Databases: Implementation and Performance Evaluation; IEEE Transactions on Knowledge andData Engineering, Vol. 3, No. 3, September 1991.
[GH93]
G6ers, Jutta, and Andreas Heuer: Definition and Application of Metclasses in an Object-Oriented Database Model, Proceedings of the 9th International Conference on Data Engineering, Vienna, Austria, April 19-23, 1993.
[GK76]
Goldberg, A. and A.Kay: Smalltalk-72 Instruction Manual, Research Report SSL 76-6, Xerox PARC, Palo Alto CA, USA, 1976.
[GR83]
Goldberg, A. and D. Robson: Smalltalk-80- The Language and its Implementation, Addison-Wesley, Reading Massachusetts, 1983.
[HAL88]
Halasz, EG.: Reflections on NoteCards: Seven Issues for the Next Generation of Hypermedia Systems; Communications of the ACM, Vol. 31, No. 7, July 1988.
[HEU92]
Heuer, Andreas: Objekt-orientierte Datenbanken, Addison-Wesley, 1992.
[HGP93]
Halper, Michael, James Geller, and Yehoshua Perl: Report on Implementing Part Relationships Using VML Metaclasses. GMD-Studien Nr.'224, GMD Sankt Augustin, Germany, November 1993.
[HM81 ]
Hammer, M.M. and D.McLeod: Database Description with SDM: A Semantic database Model, ACM Transactions on Database Systems, Vol. 6, No. 3, September 1981, pp. 351-381
[HK87]
Hull Richard and Roger King: Semantic Database Modeling: Survey, Applications, and Research Issues; ACM Computing Surveys, Vol. 19, No. 3, September 1987
[KA90]
Khoshafian, S. and R.Abnous: Object Orientation, Wiley, New York, 1990.
[KAN94]
Klas, Wolfgang, Karl Aberer, and Erich J. Neuhold: Object-Oriented Modeling for Hypermedia Systems using the VODAK Modelling Language (VML). in: Tamer Ozsu and Alex Biliris (Eds.) Object-Oriented Database Management Systems, NATO ASI Series, Springer Verlag Berlin Heidelberg, August 1994.
[KB851
Ketabchi, M.A. and V.Berzins: ODM - An Object-Oriented Data Model for Design Databases; Univ. of Minnesota Institute of Technology TR 85-41, Oct. 1985.
186
[KDN89]
Kaul, M., K. Drosten, E. Neuhold: View System: Integrating Heterogeneous InformationBases by Object-Oriented Views. Proc. IEEE Sixth Intl. Conf. on Data Engineering, Los Angeles, CA, 1990
[KFA941
Klas, Wolfgang, Gisela Fischer, and Karl Aberer: Integrating Relational and Object-Oriented Database Systems Using a Metaclass Concept, to appear in Journal of Systems Integration, Kluwer Academic Publishers, 1994.
[KLA90]
Klas, Wolfgang:A Metaclass System for Open object-OrientedData Models. PhD Thesis, Technical University of Vienna, 1990.
[KN90]
Klas, Wolfgang and E.J. Neuhold: Designing Intelligent Hypertext Systems using an Open Object-Oriented Database Model. Technical Report No.489, Arbeitspapiere der GMD, October 1990.
[KN931
Klas, W., E.J.Neuhold et.al.: VML - The VODAK Data Model Language, Version 3.0. Technical Report, GMD-IPSI, Darmstadt, November 1993.
[KNCR86]
Knowledge Craft Manual, Carnegie Group Inc., 1986.
[KNS88]
Klas, W., Neuhold, E. J., and Schrefl, M.: On an object-oriented data model for a knowledge base, in Repr. from 'Research into networks and distributed application-EUTECO', ed. Speth, R. [Hrsg.], North-Holland, 1988.
[KNS89a]
Klas, Wolfgang, Neuhold, Erich J., and Schrefl, M.: Visual Databases need Data Models for Multimedia Data, Visual Database Systems - Proceedings of the IFIP TC 21WG 2.6 Working Conference on Visual Database Systems, ELSEVIER Science, Amsterdam, Tokyo, Japan, 3-4 April 1989.
[KNS89b]
Klas, Wolfgang, Neuhold, Erich J., and Schrefl, M.: Tailoring Object-Oriented Data Models through Metaclasses, Proceedings of the Advanced Database System Symposium, Kyoto, Japan, Dez. 1989.
[KNS90]
Klas, Wolfgang, Neuhold, E. J., and Schrefl, M.: Using an Object-Oriented Approach to Model Multimedia Data, in Computer Communications, Special Issue on Multimedia Communication, Butterworths, London, Vol. 13, No. 4, May 1990
[LR82]
Landers, R. and R. Rosenberg: An overview of Multibase. In: H.J. Schneider (edt.): Distributed Databases. North Holland Publishing Company, 1982, pp. 153-164.
[MAI83]
Maier, D.: The Theory of Relational Databases. Computer Science Press. 1983.
[MAN93]
Manola E: MetaObject Protocol Concepts for a 'RISC' Object Model. Technical Report TR-0244--12-93-165 GTE Laboratories Incorporated, Waltham, MA 02254, December 30, 1993.
187
[MD86]
Manola, E and U.Dayal: P D M - An Object-oriented Data Model; in [DIT86]
[MH931
Manola, F., and S. Heiler: A 'RISC' Object Model for Object System Interoperation: Concepts and Applications, Technical Report TR-0231-08-93-165 GTE Laboratories Incorporated, Waltham, MA 02254, August 10, 1993.
[MK85]
Mannino, V. and R. Karle: "An extension of the general entity manipulator for global view definition. Data and Knowledge Engineering, No.l, 1985, pp. 305-325.
[MKN90]
Muth Peter, Wolfgang Klas, Erich J. Neuhold: How to Handle Global Transactions in Heterogeneous Database Systems. Proceedings of the Workshop on Multidatabases and Semantic Interoperability, Tulsa, Oklahoma, USA, Nov 2-4, 1990
[MOO86]
Moon, D.: Object-Oriented Programming with Flavors. Proceedings ACM Conference on Object-Oriented Systems, Languages, and Applications. Portland, Oregon, Sept. 1986.
[MOT87]
Motro, A.: Superviews: Virtual Integration of Multiple Databases. IEEE Transactions on Software Engineering, Vol. 12, No. 7, 1987, pp. 785-798.
[MRKN92]
Muth, P. T.C.Rakow, W.Klas, E.J.Neuhold: A Transaction Model for an Open Publication Environment, in: A.H.Elmagarmid (Edt.): Database Transaction Models For Advanced Applications, Morgan Kaufmann, San Mateo, USA, 1992
[MR91]
Muth Peter and Thomas Rakow: Atomic Commitment for Integrated Database Systems. Proceedings of IEEE Seventh International Conference on Data Engineering, Kobe, Japan, April 8-12, 1991
[MSO86]
Maier, D.J., J. Stein, A. Otis, and A. Purdy: Development of an Object-Oriented DBMS, Proc. Object-Oriented Programming Systems, Languages and Applications, OOPSLA'86, ACM.
[MU83]
Maier, D. and J.D. Ullman: Maximal Objects and the Semantics of Universal Relational Databases. A CM Transactions on Database Systems, Vol. 8., No. 2, 1983, pp. 1-15.
[MW80]
Mylopoulos, J. and H.K.T.Wong: Some features of the Taxis data model, Proc. The 6th International Conference on Very Large Data Bases, ACM, Montreal, Oct. 1980
[NCLB87]
Nixon, B., L.Chung, D.Lauzon, A.Borgida, J.Mylopoulos and M.Stanley: Implementation of a Compiler for a Semantic Data Model: Experiences with Taxis; Proc. ACM SIGMOD International Conference on Management of Data, 1987
188
[NIX84]
Nixon B.: TAXIS 84: Selected papers. Technical Report CSRG-160, University of Toronto, 1984.
[NEL86]
Navathe S., R. Elmasri, J. Larson: Integrating User Views in Database Design. IEEE-Computer, Jan. 1986, pp. 10-18.
[NPGT89]
Neuhold, Erich J., Y. Perl, J. Geller, and V.Turau: Separating Structural and Semantic Elements in Object Oriented Knowledge Bases, Proceedings of the Advanced Database System Symposium, Kyoto, Japan, 1989
[NS88]
Neuhold, Erich J. and M.Schrefl: Dynamic Derivation of Personalized Views, Proc. of the 14th Int. Conf. on Very Large Data Bases, Los Angeles, CA, 1988.
[NW84]
Neuhold, E. J. and B. Walter: POREL: A Distributed Data Base Management System, in: H. J. Schneider (ed.) Distributed Databases, North Holland, Amsterdam, 1982.
[ONTOS91]
ONTOS, Inc.: ONTOS Reference Manual, 1991.
[PDB93]
Paton, Norman W., Oscar Diaz, and Maria L.Barja: Combining active rules and metaclasses for enhanced extensibility in object-oriented systems, Data & Knowledge Engineering, Vol. 10, No. 1, February 1993, pp. 45-63.
[PSSW87]
Paul, H.B., H.-J. Schek, M. H. Scholl, G. Weikum, and U. Deppisch: Architecture and Implementation of the Darmstadt Database Kernel System; Proceedings of ACM SIGMOD 1987 Annual Conference, San Francisco, pp. 196-207, 27-29.05.87. Organization: Computer Science Departement, Technical University of Darmstadt
[RGN90]
Rakow, C.T., J.Gu, E.J.Neuhold: Serializability in Object-Oriented Database Systems; to appear in Proceedings 6th Int. Conf. on Data Engineering, Los Angeles, California, Feb. 1990.
[RV87]
Richard E and EVelez: An Object-Oriented Formal Data Model; Proc. Workshop on Database Programming Languages, pp. 177-192, Sep. 1987.
[SC83a]
Schiel, U.: An abstract introduction to the temporal-hierarchic data model (THM); in Proc. of the 9th International Conference on Very Large Data Bases, Florence, Italy, 1983.
[SCH88]
Schrefl, Michael: Object-oriented database integration. Doctoral Thesis, Technical University of Vienna, June 1988.
[SER90]
Servio Logic Development Corporation, GemStone V 2.0: Programming in OPAL, 1990.
[SHI81]
Shipman, D.: The Functional Data Model and the Data Language DAPLEX, ACM transactions on Database Systems, Vol. 6, No. 1, March 1981, pp. 140-173.
189
[SHT89]
Streitz, N., J.Hannemann, and M.Thiiring: From Ideas and Arguments to Hyperdocuments: Travelling through Activity Spaces, Proceedings of HYPERTEXT'89, Pittsburgh, USA, Nov. 5-8, 1989.
[SN88a]
Schrefl, Michael and Erich J. Neuhold: Object class definition by generalization using upward inheritance, Proc. 4th Int. Conf. on Data Engineering, 1988.
[SN88b]
Schrefl, Michael and Erich J. Neuhold: A Knowledge-Based Approach to Overcome Structural Differences in Object Oriented Database Integration, The Role of Artificial lntelligence in Database and Information Systems, IFIP Working Conf., Canton, China, July 88.
[SNY86]
Snyder A.: Encapsulation and Inheritance in Object-Oriented Programming Languages. Proceedings of the ACM Conference on Object-Oriented Programming Systems, Languages, and Applications, Portland, Oregon, September 1986.
[SL90]
A.P. Sheth and J.A. Larson, federated database systems for managing distributed, heterogeneous and autonomous databases: Architecture and Issues, in ACM Computing Surveys, Vol. 22, No. 3, pp. 183-236, September 1990.
[SR87a]
Stonebraker, M. and L.A. Rowe: The POSTGRES Data Model. Proceedings of the International Conference on VLDB, 1987, pp. 83-96.
[SR87b]
Stonebraker, Michael and L. Rowe, The Postgres Papers, Electronics Research Laboratory, College of Engineering; Memorandum No. UCB/ERL M86/85, p. 115, University of California, Berkeley, CA, 25 June 1987.
[SRF871
Sellis, T., N.Roussopoulos, and C.Faloutsos: The R+-tree: A dynamic index for multi-dimensional objects, in Proc. 13th Int. Conf. Very Large Data Bases, 1987.
[SS771
Smith, J.M. and D. Smith: Data Abstraction: Aggregation and Generalization. ACM Transactions on Database Systems, Vol. 2, No. 2, June 1977, pp. 105-133.
[STEE84]
Steel Jr., G.L.: Common Lisp - The Language, Digital Press, 1984.
[SB86]
Stefik, M. and D.G. Bobrow: Object-Oriented Programming - Themes and Variations, AI-Magazine, pp. 40-62, 1986.
[STR87]
Stroustrup, B.: The C++ Programming Language, Addison-Wesley, Reading, 1987.
[STW841
Schrefl, M., A.M. Tjoa, R.R. Wagner: Comparison Criteria for Semantic Data Models. In: Proceedings IEEE COMPDEC, 1984, pp. 105-133.
190
[SW86]
Schek, H.J and G.Weikum: DASDBS: Konzepte und Architektur eines neuartigen Datenbanksystems, Informatik - Forschung und Entwicklung, 1986
[TD93]
Turau, Volkerand Horst DuchSne: Equality testing for complex objects based on hashing, Data & Knowledge Engineering, Vol. 10, No. 1, February 1993, pp. 101-111.
[TOU58]
Toulmin, S.: The uses of arguments, Cambridge University Press, Cambridge, 1958
[UD86]
Urban S. and L. Delcambre: An analysis of the structural, dynamic and temporal aspects of semantic data models. Proceedings IEEE COMPDEC, 1986.
[VBASE88]
Vbase Manuals, Release 1.0, Ontologic Inc., 1988
[WEGN87]
Wegner, P.: The Object-OrientedClassificationParadigm, in Research Directions in Object-Oriented Programming, Eds. Shriver and Wegner, MIT Press 1987.
[WEGN87a] Wegner, P.: Dimensions of Object-Based Language Design, TechnicalReport No. CS-87-14, Dept. of Computer Science, Brown University, USA, July 1987 [WKL86]
Woelk, Darrel, W. Kim, and W.Luther: An Object-Oriented Approach to Multimedia Databases; ACM SIGMOD Record 1986, pp. 311 - 325, ACM, 1986.
[ZANI83]
Zaniolo, C.: The Database Language GEM, Proc. ACM SIGMOD Conference on Management of Data, San Jose, CA, May 1983
[ZM90]
Zdonik, S.B. and D.Maier (Eds.): Readings in Object-OrientedDatabase Systems. Morgan Kaufmann, San Mateo, CA, 1990.
[ZW86]
Zdonik, S.B. and P.Wegner: Language and methodology for object-oriented database environments; in Proc. 19th Annual Hawaii International Conference on System Sciences, Jan 1986
Appendix A: Index to Types and Classes This index includes the types used to describe the data model concepts and the object types, data types, and the classes specified in our examples. Page numbers printed in boldface indicate the pages where the type or class definitions are given.
A
D
ActArgList, 35, 37
DBSchema, 57
ArgList, 17
DispTbls, 44 DomArgList, 24 DomExpr, 24, 30
C
DomExprV, 24 DTD, 16, 57
CD, 23, 26 class BACKING, 121 CATEGORY-SPECIALIZATIONCLASS, 92-122, 93 CLAIM, 121 COMPLEX-PART, 92-122, 97 DATUM, 121 EMPLOYEE, 86-91 LICENSED-PART, 96-122, 97 METACLASS, 65-69 ON_ACCOUNT_OF, 121 PART, 92-122, 97 PERSON, 8f~91, 90 REBUTI'AL, 121 ROLE-SPEC-TOULMIN-NODECLASS, 118 ROLE-SPECIALIZATIONCLASS, 86-91, 87 SIMPLE-PART, 92-122, 97 SINCE, 121 SINGLETON~CLASS, 86-91 extension of, 92-122, 93 SO, 121 STUDENT, 86-91, 90 TOULMIN-NODE-CLASS, 118 TOULMIN-LINK-CLASS, 118 UNLESS, 121 UNLICENSED-PART, 96-122, 97 VML-CLASS, 53 WARRANT, 121
DTypeld, 15
I Init, 35, 37
M map, globally defined 1], 16,57 19, 18,57 or, 30, 44 ~, 27, 32, 35, 37, 57 ~, 23, 26 Md, 28 pd, 28 Md, 28 MethDef, 17 MethDen, 43, 44, 55 MethName, 15
O Object, 30, 44 ObjectDef, 27, 32, 35, 37 ObjectMem, 29, 30, 44 Objld, 15 OD, 27, 32, 35, 37, 57
ClassDef, 23, 26
OTD, 15, 18, 57
Classld, 15
OTypeDef, 15, 18
192
RoleSpec_InstlnstType, 86-91, 89 RoleSpec_InstType, 86-91, 88 RoleSpecToulminNodeClass_InstlnstType, 118 RoleSpecToulminNodeClass_InstType, 118 SingletonClassjnstlnstType, 86, 87 extension of, 93-122, 94, 102, 107 SingletonClassjnstType, 86, 87 extension of, 93-122, 94, 106 ToulminLinkClass_InstlnstType, 118 ToulminLinkClassjnstType, 118 ToulminNodeClassjnstlnstType, 118 ToulminNodeClass_InstType, 118 VML-ObjecLType, 61, 61-64 VML-Class_InstlnstType, 61-64, 62, 63 VML-Class InstType, 61-64, 62, 63, 67-68 primitive Arglist, 54 Bool, 16 Char, 16 domains of, 16 Float, 16 Integer, 16 Oid, 16 Result, 54 Sel, 16, 54 String, 16 Void, 16
OTypeld, 15
P Pq 28 PrimTypeld, 16 PropDef, 17 PropName, 15
T TC, 24 TCM, 25 TCP, 25 type data, Date, 21, 56 object 19, 18, 60, 65 Aggregation_InstlnstType, 100 Aggregation_InstType, 101 CategorySpec_InstlnstType, 93-122, 96 CategorySpec_InstType, 93-122, 95 Claim_Type, 119 CompClass_InstlnstType, 105 CompClass_InstType, 105 ContenLType, 119 Datum_Type, 120 KemelApplicationClass_InstType, 63 LinkClass_InstlnstType, 117 LinkClass_InstType, 117 Metaclass_InstlnstType, 65 Metaclass_InstType, 65, 67-68 NodeClass_InstlnstType, 116 NodeClass_InstType, 116 Person_Type, 21 RoleCompClass InstlnstType, 109, 111 RoleCompClass_InstType, 110, 111
TypeExpr, 16 TypeExprV, 17
V Value, 30, 44, 54 VarName, 15
Appendix B: Index to Functions This index includes the functions used to describe the data model concepts.
C
O
class, 27, 33, 35, 38
o-tc, 33, 35, 36, 38
createobject, 31
o-type, 33, 35, 38 objectdefs, 57
D datatypes, 57 defclass, 58 defdatatype, 58 defobjtype, 58
objecttypes,. 57 ownMeths, 44
P props, 18
destroyobject, 31 disptbl, 44
S selection, 46, 55
I
send, 45, 54 state, 30, 44
i-tc, 26 i-type, 23, 25, 26, 36, 38
T
ii-type, 38 instinstMeths, 44 instMeths, 44
t~. i, 26, 36, 38 t~. il, 39 tm.o, 33, 35, 38 tp.i, 26, 36, 38
M
tp.ii, 38
meths, 18
tp. o, 33, 35, 38
Appendix C: Summary of Formal Notation Here is a list of symbols and their explanation used in this book with which the reader may not be familiar. The symbols are part of the meta language used to describe the concepts of the data model. I[expression ]1 set of s
{},~ A~-~B [ a~--~b.... ]
[] @
the domain of a type expression or domain expression (finite) set type constructor the empty set map type constructor mapping from a to b .... the empty map map overwrite operator: map1 ~ m a p 2 denotes the map which maps domain elements of map2 into the same range elements as does map2, and maps those domain elements of map1 which are not in the domain of map2 into the same range elements as does map1, and maps nothing else: [al ~--~bl, a2 F--~b2]~) [al ~-'~Cl, a3 ~-')b3] =
[al ~ C l , a2 ~b2, a3 ~b3] \
map restrict with operator: map \ wset denotes the map which maps those domain elements of map which are not in the set
wset
into the same range elements as does map, and maps nothing else. U
map merge operator: m a p l u map2 denotes a map provided
the domains of m a p l and map2 are disjoint, otherwise undefined. The denoted map maps domain elements of m a p l into the same range
dom m
elements as does map1, and domain elements of map2 into the same range elements as does map2, and maps nothing else. denotes the set of objects which are domain elements of the
rn(~[ m
map m: dora [a1 ~'~bl , a2 ~-'~b2..... an ~-~bn] = {al , a2 ..... an } denotes the set of objects which are the range elements of the
elems t
mapm: m__g[a 1 ~--~b l , a2 ~--~b2 ..... an ~--~bn ] = { b l , b2 ..... bn } denotes the set of elements contained in the tuple t.
Appendix D: Table of Definitions Definition 1: ( Primitive Types ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
Definition 2: ( Data types, type expressions ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
Definition 3: ( Structural and behavioral property definition ) . . . . . . . . . . . . . . . . . .
17
Definition 4: ( Object type definition ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
18
Definition 5: ( Type specialization - the computation of P(T) and M(T) ) . . . . . . . . .
22
Definition 6: ( Object type - class map ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
24
Definition 7: ( Domain expressions ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
24
Definition 8: ( Type-to-Class Mapping ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
Definition 9: ( Class Definition - preliminary definition ) . . . . . . . . . . . . . . . . . . . . .
26
Definition 10: ( Object Definition - preliminary definition I ) . . . . . . . . . . . . . . . . . .
27
Definition 11: (pd(oid), Md(oid) ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
28
Definition 12: ( Determination of Pd(oid) and Md(oid) - preliminary definition I ) .
28
Definition 13: ( Domain of domain expressions ) . . . . . . . . . . . . . . . . . . . . . . . . . . . .
30
Definition 14: ( Object - preliminary definition I ) . . . . . . . . . . . . . . . . . . . . . . . . . . .
30
Definition 15: ( Object Definition - preliminary definition II, redefines Definition 10 ) 32 Definition 16: ( Determination of pd(oid) and Md(oid) - preliminary definition I I ) . .
33
Definition 17: ( Uniform Object Definition - preliminary definition III ) . . . . . . . . .
35
Definition 18: ( Uniform Object Definition - final definition IV ) . . . . . . . . . . . . . . .
37
Definition 19: ( Determination of pd(oid) and Md(oid) - final definition ) . . . . . . . . .
39
Definition 20: ( Object - final definition II ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
44
Definition 21: ( Basic message handler ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
45
Definition 22: ( Notation of semantic relationships ) . . . . . . . . . . . . . . . . . . . . . . . . .
51
Definition 23: ( Method inheritance via a semantic relationship ) . . . . . . . . . . . . . . .
52
Definition 24: ( Extended message handler ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
54
Definition 25: ( Database Schema ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
57
Definition 26: ( Role specialization of a single class ) . . . . . . . . . . . . . . . . . . . . . . . .
85
Definition 27: ( Category specialization ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
91
Definition 28: ( Aggregation ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
98
Definition 29: ( Components ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
103
Definition 30: ( Role-specialized components ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
109
Appendix E: Table of Figures Figure 1.1:
Metaclasses allow to tailor the data model for specific needs . . . . . . . .
Figure 3.1:
Examples of well-formed type expressions . . . . . . . . . . . . . . . . . . . . .
17
Figure 3.2:
Syntax for the definition of types . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
Figure 3.3:
Example of an object type definition and its implementation . . . . . . . .
21
Figure 3.4:
Syntax for the preliminary class definition . . . . . . . . . . . . . . . . . . . . . .
27
Figure 3.5:
Example of class definitions with a type-to-class mapping specification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
Example for the determination of the sets Ixl and M d for individual objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
29
Example of the determination of pd and M d of an object with an own-type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
34
Figure 3.8:
The general scheme of determining an objects structure and behavior.
40
Figure 3.9:
Syntax for the class definition statement . . . . . . . . . . . . . . . . . . . . . . .
41
Figure 3.6:
Figure 3.7:
5
Figure 3.10: Effect of property specifications with an instance-instance-type. . . . . .
42
Figure 3.11: Effect of property specifications with supertypes . . . . . . . . . . . . . . . . .
43
Figure 3.12: Dispatch tables for the determination of method bodies . . . . . . . . . . . .
45
Figure 3.13: Different roles modelled as separate classes . . . . . . . . . . . . . . . . . . . . .
49
IR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
52
Figure 3.15: If~ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
53
Figure 3.16: Class definitions including the definitions of the object types . . . . . . .
56
Figure 3.17: The conceptual parts of a database schema . . . . . . . . . . . . . . . . . . . . . .
57
Figure 3.18: The definitions of the initial predefined metaclasses . . . . . . . . . . . . . .
58
Figure 3.19: The initial metaclass system of VML . . . . . . . . . . . . . . . . . . . . . . . . . .
59
Figure 3.20: The initial subtype hierarchy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
60
Figure 3.21: Definition of the type VML--Object_Type . . . . . . . . . . . . . . . . . . . . . .
61
Figure 3.22: Definition of the types VML-Class_InstType and VML-Class_InstInstType . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
Figure 3.14:
Figure 3.23: Definition of Metaclass_InstType, Metaclass_InstlnstType, KernelApplicationClass__InstType, KernelApplicationClass_InstlnstType . . . . . . . . . 63 Figure 3.24: The effects of the initial metaclass system . . . . . . . . . . . . . . . . . . . . . .
64
Figure 3.25: Alternatives of the instantiation hierarchy of classes . . . . . . . . . . . . . . .
66
197
Figure 3.26: Using metaclasses to specify the common behavior of classes . . . . . . .
68
Figure 3.27: Using metaclasses to specify common behavior for instances of different classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 Figure 3.28: Using metaclasses to specify common behavior for classes and their instances . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
70
Figure4.1:
Category specialized classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
72
Figure4.2:
Role specialized classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
73
Figure4.3:
Aggregation classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
75
Figure4.4:
Role specialized class as component . . . . . . . . . . . . . . . . . . . . . . . . . . .
77
Figure 4.5:
Sample order database of a company . . . . . . . . . . . . . . . . . . . . . . . . . . .
78
Figure4.6:
Example of an adopted Toulmin argumentation schema [SHT89] . . . .
79
Figure5.1:
Defining semantic relationships through a single metaclass . . . . . . . . .
83
Figure5.2:
Defining semantic relationships through multiple metaclasses . . . . . .
84
Figure5.3:
Irolespec . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
86
Figure5.4:
Relationships between role specialized classes and between the metaclasses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
86
Figure5.5:
Definition of the metaclass SINGLETON-CLASS
87
Figure5.6:
Definition of the metaclass ROLE-SPECIALIZATION-CLASS . . . . .
87
Figure 5.7a:
Specification of the instance-type RoleSpec_InstType . . . . . . . . . . . . .
88
...............
Figure 5.7b: Specification of the instance-instance-type RoleSpec_InstlnstType ..
89
Figure5.8:
Definition of a class as instance of the metaclass for role specialization
90
Figure 5.9:
Method inheritance via the role specialization relationship . . . . . . . . . .
91
Figure 5.10: Icatspec . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Figure 5.11:
Relationships between category specialized classes and the metaclasses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
92 92
Figure 5.12: Definition of SINGLETON-CLASS and CATEGORY-SPECIALIZATIONCLASS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 Figure5.13:
Extensions of the instance-type and the instance-instance-type of the metaclass SINGLETON-CLASS for general category objects . . . . . . . . . . 94
Figure 5.14a: Definition of the instance-type CategorySpec_InstType . . . . . . . . . . .
95
Figure 5.14b: Definition of the instance-instance-type CategorySpec_InstlnstType .
96
Figure 5.15: Definition of some category specialized application classes . . . . . . . .
97
Figure 5.16: Example of processing category specialized objects . . . . . . . . . . . . . .
97
198
Figure 5.17: Relationships between aggregate and constituent classes and the metaclasses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
99
Figure 5.18:
Specification of the metaclass AGGREGATION--CLASS . . . . . . . . . .
99
Figure 5.19:
Specification of the instance-instance-type of the metaclass AGGREGATION-CLAS S ............................................ 100
Figure 5.20: Specification of the instance-type and instance-instance-type of the metaclass AGGREGATION-CLASS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 Figure 5.21: Extension of the instance-instance-type of the metaclass SINGLETONCLASS for constituents of aggregations . . . . . . . . . . . . . . . . . . . . . . . . 102 Figure 5.22: Specification of aggregation classes and their constituent classes . . . .
103
Figure 5.23: Relationships between component classes and metaclasses . . . . . . . . .
104
Figure 5.24:
Specification of the metaclass C O M P - C L A S S . . . . . . . . . . . . . . . . . . .
104
Figure 5.25:
Specification of the instance-instance-type of the metaclass COMP-CLASS ...........................................
105
Figure 5.26: Specification of the instance-instance-type of the metaclass COMP--CLASS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
105
Figure 5.27: Extensions of the instance-type of the metaclass SINGLETON-CLASS for classes which may have component classes . . . . . . . . . . . . . . . . . . . . . 106 Figure 5.28: Extension of the instance-instance-type of the metaclass SINGLETONCLASS for objects which may have components . . . . . . . . . . . . . . . . . 107 Figure 5.29: Specification of a component class and some sample messages . . . . . Figure 5.30:
IroleCompOf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
108 109
Figure 5.31: Relationships between role-specialized component classes and metaclasses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
110
Figure 5.32: Specification of the metaclass ROLE-SPEC-COMP-CLASS . . . . . . .
110
Figure 5.33: Specification of the object types of the metaclass ROLE-SPEC-COMPCLASS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 Figure 5.34: Specification of a role-specialized component class and sample messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
112
Figure 5.35: Fragments of object type definitions with simple cost methods . . . . . .
113
Figure 5.36: Sample messages computing the cost of any kind of parts . . . . . . . . . .
114
Figure 5.37: Example of role-specialized components of parts . . . . . . . . . . . . . . . .
114
Figure 5.38: Object types for metaclasses providing node semantics . . . . . . . . . . . .
116
Figure 5.39:
117
Object types for metaclasses providing link semantics . . . . . . . . . . . . .
199
Figure 5.40: Metaclasses TOULMIN-NODE-CLASS and TOULMIN-LINK-CLASS, ROLE-SPEC-TOULMIN-NODE-CLASS . . . . . . . . . . . . . . . . . . . . . .
118
Figure 5.41: Object type used to specify the contents of a node . . . . . . . . . . . . . . . .
119
Figure 5.42: Instance-type of class CLAIM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
119
Figure 5.43: Instance-type of class DATUM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
120
Figure 5.44: Database schema for a sample Toulmin schema . . . . . . . . . . . . . . . . . .
121
Figure 5.45: Sample Toulmin schema and some sample statements . . . . . . . . . . . . .
122
Figure 6.1:
Object class OIL-PLANT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
124
Figure 6.2:
Object class COAL-PLANT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
124
Figure 6.3:
Power plants as union of oil and coal plants
125
Figure 6.4:
Object class definition by generalization . . . . . . . . . . . . . . . . . . . . . . .
125
Figure 6.5:
Integration of data type classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
128
Figure 6.6:
Role-related object classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
132
Figure 6.7:
Counterpart-related object-classes . . . . . . . . . . . . . . . . . . . . . . . . . . . .
133
Figure 6.8:
Generalization of counterpart-related object classes . . . . . . . . . . . . . . .
137
Figure 6.9:
Generalization of role-related object classes . . . . . . . . . . . . . . . . . . . . .
137
....................
Figure 6.10: Integration of relationships . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
145
Figure 6.11: Class OIL-PLANT with relationship "Ownership" . . . . . . . . . . . . . . .
145
Figure 6.12: Class COAL-PLANT with relationship "OwnedBy". . . . . . . . . . . . . .
146
Figure 6.13: Conversion between data values and abstract objects . . . . . . . . . . . . . .
147
Figure 6.14: "Normalized" database design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
148
Figure 7.1:
Figure 7.2:
Definition of the object types LocalClass_InstType and LocalClass_lnstlnstType . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Definition of the object types ObjectClass_InstType and ObjectClass_InstlnstType . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Figure 7.3:
151
152
Definition of the object types LocalClass_InstType and LocalClass_lnstlnstType . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
153
Definition of the object types LocalClass_InstType and LocalClass_InstlnstType . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
153
Figure 7.5:
Definition of the metaclass LOCAL-OBJECT-CLASS . . . . . . . . . . . .
154
Figure 7.6:
Definition of the metaclass LOCAL-DATATYPE-CLASS . . . . . . . . .
154
Figure 7.7:
Definition of the object type GenClass InstType . . . . . . . . . . . . . . . . .
155
Figure 7.8:
Definition of the object type GenClass InstlnstType . . . . . . . . . . . . . .
155
Figure 7.4:
200
Figure 7.9:
Definition of the object type ObjectGenClass_InstType . . . . . . . . . . . .
156
Figure 7.10: Implementation of the object type ObjectGenClass_InstType . . . . . . .
157
Figure 7.11: Definition of the object type ObjectGenClass_InstlnstType . . . . . . . . .
158
Figure 7.12: Definition of the metaclass CATEGORY-GENERALIZATIONCLASS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
159
Figure 7.13: Definition of the object type CatGen InstType . . . . . . . . . . . . . . . . . .
160
Figure 7.14: Definition of the object type CatGen_InstlnstType . . . . . . . . . . . . . . .
161
Figure 7.15: Definition of the metaclass ROLE-GENERALIZATION-CLASS . . . .
161
Figure 7.16: Definition of the object type RoleGen_InstType . . . . . . . . . . . . . . . . .
162
Figure 7.17: Implementation of the object type RoleGen_InstType . . . . . . . . . . . . .
163
Figure 7.18: Implementation of the object type RoleGen_InstType . . . . . . . . . . . . .
164
Figure 7.19: Definition of the object type RoleGen_InstlnstType . . . . . . . . . . . . . .
164
Figure 7.20: Implementation of the object type RoleGen_InstlnstType . . . . . . . . . .
165
Figure 7.21: Definition of the metaclass DATATYPE-GEN-CLASS . . . . . . . . . . . .
166
Figure 7.22: Definition and Implementation of the object type DataTypeGen_InstType . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
167
Figure 7.23: Definition and Implementation of the object type DataTypeGen_InstlnstType . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
167
Figure 7.24: Definition of the class COLORED-OBJECTS . . . . . . . . . . . . . . . . . . .
168
Figure 7.25: Definition and lmplementation of the object type ColObj_InstType ..
169
Figure 7.26: Definition and Implementation of the object type ColObj_InstType ..
170
Figure 8.1:
174
The class architecture of Smalltalk-80 . . . . . . . . . . . . . . . . . . . . . . . . .
Appendix F: Tables Table 6.1:
Possible semantic relationships between two attributes/methods o f two objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
Table 6.2:
Methods to change between object identifiers . . . . . . . . . . . . . . . . . . . . .
140
Lecture Notes in Computer Science For information about Vols. 1-865 please contact your bookseller or Springer-Verlag
Vo1. 866: Y. Davidor, H.-P. Schwefel, R. Manner (Eds.), Parallel Problem Solving from Nature - PPSN III. Proceedings, 1994. XV, 642 pages. 1994.
Vol. 883: L. Fribourg, F. Turini (Eds.), Logic Program Synthesis and Transformation - Meta-Programming in Logic. Proceedings, 1994. IX, 451 pages, t994.
Vol 867: L. Steels, G. Schreiber, W. Van de Velde (Eds.), A Future for Knowledge Acquisition. Proceedings, 1994. XII, 414 pages. 1994. (Subseries LNAI).
Vol. 884: J. Nievergelt, T. Roos, H.-J. Schek, P. Widmayer (Eds.), IGIS '94: Geographic Information Systems. Proceedings, 1994. VIII, 292 pages. 19944.
Vol. 868: R. Steinmetz (Ed.), Multimedia: Advanced Teleservices and H i g h - S p e e d C o m m u n i c a t i o n Architectures. Proceedings, 1994. IX, 451 pages. 1994.
Vol. 885: R. C. Vehkamp, Closed Objects Boundaries from Scattered Points. VIII, 144 pages. 1994.
Vol. 869: Z. W, Rag, Zemankova (Eds.), Methodologies for Intelligent Systems. Proceedings, 1994. X, 613 pages. 1994. (Subseries LNAI). Vol. 870: J. S. Greenfield, Distributed Programming Paradigms with Cryptography Applications. XI, 182 pages. 1994. Vol. 871: J. P. Lee, G. G. Grinstein (Eds.), Database Issues for Data Visualization. Proceedings, 1993. XIV, 229 pages. 1994. Vol. 872: S Arikawa, K. P. Jantke (Eds.), Algorithmic Learning Theory. Proceedings, 1994. XIV, 575 pages. 1994.
Vol. 886: M. M. Veloso, Planning and Learning by Analogical Reasoning. XIlI, 181 pages. 1994. (Subseries LNA1). Vol. 887: M. Toussaint (Ed.), Ada in Europe. Proceedings, 1994. XII, 521 pages. 1994. Vol. 888: S. A. Andersson (Ed.), Analysis of Dynamical and Cognitive Systems. Proceedings, I993. VII, 260 pages. 1995. Vol. 889: H. P. Lnbich, Towards a CSCW Framework for Scientific Cooperation in Europe. X, 268 pages. 1995. Vol. 890: M. J. Wooldridge, N. R. Jennings (Eds.), Intelligent Agents. Proceedings, 1994. VIII, 407 pages. 1995. (Subseries LNAI).
Vot. 873: M. NaftaIin, T. Denvir, M. Bertran (Eds.), FME '94: Industrial Benefit of Formal Methods. Proceedings, 1994. XI, 723 pages. 1994.
Vol. 891: C. Lewerentz, T. Lindner (Eds.), Formal Development of Reactive Systems. XI, 394 pages. 1995.
Vol. 874: A. Borning (Ed.), Principles and Practice of Constraint Programming. Proceedings, 1994. IX, 361 pages. 1994.
Vol. 892: K. Pingali, U. Banerjec, D. Gelernter, A. Nicolau, D. Padua (Eds.), Languages and Compilers for Parallel Computing. Proceedings, 1994. XI, 496 pages. 1995.
Vol. 875: D. G o l l m a n n (Ed.), C o m p u t e r Security ESORICS 94. Proceedings, 1994. X1,469 pages. 1994. Vol. 876: B. Blumenthal, J. Gornostaev, C. Unger (Eds.), Human-Computer Interaction. Proceedings, 1994. IX, 239 pages. 1994. Vnl. 877: L. M. Adleman, M.-D. Huang (Eds.), Algorithmic Number Theory. Proceedings, 1994. IX, 323 pages. 1994. Vol. 878: T. lshida; Parallel, Distributed and Multiagent Production Systems. XVII, 166 pages. 1994. (Subseries LNA1). Vol. 879: J. Dongarra, J. Wa~niewski (Eds.), Parallel Scientific Computing. Proceedings, 1994. XI, 566 pages. 1994. Vol. 880: P. S~ Thiagarajan (Ed.), Foundations of Software Technology and Theoretical Computer Science. Proceedings, 1994. X|, 451 pages. 1994. Vol. 881 : P. Loucopoulos (Ed.), Entity-Relationship Approach - E R ' 9 4 . Proceedings, 1994. XIII, 579 pages. 1994. Vol. 882: D. Hutchison, A. Danthine, H. Leopold, G. Coulson (Eds.), Multimedia Transport and Teleservices. Proceedings, 1994. XI, 380 pages. 1994.
Vol. 893: G. Gottlob, M. Y. Vardi (Eds.), Database T h e o r y - ICDT '95. Proceedings, 1995~ XI, 454 pages. 1995. Vol. 894: R. Tamassia, 1. G. Tollis (Eds.), Graph Drawing. Proceedings, 1994. X, 471 pages. 1995. Vol. 895: R. L. Ibrahim (Ed.), Software Engineering Education. Proceedings, 1995. XI1, 449 pages. 1995. Vol. 896: R. N. Taylor, I. Coutaz (Eds.), Software Engineering and Human-Computer Interaction. Proceedings, 1994. X, 281 pages. 1995. Vol. 897: M. Fisher, R. Owens (Eds.), Executable Modal and Temporal Logics. Proceedings, 1993. VII, 180 pages. 1995. (Subseries LNAI). Vol. 898: P. Steffens (Ed.), Machine Translation and the L e x i c o n . P r o c e e d i n g s , 1993. X, 251 pages. 1995. (Subseries LNAI). Vol. 899: W. Banzhaf, F. H. Eeckman (Eds.), Evolution and Biocomputation. VII, 277 pages, t995. Vol. 900: E. W. Mayr, C. Puech (Eds.), STACS 95. Proceedings, 1995. XIll, 654 pages. 1995.
Vol. 901 : R. Kumar, T. Kropf (Eds.), Theorem Provers in Circuit Design. Proceedings, 1994. VIII, 303 pages. 1995.
Vol. 922: H. DSrr, Efficient Graph Rewriting and Its Implementation. IX, 266 pages. 1995.
Vol. 902: M. Dezani-Ciancaglini,G. Plotkin (eds.), Typed Lambda Calculi and Applications. Proceedings, 1995. VIII, 443 pages. 1995 Vol. 903: E. W. Mayr, G. Schmidt, G. Tinhofer (Eds.), Graph-Theoretic Concepts in Computer Science. Proceedings, 1994. IX, 414 pages. 1995.
Vol. 923: M. Meyer (Ed.), Constraint Processing. IV, 289 pages. 1995.
Vol. 904: P. Vit~inyi (Ed.), Computational Learning Theory. EuroCOLT'95. Proceedings, 1995. XVII, 415 pages. 1995. (Subseries LNAI). Vol. 905: N. Ayache (Ed.), Computer Vision, Virtual Reality and Robotics in Medicine. Proceedings, 1995. XIV, 567 pages. 1995. Vol. 906: E. Astesiano, G. Reggio, A. Tarlecki (Eds.), Recent Trends in Data Type Specification. Proceedings, 1995. VIII, 523 pages. 1995.
Vol. 924: P. Ciancarini, O. Nierstrasz, A. Yonezawa (Eds.), Object-Based Models and Languages for Concurrent Systems. Proceedings, 1994. VII, 193 pages. 1995. Vol. 925: J. Jeuring, E. Meijer (Eds.), Advanced Functional Programming. Proceedings, 1995. VII, 331 pages. 1995. Vol. 926: P. Nesi (Ed.), Objective Software Quality. Proceedings, 1995. VIII, 249 pages. 1995. Vol. 927: J. Dix, L. Moniz Pereira, T. C. Przymusinski (Eds.), Non-Monotonic Extensions of Logic Programming. Proceedings, 1994. IX, 229 pages. 1995. (Subseries LNAI).
Vol. 907: T. Ito, A. Yonezawa (Eds.), Theory and Practice of Parallel Programming. proceedings, 1995. VIII, 485 pages. 1995.
Vol. 928: V.W. Marek, A. Nerode, M. Truszezynski (Eds.), Logic Programming and Nonmonotonic Reasoning. Proceedings, 1995. VIII, 4t7 pages. 1995. (Subseries LNAI).
Vol. 908: J. R. Rao Extensions of the UNITY Methodology: Compositionality, Fairness and Probability in Parallelism. XI, 178 pages. 1995.
Vol. 929: F. Mor~in, A. Moreno, J.J. Merelo, P. Chac6n (Eds.), Advances in Artificial Life. Proceedings, 1995. XIII, 960 pages. 1995 (Subseries LNAI).
Vol. 909: H. Comon, J.-P. Jouannaud (Eds.), Term Rewriting. Proceedings, 1993. VIII, 221 pages. 1995.
Vol. 930: J. Mira, F. Sandoval (Eds.), From Natural to Artificial Neural Computation. Proceedings, 1995. XVIII, 1150 pages. 1995.
Vol. 910: A. Podelski (Ed.), Constraint Programming: Basics and Trends. Proceedings, 1995. XI, 315 pages. 1995. Vol. 911: R. Baeza-Yates, E. Goles, P. V. Poblete (Eds.), LATIN '95: Theoretical Informatics. Proceedings, 1995. IX, 525 pages. 1995. Vol. 912: N. Lavrac, S. Wrobel (Eds.), Machine Learning: ECML - 95. Proceedings, 1995. XI, 370 pages. 1995. (Subseries LNAI). Vol. 913: W. Sch~ifer (Ed.), Software Process Technology. Proceedings, 1995. IX, 26l pages. 1995. Vol. 914: J. Hsiang (Ed.), Rewriting Techniques and Applications. Proceedings, 1995. XII, 473 pages. 1995. Vol. 915: P. D. Mosses, M. Nielsen, M. I. Schwartzbach (Eds.), TAPSOFT '95: Theory and Practice of Software Development. Proceedings, 1995. XV, 810 pages. 1995. Vol. 916: N. R. Adam, B. K. Bhargava, Y. Yesha (Eds.), Digital Libraries. Proceedings, 1994. XIII, 321 pages. 1995. Vol. 917: J. Pieprzyk, R. Safavi-Naini (Eds.), Advances in Cryptology - ASIACRYPT '94. Proceedings, 1994. XII, 431 pages. 1995. Vol. 918: P. Baumgartner, R. H~ihnle, J. Posegga (Eds.), Theorem Proving with Analytic Tableaux and Related Methods. Proceedings, 1995. X, 352 pages. 1995. (Subseries LNA1). Vol. 919: B. Hertzberger, G. Serazzi (Eds.), High-Performance Computing and Networking. Proceedings, 1995. XXIV, 957 pages. 1995. VoI. 920: E. Balas, J. Clausen (Eds.), Integer Programming and Combinatorial Optimization. Proceedings, 1995. IX, 436 pages. 1995. Vol. 921: L. C. Guillou, J.-J. Quisquater (Eds.), Advances in Cryptology - EUROCRYPT '95. Proceedings, 1995. XIV, 417 pages. 1995.
Vol. 931: P.J. Braspenning, F. Thuijsman, A.J.M.M. Weijters (Eds.), Artificial Neural Networks. IX, 295 pages. 1995. Vol. 932: J. Iivari, K. Lyytinen, M. Rossi (Eds.), Advanced Information Systems Engineering. Proceedings, 1995. XI, 388 pages. 1995. Vol. 933: L. Pacholski, J. Tiuryn (Eds.), Computer Science Logic. Proceedings, 1994. IX, 543 pages. 1995. Vol. 934: P. Barahona, M. Stefanelli, J. Wyatt (Eds.), Artificial Intelligence in Medicine. Proceedings, 1995. XI, 449 pages. 1995. (Subseries LNAI). Vol. 935: G. De Michelis, M. Diaz (Eds.), Application and Theory of Petri Nets 1995. Proceedings, 1995. VIII, 511 pages. 1995. Vol. 936: V.S. Alagar, M. Nivat (Eds.), Algebraic Methodology and Software Technology. Proceedings, 1995. XIV, 591 pages. 1995. Vol. 937: Z. Galil, E. Ukkonen (Eds.), Combinatorial Pattern Matching. Proceedings, 1995. VIII, 409 pages. 1995. Vol. 938: K.P. Birman, F. Mattern, A. Schiper (Eds.), Theory and Practice in Distributed Systems. Proceedings, 1994. X, 263 pages. 1995. Vol. 939: P. Wolper (Ed.), Computer Aided Verification. Proceedings, 1995. X, 451 pages. 1995. Vol. 941: M. Cadoli, Tractable Reasoning in Artificial Intelligence. XVII, 247 pages. 1995. (Subseries LNAI). Vol. 942: G. B/~ckle, Exploitation of Fine-Grain Parallelism. IX, 188 pages. 1995. Vol. 943: W. Klas, M. Schrefl, Metaclasses and Their Application. IX, 201 pages. 1995.