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

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

public class RecursionStack4<T1,T2,T3,T4>
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).

The client may either choose to explicity check for containment, push(T1, T2, T3, T4) the arguments, 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) and pop(T1, T2, T3, T4) may assume that the stack is always in a consistent state.

See Also:
PrecomputedRecursionStack4, RecursionStack, RecursionStack2, RecursionStack3

Constructor Summary
RecursionStack4()
          Create an empty recursion stack with an IdentityQuad factory
RecursionStack4(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
<V1 extends T1,V2 extends T2,V3 extends T3,V4 extends T4,R>
R
apply(Lambda4<? super V1,? super V2,? super V3,? super V4,? extends R> lambda, Lambda4<? super V1,? super V2,? super V3,? super V4,? extends R> infiniteCase, V1 arg1, V2 arg2, V3 arg3, V4 arg4)
          If the given arguments are not on the stack, evaluate lambda with the arguments; otherwise, evaluate infiniteCase.
<V1 extends T1,V2 extends T2,V3 extends T3,V4 extends T4,R>
R
apply(Lambda4<? super V1,? super V2,? super V3,? super V4,? extends R> lambda, Lambda4<? super V1,? super V2,? super V3,? super V4,? extends R> infiniteCase, V1 arg1, V2 arg2, V3 arg3, V4 arg4, int threshold)
          If less than threshold instances of the given arguments are on the stack, evaluate lambda with the arguments; otherwise, evaluate infiniteCase.
<V1 extends T1,V2 extends T2,V3 extends T3,V4 extends T4,R>
R
apply(Lambda4<? super V1,? super V2,? super V3,? super V4,? extends R> lambda, R infiniteCase, V1 arg1, V2 arg2, V3 arg3, V4 arg4)
          Evaluate the given lambda with the given arguments, unless the arguments are already on the stack; push the arguments onto the stack during lambda evaluation
<V1 extends T1,V2 extends T2,V3 extends T3,V4 extends T4,R>
R
apply(Lambda4<? super V1,? super V2,? super V3,? super V4,? extends R> lambda, R infiniteCase, V1 arg1, V2 arg2, V3 arg3, V4 arg4, int threshold)
          Evaluate the given lambda with the given arguments, unless threshold instances of the arguments are already on the stack; push the arguments onto the stack during lambda evaluation
<R> R
apply(Thunk<? extends R> thunk, R infiniteCase, 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 during thunk evaluation
<R> R
apply(Thunk<? extends R> thunk, R infiniteCase, T1 arg1, T2 arg2, T3 arg3, T4 arg4, int threshold)
          Evaluate the given thunk, unless threshold instances of the given arguments are already on the stack; push the arguments onto the stack during thunk evaluation
<R> R
apply(Thunk<? extends R> thunk, Thunk<? extends R> infiniteCase, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
          If the given arguments are not on the stack, evaluate thunk; otherwise, evaluate infiniteCase.
<R> R
apply(Thunk<? extends R> thunk, Thunk<? extends R> infiniteCase, T1 arg1, T2 arg2, T3 arg3, T4 arg4, int threshold)
          If less than threshold instances of the given arguments are on the stack, evaluate thunk; otherwise, evaluate infiniteCase.
 boolean contains(T1 arg1, T2 arg2, T3 arg3, T4 arg4)
           
 boolean contains(T1 arg1, T2 arg2, T3 arg3, T4 arg4, int threshold)
           
 boolean isEmpty()
           
static
<T1,T2,T3,T4>
RecursionStack4<T1,T2,T3,T4>
make()
          Call the constructor (allows the type arguments to be inferred)
static
<T1,T2,T3,T4>
RecursionStack4<T1,T2,T3,T4>
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)
          Add the given arguments to the top of the stack
<V1 extends T1,V2 extends T2,V3 extends T3,V4 extends T4>
void
run(Runnable4<? super V1,? super V2,? super V3,? super V4> r, Runnable4<? super V1,? super V2,? super V3,? super V4> infiniteCase, V1 arg1, V2 arg2, V3 arg3, V4 arg4)
          If the given arguments are not on the stack, run r with argument the arguments; otherwise, run infiniteCase.
<V1 extends T1,V2 extends T2,V3 extends T3,V4 extends T4>
void
run(Runnable4<? super V1,? super V2,? super V3,? super V4> r, Runnable4<? super V1,? super V2,? super V3,? super V4> infiniteCase, V1 arg1, V2 arg2, V3 arg3, V4 arg4, int threshold)
          If less than threshold instances of the given arguments are on the stack, run r with the arguments; otherwise, run infiniteCase.
<V1 extends T1,V2 extends T2,V3 extends T3,V4 extends T4>
void
run(Runnable4<? super V1,? super V2,? super V3,? super V4> r, V1 arg1, V2 arg2, V3 arg3, V4 arg4)
          Run the given runnable with the given arguments, unless the arguments are already on the stack; push the arguments onto the stack during runnable execution
<V1 extends T1,V2 extends T2,V3 extends T3,V4 extends T4>
void
run(Runnable4<? super V1,? super V2,? super V3,? super V4> r, V1 arg1, V2 arg2, V3 arg3, V4 arg4, int threshold)
          Run the given runnable with the given arguments, unless threshold instances of the arguments are already on the stack; push the arguments onto the stack during runnable execution
 void run(Runnable r, Runnable infiniteCase, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
          If the given arguments are not on the stack, run r; otherwise, run infiniteCase.
 void run(Runnable r, Runnable infiniteCase, T1 arg1, T2 arg2, T3 arg3, T4 arg4, int threshold)
          If less than threshold instances of the given arguments are on the stack, run r; otherwise, run infiniteCase.
 void run(Runnable r, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
          Run the given runnable, unless the given arguments are already on the stack; push the arguments onto the stack during runnable execution
 void run(Runnable r, T1 arg1, T2 arg2, T3 arg3, T4 arg4, int threshold)
          Run the given runnable, unless threshold instances of the given arguments are already on the stack; push the arguments onto the stack during runnable execution
 int size()
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

RecursionStack4

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


RecursionStack4

public RecursionStack4(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 a set of values identical (according to ==) to the given arguments is currently on the stack

contains

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

push

public void push(T1 arg1,
                 T2 arg2,
                 T3 arg3,
                 T4 arg4)
Add the given arguments to the top of 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 given 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

run

public void run(Runnable r,
                T1 arg1,
                T2 arg2,
                T3 arg3,
                T4 arg4)
Run the given runnable, unless the given arguments are already on the stack; push the arguments onto the stack during runnable execution


run

public void run(Runnable r,
                T1 arg1,
                T2 arg2,
                T3 arg3,
                T4 arg4,
                int threshold)
Run the given runnable, unless threshold instances of the given arguments are already on the stack; push the arguments onto the stack during runnable execution


run

public void run(Runnable r,
                Runnable infiniteCase,
                T1 arg1,
                T2 arg2,
                T3 arg3,
                T4 arg4)
If the given arguments are not on the stack, run r; otherwise, run infiniteCase. In either case, push the arguments onto the stack during runnable execution.


run

public void run(Runnable r,
                Runnable infiniteCase,
                T1 arg1,
                T2 arg2,
                T3 arg3,
                T4 arg4,
                int threshold)
If less than threshold instances of the given arguments are on the stack, run r; otherwise, run infiniteCase. In either case, push the arguments onto the stack during runnable execution.


run

public <V1 extends T1,V2 extends T2,V3 extends T3,V4 extends T4> void run(Runnable4<? super V1,? super V2,? super V3,? super V4> r,
                                                                          V1 arg1,
                                                                          V2 arg2,
                                                                          V3 arg3,
                                                                          V4 arg4)
Run the given runnable with the given arguments, unless the arguments are already on the stack; push the arguments onto the stack during runnable execution


run

public <V1 extends T1,V2 extends T2,V3 extends T3,V4 extends T4> void run(Runnable4<? super V1,? super V2,? super V3,? super V4> r,
                                                                          V1 arg1,
                                                                          V2 arg2,
                                                                          V3 arg3,
                                                                          V4 arg4,
                                                                          int threshold)
Run the given runnable with the given arguments, unless threshold instances of the arguments are already on the stack; push the arguments onto the stack during runnable execution


run

public <V1 extends T1,V2 extends T2,V3 extends T3,V4 extends T4> void run(Runnable4<? super V1,? super V2,? super V3,? super V4> r,
                                                                          Runnable4<? super V1,? super V2,? super V3,? super V4> infiniteCase,
                                                                          V1 arg1,
                                                                          V2 arg2,
                                                                          V3 arg3,
                                                                          V4 arg4)
If the given arguments are not on the stack, run r with argument the arguments; otherwise, run infiniteCase. In either case, push the arguments onto the stack during runnable execution.


run

public <V1 extends T1,V2 extends T2,V3 extends T3,V4 extends T4> void run(Runnable4<? super V1,? super V2,? super V3,? super V4> r,
                                                                          Runnable4<? super V1,? super V2,? super V3,? super V4> infiniteCase,
                                                                          V1 arg1,
                                                                          V2 arg2,
                                                                          V3 arg3,
                                                                          V4 arg4,
                                                                          int threshold)
If less than threshold instances of the given arguments are on the stack, run r with the arguments; otherwise, run infiniteCase. In either case, push the arguments onto the stack during runnable execution.


apply

public <R> R apply(Thunk<? extends R> thunk,
                   R infiniteCase,
                   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 during thunk evaluation

Returns:
The value of thunk, or infiniteCase

apply

public <R> R apply(Thunk<? extends R> thunk,
                   R infiniteCase,
                   T1 arg1,
                   T2 arg2,
                   T3 arg3,
                   T4 arg4,
                   int threshold)
Evaluate the given thunk, unless threshold instances of the given arguments are already on the stack; push the arguments onto the stack during thunk evaluation

Returns:
The value of thunk, or infiniteCase

apply

public <R> R apply(Thunk<? extends R> thunk,
                   Thunk<? extends R> infiniteCase,
                   T1 arg1,
                   T2 arg2,
                   T3 arg3,
                   T4 arg4)
If the given arguments are not on the stack, evaluate thunk; otherwise, evaluate infiniteCase. In either case, push the arguments onto the stack during thunk evaluation.

Returns:
The value of thunk, or the value of infiniteCase

apply

public <R> R apply(Thunk<? extends R> thunk,
                   Thunk<? extends R> infiniteCase,
                   T1 arg1,
                   T2 arg2,
                   T3 arg3,
                   T4 arg4,
                   int threshold)
If less than threshold instances of the given arguments are on the stack, evaluate thunk; otherwise, evaluate infiniteCase. In either case, push the arguments onto the stack during thunk evaluation.

Returns:
The value of thunk, or the value of infiniteCase

apply

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

Returns:
The value of lambda, or infiniteCase

apply

public <V1 extends T1,V2 extends T2,V3 extends T3,V4 extends T4,R> R apply(Lambda4<? super V1,? super V2,? super V3,? super V4,? extends R> lambda,
                                                                           R infiniteCase,
                                                                           V1 arg1,
                                                                           V2 arg2,
                                                                           V3 arg3,
                                                                           V4 arg4,
                                                                           int threshold)
Evaluate the given lambda with the given arguments, unless threshold instances of the arguments are already on the stack; push the arguments onto the stack during lambda evaluation

Returns:
The value of lambda, or infiniteCase

apply

public <V1 extends T1,V2 extends T2,V3 extends T3,V4 extends T4,R> R apply(Lambda4<? super V1,? super V2,? super V3,? super V4,? extends R> lambda,
                                                                           Lambda4<? super V1,? super V2,? super V3,? super V4,? extends R> infiniteCase,
                                                                           V1 arg1,
                                                                           V2 arg2,
                                                                           V3 arg3,
                                                                           V4 arg4)
If the given arguments are not on the stack, evaluate lambda with the arguments; otherwise, evaluate infiniteCase. In either case, push the arguments onto the stack during lambda evaluation.

Returns:
The value of lambda, or the value of infiniteCase

apply

public <V1 extends T1,V2 extends T2,V3 extends T3,V4 extends T4,R> R apply(Lambda4<? super V1,? super V2,? super V3,? super V4,? extends R> lambda,
                                                                           Lambda4<? super V1,? super V2,? super V3,? super V4,? extends R> infiniteCase,
                                                                           V1 arg1,
                                                                           V2 arg2,
                                                                           V3 arg3,
                                                                           V4 arg4,
                                                                           int threshold)
If less than threshold instances of the given arguments are on the stack, evaluate lambda with the arguments; otherwise, evaluate infiniteCase. In either case, push the arguments onto the stack during lambda evaluation.

Returns:
The value of lambda, or the value of infiniteCase

make

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


make

public static <T1,T2,T3,T4> RecursionStack4<T1,T2,T3,T4> 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)