[comp.lang.prolog] setof / ,/2

bimbart@kulcs.uucp (Bart Demoen) (08/26/88)

In article <301@quintus.UUCP> ok@quintus.uucp (Richard A. O'Keefe) writes:

> Well, no.  That was just one example.  Let me provide another example:
>         | ?- A = 1, B = 1,
>         |    setof(X, (X = A ; X = B), L).
> Result: L = [1]
> 
>         | ?- setof(X, (X = A ; X = B), L),
>         |    A = 1, B = 1.
> Result: L = [1,1]

I will try one more time: if setof/3 is non-logical when its solutions are not
ground, that is because @</2 (and its sisters) are non-logical for non-ground
arguments; after all, setof/3 tries to order with @</2 or doesn't it ?


In article <307@quintus.UUCP> ok@quintus.uucp (Richard A. O'Keefe) writes:

> {I claim that clause((_,_), _) SHOULD report an error in every Prolog;
>  (_,_) has a definition, it's just that the Prolog system refuses to
>  show it do you.}

sounds as if ok@quintus wants to tell us that (_,_) actually has a Prolog
definition, but that his favourite Prolog doesn't want to show it by means
of clause/2 ... a disease inherited from Edinburgh ?
I am amazed: there is no reason why 'every Prolog' should have a Prolog
definition of (_,_); on the contrary
,/2 is a syntactic construct, with a semantics, but it is not a builtin
predicate, nor a predicate defined in Prolog

bimbart@kulcs.uucp
Bart Demoen
Dept. of Computer Science
Celestijnenlaan 200A
B-3030 Leuven
Belgium

ok@quintus.uucp (Richard A. O'Keefe) (08/30/88)

In article <1411@kulcs.kulcs.uucp> bimbart@kulcs.UUCP (Bart Demoen) writes:
>I will try one more time: if setof/3 is non-logical when its solutions are not
>ground, that is because @</2 (and its sisters) are non-logical for non-ground
>arguments; after all, setof/3 tries to order with @</2 or doesn't it?

Yes, setof/3 does its ordering with compare/3.  But that is not material.
What matters is that if an all-solutions predicate finds non-ground
solutions, it cannot tell *THEN* whether they are identical or not.
I don't care what you use to check whether X and Y are the same term,
you are going to have trouble with f(_,b) and f(a,_).  They _might_
later turn into f(a,b).  Or they _might_ later turn into f(2,b) and
f(a,surprise).  The problem is the timing of the decision.  There are
two ways that a variable might get into an answer:  it might be inherited
from the original query, in which case coroutining could take care of the
problem, or it might come from the data base, in which case coroutining
would _not_ take care of the problem, because the problem is that the
solution set is infinite.  Examples:

%  Variables inherited from query:

| ?- setof(X, member(X,[f(U,b),f(a,V)]), L).

yields L = [f(U,b),f(a,V)] in Quintus Prolog.

%  Variables coming from the data base:

p(f(_,b)).
p(f(a,_)).

| ?- setof(X, p(X), L).

yields L = [f(_1,b),f(a,_2)] in Quintus Prolog.

THESE TWO LISTS MEAN DIFFERENT THINGS.  In the first case, U and V are
ordinary Prolog variables, and the answer is
	L = [f(a,b)] & U = a & V = b
    |	L = [f(U,b),f(a,V)] & U ~= a
    |	L = [f(U,b),f(a,V)] & V ~= b
and the only thing which prevents us choosing between the alternatives
is the _timing_ of the decision: we don't know what U and V are _yet_.
In the second case, _1 and _2 are really meta-variables: *every*
instance of f(_1,b) and *every* instance of f(a,_2) is a solution of
p(X) and so should be in the set represented by L.

One of the reasons that the public-domain setof goes to the trouble of
trying to put the original variables back into the solutions is to make
it easier to distinguish between these two cases.

In a Prolog system with coroutining, it is possible to overcome the first
difficulty:  at compile time determine what the free variables are, and
generate code which will cause the query to be delayed until they are ground.
But the setof(X, p(X), L) query will proceed in such a system, because all
the variables in the nested query are appropriately quantified.

What does NU Prolog do with this second case?

>In article <307@quintus.UUCP> ok@quintus.uucp (Richard A. O'Keefe) writes:
>
>> {I claim that clause((_,_), _) SHOULD report an error in every Prolog;
>>  (_,_) has a definition, it's just that the Prolog system refuses to
>>  show it do you.}
>
>sounds as if ok@quintus wants to tell us that (_,_) actually has a Prolog
>definition, but that his favourite Prolog doesn't want to show it by means
>of clause/2 ... a disease inherited from Edinburgh ?
>I am amazed: there is no reason why 'every Prolog' should have a Prolog
>definition of (_,_); on the contrary
>,/2 is a syntactic construct, with a semantics, but it is not a builtin
>predicate, nor a predicate defined in Prolog

I said "a definition".  I did *not* say "a Prolog definition".
Demoen actually agrees with me: he says that it has "a semantics",
which is no more and no less than "a definition".
Similarly, consider foreign code, perhaps a Fortran subroutine which
has been dynamically loaded into a Prolog program.  The interface
predicate is defined, you can call it, it is capable of succeeding,
but clause/2 cannot show you the definition (although there IS a
definition).

I never claimed that _any_ Prolog system should have "a Prolog
definition of (_,_)". What I said was that I think that every Prolog
system should report as an error any attempt to obtain the Prolog code
for a (particular built-in) predicate which has a definition _that is
not in Prolog_ (or is for some other reason unavailable).  I didn't say
that clause((_,_), _) should be an error because (_,_) HAS a Prolog
definition, but because it HASN'T. I am saying that it only makes sense
to call clause/2 on predicates whose definition is thought to be in
Prolog.  What is so amazing about that?

In "Edinburgh" Prologs, ','/2 _is_ a built-in predicate:  you can at
run-time do e.g.
	C = ',', A = (X=1), B = (Y=2),
	Goal =.. [C,A,B],
	call(Goal)
With the aid of LIB:APPLY.PL or library(call) you can even do
	call(',', call(=,X,1), call(=,Y,2)).
Looks like a built-in predicate to me.

What properties distinguish "a builtin predicate" from
"a syntactic construct, with a semantics" in Prolog?
[Of course you can have a logic programming language, even one with "call",
 where ',' _is_ just a syntactic construct.  That's not the question.]