DIRECTORY Basics, Collections, Convert, LichenArrayStuff, LichenDataOps, LichenDataStructure, List, LRUCache, PairCollections, Rope; LichenNewArrayImpl1: CEDAR PROGRAM IMPORTS Collections, Convert, LichenDataOps, LichenDataStructure, List, LRUCache, PairCollections, Rope EXPORTS LichenArrayStuff, LichenDataStructure = BEGIN OPEN LichenDataOps, LichenDataStructure, LichenArrayStuff, PairColls:PairCollections, Colls:Collections; Array: TYPE ~ LichenDataStructure.Array; CreateArrayRep: PUBLIC PROC [eltType: CellType, size2, basePeriod: Size2] RETURNS [Array] ~ { statrep: StatRep ~ CreateStatRep[]; a: Array = NEW [ArrayPrivate _ [ eltType: eltType, prevArray: NIL, nextArray: NIL, size2: size2, size: size2[Foo]*size2[Bar], basePeriod: basePeriod, dumrep: NIL, statrep: statrep ]]; RETURN [a]}; CreateStatRep: PUBLIC PROC RETURNS [sr: StatRep] ~ { sr _ NEW [StatRepPrivate _ [ edges: Colls.CreateHashSet[], portEdge: [ FALSE: PairColls.CreateHashReln[functional: [FALSE, TRUE], mappable: [TRUE, FALSE]], TRUE: PairColls.CreateHashReln[functional: [FALSE, TRUE], mappable: [TRUE, FALSE]]] ]]; RETURN}; flushSelves: BOOL _ TRUE; MakeArrayNewConnection: PUBLIC PROC [act: CellType, rangeA: Range2, delta: Int2, epA, epB: Port] ~ { a: Array ~ act.asArray; fullRangeA: Range2 ~ Range2Intersection[SizeRange[a.size2], Range2Off[SizeRange[a.size2], Int2Neg[delta]]]; rangeB: Range2 ~ Range2Off[rangeA, delta]; IF a.buildPhase#buildingStatrep THEN ERROR; IF ABS[delta[Foo]]>1 OR ABS[delta[Bar]]>1 THEN ERROR; IF epA=epB AND delta=[0, 0] THEN --this self-connection is always implicitly present, let's not make it explicit-- IF flushSelves THEN RETURN; IF rangeA # fullRangeA THEN ERROR; FOR ff: NAT IN [0 .. a.basePeriod[Foo]) DO FOR fb: NAT IN [0 .. a.basePeriod[Bar]) DO fA: Nat2 ~ [ff, fb]; fB: Nat2 ~ Nat2AddMod[fA, delta, a.basePeriod]; svA: StatVertex ~ NEW [StatVertexPrivate _ [epA, fA]]; svB: StatVertex ~ NEW [StatVertexPrivate _ [epB, fB]]; IF NOT StatEdgeRedundant[a, [vs: [svA, svB], d: delta], NIL] THEN [] _ AddStatEdge[a.statrep, [vs: [FALSE: svA, TRUE: svB], d: delta]]; act _ act; ENDLOOP ENDLOOP; RETURN}; AddStatEdge: PUBLIC PROC [sr: StatRep, sep: StatEdgePrivate] RETURNS [se: StatEdge] ~ { se _ NEW [StatEdgePrivate _ sep]; sr.portEdge[FALSE].AddNewPair[[sep.vs[FALSE].port, se]]; sr.portEdge[TRUE].AddNewPair[[sep.vs[TRUE].port, se]]; IF NOT sr.edges.AddElt[se] THEN ERROR; RETURN}; StatEdgeRedundant: PUBLIC PROC [a: Array, sep: StatEdgePrivate, avoid: StatEdge _ NIL] RETURNS [redundant: BOOL] ~ { seen: Set--of PortAtIndex-- ~ Colls.CreateHashSet[portsAtIndices]; frontier: Set--of PortAtIndex-- ~ Colls.CreateHashSet[portsAtIndices]; c1: Int2 ~ WidenNat2[sep.vs[FALSE].phase]; c2: Int2 ~ Int2Add[c1, sep.d]; bounds: Range2 ~ Int2sRange[c1, c2]; IF sep.vs[TRUE].phase # Nat2AddMod[sep.vs[FALSE].phase, sep.d, a.basePeriod] THEN ERROR; IF NOT frontier.AddElt[NEW [PortAtIndexPrivate _ [sep.vs[FALSE].port, c1]]] THEN ERROR; WHILE NOT frontier.Empty[] DO pai: PortAtIndex ~ NARROW[frontier.Pop.val]; IF NOT seen.AddElt[pai] THEN LOOP; IF pai.port = sep.vs[TRUE].port AND pai.ai = c2 THEN RETURN [TRUE]; {sv: StatVertex ~ NEW [StatVertexPrivate _ [pai.port, Int2Mod[pai.ai, a.basePeriod]]]; TestEdge: PROC [se: StatEdge, ob: BOOL] RETURNS [BOOL] ~ { d: Int2 ~ IF ob THEN se.d ELSE Int2Neg[se.d]; oai: ArrayIndex ~ Int2Add[pai.ai, d]; IF se#avoid AND Int2InRange[oai, bounds] THEN [] _ frontier.AddElt[NEW [PortAtIndexPrivate _ [se.vs[ob].port, oai]]]; RETURN [FALSE]}; [] _ ScanStatEdgesFrom[a.statrep, sv, TestEdge]; }ENDLOOP; RETURN [FALSE]}; FindStatEdge: PUBLIC PROC [sr: StatRep, sep: StatEdgePrivate] RETURNS [fse: StatEdge] ~ { TestEdge: PROC [se: StatEdge, ob: BOOL] RETURNS [BOOL] ~ { RETURN [statVerts.SpaceEqual[se.vs[ob], sep.vs[TRUE]] AND sep.d = (IF ob THEN se.d ELSE Int2Neg[se.d])]}; fse _ ScanStatEdgesFrom[sr, sep.vs[FALSE], TestEdge].se; RETURN}; FinishedMakingArrayConnections: PUBLIC PROC [act: CellType] ~ { a: Array ~ act.asArray; dumrep: DumRep ~ NEW [DumRepPrivate _ [ topWires: Colls.CreateHashSet[], epToTopWire: PairColls.CreateHashFn[invable: FALSE], apToWire: PairColls.CreateHashFn[invable: TRUE] ]]; PerStatEdge: PROC [ra: REF ANY] ~ { se: StatEdge ~ NARROW[ra]; DumbifyStatEdge[a, se]; RETURN}; IF a.buildPhase#buildingStatrep THEN ERROR; a.buildPhase _ statrepFixed; IF a.dumrep#NIL THEN ERROR; a.dumrep _ dumrep; a.statrep.edges.Enumerate[PerStatEdge]; RETURN}; SetStatRep: PUBLIC PROC [act: CellType, statrep: StatRep, reset: BOOL] ~ { a: Array ~ act.asArray; IF a.buildPhase # (IF reset THEN statrepFixed ELSE buildingStatrep) THEN ERROR; a.buildPhase _ buildingStatrep; a.statrep _ statrep; FinishedMakingArrayConnections[act]; RETURN}; DumbifyStatEdge: PROC [a: Array, se: StatEdge] ~ { epA: Port ~ se.vs[FALSE].port; epB: Port ~ se.vs[TRUE].port; fullRangeA: Range2 ~ Range2Intersection[SizeRange[a.size2], Range2Off[SizeRange[a.size2], Int2Neg[se.d]]]; iRangeA: Range2 ~ Range2Div[fullRangeA, a.basePeriod, se.vs[FALSE].phase]; dwsA: RefSeq--cai _ TopDumbWire-- ~ GetDumbWires[a, epA, TRUE]; dwsB: RefSeq--cai _ TopDumbWire-- ~ GetDumbWires[a, epB, TRUE]; FOR if: INT IN [iRangeA[Foo].min .. iRangeA[Foo].maxPlusOne) DO FOR ib: INT IN [iRangeA[Bar].min .. iRangeA[Bar].maxPlusOne) DO aiA: Int2 ~ [ if*a.basePeriod[Foo]+se.vs[FALSE].phase[Foo], ib*a.basePeriod[Bar]+se.vs[FALSE].phase[Bar]]; aiB: ArrayIndex ~ Int2Add[se.d, aiA]; caiA: CompositeArrayIndex ~ ComposeAI[a, aiA]; caiB: CompositeArrayIndex ~ ComposeAI[a, aiB]; dwA: TopDumbWire ~ NARROW[dwsA[caiA]]; dwB: TopDumbWire ~ NARROW[dwsB[caiB]]; IF dwA=dwB THEN {IF dwA=NIL THEN { dw: TopDumbWire ~ NEW [DumbWirePrivate[top] _ [ children: PairColls.CreateHashFn[invable: FALSE], variant: top[eps: PairColls.CreateHashFn[invable: FALSE]] ]]; IF NOT a.dumrep.topWires.AddElt[dw] THEN ERROR; AddDumbElt[a, dw, epA, aiA]; AddDumbElt[a, dw, epB, aiB]}} ELSE IF dwA=NIL THEN AddDumbElt[a, dwB, epA, aiA] ELSE IF dwB=NIL THEN AddDumbElt[a, dwA, epB, aiB] ELSE JoinDumbWires[a, dwA, dwB]; a _ a; ENDLOOP ENDLOOP; RETURN}; AddDumbElt: PROC [a: Array, dw: TopDumbWire, ep: Port, ai: ArrayIndex] ~ { cai: CompositeArrayIndex ~ ComposeAI[a, ai]; dws: RefSeq--CompositeArrayIndex _ TopDumbWire-- ~ GetDumbWires[a, ep, TRUE]; mems: BoolSeq--CompositeArrayIndex _ member-- _ NARROW[dw.eps.Apply[ep].DVal]; IF mems=NIL THEN dw.eps.AddNewPair[[ep, mems _ CreateBoolSeq[a.size, FALSE]]]; dws[cai] _ dw; mems[cai] _ TRUE; RETURN}; JoinDumbWires: PROC [a: Array, dwA, dwB: TopDumbWire] ~ { MoveElt: PROC [pair: PairColls.Pair] ~ { ep: Port ~ NARROW[pair[left]]; dws: RefSeq--CompositeArrayIndex _ DumbWire-- ~ NARROW[a.dumrep.epToTopWire.Apply[ep].val]; memsB: BoolSeq ~ NARROW[pair[right]]; memsA: BoolSeq ~ NARROW[dwA.eps.Apply[ep].DVal]; IF memsA=NIL THEN { dwA.eps.AddNewPair[[ep, memsB]]; FOR cai: CompositeArrayIndex IN [0 .. a.size) DO IF memsB[cai] THEN dws[cai] _ dwA; ENDLOOP; } ELSE { FOR cai: CompositeArrayIndex IN [0 .. a.size) DO IF memsB[cai] THEN { memsA[cai] _ TRUE; dws[cai] _ dwA}; ENDLOOP; }; RETURN}; MoveExport: PROC [ra: REF ANY] ~ { ap: Port ~ NARROW[ra]; [] _ a.dumrep.apToWire.AddPair[[ap, dwA]]; RETURN}; IF NOT a.dumrep.topWires.RemoveElt[dwB] THEN ERROR; dwB.eps.Enumerate[MoveElt]; a.dumrep.apToWire.Mapping[dwB, rightToLeft].Enumerate[MoveExport]; RETURN}; GetDumbWires: PROC [a: Array, ep: Port, mayAdd: BOOL] RETURNS [dws: RefSeq--cai _ TopDumbWire--] ~ { dws _ NARROW[a.dumrep.epToTopWire.Apply[ep].DVal]; IF dws=NIL AND mayAdd THEN a.dumrep.epToTopWire.AddNewPair[[ep, dws _ CreateRefSeq[a.size]]]; RETURN}; GetDumbWire: PUBLIC PROC [a: Array, ep: Port, ai: ArrayIndex] RETURNS [dw: DumbWire] ~ { cai: CompositeArrayIndex ~ ComposeAI[a, ai]; Work: PROC [ep: Port] RETURNS [dw: DumbWire] ~ { dws: RefSeq--cai _ TopDumbWire-- ~ GetDumbWires[a, ep, FALSE]; IF dws#NIL THEN dw _ NARROW[dws[cai]]; IF dw#NIL THEN RETURN; IF ep.parent # a.eltType.port THEN { pdw: DumbWire ~ Work[NARROW[ep.parent]]; IF pdw#NIL THEN RETURN [GetDumbChild[pdw, ep]]; }; RETURN}; IF a.buildPhase#statrepFixed THEN ERROR; RETURN Work[ep]}; GetDumbChild: PROC [pdw: DumbWire, port: Port] RETURNS [cdw: ChildDumbWire] ~ { cdw _ NARROW[pdw.children.Apply[port].DVal]; IF cdw#NIL THEN RETURN; pdw.children.AddNewPair[[port, cdw _ NEW [DumbWirePrivate[child] _ [ children: PairColls.CreateHashFn[invable: FALSE], variant: child[pdw, port] ]] ]]; RETURN}; ArrayEltPortsConnected: PUBLIC PROC [a: Array, ai1, ai2: ArrayIndex, ep1, ep2: Port] RETURNS [BOOL] ~ { dw1: DumbWire ~ GetDumbWire[a, ep1, ai1]; dw2: DumbWire ~ GetDumbWire[a, ep2, ai2]; IF a.buildPhase#statrepFixed THEN ERROR; RETURN [dw1=dw2 AND dw1#NIL]}; EnumerateConnectedEltPorts: PUBLIC PROC [a: Array, ep: Port, Consume: PROC [Port]] ~ { seenPorts: Set--of elt Port-- ~ Colls.CreateHashSet[]; PerWire: PROC [dw: DumbWire] ~ { [] _ ScanPortsInDumbWire[a, dw, PassPort]; RETURN}; PassPort: PROC [ep: Port] RETURNS [BOOL] ~ { IF seenPorts.AddElt[ep] THEN Consume[ep]; RETURN [FALSE]}; IF a.buildPhase#statrepFixed THEN ERROR; EnumerateDumbWiresForPort[a, ep, PerWire]; RETURN}; EnumerateDumbWiresForPort: PUBLIC PROC [a: Array, ep: Port, Consume: PROC [DumbWire]] ~ { seenWires: Set--of TopDumbWire-- ~ Colls.CreateHashSet[]; Work: PROC [port: Port, Consume: PROC [DumbWire]] ~ { dws: RefSeq--CompositeArrayIndex _ TopDumbWire-- ~ NARROW[a.dumrep.epToTopWire.Apply[port].DVal]; IF dws#NIL THEN { FOR cai: CompositeArrayIndex IN [0 .. a.size) DO dw: TopDumbWire ~ NARROW[dws[cai]]; IF seenWires.AddElt[dw] THEN Consume[dw]; ENDLOOP; }; WITH port.parent SELECT FROM parent: Port => { Pass: PROC [parent: DumbWire] ~ { child: ChildDumbWire ~ GetDumbChild[parent, port]; Consume[child]; RETURN}; Work[parent, Pass]; }; x: CellType => NULL; ENDCASE => ERROR; RETURN}; IF a.buildPhase#statrepFixed THEN ERROR; Work[ep, Consume]; RETURN}; ScanPortsInDumbWire: PUBLIC PROC [a: Array, dw: DumbWire, Test: PROC [Port] RETURNS [BOOL]] RETURNS [found: BOOL, ep: Port] ~ { ScanWire: PROC [dw: DumbWire, Test: PROC [Port] RETURNS [BOOL]] RETURNS [found: BOOL, ep: Port] ~ { WITH dw SELECT FROM tdw: TopDumbWire => { TestPort: PROC [pair: PairColls.Pair] RETURNS [pass: BOOL _ FALSE] ~ { port: Port ~ NARROW[pair[left]]; IF (pass _ Test[port]) THEN ep _ port; RETURN}; found _ tdw.eps.Scan[TestPort].found; RETURN}; cdw: ChildDumbWire => { index: NATURAL ~ cdw.port.PortIndex; TestPort: PROC [parent: Port] RETURNS [pass: BOOL _ FALSE] ~ { child: Port ~ parent.SubPort[index]; IF (pass _ Test[child]) THEN ep _ child; RETURN}; found _ ScanWire[cdw.parent, TestPort].found; RETURN}; ENDCASE => ERROR; }; RETURN ScanWire[dw, Test]}; GetInstForPortInDumbWire: PUBLIC PROC [a: Array, dw: DumbWire, ep: Port] RETURNS [ArrayIndex] ~ { WITH dw SELECT FROM tdw: TopDumbWire => { mems: BoolSeq--CompositeArrayIndex _ member-- ~ NARROW[tdw.eps.Apply[ep].val]; FOR cai: NATURAL IN [0 .. a.size) DO IF mems[cai] THEN RETURN DecomposeAI[a, cai]; ENDLOOP; RETURN [ALL[-1]]}; cdw: ChildDumbWire => RETURN GetInstForPortInDumbWire[a, cdw.parent, NARROW[ep.parent]]; ENDCASE => ERROR; }; ScanPortsAtIndicesForDumbWire: PUBLIC PROC [a: Array, dw: DumbWire, Test: PROC [port: Port, ai: ArrayIndex] RETURNS [BOOL]] RETURNS [found: BOOL, pai: PortAtIndexPrivate] ~ { WITH dw SELECT FROM tdw: TopDumbWire => { PerPort: PROC [pair: PairColls.Pair] RETURNS [pass: BOOL] ~ { ep: Port ~ NARROW[pair[left]]; mems: BoolSeq--CompositeArrayIndex _ member-- ~ NARROW[pair[right]]; FOR f: INT IN [0 .. a.size2[Foo]) DO FOR b: INT IN [0 .. a.size2[Bar]) DO cai: CompositeArrayIndex ~ ComposeAI[a, [f, b]]; IF mems[cai] THEN IF (pass _ Test[ep, [f, b]]) THEN {pai _ [ep, [f, b]]; RETURN}; ENDLOOP ENDLOOP; RETURN [FALSE]}; found _ tdw.eps.Scan[PerPort].found; RETURN}; cdw: ChildDumbWire => { index: NATURAL ~ cdw.port.PortIndex; Pass: PROC [port: Port, ai: ArrayIndex] RETURNS [pass: BOOL] ~ { child: Port ~ port.SubPort[index]; IF (pass _ Test[child, ai]) THEN pai _ [child, ai]; RETURN}; found _ ScanPortsAtIndicesForDumbWire[a, cdw.parent, Pass].found; RETURN}; ENDCASE => ERROR; }; ScanStatVertices: PUBLIC PROC [a: Array, Test: PROC [StatVertex] RETURNS [BOOL]] RETURNS [found: BOOL _ FALSE, sv: StatVertex _ NIL] ~ { seen: Set--of StatVertex-- ~ Colls.CreateHashSet[statVerts]; PerEdge: PROC [ra: REF ANY] ~ { se: StatEdge ~ NARROW[ra]; IF seen.AddElt[se.vs[FALSE]] AND Test[se.vs[FALSE]] THEN {found _ TRUE; sv _ se.vs[FALSE]; RETURN}; IF seen.AddElt[se.vs[TRUE]] AND Test[se.vs[TRUE]] THEN {found _ TRUE; sv _ se.vs[TRUE]}; RETURN}; a.statrep.edges.Enumerate[PerEdge]; RETURN}; ScanStatEdgesFrom: PUBLIC PROC [sr: StatRep, from: StatVertex, Test: PROC [se: StatEdge, ob: BOOL] RETURNS [BOOL]] RETURNS [found: BOOL _ FALSE, se: StatEdge _ NIL, ob: BOOL _ FALSE] ~ { FOR ob IN BOOL DO sb: BOOL ~ NOT ob; TestEdge: PROC [ra: REF ANY] RETURNS [pass: BOOL] ~ { se: StatEdge ~ NARROW[ra]; pass _ se.vs[sb].phase = from.phase AND Test[se, ob]; RETURN}; mp: PairColls.MaybePair ~ sr.portEdge[sb].ScanMapping[from.port, TestEdge]; IF mp.found THEN RETURN [TRUE, NARROW[mp.pair[right]], ob]; ENDLOOP; RETURN}; GetArrayPortForPort: PUBLIC PROC [act: CellType, index: ArrayIndex, ep: Port, mayAdd: BOOL] RETURNS [arrayPort: Port] ~ { a: Array ~ act.asArray; dw: DumbWire ~ GetDumbWire[a, ep, index]; IF a.buildPhase#statrepFixed THEN ERROR; IF dw=NIL THEN {IF mayAdd THEN ERROR--trying to export a composite wire that doesn't really exist-- ELSE RETURN [NIL]}; {ports: Set--of array Port-- ~ a.dumrep.apToWire.Mapping[dw, rightToLeft]; IF NOT ports.Empty THEN RETURN [NARROW[ports.First[].val]]; IF NOT mayAdd THEN RETURN [NIL]; {portName: SteppyName ~ List.Append[NameIndex[a, index], SteppyDescribe[ep, a.eltType.port]]; arrayPort _ FullyAddPort[[parent: act.port, names: CreateSteppyNames[LIST[portName]]]].port; a.dumrep.apToWire.AddNewPair[[arrayPort, dw]]; RETURN}}}; NoteNewEltPort: PUBLIC PROC [a: Array, ep: Port] ~ { RETURN}; IsIncompleteArray: PUBLIC PROC [act: CellType] RETURNS [BOOL] ~ {RETURN [FALSE]}; ComposeAI: PROC [a: Array, ai: ArrayIndex] RETURNS [CompositeArrayIndex] ~ INLINE {RETURN [a.size2[Bar]*ai[Foo]+ai[Bar]]}; DecomposeAI: PROC [a: Array, cai: CompositeArrayIndex] RETURNS [ArrayIndex] ~ { f: NATURAL ~ cai/a.size2[Bar]; RETURN [[f, cai - f*a.size2[Bar]]]}; NameIndex: PUBLIC PROC [a: Array, index: ArrayIndex] RETURNS [SteppyName] = { SELECT TRUE FROM a.size2[Foo]=1 => RETURN [LIST[NewInt[index[Bar]]]]; a.size2[Bar]=1 => RETURN [LIST[NewInt[index[Foo]]]]; ENDCASE => RETURN [LIST[NewInt[index[Foo]], NewInt[index[Bar]]]]; }; FmtIndex: PUBLIC PROC [a: Array, index: ArrayIndex] RETURNS [asRope: ROPE] = { asRope _ SELECT TRUE FROM a.size2[Foo]=1 => Subscript[NIL, index[Bar]], a.size2[Bar]=1 => Subscript[NIL, index[Foo]], ENDCASE => Subscript2[NIL, index]; }; sublen: NATURAL ~ 64; subs: ARRAY [0 .. sublen) OF ROPE _ ALL[NIL]; Subscript: PUBLIC PROC [base: ROPE, index: INT] RETURNS [sub: ROPE] ~ { sub _ IF index < sublen THEN sub _ subs[index] ELSE sub _ Convert.RopeFromInt[index].Concat["/"]; IF base.Length#0 THEN sub _ base.Cat["/", sub]; RETURN}; sub2len: NATURAL _ 2050; sub2Ps: LRUCache.Handle _ LRUCache.Create[sub2len, HashAI, EqualAI]; sub2Rs: RefSeq _ CreateRefSeq[sub2len]; s2probes, s2misses: CARD _ 0; HashAI: PROC [ra: REF ANY] RETURNS [CARDINAL] --LRUCache.HashProc-- ~ { rai: REF ArrayIndex ~ NARROW[ra]; lnF: Basics.LongNumber ~ [li[rai[Foo]]]; lnB: Basics.LongNumber ~ [li[rai[Bar]]]; ln: Basics.LongNumber ~ [lc[lnF.lo + lnF.hi*3 + lnB.lo*5 + lnB.hi*7]]; RETURN [ln.lo+ln.hi]; }; EqualAI: PROC [r1, r2: REF ANY] RETURNS [BOOL] --LRUCache.EqualProc-- ~ { rai1: REF ArrayIndex ~ NARROW[r1]; rai2: REF ArrayIndex ~ NARROW[r2]; RETURN [rai1^ = rai2^]}; Subscript2: PUBLIC PROC [base: ROPE, index: ArrayIndex] RETURNS [sub: ROPE] ~ { rai: REF ArrayIndex ~ NEW [ArrayIndex _ index]; p: NATURAL; news: BOOL; [p, news, ] _ sub2Ps.Include[rai]; s2probes _ s2probes+1; IF news THEN { sub2Rs[p] _ Rope.Cat[Convert.RopeFromInt[index[Foo]], "/", Convert.RopeFromInt[index[Bar]], "/"]; s2misses _ s2misses+1; }; sub _ NARROW[sub2Rs[p]]; IF base.Length#0 THEN sub _ base.Cat["/", sub]; RETURN}; statVerts: PUBLIC Colls.Space ~ NEW [Colls.SpacePrivate _ [ Equal: StatVertsEqual, Hash: HashStatVert, Compare: CompareStatVerts, other: List.PutAssoc[$Name, "stat verts", NIL] ]]; StatVertsEqual: PROC [data, elt1, elt2: REF ANY] RETURNS [BOOL] ~ { RETURN [CompareStatVerts[data, elt1, elt2]=equal]}; HashStatVert: PROC [data, elt: REF ANY] RETURNS [CARDINAL] ~ { sv: StatVertex ~ NARROW[elt]; RETURN [Colls.HashRefI[sv.port] + Colls.HashIntI[sv.phase[Foo]]*137 + Colls.HashIntI[sv.phase[Bar]]]}; CompareStatVerts: PROC [data, elt1, elt2: REF ANY] RETURNS [c: Basics.Comparison] ~ { sv1: StatVertex ~ NARROW[elt1]; sv2: StatVertex ~ NARROW[elt2]; IF (c _ Colls.CompareRefI[sv1.port, sv2.port]) = equal THEN IF (c _ Colls.CompareIntI[sv1.phase[Foo], sv2.phase[Foo]]) = equal THEN c _ Colls.CompareIntI[sv1.phase[Bar], sv2.phase[Bar]]; RETURN}; portsAtIndices: PUBLIC Colls.Space ~ NEW [Colls.SpacePrivate _ [ Equal: PortAtIndexEqual, Hash: HashPortAtIndex, Compare: ComparePortAtIndex, other: List.PutAssoc[$Name, "ports at indices", NIL] ]]; PortAtIndexEqual: PROC [data, elt1, elt2: REF ANY] RETURNS [BOOL] ~ { RETURN [ComparePortAtIndex[data, elt1, elt2]=equal]}; HashPortAtIndex: PROC [data, elt: REF ANY] RETURNS [CARDINAL] ~ { pai: PortAtIndex ~ NARROW[elt]; RETURN [Colls.HashRefI[pai.port] + Colls.HashIntI[pai.ai[Foo]]*137 + Colls.HashIntI[pai.ai[Bar]]]}; ComparePortAtIndex: PROC [data, elt1, elt2: REF ANY] RETURNS [c: Basics.Comparison] ~ { pai1: PortAtIndex ~ NARROW[elt1]; pai2: PortAtIndex ~ NARROW[elt2]; IF (c _ Colls.CompareRefI[pai1.port, pai2.port]) = equal THEN IF (c _ Colls.CompareIntI[pai1.ai[Foo], pai2.ai[Foo]]) = equal THEN c _ Colls.CompareIntI[pai1.ai[Bar], pai2.ai[Bar]]; RETURN}; Range2Div: PUBLIC PROC [r: Range2, t, f: Nat2] RETURNS [rr: Range2] = { rr _ [ Foo: [ min: CeilDiv[r[Foo].min-f[Foo], t[Foo]], maxPlusOne: FloorDiv[r[Foo].maxPlusOne-1-f[Foo], t[Foo]] + 1], Bar: [ min: CeilDiv[r[Bar].min-f[Bar], t[Bar]], maxPlusOne: FloorDiv[r[Bar].maxPlusOne-1-f[Bar], t[Bar]] + 1]]; }; Range1Div: PUBLIC PROC [r: Range, t, f: NAT] RETURNS [rr: Range] = { rr _ [ min: CeilDiv[r.min-f, t], maxPlusOne: FloorDiv[r.maxPlusOne-1-f, t] + 1]; }; Range2MulA: PUBLIC PROC [r: Range2, t, f: Nat2] RETURNS [rr: Range2] = { rr _ [ Foo: [ min: r[Foo].min*t[Foo] + f[Foo], maxPlusOne: (r[Foo].maxPlusOne-1)*t[Foo] + 1 + f[Foo]], Bar: [ min: r[Bar].min*t[Bar] + f[Bar], maxPlusOne: (r[Bar].maxPlusOne-1)*t[Bar] + 1 + f[Bar]]]; }; Range2MulB: PUBLIC PROC [r: Range2, t, f: Nat2] RETURNS [rr: Range2] = { rr _ [ Foo: [ min: r[Foo].min*t[Foo] + f[Foo], maxPlusOne: r[Foo].maxPlusOne*t[Foo] + f[Foo]], Bar: [ min: r[Bar].min*t[Bar] + f[Bar], maxPlusOne: r[Bar].maxPlusOne*t[Bar] + f[Bar]]]; }; Range1MulB: PUBLIC PROC [r: Range, t, f: NAT] RETURNS [rr: Range] = { rr _ [ min: r.min*t + f, maxPlusOne: r.maxPlusOne*t + f]; }; Start: PROC ~ { FOR index: NATURAL IN [0 .. sublen) DO subs[index] _ Convert.RopeFromInt[index].Concat["/"]; ENDLOOP; RETURN}; Start[]; END. bLichenNewArrayImpl1.Mesa Last tweaked by Mike Spreitzer on October 20, 1987 8:17:37 pm PDT ส– "cedar" style˜code™K™A—K˜Kšฯk œ{˜„K˜šฯnœœ˜"Kšœ`˜gKšœ&˜-K˜—K˜Kšœœ7ž œžœ ˜nK˜Kšœœ˜(K˜šžœœœ/œ ˜]Kšœ#˜#šœ œ˜ K˜Kšœ œ˜Kšœ œ˜K˜ K˜Kšœ˜Kšœœ˜ Kšœ˜K˜—Kšœ˜ —K˜šž œœœœ˜4šœœ˜K˜šœ ˜ Kš œ(œœœœ˜TKš œ(œœœœ˜S—K˜—Kšœ˜—K˜Kšœ œœ˜K˜šžœœœA˜dK˜Kšœk˜kK˜*Kšœœœ˜+Kš œœœœœœ˜5Kšœ œœฯcQœœ œœ˜ŽKšœœœ˜"šœฯgฯdœœœœœ กœœœ˜UKš œ  กœ กœ˜Kš œ œ˜/Kšœœ œ˜6Kšœœ œ˜6Kšœœ' œ œœ#œœ œ ˜‡K˜ Kšœœ˜—Kšœ˜—K˜šž œœœ%œ˜WKšœœ˜!Kšœ œœ ˜8Kšœ œœ ˜6Kšœœœœ˜&Kšœ˜—K˜š žœœœ4œœ œ˜tKšœ Ÿœ'˜BKšœ Ÿœ'˜FKšœœ ˜*Kšœ œ˜Kšœ$˜$Kš œœœ  œœœ˜XKš œœœœœœ˜Wšœœ˜Kšœœ˜,Kšœœœœ˜"Kš œœœ œœœ˜CKšœœA˜Vš žœœœœœ˜:Kš  œ œœ œœ  œ˜-Kšœ" œ˜%Kšœ œœœ/˜uKšœœ˜—Kšœ0˜0Kšœœ˜ —Kšœœ˜—K˜šž œœœ%œ˜Yš žœœœœœ˜:Kšœ)œœ œœœ œœ  œ˜i—Kšœ#œ˜8Kšœ˜—K˜šžœœœ˜?K˜šœœ˜'Kšœ ˜ Kšœ-œ˜4Kšœ*œ˜/K˜—šž œœœœ˜#Kšœœ˜K˜Kšœ˜—Kšœœœ˜+Kšœ˜Kšœ œœœ˜K˜Kšœ'˜'Kšœ˜—K˜šž œœœ*œ˜JK˜Kš œœœœœœ˜OKšœ˜K˜Kšœ$˜$Kšœ˜—K˜šžœœ˜2Kšœœ˜Kšœœ˜Kšœe œ˜jKšœ<œ ˜JKšœ ŸะcmŸœœ˜?Kšœ ŸขŸœœ˜?šœกœœœ/œœกœœœ/˜˜ Kšœกœœ ˜-Kšœกœœ˜.—Kšœ œ˜%Kšœ.˜.Kšœ.˜.Kšœœ ˜&Kšœœ ˜&š œ œœœœ˜"šœœ˜/Kšœ*œ˜1Kšœ2œ˜9K˜—Kšœœœœ˜/K˜Kšœ˜—Kšœœœœ˜1Kšœœœœ˜1Kšœ˜ Kšœ˜Kšœœ˜—Kšœ˜—K˜šž œœ:˜JKšœ,˜,Kšœ ŸขŸœœ˜MKšœ ŸขŸ œœ˜NKšœœœ5œ˜NKšœ˜Kšœ œ˜Kšœ˜—K˜šž œœ&˜9šžœœ˜(Kšœ œ ˜Kšœ ŸขŸ œœ%˜[Kšœœ˜%Kšœœ˜0šœœœ˜Kšœ ˜ šœœ˜0Kšœ œ˜"Kšœ˜—K˜—šœ˜šœœ˜0šœ œ˜Kšœ œ˜Kšœ˜—Kšœ˜—K˜—Kšœ˜—šž œœœœ˜"Kšœ œ˜K˜*Kšœ˜—Kšœœ"œœ˜3K˜KšœB˜BKšœ˜—K˜š ž œœœœ ŸขŸœ˜dKšœœ&˜2KšœœœœC˜]Kšœ˜—K˜šž œœœ&œ˜XKšœ,˜,šžœœ œ˜0Kšœ ŸขŸœœ˜>Kšœœœœ ˜&Kšœœœœ˜šœœ˜$Kšœœ ˜(Kšœœœœ˜/Kšœ˜—Kšœ˜—Kšœœœ˜(Kšœ ˜—K˜šž œœœ˜OKšœœ ˜,Kšœœœœ˜šœ%œ˜DKšœ*œ˜1Kšœ ˜ —Kšœ˜—K˜š žœœœ2œœ˜gKšœ)˜)Kšœ)˜)Kšœœœ˜(Kšœ œœ˜—K˜š žœœœžœœ ˜VKšœŸœ˜6šžœœ˜ Kšœ*˜*Kšœ˜—šžœœ œœ˜,Kšœœ ˜)Kšœœ˜—Kšœœœ˜(Kšœ*˜*Kšœ˜—K˜š žœœœžœœ˜YKšœŸœ˜9šžœœžœœ˜5Kšœ ŸขŸœœ(˜ašœœœ˜šœœ˜0Kšœœ ˜#Kšœœ ˜)Kšœ˜—K˜—šœ œ˜šœ˜šžœœ˜!Kšœ2˜2K˜Kšœ˜—K˜K˜—Kšœœ˜Kšœœ˜—Kšœ˜—Kšœœœ˜(Kšœ˜Kšœ˜—K˜šžœœœžœœœœœ œ˜šžœœžœœœœœ œ˜cšœœ˜šœ˜š žœœœœœ˜FKšœ œ ˜ Kšœœ ˜&Kšœ˜—Kšœ%˜%Kšœ˜—šœ˜Kšœœ˜$š žœœœœœ˜>Kšœ$˜$Kšœœ ˜(Kšœ˜—Kšœ-˜-Kšœ˜—Kšœœ˜—K˜—Kšœ˜—K˜šžœœœ$œ˜ašœœ˜šœ˜Kšœ ŸขŸ œœ˜Nšœœœ˜$Kšœ œœ˜-Kšœ˜—Kšœœ˜—Kšœœ)œ ˜XKšœœ˜—Kšœ˜—K˜šžœœœžœœœœœ œ˜ฎšœœ˜šœ˜šžœœœœ˜=Kšœ œ ˜Kšœ ŸขŸ œœ˜Dšœœœœœœœ˜IKšœ0˜0šœ œœ˜.Kšœœ˜"—Kšœœ˜—Kšœœ˜—Kšœ$˜$Kšœ˜—šœ˜Kšœœ˜$šžœœœœ˜@K˜"Kšœœ˜3Kšœ˜—KšœA˜AKšœ˜—Kšœœ˜—Kšœ˜—K˜šžœœœ žœœœœœ œœœ˜ˆKšœ Ÿœ"˜<šžœœœœ˜Kšœœ˜Kšœœœ œœ œ œœ˜cKšœœœ œœ œ œ˜XKšœ˜—Kšœ#˜#Kšœ˜—K˜šžœœœ!žœœœœœœ œœœœœ˜บšœœœ˜Kšœœœ˜š žœœœœœœ˜5Kšœœ˜Kšœ$œ˜5Kšœ˜—KšœK˜KKš œ œœœœ˜;Kšœ˜—Kšœ˜—K˜š žœœœ6œœ˜yK˜Kšœ)˜)Kšœœœ˜(KšœœœœœŸ?œœœœ˜wKšœ Ÿœ.˜JKš œœ œœœ˜;Kš œœœœœ˜ Kšœ]˜]KšœEœ˜\Kšœ.˜.Kšœ˜ —K˜šžœœœ˜4Kšœ˜—K˜š žœœœœœ˜=Kšœœœ˜—K˜šž œœœ˜HKšœœœ!˜1—K˜šž œœ&œ˜OKšœœ˜Kšœ˜$—K˜šž œœœœ˜Mšœœ˜Kšœœœ˜4Kšœœœ˜4Kšœœœ*˜A—K˜—K˜š žœœœœ œ˜Nšœ œœ˜Kšœœ˜-Kšœœ˜-Kšœœ ˜"—K˜—K˜Kšœœ˜Kš œœœœœœ˜-K˜šž œœœœ œœœ˜GKšœœœœ.˜aKšœœ˜/Kšœ˜—K˜Kšœ œ˜KšœD˜DKšœ'˜'Kšœœ˜K˜šžœœœœœœŸœ˜GKšœœœ˜!K˜(K˜(K˜FKšœ˜K˜—K˜šžœœ œœœœŸœ˜IKšœœœ˜"Kšœœœ˜"Kšœ˜—K˜š ž œœœœœœ˜OKšœœœ˜/Kšœœ˜ Kšœœ˜ Kšœ"˜"Kšœ˜šœœ˜Kšœa˜aKšœ˜Kšœ˜—Kšœœ ˜Kšœœ˜/Kšœ˜—K˜šœ œœ˜;Kšžœ˜Kšžœ˜Kšžœ˜Kšœ*œ˜.K˜—K˜š žœœœœœœ˜CKšœ-˜3—K˜š ž œœ œœœœ˜>Kšœœ˜Kšœ`˜f—K˜š žœœœœœ˜UKšœœ˜Kšœœ˜Kšœ5œœAœ7˜บKšœ˜—K˜šœœœ˜@Kšžœ˜Kšžœ˜Kšžœ˜Kšœ0œ˜4K˜—K˜š žœœœœœœ˜EKšœ/˜5—K˜š žœœ œœœœ˜AKšœœ˜Kšœ]˜c—K˜š žœœœœœ˜WKšœœ˜!Kšœœ˜!Kšœ7œœ=œ3˜ดKšœ˜—K˜š ž œœœ  œ œœ˜G˜˜Kšœ œ œ˜(Kšœ) œ œ ˜>—˜Kšœ œ œ˜(Kšœ) œ œ ˜?——K˜—K˜šž œœœ  œ œœœ˜D˜Kšœ œ œ˜Kšœ$ œ œ˜/—K˜—K˜š ž œœœ  œ œœ˜H˜˜Kšœ œ œ˜ Kšœ" œ  œ˜7—˜Kšœ œ œ˜ Kšœ" œ  œ˜8——K˜—K˜š ž œœœ  œ œœ˜H˜˜Kšœ œ œ˜ Kšœ œ œ˜/—˜Kšœ œ œ˜ Kšœ œ œ˜0——K˜—K˜šž œœœ  œ œœœ˜E˜Kšœ  œ œ˜Kšœ œ œ˜ —K˜—K˜šžœœ˜šœœœ˜&Kšœ5˜5Kšœ˜—Kšœ˜—K˜K˜K˜Kšœ˜—…—Jˆd