I made this as a minor project in the second semester of my MSc IT.
Find a file
2021-07-02 00:47:19 +05:30
sudoku-screenshots final 2021-07-02 00:42:10 +05:30
.DS_Store final 2021-07-02 00:42:10 +05:30
_config.yml Set theme jekyll-theme-cayman 2021-05-20 14:00:04 +05:30
CNAME Create CNAME 2021-05-20 13:51:08 +05:30
db.pl final 2021-07-02 00:42:10 +05:30
README.md more minor fixes 2021-07-02 00:47:19 +05:30

INTRODUCTION

A Latin square of order n is an n × n array in which each cell contains a single symbol

from a set S with n elements, such that each symbol occurs exactly once in each row

and exactly once in each column.

Example:


a Latin square of order 3

A Sudoku Latin square is a Latin square of order 9 on the symbol set {1,..., 9} that

is partitioned into 3 × 3 squares, and each square contains all symbols.

This can also be represented as

This can be further represented as a list of variables:

And we represent the whole sudoku latin square as a list of lists.

So, in total, we have a list of rows.

CLP(FD) CONSTRAINTS

The library clpfd or Constraint Logic Programming over Finite Domains contains a lot

of built-in predicates that are useful for solving the Sudoku puzzle easily.

(ins)/2 states the domains of variables in some systems: fd_domain/3, domain/

all_distinct/ or alternatively: all_different/1, fd_all_different. describes a list of different integers

Examples :

Constraint Propagation:


CONSISTENCY TECHNIQUES

all_distinct/1 uses powerful methods from graph theory to prune the search space:

Using the previous example, the following graph states that X can be either 1 or 2, Y

can be either 1 or 2 and Z can be either 1, 2 or 3.

This is a value graph for a set of constraints.

Prolog automatically reasons about this value graph to detect whether there can still

be a solution and also to find out which assignment can not occur in a solution.
 

PROGRAM

:- use_module(library(clpfd)). % Including clpfd library.

% Defining a sudoku latin square:

sudoku (Rows) :-

    % Rows must be a list of length 9.
    length (Rows, 9),

    %Each of the rows must also be a list of 9.
    maplist(same_length(Rows), Rows),

    % The concatenation of all elements of this list is the list Vs.
    append(Rows, Vs),
    Vs ins 1..9,

    % We can define the all the elements of each of the rows
    % must be purely distinct.
    % We can do the following:
    % Rows = [Rs1|_], all_distinct(Rs1),
    % Rows = [_,Rs2|_], all_distinct(Rs2),
    % ...
    % But there is a simpler way to do this.

    maplist(all_distinct, Rows),
    % This states that all_distinct must hold for each of the rows.

    % Doing the same with columns.
    transpose(Rows, Columns),
    maplist(all_distinct, Columns),

    % Defining the sub-squares.
    Rows = [As,Bs,Cs,Ds,Es,Fs,Gs,Hs,Is],
    square(As, Bs, Cs),
    square(Ds, Es, Fs),
    square(Gs, Hs, Is).

square([], [], []). % This predicate uses 3 rows.

square([N1,N2,N3|Ns1],
       [N4,N5,N6|Ns2],
       [N7,N8,N9|Ns3]) :-
        all_distinct([N1,N2,N3,N4,N5,N6,N7,N8,N9]),
        square(Ns1, Ns2, Ns3).


% Defining different problems.

problem(1, [[_,_,_,_,_,4,_,_,2],
            [_,6,_,2,_,_,_,3,_],
            [_,8,_,_,_,3,5,_,9],
            [_,4,_,_,_,_,1,_,_],
            [1,_,_,7,_,5,_,_,_],
            [5,_,3,_,_,_,_,_,_],
            [_,9,_,3,_,_,_,_,_],
            [_,_,4,_,6,1,_,_,_],
            [_,_,5,_,_,_,7,_,_]]).

problem(2, [[_,_,9,5,_,_,_,3,7],
            [1,3,7,9,_,_,_,5,2],
            [2,_,_,_,_,3,6,9,_],
            [3,5,2,_,1,_,_,_,6],
            [_,_,_,4,5,2,3,_,_],
            [_,8,1,_,3,_,2,_,_],
            [6,_,3,_,4,_,8,_,9],
            [5,2,_,_,_,1,_,6,_],
            [_,_,_,3,_,7,_,_,_]]).

problem(3, [[_,5,_,1,_,_,_,_,_],
            [2,_,_,5,_,_,6,_,_],
            [1,_,_,_,8,_,2,_,_],
            [_,8,_,4,3,_,_,_,_],
            [_,_,_,_,_,_,_,4,_],
            [_,_,_,_,_,7,9,3,2],
            [_,4,_,6,7,_,_,_,_],
            [_,7,_,_,_,_,_,1,9],
            [9,_,_,_,_,8,_,_,_]]).

SOLUTION

We can get the solution using the following queries:

problem(1,Rows), sudoku(Rows), maplist(portray_clause, Rows).

problem(2,Rows), sudoku(Rows), maplist(portray_clause, Rows).

problem(3,Rows), sudoku(Rows), maplist(portray_clause, Rows).

ANOTHER EXAMPLE

Following is the step by step method of how prolog solves the Sudoku puzzle using intelligent constraint propagation.
 
 
 

Inconsistent values are indicated by small dots. Black dots represent “obvious” propagation, whereas, blue dots represent “intelligent” propagation.
 

REFERENCES