问题描述
我需要计算 some_predicate(X)
所持有的所有 X
,而且确实有很多这样的 X
.最好的方法是什么?
I need to count all X
for which some_predicate(X)
holds, and there really a lot of such X
.What is the best way to do that?
第一条线索是findall
,累加成一个列表,返回列表的长度.
First clue is to findall
, accumulate to a list and return the length of the list.
countAllStuff( X ) :-
findall( Y
, permutation( [1,2,3,4,5,6,7,8,9,10], Y )
, List
),
length( List, X ).
(permutation/2
只是一个虚拟的占位符,表明有很多结果,而且计算计数的方法很糟糕)
(permutation/2
is only a dummy placeholder demonstrating that there are many results and that it's bad way to compute the count)
显然,对于真实数据,会有堆栈溢出.
Obviously, with real data, there will be a stack overflow.
?- countAllStuff( X ).
ERROR: Out of global stack
然后,我试图用 setof
替换 findall
,但无济于事.
Then, I'm trying to replace findall
with setof
, to no avail.
最后,我找到了 [aggregate
][1](可点击)系列谓词,并尝试使用 aggregate/3
和 aggregate/4
:
At last, I've found the [aggregate
][1] (clickable) family of predicates, and trying to use aggregate/3
and aggregate/4
:
?- aggregate(count, permutation([1,2,3,4], X), Y ).
X = [1, 2, 3, 4],
Y = 1 .
?- aggregate(count, [1,2,3,4], permutation([1,2,3,4], X), Y ).
X = [1, 2, 3, 4],
Y = 1 ;
X = [1, 2, 4, 3],
Y = 1 ;
我想,这一切都错了.我需要得到这样的东西:
It's all wrong, I think. I need to get something like this:
?- aggregate(count, permutation([1,2,3,4], X), Y ).
Y = 24 .
我做错了什么?
What am I doing wrong?
我如何声明一个谓词来计算正确的答案?[1]:http://www.swi-prolog.org/pldoc/doc/home/vnc/prolog/lib/swipl/library/aggregate.pl
How can I declare a predicate to conpute the right answer?[1]: http://www.swi-prolog.org/pldoc/doc/home/vnc/prolog/lib/swipl/library/aggregate.pl
推荐答案
使用存在量化的变量,就像使用 setof
一样:
Use an existentially quantified variable, as you would with setof
:
?- aggregate(count, X^permutation([1,2,3,4], X), N).
N = 24.
这篇关于在 SWI-Prolog 中聚合谓词的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!