The N-queens problem
A solution to the 8-queens problem is given by placing eight queens
on a chessboard in such a way that no two queens attack each other.
The N-queens problem is similar, with N queens on an N row and N column chessboard.
We can define a solution for an arbitrary number of queens recursively in the following
way. \def\tttbar{}
\pprog{solution}{
solution([]).
solution([P|L]):-
solution(L),
legal(P),
noattack(P,L).
}
A list is a solution if no queen in the list attacks another queen
in the list.
The empty list clearly is a solution.
A list is a solution if the list L is a solution
and P represents a queen on a position on the board from where
she does not attack any of the queens in L.
To represent the position of a queen on a chessboard we use terms of
the form where X represents the row and Y the column
number of the queens location on the board.
The predicate legal may be used to enumerate all
the legal positions on a board.
\pprog{legal}{
legal(pos(X,Y)):-
member(X,[1,2,3,4,5,6,7,8]),
member(Y,[1,2,3,4,5,6,7,8]).
}
Finally, in order to check whether or not a queen attacks any of the queens
in a list, we define the recursive predicate noattack as below.
\pprog{noattack}{
noattack(_,[]).
noattack(pos(X,Y),[pos(A,B)\tttbar L\{\}]):-
X != A,
Y != B,
X-A != B-Y,
X-A != Y-B,
noattack(pos(X,Y),L).
}
A queen on a given position does not attack a queen on position
whenever the first four conditions in the body of the second clause
are satisfied.\ftn{
We assume here that the arithmetical expressions occurring on the left- and right-hand
side of the inequality symbol are automatically evaluated.
For Prolog systems that do not support such automatic evaluation
the values of these expressions must be assigned to variables
before testing their inequality.
}
A solution to the 8-queens problem may be found by evaluating the goal
?- solution([X1,X2,X3,X4,X5,X6,X7,X8]).
which results in binding
the variables to the positions
representing the queens on the chessboard.