コード例 #1
0
        public void SudokuTest()
        {
            var p      = new Problem("Sudoku");
            var digits = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
            var cell   = Predicate <int, int, int>("cell");

            foreach (var rank in digits)
            {
                foreach (var d in digits)
                {
                    p.Unique(digits, row => cell(row, rank, d));
                    p.Unique(digits, column => cell(rank, column, d));
                }
            }
            foreach (var row in digits)
            {
                foreach (var col in digits)
                {
                    p.Unique(digits, d => cell(row, col, d));
                }
            }

            for (int i = 0; i < 100; i++)
            {
                p.Solve();
            }
        }
コード例 #2
0
        public void NameTest()
        {
            string[] boys  = { "john", "joe", "jim", "james" };
            var      bMenu = new Menu <string>("boys", boys);

            string[] girls = { "jenny", "jane", "janet", "julie" };
            var      gMenu = new Menu <string>("girls", girls);

            string[] surnames = { "jones", "johnson", "jefferson", "jackson" };
            var      sMenu    = new Menu <string>("surnames", surnames);

            var p         = new Problem("NameTest");
            var firstName = new MenuVariable <string>("first", null, p);
            var lastName  = (MenuVariable <string>)sMenu.Instantiate("last", p);
            var male      = (Proposition)"male";
            var female    = (Proposition)"female";

            p.Assert(firstName.In(bMenu) <= male);
            p.Assert(firstName.In(gMenu) <= female);
            p.Unique(male, female);
            for (int i = 0; i < 100; i++)
            {
                var m = p.Solve();
                Console.WriteLine(m.Model);
                Assert.IsTrue(surnames.Contains(lastName.Value(m)));
                Assert.IsTrue((m[male] && boys.Contains(firstName.Value(m)))
                              ||
                              (m[female] && girls.Contains(firstName.Value(m))));
            }
        }
