从 Prolog 中的列表构建复合谓词

lav*_*lle 5 prolog

如果我在 Prolog 中有一个谓词列表,例如[flies, swims],我如何构建一个谓词,它是列表中所有谓词的合取,即fliesAndSwims(X) :- flies(X), swims(X).

或者,是否有一种更好的方法可以像这样在运行时构建谓词,而无需将组件谓词放入列表中并在需要时从中构建复合谓词?

编辑:所以事实证明这是Prolog 中谓词列表的重复。我之前已经找到了这个答案,但我认为它只返回给定原子是否与列表中的每个谓词匹配。我没有意识到你可以传递一个变量而不是一个原子,并让它返回每个匹配的情况。

Cap*_*liC 2

库(lambda)很强大,但它是有代价的。如果您认为“越简单越好”(关于调试,特别是......)请考虑

call_unary_list([], _).
call_unary_list([P|Ps], X) :-
    call(P, X),
    call_unary_list(Ps, X).
Run Code Online (Sandbox Code Playgroud)

我们来比较一下性能:

compare_call_list :-
    findall(flies, between(1,100000,_), L),
    time(call_unary_list(L, _)),
    time(maplist(call_unary(_), L)),
    time(maplist(X+\Pred^call(Pred,X), L)).

call_unary(X, P) :- call(P, X).

?- compare_call_list.
% 200,000 inferences, 0.123 CPU in 0.123 seconds (100% CPU, 1629657 Lips)
% 300,000 inferences, 0.145 CPU in 0.149 seconds (98% CPU, 2064184 Lips)
% 1,000,001 inferences, 1.286 CPU in 1.297 seconds (99% CPU, 777362 Lips)
true .
Run Code Online (Sandbox Code Playgroud)

call_unary/2 突出显示映射列表元谓词所需的参数交换