OneToOneImpl.Mesa
Spreitzer, April 9, 1986 3:59:50 pm PST
DIRECTORY HashTable, OneToOne;
OneToOneImpl: CEDAR PROGRAM
IMPORTS HashTable, OneToOne
EXPORTS OneToOne
= {OPEN OneToOne;
Contradiction: PUBLIC ERROR [oto: OneToOne, a, b: REF ANY] = CODE;
CreateVanillaOneToOne: PUBLIC PROC RETURNS [oto: OneToOne] = {
oto ← NEW [OneToOnePrivate ← [HashedEnumerate, HashedAssociate, HashedMap, NEW [HashOneToOnePrivate ← [HashTable.Create[], HashTable.Create[]]]]];
};
HashOneToOne: TYPE = REF HashOneToOnePrivate;
HashOneToOnePrivate: TYPE = RECORD [
forward, backward: HashTable.Table
];
HashedEnumerate: PROC [oto: OneToOne, Consume: PROC [a, b: REF ANY]] = {
hoto: HashOneToOne = NARROW[oto.data];
PerPair: PROC [key, value: REF ANY] RETURNS [quit: BOOLFALSE] --HashTable.EachPairAction-- = {
Consume[key, value];
};
[] ← hoto.forward.Pairs[PerPair];
};
HashedAssociate: PROC [oto: OneToOne, a, b: REF ANY] = {
hoto: HashOneToOne = NARROW[oto.data];
IF a=NIL OR b=NIL OR NOT (hoto.forward.Insert[a, b] AND hoto.backward.Insert[b, a]) THEN ERROR Contradiction[oto, a, b];
};
HashedMap: PROC [oto: OneToOne, from: REF ANY, forward: BOOLTRUE] RETURNS [to: REF ANY] = {
hoto: HashOneToOne = NARROW[oto.data];
to ← (IF forward THEN hoto.forward ELSE hoto.backward).Fetch[from].value;
};
Reverse: PUBLIC PROC [fwd: OneToOne] RETURNS [rev: OneToOne] = {
rev ← NEW [OneToOnePrivate ← [ReversedEnumerate, ReversedAssociate, ReversedMap, fwd]];
};
ReversedEnumerate: PROC [oto: OneToOne, Consume: PROC [a, b: REF ANY]] = {
fwd: OneToOne = NARROW[oto.data];
Reverse: PROC [a, b: REF ANY] = {Consume[b, a]};
fwd.Enumerate[Reverse];
};
ReversedAssociate: PROC [oto: OneToOne, a, b: REF ANY] = {
fwd: OneToOne = NARROW[oto.data];
fwd.Associate[b, a]};
ReversedMap: PROC [oto: OneToOne, from: REF ANY, forward: BOOLTRUE] RETURNS [to: REF ANY] = {
fwd: OneToOne = NARROW[oto.data];
to ← fwd.Map[from, NOT forward];
};
Translate: PUBLIC PROC [inner, translator: OneToOne, translateForward: BOOLTRUE] RETURNS [outer: OneToOne] = {
t: Translator = NEW [TranslatorPrivate ← [inner, translator, translateForward]];
outer ← NEW [OneToOnePrivate ← [TranslatedEnumerate, TranslatedAssociate, TranlatedMap, t]];
};
Translator: TYPE = REF TranslatorPrivate;
TranslatorPrivate: TYPE = RECORD [
inner, translate: OneToOne,
translateForward: BOOL
];
TranslatedEnumerate: PROC [oto: OneToOne, Consume: PROC [a, b: REF ANY]] = {
t: Translator = NARROW[oto.data];
Translate: PROC [a, b: REF ANY] = {
Consume[t.translate.Map[a, t.translateForward], t.translate.Map[b, t.translateForward]];
};
t.inner.Enumerate[Translate];
};
TranslatedAssociate: PROC [oto: OneToOne, a, b: REF ANY] = {
t: Translator = NARROW[oto.data];
t.inner.Associate[t.translate.Map[a, NOT t.translateForward], t.translate.Map[b, NOT t.translateForward]];
};
TranlatedMap: PROC [oto: OneToOne, from: REF ANY, forward: BOOLTRUE] RETURNS [to: REF ANY] = {
t: Translator = NARROW[oto.data];
to ← t.translate.Map[t.inner.Map[t.translate.Map[from, NOT t.translateForward], forward], t.translateForward];
};
}.