如何在不按空格键的情况下查看SWI-Prolog中的所有答案?

问题描述 投票:5回答:3

简单的例子:

?- 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)?

prolog swi-prolog prolog-toplevel
3个回答
2
投票

一个“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.

3
投票

(Goal, false ; true)代码模式称为故障驱动循环。

你也可以写bagof( _, Goal, _)Goal可以进行一些逐渐显示的打印,或者如果输出被缓冲则可以进行部分打印。一定要逃避Goal中的所有自由变量(如A^B^C^Goal)。

您可以在命令/ shell提示符下将其作为Prolog源代码文件运行,并将其输出重定向到“more”shell命令。

或者您可以在Prolog的提示符下运行查询,并始终按下;键。


3
投票

鉴于(有些)最近添加了库(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.
© www.soinside.com 2019 - 2024. All rights reserved.