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 [hashA, hashB: HashTable.HashProc _ NIL, compareA, compareB: HashTable.EqualProc _ NIL] RETURNS [oto: OneToOne] = { oto _ NEW [OneToOnePrivate _ [HashedEnumerate, HashedAssociate, HashedMap, NEW [HashOneToOnePrivate _ [HashTable.Create[equal: compareA, hash: hashA], HashTable.Create[equal: compareB, hash: hashB]]]]]; }; 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; }; id: PUBLIC OneToOne = NEW [OneToOnePrivate _ [NIL, NIL, MapId]]; MapId: PROC [oto: OneToOne, from: REF ANY, forward: BOOL _ TRUE] RETURNS [REF ANY] = {RETURN [from]}; 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]; }; Triplate: PUBLIC PROC [inward, inner, outward: OneToOne] RETURNS [outer: OneToOne] = { t: Triplator = NEW [TriplatorPrivate _ [inward, inner, outward]]; outer _ NEW [OneToOnePrivate _ [TriplatedEnumerate, TriplatedAssociate, TriplatedMap, t]]; }; Triplator: TYPE = REF TriplatorPrivate; TriplatorPrivate: TYPE = RECORD [inward, inner, outward: OneToOne]; TriplatedEnumerate: PROC [oto: OneToOne, Consume: PROC [a, b: REF ANY]] = { t: Triplator = NARROW[oto.data]; Triplate: PROC [a, b: REF ANY] = { Consume[t.inward.Map[a, FALSE], t.outward.Map[b, TRUE]]; }; t.inner.Enumerate[Triplate]; }; TriplatedAssociate: PROC [oto: OneToOne, a, b: REF ANY] = { t: Triplator = NARROW[oto.data]; t.inner.Associate[t.inward.Map[a, TRUE], t.outward.Map[b, FALSE]]; }; TriplatedMap: PROC [oto: OneToOne, from: REF ANY, forward: BOOL _ TRUE] RETURNS [to: REF ANY] = { t: Triplator = NARROW[oto.data]; to _ IF forward THEN t.outward.Map[t.inner.Map[t.inward.Map[from, TRUE], TRUE], TRUE] ELSE t.inward.Map[t.inner.Map[t.outward.Map[from, FALSE], FALSE], FALSE]; }; }. nOneToOneImpl.Mesa Spreitzer, April 9, 1986 3:59:50 pm PST Mike Spreitzer August 13, 1986 6:51:07 pm PDT Κy– "cedar" style˜code™K™'K™-—K˜KšΟk œ˜K˜šΡbnx œœ˜Kšœ˜Kšœ ˜K˜Kšœœ ˜K˜Kš Οn œœœœœœ˜BK˜š Ÿœœœ%œ,œœ˜–KšœœBœ|˜ΚK˜—K˜Kšœœœ˜-šœœœ˜$K˜"K˜—K˜š ŸœœŸœœœœ˜HKšœœ ˜&šŸœœœœœœœΟcœ˜aK˜K˜—K˜!K˜—K˜šŸœœœœ˜8Kšœœ ˜&Kšœœœœœœœœœ˜xK˜—K˜šŸ œœœœ œœœœœ˜^Kšœœ ˜&Kšœœ œœ"˜IK˜—K˜Kš œœ œœœ ˜@K˜KšŸœœœœ œœœœœœ ˜eK˜šŸœœœœ˜@KšœœN˜WK˜—K˜š ŸœœŸœœœœ˜JKšœœ ˜!KšŸœœœœ˜0K˜K˜—K˜šŸœœœœ˜:Kšœœ ˜!K˜—K˜šŸ œœœœ œœœœœ˜`Kšœœ ˜!Kšœœ ˜ K˜—K˜šŸœœœ$œ˜VKšœœ/˜AKšœœO˜ZK˜—K˜Kšœ œœ˜'Kšœœœ$˜CK˜š ŸœœŸœœœœ˜KKšœœ ˜ šŸœœœœ˜"Kšœœœ˜8K˜—Kšœ˜K˜—K˜šŸœœœœ˜;Kšœœ ˜ Kšœ"œœ˜BK˜—K˜šŸ œœœœ œœœœœ˜aKšœœ ˜ šœœ˜Kšœ.œœœ˜EKšœ.œœœ˜I—K˜—K˜K˜——…—  ‡