swi-prolog 和 yap 的不同结果

Different results in swi-prolog and yap

示例程序对8皇后解的个数进行了枚举和统计。 (抱歉,如果代码难以阅读;这是从 S 表达式机器生成的。原始代码是 https://www.cpp.edu/~jrfisher/www/prolog_tutorial/2_11.html

规则:

[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.

查询:

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

挥动 returns 92;而 yap returns 40320。 还有,我查询solve(P)的时候,swipl只有returns两个解(这也和92矛盾); yap returns 更多(可能有 40320 个)。那么为什么不同呢?有这么严重的兼容性问题吗?

版本:

在旧版本的 YAP 中,对未定义谓词的查询会简单地失败。在上面的例子中,它是 YAP 中没有定义的 member/2。由于这个原因,您的测试 alldif/1 总是成功 - 因此您得到的数字很大。

此行为由 Prolog 标志 unknown 控制,其默认值应为 error。在 YAP 6.2 中,默认值是(错误地)fail。这在 6.3 中得到了更正。说

:- set_prolog_flag(unknown, error).

为未定义的谓词获取一个干净的错误。然后,您需要定义 member/2.