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 d
j: 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 [d
e: 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.