Last modified on Wed May 12 12:07:01 PDT 1993 by swart modified on Mon Nov 18 22:04:34 PST 1991 by gnelson modified on Thu Nov 2 18:28:29 1989 by muller modified on Mon Oct 2 09:19:13 1989 by kalsow modified on Fri Jun 3 16:21:07 PDT 1988 by luca
An Interval.T
is a contiguous set of integers. An interval a
contains an integer n
if
a.lo <= n AND n < a.hiWe impose the restriction that if an interval contains no integers, then it must be equal as a record to
Interval.Empty
.
INTERFACE--- Initialization ---Interval ; IMPORT Word; TYPE T = RECORD lo, hi: INTEGER END; TYPE Bound = {Lo, Hi}; CONST Empty = T { 0, 0 }; (* A point-like interval *) CONST Full = T {FIRST(INTEGER), LAST(INTEGER)}; (* The biggest interval *)
PROCEDURE FromBounds(lo, hi: INTEGER): T;
Iflo >= hi
then returnEmpty
, else returnT{lo, hi}
.
PROCEDURE FromAbsBounds(n, m: INTEGER): T;
Return FromBounds(MIN(n,m), MAX(n,m))
.
PROCEDURE FromBound(lo: INTEGER; s: CARDINAL): T;
Return FromBounds(lo, lo+s)
.
PROCEDURE FromSize(s: CARDINAL): T;
Return FromBounds(0, s)
.
PROCEDURE Center(READONLY a: T; n: INTEGER): T;
Ifa
is empty then returnEmpty
, else returnb
such thatSize(b) = Size(a)
andMiddle(b) = n
.
--- Selection ---
PROCEDURE Size(READONLY a: T): CARDINAL;
Return a.hi - a.lo
.
PROCEDURE Middle(READONLY a: T): INTEGER;
Return (a.hi + a.lo) DIV 2
.
PROCEDURE PickBound (READONLY a: T; n: INTEGER): Bound;
Return the bound of a closest to n (one of them if equidistant)
PROCEDURE Project(READONLY a: T; n: INTEGER): INTEGER;
Return the element ofa
that is closest ton
. This is a checked runtime error ifa
is empty.
--- Transformation ---
PROCEDURE Move(READONLY a: T; n: INTEGER): T;
Return FromBounds(a.lo+n, a.hi+n)
.
PROCEDURE Inset(READONLY a: T; n: INTEGER): T;
Ifa
is empty then returnEmpty
, else returnFromBounds(a.lo + n, a.hi - n)
.
PROCEDURE Change(READONLY a: T; dlo, dhi: INTEGER): T;
Ifa
is empty then returnEmpty
, else returnFromBounds(a.lo + dlo, a.hi + dhi)
.
PROCEDURE MoveBound (x: Bound; READONLY a: T; dn: INTEGER): T;
If r is empty return empty, else add dn to the edge x of a
PROCEDURE Join(READONLY a, b: T): T;
Return the smallest interval containing botha
andb
.
PROCEDURE Meet(READONLY a, b: T): T;
Return the largest interval contained in both ofa
andb
.
PROCEDURE Chop (READONLY a: T; n: INTEGER; VAR (* out *) b, c: T);
Chop an interval in two; b is to the left of c
TYPE Partition = ARRAY [0..2] OF T; PROCEDURE Factor (READONLY a, by: T; VAR (*out*) f: Partition; dn: INTEGER) ;
a is partitioned into 3 pieces f[0]..f[2], where f[1] = Meet (a,by). The order of f is such that if i<j then f[i] translated by dn doesn't intersect f[j]. (Only the sign of dn affects the order, not its magnitude.)
PROCEDURE Mod(n: INTEGER; READONLY a: T): INTEGER;
Return the member ofa
whose distance fromn
is a multiple ofSize(a)
. This is a checked runtime error ifa
is empty.
--- Test ---
PROCEDURE Equal (READONLY a, b: T): BOOLEAN;
Interval equality; as all empty intervals must be represented as Empty, this is equivalent to a = b.
PROCEDURE IsEmpty(READONLY a: T): BOOLEAN;
Return whether a
is empty.
PROCEDURE Member(n: INTEGER; READONLY a: T): BOOLEAN;
Return whethern
is ina
.
PROCEDURE Overlap(READONLY a, b: T): BOOLEAN;
Return whethera
andb
have any element in common.
PROCEDURE Subset(READONLY a, b: T): BOOLEAN;
Return whethera
is contained inb
.
--- Standard type operations ---
PROCEDURE Compare (READONLY a, b: T): [-1 .. 1];
== RETURN 0 if Equal(a, b), -1 if (a.lo < b.lo) OR ((a.lo = b.lo) AND (a.hi < b.hi)), +1 o. w.)
PROCEDURE Hash (READONLY a: T): Word.T;
== RETURN a suitable hash value
END Interval.