Using Prolog: Given a list check if the first element of the list equals the last element

list, prolog, recursion

Solution

Here's an easy one:

fela(L) :- first(E, L), last(E, L).

Stare at that for a minute and let it really sink in.

Actually, it would be right, but your `last/2` isn't, simply traversing the list with no base case that will ever succeed. A correct `last/2` would look like this:

last(L, [L]).
last(E, [_|L]) :- last(E, L).

I see a lot of confused ideas in your case analysis. For one thing, in Prolog, you don't explicitly return true and false. You simply match what you match and the rest is failure. When dealing with lists, you automatically inherit the base case of the empty list and the inductive case of an element and the remainder of the list. This isn't sufficient to implement `fela/1` from scratch because you have no way of remembering what your first element was. So if you want to build it from scratch you'll need a helper predicate so you can keep passing the first element along. It's going to look like this:

fela([H|T]) :- fela(H, T).

fela(First, [First]).
fela(First, [_|Xs]) :- fela(First, Xs).

Notice that we've preserved the analysis of one base case, one inductive case for handling the list. This is the usual situation when processing a recursive data structure. `first/2` is a good example of when you don't follow the rule, because you aren't interested in one of the cases. Building the predicate out of `first/2` and `last/2` lets you escape the case analysis problem altogether, and is (in my opinion) more often what happens in practice.

Now I want to single out some of your ideas here for further comment. First, `H1 is H` is definitely not what you want. `is/2` is exclusively for reducing arithmetic expressions. You will always have a variable on the left and an expression on the right, or it isn't meaningful. You're trying to do some kind of assignment here, but even `H1 = H` is not helpful here, because while Prolog has variables, it does not have assignables.

`H1 is H, H1 == T` says, implausibly, that H is both the head of the list and equivalent to the tail. This isn't ever really possible, because the tail is a list and the head is an element. Even if you could craft a situation where that were true, it definitely wouldn't be interesting to this predicate. Your recursive step here is really strange.

Another problem with your case analysis, case #3 should be true. With `[X]`, `X` is both the first and the last element of the list, so `fela/1` should be trivially true for all one-element lists.

I would advocate additional study. I think you have some odd notions that a little more reading might correct.

Problem

Using prolog, I have to create a rule that determines, when given a list, if the first element of the list is equal to the last element of the list. Below is my thinking. ``` The Base Cases: 1) If The Parameter Is Not A List: Return False 2) If The Parameter Is A List But Empty: Return False 3) If The Parameter Is A List But Has One Element: Return False The Recursive Step: Recursively Going Through The List Getting The First Element And TheLast Element Then Compare fela() :- false. <-- Base Case One fela([]):-false. <-- Base Case Two fela([H]):-false. <-- Base Case Three fela([H|T]):- H1 is H, H1 == T, fela(T,H1). <-- Recursive Step ``` Bellow Are Function For First, Last, Member ``` first(F, [F|_]). last(L, [H|T]) :- last(L, T). member(X, [X|_]). member(X, [_|T]) :- member(X, T). ``` I am having trouble with my recursive step, I am unsure of how to store the first element, and traverse the list and obtain the last element, then compare the results for a true/false answer. Could someone help me out Thanks, Erik :)

Original source