/*****************************************************************************/
/** Chris MOSS, Imperial College -- format: plain text                      **/
/*****************************************************************************/

 
Object-Oriented Logic Programming
 
by Chris Moss,
 
Imperial College, London
 
What is the fundamental aim of combining object-oriented programming techniques
with logic programming? If one looks at the majority of papers presented at
conferences and even the systems on the market, one might well come to
conclusion that somehow the assignment statement has to be introduced into
Prolog and this is the best way to do it!
 
I would like to suggest that the primary benefit of object-oriented techniques
is towards the structuring of large and extensible programs. This is why
object-oriented programming is currently a vogue term in the market place, and
it applies as much to Prolog as to any other programming language. If we lose
sight of this fact then our concerns with objects can end in us losing the
distinctive benefits of Prolog.
 
Prolog has proved itself as an excellent vehicle for expressing programs in the
small. The combination of unification for pattern matching and flexible
allocation of data structures with backtracking for expressing
non-deterministic specifications provide capabilities that are not found in
other paradigms. The basis of Prolog in a subset of logic which is
comprehensible and well-founded theoretically gives it a firm foundation. On
this can be based declarative program development tools, including
transformation and debugging techniques, which further add to productivity.
 
But Prolog has had considerable difficulty "scaling up". One evidence of this
is the difficulty the Prolog standardization process has had in coming to
mutually acceptable definition of a module. Everyone agrees that modules are
desirable and even necessary for any modern programming language. But when one
lays out a module definition in detail, arguments arise, mostly concerning
dynamic behaviour, which seem marginal at first but quickly become critical and
insoluble. Most Prolog systems have modules of one form or another, but apart
from the common factor of hiding local definitions they differ considerably in
the details of what is allowed or not allowed.
 
An object definition can be seen as an implementation of a modular architecture
for programs. In languages like Simula and Smalltalk, which have been
constructed from the start on object-oriented lines, they are the primary tool
for modularization. In other languages such as C++ and CLOS where objects have
been added after other facilities for modularization (e.g. packages in Common
Lisp), the correspondence is not so clear cut.
 
Unfortunately logic gives us no guidance at all about modularization. Why this
is so might be an interesting study, but we need to look elsewhere for
inspiration. One candidate was the "multiple worlds" paradigm pioneered in
Prolog II, but this has not proved popular. Objects have a lot more potential.
The primary problem in introducing objects is that the notion of object is
composite, with a number of separate features which happen to combine well in
practice. There are no strict boundaries on the idea and what one approach
considers central is considered marginal by others.
 
There are three central notions to object-oriented programming from which most
of the implementation decisions flow: encapsulation, inheritance and
concurrency.
 
Encapsulation focusses the notion of modularity around the idea of abstract
data type (see Liskov 87). This notion, well-developed in computer science, is
already halfway towards object-oriented programming. Experience has taught that
the operations on a particular data type form the basic organizing tool for
larger projects: the operations are logically connected, need access to the
internal representation and can be isolated effectively.
 
By itself encapsulation can be too effective. What someone else encapsulates is
rarely precisely what is needed for the next task. Inheritance provides the
elastic glue for binding together objects in an intuitively natural way.
Taxonomies are central to most forms of knowledge representation and the
inheritance method of Simula and Smalltalk has provided the key to adding them
to programming. It is trivial to express taxonomies in Prolog, but this does
not in itself provide the capability that is needed. One needs the extra layer
that objects provide.
 
The third ingredient of the OO paradigm is more difficult to isolate. It is
most clearly shown in Hewitt's (1977) Actors paradigm: objects are autonomous
and self organizing entities which communicate with each other. In other words,
objects can change independently of each other, or exhibit concurrency. It is
therefore not surprising that the most convincing account of this to appear in
the logic programming literature uses Concurrent Prolog (Shapiro, Takeuchi,
1983). To represent change declaratively requires messages exchanged between
different processes which keep local state privately using recursive
procedures. This is perhaps the best example of where the left-to-right
evaluation rule of Prolog lets us down. We need coroutining to be able to
represent localized change declaratively.
 
