// END-InferenceProcedure // // // PRIVATE METHODS // /** * <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> */ private List<List<ProofStepBwChGoal>> folbcask(FOLKnowledgeBase KB, BCAskAnswerHandler ansHandler, List<Literal> goals, Dictionary<Variable, Term> theta) { List<List<ProofStepBwChGoal>> thisLevelProofSteps = new List<List<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()) { Clause r2 = KB.standardizeApart(r); // and thetaDelta <- UNIFY(q, qDelta) succeeds Dictionary<Variable, Term> thetaDelta = KB.unify(r2.getPositiveLiterals() [0].getAtomicSentence(), qDelta.getAtomicSentence()); if (null != thetaDelta) { // new_goals <- [p1,...,pn|REST(goals)] List<Literal> newGoals = new List<Literal>(r2 .getNegativeLiterals()); newGoals.AddRange(goals.Skip(1)); // answers <- FOL-BC-ASK(KB, new_goals, COMPOSE(thetaDelta, // theta)) U answers Dictionary<Variable, Term> composed = compose(KB, thetaDelta, theta); List<List<ProofStepBwChGoal>> lowerLevelProofSteps = folbcask( KB, ansHandler, newGoals, composed); ansHandler.addProofStep(lowerLevelProofSteps, r2, qDelta, composed); thisLevelProofSteps.AddRange(lowerLevelProofSteps); } } // return answers return thisLevelProofSteps; }