Mic*_*ael 3 lambda prolog swi-prolog
我可以在SWI Prolog中定义匿名谓词,将其绑定到变量,然后再调用它吗?像这样:
?- F = {(X, Y) :- Y is 2 * X}, call(F, 2.0, Y).
Run Code Online (Sandbox Code Playgroud)
或者,在 SWI-Prolog 中,您可以使用library(yall)。它可以自动加载,因此您无需导入任何内容:
?- F = [X, Y]>>( Y is 2*X ), call(F, 2.0, Y).
F = [X, 4.0]>>(4.0 is 2*X),
Y = 4.0.
Run Code Online (Sandbox Code Playgroud)
我认为在一般情况下,最好为调用 lambda 的结果使用一个新变量:
?- F = [X, Y]>>( Y is 2*X ), call(F, 2.0, R).
F = [X, Y]>>(Y is 2*X),
R = 4.0.
Run Code Online (Sandbox Code Playgroud)
那就是lambda 的用途:
?- use_module(library(lambda)).
true.
?- F_2 = (\X^Y^ ( Y is 2*X )), call(F_2,2.0,Y).
F_2 = \X^4.0^(4.0 is 2*X),
Y = 4.0.
Run Code Online (Sandbox Code Playgroud)
到目前为止,没有现代 lambda 库支持Hiord语法,不要与 Hilog 语法混淆。但由于在 ISO Prolog 中,花括号只是函子 '{}'/1,因此可以使用一些规则来实现自己的 Hiord:
'{}'((Formal :- Body), Actual) :-
copy_term(Formal-Body, Actual-Call),
Call.
'{}'((Formal1,Formal2 :- Body), Actual1, Actual2) :-
copy_term(Formal1-Formal2-Body, Actual1-Actual2-Call),
Call.
'{}'((Formal1,Formal2,Formal3 :- Body), Actual1, Actual2, Actual3) :-
copy_term(Formal1-Formal2-Formal3-Body, Actual1-Actual2-Actual3-Call),
Call.
Etc..
Run Code Online (Sandbox Code Playgroud)
以下是一些示例运行:
Jekejeke Prolog 3, Runtime Library 1.3.8 (May 23, 2019)
(c) 1985-2019, XLOG Technologies GmbH, Switzerland
?- F = {X :- write(X), nl}, call(F, hello).
hello
?- F = {X,Y :- Y is X+1}, call(F, 1, R).
R = 2
?- F = {X,Y,Z :- Z is X+Y}, call(F, 1, 2, R).
R = 3
Run Code Online (Sandbox Code Playgroud)
使用 lambda 术语时,您会发现存在许多问题。例如,有不同解决方案的全局变量问题。
除此之外,您可能还对允许柯里化的 lambda 术语感兴趣。Hiord 条款不允许对上述实现进行柯里化,例如这里失败:
?- G = {Y :- Y is X+1}, F = {X :- G}, call(F, 1, R).
Error: Undefined or inaccesible predicate {}/1.
{}/1
{}/3
Run Code Online (Sandbox Code Playgroud)
使用 Jekejeke Prologs 库(experiment/abstract)你会更幸运,它也可以做柯里化:
?- G = Y\(Y is X+1), F = X\G, call(F, 1, R).
R = 2
Run Code Online (Sandbox Code Playgroud)
SWI-Prologs lambda 库也可以进行柯里化:
?- G = [Y]>>(Y is X+1), F = [X]>>G, call(F, 1, R).
R = 2.
Run Code Online (Sandbox Code Playgroud)
而 Ulrich Neumerkels 库也可以进行柯里化:
?- G = \Y^(Y is X+1), F = \X^G, call(F, 1, R).
R = 2
Run Code Online (Sandbox Code Playgroud)