[net.lang.prolog] "name" and type conversion

michaelm@bcsaic.UUCP (michael b maxwell) (11/19/85)

In playing around with Poplog, we had a program which would sometimes
read in integers, but they were read in as atoms (because at the point
of reading in we weren't sure whether we would be reading in atoms or
integers).  For instance, we would have the atom '12', which was not the
same as the integer 12.  We wanted to convert such atoms into integers.
We were about to play around with all kinds of complicated schemes for
conversion (or with doing something like a "peek" at the input stream),
when one of our programmers discovered that the following succeeds:
	...name ('12', X), name (Y, X), integer (Y)...
In other words, running such an atom into and then back out of "name"
converts it from an atom to an integer!

Now this is a very handy thing to have.  However, I suspect that it's
not supposed to work that way, and probably doesn't in other Prologs.
Any comments?  Does anyone have another (simple) way of doing such a
conversion?
-- 
Mike Maxwell
Boeing Artificial Intelligence Center
	...uw-beaver!uw-june!bcsaic!michaelm

hopp@nbs-amrf.UUCP (Ted Hopp) (11/24/85)

>  ... one of our programmers discovered that the following succeeds:
> 	...name ('12', X), name (Y, X), integer (Y)...
> In other words, running such an atom into and then back out of "name"
> converts it from an atom to an integer!
> 
> Now this is a very handy thing to have.  However, I suspect that it's
> not supposed to work that way, and probably doesn't in other Prologs.
> Any comments?  Does anyone have another (simple) way of doing such a
> conversion?
> -- 
> Mike Maxwell
> Boeing Artificial Intelligence Center
> 	...uw-beaver!uw-june!bcsaic!michaelm

This works in C-Prolog v 1.3 as well.  According to the C-Prolog manual,
name(X,L) succeeds when L is a list of ASCII codes of the characters for
X, not only when X is an atom, but when X is an integer.  Thus,

	name('12',L), name(12,L).

succeeds.  C-Prolog (and, I suspect, DEC-10 Prolog, on which C-Prolog is
based) differ in this from Clocksin and Mellish, where the first argument
to name/2 must be an atom.

One way of evaluating a string of ASCII digits as an integer is as follows:

	int(N,[],N) .
	int(N,[X|L],M) :- ascii_digit(X), M1 is 10*N + X - 48, int(M1,L,M) .

	ascii_digit(X) :- 48 =< X, X =< 57 .

A sample call is:

	name('123',L), int(0,L,M)

which binds M to 123.  If int(0,L,M) fails, L is not a list of digits, or
M cannot be unified to the evaluation of L (e.g., M was already unified to
a different integer value).  (If you can assume that the second argument
will always be a list of digits, the call to ascii_digit/1 can be omitted
from the second clause of int/3.)

Prologs that define name/2 in strict accordance with Clocksin and Mellish,
I suspect, will not be able to use the name-in/name-out trick.  Use of
a predicate such as int/3 above should always be safe.

-- 

Ted Hopp	{seismo,umcp-cs}!nbs-amrf!hopp

dowding@bigburd.UUCP (John Dowding) (11/28/85)

name/2 behaves the same way in DEC 10 prolog, Quintus Prolog, and CProlog.
So the name('12',X),name(Y,X),integer(Y) query will always be true.

If you check, you will find that name, functor, and univ will always return
a number if it is possible to treat the result as a number.

This behavior causes trouble if you want to get the atom '12', not the
number.  If anyone knows a way of doing this, I would like to know it.

BTW:  Symbolics Prolog doesnt behave this way.  It has a predicate atom/2
that turns a number into an atom.

John Dowding