Path: utzoo!mnetor!uunet!seismo!sundc!pitstop!sun!quintus!ok
From: ok@quintus.UUCP (Richard A. O'Keefe)
Newsgroups: comp.lang.prolog
Subject: Re: Ranges of values in Cprolog
Message-ID: <944@cresswell.quintus.UUCP>
Date: 7 May 88 04:27:47 GMT
References: <242@yetti.UUCP> <451@cmx.npac.syr.edu>
Organization: Quintus Computer Systems, Mountain View, CA
Lines: 43

In article <451@cmx.npac.syr.edu>, hamid@hilbert.uucp (Hamid Bacha) writes:
> Try the following:
> :- op(500, xfx, in).
> :- op(802, xfx, '..').  % precedence higher than that of '-' to allow 
> 			% for negative numbers
In an Edinburgh-compatible Prolog, "-  is a special case; the
"-" here is the tightest binding operator and is not disabled by
	:- op(0, fy, -).
which cancels the usual unary minus.  Thus after doing
	:- op(400, xfx, ..).
both
	X = [-1..2]
and	X = [2.. -1]
should be legal.

In an Edinburgh-compatible Prolog, +  has no special meaning;
if + is a unary operator +1 means +(1).  name/2 and number_chars/2 (if it
exists) are not supposed to accept leading "+" signs either.
 
> X in [S .. L] :- S < L, X = S.
> X in [S .. L] :- S < L, N is S + 1, X in [N .. L].
> X in [X .. X].

This is actually not an efficient way of coding it in any Prolog.
Every iteration builds another [N..L] which requires a global frame
holding two bindings in a structure sharing system or takes 5 cells
in a structure copying system.

In C Prolog, which doesn't do last call optimisation, it is better
to use this thing which I dug out of an old benchmark file:

%   from(LowerBound, UpperBound, I)
%   binds I to successive integers in the range LowerBound..UpperBound.
%   Use it when it is already known that integer(LowerBound),
%   integer(UpperBound), LowerBound =< UpperBound, and var(I).
%   More generally, use the library predicate between/3, or perhaps repeat/1.
%   This version is for non-TRO systems.  [Due to D.H.D.Warren.]

from(I, I, I) :- !.
from(L, U, I) :- M is (L+U) >> 1,       from(L, M, I).
from(L, U, I) :- M is (L+U) >> 1 + 1,   from(M, U, I).

Don't forget to tell C Prolog that you want expanded_exprs.