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

时间:2019-01-17 22:40:55

标签: prolog swi-prolog prolog-toplevel

简单的例子:

?- between(1,10,X).
X = 1 ;
X = 2 ;
X = 3 ;
X = 4 ;
X = 5 ;
X = 6 ;
X = 7 ;
X = 8 ;
X = 9 ;
X = 10.

使用REPL通过SWI-Prolog完成此操作以查看下一个答案时,必须按下空格键。

如何在不按空格键的情况下将所有结果显示在屏幕上?


注意类似问题。

如果您通过搜索找到了这个问题,而您真正的问题是

  

我正在使用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)?

3 个答案:

答案 0 :(得分:3)

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

您也可以写bagof( _, Goal, _)Goal可以进行一些打印,这些打印将逐渐出现,或者如果输出被缓冲,则可以分批打印。确保将Goal中的所有可用变量转义为A^B^C^Goal

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

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

答案 1 :(得分: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:〜/ .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与1100)以及对迷你DSL的影响。

编辑

使用WillNess的漂亮模式扩展uDSL:

:- op(1100, fx, (*)).
(* Goal) :- (Goal, false ; true).

然后

?- * between(1,3,N), write(N), nl.
1
2
3
true.

答案 2 :(得分: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.
相关问题