/*   QUEEN.PL   */

:- module queen/fast.
:- public q/1.
:- public queens/1.
:- public queen/2.
:- public put/3.

q(N):-  e_register(0,_,0),queen(N,L),e_register(0,N1,N1+1),
	M is N1+1,write('No.'),write(M),nl,disp(L,N),fail.

q(_):-e_register(0,N,N),write('Total = '),write(N).

queens(N):-queen(N,L),write(L),nl,fail.

queen(N,L):-generate(N,L1),put(L1,[],L).

put(A,B,C):-select(A,S,D),safe(B,S,S),put(D,[S|B],C).
put([],L,L).

:- mode safe(+,integer,integer).
safe([A|B],C,D):-!,CC is C+1,A \==CC,DD is D-1, A \== DD,safe(B,CC,DD).
safe([],_,_).

select([A|L],A,L).
select([A|L],B,[A|P]):-select(L,B,P).

:- mode generate(+,-).
generate(0,[]):-!.
generate(N,[N|L]) :- N1 is N-1,generate(N1,L).

:- mode disp(+,+).
disp([],_):- !,nl.
disp([A|X],N):- disp1(A,N),nl,!, disp(X,N).

:- mode disp1(+,+).
disp1(1,X):- !,write(' Q'),disp2(X).
disp1(X,Y):- X1 is X-1, Y1 is Y-1, write(' .'), disp1(X1,Y1).

:- mode disp2(+).
disp2(1):- !.
disp2(X):- X1 is X-1, write(' .'), disp2(X1).



