DIRECTORY Asserting, Basics, Convert, GList, IntChainedHashTable, InterpreterOps, IntHashTable, IO, LichenArrayStuff, LichenCollections, LichenDataOps, LichenDataStructure, LichenPairCollections, RefTab, Rope; LichenArray3Impl: CEDAR PROGRAM IMPORTS GList, IntChainedHashTable, IntHashTable, LichenArrayStuff, LichenCollections, LichenDataOps, LichenDataStructure, RefTab EXPORTS LichenArrayStuff = BEGIN OPEN ICHT: IntChainedHashTable, LichenDataStructure, LichenArrayStuff, LichenDataOps, Sets:LichenCollections, Fns:LichenPairCollections; RetractFalseHypotheses: PUBLIC PROC [act: CellType] = { IF NOT IsIncompleteArray[act] THEN RETURN; {a: Array = act.asArray; SplitGroups[a]; RemakeTies[act, a]; act _ act; }}; RPDPairList: TYPE = LIST OF RPDPair; RPDPair: TYPE = REF RPDPairPrivate; RPDPairPrivate: TYPE = ARRAY End OF SidedPortData; undef: NAT = LAST[NAT]; RefinableSubset: TYPE = REF RefinableSubsetPrivate; RefinableSubsetPrivate: TYPE = RECORD [ elts: Set--of RPDPair--, oldKey, nextRoot: NAT _ undef ]; SplitGroups: PROC [a: Array] = { dt: Dim = IF a.size[Foo] > 1 THEN Foo ELSE IF a.size[Bar] > 1 THEN Bar ELSE ERROR; d1: Dim = IF RangeLength[a.groupingParmses[Foo].middle] < RangeLength[a.groupingParmses[Bar].middle] THEN Foo ELSE Bar; d2: Dim = OtherDim[d1]; FOR ff: NAT IN [0 .. a.jointsPeriod[Foo]) DO FOR fb: NAT IN [0 .. a.jointsPeriod[Bar]) DO phase: Nat2 = [ff, fb]; wir: Range2 = Range2Div[SizeRange[a.size], a.jointsPeriod, phase]; mcir: Range2 = Range2Div[GPMiddle[a.groupingParmses],a.jointsPeriod,phase]; hasMiddle: ARRAY Dim OF BOOL = [HasMiddle[a.groupingParmses[Foo]], HasMiddle[a.groupingParmses[Bar]]]; SelStart: PROC [d: Dim] RETURNS [mgi: NAT] = { mgi _ SELECT TRUE FROM hasMiddle[d] => a.groupingParmses[d].middle.min + phase[d], a.groupingParmses[d].middle.maxPlusOne <= 0 => 0, a.groupingParmses[d].middle.maxPlusOne < a.size[d] => ERROR, ENDCASE => a.groupingParmses[d].middle.min-1; }; mgi2: Nat2 = [SelStart[Foo], SelStart[Bar]]; mgi: NAT = a.groupingParmses[Bar].sum * mgi2[Foo] + mgi2[Bar]; gsm: Groupings = NARROW[a.groupingses[mgi]]; rfblSetsm: Set--of RefinableSubset-- = Sets.CreateHashSet[]; rfblSetse, rfblSetsc: Set--of RefinableSubset--; toNew: IntHashTable.Table = IntHashTable.Create[]; need: ARRAY [1 .. 4] OF BOOL = [ wir[d1].min < mcir[d1].min, mcir[d1].maxPlusOne < wir[d1].maxPlusOne, wir[d2].min < mcir[d2].min AND hasMiddle[d1], mcir[d2].maxPlusOne < wir[d2].maxPlusOne AND hasMiddle[d1]]; Prep: PROC [i: [1 .. 4]] RETURNS [Set--of RefinableSubset--] = { IF need[i] THEN { FOR j: [1 .. 4] IN (i .. 4] DO IF need[j] THEN RETURN[CopyRefinableSubsets[rfblSetsm]]; ENDLOOP; RETURN[rfblSetsm]}; RETURN [Sets.nilSet]}; GetEltRoot: PROC [a: Array, d: Dim, elt: REF ANY, side: End, clai: NAT] RETURNS [root: NAT] = { rpdPair: RPDPair = NARROW[elt]; root _ GetRoot[a, d, rpdPair[side], clai]; }; MakeGroupSets[a, dt, gsm, rfblSetsm]; IF hasMiddle[Foo] AND hasMiddle[Bar] THEN { RefineOverRange[a, dt, phase, rfblSetsm, toNew, mcir, GetEltRoot]; SetGroups[mgi2, gsm, rfblSetsm]; }; rfblSetse _ Prep[1]; FOR ci1: INT DECREASING IN [wir[d1].min .. mcir[d1].min) DO egi2: Nat2 = ConsNat2[d1, ci1*a.jointsPeriod[d1]+phase[d1], mgi2[d2]]; egi: NAT = a.groupingParmses[Bar].sum * egi2[Foo] + egi2[Bar]; gse: Groupings = NARROW[a.groupingses[egi]]; IF hasMiddle[d2] THEN { RefineOverRange[a, dt, phase, rfblSetse, toNew, ConsRange2[d1, [ci1, ci1+1], mcir[d2]], GetEltRoot]; SetGroups[egi2, gse, rfblSetse]; }; rfblSetsc _ CopyRefinableSubsets[rfblSetse]; FOR ci2: INT DECREASING IN [wir[d2].min .. mcir[d2].min) DO cgi2: Nat2 = ConsNat2[d2, ci2*a.jointsPeriod[d2]+phase[d2], egi2[d1]]; cgi: NAT = a.groupingParmses[Bar].sum * cgi2[Foo] + cgi2[Bar]; gsc: Groupings = NARROW[a.groupingses[cgi]]; RefineOverRange[a, dt, phase, rfblSetsc, toNew, ConsRange2[d2, [ci2, ci2+1], [ci1, mcir[d1].maxPlusOne]], GetEltRoot]; SetGroups[cgi2, gsc, rfblSetsc]; ENDLOOP; rfblSetsc _ CopyRefinableSubsets[rfblSetse]; FOR ci2: INT IN [mcir[d2].maxPlusOne .. wir[d2].maxPlusOne) DO cgi2: Nat2 = ConsNat2[d2, ci2*a.jointsPeriod[d2]+phase[d2] + a.groupingParmses[d2].d, egi2[d1]]; cgi: NAT = a.groupingParmses[Bar].sum * cgi2[Foo] + cgi2[Bar]; gsc: Groupings = NARROW[a.groupingses[cgi]]; RefineOverRange[a, dt, phase, rfblSetsc, toNew, ConsRange2[d2, [ci2, ci2+1], [ci1, mcir[d1].maxPlusOne]], GetEltRoot]; SetGroups[cgi2, gsc, rfblSetsc]; ENDLOOP; ENDLOOP; rfblSetse _ Prep[2]; FOR ci1: INT IN [mcir[d1].maxPlusOne .. wir[d1].maxPlusOne) DO egi2: Nat2 = ConsNat2[d1, ci1*a.jointsPeriod[d1]+phase[d1] + a.groupingParmses[d1].d, mgi2[d2]]; egi: NAT = a.groupingParmses[Bar].sum * egi2[Foo] + egi2[Bar]; gse: Groupings = NARROW[a.groupingses[egi]]; IF hasMiddle[d2] THEN { RefineOverRange[a, dt, phase, rfblSetse, toNew, ConsRange2[d1, [ci1, ci1+1], mcir[d2]], GetEltRoot]; SetGroups[egi2, gse, rfblSetse]; }; rfblSetsc _ CopyRefinableSubsets[rfblSetse]; FOR ci2: INT DECREASING IN [wir[d2].min .. mcir[d2].min) DO cgi2: Nat2 = ConsNat2[d2, ci2*a.jointsPeriod[d2]+phase[d2], egi2[d1]]; cgi: NAT = a.groupingParmses[Bar].sum * cgi2[Foo] + cgi2[Bar]; gsc: Groupings = NARROW[a.groupingses[cgi]]; RefineOverRange[a, dt, phase, rfblSetsc, toNew, ConsRange2[d2, [ci2, ci2+1], [mcir[d1].min, ci1+1]], GetEltRoot]; SetGroups[cgi2, gsc, rfblSetsc]; ENDLOOP; rfblSetsc _ CopyRefinableSubsets[rfblSetse]; FOR ci2: INT IN [mcir[d2].maxPlusOne .. wir[d2].maxPlusOne) DO cgi2: Nat2 = ConsNat2[d2, ci2*a.jointsPeriod[d2]+phase[d2] + a.groupingParmses[d2].d, egi2[d1]]; cgi: NAT = a.groupingParmses[Bar].sum * cgi2[Foo] + cgi2[Bar]; gsc: Groupings = NARROW[a.groupingses[cgi]]; RefineOverRange[a, dt, phase, rfblSetsc, toNew, ConsRange2[d2, [ci2, ci2+1], [mcir[d1].min, ci1+1]], GetEltRoot]; SetGroups[cgi2, gsc, rfblSetsc]; ENDLOOP; ENDLOOP; IF hasMiddle[d1] THEN { rfblSetse _ Prep[3]; FOR ci2: INT DECREASING IN [wir[d2].min .. mcir[d2].min) DO egi2: Nat2 = ConsNat2[d2, ci2*a.jointsPeriod[d2]+phase[d2], mgi2[d1]]; egi: NAT = a.groupingParmses[Bar].sum * egi2[Foo] + egi2[Bar]; gse: Groupings = NARROW[a.groupingses[egi]]; RefineOverRange[a, dt, phase, rfblSetse, toNew, ConsRange2[d2, [ci2, ci2+1], mcir[d1]], GetEltRoot]; SetGroups[egi2, gse, rfblSetse]; ENDLOOP; }; IF hasMiddle[d1] THEN { rfblSetse _ Prep[4]; FOR ci2: INT IN [mcir[d2].maxPlusOne .. wir[d2].maxPlusOne) DO egi2: Nat2 = ConsNat2[d2, ci2*a.jointsPeriod[d2]+phase[d2] + a.groupingParmses[d2].d, mgi2[d1]]; egi: NAT = a.groupingParmses[Bar].sum * egi2[Foo] + egi2[Bar]; gse: Groupings = NARROW[a.groupingses[egi]]; RefineOverRange[a, dt, phase, rfblSetse, toNew, ConsRange2[d2, [ci2, ci2+1], mcir[d1]], GetEltRoot]; SetGroups[egi2, gse, rfblSetse]; ENDLOOP; }; a _ a; ENDLOOP ENDLOOP; a _ a; }; MakeGroupSets: PROC [a: Array, dt: Dim, gs: Groupings, rfblSets: Set--of RefinableSubset--] = { StartSet: PROC [ra: REF ANY] = { g: Group = NARROW[ra]; rfblSet: RefinableSubset = NEW [RefinableSubsetPrivate _ [elts: Sets.CreateHashSet[] ]]; FOR ports: PortList _ g.ports, ports.rest WHILE ports # NIL DO rpdPair: RPDPair = NEW [RPDPairPrivate _ [ low: NARROW[a.toRole[dt][low].Fetch[ports.first].val], high: NARROW[a.toRole[dt][high].Fetch[ports.first].val] ]]; IF NOT rfblSet.elts.AddElt[rpdPair] THEN ERROR; ENDLOOP; IF NOT rfblSets.AddElt[rfblSet] THEN ERROR; }; gs.groups.Enumerate[StartSet]; }; SetGroups: PROC [gi2: Nat2, gs: Groupings, rfblSets: Set--of RefinableSubset--] = { Transfer: PROC [ra: REF ANY] = { rfblSet: RefinableSubset = NARROW[ra]; g: Group = NEW [GroupPrivate _ [gi2: gi2]]; TransferPort: PROC [ra: REF ANY] = { rpdPair: RPDPair = NARROW[ra]; IF rpdPair[low] = NIL OR rpdPair[high] = NIL THEN ERROR; {port: Port = rpdPair[low].port; g.ports _ CONS[port, g.ports]; IF NOT gs.toGroup.Store[port, g] THEN ERROR; }}; rfblSet.elts.Enumerate[TransferPort]; IF NOT gs.groups.AddElt[g] THEN ERROR; }; gs.toGroup.Erase[]; gs.groups _ Sets.CreateHashSet[]; rfblSets.Enumerate[Transfer]; }; CopyRefinableSubsets: PROC [original: Set--of RefinableSubset--] RETURNS [copy: Set--of RefinableSubset--] = { CopyRefinableSubset: PROC [ra: REF ANY] = { urSet: RefinableSubset = NARROW[ra]; newSet: RefinableSubset = NEW [RefinableSubsetPrivate _ [elts: Sets.CreateHashSet[] ]]; MoveRPD: PROC [ra: REF ANY] = { IF NOT newSet.elts.AddElt[ra] THEN ERROR; }; urSet.elts.Enumerate[MoveRPD]; IF NOT copy.AddElt[newSet] THEN ERROR; }; copy _ Sets.CreateHashSet[]; original.Enumerate[CopyRefinableSubset]; copy _ copy; }; RefineOverRange: PROC [a: Array, dt: Dim, phase: Nat2, rfblSets: Set--of RefinableSubset--, toNew: IntHashTable.Table, cir: Range2, GetEltRoot: PROC [a: Array, d: Dim, elt: REF ANY, side: End, clai: NAT] RETURNS [root: NAT]] = { jSize: Nat2 = Nat2Tweak[a.size, dt, -1]; FOR cif: INT IN [cir[Foo].min .. cir[Foo].maxPlusOne) DO FOR cib: INT IN [cir[Bar].min .. cir[Bar].maxPlusOne) DO lai: Nat2 _ Nat2Add[Nat2Mul[[cif, cib], a.jointsPeriod], phase]; side: End _ low; clai: NAT _ jSize[Bar]*lai[Foo] + lai[Bar]; oldKey: NAT _ 0; ResetSet: PROC [ra: REF ANY] = { rfblSet: RefinableSubset = NARROW[ra]; rfblSet.oldKey _ oldKey; oldKey _ oldKey + 1; rfblSet.nextRoot _ undef}; RefineSet: PROC [ra: REF ANY] = { rfblSet: RefinableSubset = NARROW[ra]; RefineElt: PROC [ra: REF ANY] = { elt: REF ANY = ra; root: NAT = GetEltRoot[a, dt, elt, side, clai]; SELECT rfblSet.nextRoot FROM root => NULL; undef => rfblSet.nextRoot _ root; ENDCASE => { both: Basics.LongNumber = [pair[rfblSet.oldKey, root]]; newSet: RefinableSubset _ NARROW[toNew.Fetch[both.li].value]; IF newSet = NIL THEN { newSet _ NEW [RefinableSubsetPrivate _ [ elts: Sets.CreateHashSet[], oldKey: rfblSet.oldKey, nextRoot: root]]; IF NOT toNew.Insert[both.li, newSet] THEN ERROR; IF NOT rfblSets.AddElt[newSet] THEN ERROR; }; IF NOT newSet.elts.AddElt[elt] THEN ERROR; IF NOT rfblSet.elts.RemoveElt[elt] THEN ERROR; }; }; rfblSet.elts.Enumerate[RefineElt]; }; IF lai[dt] = jSize[dt] THEN { side _ high; lai[dt] _ lai[dt] - 1; clai _ clai - (IF dt=Foo THEN jSize[Bar] ELSE 1)}; rfblSets.Enumerate[ResetSet]; rfblSets.Enumerate[RefineSet]; toNew.Erase[]; ENDLOOP ENDLOOP; }; RemakeTies: PROC [act: CellType, a: Array] = { d1: Dim = IF RangeLength[a.groupingParmses[Foo].middle] < RangeLength[a.groupingParmses[Bar].middle] THEN Foo ELSE Bar; d2: Dim = OtherDim[d1]; FOR ff: NAT IN [0 .. a.jointsPeriod[Foo]) DO FOR fb: NAT IN [0 .. a.jointsPeriod[Bar]) DO FOR dj: Dim IN Dim DO phase: Nat2 = [ff, fb]; j: Joint = GetArrayJoint[a, dj, phase]; IF j.size = 0 THEN LOOP; {wir: Range2 = SizeRange[j.size2]; mcir: Range2 = GPMiddle[j.groupingParmses]; hasMiddle: ARRAY Dim OF BOOL = [HasMiddle[a.groupingParmses[Foo]], HasMiddle[a.groupingParmses[Bar]]]; SelStart: PROC [di: Dim] RETURNS [mji: NAT] = { mji _ SELECT TRUE FROM hasMiddle[di] => j.groupingParmses[di].middle.min, a.groupingParmses[di].middle.maxPlusOne <= 0 => 0, a.groupingParmses[di].middle.maxPlusOne < j.size2[di] => ERROR, ENDCASE => a.groupingParmses[di].middle.min-1; }; mji2: Nat2 = [SelStart[Foo], SelStart[Bar]]; mji: NAT = j.groupingParmses[Bar].sum * mji2[Foo] + mji2[Bar]; tsm: VarSet--of Tie-- = FetchTies[j, mji]; rfblSetsm: Set--of RefinableSubset-- = Sets.CreateHashSet[]; rfblSetse, rfblSetsc: Set--of RefinableSubset--; toNew: IntHashTable.Table = IntHashTable.Create[]; need: ARRAY [1 .. 4] OF BOOL = [ wir[d1].min < mcir[d1].min, mcir[d1].maxPlusOne < wir[d1].maxPlusOne, wir[d2].min < mcir[d2].min AND hasMiddle[d1], mcir[d2].maxPlusOne < wir[d2].maxPlusOne AND hasMiddle[d1]]; Prep: PROC [i: [1 .. 4]] RETURNS [Set--of RefinableSubset--] = { IF need[i] THEN { FOR j: [1 .. 4] IN (i .. 4] DO IF need[j] THEN RETURN[CopyRefinableSubsets[rfblSetsm]]; ENDLOOP; RETURN[rfblSetsm]}; RETURN [Sets.nilSet]}; GetEltRoot: PROC [a: Array, d: Dim, elt: REF ANY, side: End, clai: NAT] RETURNS [root: NAT] = { rpd: SidedPortData = NARROW[elt]; IF side # low THEN ERROR; root _ GetRoot[a, d, rpd, clai]; }; MakeTieSets[a, dj, tsm, rfblSetsm]; IF hasMiddle[Foo] AND hasMiddle[Bar] THEN { RefineOverRange[a, dj, phase, rfblSetsm, toNew, mcir, GetEltRoot]; SetTies[act, a, dj, phase, j, mji2, rfblSetsm]; }; rfblSetse _ Prep[1]; FOR ci1: INT DECREASING IN [wir[d1].min .. mcir[d1].min) DO eji2: Nat2 = ConsNat2[d1, ci1, mji2[d2]]; IF hasMiddle[d2] THEN { RefineOverRange[a, dj, phase, rfblSetse, toNew, ConsRange2[d1, [ci1, ci1+1], mcir[d2]], GetEltRoot]; SetTies[act, a, dj, phase, j, eji2, rfblSetse]; }; rfblSetsc _ CopyRefinableSubsets[rfblSetse]; FOR ci2: INT DECREASING IN [wir[d2].min .. mcir[d2].min) DO cji2: Nat2 = ConsNat2[d2, ci2, eji2[d1]]; RefineOverRange[a, dj, phase, rfblSetsc, toNew, ConsRange2[d2, [ci2, ci2+1], [ci1, mcir[d1].maxPlusOne]], GetEltRoot]; SetTies[act, a, dj, phase, j, cji2, rfblSetsc]; ENDLOOP; rfblSetsc _ CopyRefinableSubsets[rfblSetse]; FOR ci2: INT IN [mcir[d2].maxPlusOne .. wir[d2].maxPlusOne) DO cji2: Nat2 = ConsNat2[d2, ci2 + j.groupingParmses[d2].d, eji2[d1]]; RefineOverRange[a, dj, phase, rfblSetsc, toNew, ConsRange2[d2, [ci2, ci2+1], [ci1, mcir[d1].maxPlusOne]], GetEltRoot]; SetTies[act, a, dj, phase, j, cji2, rfblSetsc]; ENDLOOP; ENDLOOP; rfblSetse _ Prep[2]; FOR ci1: INT IN [mcir[d1].maxPlusOne .. wir[d1].maxPlusOne) DO eji2: Nat2 = ConsNat2[d1, ci1 + j.groupingParmses[d1].d, mji2[d2]]; IF hasMiddle[d2] THEN { RefineOverRange[a, dj, phase, rfblSetse, toNew, ConsRange2[d1, [ci1, ci1+1], mcir[d2]], GetEltRoot]; SetTies[act, a, dj, phase, j, eji2, rfblSetse]; }; rfblSetsc _ CopyRefinableSubsets[rfblSetse]; FOR ci2: INT DECREASING IN [wir[d2].min .. mcir[d2].min) DO cji2: Nat2 = ConsNat2[d2, ci2, eji2[d1]]; RefineOverRange[a, dj, phase, rfblSetsc, toNew, ConsRange2[d2, [ci2, ci2+1], [mcir[d1].min, ci1+1]], GetEltRoot]; SetTies[act, a, dj, phase, j, cji2, rfblSetsc]; ENDLOOP; rfblSetsc _ CopyRefinableSubsets[rfblSetse]; FOR ci2: INT IN [mcir[d2].maxPlusOne .. wir[d2].maxPlusOne) DO cji2: Nat2 = ConsNat2[d2, ci2 + j.groupingParmses[d2].d, eji2[d1]]; RefineOverRange[a, dj, phase, rfblSetsc, toNew, ConsRange2[d2, [ci2, ci2+1], [mcir[d1].min, ci1+1]], GetEltRoot]; SetTies[act, a, dj, phase, j, cji2, rfblSetsc]; ENDLOOP; ENDLOOP; IF hasMiddle[d1] THEN { rfblSetse _ Prep[3]; FOR ci2: INT DECREASING IN [wir[d2].min .. mcir[d2].min) DO eji2: Nat2 = ConsNat2[d2, ci2, mji2[d1]]; RefineOverRange[a, dj, phase, rfblSetse, toNew, ConsRange2[d2, [ci2, ci2+1], mcir[d1]], GetEltRoot]; SetTies[act, a, dj, phase, j, eji2, rfblSetse]; ENDLOOP; }; IF hasMiddle[d1] THEN { rfblSetse _ Prep[4]; FOR ci2: INT IN [mcir[d2].maxPlusOne .. wir[d2].maxPlusOne) DO eji2: Nat2 = ConsNat2[d2, ci2 + j.groupingParmses[d2].d, mji2[d1]]; RefineOverRange[a, dj, phase, rfblSetse, toNew, ConsRange2[d2, [ci2, ci2+1], mcir[d1]], GetEltRoot]; SetTies[act, a, dj, phase, j, eji2, rfblSetse]; ENDLOOP; }; a _ a; }ENDLOOP ENDLOOP ENDLOOP; a _ a; }; MakeTieSets: PROC [a: Array, dj: Dim, ts: Set--of Tie--, rfblSets: Set--of RefinableSubset--] = { StartSet: PROC [ra: REF ANY] = { t: Tie = NARROW[ra]; rfblSet: RefinableSubset = NEW [RefinableSubsetPrivate _ [elts: Sets.CreateHashSet[] ]]; FOR side: End IN End DO IF t.groups[side] # NIL THEN FOR ports: PortList _ t.groups[side].ports, ports.rest WHILE ports # NIL DO rpd: SidedPortData = NARROW[a.toRole[dj][side].Fetch[ports.first].val]; IF rpd = NIL THEN ERROR; IF NOT rfblSet.elts.AddElt[rpd] THEN ERROR; ENDLOOP; ENDLOOP; IF rfblSet.elts.Size[] = 0 THEN ERROR; IF NOT rfblSets.AddElt[rfblSet] THEN ERROR; }; ts.Enumerate[StartSet]; }; RoledGroupList: TYPE = LIST OF RoledGroup; RoledGroup: TYPE = REF RoledGroupPrivate; RoledGroupPrivate: TYPE = RECORD [side: End, g: Group]; GroupPairList: TYPE = LIST OF GroupPair; GroupPairRef: TYPE = REF GroupPair; GroupPair: TYPE = ARRAY End OF Group; SetTies: PROC [act: CellType, a: Array, d: Dim, phase: Nat2, j: Joint, jgi2: Nat2, rfblSets: Set--of RefinableSubset--] = { jSize: Nat2 = Nat2Tweak[a.size, d, -1]; jgi: NAT = j.groupingParmses[Bar].sum * jgi2[Foo] + jgi2[Bar]; gip: GIPair = Jgi2ToGip[a, d, phase, j, jgi2]; oldTS: VarSet--of Tie-- = FetchTies[j, jgi]; newTS: VarSet--of Tie-- = Sets.CreateHashSet[]; g2t: ARRAY End OF RefTable--Group _ Tie-- = [NARROW[j.toTie[low][jgi]], NARROW[j.toTie[high][jgi]]]; Transfer: PROC [ra: REF ANY] = { rfblSet: RefinableSubset = NARROW[ra]; groupses: ARRAY End OF GroupList _ ALL[NIL]; TransferPort: PROC [ra: REF ANY] = { rpd: SidedPortData = NARROW[ra]; g: Group = PortToGroup[a, gip[rpd.side], rpd.port]; groupses[rpd.side] _ NARROW[GList.Union[groupses[rpd.side], NARROW[LIST[g], GroupList]]]; }; rfblSet.elts.Enumerate[TransferPort]; IF groupses[low] # NIL AND groupses[high] # NIL THEN { t: Tie = NEW [TiePrivate _ [groups: [groupses[low].first, groupses[high].first]]]; IF NOT newTS.AddElt[t] THEN ERROR; FOR side: End IN End DO IF NOT g2t[side].Store[t.groups[side], t] THEN ERROR; ENDLOOP; }; }; toPair: ARRAY End OF RefTable = [CreateRefTable[], CreateRefTable[]]; Patch: PROC [ra: REF ANY] = { oldTie: Tie = NARROW[ra]; lair: Range2 = Jgi2ToLair[a, phase, j, jgi2].lair; gpl: GroupPairList _ NIL; size: NAT _ 0; toPair[low].Erase[]; toPair[high].Erase[]; FOR side: End IN End DO otherSide: End = OtherEnd[side]; oldG: Group = oldTie.groups[side]; IF oldG # NIL THEN FOR ports: PortList _ oldG.ports, ports.rest WHILE ports # NIL DO newG: Group = PortToGroup[a, gip[side], ports.first]; IF toPair[side].Fetch[newG].found THEN LOOP; {newTie: Tie = FetchTie[j, side, jgi, newG]; IF newTie # NIL AND newTie.groups[side] # newG THEN ERROR; gpl _ CONS[[NIL, NIL], gpl]; size _ size + 1; IF newTie # NIL THEN gpl.first _ newTie.groups ELSE gpl.first[side] _ newG; IF NOT toPair[side].Store[newG, gpl] THEN ERROR; IF newTie # NIL AND NOT toPair[otherSide].Store[gpl.first[otherSide], gpl] THEN ERROR; }ENDLOOP; ENDLOOP; {rootToPairs: ICHT.Table = ICHT.Create[-1, size/4*6+5]; FOR laif: INT IN [lair[Foo].min .. lair[Foo].maxPlusOne) DO FOR laib: INT IN [lair[Bar].min .. lair[Bar].maxPlusOne) DO lai: ArrayIndex = [laif, laib]; hai: ArrayIndex = Int2Tweak[lai, d, 1]; clai: NAT = jSize[Bar]*laif + laib; gis, giis: ARRAY End OF Nat2; FOR gps: GroupPairList _ gpl, gps.rest WHILE gps # NIL DO rpd: SidedPortData = IF gps.first[low] # NIL THEN FetchRPD[a, d, [low, gps.first[low].ports.first]] ELSE FetchRPD[a, d, [high, gps.first[high].ports.first]]; root: NAT = GetRoot[a, d, rpd, clai]; pairs: REF GroupListPair _ NARROW[rootToPairs.Fetch[root].value]; IF pairs = NIL AND NOT rootToPairs.Store[root, pairs _ NEW [GroupListPair _ [NIL, NIL]]] THEN ERROR; IF gps.first[low] # NIL THEN pairs[low] _ CONS[gps.first[low], pairs[low]]; IF gps.first[high] # NIL THEN pairs[high] _ CONS[gps.first[high], pairs[high]]; ENDLOOP; [gi2: gis[low], gii2: giis[low]] _ ComputeGroupingsIndex[a, lai]; [gi2: gis[high], gii2: giis[high]] _ ComputeGroupingsIndex[a, hai]; {lastPort: Port _ NIL; Export: PROC [key: INT, value: REF ANY] RETURNS [quit: BOOL _ FALSE] --ICHT.EachPairAction-- = { pairs: REF GroupListPair = NARROW[value]; thisPort: Port = EnsurePortForGroups[act, gis, giis, pairs^]; ConnectInstance: PROC [ci: CellInstance] = { w1: Wire = FindTransitiveConnection[ci, lastPort]; w2: Wire = FindTransitiveConnection[ci, thisPort]; IF w1=NIL OR w2=NIL THEN ERROR; IF w1 # w2 THEN [] _ MergeNets[w1, w2]; }; ConnectArrayElts: PROC [pct: CellType] = { pa: Array = pct.asArray; IF NOT MakeArrayConnection[pct, Foo, SizeRange[Nat2Tweak[pa.size, Foo, -1]], [low, lastPort], [low, thisPort], TRUE] THEN ERROR; IF NOT MakeArrayConnection[pct, Foo, SizeRange[Nat2Tweak[pa.size, Foo, -1]], [high, lastPort], [high, thisPort], TRUE] THEN ERROR; }; IF lastPort # NIL THEN { EnumerateInstances[act, ConnectInstance, FALSE]; EnumerateArrays[act, ConnectArrayElts]; }; lastPort _ thisPort; }; [] _ rootToPairs.Pairs[Export]; rootToPairs.Erase[]; }ENDLOOP ENDLOOP; }}; j.ties[jgi] _ newTS.Refify; FOR side: End IN End DO g2t[side].Erase[] ENDLOOP; rfblSets.Enumerate[Transfer]; oldTS.Enumerate[Patch]; }; Start: PROC ~ { }; Start[]; END. \LichenArray3Impl.Mesa Last tweaked by Mike Spreitzer on July 28, 1987 5:07:19 pm PDT Κ˜™Icodešœ>™>—J˜KšΟk œWœo˜ΡK˜šΡbnxœœ˜Kšœz˜Kšœ˜Kšœ˜—K˜Kš œœœNΟnœŸœ˜K˜šŸœœœ˜7Kšœœœœ˜*K˜K˜K˜K˜ K˜—K˜Kšœ œœœ ˜$Kšœ œœ˜#Kšœœœœ˜2Kšœœœœ˜K˜Kšœœœ˜3šœœœ˜'Kšœ Οcœ˜Kšœœ˜K˜—K˜šŸ œœ˜ KšœΟdœœœœœœœœ˜RKšœ œYœœ˜wK˜šœΟg‘œœœœœ’‘œœœ˜YKšœ’‘œ’‘œ˜KšœB˜BKšœK˜KKšœ œœœJ˜fšŸœœ œœ˜.šœœœ˜Kšœ;˜;Kšœ1˜1Kšœ6œ˜Kšœ‘œœ˜,Kšœ‘œ œ˜Kšœ‘œœ˜,šœœ˜Kš œ‘œ‘œ‘œ‘œ˜dKšœ‘œ ‘œ˜ K˜—Kšœ‘œ ‘œ˜,š œ‘œœ œœ˜;Kšœ‘œ)˜FKšœœ6˜>Kšœ‘œœ˜,Kš œ‘œ‘œ‘œ‘œ‘œ%˜vKšœ‘œ ‘œ˜ Kšœ˜—Kšœ‘œ ‘œ˜,š œ‘œœœ-˜>Kšœ‘œ6’œ ˜`Kšœœ6˜>Kšœ‘œœ˜,Kš œ‘œ‘œ‘œ‘œ‘œ%˜vKšœ‘œ ‘œ˜ Kšœ˜—Kšœ˜—Kšœ‘œ ˜š œ‘œœœ-˜>Kšœ‘œ6’œ ˜`Kšœœ6˜>Kšœ‘œœ˜,šœœ˜Kš œ‘œ‘œ‘œ‘œ˜dKšœ‘œ ‘œ˜ K˜—Kšœ‘œ ‘œ˜,š œ‘œœ œœ˜;Kšœ‘œ)˜FKšœœ6˜>Kšœ‘œœ˜,Kš œ‘œ‘œ‘œ‘œ‘œ˜qKšœ‘œ ‘œ˜ Kšœ˜—Kšœ‘œ ‘œ˜,š œ‘œœœ-˜>Kšœ‘œ6’œ ˜`Kšœœ6˜>Kšœ‘œœ˜,Kš œ‘œ‘œ‘œ‘œ‘œ˜qKšœ‘œ ‘œ˜ Kšœ˜—Kšœ˜—šœœ˜Kšœ‘œ ˜š œ‘œœ œœ˜;Kšœ‘œ)˜FKšœœ6˜>Kšœ‘œœ˜,Kš œ‘œ‘œ‘œ‘œ˜dKšœ‘œ ‘œ˜ Kšœ˜—K˜—šœœ˜Kšœ‘œ ˜š œ‘œœœ-˜>Kšœ‘œ6’œ ˜`Kšœœ6˜>Kšœ‘œœ˜,Kš œ‘œ‘œ‘œ‘œ˜dKšœ‘œ ‘œ˜ Kšœ˜—K˜—K˜Kšœœ˜—K˜Kšœ˜—K˜šŸ œœ ‘œ# œ˜_šŸœœœœ˜ Kšœ œ˜Kšœœ:˜Xšœ'œ œ˜>šœœ˜*Kšœœ ‘œ˜6Kšœœ ‘œ#˜;—Kšœœœœ˜/Kšœ˜—Kšœœœœ˜+K˜—K˜Kšœ˜—K˜šŸ œœ) œ˜SšŸœœœœ˜ Kšœœ˜&Kšœ œ˜+šŸ œœœœ˜$Kšœœ˜Kš œœœœœœ˜8Kšœ ˜ Kšœ œ˜Kšœœœœ˜,K˜—K˜%Kšœœœœ˜&K˜—K˜K˜!K˜K˜—K˜š Ÿœœ œœ  œ˜nšŸœœœœ˜+Kšœœ˜$Kšœœ:˜WšŸœœœœ˜Kšœœœœ˜)K˜—Kšœ˜Kšœœœœ˜&K˜—K˜Kšœ(˜(K˜ K˜—K˜šŸœœ ‘œ! œ*Ÿ œœœœœœœ˜δKšœ!‘œ˜(šœ‘œœœ'œœ‘œœœ'˜qKšœ‘œ‘œ˜@K˜Kšœœ"˜+Kšœœ˜šŸœœœœ˜ Kšœœ˜&K˜K˜K˜—šŸ œœœœ˜!Kšœœ˜&šŸ œœœœ˜!Kšœœœ˜Kšœœ‘œ˜/šœ˜Kšœœ˜ K˜!šœ˜ K˜7Kšœœ˜=šœ œœ˜šœ œ˜(K˜K˜Kšœ˜—Kšœœœœ˜0Kšœœœœ˜*K˜—Kšœœœœ˜*Kšœœœœ˜.K˜——K˜—Kšœ"˜"K˜—šœ‘œ ‘œœ˜Kšœ ˜ Kšœ‘œ ‘œ˜Kš œœ‘œœ œ˜2—Kšœ˜Kšœ˜K˜Kšœœ˜—K˜—K˜šŸ œœ˜.Kšœ œYœœ˜wK˜šœ’‘œœœœœ’‘œœœœœ‘œœ˜oKšœ’‘œ’‘œ˜Kšœ‘œ ˜'Kšœ œœ˜Kšœ"˜"Kšœ+˜+Kšœ œœœJ˜fš Ÿœœ‘œœœ˜/šœœœ˜Kšœ ‘œ‘œ ˜2Kšœ‘œ˜2Kšœ‘œ‘œœ˜?Kšœ‘œ˜.K˜——Kšœ,˜,Kšœœ6˜>Kšœ‘œ  œ˜*Kšœ‘œ œ˜Kšœ‘œ’œ ˜CKš œ‘œ‘œ‘œ‘œ‘œ%˜vKšœ‘œ‘œ˜/Kšœ˜—Kšœ˜—Kšœ‘œ ˜š œ‘œœœ-˜>Kšœ‘œ’œ ˜Cšœœ˜Kš œ‘œ‘œ‘œ‘œ˜dKšœ‘œ‘œ˜/K˜—Kšœ‘œ ‘œ˜,š œ‘œœ œœ˜;Kšœ‘œ ˜)Kš œ‘œ‘œ‘œ‘œ‘œ˜qKšœ‘œ‘œ˜/Kšœ˜—Kšœ‘œ ‘œ˜,š œ‘œœœ-˜>Kšœ‘œ’œ ˜CKš œ‘œ‘œ‘œ‘œ‘œ˜qKšœ‘œ‘œ˜/Kšœ˜—Kšœ˜—šœœ˜Kšœ‘œ ˜š œ‘œœ œœ˜;Kšœ‘œ ˜)Kš œ‘œ‘œ‘œ‘œ˜dKšœ‘œ‘œ˜/Kšœ˜—K˜—šœœ˜Kšœ‘œ ˜š œ‘œœœ-˜>Kšœ‘œ’œ ˜CKš œ‘œ‘œ‘œ‘œ˜dKšœ‘œ‘œ˜/Kšœ˜—K˜—K˜Kšœœœœ˜—K˜Kšœ˜—K˜š Ÿ œœ ‘œ  œ œ˜ašŸœœœœ˜ Kšœ œ˜Kšœœ:˜Xšœ œ˜š œœœœ4œ œ˜hKšœœ ‘œ ˜GKšœœœœ˜Kšœœœœ˜+Kšœ˜—Kšœ˜—Kšœœœ˜&Kšœœœœ˜+K˜—K˜Kšœ˜—K˜Kšœœœœ ˜*Kšœ œœ˜)Kšœœœ˜7K˜Kšœœœœ ˜(Kšœœœ ˜#Kšœ œœœ˜%K˜šŸœœS œ˜{K˜'Kšœœ6˜>K˜.Kšœ   œ˜,Kšœ   œ˜/Kš œœœ  Πcm œœœ˜dšŸœœœœ˜ Kšœœ˜&Kš œ œœ œœ˜,šŸ œœœœ˜$Kšœœ˜ Kšœ3˜3Kšœœ!œœ˜YK˜—K˜%š œœœœœ˜6Kšœ œF˜RKšœœœœ˜"šœ œ˜Kšœœ$œœ˜5Kšœ˜—K˜—K˜—Kšœœœ1˜EšŸœœœœ˜Kšœœ˜K˜2Kšœœ˜Kšœœ˜Kšœ˜Kšœ˜šœ œ˜K˜ K˜"š œœœœ*œ œ˜TK˜5Kšœ œœ˜,Kšœ,˜,Kš œ œœœœ˜:Kšœœœœ˜K˜Kšœ œœœ˜KKšœœœœ˜0Kš œ œœœ4œœ˜VKšœœ˜ —Kšœ˜—Kšœœ œ˜7šœ‘œœœ)œœ‘œœœ)˜wKšœ‘œ‘œ˜Kšœ'˜'Kšœœ‘œ‘œ˜#Kšœ œœ˜šœ$œœ˜9Kš œœœœ3œ5˜Kšœœ˜%Kšœœœ ˜AKšœ œœœ!œœœœœ˜dKšœœœœ˜KKšœœœœ˜OKšœ˜—KšœA˜AKšœC˜CKšœœ˜šŸœœœ œœœœœ œ˜`Kšœœœ˜)Kšœ=˜=šŸœœ˜,Kšœ2˜2Kšœ2˜2Kš œœœœœœ˜Kšœ œ˜'K˜—šŸœœ˜*K˜Kš œœiœœœ˜€Kš œœkœœœ˜‚K˜—šœ œœ˜Kšœ)œ˜0Kšœ'˜'K˜—K˜K˜—Kšœ˜Kšœ˜Kšœœœ˜—K˜—K˜Kšœ œœœ˜2K˜K˜K˜—K˜šŸœœ˜K˜—K˜K˜K˜Kšœ˜—…—MtfΠ