我正在编写Prolog程序,并且试图将模块合并到程序设计中以封装复杂性,从而减少冗余功能。
我遇到的一个困难是元谓词的使用。我想在一个模块中定义一个元谓词,然后将其导入到另一个模块中;这引入了并发症。幸运的是,meta_predicate
指令有助于解析模块前缀,但是我在理解此处描述的参数时遇到了麻烦:https://www.swi-prolog.org/pldoc/man?section=metapred
具体地说,我在使用数字参数时遇到了麻烦。根据文档:
参数是一个术语,用于引用比给定参数多N个参数的谓词。例如:call(0)或maplist(1,+)。
我知道,由数字值表示的参数将是用于引用谓词的术语。我不明白的是,被引用谓词如何具有比自变量项更多的自变量。有人可以提供有关数字参数何时合适的更深入的解释,还是何时使用数字参数的合适示例?
meta-predicate指令指定了调用时要添加到谓词的参数数量。这是一个简单的示例:
:- 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)
这是一种仅在人们知道其含义后才容易理解的表述,并且可能应该重做。
:-meta_predicate maplist(2, ?, ?).
...仅表示在“ 2”处的参数表示将被调用的谓词。我们对此没有特殊的记号(恕我直言,这是个大错误),因此我们将以标准方式将其写为f(foo,bar)
或f(foo)
或f
之类的术语。以及如何调用相应的谓词?好吧,该术语将在语法上进行转换,并在其末尾附加两个自变量:f(foo,bar, ARG1,ARG2)
或f(foo, ARG1,ARG2)
或f(ARG1,ARG2)
。 然后将被调用。
例如,对于前面提到的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.
这允许一个人传递“部分填写的电话”。 maplist/2
会将1个参数附加到其第一个参数的末尾,因此可以说:
?- maplist(myprint("foo+"),[a,b,c,d]).
foo+,a
foo+,b
foo+,c
foo+,d
true.
以上内容实际上与Paulo Moura的library(yall)
结合使用,后者将目标包装到匿名谓词中,从而公开了论点。然后就可以灵活地重新排列内容
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.
为ISO标准中严重缺失的Lambda表达式提供了正确的语法,以明确显示缺失的参数,如:
library(yall)
或留在ASCIIland中,类似于:
?- maplist(λX.verify(3,X), [1,2,3,4,5]).