Search code examples
listprolog

Prolog: having true and false value


I am learning to use SWI Prolog, and I am learning to use lists. A small exercise is to check if an element is in a list. Here's what I got:

member(X,[X|_]).
member(X,[_|T]):-member[X|T].

The first case goes as intended:

?- member(a,[b,a]).
true.

But the second doesn't, as some backtracking seems to appear:

?- member(a,[a,b]).
true ;
false.

How could I prevent this from happening, i.e. to get Prolog return me only true? (I don't want to ignore false.)


Solution

  • member/2 is a standard Prolog predicate. You should name yours something else. The standard predicate has the same behavior that you show.

    When you query:

    ?- member(a, [a,b]).
    true ;
    false.
    

    Prolog finds that a matches the first element and succeeds. There's more in the list to check so it prompts you for more. Pressing ; says "yes, please, check for more". When it does, it finds no more a members so then yields false (in GNU Prolog, it would say no).

    You can make it go away by either:

    • Not pressing ; but press Enter instead, OR
    • Use once/1: once(member(a, [a,b])), OR
    • You can change your predicate to include a cut in the first clause, but this is a bad idea since then it won't work in the general case: member(X, [a,b]) will only return X = a and then stop.