swi-prolog和yap的结果不同

Asa*_*aro 7 prolog iso-prolog

示例程序枚举并计算8-queen解决方案的数量.(对不起代码很难读;这是用S-expression机器生成的.原始代码是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.
Run Code Online (Sandbox Code Playgroud)

查询:

(setof(P,solve(P),Set),length(Set,L),write(L),write('\n'),fail).
Run Code Online (Sandbox Code Playgroud)

swipl返回92; 而yap返回40320.此外,当我查询时solve(P),swipl只返回两个解决方案(这也与92相矛盾); yap返回更多(可能是40320).为什么差异呢?有这么严重的兼容性问题吗?

版本:

  • YAP 6.2.2(x86_64-linux):2016年9月17日星期六13:59:03 UTC
  • 适用于amd64的SWI-Prolog版本7.2.3

fal*_*lse 7

在旧版本的YAP中,对未定义谓词的查询失败.在上面的例子中,它member/2没有在YAP中定义.因此,您的测试alldif/1总是成功 - 因此您获得的数量很大.

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

:- set_prolog_flag(unknown, error).
Run Code Online (Sandbox Code Playgroud)

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

  • 谢谢,所以`member`不是内置插件......但那些"序言"(兼容层,有点)听起来不错.我可以让lisp-to-prolog库在启动进程时加载它. (2认同)
  • @Asai:从6.2-> 6.3的过渡是一个汇合的情况. (2认同)