// Recursive Depth Limited Search
private void recursiveDLS(int maxDepth, int currentDepth, Chain nearParent,
IndexedFarParents indexedFarParents, AnswerHandler ansHandler)
{
// Keep track of the maximum depth reached.
ansHandler.updateMaxDepthReached(currentDepth);
if (currentDepth == maxDepth)
{
return;
}
int noCandidateFarParents = indexedFarParents
.getNumberCandidateFarParents(nearParent);
if (null != tracer)
{
tracer.increment(currentDepth, noCandidateFarParents);
}
indexedFarParents.standardizeApart(nearParent);
for (int farParentIdx = 0; farParentIdx < noCandidateFarParents; farParentIdx++)
{
// If have a complete answer, don't keep
// checking candidate far parents
if (ansHandler.isComplete())
{
break;
}
// Reduction
Chain nextNearParent = indexedFarParents.attemptReduction(
nearParent, farParentIdx);
if (null == nextNearParent)
{
// Unable to remove the head via reduction
continue;
}
// Handle Canceling and Dropping
bool cancelled = false;
bool dropped = false;
do
{
cancelled = false;
Chain nextParent = null;
while (nextNearParent != (nextParent = tryCancellation(nextNearParent)))
{
nextNearParent = nextParent;
cancelled = true;
}
dropped = false;
while (nextNearParent != (nextParent = tryDropping(nextNearParent)))
{
nextNearParent = nextParent;
dropped = true;
}
} while (dropped || cancelled);
// Check if have answer before
// going to the next level
if (!ansHandler.isAnswer(nextNearParent))
{
// Keep track of the current # of
// far parents that are possible for the next near parent.
int noNextFarParents = indexedFarParents
.getNumberFarParents(nextNearParent);
// Add to indexed far parents
nextNearParent = indexedFarParents.addToIndex(nextNearParent);
// Check the next level
recursiveDLS(maxDepth, currentDepth + 1, nextNearParent,
indexedFarParents, ansHandler);
// Reset the number of far parents possible
// when recursing back up.
indexedFarParents.resetNumberFarParentsTo(nextNearParent,
noNextFarParents);
}
}
}