Search code examples
prologclpfdn-queens

n-queens solution not working in Prolog


I am trying to run following code from N-Queens Problem‍​..How far can we go? to find solutions to n-queens problem:

generate([],_).
generate([H|T],N) :- H in 1..N , generate(T,N).
lenlist(L,N) :- lenlist(L,0,N).
lenlist([],N,N).
lenlist([_|T],P,N) :- P1 is P+1 , lenlist(T,P1,N).

queens(N,L) :-
        generate(L,N),lenlist(L,N),
        safe(L),!,
        labeling([ffc],L).

notattack(X,Xs) :- notattack(X,Xs,1).
notattack(X,[],N).
notattack(X,[Y|Ys],N) :- X #\= Y,
                         X #\= Y - N,
                         X #\= Y + N,
                         N1 is N + 1,
                         notattack(X,Ys,N1).

safe([]).
safe([F|T]) :- notattack(F,T), safe(T).

I have swi-prolog installed on Debian-9 (stable) Linux and I am running above using command "swipl -f nqueens.pl". On loading, I get an error:

Syntax error: operator expected (probably on 2nd code line)

Where is the problem and how can this be solved? Thanks for your help.


Solution

  • The question actually mentions that it is writting in CLPFD (A Constraint Logic Programming tool over Finite Domains). You have to import this library:

    :- use_module(library(clpfd)).
    
    generate([],_).
    generate([H|T],N) :- H in 1..N , generate(T,N).
    lenlist(L,N) :- lenlist(L,0,N).
    lenlist([],N,N).
    lenlist([_|T],P,N) :- P1 is P+1 , lenlist(T,P1,N).
    
    queens(N,L) :-
            generate(L,N),lenlist(L,N),
            safe(L),!,
            labeling([ffc],L).
    
    notattack(X,Xs) :- notattack(X,Xs,1).
    notattack(X,[],N).
    notattack(X,[Y|Ys],N) :- X #\= Y,
                             X #\= Y - N,
                             X #\= Y + N,
                             N1 is N + 1,
                             notattack(X,Ys,N1).
    
    safe([]).
    safe([F|T]) :- notattack(F,T), safe(T).

    Then it works, and produces for instance:

    ?- queens(5,L).
    L = [1, 3, 5, 2, 4] ;
    L = [1, 4, 2, 5, 3] ;
    L = [2, 4, 1, 3, 5] ;
    L = [2, 5, 3, 1, 4] ;
    L = [3, 1, 4, 2, 5] ;
    L = [3, 5, 2, 4, 1] ;
    L = [4, 1, 3, 5, 2] ;
    L = [4, 2, 5, 3, 1] ;
    L = [5, 2, 4, 1, 3] ;
    L = [5, 3, 1, 4, 2].