Beispiel #1
0
        private static void Main(string[] args)
        {
            // Basic Usage
            using (var ctx = new Z3Context())
            {
                ctx.Log = Console.Out; // see internal logging

                var theorem = from t in ctx.NewTheorem(new { x = default(bool), y = default(bool) })
                              where t.x ^ t.y
                              select t;

                var result = theorem.Solve();
                Console.WriteLine(result);
            }

            // Advanced Usage
            using (var ctx = new Z3Context())
            {
                ctx.Log = Console.Out; // see internal logging

                var theorem = from t in ctx.NewTheorem <Symbols <int, int> >()
                              where t.X1 < t.X2 + 1
                              where t.X1 > 2
                              where t.X1 != t.X2
                              select t;

                var result = theorem.Solve();
                Console.WriteLine(result);
            }

            // Sudoku Extension Usage (Z3.LinqBinding.Sudoku)
            using (var ctx = new Z3Context())
            {
                var theorem = from t in SudokuTheorem.Create(ctx)
                              where t.Cell13 == 2 && t.Cell16 == 1 && t.Cell18 == 6
                              where t.Cell23 == 7 && t.Cell26 == 4
                              where t.Cell31 == 5 && t.Cell37 == 9
                              where t.Cell42 == 1 && t.Cell44 == 3
                              where t.Cell51 == 8 && t.Cell55 == 5 && t.Cell59 == 4
                              where t.Cell66 == 6 && t.Cell68 == 2
                              where t.Cell73 == 6 && t.Cell79 == 7
                              where t.Cell84 == 8 && t.Cell87 == 3
                              where t.Cell92 == 4 && t.Cell94 == 9 && t.Cell97 == 2
                              select t;

                var result = theorem.Solve();
                Console.WriteLine(result);
            }

            // All samples
            using (var ctx = new Z3Context())
            {
                ctx.Log = Console.Out; // see internal logging

                Print(from t in ctx.NewTheorem(new { x = default(bool) })
                      where t.x && !t.x
                      select t);

                Print(from t in ctx.NewTheorem(new { x = default(bool), y = default(bool) })
                      where t.x ^ t.y
                      select t);

                Print(from t in ctx.NewTheorem(new { x = default(int), y = default(int) })
                      where t.x < t.y + 1
                      where t.x > 2
                      select t);

                Print(from t in ctx.NewTheorem <Symbols <int, int> >()
                      where t.X1 < t.X2 + 1
                      where t.X1 > 2
                      where t.X1 != t.X2
                      select t);

                Print(from t in ctx.NewTheorem <Symbols <int, int, int, int, int> >()
                      where t.X1 - t.X2 >= 1
                      where t.X1 - t.X2 <= 3
                      where t.X1 == (2 * t.X3) + t.X5
                      where t.X3 == t.X5
                      where t.X2 == 6 * t.X4
                      select t);

                Print(from t in ctx.NewTheorem <Symbols <int, int> >()
                      where Z3Methods.Distinct(t.X1, t.X2)
                      select t);

                Print(from t in SudokuTheorem.Create(ctx)
                      where t.Cell13 == 2 && t.Cell16 == 1 && t.Cell18 == 6
                      where t.Cell23 == 7 && t.Cell26 == 4
                      where t.Cell31 == 5 && t.Cell37 == 9
                      where t.Cell42 == 1 && t.Cell44 == 3
                      where t.Cell51 == 8 && t.Cell55 == 5 && t.Cell59 == 4
                      where t.Cell66 == 6 && t.Cell68 == 2
                      where t.Cell73 == 6 && t.Cell79 == 7
                      where t.Cell84 == 8 && t.Cell87 == 3
                      where t.Cell92 == 4 && t.Cell94 == 9 && t.Cell97 == 2
                      select t);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Creates a Z3-capable theorem to solve a Sudoku
        /// </summary>
        /// <param name="context">The wrapping Z3 context used to interpret c# Lambda into Z3 constraints</param>
        /// <returns>A typed theorem to be further filtered with additional contraints</returns>
        public static Theorem <Sudoku.Core.Sudoku> CreateTheorem(Z3Context context, Sudoku.Core.Sudoku s)
        {
            var sudokuTheorem = context.NewTheorem <Sudoku.Core.Sudoku>();


            for (int i = 0; i < 81; i++)
            {
                if (s.Cells[i] != 0)
                {
                    var idx       = i;
                    var cellValue = s.Cells[i];
                    sudokuTheorem = sudokuTheorem.Where(sudoku => sudoku.Cells[idx] == cellValue);
                }
            }



            // Cells have values between 1 and 9
            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    //To avoid side effects with lambdas, we copy indices to local variables
                    var i1 = i;
                    var j1 = j;
                    sudokuTheorem = sudokuTheorem.Where(sudoku => (sudoku.Cells[i1 * 9 + j1] > 0 && sudoku.Cells[i1 * 9 + j1] < 10));
                }
            }

            // Rows must have distinct digits
            for (int r = 0; r < 9; r++)
            {
                //Again we avoid Lambda closure side effects
                var r1 = r;
                sudokuTheorem = sudokuTheorem.Where(t => Z3Methods.Distinct(Indices.Select(j => t.Cells[r1 * 9 + j]).ToArray()));
            }

            // Columns must have distinct digits
            for (int c = 0; c < 9; c++)
            {
                //Preventing closure side effects
                var c1 = c;
                sudokuTheorem = sudokuTheorem.Where(t => Z3Methods.Distinct(Indices.Select(i => t.Cells[i * 9 + c1]).ToArray()));
            }

            // Boxes must have distinct digits
            for (int b = 0; b < 9; b++)
            {
                //On évite les effets de bords par closure
                var b1 = b;
                // We retrieve to top left cell for all boxes, using integer division and remainders.
                var iStart     = b1 / 3;
                var jStart     = b1 % 3;
                var indexStart = iStart * 3 * 9 + jStart * 3;
                sudokuTheorem = sudokuTheorem.Where(t => Z3Methods.Distinct(new int[]
                {
                    t.Cells[indexStart],
                    t.Cells[indexStart + 1],
                    t.Cells[indexStart + 2],
                    t.Cells[indexStart + 9],
                    t.Cells[indexStart + 10],
                    t.Cells[indexStart + 11],
                    t.Cells[indexStart + 18],
                    t.Cells[indexStart + 19],
                    t.Cells[indexStart + 20],
                }
                                                                            )
                                                    );
            }

            return(sudokuTheorem);
        }
