在 XSB 中,Hilog 术语与 XSB 独有的模块系统密切相关。 XSB 有一个基于函子的模块系统。也就是说,在同一范围内length(X) 可能属于一个模块,而length(L, N) 可能属于另一个模块。因此,call(length(L), N) 可能指代一个模块,call(length(L, N)) 指代另一个:
[Patch date: 2013/02/20 06:17:59]
| ?- use_module(basics,length/2).
yes
| ?- length(Xs,2).
Xs = [_h201,_h203]
yes
| ?- call(length(Xs),2).
Xs = [_h217,_h219]
yes
| ?- use_module(inex,length/1).
yes
| ?- length(Xs,2).
Xs = [_h201,_h203]
yes
| ?- call(length(Xs),2).
++Error[XSB/Runtime/P]: [Existence (No module inex exists)] in arg 1 of predicate load
| ?- call(call(length,Xs),2).
Xs = [_h228,_h230];
在这种情况下,call/N 和 Hilog 术语之间可能存在差异。但是,我目前还没有找到。
历史上,Hilog 术语是在 1987-1989 年引入的。在那个时间点,call/N 已经在 NU 中作为内置插件存在,在 Quintus Prolog 中作为 library(call) 和 only cursory documentation 存在。已提议1984 by Richard O'Keefe。另一方面,call/N Hilog 的作者显然不知道,正如 Weidong Chen、Michael Kifer、David Scott Warren 的 p.1101 所示:HiLog:一阶
高阶逻辑编程结构的语义。 NACLP
1989. 1090-1114。麻省理工学院出版社。
... 通用传递闭包也可以在 Prolog 中定义:
closure(R, X, Y) :- C =.. [R, X, Y], call(C).
closure(R, X, Y) :- C =.. [R, X, Z], call(C), closure(R, Z, Y).
但是,与 HiLog 相比,这显然是不优雅的(参见第 2.1 节),因为这涉及从列表中构造一个术语并使用“调用”将该术语反映到一个原子公式中。这个例子的要点是,Prolog 中缺乏高阶结构的理论基础导致语法晦涩难懂,这部分解释了为什么涉及这种结构的 Prolog 程序出了名地难以理解。
现在,这可以使用call/N 来完成,如下所示:
closure(R, X, Y) :- call(R, X, Y).
closure(R, X, Y) :- call(R, X, Z), closure(R, Z, Y).
这比(=..)/2-version 更通用,因为R 不再局限于作为原子。顺便说一句,我宁愿写:
closure(R_2, X0,X) :- call(R_2, X0,X1), closure0(R_2, X1,X).
closure0(_R_2, X,X).
closure0(R_2, X0,X) :- call(R_2, X0,X1), closure0(R_2, X1,X).