Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prolog - count occurrence of number

Tags:

prolog

I want to write predicate which can count all encountered number:

count(1, [1,0,0,1,0], X).
X = 2.

I tried to write it like:

count(_, [], 0).
count(Num, [H|T], X) :- count(Num, T, X1), Num = H, X is X1 + 1.

Why doesn't work it?

like image 778
user Avatar asked Dec 06 '25 08:12

user


1 Answers

Why doesn't work it?

Prolog is a programming language that often can answer such question directly. Look how I tried out your definition starting with your failing query:

?- count(1, [1,0,0,1,0], X).
   false.
?- count(1, Xs, X).
   Xs = [], X = 0
;  Xs = [1], X = 1
;  Xs = [1,1], X = 2
;  Xs = [1,1,1], X = 3
;  ... .
?- Xs = [_,_,_], count(1, Xs, X).
   Xs = [1,1,1], X = 3.

So first I realized that the query does not work at all, then I generalized the query. I replaced the big list by a variable Xs and said: Prolog, fill in the blanks for me! And Prolog did this and reveals us precisely the cases when it will succeed.

In fact, it only succeeds with lists of 1s only. That is odd. Your definition is too restricted - it correctly counts the 1s in lists where there are only ones, but all other lists are rejected. @coder showed you how to extend your definition.

Here is another one using library(reif) for SICStus|SWI. Alternatively, see tfilter/3.

count(X, Xs, N) :-
   tfilter(=(X), Xs, Ys),
   length(Ys, N).

A definition more in the style of the other definitions:

count(_, [], 0).
count(E, [X|Xs], N0) :-
   if_(E = X, C = 1, C = 0),
   count(E, Xs, N1),
   N0 is N1+C.

And now for some more general uses:

How does a four element list look like that has 3 times a 1 in it?

?- length(L, 4), count(1, L, 3).
   L = [1,1,1,_A], dif(1,_A)
;  L = [1,1,_A,1], dif(1,_A)
;  L = [1,_A,1,1], dif(1,_A)
;  L = [_A,1,1,1], dif(1,_A)
;  false.

So the remaining element must be something different from 1.

That's the fine generality Prolog offers us.

like image 135
false Avatar answered Dec 09 '25 00:12

false



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!