[comp.lang.prolog] Ranges of values in Cprolog

asst-jos@yetti.UUCP (Jonathan) (05/04/88)

	I am working with C-prolog 1.5, and have implemented the following
predicate for sets. (I use lists to implement sets)

:- op(500, yfx, in).

X in [X|Rest].
X in [Y|Rest] :- X in Rest.

?- 3 in [1,2,3].

yes
?- X in [1,2,3,4].
X = 1;
X = 2;
X = 3;
X = 4;
no
?-

I use this (in conjunction with higher level predicates) to return the 
state of a set of variables, one at a time, (ie. on failure, as in setof/3).
I would to implement the this 'in' operator to allow for the following:
	(The '..' would have the same meaning as it does in Pascal).


?- X in [1 .. 100].
X = 1;
X = 2;
X = 3;
  .
  .
  .
X = 100;
no
?-


Unfortunately, I keep running into problems when attempting this, and I am 
tired of hitting my head against a brick wall. Any suggestions???


Thanks in advance.

-------------------------------------------------------------------------
Jeffrey Klein                 BITNET: PROJ15@YUSOL
York University                 UUCP: ...!utzoo!yunexus!yuyetti!asst-jos
Toronto, Ontario  
-------------------------------------------------------------------------

nxm7669@acf5.NYU.EDU (Nik. Markantonatos) (05/05/88)

/* acf5:comp.lang.prolog / asst-jos@yetti.UUCP (Jonathan) /  2:49 pm  May  4, 1988 */

	I am working with C-prolog 1.5, and have implemented the following
predicate for sets. (I use lists to implement sets)

:- op(500, yfx, in).

X in [X|Rest].
X in [Y|Rest] :- X in Rest.

?- 3 in [1,2,3].

yes
?- X in [1,2,3,4].
X = 1;
X = 2;
X = 3;
X = 4;
no
?-

I use this (in conjunction with higher level predicates) to return the 
state of a set of variables, one at a time, (ie. on failure, as in setof/3).
I would to implement the this 'in' operator to allow for the following:
	(The '..' would have the same meaning as it does in Pascal).


?- X in [1 .. 100].
X = 1;
X = 2;
X = 3;
  .
  .
  .
X = 100;
no
?-


Unfortunately, I keep running into problems when attempting this, and I am 
tired of hitting my head against a brick wall. Any suggestions???


Thanks in advance.

-------------------------------------------------------------------------
Jeffrey Klein                 BITNET: PROJ15@YUSOL
York University                 UUCP: ...!utzoo!yunexus!yuyetti!asst-jos
Toronto, Ontario  
-------------------------------------------------------------------------
/* ---------- */
Relay-Version: version nyu B notes v1.5 12/10/84; site acf5.NYU.EDU
From: nxm7669@acf5.NYU.EDU (Nik. Markantonatos)
Date: 5-May-88 10:39 EDT
Date-Received: 5-May-88 10:39 EDT
Subject: Re: Ranges of values in Cprolog
Message-ID: <1840002@acf5.NYU.EDU>
Path: acf5!nxm7669
Newsgroups: comp.lang.prolog
Posting-Version: version nyu B notes v1.5 12/10/84; site acf5.NYU.EDU
Organization: New York University
References: <242@yetti.UUCP>



Sorry for the previous null posting.

The following program seems to be solving your problem with ranges in sets:

:- op(500,yfx,in).
:- op(400,xfx,..).

X in [Y..Z|Rest] :- !, range(Y,Z,Range), append(Range,Rest,Set), X in Set.
X in [X|Rest].
X in [Y|Rest] :- X in Rest.

range(X,Y,[X|Xs]) :- X =< Y, X1 is X + 1, range(X1,Y,Xs).
range(X,Y,[]) :- X > Y.

append([X|Xs],Ys,[X|Zs]) :- append(Xs,Ys,Zs).
append([],Ys,Ys).

?- X in [1..2,6,7,8..8,9,10..9,10].

X = 1;
X = 2;
X = 6;
X = 7;
X = 8;
X = 9;
X = 10;
no


Nick Markantonatos


Relay-Version: version nyu B notes v1.5 12/10/84; site acf5.NYU.EDU
From: gxp7658@acf5.NYU.EDU (Georgios Papadopoulos)
Date: 5-May-88 13:45 EDT
Date-Received: 5-May-88 13:45 EDT
Subject: Re: Shutterberg ( Was Re: Want Camera Bag Recommendation)
Message-ID: <1250001@acf5.NYU.EDU>
Path: acf5!gxp7658
Newsgroups: rec.photo
Posting-Version: version nyu B notes v1.5 12/10/84; site acf5.NYU.EDU
Organization: New York University
References: <1238@sbcs.sunysb.edu>

    In response to your search for Shutterbug, the address is:

			SHUTTERBUG
			Dept S067
			5211 S. Washington Ave,
			Titusville, FL 32780

