Interview question!
This is how you normally define the member
relation in Prolog:
member(X, [X|_]). % member(X, [Head|Tail]) is true if X = Head % that is, if X is the head of the list member(X, [_|Tail]) :- % or if X is a member of Tail, member(X, Tail). % ie. if member(X, Tail) is true.
Define it using only one rule.
If Term is a variable and List is a list, all the members of the list List are found on backtracking. If List is not instantiated, member/2 binds List to a new partial list containing the element Term. The definition of this Prolog library predicate is: member(X,[X|_]).
Because of the problems of negation-as-failure, negation in Prolog is represented in modern Prolog interpreters using the symbol \+ , which is supposed to be a mnemonic for not provable with the \ standing for not and the + for provable.
Used to check that Element is not a member of the list List. The definition of this Prolog library predicate is: nonmember(Arg,[Arg|_]) :- !, fail. nonmember(Arg,[_|Tail]) :- !, nonmember(Arg,Tail).
You can't modify lists in Prolog, but you can create a list with an unspecified length: main :- A = [1,2,3,4|_]. Then, you can insert an element using nth0/3 in SWI-Prolog: :- initialization(main).
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:
X
, in the the second argument, [Y|T]
.Y
matches its head, T
matches the tail.X = Y
(i.e. X
can be unified with Y
) then we found X
in the list. Otherwise (;
) we test whether X
is in the tail.Remarks:
=
(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 on member(X, [a])
and cause a stack overflow on member(a, X)
(tested with SWI-Prolog version 5.6.57).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With