-
Solution:
member(X, [Y|T]) :- X = Y; member(X, T). -
Demonstration:
?- member(a, []). fail. ?- member(a, [a]). true ; fail. ?- member(a, [b]). fail. ?- member(a, [1, 2, 3, a, 5, 6, a]). true ; true ; fail. -
How it works:
- We are looking for an occurrence of the first argument,
X, in the the second argument,[Y|T]. - The second argument is assumed to be a list.
Ymatches its head,Tmatches the tail. - As a result the predicate fails for the empty list (as it should).
- If
X = Y(i.e.Xcan be unified withY) then we foundXin the list. Otherwise (;) we test whetherXis in the tail.
- We are looking for an occurrence of the first argument,
-
Remarks:
- Thanks to humble coffee for pointing out that using
=(unification) yields more flexible code than using==(testing for equality). -
This code can also be used to enumerate the elements of a given list:
?- member(X, [a, b]). X = a ; X = b ; fail. -
And it can be used to “enumerate” all lists which contain a given element:
?- member(a, X). X = [a|_G246] ; X = [_G245, a|_G249] ; X = [_G245, _G248, a|_G252] ; ... -
Replacing
=by==in the above code makes it a lot less flexible: it would immediately fail onmember(X, [a])and cause a stack overflow onmember(a, X)(tested with SWI-Prolog version 5.6.57).
- Thanks to humble coffee for pointing out that using