Subject: Re: troubles with SWI -Prolog

From: "Richard A. O'Keefe" <[email-masked]>
Date: Thu, 14 Sep 2000 13:42:45 +1200 (NZST)

I'm having some problems getting some list operations to work.

Nope, you're having problems with basic syntax.
	del( X, [X | Tail], Tail).
	
	del (X, [ Y| Tail ], [ Y | Tail1] ) :- del(X, Tail, Tail1).
           ^	
	
Can can Prolog tell the difference between a compound term and
a unary operator applied to a tuple?

	f(X, Y, Z)		must be a compound term
	f (X,Y,Z)		must be a unary operator applied to (X,Y,Z).

In functional programming languages with syntax based on the lambda calculus,
it is good style to put spaces after function names, as in
	elem x xs
	conc xs ys
	del x xs
In no other programming languages is this so.  It isn't good style to put
spaces after function names in C, Pascal, C++, Ada, Java, Eiffel, you name
it.  And in Prolog it just plain doesn't work.

There is another problem with your del/3 implementation which you would
certainly have found yourself once you got past the syntax error.
You are programming as if the FIRST solution found for a goal was the
ONLY solution ever to be reported.  But that's not what Prolog is all
about.  In Prolog you define *relations*, not functions, and Prolog is
*supposed* to return multiple solutions when multiple solutions exist.

Given
	del(X, [X|Tail], Tail).
	del(X, [Y|Tail], [Y|Rest]) :- del(X, Tail, Rest).

the query
	?- del(1, [3,1,4,1,5], Ans).
has solutions
	Ans = [3,4,1,5] ;
	Ans = [3,1,4,5] .

Which of them do you want?  If you really want both, you ought to say
so in a comment.  If you want the first one, you need a cut.  If you
want all the instances of X to go away, you need a different definition.
	
For what it's worth, your del/3 is what the DEC-10 Prolog library
called select/3 because you can use it to select an element from a
set and return the element and the reduced set.

	%   del(X, Xs, Ys)
	%   is true when Xs has X as an element and Ys is the same
	%   as Xs except that it is missing one copy of X.
	%   In general this has multiple solutions.

	del(X, [X|Xs], Xs).
	del(X, [Y|Xs], [Y|Ys]) :- del(X, Xs, Ys).

	%   del1(X, Xs, Ys)
	%   is true when Xs has X as an element and Ys is the same
	%   as Xs except that it is missing the first copy of X.
	%   This has at most one solution.  See the Craft of Prolog
	%   to find out why the output unification was moved past
	%   the cut.  X and Xs should be ground.

	del1(X, [X|Xs], Ys) :- !, Ys = Xs.
	del1(X, [Y|Xs], [Y|Ys]) :- del1(X, Xs, Ys).

	%   del_all(X, Xs, ys)
	%   is true when Ys is the same as Xs except that it contains
	%   no copies of X.  Xs need not contain X in the first place.
	%   This has at most one solution.  X and Xs should be ground.
	
	del_all(_, [], []).
	del_all(X, [X|Xs], Ys) :- !, del_all(X, Xs, Ys).
	del_all(X, [Y|Xs], [Y|Ys]) :- del_all(X, Xs, Ys).

/