0

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

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

类似以下的内容应该返回 true。这在 Prolog 中可能吗?

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

1 回答 1

1

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

call(X, Y).

给定X=number, 和Yis 例如3,它会调用number(3). 如果 caseX是一个术语, like number(1),它称它为 like 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 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>

.

于 2018-10-12T18:35:51.067 回答