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, 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
f
f:
NAT
IN [0 .. a.jointsPeriod[Foo])
DO
FOR
f
b:
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 ci
1:
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 ci
2:
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 ci
2:
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 ci
1:
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 ci
2:
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 ci
2:
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 ci
2:
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 ci
2:
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, d
t: 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, d
t: 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 ci
f:
INT
IN [cir[Foo].min .. cir[Foo].maxPlusOne)
DO
FOR ci
b:
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[d
t] = jSize[d
t]
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
f
f:
NAT
IN [0 .. a.jointsPeriod[Foo])
DO
FOR
f
b:
NAT
IN [0 .. a.jointsPeriod[Bar])
DO
FOR d
j: 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 [d
i: 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 ci
1:
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 ci
2:
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 ci
2:
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 ci
1:
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 ci
2:
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 ci
2:
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 ci
2:
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 ci
2:
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, d
j: 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 lai
f:
INT
IN [lair[Foo].min .. lair[Foo].maxPlusOne)
DO
FOR lai
b:
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[];
END.