-- file: PascalSetsImpl.mesa
-- last modified by Ramshaw, December 25, 1982 9:14 am
-- written by McCreight, December 19, 1980 10:44 AM


-- Cedar Pascal-to-Mesa Runtime support for sets

DIRECTORY
PascalBasic,
PascalSets;

PascalSetsImpl: CEDAR PROGRAM
EXPORTS PascalSets =

BEGIN OPEN PascalBasic, PascalSets;


PascalMediumSetGenerateElement: PUBLIC PROCEDURE [i: PascalInteger]
RETURNS [PascalMediumSet] = {s: PascalMediumSet; s[i] ← TRUE; RETURN[s]};

PascalMediumSetGenerateInterval: PUBLIC PROCEDURE [i, j: PascalInteger]
RETURNS [PascalMediumSet] =
BEGIN
s: PascalMediumSet;
k: PascalInteger;
FOR k IN [i..j] DO s[k] ← TRUE ENDLOOP;
RETURN[s]
END;

PascalMediumSetAddElement: PUBLIC PROCEDURE [
i: PascalInteger, s: PascalMediumSet] RETURNS [PascalMediumSet] = {
s[i] ← TRUE; RETURN[s]};

PascalMediumSetAddInterval: PUBLIC PROCEDURE [
i, j: PascalInteger, s: PascalMediumSet] RETURNS [PascalMediumSet] =
BEGIN k: PascalInteger; FOR k IN [i..j] DO s[k] ← TRUE ENDLOOP; RETURN[s] END;

PascalMediumSetUnion: PUBLIC PROCEDURE [x, y: PascalMediumSet]
RETURNS [PascalMediumSet] =
BEGIN
s: PascalMediumSet;
i: PascalMediumSetRange;
FOR i IN PascalMediumSetRange DO s[i] ← x[i] OR y[i] ENDLOOP;
RETURN[s];
END;

PascalMediumSetIntersection: PUBLIC PROCEDURE [x, y: PascalMediumSet]
RETURNS [PascalMediumSet] =
BEGIN
s: PascalMediumSet;
i: PascalMediumSetRange;
FOR i IN PascalMediumSetRange DO s[i] ← x[i] AND y[i] ENDLOOP;
RETURN[s];
END;

PascalMediumSetDifference: PUBLIC PROCEDURE [x, y: PascalMediumSet]
RETURNS [PascalMediumSet] =
BEGIN
s: PascalMediumSet;
i: PascalMediumSetRange;
FOR i IN PascalMediumSetRange DO s[i] ← x[i] AND NOT y[i] ENDLOOP;
RETURN[s];
END;

PascalMediumSetIsSubset: PUBLIC PROCEDURE [x, y: PascalMediumSet]
RETURNS [PascalBoolean] =
BEGIN
i: PascalMediumSetRange;
FOR i IN PascalMediumSetRange DO
IF x[i] AND NOT y[i] THEN RETURN[FALSE] ENDLOOP;
RETURN[TRUE];
END;

PascalMediumSetIsSame: PUBLIC PROCEDURE [x, y: PascalMediumSet]
RETURNS [PascalBoolean] =
BEGIN
i: PascalMediumSetRange;
FOR i IN PascalMediumSetRange DO IF x[i] # y[i] THEN RETURN[FALSE] ENDLOOP;
RETURN[TRUE];
END;

PascalMediumSetCARD: PUBLIC PROCEDURE [x: PascalMediumSet]
RETURNS [PascalInteger] =
BEGIN
i: PascalMediumSetRange;
count: CARDINAL ← 0;
FOR i IN PascalMediumSetRange DO IF x[i] THEN count ← count + 1 ENDLOOP;
RETURN[count];
END;

PascalLargeSetGenerateElement: PUBLIC PROCEDURE [i: PascalInteger]
RETURNS [PascalLargeSet] = {s: PascalLargeSet; s[i] ← TRUE; RETURN[s]};

PascalLargeSetGenerateInterval: PUBLIC PROCEDURE [i, j: PascalInteger]
RETURNS [PascalLargeSet] =
BEGIN
s: PascalLargeSet;
k: PascalInteger;
FOR k IN [i..j] DO s[k] ← TRUE ENDLOOP;
RETURN[s]
END;

PascalLargeSetAddElement: PUBLIC PROCEDURE [i: PascalInteger, s: PascalLargeSet]
RETURNS [PascalLargeSet] = {s[i] ← TRUE; RETURN[s]};

PascalLargeSetAddInterval: PUBLIC PROCEDURE [
i, j: PascalInteger, s: PascalLargeSet] RETURNS [PascalLargeSet] =
BEGIN k: PascalInteger; FOR k IN [i..j] DO s[k] ← TRUE ENDLOOP; RETURN[s] END;

PascalLargeSetUnion: PUBLIC PROCEDURE [x, y: PascalLargeSet]
RETURNS [PascalLargeSet] =
BEGIN
s: PascalLargeSet;
i: PascalLargeSetRange;
FOR i IN PascalLargeSetRange DO s[i] ← x[i] OR y[i] ENDLOOP;
RETURN[s];
END;

PascalLargeSetIntersection: PUBLIC PROCEDURE [x, y: PascalLargeSet]
RETURNS [PascalLargeSet] =
BEGIN
s: PascalLargeSet;
i: PascalLargeSetRange;
FOR i IN PascalLargeSetRange DO s[i] ← x[i] AND y[i] ENDLOOP;
RETURN[s];
END;

PascalLargeSetDifference: PUBLIC PROCEDURE [x, y: PascalLargeSet]
RETURNS [PascalLargeSet] =
BEGIN
s: PascalLargeSet;
i: PascalLargeSetRange;
FOR i IN PascalLargeSetRange DO s[i] ← x[i] AND NOT y[i] ENDLOOP;
RETURN[s];
END;

PascalLargeSetIsSubset: PUBLIC PROCEDURE [x, y: PascalLargeSet]
RETURNS [PascalBoolean] =
BEGIN
i: PascalLargeSetRange;
FOR i IN PascalLargeSetRange DO
IF x[i] AND NOT y[i] THEN RETURN[FALSE] ENDLOOP;
RETURN[TRUE];
END;

PascalLargeSetIsSame: PUBLIC PROCEDURE [x, y: PascalLargeSet]
RETURNS [PascalBoolean] =
BEGIN
i: PascalLargeSetRange;
FOR i IN PascalLargeSetRange DO IF x[i] # y[i] THEN RETURN[FALSE] ENDLOOP;
RETURN[TRUE];
END;

PascalLargeSetCARD: PUBLIC PROCEDURE [x: PascalLargeSet]
RETURNS [PascalInteger] =
BEGIN
i: PascalLargeSetRange;
count: CARDINAL ← 0;
FOR i IN PascalLargeSetRange DO IF x[i] THEN count ← count + 1 ENDLOOP;
RETURN[count];
END;

END. -- PascalSetsImpl