edu.rice.cs.plt.recur
Class PrecomputedRecursionStack4<T1,T2,T3,T4,R>

java.lang.Object
  extended by edu.rice.cs.plt.recur.PrecomputedRecursionStack4<T1,T2,T3,T4,R>

public class PrecomputedRecursionStack4<T1,T2,T3,T4,R>
extends Object

A stack used to store the arguments of a recursive invocation in order to prevent infinite recursion. By checking that the given arguments have not been used previously before recurring, a client can prevent infinite recursion in some circumstances (such as when traversing an infinite, immutable data structure).

While RecursionStack4 allows arbitrary application result values to be provided for the infinite case, this class follows a stricter discipline: the infinite case result must be provided at the time of the first invocation of the arguments; that value will be stored, and a second invocation will return it. In this way, the result of a recursive computation is always precomputed -- that is, it must be determined before the computation takes place. Classes like DelayedThunk can be used to create precomputed values, providing an initial "empty box" that can be "filled" when computation is complete. This allows the definition, for example, of data structures that contain themselves. Due to the restricted applicability of this class (in comparison to RecursionStack4), methods that involve invoking Runnables or recurring multiple times based on a threshold value are not defined here.

The client may either choose to explicity check for containment, push(T1, T2, T3, T4, R) the argument, recur, and then pop(T1, T2, T3, T4), or invoke one of a variety of lambda-based methods that perform these bookkeeping tasks automatically. In the latter case, when an exception occurs between a push and a matching pop, the pop is guaranteed to execute before the exception propagates upward. Thus, clients who do not directly invoke push(T1, T2, T3, T4, R) and pop(T1, T2, T3, T4) may assume that the stack is always in a consistent state.

See Also:
RecursionStack4, PrecomputedRecursionStack, PrecomputedRecursionStack2, PrecomputedRecursionStack3

Constructor Summary
PrecomputedRecursionStack4()
          Create an empty recursion stack with an IdentityQuad factory
PrecomputedRecursionStack4(Lambda4<? super T1,? super T2,? super T3,? super T4,? extends Quad<T1,T2,T3,T4>> quadFactory)
          Create an empty recursion stack with the given Quad factory
 
