예제 #1
0
        public void PartyGeneratorTest()
        {
            var prog         = new Problem("Party generator");
            var cast         = new[] { "fred", "jenny", "sally" };
            var character    = Predicate <string>("character");
            var human        = Predicate <string>("human");
            var electroid    = Predicate <string>("electroid");
            var insectoid    = Predicate <string>("insectoid");
            var fighter      = Predicate <string>("fighter");
            var magicUser    = Predicate <string>("magic_user");
            var cleric       = Predicate <string>("cleric");
            var thief        = Predicate <string>("thief");
            var landia       = Predicate <string>("landia");
            var placeville   = Predicate <string>("placeville");
            var cityburgh    = Predicate <string>("cityburgh");
            var monotheist   = Predicate <string>("monotheist");
            var pantheist    = Predicate <string>("pantheist");
            var lovecraftian = Predicate <string>("lovecraftian");
            var dawkinsian   = Predicate <string>("dawkinsian");


            foreach (var who in cast)
            {
                prog.Assert(character(who));
                // Races
                Partition(character(who), human(who), electroid(who), insectoid(who));

                // Classes
                Partition(character(who), fighter(who), magicUser(who), cleric(who), thief(who));
                prog.Inconsistent(electroid(who), cleric(who));

                // Nationalities of humans
                Partition(human(who), landia(who), placeville(who), cityburgh(who));

                // Religions of clerics
                Partition(cleric(who), monotheist(who), pantheist(who), lovecraftian(who), dawkinsian(who));
                // Lovecraftianism is outlawed in Landia
                prog.Inconsistent(landia(who), lovecraftian(who));
                // Insectoids believe in strict hierarchies
                prog.Inconsistent(insectoid(who), pantheist(who));
                // Lovecraftianism is the state religion of cityburgh
                prog.Inconsistent(cityburgh(who), cleric(who), Not(lovecraftian(who)));
            }

            prog.AtMost(1, cast, fighter);
            prog.AtMost(1, cast, magicUser);
            prog.AtMost(1, cast, cleric);
            prog.AtMost(1, cast, thief);


            for (int i = 0; i < 100; i++)
            {
                Console.WriteLine(prog.Solve().Model);
            }
        }
예제 #2
0
        public void NRooksHarderTest()
        {
            var n = 8;

            var p = new Problem("N rooks hard")
            {
                Timeout = 2000000
            };


            // rook(i, j) means there's a root at row i, column j
            var rook = Predicate <int, int>("rook");

            //
            // Add constraint to the program
            //

            // There should be a total of n rooks
            p.Exactly(n, Range(0, n).SelectMany(i => Range(0, n).Select(j => rook(i, j))));

            // There should be at most one rook in each row
            foreach (var i in Range(0, n))
            {
                p.AtMost(1, Range(0, n), j => rook(i, j));
            }

            // There should be at most one rook in each column
            foreach (var j in Range(0, n))
            {
                p.AtMost(1, Range(0, n), i => rook(i, j));
            }

            var m = p.Solve();

            //
            // Test the constraint in the solution
            //

            m.Exactly(n, Range(0, n).SelectMany(i => Range(0, n).Select(j => rook(i, j))));
            foreach (var i in Range(0, n))
            {
                m.AtMost(1, Range(0, n).Select(j => rook(i, j)));
            }
            foreach (var j in Range(0, n))
            {
                m.AtMost(1, Range(0, n).Select(i => rook(i, j)));
            }
        }
예제 #3
0
        public void StoryTellerDemoTest()
        {
            var p           = new Problem("Storyteller demo rebuild");
            var cast        = new[] { "red", "green", "blue" }; // characters don't have names and gender doesn't matter
            var rich        = Predicate <string>("rich");
            var caged       = Predicate <string>("caged");
            var hasSword    = Predicate <string>("hasSword");
            var evil        = Predicate <string>("evil");
            var kill        = Predicate <string, string>("kill");
            var loves       = Predicate <string, string>("loves");
            var dead        = Predicate <string>("dead");
            var tombstone   = Predicate <string>("tombstone");
            var someoneFree = (Proposition)"someoneFree";

            // Panel 1 -> panel 2
            foreach (var x in cast)
            {
                p.Assert(
                    evil(x) == Not(rich(x)),
                    caged(x) > rich(x),
                    hasSword(x) == (rich(x) & Not(caged(x))),
                    someoneFree <= Not(caged(x)),
                    Not(kill(x, x))
                    );
                // You can't kill multiple people
                p.AtMost(1, cast, y => kill(x, y));
                foreach (var y in cast)
                {
                    p.Assert(
                        kill(x, y) > hasSword(x),
                        kill(x, y) > evil(y)
                        );
                }
            }

            // Panel 2 -> panel 3
            foreach (var x in cast)
            {
                foreach (var y in cast)
                {
                    p.Assert(
                        dead(y) <= kill(x, y),
                        tombstone(x) <= (caged(x) & evil(y) & Not(dead(y))),
                        tombstone(x) <= (Expression)Not(someoneFree),
                        tombstone(x) <= dead(x)
                        );
                    foreach (var z in cast)
                    {
                        p.Assert(loves(x, y) <= (caged(x) & kill(y, z)));
                    }
                }
            }

            Console.WriteLine(p.Stats);
            for (int i = 0; i < 100; i++)
            {
                var s = p.Solve();
                Console.WriteLine(s.Model);
            }
        }
