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.
% 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)
	).