Method Summary
 R apply(Lambda4<? super T1,? super T2,? super T3,? super T4,? extends R> lambda, Lambda4<? super T1,? super T2,? super T3,? super T4,? extends R> precomputed, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
          Evaluate the given lambda with the given arguments, unless the arguments are already on the stack; push the arguments onto the stack with the given precomputed result during lambda's evaluation
 R apply(Lambda4<? super T1,? super T2,? super T3,? super T4,? extends R> lambda, R precomputed, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
          Evaluate the given lambda with the given arguments, unless the arguments are already on the stack; push the arguments onto the stack with the given precomputed result during lambda's evaluation
 R apply(Lambda4<? super T1,? super T2,? super T3,? super T4,? extends R> lambda, Thunk<? extends R> precomputed, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
          Evaluate the given lambda with the given arguments, unless the arguments are already on the stack; push the arguments onto the stack with the given precomputed result during lambda's evaluation
 R apply(Thunk<? extends R> thunk, Lambda4<? super T1,? super T2,? super T3,? super T4,? extends R> precomputed, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
          Evaluate the given thunk, unless the given arguments are already on the stack; push the arguments onto the stack with the given precomputed result during thunk's evaluation
 R apply(Thunk<? extends R> thunk, R precomputed, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
          Evaluate the given thunk, unless the given arguments are already on the stack; push the arguments onto the stack with the given precomputed result during thunk's evaluation
 R apply(Thunk<? extends R> thunk, Thunk<? extends R> precomputed, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
          Evaluate the given thunk, unless the given arguments are already on the stack; push the arguments onto the stack with the given precomputed result during thunk's evaluation
 boolean contains(T1 arg1, T2 arg2, T3 arg3, T4 arg4)
           
 R get(T1 arg1, T2 arg2, T3 arg3, T4 arg4)
           
 boolean isEmpty()
           
static
<T1,T2,T3,T4,R>
PrecomputedRecursionStack4<T1,T2,T3,T4,R>
make()
          Call the constructor (allows the type arguments to be inferred)
static
<T1,T2,T3,T4,R>
PrecomputedRecursionStack4<T1,T2,T3,T4,R>
make(Lambda4<? super T1,? super T2,? super T3,? super T4,? extends Quad<T1,T2,T3,T4>> quadFactory)
          Call the constructor (allows the type arguments to be inferred)
 void pop(T1 arg1, T2 arg2, T3 arg3, T4 arg4)
          Remove the given arguments from the top of the stack
 void push(T1 arg1, T2 arg2, T3 arg3, T4 arg4, Lambda4<? super T1,? super T2,? super T3,? super T4,? extends R> value)
          Add the given arguments to the top of the stack with the given lambda producing their infinite-case result.
 void push(T1 arg1, T2 arg2, T3 arg3, T4 arg4, R value)
          Add the given arguments to the top of the stack with the given infinite-case result.
 void push(T1 arg1, T2 arg2, T3 arg3, T4 arg4, Thunk<? extends R> value)
          Add the given arguments to the top of the stack with the given thunk producing their infinite-case result.
 int size()
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

PrecomputedRecursionStack4

public PrecomputedRecursionStack4()
Create an empty recursion stack with an IdentityQuad factory


PrecomputedRecursionStack4

public PrecomputedRecursionStack4(Lambda4<? super T1,? super T2,? super T3,? super T4,? extends Quad<T1,T2,T3,T4>> quadFactory)
Create an empty recursion stack with the given Quad factory

Parameters:
quadFactory - A lambda used to produce a quad for values placed on the stack. This provides clients with control over the method used to determine if a value has been seen previously.
Method Detail

contains

public boolean contains(T1 arg1,
                        T2 arg2,
                        T3 arg3,
                        T4 arg4)
Returns:
true iff values identical (according to ==) to the given arguments are currently on the stack

get

public R get(T1 arg1,
             T2 arg2,
             T3 arg3,
             T4 arg4)
Returns:
The infinite-case result provided for the given arguments
Throws:
IllegalStateException - If the arguments are not on the stack

push

public void push(T1 arg1,
                 T2 arg2,
                 T3 arg3,
                 T4 arg4,
                 R value)
Add the given arguments to the top of the stack with the given infinite-case result.

Throws:
IllegalArgumentException - If the arguments are already on the stack

push

public void push(T1 arg1,
                 T2 arg2,
                 T3 arg3,
                 T4 arg4,
                 Thunk<? extends R> value)
Add the given arguments to the top of the stack with the given thunk producing their infinite-case result.

Throws:
IllegalArgumentException - If the arguments are already on the stack

push

public void push(T1 arg1,
                 T2 arg2,
                 T3 arg3,
                 T4 arg4,
                 Lambda4<? super T1,? super T2,? super T3,? super T4,? extends R> value)
Add the given arguments to the top of the stack with the given lambda producing their infinite-case result.

Throws:
IllegalArgumentException - If the arguments are already on the stack

pop

public void pop(T1 arg1,
                T2 arg2,
                T3 arg3,
                T4 arg4)
Remove the given arguments from the top of the stack

Throws:
IllegalArgumentException - If the arguments are not at the top of the stack

size

public int size()
Returns:
The current size (depth) of the stack

isEmpty

public boolean isEmpty()
Returns:
true iff the stack is currently empty

apply

public R apply(Thunk<? extends R> thunk,
               R precomputed,
               T1 arg1,
               T2 arg2,
               T3 arg3,
               T4 arg4)
Evaluate the given thunk, unless the given arguments are already on the stack; push the arguments onto the stack with the given precomputed result during thunk's evaluation

Returns:
The value of thunk, or a previously-provided precomputed value

apply

public R apply(Thunk<? extends R> thunk,
               Thunk<? extends R> precomputed,
               T1 arg1,
               T2 arg2,
               T3 arg3,
               T4 arg4)
Evaluate the given thunk, unless the given arguments are already on the stack; push the arguments onto the stack with the given precomputed result during thunk's evaluation

Returns:
The value of thunk, or a previously-provided precomputed value

apply

public R apply(Thunk<? extends R> thunk,
               Lambda4<? super T1,? super T2,? super T3,? super T4,? extends R> precomputed,
               T1 arg1,
               T2 arg2,
               T3 arg3,
               T4 arg4)
Evaluate the given thunk, unless the given arguments are already on the stack; push the arguments onto the stack with the given precomputed result during thunk's evaluation

Returns:
The value of thunk, or a previously-provided precomputed value

apply

public R apply(Lambda4<? super T1,? super T2,? super T3,? super T4,? extends R> lambda,
               R precomputed,
               T1 arg1,
               T2 arg2,
               T3 arg3,
               T4 arg4)
Evaluate the given lambda with the given arguments, unless the arguments are already on the stack; push the arguments onto the stack with the given precomputed result during lambda's evaluation

Returns:
The value of lambda, or a previously-provided precomputed value

apply

public R apply(Lambda4<? super T1,? super T2,? super T3,? super T4,? extends R> lambda,
               Thunk<? extends R> precomputed,
               T1 arg1,
               T2 arg2,
               T3 arg3,
               T4 arg4)
Evaluate the given lambda with the given arguments, unless the arguments are already on the stack; push the arguments onto the stack with the given precomputed result during lambda's evaluation

Returns:
The value of lambda, or a previously-provided precomputed value

apply

public R apply(Lambda4<? super T1,? super T2,? super T3,? super T4,? extends R> lambda,
               Lambda4<? super T1,? super T2,? super T3,? super T4,? extends R> precomputed,
               T1 arg1,
               T2 arg2,
               T3 arg3,
               T4 arg4)
Evaluate the given lambda with the given arguments, unless the arguments are already on the stack; push the arguments onto the stack with the given precomputed result during lambda's evaluation

Returns:
The value of lambda, or a previously-provided precomputed value

make

public static <T1,T2,T3,T4,R> PrecomputedRecursionStack4<T1,T2,T3,T4,R> make()
Call the constructor (allows the type arguments to be inferred)


make

public static <T1,T2,T3,T4,R> PrecomputedRecursionStack4<T1,T2,T3,T4,R> make(Lambda4<? super T1,? super T2,? super T3,? super T4,? extends Quad<T1,T2,T3,T4>> quadFactory)
Call the constructor (allows the type arguments to be inferred)