A Linda style interface to the blackboard

The following predicates show how to do some Linda-style operations on top of the blackboard primitives.

The current focus of the operations is managed by object/1 and message/1. Out/? puts a tuple Mes on the blackboard, rd/? reads it and in/? removes it. Eval/? executes the Goal part of the clause (Answer:-Goal) focussed by object/1 and message/1. Then it puts the result Answer back to the blackboard. As Answer itself can be of the form (A:-G), a limited number of cascaded evals are possible.

% out/1, rd/1, in/1 
out(Mes):-object(Obj),message(Id),out(Obj,Id,Mes).
rd(Mes):-object(Obj),message(Id),rd(Obj,Id,Mes).
in(Mes):- object(Obj),message(Id),in(Obj,Id,Mes).

% out/2, rd/2, in/2
out(Id,Mes):-object(Obj),out(Obj,Id,Mes).
rd(Id,Mes):-object(Obj),rd(Obj,Id,Mes).
in(Id,Mes):-object(Obj),in(Obj,Id,Mes).

% out/3, rd/3, in/3
out(Obj,Id,_):-val(Obj,Id,_),!,fail.
out(Obj,Id,Mes):-saved(Mes,Sent),let(Obj,Id,Sent).
rd(Obj,Id,Mes):-val(Obj,Id,Mes).
in(Obj,Id,Mes):-val(Obj,Id,Mes),rm(Obj,Id).

% eval/0, eval/1, eval/2
eval:-object(Obj),message(Id),eval(Obj,Id).
eval(Id):-object(O),eval(O,Id).
eval(Obj,Id):-val(Obj,Id,(Answer:-Goal)),Goal,!,
  saved(Answer,NewAnswer),
  set(Obj,Id,NewAnswer).

% tools
object(New):-var(New),!,val('$object','$object',New).
object(New):-atomic(New),let('$object','$object',New).

message(New):-var(New),!,object(O),val(O,'$message',New).
message(New):-atomic(New),object(O),let(O,'$message',New).