Beispiel #3
0
        private static void AllSamplesInSameContext()
        {
            // All samples
            using (var ctx = new Z3Context())
            {
                ctx.Log = Console.Out; // see internal logging

                Print(from t in ctx.NewTheorem(new
                {
                    x = default(bool)
                })

                      where t.x && !t.x
                      select t);

                Print(from t in ctx.NewTheorem(new
                {
                    x = default(bool),
                    y = default(bool)
                })

                      where t.x ^ t.y
                      select t);

                Print(from t in ctx.NewTheorem(new
                {
                    x = default(int),
                    y = default(int)
                })

                      where t.x < t.y + 1
                      where t.x > 2
                      select t);

                Print(from t in ctx.NewTheorem <Symbols <int, int> >()
                      where t.X1 < t.X2 + 1
                      where t.X1 > 2
                      where t.X1 != t.X2
                      select t);

                Print(from t in ctx.NewTheorem <Symbols <int, int, int, int, int> >()
                      where t.X1 - t.X2 >= 1
                      where t.X1 - t.X2 <= 3
                      where t.X1 == (2 * t.X3) + t.X5
                      where t.X3 == t.X5
                      where t.X2 == 6 * t.X4
                      select t);

                Print(from t in ctx.NewTheorem <Symbols <int, int> >()
                      where Z3Methods.Distinct(t.X1, t.X2)
                      select t);

                Print(from t in SudokuTheorem.Create(ctx)
                      where t.Cell13 == 2 && t.Cell16 == 1 && t.Cell18 == 6
                      where t.Cell23 == 7 && t.Cell26 == 4
                      where t.Cell31 == 5 && t.Cell37 == 9
                      where t.Cell42 == 1 && t.Cell44 == 3
                      where t.Cell51 == 8 && t.Cell55 == 5 && t.Cell59 == 4
                      where t.Cell66 == 6 && t.Cell68 == 2
                      where t.Cell73 == 6 && t.Cell79 == 7
                      where t.Cell84 == 8 && t.Cell87 == 3
                      where t.Cell92 == 4 && t.Cell94 == 9 && t.Cell97 == 2
                      select t);


                // Sudoku Extension Usage Z3.LinqBinding.Sudoku demonstrating array capabilities

                Print <SudokuAsArray>(SudokuAsArray
                                      .Parse("9.2..54.31...63.255.84.7.6..263.9..1.57.1.29..9.67.53.24.53.6..7.52..3.4.8..4195.") // Very easy
                                      .CreateTheorem(ctx));
                Print <SudokuAsArray>(SudokuAsArray
                                      .Parse("..48...1767.9.....5.8.3...43..74.1...69...78...1.69..51...8.3.6.....6.9124...15..") // Easy
                                      .CreateTheorem(ctx));
                Print <SudokuAsArray>(SudokuAsArray
                                      .Parse("..6.......8..542...4..9..7...79..3......8.4..6.....1..2.3.67981...5...4.478319562") // Medium
                                      .CreateTheorem(ctx));
                Print <SudokuAsArray>(SudokuAsArray
                                      .Parse("....9.4.8.....2.7..1.7....32.4..156...........952..7.19....5.1..3.4.....1.2.7....") // Hard
                                      .CreateTheorem(ctx));

                // Solving Canibals & Missionaires
                var can = new MissionariesAndCannibals()
                {
                    NbMissionaries = 3, SizeBoat = 2, Length = 50
                };
                Print <MissionariesAndCannibals>(can.Create(ctx));
            }
        }