We will describe some simple utilizations of the blackboard to implement efficiently some basic abstract data types. They all use the saved/2 predicate instead of save_term/2. Saved/2 does basically the same work but also makes a call to the blackboard garbage collector if necessary. The reader can find the code in the file lib.pl of the BinProlog distribution.
A very useful data structure that is implemented with the blackboard is a stack/queue that survives failure but still allows the programmer to use some of the nice properties of logical variables. It is implemented through a set of C-based builtins in BinProlog 5.75 and used among other things in the implementation of BinProlog's dynamic code.
addq/3 adds to end of persistent queue as in addq(key1,key2,33). pushq/3 adds to beginning of a persistent queue cpopq/3 pops (copy of) first element of the queue cmembq/3 backtracks over (copies of) members of a queue cdelq/4 deletes first matching element from a queue
See examples of use in the automatically generated Appendix.
Defining a vector is done initializing it to a given Zero element. The vector_set/3 update operation uses saved/2, therefore the old content of vectors is also subject to garbage collection.
vector_def(Name,Dim,Zero):- Max is Dim-1, for(I,0,Max), % generator for I from 0 to Max bb_let(Name,I,Zero), fail. vector_def(_,_,_). vector_set(Name,I,Val):-bb_set(Name,I,Val). vector_val(Name,I,Val):-bb_val(Name,I,Val).
Building multi-dimensional arrays on these vectors is straightforward, by defining an index-to-address translation function.
The special case of a high-performance 2-dimension (possibly sparse) global array can be handled conveniently by using bb_def/3, bb_set/3, bb_val/3 as in:
global_array_set(I,J,Val):-bb_set(I,J,Val).