
% Communication primitives.

trans(openCh(Ch)) :- isolate(seq(unOpened(Ch),
                                  ins(channel(Ch,[])))).

trans(closeCh(Ch)) :- del(channel(Ch,Queue)).

trans(send(Msg,Ch)) :- isolate(seq(del(channel(Ch,Queue1)),
                                seq(enQueue(Msg,Queue1,Queue2),
                                     ins(channel(Ch,Queue2))))).

trans(recv(Msg,Ch)) :- isolate(seq(del(channel(Ch,Queue1)),
                                seq(deQueue(Msg,Queue1,Queue2),
                                     ins(channel(Ch,Queue2))))).


% The following rules are in the database, not the transaction base.

% Determine whether or not communication channel Ch has been opened.
%
unOpened(Ch) :- not(opened(Ch)).

opened(Ch) :- channel(Ch,Queue).


% Add a message to a message queue.
%
enQueue(Msg,Queue,[Msg|Queue]).


% Remove a message from a message queue.
%
deQueue(Msg1,[Msg2|Queue1],[Msg2|Queue2]) :- deQueue(Msg1,Queue1,Queue2).

deQueue(Msg,[Msg],[]).



% Declare channel/2 to be a base predicate.
%
channel(X,Y) :- db(channel(X,Y)).


% The following dummy rules tell Prolog that certain predicates are
% defined.
%
openCh(dummy) :- fail.
closeCh(dummy) :- fail.
send(dummy,dummy) :- fail.
recv(dummy,dummy).
