-- Compiler Relations/n
-- Tiberi November 13, 1979 11:38 AM
-- Ordered pairs; building and searching
-- Last Edited by: Stone, January 28, 1983 12:02 am

DIRECTORY
 GriffinMemoryDefs USING [Allocate,Free],
 RelationDefs: FROM "RelationDefs";

Relations: PROGRAM
IMPORTS GriffinMemoryDefs
EXPORTS RelationDefs =
BEGIN OPEN RelationDefs, GriffinMemoryDefs;

CreateRelation: PUBLIC PROCEDURE RETURNS [relation: Relation] =
BEGIN
relation ← Allocate[SIZE[RelationHead]];
relation.first ← NIL;
END;

AddPair: PUBLIC PROCEDURE [relation: Relation,
  left, right: CARDINAL] =
BEGIN
pair: LONG POINTER TO Pair ← Allocate[SIZE[Pair]];
pair.left ← left; pair.right ← right;
pair.link ← relation.first;
relation.first ← pair;
END;

Left: PUBLIC PROCEDURE[relation: Relation, right: CARDINAL]
RETURNS [left: CARDINAL] =
BEGIN
IsRight: PROCEDURE [leftPart, rightPart: CARDINAL] =
BEGIN
IF right=rightPart THEN left←leftPart;
END;
left←notFound;
ForAllPairs[relation, IsRight];
END;

Right: PUBLIC PROCEDURE[relation: Relation, left: CARDINAL]
RETURNS [right: CARDINAL] =
BEGIN
IsLeft: PROCEDURE [leftPart, rightPart: CARDINAL] =
BEGIN
IF left=leftPart THEN right←rightPart;
END;
right←notFound;
ForAllPairs[relation, IsLeft];
END;

ForAllPairs: PUBLIC PROCEDURE[relation: Relation,
 do: PROCEDURE[leftPart, rightPart: CARDINAL]] =
BEGIN
pair: LONG POINTER TO Pair ← NIL;
FOR pair ← relation.first, pair.link UNTIL pair=NIL
DO do[pair.left, pair.right] ENDLOOP;
END;

DestroyRelation: PUBLIC PROCEDURE[relation: Relation] =
BEGIN
pair, next: LONG POINTER TO Pair ← NIL;
FOR pair ← relation.first, next UNTIL pair=NIL
DO
 next ← pair.link;
 Free[pair];
ENDLOOP;
Free[relation];
END;

END.