[ Non-logical Variables, Arrays, Bags, Shelves and Stores | The ECLiPSe Built-In Predicates | 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

- shelf_create(+, -) is det

### 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