// Note: see - // http://logic.stanford.edu/classes/cs157/2008/lectures/lecture15.pdf // slide 12 for where this test example was taken from. public static FOLKnowledgeBase createABCEqualityKnowledgeBase( InferenceProcedure infp, bool includeEqualityAxioms) { FOLDomain domain = new FOLDomain(); domain.addConstant("A"); domain.addConstant("B"); domain.addConstant("C"); FOLKnowledgeBase kb = new FOLKnowledgeBase(domain, infp); kb.tell("B = A"); kb.tell("B = C"); if (includeEqualityAxioms) { // Reflexivity Axiom kb.tell("x = x"); // Symmetry Axiom kb.tell("(x = y => y = x)"); // Transitivity Axiom kb.tell("((x = y AND y = z) => x = z)"); } return(kb); }
public void setUp() { StandardizeApartIndexicalFactory.flush(); weaponsKB = new FOLKnowledgeBase(DomainFactory.weaponsDomain()); kingsKB = new FOLKnowledgeBase(DomainFactory.kingsDomain()); }
public static FOLKnowledgeBase createKingsKnowledgeBase( InferenceProcedure infp) { FOLKnowledgeBase kb = new FOLKnowledgeBase(DomainFactory.kingsDomain(), infp); kb.tell("((King(x) AND Greedy(x)) => Evil(x))"); kb.tell("King(John)"); kb.tell("King(Richard)"); kb.tell("Greedy(John)"); return kb; }
public static FOLKnowledgeBase createKingsKnowledgeBase( InferenceProcedure infp) { FOLKnowledgeBase kb = new FOLKnowledgeBase(DomainFactory.kingsDomain(), infp); kb.tell("((King(x) AND Greedy(x)) => Evil(x))"); kb.tell("King(John)"); kb.tell("King(Richard)"); kb.tell("Greedy(John)"); return(kb); }
// // 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; }
// 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; }
public static FOLKnowledgeBase createLovesAnimalKnowledgeBase( InferenceProcedure infp) { FOLKnowledgeBase kb = new FOLKnowledgeBase(DomainFactory .lovesAnimalDomain(), infp); 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))"); return(kb); }
public static FOLKnowledgeBase createWeaponsKnowledgeBase( InferenceProcedure infp) { FOLKnowledgeBase kb = new FOLKnowledgeBase(DomainFactory .weaponsDomain(), infp); kb .tell("( (((American(x) AND Weapon(y)) AND Sells(x,y,z)) AND Hostile(z)) => Criminal(x))"); kb.tell(" Owns(Nono, M1)"); kb.tell(" Missile(M1)"); kb.tell("((Missile(x) AND Owns(Nono,x)) => Sells(West,x,Nono))"); kb.tell("(Missile(x) => Weapon(x))"); kb.tell("(Enemy(x,America) => Hostile(x))"); kb.tell("American(West)"); kb.tell("Enemy(Nono,America)"); return kb; }
public static FOLKnowledgeBase createLovesAnimalKnowledgeBase( InferenceProcedure infp) { FOLKnowledgeBase kb = new FOLKnowledgeBase(DomainFactory .lovesAnimalDomain(), infp); 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))"); return kb; }
// // START-Learner public void train(DataSet ds) { folDSDomain = new FOLDataSetDomain(ds.specification, trueGoalValue); List<FOLExample> folExamples = new List<FOLExample>(); int egNo = 1; foreach (Example e in ds.examples) { folExamples.Add(new FOLExample(folDSDomain, e, egNo)); egNo++; } // Setup a KB to be used for learning kb = new FOLKnowledgeBase(folDSDomain, new FOLOTTERLikeTheoremProver( 1000, false)); CurrentBestLearning cbl = new CurrentBestLearning(folDSDomain, kb); currentBestHypothesis = cbl.currentBestLearning(folExamples); }
public static FOLKnowledgeBase createWeaponsKnowledgeBase( InferenceProcedure infp) { FOLKnowledgeBase kb = new FOLKnowledgeBase(DomainFactory .weaponsDomain(), infp); kb .tell("( (((American(x) AND Weapon(y)) AND Sells(x,y,z)) AND Hostile(z)) => Criminal(x))"); kb.tell(" Owns(Nono, M1)"); kb.tell(" Missile(M1)"); kb.tell("((Missile(x) AND Owns(Nono,x)) => Sells(West,x,Nono))"); kb.tell("(Missile(x) => Weapon(x))"); kb.tell("(Enemy(x,America) => Hostile(x))"); kb.tell("American(West)"); kb.tell("Enemy(Nono,America)"); return(kb); }
public static FOLKnowledgeBase createRingOfThievesKnowledgeBase( InferenceProcedure infp) { FOLKnowledgeBase kb = new FOLKnowledgeBase(DomainFactory .ringOfThievesDomain(), infp); // s(x) => ~c(x) One who skis never gets caught kb.tell("(Skis(x) => NOT(Caught(x)))"); // c(x) => ~s(x) Those who are caught don't ever ski kb.tell("(Caught(x) => NOT(Skis(x)))"); // p(x,y) & c(y) => s(x) Jailbird parents have skiing kids kb.tell("((Parent(x,y) AND Caught(y)) => Skis(x))"); // s(x) & f(x,y) => s(y) All friends ski together kb.tell("(Skis(x) AND Friend(x,y) => Skis(y))"); // f(x,y) => f(y,x) Friendship is symmetric kb.tell("(Friend(x,y) => Friend(y,x))"); // FACTS // 1. { p(Mike,Joe) } Premise kb.tell("Parent(Mike, Joe)"); // 2. { p(Janet,Joe) } Premise kb.tell("Parent(Janet,Joe)"); // 3. { p(Nancy,Mike) } Premise kb.tell("Parent(Nancy,Mike)"); // 4. { p(Ernie,Janet) } Premise kb.tell("Parent(Ernie,Janet)"); // 5. { p(Bert,Nancy) } Premise kb.tell("Parent(Bert,Nancy)"); // 6. { p(Red,Ernie) } Premise kb.tell("Parent(Red,Ernie)"); // 7. { f(Red,Bert) } Premise kb.tell("Friend(Red,Bert)"); // 8. { f(Drew,Nancy) } Premise kb.tell("Friend(Drew,Nancy)"); // 9. { c(Mike) } Premise kb.tell("Caught(Mike)"); // 10. { c(Ernie) } Premise kb.tell("Caught(Ernie)"); return kb; }
public static FOLKnowledgeBase createRingOfThievesKnowledgeBase( InferenceProcedure infp) { FOLKnowledgeBase kb = new FOLKnowledgeBase(DomainFactory .ringOfThievesDomain(), infp); // s(x) => ~c(x) One who skis never gets caught kb.tell("(Skis(x) => NOT(Caught(x)))"); // c(x) => ~s(x) Those who are caught don't ever ski kb.tell("(Caught(x) => NOT(Skis(x)))"); // p(x,y) & c(y) => s(x) Jailbird parents have skiing kids kb.tell("((Parent(x,y) AND Caught(y)) => Skis(x))"); // s(x) & f(x,y) => s(y) All friends ski together kb.tell("(Skis(x) AND Friend(x,y) => Skis(y))"); // f(x,y) => f(y,x) Friendship is symmetric kb.tell("(Friend(x,y) => Friend(y,x))"); // FACTS // 1. { p(Mike,Joe) } Premise kb.tell("Parent(Mike, Joe)"); // 2. { p(Janet,Joe) } Premise kb.tell("Parent(Janet,Joe)"); // 3. { p(Nancy,Mike) } Premise kb.tell("Parent(Nancy,Mike)"); // 4. { p(Ernie,Janet) } Premise kb.tell("Parent(Ernie,Janet)"); // 5. { p(Bert,Nancy) } Premise kb.tell("Parent(Bert,Nancy)"); // 6. { p(Red,Ernie) } Premise kb.tell("Parent(Red,Ernie)"); // 7. { f(Red,Bert) } Premise kb.tell("Friend(Red,Bert)"); // 8. { f(Drew,Nancy) } Premise kb.tell("Friend(Drew,Nancy)"); // 9. { c(Mike) } Premise kb.tell("Caught(Mike)"); // 10. { c(Ernie) } Premise kb.tell("Caught(Ernie)"); return(kb); }
// // START-InferenceProcedure public InferenceResult ask(FOLKnowledgeBase KB, Sentence query) { // Assertions on the type queries this Inference procedure // supports if (!(query is AtomicSentence)) { throw new ArgumentException( "Only Atomic Queries are supported."); } List<Literal> goals = new List<Literal>(); goals.Add(new Literal((AtomicSentence)query)); BCAskAnswerHandler ansHandler = new BCAskAnswerHandler(); List<List<ProofStepBwChGoal>> allProofSteps = folbcask(KB, ansHandler, goals, new Dictionary<Variable, Term>()); ansHandler.setAllProofSteps(allProofSteps); return ansHandler; }
// Note: see - // http://logic.stanford.edu/classes/cs157/2008/lectures/lecture15.pdf // slide 16,17, and 18 for where this test example was taken from. public static FOLKnowledgeBase createABCDEqualityAndSubstitutionKnowledgeBase( InferenceProcedure infp, bool includeEqualityAxioms) { FOLDomain domain = new FOLDomain(); domain.addConstant("A"); domain.addConstant("B"); domain.addConstant("C"); domain.addConstant("D"); domain.addPredicate("P"); domain.addFunction("F"); FOLKnowledgeBase kb = new FOLKnowledgeBase(domain, infp); kb.tell("F(A) = B"); kb.tell("F(B) = A"); kb.tell("C = D"); kb.tell("P(A)"); kb.tell("P(C)"); if (includeEqualityAxioms) { // Reflexivity Axiom kb.tell("x = x"); // Symmetry Axiom kb.tell("(x = y => y = x)"); // Transitivity Axiom kb.tell("((x = y AND y = z) => x = z)"); // Function F Substitution Axiom kb.tell("((x = y AND F(y) = z) => F(x) = z)"); // Predicate P Substitution Axiom kb.tell("((x = y AND P(y)) => P(x))"); } return(kb); }
// // PUBLIC METHODS // public CurrentBestLearning(FOLDataSetDomain folDSDomain, FOLKnowledgeBase kbForLearning) { this.folDSDomain = folDSDomain; this.kbForLearning = kbForLearning; }
// See: // http://logic.stanford.edu/classes/cs157/2008/miscellaneous/faq.html#jump165 // for need for this. private Dictionary<Variable, Term> cascadeSubstitutions(FOLKnowledgeBase KB, Dictionary<Variable, Term> theta) { foreach (Variable v in theta.Keys) { Term t = theta[v]; theta.Add(v, KB.subst(theta, t)); } return theta; }
// Artificial Intelligence A Modern Approach (2nd Edition): page 288. // COMPOSE(delta, tau) is the substitution whose effect is identical to // the effect of applying each substitution in turn. That is, // SUBST(COMPOSE(theta1, theta2), p) = SUBST(theta2, SUBST(theta1, p)) private Dictionary<Variable, Term> compose(FOLKnowledgeBase KB, Dictionary<Variable, Term> theta1, Dictionary<Variable, Term> theta2) { Dictionary<Variable, Term> composed = new Dictionary<Variable, Term>(); // So that it behaves like: // SUBST(theta2, SUBST(theta1, p)) // There are two steps involved here. // See: http://logic.stanford.edu/classes/cs157/2008/notes/chap09.pdf // for a detailed discussion: // 1. Apply theta2 to the range of theta1. foreach (Variable v in theta1.Keys) { composed.Add(v, KB.subst(theta2, theta1[v])); } // 2. Adjoin to delta all pairs from tau with different // domain variables. foreach (Variable v in theta2.Keys) { if (!theta1.ContainsKey(v)) { composed.Add(v, theta2[v]); } } return cascadeSubstitutions(KB, composed); }
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 /** * <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; }
// // 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); }
public AnswerHandler(FOLKnowledgeBase kb, Sentence aQuery, long maxQueryTime, FOLModelElimination folModelElimination) { finishTime = System.DateTime.UtcNow.Ticks + maxQueryTime; Sentence refutationQuery = new NotSentence(aQuery); // Want to use an answer literal to pull // query variables where necessary Literal answerLiteral = kb.createAnswerLiteral(refutationQuery); answerLiteralVariables = kb.collectAllVariables(answerLiteral .getAtomicSentence()); // Create the Set of Support based on the Query. if (answerLiteralVariables.Count > 0) { Sentence refutationQueryWithAnswer = new ConnectedSentence( Connectors.OR, refutationQuery, (Sentence)answerLiteral .getAtomicSentence().copy()); sos = folModelElimination.createChainsFromClauses(kb .convertToClauses(refutationQueryWithAnswer)); answerChain.addLiteral(answerLiteral); } else { sos = folModelElimination.createChainsFromClauses(kb .convertToClauses(refutationQuery)); } foreach (Chain s in sos) { s.setProofStep(new ProofStepGoal(s)); } }
// Note: see - // http://logic.stanford.edu/classes/cs157/2008/lectures/lecture15.pdf // slide 16,17, and 18 for where this test example was taken from. public static FOLKnowledgeBase createABCDEqualityAndSubstitutionKnowledgeBase( InferenceProcedure infp, bool includeEqualityAxioms) { FOLDomain domain = new FOLDomain(); domain.addConstant("A"); domain.addConstant("B"); domain.addConstant("C"); domain.addConstant("D"); domain.addPredicate("P"); domain.addFunction("F"); FOLKnowledgeBase kb = new FOLKnowledgeBase(domain, infp); kb.tell("F(A) = B"); kb.tell("F(B) = A"); kb.tell("C = D"); kb.tell("P(A)"); kb.tell("P(C)"); if (includeEqualityAxioms) { // Reflexivity Axiom kb.tell("x = x"); // Symmetry Axiom kb.tell("(x = y => y = x)"); // Transitivity Axiom kb.tell("((x = y AND y = z) => x = z)"); // Function F Substitution Axiom kb.tell("((x = y AND F(y) = z) => F(x) = z)"); // Predicate P Substitution Axiom kb.tell("((x = y AND P(y)) => P(x))"); } return kb; }
// Note: see - // http://logic.stanford.edu/classes/cs157/2008/lectures/lecture15.pdf // slide 12 for where this test example was taken from. public static FOLKnowledgeBase createABCEqualityKnowledgeBase( InferenceProcedure infp, bool includeEqualityAxioms) { FOLDomain domain = new FOLDomain(); domain.addConstant("A"); domain.addConstant("B"); domain.addConstant("C"); FOLKnowledgeBase kb = new FOLKnowledgeBase(domain, infp); kb.tell("B = A"); kb.tell("B = C"); if (includeEqualityAxioms) { // Reflexivity Axiom kb.tell("x = x"); // Symmetry Axiom kb.tell("(x = y => y = x)"); // Transitivity Axiom kb.tell("((x = y AND y = z) => x = z)"); } return kb; }
public void testExhaustsSearchSpace() { // Taken from AIMA pg 679 FOLDomain domain = new FOLDomain(); domain.addPredicate("alternate"); domain.addPredicate("bar"); domain.addPredicate("fri_sat"); domain.addPredicate("hungry"); domain.addPredicate("patrons"); domain.addPredicate("price"); domain.addPredicate("raining"); domain.addPredicate("reservation"); domain.addPredicate("type"); domain.addPredicate("wait_estimate"); domain.addPredicate("will_wait"); domain.addConstant("Some"); domain.addConstant("Full"); domain.addConstant("French"); domain.addConstant("Thai"); domain.addConstant("Burger"); domain.addConstant("$"); domain.addConstant("_30_60"); domain.addConstant("X0"); FOLParser parser = new FOLParser(domain); // The hypothesis String c1 = "patrons(v,Some)"; String c2 = "patrons(v,Full) AND (hungry(v) AND type(v,French))"; String c3 = "patrons(v,Full) AND (hungry(v) AND (type(v,Thai) AND fri_sat(v)))"; String c4 = "patrons(v,Full) AND (hungry(v) AND type(v,Burger))"; String sh = "FORALL v (will_wait(v) <=> (" + c1 + " OR (" + c2 + " OR (" + c3 + " OR (" + c4 + ")))))"; Sentence hypothesis = parser.parse(sh); Sentence desc = parser .parse("(((((((((alternate(X0) AND NOT(bar(X0))) AND NOT(fri_sat(X0))) AND hungry(X0)) AND patrons(X0,Full)) AND price(X0,$)) AND NOT(raining(X0))) AND NOT(reservation(X0))) AND type(X0,Thai)) AND wait_estimate(X0,_30_60))"); Sentence classification = parser.parse("will_wait(X0)"); FOLKnowledgeBase kb = new FOLKnowledgeBase(domain, new FOLOTTERLikeTheoremProver(false)); kb.tell(hypothesis); kb.tell(desc); InferenceResult ir = kb.ask(classification); Assert.IsFalse(ir.isTrue()); Assert.IsTrue(ir.isPossiblyFalse()); Assert.IsFalse(ir.isUnknownDueToTimeout()); Assert.IsFalse(ir.isPartialResultDueToTimeout()); Assert.AreEqual(0, ir.getProofs().Count); }
// // 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; }