我想计算自定义谓词为真的次数.例如,我有以下代码:
is_man(john).
is_man(alex).
?:-is_man(X).
Run Code Online (Sandbox Code Playgroud)
X将返回john,然后如果我按分号,它也将返回alex,然后返回false.
我想建立像:
count(is_man(X), Count).
Run Code Online (Sandbox Code Playgroud)
而这回归
Count = 2
Run Code Online (Sandbox Code Playgroud)
我怎样才能做到这一点?
Kaa*_*rel 28
在SWI-Prolog中:
aggregate_all(count, is_man(X), Count).
Run Code Online (Sandbox Code Playgroud)
har*_*ath 11
对于ISO标准Prolog解决方案,您可以使用findall/3生成所有解决方案的列表,然后将Count设置为结果列表的长度.如你所提议的那样将它包装成用户定义的谓词count/2可能有点棘手,因为我们需要以一种方式形成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)).
Run Code Online (Sandbox Code Playgroud)