// 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;
}