You will also find subscription forms inside the `Outdoor Photographer'
magazine at 42% off ($13.97 for 12 monthly issues).


	-- Georgios Papadopoulos

Relay-Version: version nyu B notes v1.5 12/10/84; site acf5.NYU.EDU
From: efj0712@acf5.NYU.EDU (Roach)
Date: 5-May-88 21:03 EDT
Date-Received: 5-May-88 21:03 EDT
Subject: Re: First time jump; Skydive East
Message-ID: <579@acf5.NYU.EDU>
Path: acf5!efj0712
Newsgroups: rec.skydiving
Organization: New York University
References: <1372@lznv.ATT.COM> <576@acf5.NYU.EDU> <2149@mipos3.intel.com> <578@acf5.NYU.EDU> <16786@cornell.UUCP>
Reply-To: efj0712@acf5.UUCP (Roach)
Lines: 10

Please don't get me wrong, in no way am I blaming what happened to me on
any of the jump masters at SDE.  Wind conditions can vary very quickly,
and the mis-calculation which occured when I jumped may not have been 
that at all.  I think the level of instruction at SDE was very good, as
I have also sat in on a class at SKYDIVE Long Island, and preferred the
training at SDE.  I think, however, that the training at Perris Valley,
CA was superior to both though.

						Roach

hamid@hilbert.uucp (Hamid Bacha) (05/06/88)

Try the following:


%---------------

:- op(500, xfx, in).
:- op(802, xfx, '..').  % precedence higher than that of '-' to allow 
			% for negative numbers

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].

%---------------

| ?- X in [-1 .. 2].

X = -1 ;
 
X = 0 ;
 
X = 1 ;
 
X = 2 ;
 
no
| ?- X in [2 .. 1].
 
no
| ?- X in [1 .. 1]. 
 
X = 1 ;
 
no
| ?- X in [1 .. +1].
 
no

Note: The last two examples give different results because 1 is different
from +1 in some Prolog systems (including CProlog 1.5).

H. Bacha 
Logic Programming Research Group
Syracuse University

ok@quintus.UUCP (Richard A. O'Keefe) (05/06/88)

In article <242@yetti.UUCP>, asst-jos@yetti.UUCP (Jonathan) writes:
> 	I am working with C-prolog 1.5, and have implemented the following
> predicate for sets. (I use lists to implement sets)
[code for member/2, written as an infix 'in']

> I would [like] to implement this 'in' operator to allow for the following:
> (The '..' would have the same meaning as it does in Pascal).
> ?- X in [1 .. 100].
> Unfortunately, I keep running into problems when attempting this, and I am 
> tired of hitting my head against a brick wall. Any suggestions???

If you didn't get the CProlog version of the DEC-10 Prolog library with
your copy of CProlog, ask whoever you got your CProlog licence from to
explain why not.  If you _did_ get the library, you'll find a predicate
	between(LowerBound, UpperBound, X) <->
		all arguments integer & LowerBound <= X <= UpperBound
and you can adapt that.

You'll need to define your 'in' a little bit more clearly.
What, if anything, should
	c in [1..10,alpha..gamma,no(c)]
do?

It is rather ugly to have a list whose elements are not of the same
"type", and 5 and 4..6 seem to me to be of different "types".  A clean
approach to the design of such a data structure might go like this:

a <integer set> can be		% type intset -->
	an <empty> set		%	{}
	a <singleton> set	%    |	{integer}
	an <interval>, or	%    |	integer..integer
	a <union> of two sets.	%    |  intset + intset

Coding this, we obtain

	:- current_op(Prio, yfx, *), op(Prio, xfx, ..).
	:- current_op(Prio, xfx, <), op(Prio, xfx, in).

	:- lib(between).		% CProlog 1.5.edai
	:- compile(library(between)).	% Quintus Prolog

	in(Element, Set) :-
		in1(Set, Element).

	in1({Element}, Element).
	in1(Low..High, Element) :-
		between(Low, High, Element).
	in1(Set+_,     Element) :-
		in1(Set, Element).
	in1(_+Set,     Element) :-
		in1(Set, Element).

This works just fine in Quintus Prolog (e.g. "X in {1}+2..4+{5}"
enumerated the results 1,..,5).  What are the problems you keep running into?

ok@quintus.UUCP (Richard A. O'Keefe) (05/07/88)

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, "- <number> 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, + <number> 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.

hamid@hilbert.uucp (Hamid Bacha) (05/08/88)

In article <944@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes:
>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, "- <number> 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 C-Prolog (version 1.5) unary '-' is defined as op(fx, 500, -) and does
not bind tighter than operators with higher precedence (lower precedence 
number). It is treated as a special case in that -1 is negative integer 1 
instead of -(1). A simple example using C-Prolog proves it:

C-Prolog version 1.5
| ?- op(400, xfx, ..).
 
yes
| ?- assert(p(-1 .. 2)).
 
yes
| ?- p(-X).
 
X = 1..2 
 

This is clearly different from '..'(-1,2) which Richard claims it should be.
The same behavior is observed with ALS-Prolog (the other system I have 
access to in addition to our own Columbus Prolog and MetaProlog). So my
comment about the precedence of '..' still stands.

>In an Edinburgh-compatible Prolog, + <number> 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.
 
I agree entirely with you on this point. The thought that entered my mind
when I wrote my comment was that since -1 is treated as negative interger 1, 
wouldn't it make sense to treat its dual +1 as integer 1.

ok@quintus.UUCP (Richard A. O'Keefe) (05/09/88)

In article <467@cmx.npac.syr.edu>, hamid@hilbert.uucp (Hamid Bacha) writes:
> In article <944@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes:
> >In article <451@cmx.npac.syr.edu>, hamid@hilbert.uucp (Hamid Bacha) writes:
> >In an Edinburgh-compatible Prolog, "- <number> 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

> In C-Prolog (version 1.5) unary '-' is defined as op(fx, 500, -) and does
> not bind tighter than operators with higher precedence (lower precedence 
> number). It is treated as a special case in that -1 is negative integer 1 
> instead of -(1). A simple example using C-Prolog proves it:

(1) Surely that's op(500, fx, -).

> C-Prolog version 1.5
> | ?- op(400, xfx, ..).
> | ?- assert(p(-1 .. 2)).
> | ?- p(-X).
> X = 1..2 
> This is clearly different from '..'(-1,2) which Richard claims it should be.
> The same behavior is observed with ALS-Prolog (the other system I have 
> access to in addition to our own Columbus Prolog and MetaProlog).

(2) If this really is the case, it is a bug.  (C Prolog is known to take
    a few short-cuts with operators.)

    The test case which is supposed to make it all clear is
	x^ -2
    If current_op(200, xfy, ^) and current_op(500, fx, -) (as is normally
    the case), this would be illegal, and you should find that
    	x^ -y
    IS illegal.  - <number> being a special case, however, x^ -2 means
    the same as x^ (-2).

(3) Believe it or not, there is method in't.  The idea is to simplify the
    *output* routines.  We would like writeq(X) to be able to say "oh, X
    is a number, I'll just write it", whatever the surrounding context,
    rather than sometimes having to write a negative number as (-4) or
    whatever.

    It could be argued that having -<number> treated specially is a bad
    idea, and that it would be better to have it parsed as an ordinary
    operator and then treated specially when operator and operand are
    combined.  However, in DEC-10 Prolog, all operators can have their
    priority reassigned, and all operators can be cancelled by assigning
    priority 0, so there has to be something special about -<number> or
    it would be possible to get into a state where negative numbers could
    not be entered.

(4) I have just received a copy of ALS Prolog version 1.0 for the
    Macintosh SI and MAc II.  I tried
	write(-(5))
    and writeq(-(5))
    in it.  Both printed "-5", which is quite wrong.  writeq/1 is supposed
    to write something so that it can be read back, so writeq(-(5)) ought
    to write -(5) or (-(5)) or '-'(5) or -((5)) or - (5) or almost anything
    BUT -5.  I think it's fair to call this a bug.

    ALS Prolog fails to report the syntax error in (x^ -y) although this
    is clearly illegal according to the table on p42 and the last two
    paragraphs of section 5.7.  While it does indeed parse -1..2
    (incorrectly) as -(1..2), it parses 1.. -2 as ..(1,-2) which ought to
    be illegal if - doesn't have lower rank than .. .  This inconsistency
    does not seem desirable.

    There is much to admire in ALS Prolog, and I don't want to give anyone
    a bad impression of it.  I just want to point out that its I/O is (in
    this *specific* release) at least as buggy as that of C Prolog, and it
    should not be cited to prove what "Edinburgh syntax" is.
    [That is what the public-domain parser is for.]