public IInferenceResult Ask(FOLKnowledgeBase kb, ISentence aQuery) { // // Get the background knowledge - are assuming this is satisfiable // as using Set of Support strategy. ISet <Clause> bgClauses = new HashedSet <Clause>(kb.GetAllClauses()); bgClauses.ExceptWith(SubsumptionElimination.FindSubsumedClauses(bgClauses)); IList <Chain> background = CreateChainsFromClauses(bgClauses); // Collect the information necessary for constructing // an answer (supports use of answer literals). var ansHandler = new AnswerHandler(kb, aQuery, this.MaxQueryTime); var 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()) { this.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; bool dropped; do { cancelled = false; Chain nextParent; while (nextNearParent != (nextParent = this.TryCancellation(nextNearParent))) { nextNearParent = nextParent; cancelled = true; } dropped = false; while (nextNearParent != (nextParent = this.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 this.RecursiveDls(maxDepth, currentDepth + 1, nextNearParent, indexedFarParents, ansHandler); // Reset the number of far parents possible // when recursing back up. indexedFarParents.ResetNumberFarParentsTo(nextNearParent, noNextFarParents); } } }