예제 #4
0
        public void StoryTest()
        {
            var p = new Problem("murder test")
            {
                TimeHorizon = 4, Timeout = 50000
            };
            var cast = new[] { "Fred", "Betty", "Frieda" };

            // FLUENTS

            // alive(a, t) iff a alive at time t
            var alive   = Fluent("alive", cast);
            var married = Fluent("married", cast);

            // Everyone is initially alive an unmarried
            foreach (var c in cast)
            {
                p.Assert(alive(c, 0),
                         Not(married(c, 0)));
            }

            var hates     = Fluent("hates", cast, cast);
            var loves     = Fluent("loves", cast, cast);
            var marriedTo = SymmetricFluent("marriedTo", cast);

            foreach (var c1 in cast)
            {
                foreach (var c2 in cast)
                {
                    p.Assert(Not(marriedTo(c1, c2, 0)),
                             Not(loves(c1, c2, 0)));
                }
            }

            // Love and hate disable one another
            foreach (var agent in cast)
            {
                foreach (var patient in cast)
                {
                    foreach (var t in ActionTimePoints)
                    {
                        p.Assert(Deactivate(hates(agent, patient, t)) <= Activate(loves(agent, patient, t)),
                                 Deactivate(loves(agent, patient, t)) <= Activate(hates(agent, patient, t)));
                    }
                }
            }

            // ACTIONS
            // kill(a,b,t) means a kills b at time t
            var kill = Action("kill", cast, cast);

            Precondition(kill, (a, b, t) => alive(b, t));
            Precondition(kill, (a, b, t) => alive(a, t));
            Precondition(kill, (a, b, t) => hates(a, b, t));
            Deletes(kill, (a, b, t) => alive(b, t));

            // fallFor(faller, loveInterest, time)
            var fallFor = Action("fallFor", cast, cast);

            Precondition(fallFor, (f, l, t) => Not(loves(f, l, t)));
            Precondition(fallFor, (f, l, t) => alive(f, t));
            Precondition(fallFor, (f, l, t) => alive(l, t));
            Precondition(fallFor, (f, l, t) => f != l);
            Adds(fallFor, (f, l, t) => loves(f, l, t));

            // marry(a, b, t)
            var marry = SymmetricAction("marry", cast);

            Precondition(marry, (a, b, t) => loves(a, b, t));
            Precondition(marry, (a, b, t) => loves(b, a, t));
            Precondition(marry, (a, b, t) => a != b);
            Precondition(marry, (a, b, t) => alive(a, t));
            Precondition(marry, (a, b, t) => alive(b, t));
            Precondition(marry, (a, b, t) => Not(married(a, t)));
            Precondition(marry, (a, b, t) => Not(married(b, t)));
            Adds(marry, (a, b, t) => marriedTo(a, b, t));
            Adds(marry, (a, b, t) => married(a, t));
            Adds(marry, (a, b, t) => married(b, t));

            // You can't marry or fall in love with yourself
            foreach (var t in ActionTimePoints)
            {
                foreach (var c in cast)
                {
                    p.Assert(Not(marry(c, c, t)), Not(fallFor(c, c, t)));
                }
            }

            IEnumerable <ActionInstantiation> PossibleActions(int t)
            {
                return(Instances(kill, t).Concat(Instances(fallFor, t)).Concat(Instances(marry, t)));
            }

            foreach (var t in ActionTimePoints)
            {
                // Exactly one action per time point
                p.AtMost(1, PossibleActions(t));
            }

            // Tragedy strikes
            //foreach (var c in cast)
            //    p.Assert(Not(alive(c, TimeHorizon-1)));

            //p.Assert(married("Fred", 3));

            p.Optimize();

            Console.WriteLine(p.Stats);

            var s = p.Solve();

            foreach (var t in ActionTimePoints)
            {
                Console.Write($"Time {t}: ");
                foreach (var a in PossibleActions(t))
                {
                    if (s[a])
                    {
                        Console.Write($"{a}, ");
                    }
                }
                Console.WriteLine();
            }
        }
예제 #5
0
        public void MurderTest()
        {
            var p = new Problem("murder test")
            {
                TimeHorizon = 10
            };
            var cast = new[] { "fred", "lefty" };

            // FLUENT
            // alive(a, t) iff a alive at time t
            var alive = Fluent("alive", cast);

            // ACTION
            // kill(a,b,t) means a kills b at time t
            var kill = Action("kill", cast, cast);

            Precondition(kill, (a, b, t) => alive(b, t));
            Precondition(kill, (a, b, t) => alive(a, t));
            Deletes(kill, (a, b, t) => alive(b, t));

            // AXIOMS
            // No suicide
            foreach (var t in ActionTimePoints)
            {
                foreach (var a in cast)
                {
                    p.Assert(Not(kill(a, a, t)));
                }
            }

            // INITIAL CONDITIONS
            // Everyone is initially alive
            foreach (var c in cast)
            {
                p.Assert(alive(c, 0));
            }

            // GOAL
            // At least one character has to die.
            p.AtMost(1, cast, who => alive(who, TimeHorizon - 1));

            // SOLVE
            for (int i = 0; i < 100; i++)
            {
                var s       = p.Solve();
                var murders = new List <Proposition>();

                // Find all the murders
                foreach (var t in ActionTimePoints)
                {
                    foreach (var a in cast)
                    {
                        foreach (var b in cast)
                        {
                            if (s[kill(a, b, t)])
                            {
                                murders.Add(kill(a, b, t));
                            }
                        }
                    }
                }

                // There should be one, and at most two
                Assert.IsTrue(murders.Count > 0 && murders.Count <= 2);

                // If there are two, then they'd better have been simultaneous.
                if (murders.Count == 2)
                {
                    Assert.IsTrue(Equals(murders[0].Arg(2), murders[1].Arg(2)));
                }
            }
        }