public string Predict(Example e) { string prediction = "~" + e.TargetValue(); if (null != currentBestHypothesis) { var etp = new FOLExample(folDSDomain, e, 0); kb.Clear(); kb.tell(etp.GetDescription()); kb.tell(currentBestHypothesis.GetHypothesis()); IInferenceResult ir = kb.Ask(etp.GetClassification()); if (ir.IsTrue()) { if (trueGoalValue.Equals(e.TargetValue())) { prediction = e.TargetValue(); } } else if (ir.IsPossiblyFalse() || ir.IsUnknownDueToTimeout()) { if (!trueGoalValue.Equals(e.TargetValue())) { prediction = e.TargetValue(); } } } return(prediction); }
public void testAddRuleAndFact() { weaponsKB.tell("(Missile(x) => Weapon(x))"); Assert.AreEqual(1, weaponsKB.getNumberRules()); weaponsKB.tell("American(West)"); Assert.AreEqual(1, weaponsKB.getNumberRules()); Assert.AreEqual(1, weaponsKB.getNumberFacts()); }
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); }
// TODO - Implement!!! public Hypothesis currentBestLearning(ICollection <FOLExample> examples) { // TODO-use the default from pg 769 for now. 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 + ")))))"; Hypothesis h = new Hypothesis(kbForLearning.tell(sh)); return(h); }
// 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); }
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))"); ISet <Clause> clauses = CollectionFactory.CreateSet <Clause>(); clauses.AddAll(kb.getAllClauses()); ISet <Clause> newClauses = CollectionFactory.CreateSet <Clause>(); long maxRunTime = 30 * 1000; // 30 seconds IDateTime finishTime = CommonFactory.Now().AddMilliseconds(maxRunTime); do { clauses.AddAll(newClauses); newClauses.Clear(); Clause[] clausesA = clauses.ToArray(); 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.AddAll(cI.getFactors()); newClauses.AddAll(cJ.getFactors()); ISet <Clause> cIresolvents = cI.binaryResolvents(cJ); ISet <Clause> cJresolvents = cJ.binaryResolvents(cI); if (!cIresolvents.SequenceEqual(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 important, which should not be the case"); } foreach (Clause r in cIresolvents) { newClauses.AddAll(r.getFactors()); } if (CommonFactory.Now().BiggerThan(finishTime)) { break; } } if (CommonFactory.Now().BiggerThan(finishTime)) { break; } } } while (CommonFactory.Now().SmallerThan(finishTime)); }
// If your activity returns a value, derive from CodeActivity<TResult> // and return the value from the Execute method. protected override void Execute(CodeActivityContext context) { FOLKnowledgeBase kb = context.GetValue <FOLKnowledgeBase>(KB); kb.tell(TellText); }