Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 268
rnso Avatar asked Jan 29 '26 06:01

rnso


1 Answers

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].
like image 70
Willem Van Onsem Avatar answered Jan 31 '26 16:01

Willem Van Onsem



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!