Reputation: 2441
I am new to Prolog and I am trying to remove the last element from a list. The code I have tried:
removeLast([],[_]).
removeLast([_|T], [_|OT]):-removeLast(T, OT).
Obtained from here. I executed the code from SWi Prolog and I am getting a weird output ...
1 ?-
| removeLast(X, [1,2,3,4]).
X = [_G299, _G302, _G305] .
This is supposed to show [1,2,3], instead it is showing some numbers(?)
I don't know what am I doing wrong, why it is displaying in this format? I tried every Google combination I know of to search this term, although I saw people use this format directly in their queries like, parent(X, _G3248)
.
Update: Thanks to @lurker, modifying the code to the original format gives the output correctly:
removeLast([],[_]).
removeLast([X|T], [X|OT]):-removeLast(T, OT).
15 ?- removeLast(X, [1,2,3,4]).
X = [1, 2, 3]
But can someone explain, what is _G3240?
Upvotes: 0
Views: 949
Reputation: 58244
Here's the difference in the behavior of the solutions. Let's take the malfunctioning one.
removeLast([],[_]).
This rule says that if I have a list of one element, then the corresponding list with last element removed is []
and I don't care what that one element was (it could even be a variable). This is true, and a valid rule.
removeLast([_|T], [_|OT]) :- removeLast(T, OT).
This rule says that [_|T]
is [_|OT]
with the last element removed if I don't care what their first elements are and T
is OT
with its last element removed (following the same rules). This doesn't sound quite right. It means that if I am removing the last element from a list, I don't care what element I have in my result. So you get an arbitrary list of elements whose count is one less than your original list. But the elements don't match those at the front of the original list. In Prolog, the two _
instances are different anonymous variables. They are not unified.
The corrected clause is:
removeLast([X|T], [X|OT]) :- removeLast(T, OT).
This says that a list [X|T]
is the list [X|OT]
with its last element removed if T
is the list OT
with its last element removed. The common X
means they share the same head of the list, which is correct. When the recursion reaches the very last element of the second argument, then the first clause is matched and that single-element tail is replaced by the empty list []
. And then you get the correct, final result.
I refer to the _
variable as "anonymous" rather than "don't care" since there are some uses for anonymous variables in which their values do matter. Often though, as in this case, they are used when the value is not being used.
Upvotes: 1