I'm trying to implement some predicates for list manipulation in Prolog. Everything works as desired. For example
append([],Ys,Ys).
append([X|Xs],Ys,[X|Zs]) :- append(Xs,Ys,Zs).
Sample query:
?- append([1,2,3],[4,5,6],X).
X = [1,2,3,4,5,6]. % OK
But I'm having trouble with the 'delete'-predicate. Here's how it's implemented:
delete(X,[Y|Ys],Zs) :- X == Y, delete(X,Ys,Zs).
delete(X,[_X|Ys],[_Z|Zs]) :- delete(X,Ys,Zs).
delete(_X,[],[]).
Sample query with bad result:
?- delete(4,[1,2,3,4],X).
X = [_G8975, _G8978, _G8981]. % BAD
I've tested it with further input and it always returns a list of the expected length so in a way it works. But why am I getting only those cryptic _GXXXX and not the numbers?
Many thanks in advance!
One cryptic way to get rid of cryptic variable names is to use numbervars/3
, for example,
?- length(X, 3).
X = [_G2019, _G2022, _G2025].
?- length(X, 3), numbervars(X, 0, _).
X = [A, B, C].
Now to your delete/3
. Apart from other minor problems, like unusual order of the arguments, unusual order of the clauses, etc, you have one major problem: in the second clause, you put a new, anonymous variable where the element of the original list should have been.
delete(X, [Y|Ys], [Y|Zs]) :- delete(X, Ys, Zs).
With this in the second clause, it sort of works:
?- delete(4, [1,2,3,4], L).
L = [1, 2, 3] .
?- delete(2, [1,2,3,4,2,3,4], L).
L = [1, 3, 4, 3, 4] .
There are further problems with your implementation. You can look at the implementation of the same predicate in library(lists)
from SWI-Prolog: read the documentation, too!