コード例 #3
0
        public void NRooksTest()
        {
            var n = 8;

            var p = new Problem("N rooks");

            // 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 one rook in each row
            foreach (var i in Range(0, n))
            {
                p.Unique(Range(0, n), j => rook(i, j));
            }

            // There should be one rook in each column
            foreach (var j in Range(0, n))
            {
                p.Unique(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.Unique(Range(0, n), j => rook(i, j));
            }
            foreach (var j in Range(0, n))
            {
                m.Unique(Range(0, n), i => rook(i, j));
            }
        }
コード例 #4
0
        public void QuantificationConstantFoldingSatisfiableTest()
        {
            var p = new Problem("QuantificationConstantFoldingTest");

            p.Unique(true, false, "a", "b");
            for (int i = 0; i < 100; i++)
            {
                var s = p.Solve();
                Assert.IsFalse(s["a"] || s["b"]);
            }
        }
コード例 #5
0
        public void QuantificationNoConstantFoldingTest()
        {
            var p = new Problem("QuantificationConstantFoldingTest");

            p.Unique("a", "b");
            for (int i = 0; i < 100; i++)
            {
                var s = p.Solve();
                Assert.IsTrue(s["a"] ^ s["b"]);
            }
        }
コード例 #6
0
ファイル: PseudoSMT.cs プロジェクト: ianhorswill/CatSAT
        public void PSMTNPCStatsTest()
        {
            SMTVar.Reset();
            var p        = new Problem("NPC stats");
            var str      = new SMTVar("str", 0, 10);
            var con      = new SMTVar("con", 0, 10);
            var dex      = new SMTVar("dex", 0, 10);
            var intel    = new SMTVar("int", 0, 10);
            var wis      = new SMTVar("wis", 0, 10);
            var charisma = new SMTVar("char", 0, 10);

            p.Unique("fighter", "magic user", "cleric", "thief");
            p.Assert(
                ((Expression)(Proposition)"fighter") > (str > intel),
                ((Expression)(Proposition)"fighter") > (str > 5),
                ((Expression)(Proposition)"fighter") > (con > 5),
                ((Expression)(Proposition)"fighter") > (intel < 8),
                ((Expression)(Proposition)"magic") > (str < intel),
                ((Expression)(Proposition)"magic") > (intel > 5),
                ((Expression)(Proposition)"magic") > (str < 8),
                ((Expression)(Proposition)"cleric") > (wis > 5),
                ((Expression)(Proposition)"cleric") > (con < wis),
                ((Expression)(Proposition)"theif") > (dex > 5),
                ((Expression)(Proposition)"theif") > (charisma > 5),
                ((Expression)(Proposition)"theif") > (wis < 5),
                ((Expression)(Proposition)"theif") > (dex > str),
                ((Expression)(Proposition)"theif") > (charisma > intel)
                );
            for (int i = 0; i < 100; i++)
            {
                Solution solution;
                do
                {
                    solution = p.Solve();
                } while (!SMTVar.Solve(solution));
            }
        }
コード例 #7
0
        public void QuantificationConstantFoldingTooManyTest()
        {
            var p = new Problem("QuantificationConstantFoldingTest");

            p.Unique(true, true, "a", "b");
        }
コード例 #8
0
        public void FamilyGeneratorTest()
        {
            var p = new Problem("family generator");

            var FamilySize       = 25;
            var generationCount  = 5;
            var matriarch        = 1;
            var cast             = Enumerable.Range(matriarch, FamilySize).ToArray();
            var kids             = Enumerable.Range(matriarch + 1, FamilySize - 1).ToArray();
            var childGenerations = Enumerable.Range(1, generationCount - 1).ToArray();
            var female           = Predicate <int>("female");
            var generation       = Predicate <int, int>("generation");
            var parent           = Predicate <int, int>("parent");

            // Interestingly, this doesn't seem to speed things up.
            //Func<int, int, Proposition> parent = (child, par) =>
            //    child > par ? p.GetProposition(Call.FromArgs(Problem.Current, "parent", child, par)) : false;

            // Make of person # who is person number -who
            int Mate(int who) => - who;

            // Family must be 40-60% female
            p.Quantify((int)(FamilySize * .4), (int)(FamilySize * .6), kids, female);

            // Matriarch is the generation 0 female
            p.Assert(female(matriarch), Not(female(Mate(matriarch))));
            p.Assert(generation(matriarch, 0));

            foreach (var child in kids)
            {
                // Everyone has exactly one parent from within the family (and one from outside)
                p.Unique(cast, par => parent(child, par));
                foreach (var par in cast)
                {
                    parent(child, par).InitialProbability = 0;
                }
                // Everyone has a generation number
                p.Unique(childGenerations, g => generation(child, g));
                p.Assert(
                    // Only matriarch and patriarch are generation 0
                    Not(generation(child, 0)),
                    // Heteronormativity
                    female(child) == Not(female(Mate(child))));
                foreach (var par in cast)
                {
                    foreach (var g in childGenerations)
                    {
                        // Child's generation is one more than parent's generation
                        p.Assert(generation(child, g) <= (parent(child, par) & generation(par, g - 1)));
                    }
                }
            }
            // Every generation has at least one kid
            foreach (var g in childGenerations)
            {
                p.Exists(kids, k => generation(k, g));
            }
            p.Optimize();

            Console.WriteLine(p.Stats);
            Console.WriteLine(p.PerformanceStatistics);
            Console.WriteLine();

            for (int i = 0; i < 100; i++)
            {
                var s = p.Solve();
                Console.WriteLine(p.PerformanceStatistics);
                void PrintTree(int who, int depth)
                {
                    for (int j = 0; j < depth; j++)
                    {
                        Console.Write("    ");
                    }
                    Console.WriteLine($"{Gender(who)} {who}: + {Mate(who)}");
                    foreach (var child in kids.Where(k => s[parent(k, who)]))
                    {
                        PrintTree(child, depth + 1);
                    }
                }

                string Gender(int who)
                {
                    return(s[female(who)] ? "female" : "male");
                }

                PrintTree(matriarch, 0);
            }
        }