:- use_module(library(clpfd)).
:- op(700,xfx,ins). % für SICStus-Prolog

queens(N,L) :-
        length(L,N),         % L hat N Variablen
        (current_prolog_flag(dialect,sicstus)
         -> domain(L, 1, N)  % Wertebereich der Variablen (SICStus-Prolog)
          ; L ins 1 .. N  ), % Wertebereich der Variablen (SWI-Prolog)
        all_safe(L),         % Damen können sich nicht gegenseitig schlagen
        labeling([ff],L). % first fail!

% Die Damen können sich nicht gegenseitig schlagen:
all_safe([]).
all_safe([Q|Qs]) :- safe(Q,Qs,1), all_safe(Qs).

% Q (erstes Argument) kann keine andere Dame schlagen
safe(_,[],_).
safe(Q,[Q1|Qs],D) :-
        no_attack(Q,Q1,D),
        D1 #= D+1,
        safe(Q,Qs,D1).

% Damen können waagerecht und diagonal schlagen (D: Spaltenabstand)
no_attack(Q,Q1,D) :-
        Q #\= Q1,   % nicht in gleicher Spalte
        Q #\= Q1+D, % nicht diagonal
        Q #\= Q1-D.




% Dies sorgt dafür, dass in der Prolog REPL (top-level)
% Terme mit beliebiger Tiefe ausgegeben werden:
:- current_prolog_flag(dialect,sicstus)
   -> % SCIStus-Prolog:
      set_prolog_flag(toplevel_print_options,
                      [quoted(true), portrayed(true), max_depth(0)])
    ; % SWI-Prolog:
      set_prolog_flag(answer_write_options,
                      [quoted(true), portray(true), max_depth(0)]).
