public async Task ManyHouseCats() { var tom = Literal.NewAtom(); var heathcliff = Literal.NewAtom(); var sylvester = Literal.NewAtom(); var houseCat = Literal.NewFunctor(1); var any = Literal.NewVariable(); var knowledge = KnowledgeBase.New() .Assert(Clause.Always(houseCat.With(tom))) .Assert(Clause.Always(houseCat.With(heathcliff))) .Assert(Clause.Always(houseCat.With(sylvester))); // Get all the cats var solver = new SimpleDispatchingSolver(); await solver.LoadFromKnowledgeBase(knowledge); var allResults = new List <ILiteral>(); 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); }
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 void SolveAsSelf() { var a = Literal.NewAtom(); var b = Literal.NewAtom(); var fab = Literal.NewFunctor(2).With(a, b); var clause = Clause.Always(fab); var solver = new SimpleSingleClauseSolver(clause, new NothingSolver()); Assert.IsTrue(solver.Query(fab).Success); }
public void DifferentDoesNotSolve() { var a = Literal.NewAtom(); var b = Literal.NewAtom(); var c = Literal.NewAtom(); var f = Literal.NewFunctor(2); var fab = f.With(a, b); var fac = f.With(a, c); var clause = Clause.Always(fab); var solver = new SimpleSingleClauseSolver(clause, new NothingSolver()); Assert.IsFalse(solver.Query(fac).Success); }
public void SolveWithVariable() { var a = Literal.NewAtom(); var b = Literal.NewAtom(); var f = Literal.NewFunctor(2); var X = Literal.NewVariable(); var fab = f.With(a, b); var fXb = f.With(X, b); var clause = Clause.Always(fab); var solver = new SimpleSingleClauseSolver(clause, new NothingSolver()); Assert.IsTrue(solver.Query(fXb).Success); }
public void VariablesThatCantUnifyCantBeSolved2() { // The arguments a,b can't unify against X,X as X can't be both values var a = Literal.NewAtom(); var b = Literal.NewAtom(); var f = Literal.NewFunctor(2); var X = Literal.NewVariable(); var fab = f.With(a, b); var fXX = f.With(X, X); var clause = Clause.Always(fab); var solver = new SimpleSingleClauseSolver(clause, new NothingSolver()); Assert.IsFalse(solver.Query(fXX).Success); }
public void VariablesThatCantUnifyCantBeSolved1() { // An argument of f(X, X) can't unify against f(a, b) as X can't be both b and a var a = Literal.NewAtom(); var b = Literal.NewAtom(); var f = Literal.NewFunctor(2); var g = Literal.NewFunctor(1); var X = Literal.NewVariable(); var gfab = g.With(f.With(a, b)); var gfXX = g.With(f.With(X, X)); var clause = Clause.Always(gfab); var solver = new SimpleSingleClauseSolver(clause, new NothingSolver()); Assert.IsFalse(solver.Query(gfXX).Success); }
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 SolveSimplePredicate() { // Knowledge is a(x) var a = Literal.NewFunctor(1); var x = Literal.NewAtom(); var aOfX = a.With(x); var knowledge = KnowledgeBase.New().Assert(Clause.Always(aOfX)); // Generate a bytecode solver for this var solver = new ByteCodeSolver(); await solver.Compile(knowledge); // Call it with the query a(Y) var refToY = new SimpleReference(); var solve = solver.Call(a, refToY); var solved = solve(); Assert.IsTrue(solved); Assert.AreEqual(x, refToY.Term); }
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); }