private void AskSentence(Fact sentence, LinkedList<Expression> goals, KnowledgeBase context, Substitution theta, ProverCache cache, VariableRenamer renamer, bool askOne, HashSet<Substitution> results, HashSet<Fact> alreadyAsking) { if (!cache.Contains(sentence)) { //Prevent infinite loops on certain recursive queries. if(alreadyAsking.Contains(sentence)) { return; } alreadyAsking.Add(sentence); List<Implication> candidates = new List<Implication>(); candidates.AddRange(_knowledgeBase.Fetch(sentence)); candidates.AddRange(context.Fetch(sentence)); var sentenceResults = new HashSet<Substitution>(); foreach (Implication rule in candidates) { Implication r = renamer.Rename(rule); Substitution thetaPrime = Unifier.Unify(r.Consequent, sentence); if (thetaPrime != null) { LinkedList<Expression> sentenceGoals = new LinkedList<Expression>(); for (int i = 0; i < r.NumAntecedents(); i++) sentenceGoals.AddLast(r.Antecedents.Constituents[i]); Ask(sentenceGoals, context, theta.Compose(thetaPrime), cache, renamer, false, sentenceResults, alreadyAsking); } } cache[sentence] = sentenceResults; alreadyAsking.Remove(sentence); } foreach (Substitution thetaPrime in cache[sentence]) { Ask(goals, context, theta.Compose(thetaPrime), cache, renamer, askOne, results, alreadyAsking); if (askOne && (results.Any())) break; } }