示例程序枚举并计算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).为什么差异呢?有这么严重的兼容性问题吗?
版本:
我正在编写一个使用不同编程语言的Prolog解释器的包装器.我没有详细介绍,但它基本上生成了一个符合要求的Prolog程序,并将程序从标准输入提供给解释器.我是Prolog的新手.
问题是,我找不到[user].从标准输入读取规则的术语规范.具体来说,它如何检测输入的结束.
实现此目的最直观的方法是发送一个EOT字符(Ctrl-D),但它似乎不起作用.下面是一个说明性示例,将^ D替换为实际的EOT字符.假设此文件已保存input.pl.我打算以编程方式生成这样的代码,并通过标准输入将其提供给后台prolog进程.
[user].
factorial(0,1).
factorial(N,F) :- (>(N,0),is(N1,-(N,1)),factorial(N1,F1),is(F,*(N,F1))).
^D
factorial(3,W).
Run Code Online (Sandbox Code Playgroud)
当我跑到cat input.pl | <prolog>哪里<prolog>是Prolog解释器(swipl,yap等),它似乎没有认识到^ D. 为什么这样,我该如何解决这个问题?在终端^ D工作正常.
上面的例子应该返回"W = 6".SWI抱怨Syntax error: illegal_character.Yap似乎忽略了^ D,只是解析一切并返回yes.
当然,我可以将程序写入临时文件并告诉解释器查阅该文件,但速度很慢.