Prolog计算谓词为真的次数

时间:2011-05-19 14:30:13

标签: prolog

我想计算自定义谓词为真的次数。 例如,我有以下代码:

is_man(john).
is_man(alex).
?:-is_man(X).

X将返回john,然后如果我按分号,它也将返回alex,然后返回false。

我想构建类似的东西:

count(is_man(X), Count).

这将返回

Count = 2

我该怎么做?

3 个答案:

答案 0 :(得分:27)

在SWI-Prolog中:

aggregate_all(count, is_man(X), Count).

答案 1 :(得分:11)

对于ISO标准Prolog解决方案,您可以使用 findall / 3 生成所有解决方案的列表,然后将Count设置为结果列表的长度。如你所提议的那样将它包装成用户定义的谓词 count / 2 可能有点棘手,因为我们需要在a中形成 findall / 3 的第一个参数。考虑你想要作为 count / 2 的第一个参数传递的目标中的任何免费(未绑定)变量的方式。

许多Prolog提供“计数器”或其他形式的可变全局值,一种非标准扩展,可以与故障驱动的“循环”结合使用以进行相同的计数。稍微麻烦但坚持Prolog标准的字母将是使用断言收回来通过调整动态事实来创建自己的“计数器”。

后面的方法的说明如下。使其“多线程安全”需要额外的逻辑。

count(Goal,_) :-
    setGoalCount(0),
    call(Goal),
    incGoalCount(1),
    fail.              /* or false in some Prologs */
count(_,Count) :-
    getGoalCount(Count).

setGoalCount(_) :-
    retract(getGoalCount(_)),
    fail.
setGoalCount(X) :-
    assert(getGoalCount(X)).

incGoalCount(Y) :-
    retract(getGoalCount(X)),
    !,
    Z is X + Y,
    assert(getGoalCount(Z)).

答案 2 :(得分:5)


count(P,Count) :-
        findall(1,P,L),
        length(L,Count).