Abbott%AEROSPACE@sri-unix.UUCP (11/10/83)
From: Abbott at AEROSPACE (Russ Abbott) I agree with Richard that (1) f_i(X1, X2, .. , Xn) =.. [f_i, X1, X2, .. , Xn]. call(p_i(X1, X2, .. , Xn) :- p_i(X1, X2, .. , Xn). (and let's include) current_predicate(p, p(X1, X2, .. , Xn)). % Succeeds if p/n % is defined. are first order definitions of =.. (univ), call, and current_predicate for particular f_i and p_i. One could have as many of these as one wants. (Note, current_predicate is defined in the Edinburgh C-Prolog that I have. I'm assuming that it's a more or less standard built-in.) But I don't suppose one would really want to claim that (2) (for all n) F(X1, X2, .. , Xn) =.. [F, X1, X2, .. , Xn]. call(P(X1, X2, .. , Xn)) :- current_predicate(P, P(X1, X2, .. , Xn)), P(X1, X2, .. , Xn)). current_predicate(P, P(X1, X2, .. , Xn)). are also first order definitions ? I suppose the real question is: when is there a difference between (1) and (2)? As Richard points out (that David Warren points out), for a static collection of predicates and functors, (2) can be understood as an abbreviation for (1). But as Richard also points out, if one allows assert, (2) gives one more than (1). For example, assert(new_p(a)), call(new_p(a)) will succeed with (2) but not with (1). It will not succeed with (1) since under (1) the clause: call(new_p(X1, X2, .. , Xn) :- new_p(X1, X2, .. , Xn). does not exist. Given all that, and also given that, in fact, Prolog's are built with assert and with the (2) version of the functions discussed, my next question is: Why don't most Prolog's allow call(P(X1, X2, .. , Xn)). for variable P, where call is defined as above? It certainly would be a convenience for the user in certain situations. According to the preceding argument it is essentially the same as allowing assert--which they do. And in any event, if the system doesn't do it for me, I can define my own. (Although the syntax isn't quite so pretty.) my_call(P, X) :- current_predicate(P, Y), not P = my_call, % to avoid an infinite loop. Y, Y =.. [P | X]. If P and X are initially uninstantiated, my_call(P, X) will succeed with P instantiated in turn to all the predicates that succeed with some argument(s), and with X instantiated to the successful argument list(s). -- Russ Abbott