command-line - 从终端查询不会打印任何内容

标签 command-line prolog swi-prolog

当在命令行中运行时,这

swipl -g "write(42)" -t "halt"

按预期将 42 打印到 STDOUT

但是,这个

swipl -g "X = 42" -t "halt"

不打印任何内容,它只是返回。

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

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

最佳答案

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

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

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

repl :-
        read_line_to_codes(current_input, Codes),
        read_term_from_codes(Codes, Term, [variable_names(NameVars)]),
        call(Term),
        report_bindings(NameVars).
repl :- repl.

report_bindings(NameVars) :-
        phrase(bindings(NameVars), Bs),
        format("~s", [Bs]).

bindings([])           --> [].
bindings([E])          --> name_var(E).
bindings([E1,E2|Rest]) --> name_var(E1), ",\n", bindings([E2|Rest]).

name_var(Name=Var) -->
        format_("~w = ~q", [Name,Var]).

format_(Format, Ls) -->
        call(format_codes(Format, Ls)).

format_codes(Format, Ls, Cs0, Cs) :-
        format(codes(Cs0,Cs), Format, Ls).

示例:

?- repl.
|: X = 4, between(1, 3, Y).
X = 4,
Y = 1
true ;
X = 4,
Y = 2
true ;
X = 4,
Y = 3
true ;
|: X = 7.
X = 7

很容易对其进行修改,使其适用于指定为参数的术语。

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

这种读取变量名称的能力是实现可移植 Prolog 顶层的要求!

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

关于command-line - 从终端查询不会打印任何内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38283454/

相关文章:

windows-7 - 批处理脚本: Find pattern in string

bash - 为什么是 [[ ! ! expr ]] 等价于 [[ ! expr ]] 在 bash 中?

list - 使用 Prolog 折叠添加列表中的所有项目

lambda - 重复列表

linux - 如何通过Linux命令 'grep'获得值

java - "Could not find or load main class"使用命令行

prolog - 为什么foreach只循环一次?

string - SWI Prolog 转义引号

c++ - 如何通过 C++ FFI 从 Prolog 获取结果到 C++ 变量中

macos - 如何设置 PrologScript