There are several issues in your program. But first, as a beginner:
Stick to the pure monotonic subset of Prolog
In your program, you are using (==)/2
which is no longer in that pure subset. In your case replace it by (=)/2
.
Always look at all the answers
Prolog's top-level loops shows you only the first answer. You have to demand for more by pressing ; or SPACE. Your program with (=)/2
gives (with more readable variables):
?- delete(4,[1,2,3,4],X).
X = [_A,_B,_C] ;
X = [_A,_B,_C,_D] ;
false.
That is: Not only is the first answer unexpected, but there is a second one, with a list of same length as the original one. On the other hand, the first answer included the expected solution. So the program is rather too general.
Reduce the input size
?- delete(4,[4],L).
L = [] ;
L = [_A] ;
false.
The first answer seems now correct, but the second is entirely unexpected. That is, the definition is too general as witnessed by delete(4,[4],[any])
Specialize the program
To localize the program, specialize the program by introducing goals like false
, and =
as much as possible, and as long as delete(4,[4],[any])
succeeds. I come up with:
?- delete(4,[4],[any]).
delete(X,[Y|Ys],Zs) :- false, X = Y, delete(X,Ys,Zs).
delete(X,[_X|Ys],[_Z|Zs]) :- X = 4, _X = 4, _Z = any,
delete(X,Ys,Zs).
delete(_X,[],[]) :- _X = 4.
Now it should be evident that in this rule, _X =4, _Z = any
should be rather the same, and X = 4, _X = 4
should be different. Inequality is best expressed with dif/2
.
delete(_X, [], []).
delete(X, [Y|Ys], [Y|Zs]) :-
dif(X, Y),
delete(X, Ys, Zs).
delete(X, [X|Ys], Zs) :-
delete(X, Ys, Zs).
This definition can now be used in many ways. Like
?- delete(X,Xs,[1,2,3]).
Xs = [1, 2, 3],
dif(X, 3),
dif(X, 2),
dif(X, 1) ;
Xs = [1, 2, 3, X],
dif(X, 3),
dif(X, 2),
dif(X, 1) ;
Xs = [1, 2, 3, X, X],
dif(X, 3),
dif(X, 2),
dif(X, 1) ...
Note that there are now infinitely many answers!