Communication over channels The idea originally proposed in  [ST83], to implement object oriented programming by continuously running processes receiving a stream of messages, has been a starting point for a number of object oriented extensions of Concurrent Prolog and Parlog. Cf.  [Da89]. A similar idea is embodied in Delta Prolog.  [PN84] Our proposal resembles the one given in  [PN84], although there are some important differences. Before going into details we will present the language constructs involved. First of all we need a facility to create processes. We will use a goal of the form to create an active instance of the object c.\n For creating new channels we use a goal of the form to the logical variable C.\n Further we need, what we call an output statement of the form for C referring to a channel and t an arbitrary term.\n Also, still following CSP terminology, we need an input statement of the form where C is assumed to refer to a channel and t an arbitrary term. We will characterize the semantics of communication over channels by giving a simple example, adapted from  [PN84], but originally given in  [ST83]. Assume that we wish to implement a counter, that allows us to ask for its value and to increment its value. Clearly we must have some means to store the state of the object, and also some means to send it the corresponding messages. With the constructs introduced, our implementation looks as follows. XX The first clause encountered is the constructor for an instance of ctr. The argument C is assumed to be referring to a channel. Evaluating the constructor results in calling run(C,0), initializing the (logical) state variable holding the value of the counter to zero. The remaining two clauses define the body of the object. The first clause contains the input statement C?value(N) that is used to answer requests for the value of the counter. The second clause contains the input statement C?inc() that is used to increment the value of the counter. The actual value of the counter is maintained in a proper way by passing it as an argument to the tail-recursive call to run. A typical example of the use of such a counter is the goal XX that effects the binding of X to one. The example given illustrates the use of such objects to implement server processes. Let us now give a more detailed description of the semantics of communication over channels. Communication over channels is synchronous, in that either side waits until there is a complementary communication intention for that channel. For the example above this means that the body of the counter will stick to the gola C?value(N) until the user process reaches C!inc(), or reversely the goal C!inc() must wait until C?value(N) is reached. We call a communication successful if the term at the input side, or more briefly the input term, is unifiable with the output term, the term at the output side. When these terms do not unify, as is the case for inc() and value(N), the input side is allowed to backtrack until it finds another input statement for that channel and the procedure is repeated.. As long as the input side is backtracking the output side waits with its request to communicate. The assymetry with respect to backtracking is sufficiently motivated by the example above. We must remark however that Delta Prolog adopted a communication mechanism that is symmetric in its backtracking behavior, and rather complex to our mind. We stress the fact that both in Delta-prolog and in our proposal communication over channels is bi-directional, in the sense that variables both in the input term and the output term may receive a value through unification. As an example consider the following object declaration
  object a {
  a(C):- run(C,0).
  run(C,N):- C?f(N,Y), run(C,Y).
  }
  
and the goal
} :- C = new(channel), new(a(C)), C!(X,1).
  which results in binding X to zero and Y in the body of a to one.
  
  We conclude this intermezzo with an example of a situation
  where the number of processes can grow indefinitly large.
  Below we present our implementation of the solution to
  generating primes given in  [Ho78].
  
  YY
  
  As sketched here, communication over channels
  offers a rather limited functionality.
  In particular since we have not included
  guarded commands or annotated variables,
  synchronization must relie purely on the synchronous
  nature of communication.
  Another important limitation is that
  no backtracking over the results of a communication is
  allowed,
  once a successful communication is achieved.
  
  
  
  
  
  
  
  
  
  
  
  a------------------
  In the previous section we have seen how we may implement
  objects with states without the use of non-logical variables
  to store the state of such objects.
  The approach sketched there
  knew a number of limitations.
  Instead of augmenting the proposal of the previous section,
  we will take up the main thread of this chapter
  and will investigate how we may achieve
  object oriented behavior by regarding clauses as methods.
  
  Below we summarize the language extensions that we treat in this
  section.
  
  Nota that we restrict ourselves to active objects. KK
  
  

States

As we have indicated