name = 'memb/2' slug = 'find elements in list' description = '''\
memb(M, L)
: M
is an element of list L
.
?- memb(X, [1,2,3]). X = 1 ; X = 2 ; X = 3. ?- memb(1, [3,2,X]). X = 1.''' plan = ['''\
Where can we find the searched for element X
? Remember that the list has two parts: the head and
the tail. Therefore, there are two possibilies! ;)
In prolog we can understand a list like a queue of people waiting for a bus. The driver only sees
the first person in the queue, the others are hidden in the list's tail. So the element X
can either be at the start of the queue or...
It's easy to look at ("search for") the head of the list. But how do we search the tail? Simply,
we remove the first element and repeat the search with the smaller list (tail). If [H|T]
is our whole list, then T
is this same list without the first element.
Since the new list (tail) is smaller, we reduced the problem and thus facilitated the use of recursion.
The operator ==
is "stricter" than operator =
in the sense that
for the latter it is enough to be able to make the two operands equal (unification). Perhaps by using =
you can make the predicate memb/2
more general (e.g. able to work with output arguments becoming inputs).
Of course, you can also solve the exercise without explicit use of either of these two operators, just remember that unification is implicitly performed with the predicate's arguments (head of clause).
''', 'eq_instead_of_equ_markup': '''\Perhaps the operator for unification (=) would be better?
''', 'base_case': '''\Did you think of a base case? What is the simplest possible case if the element is present in the list? Which element in the list is the easiest to access?
''', 'recursive_case': '''\The base case is ok. However, what about the general recursive case?
''', 'predicate_always_false': '''\It seems your predicate is
If the name is correct, check whether something else is misspelled, perhaps there is a full stop instead of a comma or vice versa, or maybe you typed a variable name in lowercase?
It is, of course, also possible that your conditions are too restrictive, or even impossible to satisfy
(as would be, for example, the condition that an empty list []
is equal to a list with
exactly three elements [A,B,C]
,
or something similarly impossible).
Is there an infinite recursion at work here? How will it ever stop?
Or perhaps is there a missing, faulty, or simply incompatible (with the general recursive case) base case?
''', 'final_hint': '''\Predicate memb/2
is useful for much more than just checking whether a list contains
a given element or not. Actually, most of the time, it's used in "a different direction" as
"return some element X
from list L
". In fact you've just written yourself
a generator of elements from the list.
Try the following query:
?- memb(Coin, [1,2,5,10,20,50,100,200]).
or this one:
?- memb(Operator, [+, -, *, /]).
Can you form a query to ask prolog how do we get a sum of 30 cents with exactly three coins?
The operator =:=
is used to check for arithmetic equality. How many solutions are there? ;)