/// <summary> /// <code> /// function FOL-BC-ASK(KB, goals, theta) returns a set of substitutions /// input: KB, a knowledge base /// goals, a list of conjuncts forming a query (theta already applied) /// theta, the current substitution, initially the empty substitution {} /// </code> /// </summary> /// <param name="KB"></param> /// <param name="ansHandler"></param> /// <param name="goals"></param> /// <param name="theta"></param> /// <returns></returns> private IList <IList <ProofStepBwChGoal> > Folbcask(FOLKnowledgeBase KB, BCAskAnswerHandler ansHandler, IList <Literal> goals, IDictionary <Variable, ITerm> theta) { var thisLevelProofSteps = new List <IList <ProofStepBwChGoal> >(); // local variables: answers, a set of substitutions, initially empty // if goals is empty then return {theta} if (goals.Count == 0) { thisLevelProofSteps.Add(new List <ProofStepBwChGoal>()); return(thisLevelProofSteps); } // qDelta <- SUBST(theta, FIRST(goals)) Literal qDelta = KB.Subst(theta, goals[0]); // for each sentence r in KB where // STANDARDIZE-APART(r) = (p1 ^ ... ^ pn => q) foreach (Clause r in KB.GetAllDefiniteClauses()) { var standardizedR = KB.StandardizeApart(r); // and thetaDelta <- UNIFY(q, qDelta) succeeds IDictionary <Variable, ITerm> thetaDelta = KB.Unify(standardizedR.GetPositiveLiterals()[0].AtomicSentence, qDelta.AtomicSentence); if (null != thetaDelta) { // new_goals <- [p1,...,pn|REST(goals)] var newGoals = new List <Literal>(standardizedR.GetNegativeLiterals()); newGoals.AddRange(goals.Skip(1)); // answers <- FOL-BC-ASK(KB, new_goals, COMPOSE(thetaDelta, // theta)) U answers IDictionary <Variable, ITerm> composed = this.Compose(KB, thetaDelta, theta); IList <IList <ProofStepBwChGoal> > lowerLevelProofSteps = this.Folbcask( KB, ansHandler, newGoals, composed); ansHandler.AddProofStep(lowerLevelProofSteps, standardizedR, qDelta, composed); thisLevelProofSteps.AddRange(lowerLevelProofSteps); } } // return answers return(thisLevelProofSteps); }