// 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); }
/** * <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 ICollection <ICollection <ProofStepBwChGoal> > folbcask(FOLKnowledgeBase KB, BCAskAnswerHandler ansHandler, ICollection <Literal> goals, IMap <Variable, Term> theta) { ICollection <ICollection <ProofStepBwChGoal> > thisLevelProofSteps = CollectionFactory.CreateQueue <ICollection <ProofStepBwChGoal> >(); // local variables: answers, a set of substitutions, initially empty // if goals is empty then return {theta} if (goals.IsEmpty()) { thisLevelProofSteps.Add(CollectionFactory.CreateQueue <ProofStepBwChGoal>()); return(thisLevelProofSteps); } // qDelta <- SUBST(theta, FIRST(goals)) Literal qDelta = KB.subst(theta, goals.Get(0)); // for each sentence r in KB where // STANDARDIZE-APART(r) = (p1 ^ ... ^ pn => q) foreach (Clause rIter in KB.getAllDefiniteClauses()) { Clause r = rIter; r = KB.standardizeApart(r); // and thetaDelta <- UNIFY(q, qDelta) succeeds IMap <Variable, Term> thetaDelta = KB.unify(r.getPositiveLiterals() .Get(0).getAtomicSentence(), qDelta.getAtomicSentence()); if (null != thetaDelta) { // new_goals <- [p1,...,pn|REST(goals)] ICollection <Literal> newGoals = CollectionFactory.CreateQueue <Literal>(r.getNegativeLiterals()); newGoals.AddAll(goals.subList(1, goals.Size())); // answers <- FOL-BC-ASK(KB, new_goals, COMPOSE(thetaDelta, // theta)) U answers IMap <Variable, Term> composed = compose(KB, thetaDelta, theta); ICollection <ICollection <ProofStepBwChGoal> > lowerLevelProofSteps = folbcask( KB, ansHandler, newGoals, composed); ansHandler.addProofStep(lowerLevelProofSteps, r, qDelta, composed); thisLevelProofSteps.AddAll(lowerLevelProofSteps); } } // return answers return(thisLevelProofSteps); }
// 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 ISet <Clause> clauses = CollectionFactory.CreateSet <Clause>(); foreach (Clause cIter in KB.getAllClauses()) { Clause c = cIter; c = KB.standardizeApart(c); c.setStandardizedApartCheckNotRequired(); clauses.AddAll(c.getFactors()); } Sentence notAlpha = new NotSentence(alpha); // Want to use an answer literal to pull // query variables where necessary Literal answerLiteral = KB.createAnswerLiteral(notAlpha); ISet <Variable> answerLiteralVariables = KB.collectAllVariables(answerLiteral.getAtomicSentence()); Clause answerClause = new Clause(); if (answerLiteralVariables.Size() > 0) { Sentence notAlphaWithAnswer = new ConnectedSentence(Connectors.OR, notAlpha, answerLiteral.getAtomicSentence()); foreach (Clause cIter in KB.convertToClauses(notAlphaWithAnswer)) { Clause c = cIter; c = KB.standardizeApart(c); c.setProofStep(new ProofStepGoal(c)); c.setStandardizedApartCheckNotRequired(); clauses.AddAll(c.getFactors()); } answerClause.addLiteral(answerLiteral); } else { foreach (Clause cIter in KB.convertToClauses(notAlpha)) { Clause c = cIter; c = KB.standardizeApart(c); c.setProofStep(new ProofStepGoal(c)); c.setStandardizedApartCheckNotRequired(); clauses.AddAll(c.getFactors()); } } TFMAnswerHandler ansHandler = new TFMAnswerHandler(answerLiteral, answerLiteralVariables, answerClause, maxQueryTime); // new <- {} ISet <Clause> newClauses = CollectionFactory.CreateSet <Clause>(); ISet <Clause> toAdd = CollectionFactory.CreateSet <Clause>(); // loop do int noOfPrevClauses = clauses.Size(); do { if (null != tracer) { tracer.stepStartWhile(clauses, clauses.Size(), newClauses.Size()); } newClauses.Clear(); // for each Ci, Cj in clauses do Clause[] 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) ISet <Clause> resolvents = cI.binaryResolvents(cJ); if (resolvents.Size() > 0) { toAdd.Clear(); // new <- new <UNION> resolvent foreach (Clause rc in resolvents) { toAdd.AddAll(rc.getFactors()); } if (null != tracer) { tracer.stepResolved(cI, cJ, toAdd); } ansHandler.checkForPossibleAnswers(toAdd); if (ansHandler.isComplete()) { break; } newClauses.AddAll(toAdd); } if (ansHandler.isComplete()) { break; } } if (ansHandler.isComplete()) { break; } } noOfPrevClauses = clauses.Size(); // clauses <- clauses <UNION> new clauses.AddAll(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.Size()); if (null != tracer) { tracer.stepFinished(clauses, ansHandler); } return(ansHandler); }
// START-InferenceProcedure /** * <code> * function FOL-FC-ASK(KB, alpha) returns a substitution or false * inputs: KB, the knowledge base, a set of first order definite clauses * alpha, the query, an atomic sentence * </code> */ public InferenceResult ask(FOLKnowledgeBase KB, Sentence query) { // Assertions on the type of queries this Inference procedure // supports if (!(query is AtomicSentence)) { throw new ArgumentException( "Only Atomic Queries are supported."); } FCAskAnswerHandler ansHandler = new FCAskAnswerHandler(); Literal alpha = new Literal((AtomicSentence)query); // local variables: new, the new sentences inferred on each iteration List <Literal> newSentences = new List <Literal>(); // Ensure query is not already a know fact before // attempting forward chaining. List <Dictionary <Variable, Term> > answers = KB.fetch(alpha); if (answers.Count > 0) { ansHandler.addProofStep(new ProofStepFoChAlreadyAFact(alpha)); ansHandler.setAnswers(answers); return(ansHandler); } // repeat until new is empty do { // new <- {} newSentences.Clear(); // for each rule in KB do // (p1 ^ ... ^ pn => q) <-STANDARDIZE-VARIABLES(rule) foreach (Clause impl in KB.getAllDefiniteClauseImplications()) { Clause impl2 = KB.standardizeApart(impl); // for each theta such that SUBST(theta, p1 ^ ... ^ pn) = // SUBST(theta, p'1 ^ ... ^ p'n) // --- for some p'1,...,p'n in KB foreach (Dictionary <Variable, Term> theta in KB.fetch(invert(new List <Literal>(impl2 .getNegativeLiterals())))) { // q' <- SUBST(theta, q) Literal qPrime = KB.subst(theta, impl.getPositiveLiterals() [0]); // if q' does not unify with some sentence already in KB or // new then do if (!KB.isRenaming(qPrime) && !KB.isRenaming(qPrime, newSentences)) { // add q' to new newSentences.Add(qPrime); ansHandler.addProofStep(impl, qPrime, theta); // theta <- UNIFY(q', alpha) Dictionary <Variable, Term> theta2 = KB.unify(qPrime.getAtomicSentence(), alpha .getAtomicSentence()); // if theta is not fail then return theta if (null != theta2) { foreach (Literal l in newSentences) { Sentence s = null; if (l.isPositiveLiteral()) { s = l.getAtomicSentence(); } else { s = new NotSentence(l.getAtomicSentence()); } KB.tell(s); } ansHandler.setAnswers(KB.fetch(alpha)); return(ansHandler); } } } } // add new to KB foreach (Literal l in newSentences) { Sentence s = null; if (l.isPositiveLiteral()) { s = l.getAtomicSentence(); } else { s = new NotSentence(l.getAtomicSentence()); } KB.tell(s); } } while (newSentences.Count > 0); // return false return(ansHandler); }