Waffles
Waffles

Reputation: 1

What is wrong with this predicate in Prolog?

        findThree([H|T],_,3).    
        findThree([H|T], M, Z):-
            ( member(H,M)
              -> Z2 is Z + 1,
              select(H,M,C),
              findThree(T,C,Z2)
              ;select(H,M,C),
              findThree(T,C,Z)
            ).

So, what I'm trying to do is see if an element is in a specified list. If it is, I increment some variable, and stop if I found 3 of those elements. However, this does not seem to be working for me- is it a problem with my syntax? I'm trying to use an If-else construct in SWI-Prolog; could that be the issue?

Upvotes: 0

Views: 1168

Answers (1)

Jeremiah Willcock
Jeremiah Willcock

Reputation: 30969

Z is Z + 1 will always fail for integers; that will compute the value of Z + 1 and then try to unify it with Z. Since Z will generally not have the same value as Z + 1, the is will fail. You will need to create a new variable Z2, use Z2 is Z + 1, and then use Z2 instead of Z in relevant places.

Taking your code and making fixes:

findThree(_,_,3).  % This should allow anything as the first element

findThree([H|T], M, Z) :-
  select(H, M, C), Z2 is Z + 1, findThree(T, C, Z2). % select includes member implicitly
findThree([_|T], M, Z) :-
  findThree(T, M, Z). % Allow this second case since it simplifies the code

Upvotes: 1

Related Questions