name = 'palindrome/1' slug = 'check if list is a palindrome' description = '''\
palindrome(L)
: the elements of list L
are the same when read from the front or back of the list.
?- palindrome([1,2,3,2,1]). true. ?- palindrome([1,2,3]). false. ?- palindrome([a,b,b,a]). true.''' plan = ['''\
A palindrome is a list (ok, a word) that reads the same from front or back. Like aibohphobia! Was it a car or a cat I saw? ;)
''', '''\As always we want to reduce the problem into a smaller one. Let's chop off the first and the last element of a list, and, if equal, proceed recursively.
''', '''\If head H
of list L
is equal to the list's last element, and if the remainder
(middle part) is a palindrome, then list L
is also a palindrome.
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).
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? Which list represents the shortest possible palindrome?
''', '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 N
is equal to N + 1
,
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?
''', '[X,X]_instead_of_[]_base_case': '''\Well, [X,X]
is definitely a good base case. However, it doesn't cover one special case,
and that is an empty list. Of course, this is a matter of definition (taste even?), but please correct it
so that we all have solutions working in the same way.
Do you take two elements out with each recursive call? How does this end? Odd, even? ;)
Try the following two queries. One will work nicely, the other one won't. What's the difference?
?- palindrome([a,b,b,a]).
?- palindrome([l,e,v,e,l]).
Note that _
is not the same as [_]
. The first pattern represents an arbitrary
variable (anything), the second a list with a single arbitrary element.
By using predicate last/2
it will be difficult to solve this exercise as it leaves the last
element in the original list.
Interesting tidbit: do you know that you could have solved this exercise with just a single predicate call? What happens with the palindrome if you... hmm, reverse it? ;)
''', 'final_hint_2': '''\You can make the solution even shorter! How can you get rid of the operator =
(==
)
or rather make it implicit?