Encodes 9x9 or 16x16 Sudoku to CNF, solves with Z3, and decodes back to a completed grid.
- OCaml compiler (
ocamlc) - Z3 SAT solve
make clean
make
make runPipeline:
./sudoku2cnf input.txt > problem.cnf- Encode puzzle to CNFz3 -dimacs problem.cnf > sat_output.txt- Solve with Z3./sol2grid sat_output.txt > output.txt- Decode solution
Expected Output: output.txt contains the solved Sudoku grid (if exists) or No solution exists.
make -f Makefile.multi clean
make -f Makefile.multi
make -f Makefile.multi runPipeline:
./sudoku2cnf input.txt > problem.cnf- Encode puzzle to CNFz3 -dimacs problem.cnf > sat_output.txt- Solve with Z3./sol2grid2 sat_output.txt > output.txt- Decode and check uniqueness
Expected Output: output.txt contains the solved grid + uniqueness message (Unique solution or Multiple solutions) or No solution.
- One row per line, use
.for empty cells - 9x9: digits
1-9 - 16x16: digits
0-9and lettersA-F
Example input.txt (9x9):
53..7....
6..195...
.98....6.
8...6...3
4..8.3..1
7...2...6
.6....28.
...419..5
....8..79
make checkVerifies the solution against the original puzzle.
- Reads Sudoku from
input.txt - Writes clauses in DIMACS format to
problem.cnf - 5 types of constraints are written -> givens -> at least one value per cell -> at most one value per cell -> row uniqueness -> column uniqueness -> block uniqueness
- map function used for variable indexing, e.g., for 9x9:
var(i,j,v) = 81*(v-1) + 9*i + j + 1 - all the print statements for clauses are written along with the constraints
- clauses are counted before hand to write the header, = given_numbers_in_sudoku + (size * size) + (size * size * choose2 size) + 3 * (size * size * choose2 size)
- Reads Z3 output from
sat_output.txt - if first line is
s UNSATISFIABLE, printsNo solution exists - else reads variable assignments, filters positive ones and decodes them back to grid format
- uses inverse of map function to decode variable indices back to (i,j,v)
- Similar to sol2grid.ml but also checks for uniqueness
- After decoding the first solution, adds a clause to block that solution and re-runs Z3
- If second solution found, prints
Multiple solutions, elseUnique solution