1
votes

Here is my code.

equals2(X,Y,N,I):- X is Y,I is N+1; I is N.
elemNum(X,[],0).
elemNum(X,[Y|Ys],N) :-  elemNum(X,Ys,N1),equals2(X,Y,N1,I),N is I.

lemNum first argument is element from array, second is array. It counts the number of elements in array. Then in console

| ?- elemNum(1,[1,2,3,1,1],N),N<2.

N = 1 ? 

yes

I am sure than my function elemNum works just fine. How its possible that in console this assertion returns 1? Thanks for help

1

1 Answers

0
votes

Non sure to understand what do you want ... but I suppose that you want count the number of element in the list (second argument of elemNum/3) that are equals to the first argument.

If so, you should modify equals2/4 as follows

equals2(X,Y,N,I):- X is Y,I is N+1; X \== Y, I is N.

or better (IMHO) split it in 2 different clauses

equals2(X,X,N,I):- I is N+1.

equals2(X,Y,N,N):- X \== Y.

With your equal2/4, the second or case (I is N) is executed (in backtracking) even when X is equal to Y so elemNum(1,[1,2,3,1,1],N) unifiy N with 3, 2, 2 again, 1, 2, 1, 1 again and 0.

Regarding elemNum/3, works but you can semplify it (avoiding a warning) as

elemNum(_,[],0).

elemNum(X,[Y|Ys],I) :-  elemNum(X,Ys,N1), equals2(X,Y,N1,I).

or you can rewrite it, avoiding the use of equals2/4 as

elemNum(_, [], 0).

elemNum(X, [X | Ys], I) :-  elemNum(X, Ys, I0), I is I0+1. 

elemNum(X, [Y | Ys], I) :-  X \== Y, elemNum(X, Ys, I).