4
votes

I have something like this in my knowledge base:

number(1).
number(3).
number(6).
number(8).
number(9).
number(12).

Now, I need a predicate that evaluates how many numbers there are in the knowledge base, example:

countnumbers(X).
X = 6.

How can I do this? please, I'm new with prolog and I can't figure this out

2

2 Answers

8
votes

Use findall/3 to get all facts from your database, and then get the length of the list:

countnumbers(X) :-
    findall(N, number(N), Ns),
    length(Ns, X).

Take care: number/1 may be a built-in predicate.

8
votes

If you need to know how many X satisfied some predicate you don't need to know all of them. Using of findall/3 is really redundant in tasks like that. When you have 6 or 606 these X - it's not a big deal of course. But when you have really large and heavy generator - you don't need to keeping all values in list and then counting it length.

Aggregate solves this problem well:

numberr(1).
numberr(3).
numberr(6).
numberr(8).
numberr(9).
numberr(12).

countNumbers( Numbers ) :-
    aggregate( count, X^numberr( X ), Numbers ).

X^ means "there exists X", so the whole formula means something like "count the number X that numberr(X) and call that number Numbers.

So

?- countNumbers(X).
X = 6.