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

时间:2015-04-26 11:09:02

标签: prolog

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

或者,是否有更好的方法在运行时构建谓词,而不将组件谓词放在列表中,并在需要时从中构建复合谓词?

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

2 个答案:

答案 0 :(得分:2)

以下是更新Prolog's dynamic database的替代方法......您可以使用meta-predicate maplist/2,理想情况下与Prolog lambda expressions结合使用恕我直言。

首先,flies/1swims/1的一些样本(超完整)定义:

flies(duck).
flies(eagle).

swims(penguin).
swims(ostrich).
swims(duck).
swims(kiwi).
swims(eagle).

现在让我们进行查询:

?- use_module(library(lambda)).
true.

?- maplist(X+\Pred^call(Pred,X), [flies,swims]).
X = duck ;
X = eagle.

答案 1 :(得分:2)

library(lambda)很强大,但它有成本。如果你认为更简单更好' (wrt调试,特别是...)考虑

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元谓词所需的参数交换