Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different results in swi-prolog and yap

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
like image 496
Asai Masataro Avatar asked Nov 10 '17 13:11

Asai Masataro


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.

like image 148
false Avatar answered Sep 28 '22 00:09

false