public abstract class TailRecursivePredicate extends Object implements Predicate
Predicate
that are tail recursive.
It is common for Prolog developers to define predicates using recursion. Although recursive programs can be concise
and elegant they do require increased stack space for each iteration - which after many iterations will cause a
java.lang.StackOverflowError
. Where it can determine it is safe to do, Projog converts recursive user defined
predicates into iterative versions - requiring a constant stack space regardless of the number of iterations. This
technique is known as tail recursion optimisation or last call optimisation. The algorithm for
implementing tail recursion optimisation is encapsulated in TailRecursivePredicate
. Subclasses of
TailRecursivePredicate
can implement the logic of evaluating the clauses of a specific user defined predicate
without having to redefine the tail recursion optimisation algorithm.
For a user defined predicate to be implemented using TailRecursivePredicate
it must be judged as eligible for
tail recursion optimisation using the criteria used by TailRecursivePredicateMetaData
.
TailRecursivePredicateMetaData
Constructor and Description |
---|
TailRecursivePredicate() |
Modifier and Type | Method and Description |
---|---|
protected abstract void |
backtrack()
Backtracks the arguments to before the last attempt to match the first rule.
|
boolean |
evaluate()
Attempts to satisfy the goal this instance represents.
|
protected abstract void |
logCall() |
protected abstract void |
logExit() |
protected abstract void |
logFail() |
protected abstract void |
logRedo() |
protected abstract boolean |
matchFirstRule()
Match the first rule of the tail recursive predicate.
|
protected abstract boolean |
matchSecondRule()
Match the second rule of the tail recursive predicate.
|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
couldReevaluationSucceed
public final boolean evaluate()
Predicate
Calling this method multiple times on a single instance allows all possible answers to be identified. An attempt to find a solution carries on from where the last successful call finished.
If PredicateFactory.isRetryable()
returns false
then this method should only be called once per
individual query (no attempt should be made to find alternative solutions).
If PredicateFactory.isRetryable()
returns true
then, in order to find all possible solutions for
an individual query, this method should be recalled on backtracking until it returns false
.
evaluate
in interface Predicate
true
if it was possible to satisfy the clause, false
otherwisePredicateFactory.getPredicate(Term[])
protected abstract boolean matchFirstRule()
If the head of the first rule is matched then the rule has been successfully evaluated.
true
if the first rule is matched, else false
protected abstract boolean matchSecondRule()
If the second rule is matched then the attempt at evaluating the rule continues for another level of recursion.
true
if the second rule is matched, else false
protected abstract void backtrack()
protected abstract void logCall()
protected abstract void logRedo()
protected abstract void logExit()
protected abstract void logFail()
Copyright © 2024. All rights reserved.