Hilog 项(即具有任意项作为函子的化合物)是否仍然被视为 XSB Prolog(或任何其他 Prolog)中的强大功能?目前有很多 XSB 项目使用这个功能吗?例如,他们中的哪一个?
我问,因为据我了解,使用 ISO 内置 call/N 进行高阶编程同样可能。
具体来说,我想了解 XSB 是否只是出于历史原因使用 Hilog 术语,或者与当前的 ISO 标准相比,Hilog 术语是否具有相当大的优势。
Hilog 项(即具有任意项作为函子的化合物)是否仍然被视为 XSB Prolog(或任何其他 Prolog)中的强大功能?目前有很多 XSB 项目使用这个功能吗?例如,他们中的哪一个?
我问,因为据我了解,使用 ISO 内置 call/N 进行高阶编程同样可能。
具体来说,我想了解 XSB 是否只是出于历史原因使用 Hilog 术语,或者与当前的 ISO 标准相比,Hilog 术语是否具有相当大的优势。
在 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 年引入的。在那个时候, NU 和Quintus Prologcall/N
中已经作为内置插件存在,只有粗略的文档。它由 Richard O'Keefe 于 1984 年提出。另一方面,Hilog 的作者显然不知道,如 Weidong Chen、Michael Kifer、David Scott Warren 的 p.1101 所示:HiLog: A First-Order Semantics for Higher-Order Logic Programming Constructs。NACLP 1989. 1090-1114。麻省理工学院出版社。library(call)
call/N
... 通用传递闭包也可以在 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).
HiLog 允许目标,例如
foo(X(a, Y(b))).
而 ISO Prolog 没有。在 ISO Prolog 中,您必须编写
foo(T), T=..[X, a, R], R=..[Y, b].
这不太方便,可能会更慢。