Appeared in Volume 8/1, February 1995
Samuel Yet K Hung
21st November 1994
When I posed this query in Prolog:
The result is X = 44.
Can anyone tell me why this happened? Also, since my intended program needs X = true, can you tell me how I can achieve this?
Richard A. O'Keefe
2nd December 1994
The query clause(Head, Body) asks:
"find rules H:-B where Head = H and Body = B"
It asks about the literal term structure of a stored clause. Now, consider three different Prolog systems.
(A) implements calls to '>' by special in-line code sequences produced by the compiler. For the sake of interpreted calls, it has a rule:
X > Y :- X > Y.
This isn't as circular as it sounds; the call on the right turns into special in-line code that does not call (>)/2. Quintus Prolog used to have rules like this; I don't know what it does now.
(B) implements '>' on top of term comparison. It has a rule:
X > Y :- is(VX, X), is(VY, Y), compare(>, VX, VY).This is not in fact correct for mixed arithmetic; floats and integers should be well separated by term comparison. Never mind; some Prologs didn't have floating point.
(C) implements '>' using a special hook to the interpreter. It has rules of a very special form that the user is not allowed to define and is never supposed to see:
X > Y :- 44.
When the interpreter is about to execute the body of a clause, it checks to see if that's a number, and if so it executes the right part of a giant 'C' switch() statement. That is the way C Prolog works.
Now, let's review what clause/2 should do in each case.
(A) The stored clause is :-
( /*H=*/ >(X,Y), /*B=*/ >(X,Y) ).(B) The stored clause is :-
( /*H=*/ >(X,Y), /*B=*/ ','(is(VX,X), ','(is(VY,Y), compare(>,VX,VY))) ).(C) The stored clause is :-
( /*H=*/ >(X,Y), /*B=*/ 44 ).The query
clause(1 > 0, Body)should produce these results:
Body = (1 > 0)
Body = (VX is 1, VY is 0, compare(>, VX, VY)) % up to variable
Body = 44
In no case is the Body 'true', and the reason is not hard to find. When you ask clause(Head, Body), you are not asking whether Head is true, you are asking "What would you do to prove Head?"
As I've shown, different systems may legitimately implement built-in predicates in very different ways, and for that matter, different versions from the same vendor may use different methods. The only predicates for which calling clause/2 makes any sense are the ones you have defined, and you have not defined (>)/2! Quintus Prolog makes this really clear by reporting a run-time error if you try to inspect the code of built-in predicates. (DEC-10 Prolog did make a distinction, but it just quietly failed such queries.) The only reason that you can see '44' in your test is that there is a bug in the version of C Prolog you are using.
What is it that you are trying to do?