BEGIN OPEN PascalBasic;
T Y P E S
PascalSmallSetRange: TYPE = PascalInteger [0..16);
PascalSmallSet: TYPE = PACKED ARRAY PascalSmallSetRange OF BOOLEAN ← ALL[FALSE];
PascalMediumSetRange: TYPE = PascalInteger [0..64);
PascalMediumSet:
TYPE =
PACKED
ARRAY PascalMediumSetRange
OF
BOOLEAN ←
ALL[
FALSE];
PascalLargeSetRange: TYPE = PascalInteger [0..256);
PascalLargeSet: TYPE = PACKED ARRAY PascalLargeSetRange OF BOOLEAN ← ALL[FALSE];
C O N S T A N T S A N D P R O C S
PascalSmallSetEmpty: PascalSmallSet = ALL[FALSE];
PascalSmallSetGenerateElement:
PROCEDURE [i: PascalInteger]
RETURNS [PascalSmallSet] = INLINE {s: PascalSmallSet; s[i] ← TRUE; RETURN[s]};
PascalSmallSetGenerateInterval:
PROCEDURE [i, j: PascalInteger]
RETURNS [PascalSmallSet] = INLINE
BEGIN
s: PascalSmallSet;
k: PascalInteger;
FOR k IN [i..j] DO s[k] ← TRUE ENDLOOP;
RETURN[s]
END;
PascalSmallSetAddElement:
PROCEDURE [s: PascalSmallSet, i: PascalInteger]
RETURNS [PascalSmallSet] = INLINE {s[i] ← TRUE; RETURN[s]};
PascalSmallSetAddInterval:
PROCEDURE [s: PascalSmallSet, i, j: PascalInteger]
RETURNS [PascalSmallSet] = INLINE
BEGIN k: PascalInteger; FOR k IN [i..j] DO s[k] ← TRUE ENDLOOP; RETURN[s] END;
PascalSmallSetUnion:
PROCEDURE [x, y: PascalSmallSet]
RETURNS [PascalSmallSet] =
TRUSTED INLINE {RETURN[LOOPHOLE[PrincOpsUtils.BITOR[LOOPHOLE[x],LOOPHOLE[y]]]]};
PascalSmallSetIntersection:
PROCEDURE [x, y: PascalSmallSet]
RETURNS [PascalSmallSet] =
TRUSTED INLINE {RETURN[LOOPHOLE[PrincOpsUtils.BITAND[LOOPHOLE[x],LOOPHOLE[y]]]]};
PascalSmallSetDifference:
PROCEDURE [x, y: PascalSmallSet]
RETURNS [PascalSmallSet] = TRUSTED INLINE {
RETURN[LOOPHOLE[PrincOpsUtils.BITAND[LOOPHOLE[x], PrincOpsUtils.BITNOT[LOOPHOLE[y]]]]]};
PascalSmallSetIsSubset:
PROCEDURE [x, y: PascalSmallSet]
RETURNS [PascalBoolean] = INLINE {RETURN[y = PascalSmallSetUnion[y, x]]};
PascalSmallSetIsSuperset:
PROCEDURE [x, y: PascalSmallSet]
RETURNS [PascalBoolean] = INLINE {RETURN[x = PascalSmallSetUnion[y, x]]};
PascalSmallSetIsSame:
PROCEDURE [x, y: PascalSmallSet]
RETURNS [PascalBoolean] =
INLINE {RETURN[LOOPHOLE[y, CARDINAL] = LOOPHOLE[x, CARDINAL]]};
PascalSmallSetIsDifferent:
PROCEDURE [x, y: PascalSmallSet]
RETURNS [PascalBoolean] = INLINE {
RETURN[LOOPHOLE[y, CARDINAL] # LOOPHOLE[x, CARDINAL]]};
PascalSmallSetCARD:
PROCEDURE [x: PascalSmallSet]
RETURNS [PascalInteger] =
TRUSTED INLINE
BEGIN OPEN PrincOpsUtils;
fast bit-counter that adds a pair of eight one-bit registers to
yield eight two-bit sums, then breaks those into a pair of four two-bit registers which
are combined to yield four four-bit sums, and so on.
c: CARDINAL ← BITAND[LOOPHOLE[x], 52525B]
+ BITAND[BITSHIFT[LOOPHOLE[x], -1], 52525B];
c ← BITAND[c, 31463B] + BITAND[BITSHIFT[c, -2], 31463B];
c ← BITAND[c, 7417B] + BITAND[BITSHIFT[c, -4], 7417B];
RETURN[BITAND[c, 377B] + BITAND[BITSHIFT[c, -8], 377B]];
END;
PascalSmallSetContains:
PROCEDURE [s: PascalSmallSet, e: PascalInteger]
RETURNS [PascalBoolean] = INLINE {RETURN[s[e]]};
PascalMediumSetEmpty: PascalMediumSet = ALL[FALSE];
PascalMediumSetGenerateElement:
PROCEDURE [i: PascalInteger]
RETURNS [PascalMediumSet];
PascalMediumSetGenerateInterval:
PROCEDURE [i, j: PascalInteger]
RETURNS [PascalMediumSet];
PascalMediumSetAddElement:
PROCEDURE [i: PascalInteger, s: PascalMediumSet]
RETURNS [PascalMediumSet];
PascalMediumSetAddInterval:
PROCEDURE [i, j: PascalInteger, s: PascalMediumSet]
RETURNS [PascalMediumSet];
PascalMediumSetUnion, PascalMediumSetIntersection, PascalMediumSetDifference:
PROCEDURE [x, y: PascalMediumSet] RETURNS [PascalMediumSet];
PascalMediumSetIsSubset,
PascalMediumSetIsSame:
PROCEDURE [
x, y: PascalMediumSet] RETURNS [PascalBoolean];
PascalMediumSetIsSuperset:
PROCEDURE [x, y: PascalMediumSet]
RETURNS [PascalBoolean] = INLINE {RETURN[PascalMediumSetIsSubset[y, x]]};
PascalMediumSetIsDifferent:
PROCEDURE [x, y: PascalMediumSet]
RETURNS [PascalBoolean] = INLINE {RETURN[NOT PascalMediumSetIsSame[x, y]]};
PascalMediumSetCARD: PROCEDURE [x: PascalMediumSet] RETURNS [PascalInteger];
PascalMediumSetContains:
PROCEDURE [s: PascalMediumSet, e: PascalInteger]
RETURNS [PascalBoolean] = INLINE {RETURN[s[e]]};
PascalLargeSetEmpty: PascalLargeSet = ALL[FALSE];
PascalLargeSetGenerateElement:
PROCEDURE [i: PascalInteger]
RETURNS [PascalLargeSet];
PascalLargeSetGenerateInterval:
PROCEDURE [i, j: PascalInteger]
RETURNS [PascalLargeSet];
PascalLargeSetAddElement:
PROCEDURE [i: PascalInteger, s: PascalLargeSet]
RETURNS [PascalLargeSet];
PascalLargeSetAddInterval:
PROCEDURE [i, j: PascalInteger, s: PascalLargeSet]
RETURNS [PascalLargeSet];
PascalLargeSetUnion, PascalLargeSetIntersection, PascalLargeSetDifference:
PROCEDURE [x, y: PascalLargeSet] RETURNS [PascalLargeSet];
PascalLargeSetIsSubset,
PascalLargeSetIsSame:
PROCEDURE [x, y: PascalLargeSet]
RETURNS [PascalBoolean];
PascalLargeSetIsSuperset:
PROCEDURE [x, y: PascalLargeSet]
RETURNS [PascalBoolean] = INLINE {RETURN[PascalLargeSetIsSubset[y, x]]};
PascalLargeSetIsDifferent:
PROCEDURE [x, y: PascalLargeSet]
RETURNS [PascalBoolean] = INLINE {RETURN[NOT PascalLargeSetIsSame[x, y]]};
PascalLargeSetCARD: PROCEDURE [x: PascalLargeSet] RETURNS [PascalInteger];
PascalLargeSetContains:
PROCEDURE [s: PascalLargeSet, e: PascalInteger]
RETURNS [PascalBoolean] = INLINE {RETURN[s[e]]};
END. -- PascalSets