-- Compiler Relations/n
-- Tiberi November 13, 1979  11:38 AM
-- Ordered pairs; building and searching

DIRECTORY
	GriffinMemoryDefs: FROM "GriffinMemoryDefs",
	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: UNSPECIFIED] =
BEGIN
pair: 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: UNSPECIFIED]
	RETURNS [left: UNSPECIFIED] =
BEGIN
IsRight: PROCEDURE [leftPart, rightPart: UNSPECIFIED] =
	BEGIN
	IF right=rightPart THEN left←leftPart;
	END;
left←notFound;
ForAllPairs[relation, IsRight];
END;

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

ForAllPairs: PUBLIC PROCEDURE[relation: Relation,
	do: PROCEDURE[leftPart, rightPart: UNSPECIFIED]] =
BEGIN
pair: 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: POINTER TO Pair ← NIL;
FOR pair ← relation.first, next UNTIL pair=NIL
	DO
	next ← pair.link;
	Free[pair];
	ENDLOOP;
Free[relation];
END;

END.