public void PicksCorrectVariablesInSimpleCase() { // Predicate p(X,Y) :- q(X, Z), r(Z,Y) should have Z and Y as permanent variables var p = Literal.NewAtom(); var q = Literal.NewAtom(); var r = Literal.NewAtom(); var X = Literal.NewVariable(); var Y = Literal.NewVariable(); var Z = Literal.NewVariable(); var pXY = Literal.NewFunctor(2).With(X, Y); var qXZ = Literal.NewFunctor(2).With(X, Z); var rZY = Literal.NewFunctor(2).With(Z, Y); // Create the clause var clause = Clause.If(qXZ, rZY).Then(pXY); // Compile to assignments var allPredicates = new[] { clause.Implies }.Concat(clause.If).ToArray(); var assignmentList = allPredicates.Select(predicate => PredicateAssignmentList.FromPredicate(predicate)); // Get the set of permanent variables var permanent = PermanentVariableAssignments.PermanentVariables(assignmentList); // Z and Y are the only permanent variables Assert.IsFalse(permanent.Contains(X)); Assert.IsTrue(permanent.Contains(Y)); Assert.IsTrue(permanent.Contains(Z)); Assert.AreEqual(2, permanent.Count); }
public async Task ResolveAMoreComplicatedGoal() { var knowledge = KnowledgeBase.New(); var houseCat = Literal.NewFunctor(1); var feline = Literal.NewFunctor(1); var small = Literal.NewFunctor(1); var meows = Literal.NewFunctor(1); var tom = Literal.NewAtom(); var X = Literal.NewVariable(); var Y = Literal.NewVariable(); // houseCat(X) :- small(X), feline(X) var houseCatsAreSmallFelines = Clause.If(feline.With(X), small.With(X)).Then(houseCat.With(X)); var felinesMeow = Clause.If(meows.With(Y)).Then(feline.With(Y)); var tomIsSmall = Clause.Always(small.With(tom)); var tomMeows = Clause.Always(meows.With(tom)); knowledge = knowledge .Assert(houseCatsAreSmallFelines) .Assert(tomIsSmall) .Assert(felinesMeow) .Assert(tomMeows); var solver = await Solver.NewSolver(knowledge); var result = solver.Query(houseCat.With(tom)); Assert.IsTrue(result.Success); var allCats = solver.Query(houseCat.With(X)); Assert.IsTrue(result.Success); Assert.AreEqual(tom, allCats.Bindings.GetValueForVariable(X)); }
public async Task MultiChainQuery() { var knowledge = KnowledgeBase.New(); var houseCat = Literal.NewFunctor(1); var feline = Literal.NewFunctor(1); var small = Literal.NewFunctor(1); var meows = Literal.NewFunctor(1); var tom = Literal.NewAtom(); var heathcliff = Literal.NewAtom(); var sylvester = Literal.NewAtom(); var X = Literal.NewVariable(); var Y = Literal.NewVariable(); // houseCat(X) :- small(X), feline(X) var houseCatsAreSmallFelines = Clause.If(feline.With(X), small.With(X)).Then(houseCat.With(X)); var felinesMeow = Clause.If(meows.With(Y)).Then(feline.With(Y)); var tomIsSmall = Clause.Always(small.With(tom)); var heathcliffIsSmall = Clause.Always(small.With(heathcliff)); var sylvesterIsSmall = Clause.Always(small.With(sylvester)); var tomMeows = Clause.Always(meows.With(tom)); var heathcliffIsFeline = Clause.Always(feline.With(heathcliff)); var sylvesterMeows = Clause.Always(meows.With(sylvester)); knowledge = knowledge .Assert(houseCatsAreSmallFelines) .Assert(tomIsSmall) .Assert(felinesMeow) .Assert(tomMeows) .Assert(heathcliffIsSmall) .Assert(heathcliffIsFeline) .Assert(sylvesterIsSmall) .Assert(sylvesterMeows); var solver = new SimpleDispatchingSolver(); await solver.LoadFromKnowledgeBase(knowledge); // Get all the cats var start = DateTime.Now; for (var x = 0; x < 10000; ++x) { var allResults = new List <ILiteral>(); var any = Literal.NewVariable(); for (var result = solver.Query(houseCat.With(any)); result != null && result.Success; result = await result.Next()) { allResults.Add(result.Bindings.GetValueForVariable(any)); } Assert.IsTrue(allResults.Contains(tom)); Assert.IsTrue(allResults.Contains(heathcliff)); Assert.IsTrue(allResults.Contains(sylvester)); Assert.AreEqual(3, allResults.Count); } Console.WriteLine("10000 solutions in {0}s", (DateTime.Now - start).TotalSeconds); }
public async Task SimpleChainQuery() { var knowledge = KnowledgeBase.New(); var houseCat = Literal.NewFunctor(1); var feline = Literal.NewFunctor(1); var small = Literal.NewFunctor(1); var meows = Literal.NewFunctor(1); var tom = Literal.NewAtom(); var jerry = Literal.NewAtom(); var X = Literal.NewVariable(); var Y = Literal.NewVariable(); // houseCat(X) :- small(X), feline(X) var houseCatsAreSmallFelines = Clause.If(feline.With(X), small.With(X)).Then(houseCat.With(X)); var felinesMeow = Clause.If(meows.With(Y)).Then(feline.With(Y)); var tomIsSmall = Clause.Always(small.With(tom)); var jerryIsSmall = Clause.Always(small.With(jerry)); var tomMeows = Clause.Always(meows.With(tom)); knowledge = knowledge .Assert(houseCatsAreSmallFelines) .Assert(tomIsSmall) .Assert(felinesMeow) .Assert(jerryIsSmall) .Assert(tomMeows); var solver = new SimpleDispatchingSolver(); await solver.LoadFromKnowledgeBase(knowledge); // Tom is a housecat var result = solver.Query(houseCat.With(tom)); Assert.IsTrue(result.Success); Assert.IsFalse((await result.Next()).Success); // Jerry is not a housecat result = solver.Query(houseCat.With(jerry)); Assert.IsFalse(result.Success); }
public async Task ResolveASimpleGoal() { // Create some knowledge var knowledge = KnowledgeBase.New(); var houseCat = Literal.NewAtom(); var feline = Literal.NewAtom(); var small = Literal.NewAtom(); // Small felines are house cats and small and feline are true var houseCatsAreSmallFelines = Clause.If(feline, small).Then(houseCat); knowledge = knowledge.Assert(houseCatsAreSmallFelines); knowledge = knowledge.Assert(Clause.Always(feline)); knowledge = knowledge.Assert(Clause.Always(small)); // Solve for 'houseCat' (which should be true under this simple system) var solver = await Solver.NewSolver(knowledge); // Should be true var result = solver.Query(houseCat); Assert.IsTrue(result.Success); }
public void SimpleCompile() { var p = Literal.NewAtom(); var q = Literal.NewAtom(); var r = Literal.NewAtom(); var X = Literal.NewVariable(); var Y = Literal.NewVariable(); var Z = Literal.NewVariable(); var pXY = Literal.NewFunctor(2).With(X, Y); var qXZ = Literal.NewFunctor(2).With(X, Z); var rZY = Literal.NewFunctor(2).With(Z, Y); // p(X, Y) :- q(X, Z), r(Z, Y) var clause = Clause.If(qXZ, rZY).Then(pXY); // Compile ByteCodeProgram program = new ByteCodeProgram(); clause.Compile(program); Console.WriteLine(program.ToString()); }