\dlpindex{overview}
The constructs that we have explored in previous sections
are part of the language DLP,
a language for distributed logic programming,
that has been the result of the research reported
in this book.
In this section we provide an overview
of the language DLP.
In the next section
we will isolate the subsets of DLP
chosen for studying the semantics of the language.
Declarations
\label{des/dlp:decl}
A DLP program consists of a number of object declarations.
The clauses occurring in the object declarations may contain
special statements for updating non-logical (instance)
variables, for creating objects and for communicating with
other objects.
An object declaration is of the form
object name {
use objects.
var variables.
clauses
}
Among the clauses may be constructor clauses,
that enable to create active instances of an object.
The clauses of an object act as methods, in that they have exclusive
access to the non-logical variables of an object.
Clauses are ordinary Prolog clauses,
except for the possible occurrence of special forms
by which DLP extends Prolog.
Inheritance
of the non-logical variables of objects
is achieved by including the declaration
isa objects
in the object declaration.
The declared object then contains a copy of all the
non-logical variables of the objects
mentioned in the isa list.
Clauses are inherited from objects by including the declaration
use objects
The declared object then adds the clauses of the objects mentioned
in the use list to its own clauses.
A declaration of the form
object a:b { }
must be read as
object a {
isa b.
use b.
}
Inheritance is static.
It is effected before an object starts to evaluate a goal.
In other words, there is no interaction between
objects, except on the occasion of an explicit communication.\ftn{
See chapter \ref{des/know} for a more precise characterization
of inheritance, and the resolution of possible name conflicts.
}
Statements
\label{des/dlp:stat}
The core of DLP consists of the special forms
- --- to assign (the value of) the term t
to the non-logical variable v
- --- to create an active instance of the object c
- --- to call the method for the object O
- --- to state the willingness to accept methods
These are the extensions that play a prominent role
in part [sem],
treating the semantics of DLP.
Moreover, the constructs listed above are sufficient to
solve most of the knowledge representation problems
presented in chapter \ref{des/know}.
Channels
In addition, however, we have special forms that allow to communicate over
channels.
- --- to create a new channel
- --- to put output term t on channel C
- --- to put t as an input term on channel C
Conditional acceptance
Apart from the regular accept statement we have introduced
a generalized accept statement, that may contain
conditional accept expressions of the form
that result in the goal being evaluated,
if the method template matches the call
and moreover the guard holds. (C.f. section \ref{des/ext/accept})
Process creation and resumptions
For those wishing to squeeze out the last drop of
parallelism
we have included the primitives
- --- to create a process to evaluate G
- --- to ask for the results of process Q
These are the primitives that have been used
to implement the synchronous rendez-vous as
O!G :- Q = O!G, Q?.
Allocation
Lastly, since effective parallelism requires some strategy
of allocating resources
we have provided node-expressions
that can be used to allocate an object or a process, evaluating
a goal.
The special forms
where obj is either an object name or a constructor,
respectively allocate an object or a goal at the processor
node denoted by N.
Remarks
Since we have striven for full compatibility with Prolog,
we have retained the backtracking behavior to the extent possible.
We support both local backtracking, that occurs within
the confines of a process,
and global (or distributed) backtracking in which
multiple processes are involved.
We have made a distinction between active objects, which have
own activity that must explicitly be interrupted to
answer method calls; and passive objects that may answer a method
any time.
Active objects are allowed to have a limited amount of internal
concurrency, in that multiple processes may be active
backtracking over the results of a method call.
Passive objects, on the other hand, display full internal
concurrency.
Method calls may be evaluated concurrently.
Providing the needed protection
is in this case the duty of the programmer.