从终端查询不打印任何内容

Fat*_*ize 4 command-line prolog swi-prolog

在命令行中运行时,

swipl -g "write(42)" -t "halt"
Run Code Online (Sandbox Code Playgroud)

STDOUT按预期打印42 。

但是这个

swipl -g "X = 42" -t "halt"
Run Code Online (Sandbox Code Playgroud)

不打印任何内容,仅返回。

如何获得它以打印在REPL中打印的内容(即X = 42)?

注意:这在Windows终端中。让我知道这是否真的可以在Linux终端中使用。

mat*_*mat 5

正如预期的那样,X = 42它本身不会产生任何输出,因为它(=)/2是一个完全纯的谓词,它本身不会产生任何副作用。在Window,OSX和所有其他操作系统上就是这种情况。

即使有一种获取和重定向顶层输出本身的方法,事实仍然是SWI顶层可能会发生变化,并且您不能依靠将来的版本来表现与现在相同的行为。从长远来看,您可能会更好地推出自己的顶级产品,并准确地产生所需的输出。

推出自己的顶级产品并不难。技巧主要是variable_names/1在阅读术语时使用该选项,以便您可以跟踪要在答案中显示的变量名称。这是一个非常简单的开始:

代表:-
        read_line_to_codes(current_input,Codes),
        read_term_from_codes(代码,术语,[ variable_names(NameVars) ]),
        通话(期限)
        report_bindings(NameVars)。
代表:-代表

report_bindings(NameVars):-
        短语(bindings(NameVars),Bs),
        格式(“〜s”,[Bs])。

bindings([])-> []。
bindings([E])-> name_var(E)。
bindings([E1,E2 | Rest])-> name_var(E1),“,\ n”,绑定([E2 | Rest])。

name_var(名称=变量)->
        format _(“〜w =〜q”,[名称,变量])。

format_(Format,Ls)->
        呼叫(format_codes(Format,Ls))。

format_codes(Format,Ls,Cs0,Cs):-
        格式(codes(Cs0,Cs),Format,Ls)。

例:

?
|:X = 4,介于(1、3,Y)之间。
X = 4
Y = 1
真实;
X = 4
Y = 2
真实;
X = 4
Y = 3
真实;
|:X = 7。
X = 7

修改它很容易,这样它就可以在指定为参数的术语上使用  。

请注意,该variable_names/1选项对于以这种方式读取术语必不可少,并且由于进行了ISO标准化工作,越来越多的实现为它read_term/2和相关谓词提供了实现。

具备读取变量名的能力是实现便携式Prolog顶层的必要条件

我留给您的主要练习是检查报价在所有情况下是否正确,以及(如果需要)以始终可以将其粘贴回终端的方式生成答案。要将其扩展到剩余约束,请使用copy_term/3call_residue_vars/2收集可以附加到绑定的未决约束。

  • 在命令行上很好地执行单个目标与REPL完全不同,通常从shell脚本运行SWI时您不希望REPL进行交互,因此到目前为止,只有少数实例值得排除REPL。我同意它应该更具模块化,事实上,我希望我们可以共同开发一个更具模块化的REPL,这在与Prolog解释器进行交互的其他情况下也很有用!我认为开始运行基本的REPL并不困难,希望您考虑从那里继续这样做。 (3认同)
  • 对于应该首先起作用的东西来说,这似乎是很多工作。如果您无法立即获得REPL的结果,那么能够在REPL之外运行查询有什么意义呢? (2认同)
  • 不要忘记使用write-option`variable_names / 1`来编写可读变量! (2认同)