问题描述
如果我在 Prolog 中有一个谓词列表,例如 [flies,swims]
,我如何构建一个谓词,该谓词是列表中所有谓词的合取,即 fliesAndSwims(X) :- 苍蝇(X),游泳(X).
?
If I have a list of predicates in Prolog like [flies, swims]
, how can I build a predicate that is the conjunction of all the predicates in the list, ie fliesAndSwims(X) :- flies(X), swims(X).
?
或者,有没有更好的方法可以在运行时构建这样的谓词,而无需将组件谓词放在列表中并在需要时从它们构建复合谓词?
Alternatively, is there a better way of building up a predicate at runtime like this without putting the component predicates in a list and building the compound one from them when needed?
所以事实证明这是Prolog中的谓词列表的副本.我以前找到了那个答案,但我认为它只返回给定原子是否与列表中的每个谓词匹配.我没有意识到你可以传递一个变量而不是一个原子,并让它返回每个匹配的案例.
So it turns out this is a duplicate of List of predicates in Prolog. I had previously found that answer, but I thought that it only returned whether a given atom matched every predicate in the list. I didn't realise that you can pass a variable instead of an atom and have it return every case that matches as well.
推荐答案
library(lambda) 功能强大,但也有代价.如果您认为越简单越好"(特别是调试,特别是...),请考虑
library(lambda) is powerful, but it has a cost. If you think 'simpler is better' (wrt debugging, specially...) consider
call_unary_list([], _).
call_unary_list([P|Ps], X) :-
call(P, X),
call_unary_list(Ps, X).
让我们比较一下性能:
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 .
call_unary/2 突出显示了 maplist 元谓词所需的参数交换
the call_unary/2 highlights the arguments swap that's required by the maplist meta predicate
这篇关于从 Prolog 中的列表构建复合谓词的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!