public void testContrapositives() { List<Chain> conts; Literal p = new Literal(new Predicate("P", new List<Term>())); Literal notq = new Literal(new Predicate("Q", new List<Term>()), true); Literal notr = new Literal(new Predicate("R", new List<Term>()), true); Chain c = new Chain(); conts = c.getContrapositives(); Assert.AreEqual(0, conts.Count); c.addLiteral(p); conts = c.getContrapositives(); Assert.AreEqual(0, conts.Count); c.addLiteral(notq); conts = c.getContrapositives(); Assert.AreEqual(1, conts.Count); Assert.AreEqual("<~Q(),P()>", conts[0].ToString()); c.addLiteral(notr); conts = c.getContrapositives(); Assert.AreEqual(2, conts.Count); Assert.AreEqual("<~Q(),P(),~R()>", conts[0].ToString()); Assert.AreEqual("<~R(),P(),~Q()>", conts[1].ToString()); }
public ProofStepBwChGoal(Clause toProve, Literal currentGoal, Dictionary<Variable, Term> bindings) { this.toProve = toProve; this.currentGoal = currentGoal; foreach (Variable key in bindings.Keys) { this.bindings.Add(key, bindings[key]); } }
public ProofStepFoChAssertFact(Clause implication, Literal fact, Dictionary<Variable, Term> bindings, ProofStep predecessor) { this.implication = implication; this.fact = fact; this.bindings = bindings; if (null != predecessor) { predecessors.Add(predecessor); } }
public Literal subst(Dictionary<Variable, Term> theta, Literal aLiteral) { return aLiteral.newInstance((AtomicSentence)aLiteral .getAtomicSentence().accept(this, theta)); }
public OTTERAnswerHandler(Literal answerLiteral, List<Variable> answerLiteralVariables, Clause answerClause, long maxQueryTime) { this.answerLiteral = answerLiteral; this.answerLiteralVariables = answerLiteralVariables; this.answerClause = answerClause; // this.finishTime = DateTime.UtcNow.Ticks + maxQueryTime; }
private String getFactKey(Literal l) { StringBuilder key = new StringBuilder(); if (l.isPositiveLiteral()) { key.Append("+"); } else { key.Append("-"); } key.Append(l.getAtomicSentence().getSymbolicName()); return key.ToString(); }
private List<Literal> fetchMatchingFacts(Literal l) { if (!indexFacts.ContainsKey(getFactKey(l))) { return null; } return indexFacts[getFactKey(l)]; }
private void recursiveFetch(Dictionary<Variable, Term> theta, Literal l, List<Literal> remainingLiterals, List<Dictionary<Variable, Term>> possibleSubstitutions) { // Find all substitutions for current predicate based on the // substitutions of prior predicates in the list (i.e. SUBST with // theta). List<Dictionary<Variable, Term>> pSubsts = fetch(subst(theta, l)); // No substitutions, therefore cannot continue if (null == pSubsts) { return; } foreach (Dictionary<Variable, Term> psubst in pSubsts) { // Ensure all prior substitution information is maintained // along the chain of predicates (i.e. for shared variables // across the predicates). foreach(Variable key in theta.Keys) { psubst.Add(key,theta[key]); } if (remainingLiterals.Count == 0) { // This means I am at the end of the chain of predicates // and have found a valid substitution. possibleSubstitutions.Add(psubst); } else { // Need to move to the next link in the chain of substitutions Literal first = remainingLiterals[0]; List<Literal> rest = remainingLiterals.Skip(1).ToList<Literal>(); recursiveFetch(psubst, first, rest, possibleSubstitutions); } } }
// Note: see pg. 281 public bool isRenaming(Literal l, List<Literal> possibleMatches) { foreach (Literal q in possibleMatches) { if (l.isPositiveLiteral() != q.isPositiveLiteral()) { continue; } Dictionary<Variable, Term> subst = unifier.unify(l.getAtomicSentence(), q .getAtomicSentence()); if (null != subst) { int cntVarTerms = 0; foreach (Term t in subst.Values) { if (t is Variable) { cntVarTerms++; } } // If all the substitutions, even if none, map to Variables // then this is a renaming if (subst.Count == cntVarTerms) { return true; } } } return false; }
// Note: see pg. 281 public bool isRenaming(Literal l) { List<Literal> possibleMatches = fetchMatchingFacts(l); if (null != possibleMatches) { return isRenaming(l, possibleMatches); } return false; }
public Literal subst(Dictionary<Variable, Term> theta, Literal l) { return substVisitor.subst(theta, l); }
// Note: pg 278, FETCH(q) concept. public /* lock */ List<Dictionary<Variable, Term>> fetch(Literal l) { // Get all of the substitutions in the KB that p unifies with List<Dictionary<Variable, Term>> allUnifiers = new List<Dictionary<Variable, Term>>(); List<Literal> matchingFacts = fetchMatchingFacts(l); if (null != matchingFacts) { foreach (Literal fact in matchingFacts) { Dictionary<Variable, Term> substitution = unifier.unify(l .getAtomicSentence(), fact.getAtomicSentence()); if (null != substitution) { allUnifiers.Add(substitution); } } } return allUnifiers; }
// // 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; }
// END-InferenceResult // public void addProofStep(Clause implication, Literal fact, Dictionary<Variable, Term> bindings) { stepFinal = new ProofStepFoChAssertFact(implication, fact, bindings, stepFinal); }
public ProofStepFoChAlreadyAFact(Literal fact) { this.fact = fact; }
// Only if it is a unit clause does it get indexed as a fact // see pg. 279 for general idea. private void indexFact(Literal fact) { String factKey = getFactKey(fact); if (!indexFacts.ContainsKey(factKey)) { indexFacts.Add(factKey, new List<Literal>()); } indexFacts[factKey].Add(fact); }
public void addProofStep( List<List<ProofStepBwChGoal>> currentLevelProofSteps, Clause toProve, Literal currentGoal, Dictionary<Variable, Term> bindings) { if (currentLevelProofSteps.Count > 0) { ProofStepBwChGoal predecessor = new ProofStepBwChGoal(toProve, currentGoal, bindings); foreach (List<ProofStepBwChGoal> steps in currentLevelProofSteps) { if (steps.Count > 0) { steps[0].setPredecessor(predecessor); } steps.Insert(0, predecessor); } } }
public void addLiteral(Literal literal) { literals.Add(literal); }