2

I want to count a specific element in a list.

?count(3,[3,3,3],C).

count(_,[],_).
count(X,[Y|R],C):- X \= Y, count(X,R,C).
count(X,[Y|R],C):- X = Y, L is C + 1, count(X,R,L).

But I get this error and I do not see why: Arguments are not sufficiently instantiated In: [1] count(3,[3,3|...],_1594)

Do you have a tipp?

Lisa
  • 87
  • 5

1 Answers1

2

The instantiation error occurs in the goal L is C + 1 as the variable C is unbound when the goal is called.

One solution is to rewrite the predicate to use an accumulator. Doing the minimal changes to your code:

count(Element, List, Count) :-
    count(Element, List, 0, Count).

count(_, [], Count, Count).
count(X, [Y|R], Count0, Count) :-
    X \= Y,
    count(X, R, Count0, Count).
count(X, [Y|R], Count0, Count) :-
    X = Y,
    Count1 is Count0 + 1,
    count(X, R, Count1, Count).

With your sample call:

| ?- count(3, [3,3,3], Count).

Count = 3 ? ;

no

Notice that this new definition leaves a spurious choice-point. Can you improve it so that calls (with the two first arguments ground) become deterministic? Hint: start by moving the list argument to the first position in the auxiliary count/4 predicate.

Paulo Moura
  • 18,373
  • 3
  • 23
  • 33