如何在序言中指定谓词作为另一个参数的参数?

时间:2018-10-12 18:28:36

标签: prolog meta-predicate

我想编写一个序言谓词,如果谓词作为第一个参数出现,则该谓词对于第二个参数中包含的列表的所有元素均成立。这是我尝试过的东西:

?- listing(all).
all(pred(_), [A|B]) :-
    pred(A),
    all(pred(_), B).
all(pred(_), [x]) :-
    pred(x).

类似下面的内容应返回true。在Prolog中有可能吗?

all(number, [3, 5 ,7]).

1 个答案:

答案 0 :(得分:0)

您可以使用call/n [swi-doc]

call(X, Y).

给出X=number,而Y例如3,它将调用number(3)。如果X是一个术语,例如number(1),则将其称为number(1, 3),就好像谓词是“ curried ”一样。

因此您可以将功能实现为:

all(_, []).
all(P, [A|B]) :-
    call(P, A),
    all(P, B).

尽管为了更有效地回溯,最好交换参数:

all(P, L) :-
    all2(L, P).

all2([], _).
all2([A|B], P) :-
    call(P, A),
    all2(B, P).

但是您要实现的谓词已经在一些流行的Prolog解释器maplist/2 [swi-doc]中存在。

这将在列表的所有元素上调用Goal,如果谓词在某个时候失败,则失败。

您还可以使用(=..)/2 [swi-doc]构造函子。例如:

X =.. [number, 1, 3]

将产生X = number(1, 3)。然后,可以对构造的函子使用调用call/1 [swi-doc]来调用函子,就好像它是谓词一样,

X =.. [number, 1, 3], call(X).

请注意,(=..)/2谓词不适用于这种“周期性”的函子,例如:

?- X =.. [number(1), 3].
ERROR: Type error: `atom' expected, found `number(1)' (a compound)
ERROR: In:
ERROR:    [8] _6428=..[number(1),3]
ERROR:    [7] <user>