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: BOOL _ FALSE] --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: BOOL _ TRUE] 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: BOOL _ TRUE] RETURNS [to: REF ANY] = { fwd: OneToOne = NARROW[oto.data]; to _ fwd.Map[from, NOT forward]; }; Translate: PUBLIC PROC [inner, translator: OneToOne, translateForward: BOOL _ TRUE] 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: BOOL _ TRUE] 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]; }; }. @OneToOneImpl.Mesa Spreitzer, April 9, 1986 3:59:50 pm PST Κ – "cedar" style˜code™K™'—K˜KšΟk œ˜K˜šΡbnx œœ˜Kšœ˜Kšœ ˜K˜Kšœœ ˜K˜Kš Οn œœœœœœ˜BK˜šŸœœœœ˜>KšœœBœD˜’K˜—K˜Kšœœœ˜-šœœœ˜$K˜"K˜—K˜š ŸœœŸœœœœ˜HKšœœ ˜&šŸœœœœœœœΟcœ˜aK˜K˜—K˜!K˜—K˜šŸœœœœ˜8Kšœœ ˜&Kšœœœœœœœœœ˜xK˜—K˜šŸ œœœœ œœœœœ˜^Kšœœ ˜&Kšœœ œœ"˜IK˜—K˜šŸœœœœ˜@KšœœN˜WK˜—K˜š ŸœœŸœœœœ˜JKšœœ ˜!KšŸœœœœ˜0K˜K˜—K˜šŸœœœœ˜:Kšœœ ˜!K˜—K˜šŸ œœœœ œœœœœ˜`Kšœœ ˜!Kšœœ ˜ K˜—K˜š Ÿ œœœ1œœœ˜qKšœœ=˜PKšœœQ˜\K˜—K˜Kšœ œœ˜)šœœœ˜"Kšœ˜Kšœ˜K˜—K˜š ŸœœŸœœœœ˜LKšœœ ˜!šŸ œœœœ˜#KšœX˜XK˜—Kšœ˜K˜—K˜šŸœœœœ˜