Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prolog Assignment

Tags:

list

prolog

This is the question for one of my assignments:

Write repCount(L, X, N) which is true when N is the number of occurrences of X in list L.

Here's my code where I try to tackle the problem recursively:

repCount([], X, N) :-
   N is 0.
repCount([H|T], X, N) :-
   count([H|T], X, N).

count([], X, 0).
count([H|T], X, N) :-
   count(T, X, N1), 
   X =:= H,
   N is N1 + 1.

And it works when I supply a list full of identical numbers like this:

?- repCount([2,2,2], 2, N).
N = 3.

But if I supply a list with at least one different value:

?- repCount([2,2,22], 2, N).
false.

It returns false. I cannot figure out why this happens or how to change it to 'skip' the non-matching value, rather than declare the whole thing false. Any input is appreciated.

like image 913
IDDQD Avatar asked Jan 18 '23 10:01

IDDQD


1 Answers

count([H|T], X, N):- count(T, X, N1), X=:=H, N is N1 + 1.

here you declare that N should be N1+1 if X is H; however you do not define what should happen if X is not H (basically missing an else clause) this should work:

count([H|T], X, N):- 
    count(T, X, N1), 
    (X=:=H->
       N is N1 + 1
       ; N is N1).

another way would be:

count([H|T], X, N):- count(T, X, N1), X=:=H, N is N1 + 1.

count([H|T], X, N):- X=\=H, count(T, X, N1), N is N1.

but this is inefficient since count(T,X,N1) will be called twice if X is not H. we can fix this by doing the check in the head of the clause:

count([H|T], H, N):- count(T, X, N1), N is N1 + 1.

count([H|T], X, N):- count(T, X, N1), N is N1.

or simply: count([H|T], H, N):- count(T, X, N1), N is N1 + 1.

count([H|T], X, N1):- X=\=H, count(T, X, N1).
like image 94
Thanos Tintinidis Avatar answered Jan 25 '23 17:01

Thanos Tintinidis