Prolog 中的 Lambda 表达式?
Lambdas in Prolog?
我通常能够通过 maplist 找出 Lambda 的一些用法,但通常很难在 prolog 中使用 lambda。
可能是因为它和其他语言不同,因为统一。
这是症结之一:如何应用已声明的 Lambda 表达式? f.e.
LAM = \X^R^(....)
(奇怪,=和\之间必须有space)
你好:
\(LAM)(abc,R)
我想做的另一件事是像 FACT 一样存储 Lambda 表达式,以便我可以查询它,但也像 lambda 函数一样存储它,这样我可以稍后进行绑定..f.e。只是我的头顶...我可能认为它是错误的..
move = \Obj^From^To(move(Obj,From,To))
实例化:
?- \(move)(ball,ground,table).
或部分:
?- L2 = \(move)(ball).
?- L3 = \(L2)(table,floor)
查询:
?- move(ball,F,T).
让我们考虑以下 lambda 项:
?- LAM_2 = \X^R^atom_chars(X,R).
LAM_2 = \X^R^atom_chars(X, R).
_2
提醒我们缺少两个论点才能使它成为真正的目标。
要使用它,您现在必须提供这两个参数。使用一些元谓词,如 maplist/3
或 call/3
.
?- LAM_2 = \X^R^atom_chars(X,R), call(LAM_2, abc, Res).
LAM_2 = \X^R^atom_chars(X, R),
Res = [a, b, c].
?- LAM_2 = \X^R^atom_chars(X,R), maplist(LAM_2, [abc,def], Xss).
LAM_2 = \X^R^atom_chars(X, R),
Xss = [[a, b, c], [d, e, f]].
注意变量 X
和 R
没有被实例化!
真正有点不寻常的是没有逻辑变量的直接作用域。它们在一个子句中都是全局的,所以我们要注意不要不小心重用这些变量。
另请注意,我们可以为上面的示例编写,只是:
?- LAM_2 = atom_chars, call(LAM_2, abc, Res).
LAM_2 = atom_chars,
Res = [a, b, c].
to store Lambda expression like a FACT, so that I can query it
为什么不直接定义事实呢?否则无法做到这一点。
你举的例子很有道理,前提是我们已经定义了事实:
move(ball, table, floor).
现在我们可以通过环绕 call/2
添加参数来逐步构造查询。
?- L1_3 = move, L2_2 = call(move, ball), L3_0 = call(L2_2, table, X), L3_0.
L1_3 = move,
L2_2 = call(move, ball),
L3_0 = call(call(move, ball), table, floor),
X = floor.
但是,请注意,如今很少使用此类局部目标。 call/N
的直接使用主要保留给元谓词,如 maplist/3
.
除了 SWI-Prolog package that's already been mentioned you might be also interested in λProlog.
此外,Logtalk supports lambdas 自 2009 年以来。
我通常能够通过 maplist 找出 Lambda 的一些用法,但通常很难在 prolog 中使用 lambda。 可能是因为它和其他语言不同,因为统一。
这是症结之一:如何应用已声明的 Lambda 表达式? f.e.
LAM = \X^R^(....)
(奇怪,=和\之间必须有space)
你好:
\(LAM)(abc,R)
我想做的另一件事是像 FACT 一样存储 Lambda 表达式,以便我可以查询它,但也像 lambda 函数一样存储它,这样我可以稍后进行绑定..f.e。只是我的头顶...我可能认为它是错误的..
move = \Obj^From^To(move(Obj,From,To))
实例化:
?- \(move)(ball,ground,table).
或部分:
?- L2 = \(move)(ball).
?- L3 = \(L2)(table,floor)
查询:
?- move(ball,F,T).
让我们考虑以下 lambda 项:
?- LAM_2 = \X^R^atom_chars(X,R).
LAM_2 = \X^R^atom_chars(X, R).
_2
提醒我们缺少两个论点才能使它成为真正的目标。
要使用它,您现在必须提供这两个参数。使用一些元谓词,如 maplist/3
或 call/3
.
?- LAM_2 = \X^R^atom_chars(X,R), call(LAM_2, abc, Res).
LAM_2 = \X^R^atom_chars(X, R),
Res = [a, b, c].
?- LAM_2 = \X^R^atom_chars(X,R), maplist(LAM_2, [abc,def], Xss).
LAM_2 = \X^R^atom_chars(X, R),
Xss = [[a, b, c], [d, e, f]].
注意变量 X
和 R
没有被实例化!
真正有点不寻常的是没有逻辑变量的直接作用域。它们在一个子句中都是全局的,所以我们要注意不要不小心重用这些变量。
另请注意,我们可以为上面的示例编写,只是:
?- LAM_2 = atom_chars, call(LAM_2, abc, Res).
LAM_2 = atom_chars,
Res = [a, b, c].
to store Lambda expression like a FACT, so that I can query it
为什么不直接定义事实呢?否则无法做到这一点。
你举的例子很有道理,前提是我们已经定义了事实:
move(ball, table, floor).
现在我们可以通过环绕 call/2
添加参数来逐步构造查询。
?- L1_3 = move, L2_2 = call(move, ball), L3_0 = call(L2_2, table, X), L3_0.
L1_3 = move,
L2_2 = call(move, ball),
L3_0 = call(call(move, ball), table, floor),
X = floor.
但是,请注意,如今很少使用此类局部目标。 call/N
的直接使用主要保留给元谓词,如 maplist/3
.
除了 SWI-Prolog package that's already been mentioned you might be also interested in λProlog.
此外,Logtalk supports lambdas 自 2009 年以来。