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?
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
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
Then, I'm trying to replace findall
with setof
, to no avail.
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?
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
Use an existentially quantified variable, as you would with setof
:
?- aggregate(count, X^permutation([1,2,3,4], X), N).
N = 24.