queens(N):- length(Qs,N), Qs :: 1..N, foreach(I in 1..N-1, J in I+1..N, (Qs[I] #\= Qs[J], abs(Qs[I]-Qs[J]) #\= J-I)), labeling([ff],Qs), writeln(Qs).The array notation on lists helps shorten the description. Without it, the foreach loop in the program would have to be written as follows:
foreach(I in 1..N-1, J in I+1..N,[Qi,Qj], (nth(Qs,I,Qi), nth(Qs,J,Qj), Qi #\= Qj, abs(Qi-Qj) #\= J-I)),where Qi and Qj are declared local to each iteration. The following gives a program for the N-queens problem, which uses a Boolean variable for each square on the board.
bool_queens(N):- new_array(Qs,[N,N]), Vars @= [Qs[I,J] : I in 1..N, J in 1..N], Vars :: 0..1, foreach(I in 1..N, % one queen in each row sum([Qs[I,J] : J in 1..N]) #= 1), foreach(J in 1..N, % one queen in each column sum([Qs[I,J] : I in 1..N]) #= 1), foreach(K in 1-N..N-1, % at most one queen in each diag sum([Qs[I,J] : I in 1..N, J in 1..N, I-J=:=K]) #=< 1), foreach(K in 2..2*N, sum([Qs[I,J] : I in 1..N, J in 1..N, I+J=:=K]) #=< 1), labeling(Vars), foreach(I in 1..N,[Row], (Row @= [Qs[I,J] : J in 1..N], writeln(Row))).