There is of course another way of handling conceptual concurrency, which is
used by almost all the current crop of OO languages: the assignment statement.
This is not remarkable for most imperative programming languages, but it does
exhibit itself at a global level in an interesting way. It becomes an
acceptable design technique to break down the manipulation of an object into a
number of small changes to that object, of which the object itself keeps track
(see e.g. Meyer 1988). Thus change is captured not at the micro-level of the
individual machine instruction or individual routine within an object but at
the overall level of the consistent states of an object. This is a use of
assignment which is more acceptable in a Prolog context, reflecting the way in
which assignment is used by experienced programmers to record the results of
major stages of a computation.
 
Given these three central concerns of object-oriented programming, one strategy
for combining the two paradigms is obvious. It corresponds to the technique
used widely in languages such as Object Pascal and Objective C: make objects
into an extra layer on top of the basic computer language but not interfering
with it (see e.g. Cox 1986). This incurs some performance penalties but is
another example of modular design which has its advantages also: the compiler
writer can concentrate on optimising the small-scale steps and the object
language translator on the larger scale.
 
This is the strategy adopted by most Prolog suppliers today, most of which are,
broadly speaking, based on the lead of Zaniolo (1984) and preserve the
distinctive features of Prolog, such as unification and multiple solutions. A
list of the major distributed OOLP products available, together with their host
systems, is shown below. In addition to these, many other suppliers provide
partial object systems for handling user interfaces.
 
Product Host    System Supplier
Emicat  Delphia Prolog  Delphia, France
LAP    Quintus Prolog  ELSA, France
Prolog++      LPA Prolog(s)   LPA, U.K.
Prolog Workbench    IBM Prolog  IBM, France
Object-Prolog   Quintec Prolog  Quintec, U.K.
SPIRAL  (internal)  CRIL, France
STEP    Strand-88   Strand, U.K.
 
Some of these systems were developed for specific customer's requirements (e.g.
Emicat was produced by Electroniqe Serge Dessault for the French atomic energy
authority) and none have as yet received widespread use. The reason for this is
probably mainly because the approach is still inadequately recognized and the
reasons for adding objects to Prolog misunderstood. If the approach outlined
here is the right one, then these products deserve to be reviewed in this light
and given more attention.
 
At some point there needs to be an appraisal of which OO features are
successful and which are not so important. It's important not to standardize
this type of development too early as there is no definitive basis on which to
do so: we should give competitive forces time to work. The fact that modules
have not been incorporated into the Prolog standard will probably be seen in
the future as a blessing (though there is still pressure to include them;
pressure which will, I hope, be resisted). However it may be that the market
will not take off without some agreement: for instance on the syntax of object
declaration and use, or on the basic functionality of an object system.
Here is a partial list of the features which these systems offer which shows
the issues that need to be agreed.
 
    multiple inheritance
    methods and messages
    polymorphism
    classes
    exception handling
    overloading
    dynamic binding
    attributes
    assignment
 
A Question:
 
There is one major challenge which faces these schemes. If parallel
implementations of Prolog provide a better declarative model for change than
the assignment statement, then encouraging the use of assignment, even in a
localized form, is a backward step which might hinder the introduction of true
parallelism. The answer to this is close at hand but has not yet been explored,
as far as I know: the coroutining facilities offered by Prolog II, NU-Prolog
etc. are capable of emulating the type of concurrency used in conccurrent
Prologs. Is this a practical approach, and has anyone tried it?
 
Conclusion:
 
If we recognize that the basic aim of introducing objects is to structure large
logic programs, then we can concentrate on building those facilities into
object-oriented Prolog systems which enhance this aim. Pure functionality in
other directions is less important.
 
-----------------------
 
Dr. Chris Moss.
 
Current Address: 3 rue Comte de Ferraris, L1518, Luxembourg.
Tel & Fax: +352 431809
Email: Bel0172@applelink.apple.com or cdsm@crpculu.uucp
 
References:
 
B. Cox (1986): Object-oriented Programming, An Evolutionary Approach.
Addison-Wesley.
 
C. Hewitt (1977) Viewing Control Structures as Patterns of Passing Messages.
Artificial Intelligence.
 
B. Liskov (1987) Data Abstraction and Hierarchy. OOPSLA 87. Addendum to
Proceedings.
 
B. Meyer (1988): Object-oriented software construction. Prentice-Hall.
 
E.Y. Shapiro,  A. Takeuchi (1983): Object Oriented Programming in Concurrent
Prolog. New Generation Computing, Vol 1, pp25-48.
 
C. Zaniolo (1984): Object-Oriented Programming in Prolog. Proc. International
Symposium on Logic Programming, Atlantic City.
