LichenArray3Impl.Mesa
Last tweaked by Mike Spreitzer on July 28, 1987 5:07:19 pm PDT
DIRECTORY Asserting, Basics, Convert, GList, IntChainedHashTable, InterpreterOps, IntHashTable, IO, LichenArrayStuff, Collections, LichenDataOps, LichenDataStructure, PairCollections, RefTab, Rope;
LichenArray3Impl: CEDAR PROGRAM
IMPORTS GList, IntChainedHashTable, IntHashTable, LichenArrayStuff, Collections, LichenDataOps, LichenDataStructure, RefTab
EXPORTS LichenArrayStuff
=
BEGIN OPEN ICHT: IntChainedHashTable, LichenDataStructure, LichenArrayStuff, LichenDataOps, Sets:Collections, Fns:PairCollections;
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 b 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: BOOLFALSE] --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.