public InferenceResult ask(FOLKnowledgeBase KB, Sentence alpha)
{
// clauses <- the set of clauses in CNF representation of KB ^ ~alpha
List<Clause> clauses = new List<Clause>();
foreach (Clause c in KB.getAllClauses())
{
Clause c2 = KB.standardizeApart(c);
c2.setStandardizedApartCheckNotRequired();
clauses.AddRange(c2.getFactors());
}
Sentence notAlpha = new NotSentence(alpha);
// Want to use an answer literal to pull
// query variables where necessary
Literal answerLiteral = KB.createAnswerLiteral(notAlpha);
List<Variable> answerLiteralVariables = KB
.collectAllVariables(answerLiteral.getAtomicSentence());
Clause answerClause = new Clause();
if (answerLiteralVariables.Count > 0)
{
Sentence notAlphaWithAnswer = new ConnectedSentence(Connectors.OR,
notAlpha, answerLiteral.getAtomicSentence());
foreach (Clause c in KB.convertToClauses(notAlphaWithAnswer))
{
Clause c2 = KB.standardizeApart(c);
c2.setProofStep(new ProofStepGoal(c2));
c2.setStandardizedApartCheckNotRequired();
clauses.AddRange(c2.getFactors());
}
answerClause.addLiteral(answerLiteral);
}
else
{
foreach (Clause c in KB.convertToClauses(notAlpha))
{
Clause c2 = KB.standardizeApart(c);
c2.setProofStep(new ProofStepGoal(c2));
c2.setStandardizedApartCheckNotRequired();
clauses.AddRange(c2.getFactors());
}
}
TFMAnswerHandler ansHandler = new TFMAnswerHandler(answerLiteral,
answerLiteralVariables, answerClause, maxQueryTime);
// new <- {}
List<Clause> newClauses = new List<Clause>();
List<Clause> toAdd = new List<Clause>();
// loop do
int noOfPrevClauses = clauses.Count;
do
{
if (null != tracer)
{
tracer.stepStartWhile(clauses, clauses.Count, newClauses
.Count);
}
newClauses.Clear();
// for each Ci, Cj in clauses do
Clause[] clausesA = new Clause[clauses.Count];
clausesA = clauses.ToArray();
// Basically, using the simple T)wo F)inger M)ethod here.
for (int i = 0; i < clausesA.Length; i++)
{
Clause cI = clausesA[i];
if (null != tracer)
{
tracer.stepOuterFor(cI);
}
for (int j = i; j < clausesA.Length; j++)
{
Clause cJ = clausesA[j];
if (null != tracer)
{
tracer.stepInnerFor(cI, cJ);
}
// resolvent <- FOL-RESOLVE(Ci, Cj)
List<Clause> resolvents = cI.binaryResolvents(cJ);
if (resolvents.Count > 0)
{
toAdd.Clear();
// new <- new <UNION> resolvent
foreach (Clause rc in resolvents)
{
toAdd.AddRange(rc.getFactors());
}
if (null != tracer)
{
tracer.stepResolved(cI, cJ, toAdd);
}
ansHandler.checkForPossibleAnswers(toAdd);
if (ansHandler.isComplete())
{
break;
}
newClauses.AddRange(toAdd);
}
if (ansHandler.isComplete())
{
break;
}
}
if (ansHandler.isComplete())
{
break;
}
}
noOfPrevClauses = clauses.Count;
// clauses <- clauses <UNION> new
clauses.AddRange(newClauses);
if (ansHandler.isComplete())
{
break;
}
// if new is a <SUBSET> of clauses then finished
// searching for an answer
// (i.e. when they were added the # clauses
// did not increase).
} while (noOfPrevClauses < clauses.Count);
if (null != tracer)
{
tracer.stepFinished(clauses, ansHandler);
}
return ansHandler;
}