Different results in swi-prolog and yap

Viewed 242

The sample program enumerates and counts the number of 8-queen solutions. (sorry if the code is hard to read; this is machine-generated from an S-expression. The original code is https://www.cpp.edu/~jrfisher/www/prolog_tutorial/2_11.html)

rules:

[user].
(perm([X|Y],Z) :- (perm(Y,W),takeout(X,Z,W))).
perm([],[]).
takeout(X,[X|R],R).
(takeout(X,[F|R],[F|S]) :- (takeout(X,R,S))).
(solve(P) :- (perm([1,2,3,4,5,6,7,8],P),combine([1,2,3,4,5,6,7,8],P,S,D),alldiff(S),alldiff(D))).
(combine([X1|X],[Y1|Y],[S1|S],[D1|D]) :- (is(S1,+(X1,Y1)),is(D1,-(X1,Y1)),combine(X,Y,S,D))).
combine([],[],[],[]).
(alldiff([X|Y]) :- (\+ member(X,Y),alldiff(Y))).
alldiff([X]).
end_of_file.

query:

(setof(P,solve(P),Set),length(Set,L),write(L),write('\n'),fail).

swipl returns 92; while yap returns 40320. Also, when I query solve(P), swipl only returns two solutions (which also contradicts 92); yap returns much more (possibly 40320 of them). So why the difference? Is there such a serious compatibility issue?

Versions:

  • YAP 6.2.2 (x86_64-linux): Sat Sep 17 13:59:03 UTC 2016
  • SWI-Prolog version 7.2.3 for amd64
1 Answers

In older versions of YAP, a query for an undefined predicate simply failed. In the case above, it is member/2 which is not defined in YAP. And for this reason your test alldif/1 always succeeds - thus the large number you get.

The behavior for this is governed by the Prolog flag unknown whose default value should be error. In YAP 6.2 the default was (incorrectly) fail. This was corrected in 6.3. Say

:- set_prolog_flag(unknown, error).

to get a clean error for undefined predicates. Then, you would need to define member/2.

Related