
shelf_create(+InitTerm, -ShelfHandle)

   Create a shelf object which can store data across failures

Arguments
   InitTerm            A compound term
   ShelfHandle         A free variable

Type
   Non-logical Variables, Arrays, Bags, Shelves and Stores

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
   shelf_create(+, -) is det

Exceptions
     4 --- InitTerm is not instantiated
     5 --- InitTerm is instantiated but not to a compound term
     5 --- 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
