【问题标题】:Is there something like anonymous predicates in SWI Prolog?SWI Prolog 中是否有类似匿名谓词的东西?
【发布时间】:2019-06-19 07:17:07
【问题描述】:

我可以在 SWI Prolog 中定义一个匿名谓词,将它绑定到一个变量,然后再调用它吗?像这样的:

?- F = {(X, Y) :- Y is 2 * X}, call(F, 2.0, Y).

【问题讨论】:

  • 你不需要写 (X,Y),你可以简单地写 X,Y 因为术语在 '{}'/1 里面,并且根据 ISO 核心标准,参数是 ' {}'/1 从操作员级别 1200 开始。

标签: lambda prolog anonymous-function swi-prolog


【解决方案1】:

这就是lambdas 适用于:

?- 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.

【讨论】:

【解决方案2】:

或者,在 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.

认为在一般情况下,最好为调用 lambda 的结果使用一个新变量:

?- F = [X, Y]>>( Y is 2*X ), call(F, 2.0, R).
F = [X, Y]>>(Y is 2*X),
R = 4.0.

【讨论】:

    【解决方案3】:

    到目前为止,没有现代 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..
    

    以下是一些运行示例:

    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
    

    使用 lambda 项时,您会看到 是很多问题。例如有全局问题 有不同解的变量。

    此外,您可能还对允许柯里化的 lambda 术语感兴趣。 Hiord 术语不允许使用上述实现进行柯里化,例如这里失败:

    ?- G = {Y :- Y is X+1},  F = {X :- G}, call(F, 1, R).
    Error: Undefined or inaccesible predicate {}/1.
        {}/1
        {}/3   
    

    Jekejeke Prologs 会让你更幸运 library(experiment/abstract) 也可以进行柯里化:

    ?- G = Y\(Y is X+1), F = X\G, call(F, 1, R).
    R = 2
    

    SWI-Prologs lambda 库也可以进行柯里化:

    ?- G = [Y]>>(Y is X+1), F = [X]>>G, call(F, 1, R).
    R = 2.
    

    Ulrich Neumerkels 库也可以进行柯里化:

    ?- G = \Y^(Y is X+1), F = \X^G, call(F, 1, R).
    R = 2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-24
      • 2011-11-11
      • 2012-04-06
      相关资源
      最近更新 更多