meta_predicate 的数字参数在 SWI-Prolog 中是什么意思?
What do the numeric arguments for meta_predicate mean in SWI-Prolog?
我正在编写一个 Prolog 程序,我正在尝试将模块合并到程序设计中以封装复杂性以减少冗余功能。
我遇到困难的一个功能是元谓词的使用。我想在一个模块中定义一个元谓词,然后将其导入另一个模块;这会带来并发症。幸运的是,meta_predicate
指令有助于解析模块前缀,但我无法理解这里描述的参数:https://www.swi-prolog.org/pldoc/man?section=metapred
具体来说,我在处理数字参数时遇到了问题。根据文档:
The argument is a term that is used to reference a predicate with N more arguments than the given argument term. For example: call(0) or maplist(1, +).
我了解由数值表示的参数将是用于引用谓词的术语。我不明白的是被引用的谓词如何比参数术语有更多的参数。有人可以更深入地解释数字参数何时适用,或何时适用的示例吗?
这是一个只有知道它的意思才容易理解的公式,可能应该重做。
:-meta_predicate maplist(2, ?, ?).
... 只是表示“2”处的参数将用作将要调用的谓词的内核。我们对此没有特殊的表示法(恕我直言,这是一个很大的错误),因此我们将以标准方式将其写为 f(foo,bar)
、f(foo)
或 f
等术语。元谓词 maplist/3
将如何处理该术语?好吧,它将在语法上对其进行转换并在其末尾添加“2”个附加参数(并且仅在其末尾,这会导致尴尬):f(foo,bar, ARG1,ARG2)
,或f(foo, ARG1,ARG2)
,或f(ARG1,ARG2)
。 然后 maplist/3
会调用它。
例如,对于前面提到的 maplist/3
,以这个带有两个参数的谓词为例:
myprint(X,Y)
:- format("~w\n",[(X,Y)]).
它可以像这样在 maplist/3
调用中使用,不指示任何参数:
maplist(myprint,[0,1,2,3],[a,b,c,d]).
并且两个参数,每个列表中的一个,将附加在术语 myprint
上,然后该术语被封为谓词,并称为:
?- maplist(myprint,[0,1,2,3],[a,b,c,d]).
0,a
1,b
2,c
3,d
true.
这样可以通过 "partially filled-in calls"。 maplist/2
会将 1 个参数附加到第一个参数的末尾,因此可以说:
?- maplist(myprint("foo+"),[a,b,c,d]).
foo+,a
foo+,b
foo+,c
foo+,d
true.
以上内容与 Paulo Moura 的 library(yall)
结合使用,后者将目标包装到匿名谓词中,公开参数。然后可以灵活地重新排列东西
?- maplist([X,Y]>>format("~w\n",[(X,Y)]),[0,1,2,3],[a,b,c,d]).
0,a
1,b
2,c
3,d
true.
?- maplist([Y,X]>>format("~w\n",[(X,Y)]),[0,1,2,3],[a,b,c,d]).
a,0
b,1
c,2
d,3
true.
事实上 library(yall)
为 ISO 标准中严重缺失的 Lambda 表达式提供了正确的语法,以明确显示缺失的参数。
很久以前就可以想象有这样的表达:
?- maplist(λX.verify(3,X), [1,2,3,4,5]).
或者留在 ASCIIland,比如:
?- maplist(\X.verify(3,X), [1,2,3,4,5]).
但这并没有发生。
元谓词指令指定调用时添加到谓词的参数数量。这是一个简单的例子:
:- meta_predicate foo(2, +).
foo(Pred, X) :-
call(Pred, X, Y),
format('~q(~q,~q)~n', [Pred, X, Y]).
some_pred(X, Y) :-
Y is X + 1.
产生以下结果。如您所见,meta_predicate
指令导致 Pred
参数添加模块(在本例中为 user
):
?- foo(some_pred, 5).
user:some_pred(5,6)
与其他语言中的 "closure" 类似的操作可以轻松完成,也可以使用 meta_predicate 指令。例如,我们可以
:-meta_predicate foo2(1).
foo2(Pred):-
call(Pred, Y),
format('~q=~q',[Pred,Y]).
并称它为:
?-foo2(some_pred(5)).
我正在编写一个 Prolog 程序,我正在尝试将模块合并到程序设计中以封装复杂性以减少冗余功能。
我遇到困难的一个功能是元谓词的使用。我想在一个模块中定义一个元谓词,然后将其导入另一个模块;这会带来并发症。幸运的是,meta_predicate
指令有助于解析模块前缀,但我无法理解这里描述的参数:https://www.swi-prolog.org/pldoc/man?section=metapred
具体来说,我在处理数字参数时遇到了问题。根据文档:
The argument is a term that is used to reference a predicate with N more arguments than the given argument term. For example: call(0) or maplist(1, +).
我了解由数值表示的参数将是用于引用谓词的术语。我不明白的是被引用的谓词如何比参数术语有更多的参数。有人可以更深入地解释数字参数何时适用,或何时适用的示例吗?
这是一个只有知道它的意思才容易理解的公式,可能应该重做。
:-meta_predicate maplist(2, ?, ?).
... 只是表示“2”处的参数将用作将要调用的谓词的内核。我们对此没有特殊的表示法(恕我直言,这是一个很大的错误),因此我们将以标准方式将其写为 f(foo,bar)
、f(foo)
或 f
等术语。元谓词 maplist/3
将如何处理该术语?好吧,它将在语法上对其进行转换并在其末尾添加“2”个附加参数(并且仅在其末尾,这会导致尴尬):f(foo,bar, ARG1,ARG2)
,或f(foo, ARG1,ARG2)
,或f(ARG1,ARG2)
。 然后 maplist/3
会调用它。
例如,对于前面提到的 maplist/3
,以这个带有两个参数的谓词为例:
myprint(X,Y)
:- format("~w\n",[(X,Y)]).
它可以像这样在 maplist/3
调用中使用,不指示任何参数:
maplist(myprint,[0,1,2,3],[a,b,c,d]).
并且两个参数,每个列表中的一个,将附加在术语 myprint
上,然后该术语被封为谓词,并称为:
?- maplist(myprint,[0,1,2,3],[a,b,c,d]).
0,a
1,b
2,c
3,d
true.
这样可以通过 "partially filled-in calls"。 maplist/2
会将 1 个参数附加到第一个参数的末尾,因此可以说:
?- maplist(myprint("foo+"),[a,b,c,d]).
foo+,a
foo+,b
foo+,c
foo+,d
true.
以上内容与 Paulo Moura 的 library(yall)
结合使用,后者将目标包装到匿名谓词中,公开参数。然后可以灵活地重新排列东西
?- maplist([X,Y]>>format("~w\n",[(X,Y)]),[0,1,2,3],[a,b,c,d]).
0,a
1,b
2,c
3,d
true.
?- maplist([Y,X]>>format("~w\n",[(X,Y)]),[0,1,2,3],[a,b,c,d]).
a,0
b,1
c,2
d,3
true.
事实上 library(yall)
为 ISO 标准中严重缺失的 Lambda 表达式提供了正确的语法,以明确显示缺失的参数。
很久以前就可以想象有这样的表达:
?- maplist(λX.verify(3,X), [1,2,3,4,5]).
或者留在 ASCIIland,比如:
?- maplist(\X.verify(3,X), [1,2,3,4,5]).
但这并没有发生。
元谓词指令指定调用时添加到谓词的参数数量。这是一个简单的例子:
:- meta_predicate foo(2, +).
foo(Pred, X) :-
call(Pred, X, Y),
format('~q(~q,~q)~n', [Pred, X, Y]).
some_pred(X, Y) :-
Y is X + 1.
产生以下结果。如您所见,meta_predicate
指令导致 Pred
参数添加模块(在本例中为 user
):
?- foo(some_pred, 5).
user:some_pred(5,6)
与其他语言中的 "closure" 类似的操作可以轻松完成,也可以使用 meta_predicate 指令。例如,我们可以
:-meta_predicate foo2(1).
foo2(Pred):-
call(Pred, Y),
format('~q=~q',[Pred,Y]).
并称它为:
?-foo2(some_pred(5)).