:-use_module(library(clpfd)).
:-use_module(library(lists)).
:-use_module(library(terms)).
%%%%%%%%%%%%%%%%%%%%%%%%
%%%% How to compile %%%%
%%%%%%%%%%%%%%%%%%%%%%%%
%
% | ?- [queens].
%

%%%%%%%%%%%%%%%%%%%%
%%%% How to run %%%%
%%%%%%%%%%%%%%%%%%%%
%
% | ?- queens( N ).
%
% where N is a positive integer (the length of the board side):



queens( N ) :-
    statistics(runtime,_),
    actual_queens(N, Queens),
    statistics(runtime,[_,T]),
    write('N='),write(N),write('\t'),write(T),write('\t'),write('ms'),nl.
%    write(Queens). 

actual_queens(N, Queens) :- 

    length(Queens, N),
    domain(Queens,1,N),
    constrain(Queens),
    labeling([ff], Queens).

constrain(Queens) :- 
    all_distinct(Queens),
    diagonal(Queens).

diagonal([]).
diagonal([Q|Queens]) :- 
    sicure(Q, 1, Queens),
    diagonal(Queens).

sicure( _,_,[]).
sicure(X,D,[Q|Queens]) :- 
    nonattacca(X,Q,D),
    D1 is D+1,
    sicure(X,D1,Queens).
    nonattacca(X,Y,D) :- X + D #\= Y,
    Y + D #\= X.


