简单的例子:
?- between(1,10,X).
X = 1 ;
X = 2 ;
X = 3 ;
X = 4 ;
X = 5 ;
X = 6 ;
X = 7 ;
X = 8 ;
X = 9 ;
X = 10.
当使用SWL-Prolog使用REPL查看下一个答案时,必须按下空格键。
如何在不按空格键的情况下将所有结果列在屏幕上?
关于类似问题的说明。
如果你通过搜索得出这个问题,你的真正问题是
我正在使用SWI-Prolog并且我正在尝试打印列表,但如果列表中有超过9个项目 - 它看起来像那样 -
[1, 15, 8, 22, 5, 19, 12, 25, 3|...]
有没有办法显示整个列表?
然后看这些问答:
SWI-Prolog - show long list SWI-Prolog how to show entire answer (list)?
一个“hackish”解决方案是将print(X), nl, fail
添加到呼叫中。在这里,print(X)
当然可以打印任何相关信息。例如between(1,10,X), print(X), nl, fail
。
这是有效的,因为print/1
[swi-doc]只是另一个打印传递给它的术语的谓词。 nl/0
[swi-doc]将打印一个新的线字符,fail/0
[swi-doc]总是失败。
因此,我们让Prolog提出解决方案,打印这些,打印一条新线,并且fail
将“激活”回溯机制,旨在寻找另一种再次打印并失败的解决方案。
最终打印所有解决方案,因此呼叫失败。这样就产生了:
?- between(1,10,X), print(X), nl, fail.
1
2
3
4
5
6
7
8
9
10
false.
(Goal, false ; true)
代码模式称为故障驱动循环。
你也可以写bagof( _, Goal, _)
。 Goal
可以进行一些逐渐显示的打印,或者如果输出被缓冲则可以进行部分打印。一定要逃避Goal
中的所有自由变量(如A^B^C^Goal
)。
您可以在命令/ shell提示符下将其作为Prolog源代码文件运行,并将其输出重定向到“more
”shell命令。
或者您可以在Prolog的提示符下运行查询,并始终按下;
键。
鉴于(有些)最近添加了库(solution_sequences),特别是call_nth / 2,今天你可以写
?- call_nth((between(1,4,X), writeln(X)), 100).
1
2
3
4
false.
当然,只对前100个答案感兴趣。一点控制:
?- call_nth((between(1,4,X), writeln(X)), 2).
1
2
X = 2.
在call_nth / 2之前,我使用的是forall / 2:
?- forall(between(1,4,X), writeln(X)).
1
2
3
4
true.
编辑
鉴于call_nth和forall是二元谓词,一些语法糖可以缩短一点REPL:in~ / .swiplrc add
:- op(100, xfx, (?*)).
Gen ?* Test :- forall(Gen, Test).
:- op(1100, xfx, (?+)).
Run ?+ Count :- call_nth(Run, Count).
然后重新启动swipl,现在
?- between(1,4,X) ?* (S is X*X, writeln(square_of(X):S)).
square_of(1):1
square_of(2):4
square_of(3):9
square_of(4):16
true.
?- between(1,4,X), write(X), nl ?+ 2.
1
2
X = 2.
注意不同的优先级(100 vs 1100)以及对mini DSL的影响。
编辑
使用WillNess的漂亮模式扩展uDSL:
:- op(1100, fx, (*)).
(* Goal) :- (Goal, false ; true).
然后
?- * between(1,3,N), write(N), nl.
1
2
3
true.