// START-InferenceProcedure public InferenceResult ask(FOLKnowledgeBase kb, Sentence aQuery) { // Get the background knowledge - are assuming this is satisfiable // as using Set of Support strategy. List <Clause> bgClauses = new List <Clause>(kb.getAllClauses()); List <Clause> removeList = SubsumptionElimination.findSubsumedClauses(bgClauses); foreach (Clause c in removeList) { bgClauses.Remove(c); } List <Chain> background = createChainsFromClauses(bgClauses); // Collect the information necessary for constructing // an answer (supports use of answer literals). AnswerHandler ansHandler = new AnswerHandler(kb, aQuery, maxQueryTime, this); IndexedFarParents ifps = new IndexedFarParents(ansHandler .getSetOfSupport(), background); // Iterative deepening to be used for (int maxDepth = 1; maxDepth < int.MaxValue; maxDepth++) { // Track the depth actually reached ansHandler.resetMaxDepthReached(); if (null != tracer) { tracer.reset(); } foreach (Chain nearParent in ansHandler.getSetOfSupport()) { recursiveDLS(maxDepth, 0, nearParent, ifps, ansHandler); if (ansHandler.isComplete()) { return(ansHandler); } } // This means the search tree // has bottomed out (i.e. finite). // Return what I know based on exploring everything. if (ansHandler.getMaxDepthReached() < maxDepth) { return(ansHandler); } } return(ansHandler); }
// 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); } } }