// // START-InferenceProcedure public InferenceResult ask(FOLKnowledgeBase kb, Sentence aQuery) { // // Get the background knowledge - are assuming this is satisfiable // as using Set of Support strategy. List<Clause> bgClauses = new List<Clause>(kb.getAllClauses()); List<Clause> removeList = SubsumptionElimination.findSubsumedClauses(bgClauses); foreach (Clause c in removeList) { bgClauses.Remove(c); } List<Chain> background = createChainsFromClauses(bgClauses); // Collect the information necessary for constructing // an answer (supports use of answer literals). AnswerHandler ansHandler = new AnswerHandler(kb, aQuery, maxQueryTime,this); IndexedFarParents ifps = new IndexedFarParents(ansHandler .getSetOfSupport(), background); // Iterative deepening to be used for (int maxDepth = 1; maxDepth < int.MaxValue; maxDepth++) { // Track the depth actually reached ansHandler.resetMaxDepthReached(); if (null != tracer) { tracer.reset(); } foreach (Chain nearParent in ansHandler.getSetOfSupport()) { recursiveDLS(maxDepth, 0, nearParent, ifps, ansHandler); if (ansHandler.isComplete()) { return ansHandler; } } // This means the search tree // has bottomed out (i.e. finite). // Return what I know based on exploring everything. if (ansHandler.getMaxDepthReached() < maxDepth) { return ansHandler; } } return ansHandler; }
public void testBinaryResolventsOrderDoesNotMatter() { // This is a regression test, to ensure // the ordering of resolvents does not matter. // If the order ends up mattering, then likely // a problem was introduced in the Clause class // unifier, or related class. // Set up the initial set of clauses based on the // loves animal domain as it contains functions // new clauses will always be created (i.e. is an // infinite universe of discourse). FOLKnowledgeBase kb = new FOLKnowledgeBase(DomainFactory .lovesAnimalDomain()); kb .tell("FORALL x (FORALL y (Animal(y) => Loves(x, y)) => EXISTS y Loves(y, x))"); kb .tell("FORALL x (EXISTS y (Animal(y) AND Kills(x, y)) => FORALL z NOT(Loves(z, x)))"); kb.tell("FORALL x (Animal(x) => Loves(Jack, x))"); kb.tell("(Kills(Jack, Tuna) OR Kills(Curiosity, Tuna))"); kb.tell("Cat(Tuna)"); kb.tell("FORALL x (Cat(x) => Animal(x))"); List<Clause> clauses = new List<Clause>(); clauses.AddRange(kb.getAllClauses()); List<Clause> newClauses = new List<Clause>(); long maxRunTime = 30 * 1000; // 30 seconds long finishTime = System.DateTime.UtcNow.Ticks + maxRunTime; do { clauses.AddRange(newClauses); newClauses.Clear(); Clause[] clausesA = new Clause[clauses.Count]; clauses.CopyTo(clausesA); for (int i = 0; i < clausesA.Length; i++) { Clause cI = clausesA[i]; for (int j = 0; j < clausesA.Length; j++) { Clause cJ = clausesA[j]; newClauses.AddRange(cI.getFactors()); newClauses.AddRange(cJ.getFactors()); List<Clause> cIresolvents = cI.binaryResolvents(cJ); List<Clause> cJresolvents = cJ.binaryResolvents(cI); if (!cIresolvents.Equals(cJresolvents)) { System.Console.WriteLine("cI=" + cI); System.Console.WriteLine("cJ=" + cJ); System.Console.WriteLine("cIR=" + cIresolvents); System.Console.WriteLine("cJR=" + cJresolvents); Assert .Fail("Ordering of binary resolvents has become usingant, which should not be the case"); } foreach (Clause r in cIresolvents) { newClauses.AddRange(r.getFactors()); } if (System.DateTime.UtcNow.Ticks > finishTime) { break; } } if (System.DateTime.UtcNow.Ticks > finishTime) { break; } } } while (System.DateTime.UtcNow.Ticks < finishTime); }
// // START-InferenceProcedure public InferenceResult ask(FOLKnowledgeBase KB, Sentence alpha) { List<Clause> sos = new List<Clause>(); List<Clause> usable = new List<Clause>(); // Usable set will be the set of clauses in the KB, // are assuming this is satisfiable as using the // Set of Support strategy. foreach (Clause c in KB.getAllClauses()) { Clause c2 = KB.standardizeApart(c); c2.setStandardizedApartCheckNotRequired(); usable.AddRange(c2.getFactors()); } // Ensure reflexivity axiom is added to usable if using paramodulation. if (isUseParamodulation()) { // Reflexivity Axiom: x = x TermEquality reflexivityAxiom = new TermEquality(new Variable("x"), new Variable("x")); Clause reflexivityClause = new Clause(); reflexivityClause.addLiteral(new Literal(reflexivityAxiom)); reflexivityClause = KB.standardizeApart(reflexivityClause); reflexivityClause.setStandardizedApartCheckNotRequired(); usable.Add(reflexivityClause); } 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(); sos.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(); sos.AddRange(c2.getFactors()); } } // Ensure all subsumed clauses are removed foreach (Clause c in SubsumptionElimination.findSubsumedClauses(usable)) { usable.Remove(c); } foreach (Clause c in SubsumptionElimination.findSubsumedClauses(sos)) { sos.Remove(c); } OTTERAnswerHandler ansHandler = new OTTERAnswerHandler(answerLiteral, answerLiteralVariables, answerClause, maxQueryTime); IndexedClauses idxdClauses = new IndexedClauses( getLightestClauseHeuristic(), sos, usable); return otter(ansHandler, idxdClauses, sos, usable); }
// // START-InferenceProcedure 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; }