LichenArrayImpl.Mesa
Mike Spreitzer November 17, 1986 10:42:19 pm PST
DIRECTORY Basics, Convert, GList, HashTable, IntChainedHashTable, InterpreterOps, IntHashTable, IO, LichenDataOps, LichenDataStructure, LichenSetTheory, Rope;
LichenArray2Impl: CEDAR MONITOR
IMPORTS HashTable, LichenDataStructure, LichenSetTheory
INVARIANT
tie.completion is redundant with the information in the rpd.links.
tie.completion = NIL iff tie.completion.nIncomplete = 0.
a RoledPortData has links iff needed or array is being created.
=
BEGIN OPEN ICHT: IntChainedHashTable, LichenSetTheory, LichenDataStructure;
Abort: ERROR = CODE;
ConsInt2: PROC [d1: Dim, x1, x2: INT] RETURNS [x: Int2]
= INLINE {x[d1] ← x1; x[OtherDim[d1]] ← x2};
Range2Intersection: PROC [a, b: Range2] RETURNS [c: Range2]
= INLINE {c ← [
Foo: [
min: MAX[a[Foo].min, b[Foo].min],
maxPlusOne: MIN[a[Foo].maxPlusOne, b[Foo].maxPlusOne]],
Bar: [
min: MAX[a[Bar].min, b[Bar].min],
maxPlusOne: MIN[a[Bar].maxPlusOne, b[Bar].maxPlusOne]]]};
EnumJgiOfGi: PROC [a: Array, gi2: Nat2, Consume: PROC [d: Dim, j: Joint, side: End, jgi2: Nat2]] = {
phase: Nat2;
air: Range2 = Gi2ToAir[a, gi2].air;
FOR d: Dim IN Dim DO
phase[d] ← SELECT TRUE FROM
gi2[d] < a.groupingParmses[d].middle.min => gi2[d] MOD a.jointsPeriod[d],
gi2[d] >= a.groupingParmses[d].firstHigh => NAT[(gi2[d]-a.groupingParmses[d].d) MOD a.jointsPeriod[d]],
ENDCASE => gi2[d] - NAT[a.groupingParmses[d].middle.min];
ENDLOOP;
FOR dj: Dim IN Dim DO
lairMax: Range2 = SizeRange[Nat2Tweak[a.size, dj, -1]];
j: Joint = GetArrayJoint[a, dj, phase];
FOR side: End IN End DO
lair: Range2 = Range2Intersection[lairMax, IF side = low THEN air ELSE Range2Off[air, ConsInt2[dj, -1, 0]]];
lf: Nat2 = [lair[Foo].min MOD a.jointsPeriod[Foo], lair[Bar].min MOD a.jointsPeriod[Bar]];
jir: Range2 = Range2Div[lair, a.jointsPeriod, lf];
Enum: PROC [de: Dim, Consume: PROC [NAT]] = {
IF jir[de].min >= jir[de].maxPlusOne OR j.groupingParmses[de].middle.min >= j.groupingParmses[de].middle.maxPlusOne THEN RETURN;
FOR jgi: INT IN [jir[de].min .. j.groupingParmses[de].middle.min) DO Consume[jgi] ENDLOOP;
FOR jgi: INT IN [j.groupingParmses[de].middle.maxPlusOne .. jir[de].maxPlusOne) DO Consume[jgi] ENDLOOP;
IF jir[de].min < j.groupingParmses[de].middle.maxPlusOne OR jir[de].maxPlusOne > j.groupingParmses[de].middle.min THEN Consume[j.groupingParmses[de].middle.min];
};
Med: PROC [jgif: NAT] = {
Inner: PROC [jgib: NAT] = {Consume[dj, j, side, [jgif, jgib]]};
Enum[Bar, Inner]};
Enum[Foo, Med];
ENDLOOP;
ENDLOOP;
};
Gi2ToAir: PROC [a: Array, gi2: Nat2] RETURNS [air: Range2, ngii: NAT] = {
Do1: PROC [d: Dim] RETURNS [air: Range, n: INT] = {
SELECT TRUE FROM
gi2[d]<a.groupingParmses[d].middle.min => RETURN [[gi2[d], gi2[d]+1], 1];
gi2[d]>=a.groupingParmses[d].firstHigh => {
air.min ← gi2[d] - a.groupingParmses[d].d;
RETURN [[air.min, air.min+1], 1]};
ENDCASE => {
f: NAT = gi2[d] - a.groupingParmses[d].middle.min;
jiir: Range = Range1Div[a.groupingParmses[d].middle, a.jointsPeriod[d], f];
RETURN [Range1Mul[jiir, a.jointsPeriod[d], f], RangeLength[jiir]];
};
};
count2: ARRAY Dim OF INT;
[air[Foo], count2[Foo]] ← Do1[Foo];
[air[Bar], count2[Bar]] ← Do1[Foo];
ngii ← count2[Foo] * count2[Bar];
};
HasUnusedGroups: PROC [ct: CellType] RETURNS [has: BOOL] = {
ENABLE Abort => {has ← TRUE; CONTINUE};
a: Array = ct.asArray;
has ← FALSE;
IF a = NIL THEN RETURN;
FOR gif: NAT IN [0 .. a.groupingParmses[Foo].sum) DO FOR gib: NAT IN [0 .. a.groupingParmses[Bar].sum) DO
gi2: Nat2 = [gif, gib];
gi: NAT = a.groupingParmses[Bar].sum * gif + gib;
gs: Groupings = NARROW[a.groupingses[gi]];
PerGroup: PROC [ra: REF ANY] = {
g: Group = NARROW[ra];
PerJgi: PROC [d: Dim, j: Joint, side: End, jgi2: Nat2] = {
jgi: NAT = j.groupingParmses[Bar].sum * jgi2[Foo] + jgi2[Bar];
IF FetchTie[j, side, jgi, g] # NIL THEN ERROR Abort[];
};
EnumJgiOfGi[a, gi2, PerJgi !Abort => GOTO Used];
ERROR Abort[];
EXITS Used => ra ← ra;
};
gs.groups.Enumerate[PerGroup];
IF has THEN RETURN;
ENDLOOP ENDLOOP;
has ← FALSE;
};
END.