[ Non-logical Variables, Arrays, Bags, Shelves and Stores | Reference Manual | Alphabetic Index ]

shelf_create(+InitTerm, -ShelfHandle)

Create a shelf object which can store data across failures
InitTerm
A compound term
ShelfHandle
A free variable

Description

This creates a 'shelf' object which can be used to store information across failures. A typical application is counting of solutions, keeping track of the best solution, aggregating information across multiple solutions etc.

A shelf is an object with multiple slots whose contents survive backtracking. The content of each slot can be set and retrieved individually, or the whole shelf can be retrieved as a term.

Shelves are referred to by handle, not by name, so they make it easy to write robust, reentrant code. A shelf disappears when the system backtracks over its creation, when the shelf handle gets garbage collected, or when it is explicitly destroyed.

A shelf is initialized from a compound term InitTerm. InitTerm's arity determines the number of slots the shelf provides, and InitTerm's arguments are used to initialize the corresponding shelf slots.

Modes and Determinism

Exceptions

(4) instantiation fault
InitTerm is not instantiated
(5) type error
InitTerm is instantiated but not to a compound term
(5) type error
ShelfHandle is not a variable

Examples


% a meta-predicate to count the number of solutions to a goal:

    count_solutions(Goal, Total) :-
    	shelf_create(count(0), Shelf),
	(
	    call(Goal),
	    shelf_inc(Shelf, 1),
	    fail
	;
	    shelf_get(Shelf, 1, Total)
	),
	shelf_abolish(Shelf).


% finding the sum and maximum of data/1 facts:

    data(2).
    data(9).
    data(3).
    data(5).
    data(7).

    sum_and_max(Sum, Max) :-
    	shelf_create(agg(0,0), Shelf),
	(
	    data(X),
	    shelf_get(Shelf, 1, OldMax),
	    ( X > OldMax -> shelf_set(Shelf, 1, X) ; true ),
	    shelf_get(Shelf, 2, OldSum),
	    NewSum is OldSum + X,
	    shelf_set(Shelf, 2, NewSum),
	    fail
	;
	    shelf_get(Shelf, 0, agg(Max, Sum))
	),
	shelf_abolish(Shelf).


% if-then-else with backtracking over the condition:

    if(Cond, Then, Else) :-
	shelf_create(sol(no), SolFlag),
	(
	    call(Cond),
	    shelf_set(SolFlag, 1, yes),   % remember there was a solution
	    call(Then)
	;
	    shelf_get(SolFlag, 1, no),    % fail if there was a solution
	    call(Else)
	).
    

See Also

shelf_create / 3, shelf_set / 3, shelf_get / 3, shelf_abolish / 1, array / 1, bag_create / 1