DIRECTORY OrderedSymbolTableRef USING [Table, CompareProc, Insert, CreateTable, DestroyTable, EnumerateIncreasing, LookupSmallest, LookupNextLarger, DeleteAllItems, Size], IPParams, Misc, IPCoTab, IPCTG, IPCoVerifier, IPCTGMaker; IPCTGMakerImpl: CEDAR PROGRAM IMPORTS OrderedSymbolTableRef, Misc, IPParams, IPCTG, IPCoTab, IPCoVerifier EXPORTS IPCTGMaker = BEGIN OPEN IPCTGMaker; Create: PUBLIC PROC[] RETURNS[Ref]= { RETURN [NEW[Rep _ [comps:, horPreChs: OrderedSymbolTableRef.CreateTable[preChCompareProc], verPreChs: OrderedSymbolTableRef.CreateTable[preChCompareProc], xMin:, yMin:, xMax:, yMax:]]]}; --Create -- Destroy: PUBLIC PROC [r: Ref]= { DeletePreChs[r]; r.horPreChs.DestroyTable[]; r.verPreChs.DestroyTable[]; }; --Destroy -- ConstructCTG: PUBLIC PROC[r: Ref, cV: IPCoVerifier.Ref, chWidth: INT _ IPParams.ChDefaultWidth, yPrimary, maxChWidth: BOOL _ TRUE] RETURNS[needGeom: BOOL _ FALSE, ctg: IPCTG.Ref]= { preChs: OrderedSymbolTableRef.Table; mPreCh: PreCh _ NIL; wSpan: Misc.Interval _ IF yPrimary THEN cV.GetBRect.x ELSE cV.GetBRect.y; cl: Clusters _ ClCreate[]; primClCnt: NAT; chWidth _ chWidth.SUCC; --***Added to allow chWidth = 0*** AcceptCoVerifier[r, cV, chWidth]; preChs _ IF yPrimary THEN r.horPreChs ELSE r.verPreChs; WHILE (mPreCh _ GetNextPreCh[preChs, mPreCh]) # NIL DO mWind: Misc.Window _ Misc.WindCreate[wSpan.min, wSpan.max]; mRange: Misc.Interval _ mPreCh.range; mSpan: Misc.Interval _ mPreCh.span; tPreCh: PreCh _ GetNextPreCh[preChs, mPreCh]; tSpan: Misc.Interval; cluster: LIST OF PreCh _ NIL; IF mPreCh.posComp THEN { IF mPreCh.cluster = 0 THEN ERROR ELSE LOOP}; --%Debugging%-- WHILE tPreCh # NIL DO { IF mWind.WindCurtainsCoverIntl[mSpan] THEN EXIT; tSpan _ tPreCh.span; IF (NOT tPreCh.posComp) OR mSpan.IntlIntersect[tSpan] = NIL THEN GOTO nextTest; IF mWind.WindPassesIntl[tSpan] OR mRange.IntlContainPt[tPreCh.coord] THEN {cluster _ CONS[tPreCh, cluster]; mRange _ mRange.IntlIntersect[tPreCh.range]} ELSE GOTO nextTest; IF mRange.IntlOneOf = interval THEN GOTO nextTest; --%Debugging%-- ERROR; EXITS nextTest => {mWind.WindAddCurtain[tSpan]; tPreCh _ GetNextPreCh[preChs, tPreCh]}} ENDLOOP; ClClusterize[cl, mPreCh, cluster]; ENDLOOP; primClCnt _ cl.count; FOR i: NAT IN [1..primClCnt] DO mCl: Cluster _ cl.clusters[i]; nPs: LIST OF PreCh; pPs: LIST OF PreCh; IF mCl = NIL THEN LOOP; nPs _ mCl.negPreChs; pPs _ mCl.posPreChs; mCl.negBndCl _ ClMerge2[cl, nPs.first.negBnd, pPs.first.negBnd]; IF cl.clusters[mCl.negBndCl].range.IntlOneOf # interval THEN needGeom _ TRUE; IF nPs.first.negBnd.posComp # pPs.first.negBnd.posComp THEN { negP: PreCh _ nPs.first; posP: PreCh _ pPs.first; IF negP.negBnd.negBnd = negP AND posP.negBnd.negBnd = posP THEN { cl.clusters[mCl.negBndCl].negBndCl _ i; GOTO ok;}; IF negP.negBnd.posBnd = negP AND posP.negBnd.posBnd = posP THEN { cl.clusters[mCl.negBndCl].posBndCl _ i; GOTO ok;}; ERROR; -- %Shouldn't Happen%-- EXITS ok => NULL;}; DO IF nPs.rest = NIL THEN EXIT; cl.clusters[ClMerge2[cl, nPs.first.posBnd, nPs.rest.first.negBnd]].posBndCl _ i; nPs _ nPs.rest; ENDLOOP; DO IF pPs.rest = NIL THEN EXIT; cl.clusters[ClMerge2[cl, pPs.first.posBnd, pPs.rest.first.negBnd]].negBndCl _ i; pPs _ pPs.rest; ENDLOOP; mCl.posBndCl _ ClMerge2[cl, nPs.first.posBnd, pPs.first.posBnd]; IF cl.clusters[mCl.posBndCl].range.IntlOneOf # interval THEN {needGeom _ TRUE}; IF nPs.first.posBnd.posComp # pPs.first.posBnd.posComp THEN { negP: PreCh _ nPs.first; posP: PreCh _ pPs.first; IF negP.posBnd.negBnd = negP AND posP.posBnd.negBnd = posP THEN { cl.clusters[mCl.posBndCl].negBndCl _ i; GOTO ok;}; IF negP.posBnd.posBnd = negP AND posP.posBnd.posBnd = posP THEN { cl.clusters[mCl.posBndCl].posBndCl _ i; GOTO ok;}; ERROR; -- %Shouldn't Happen%-- EXITS ok => NULL;}; ENDLOOP; chWidth _ chWidth.PRED; ctg _ ClToCTG[cl, chWidth, maxChWidth]; FOR indx: NAT IN [1..r.comps.count] DO InsertComp[r.comps.compItems[indx], cl] ENDLOOP; }; -- ConstructCTG-- PosInfinity: INT = LAST[INT]; NegInfinity: INT = FIRST[INT]; preChCompareProc: OrderedSymbolTableRef.CompareProc ={ p1: PreCh _ NARROW[r1]; p2: PreCh _ NARROW[r2]; IF p1 = p2 THEN RETURN [equal]; IF p1.coord> p2.coord THEN RETURN [greater]; IF p1.coord < p2.coord THEN RETURN [less]; IF p1.negBnd.coord > p2.negBnd.coord THEN RETURN [greater]; IF p1.negBnd.coord < p2.negBnd.coord THEN RETURN [less]; ERROR; --%Shouldnt Happen%-- }; --preChCompareProc-- AcceptCoVerifier: PROC[r: Ref, cV: IPCoVerifier.Ref, chWidth: INT]= { OPEN rc: r.comps; aP: IPCoVerifier.EachCompItemAction ={ quit _ FALSE; rc.compItems[(rc.count _ rc.count + 1)] _ NEW[CompItemRep _ [cI.comp]]; AcceptCompItem[r, cI, rc.count]}; --aP-- DeletePreChs[r]; r.comps _ NEW[CompItemsRep]; AcceptBRect[r, cV.GetBRect, chWidth]; cV.CompItems[aP]; }; --AcceptCoVerifier -- DeletePreChs: PROC[r: Ref] ={ preChList: LIST OF PreCh _ NIL; p: PROC[i: REF] RETURNS[BOOL] ={pCh: PreCh _ NARROW[i]; preChList _ CONS[pCh, preChList]; RETURN [FALSE]}; --p-- IF r.horPreChs.Size < r.verPreChs.Size THEN {r.horPreChs.EnumerateIncreasing[p]} ELSE {r.verPreChs.EnumerateIncreasing[p]}; WHILE preChList # NIL DO PreChSetBnds[preChList.first, NIL, NIL]; preChList _ preChList.rest; ENDLOOP;r.comps _ NIL; r.horPreChs.DeleteAllItems[]; r.verPreChs.DeleteAllItems[]; }; --DeletePreChs-- AcceptBRect: PROC[r: Ref, bRect: Misc.Rect, margin: INT] ={ I: PROC[min, max: INT] RETURNS[Misc.Interval] = Misc.IntlCreate; south, east, north, west: PreCh; r.xMin _ bRect.xMin - margin; r.yMin _ bRect.yMin - margin; r.xMax _ bRect.xMax + margin; r.yMax _ bRect.yMax + margin; south _ NewPreCh[hor, FALSE, r.yMin, I[r.xMin, r.xMax], I[r.yMin, PosInfinity], NIL]; east _ NewPreCh[ver, TRUE, r.xMax, I[r.yMin, r.yMax], I[NegInfinity, r.xMax], NIL]; north _ NewPreCh[hor, TRUE, r.yMax, I[r.xMin, r.xMax], I[NegInfinity, r.yMax], NIL]; west _ NewPreCh[ver, FALSE, r.xMin, I[r.yMin, r.yMax], I[r.xMin, PosInfinity], NIL]; PreChSetBnds[south, west, east]; PreChSetBnds[east, south, north]; PreChSetBnds[north, west, east]; PreChSetBnds[west, south, north]; InsertPreCh[r, south]; InsertPreCh[r, east]; InsertPreCh[r, north]; InsertPreCh[r, west]; }; --AcceptBRect-- AcceptCompItem: PROC[r: Ref, cI: IPCoVerifier.CompItem, compIndex: CompItemIndices] ={ OPEN h: cI.hint; I: PROC[min, max: INT] RETURNS[Misc.Interval] = Misc.IntlCreate; co: IPCoTab.Component _ cI.comp; south, east, north, west: PreCh; swC, seC, neC, nwC: CornerPreChs _ NIL; bR, swR0, seR0, neR0, nwR0, swR1, seR1, neR1, nwR1: Misc.Rect; southSpan, eastSpan, northSpan, westSpan: Misc.Interval; epsilon: NAT _ 1; --This has very subtle effects-- hC, vC: PreCh; bR _ IPCoTab.GetBRect[co]; [swR0, seR0, neR0, nwR0] _ IPCoTab.GetCornerRects[co, 0]; [swR1, seR1, neR1, nwR1] _ IPCoTab.GetCornerRects[co, 1]; southSpan _ northSpan _ bR.x; eastSpan _ westSpan _ bR.y; IF h.sw THEN {southSpan _ southSpan.IntlSubtract[swR1.x]; westSpan _ westSpan.IntlSubtract[swR1.y]}; IF h.se THEN {southSpan _ southSpan.IntlSubtract[seR1.x]; eastSpan _ eastSpan.IntlSubtract[seR1.y]}; IF h.ne THEN {northSpan _ northSpan.IntlSubtract[neR1.x]; eastSpan _ eastSpan.IntlSubtract[neR1.y]}; IF h.nw THEN {northSpan _ northSpan.IntlSubtract[nwR1.x]; westSpan _ westSpan.IntlSubtract[nwR1.y]}; south _ NewPreCh[hor, TRUE, bR.yMin, southSpan, I[NegInfinity, bR.yMin], co]; east _ NewPreCh[ver,FALSE,bR.xMax, eastSpan, I[bR.xMax, PosInfinity], co]; north _ NewPreCh[hor, FALSE, bR.yMax, northSpan, I[bR.yMax, PosInfinity], co]; west _ NewPreCh[ver, TRUE, bR.xMin, westSpan, I[NegInfinity, bR.xMin], co]; IF h.sw THEN { hC _ NewPreCh[hor, TRUE, swR0.yMax, swR1.x, swR0.y, co]; vC _ NewPreCh[ver, TRUE, swR0.xMax, swR1.y, swR0.x,co]; PreChSetBnds[hC, west, vC]; PreChSetBnds[vC, south, hC]; swC _ NEW[CornerPreChsRep _[hor: hC, ver: vC]]; InsertPreCh[r, hC]; InsertPreCh[r, vC];}; IF h.se THEN { hC _ NewPreCh[hor, TRUE, seR0.yMax, seR1.x, seR0.y, co]; vC _ NewPreCh[ver, FALSE, seR0.xMin, seR1.y, seR0.x, co]; PreChSetBnds[hC, vC, east]; PreChSetBnds[vC, south, hC]; seC _ NEW[CornerPreChsRep _[hor: hC, ver: vC]]; InsertPreCh[r, hC]; InsertPreCh[r, vC];}; IF h.ne THEN { hC _ NewPreCh[hor, FALSE, neR0.yMin, neR1.x, neR0.y, co]; vC _ NewPreCh[ver, FALSE, neR0.xMin, neR1.y, neR0.x, co]; PreChSetBnds[hC, vC, east]; PreChSetBnds[vC, hC, north]; neC _ NEW[CornerPreChsRep _[hor: hC, ver: vC]]; InsertPreCh[r, hC]; InsertPreCh[r, vC];}; IF h.nw THEN { hC _ NewPreCh[hor, FALSE, nwR0.yMin, nwR1.x, nwR0.y,co]; vC _ NewPreCh[ver, TRUE, nwR0.xMax, nwR1.y, nwR0.x, co]; PreChSetBnds[hC, west, vC]; PreChSetBnds[vC, hC, north]; nwC _ NEW[CornerPreChsRep _[hor: hC, ver: vC]]; InsertPreCh[r, hC]; InsertPreCh[r, vC];}; PreChSetBnds[south, (IF h.sw THEN swC.ver ELSE west), (IF h.se THEN seC.ver ELSE east)]; PreChSetBnds[east, (IF h.se THEN seC.hor ELSE south), (IF h.ne THEN neC.hor ELSE north)]; PreChSetBnds[north, (IF h.nw THEN nwC.ver ELSE west), (IF h.ne THEN neC.ver ELSE east)]; PreChSetBnds[west, (IF h.sw THEN swC.hor ELSE south), (IF h.nw THEN nwC.hor ELSE north)]; r.comps.compItems[compIndex].prinPreChs _ [south: south, east: east, north: north, west: west]; r.comps.compItems[compIndex].cornerPreChs _ [sw: swC, se: seC, ne: neC, nw: nwC]; InsertPreCh[r, south]; InsertPreCh[r, east]; InsertPreCh[r, north]; InsertPreCh[r, west]; };--AcceptCompItem-- NewPreCh: PROC[type: IPCTG.ChType, posComp: BOOL, coord: INT, span, range: Misc.Interval, comp: IPCoTab.Component] RETURNS [PreCh] ={ RETURN [NEW[PreChRep _ [type, posComp, coord, span, range, comp]]]; }; --NewPreCh-- InsertPreCh: PROC[r: Ref, p: PreCh] ={ SELECT p.type FROM hor => {r.horPreChs.Insert[p]}; ver => {r.verPreChs.Insert[p]}; ENDCASE => ERROR; }; --InsertPreCh-- GetNextPreCh: PROC[tab: OrderedSymbolTableRef.Table, p: PreCh] RETURNS [PreCh] ={ IF p = NIL THEN RETURN [NARROW[tab.LookupSmallest]] ELSE RETURN [NARROW[tab.LookupNextLarger[p]]]};--GetNextPreCh-- PreChSetBnds: PROC[p, negBnd, posBnd: PreCh] ={ IF negBnd # NIL AND negBnd.type = p.type THEN ERROR; IF posBnd # NIL AND posBnd.type = p.type THEN ERROR; p.negBnd _ negBnd; p.posBnd _ posBnd; }; --PreChSetBnds-- InsertComp: PROC[cI: CompItem, cl: Clusters] ={ OPEN p: cI.prinPreChs, cc: cI.cornerPreChs; swC, seC, neC, nwC: IPCoTab.CornerChannels _ NIL; IF cc.sw # NIL THEN swC _ NEW[IPCoTab.CornerChannelsRep _ [hor: ClGetCh[cl, cc.sw.hor], ver: ClGetCh[cl, cc.sw.ver]]]; IF cc.se # NIL THEN seC _ NEW[IPCoTab.CornerChannelsRep _ [hor: ClGetCh[cl, cc.se.hor], ver:ClGetCh[cl, cc.se.ver]]]; IF cc.ne # NIL THEN neC _ NEW[IPCoTab.CornerChannelsRep _ [hor: ClGetCh[cl, cc.ne.hor], ver:ClGetCh[cl, cc.ne.ver]]]; IF cc.nw # NIL THEN nwC _ NEW[IPCoTab.CornerChannelsRep _ [hor: ClGetCh[cl, cc.nw.hor], ver:ClGetCh[cl, cc.nw.ver]]]; IPCoTab.InsertComponent[cI.co, ClGetCh[cl, p.south], ClGetCh[cl, p.east], ClGetCh[cl, p.north], ClGetCh[cl, p.west], swC, seC, neC, nwC] }; --InsertComp-- Clusters: TYPE = REF ClustersRep; ClustersRep: TYPE = RECORD[count: NAT _ 0, clusters: ARRAY ClusterIndices OF Cluster _ ALL[NIL]]; Cluster: TYPE = REF ClusterRep; ClusterRep: TYPE = RECORD[type: IPCTG.ChType, range: Misc.Interval, negPreChs, posPreChs: LIST OF PreCh _ NIL, negBndCl, posBndCl: NAT _ 0, ch: IPCTG.Channel _ NIL, primOrdering: INT]; ClusterIndices: TYPE = [1..MaxClusterCnt]; ClCreate: PROC RETURNS [Clusters] ={RETURN [NEW[ClustersRep]]}; --ClCreate-- ClNewCluster: PROC[cl: Clusters, type: IPCTG.ChType, range: Misc.Interval, order: INT _ FIRST[INT]] RETURNS [ClusterIndices] ={ cl.clusters[(cl.count _ cl.count + 1)] _ NEW[ClusterRep _[type: type, range: range, primOrdering: order]]; RETURN [cl.count]}; --ClNewCluster-- ClClusterize: PROC[cl: Clusters, pCh: PreCh, lp: LIST OF PreCh] ={ cIndex: NAT _ 0; FOR l: LIST OF PreCh _ lp, l.rest UNTIL l = NIL DO cIndex _ MAX[cIndex, l.first.cluster]; ENDLOOP; IF cIndex = 0 OR cl.clusters[cIndex].primOrdering < pCh.range.min THEN {cIndex _ ClNewCluster[cl, pCh.type, pCh.range, pCh.range.min]}; ClAddPreCh[cl, cIndex, pCh]; FOR l: LIST OF PreCh _ lp, l.rest UNTIL l = NIL DO IF l.first.cluster = cIndex THEN LOOP; IF l.first.cluster = 0 THEN {ClAddPreCh[cl, cIndex, l.first]} ELSE {ClMergeClusterInto[cl, l.first.cluster, cIndex]}; ENDLOOP; IF cl.clusters[cIndex].range.IntlOneOf # interval THEN ERROR; -- %Debugging%-- }; --ClClusterize-- ClMerge2: PROC[cl: Clusters, p1, p2: PreCh] RETURNS [ClusterIndices] ={ nCl: NAT; IF p1.type # p2.type THEN ERROR; IF p1.cluster # 0 AND p2.cluster # 0 THEN { IF p1.cluster = p2.cluster THEN RETURN[p1.cluster] ELSE ERROR}; -- %Shouldnt Happen%-- nCl _ MAX[p1.cluster, p2.cluster]; IF nCl = 0 THEN nCl _ ClNewCluster[cl, p1.type, p1.range]; ClAddPreCh[cl, nCl, p1]; ClAddPreCh[cl, nCl, p2]; RETURN [nCl] };--ClMerge2-- ClMergeClusterInto: PROC[cl: Clusters, from, into: ClusterIndices] ={ fCl: Cluster _ cl.clusters[from]; FOR l: LIST OF PreCh _ fCl.negPreChs, l.rest UNTIL l = NIL DO ClAddPreCh[cl, into, l.first]; ENDLOOP; FOR l: LIST OF PreCh _ fCl.posPreChs, l.rest UNTIL l = NIL DO ClAddPreCh[cl, into, l.first]; ENDLOOP; cl.clusters[from] _ NIL; };--ClMergeClusterInto-- ClAddPreCh: PROC[cl: Clusters, i: ClusterIndices, pCh: PreCh] ={ chList: LIST OF PreCh; pLess: PROC[p1, p2: PreCh] RETURNS [BOOL] = { RETURN [p1.negBnd.coord < p2.negBnd.coord] };--pLess-- IF cl.clusters[i].type # pCh.type THEN ERROR; IF pCh.cluster = i THEN RETURN; pCh.cluster _ i; cl.clusters[i].range_ cl.clusters[i].range.IntlIntersect[pCh.range]; IF pCh.posComp THEN {IF (chList _ cl.clusters[i].posPreChs) = NIL OR pLess[pCh, chList.first] THEN {cl.clusters[i].posPreChs _ CONS[pCh, chList]; RETURN}} ELSE {IF (chList _ cl.clusters[i].negPreChs) = NIL OR pLess[pCh, chList.first] THEN {cl.clusters[i].negPreChs _ CONS[pCh, chList]; RETURN}}; FOR l: LIST OF PreCh _ chList, l.rest DO IF l.rest = NIL THEN {l.rest _ LIST[pCh]; EXIT}; IF pLess[pCh, l.rest.first] THEN {l.rest _ CONS[pCh, l.rest]; EXIT} ENDLOOP; };--ClAddPreCh-- ClGetCh: PROC[cl: Clusters, p: PreCh] RETURNS [IPCTG.Channel] ={ RETURN [cl.clusters[p.cluster].ch]}; --ClGetCh-- ClToCTG: PROC[cl: Clusters, chWidth: INT, maxChWidth: BOOL] RETURNS [IPCTG.Ref] ={ ctg: IPCTG.Ref _ IPCTG.Create[]; makeCh: PROC[c: Cluster] ={ r: Misc.Interval _ c.range; width: INT _ IF maxChWidth THEN MAX[r.IntlLength, chWidth] ELSE chWidth; coord: INT _ IF r = NIL THEN (c.negPreChs.first.coord + c.posPreChs.first.coord)/2 ELSE (r.min + r.max)/2; c.ch _ ctg.CreateChannel[c.type, width, coord]; }; --makeCh-- makeChBoundary: PROC[index: ClusterIndices] ={ c: Cluster _ cl.clusters[index]; eP: PROC [end: {neg, pos}] RETURNS [IPCTG.Intersection] ={ ch: IPCTG.Channel; iType: IPCTG.IntersectionType; ch _ SELECT end FROM neg => cl.clusters[c.negBndCl].ch, pos => cl.clusters[c.posBndCl].ch, ENDCASE => ERROR; SELECT end FROM neg => {SELECT index FROM cl.clusters[c.negBndCl].posBndCl => iType _ -1; cl.clusters[c.negBndCl].negBndCl => iType _ 1; ENDCASE => iType _ 0;}; pos => {SELECT index FROM cl.clusters[c.posBndCl].posBndCl => iType _ -1; cl.clusters[c.posBndCl].negBndCl => iType _ 1; ENDCASE => iType _ 0;}; ENDCASE => ERROR; RETURN [IPCTG.NewIn[ch: ch, type: iType]] }; --eP-- sP: PROC [side: {neg, pos}] RETURNS [LIST OF IPCTG.Intersection] ={ iListHd, iListTl: LIST OF IPCTG.Intersection; iType: IPCTG.IntersectionType _ (SELECT side FROM neg => -1, pos => 1, ENDCASE => ERROR); iListHd _ iListTl _ CONS[NIL, NIL]; FOR pChs: LIST OF PreCh _ (SELECT side FROM neg => c.negPreChs, pos => c.posPreChs, ENDCASE => ERROR), pChs.rest UNTIL pChs.rest = NIL DO ch: IPCTG.Channel _ cl.clusters[pChs.first.posBnd.cluster].ch; IF pChs.first.posBnd.cluster # pChs.rest.first.negBnd.cluster THEN ERROR; --%Debugging%-- iListTl.rest _ LIST[IPCTG.NewIn[ch: ch, type: iType]]; iListTl _ iListTl.rest ENDLOOP; RETURN [iListHd.rest]}; --sP-- IPCTG.SetBoundary[c.ch, eP[neg], eP[pos], sP[neg], sP[pos]] }; --makeChBoundary-- FOR i: NAT IN [1..cl.count] DO IF cl.clusters[i] # NIL THEN makeCh[cl.clusters[i]]; ENDLOOP; FOR i: NAT IN [1..cl.count] DO IF cl.clusters[i] # NIL THEN makeChBoundary[i]; ENDLOOP; RETURN [ctg]; }; --ClToCTG-- END. Œ-- File: IPCTGMakerImpl.mesa -- Last Edited by: CSChow, January 23, 1985 9:53:38 pm PST Preas, August 2, 1986 3:04:13 pm PDT changed definition of ConstructCTG, AcceptCoVerifier, AcceptBRect, ClToCTG November 30, 1987 2:42:26 pm PST --Documentation will come later after consolidating the design -- --This piece of code was written with the assumption that channels do not have zero width. --So all the error checkings '%Debugging%' and some internal routines uses that information. --But this assumption is no longer valid. An easy way out is by add the 2 lines below -- marked by: '***Added to allow chWidth = 0***' --This is not an efficient implement, a lot of design and efficiency improvements -- can be made to it. However it is ample for the size of problems we are -- dealing with and since it is only called once (ie. to enter the topological domain) -- the pay off is not great. But if it ever becomes necessary to increase the efficiency, -- I can give you a lot of pointers on how to do it. --CSChow: January 23, 1985 9:45:19 pm PST --The rest of the code can now proceed with chWidth > 0 --(0) Initialize the input- --(1) Form primary clusters-- --(2) Form secondary clusters-- ***Added to allow chWidth = 0*** -- Nullifies the effect eariler --########### Private procedures ###########-- --Operations on individual PreCh and CompItem-- -- ########## Cluster abstraction ########## -- Κ!I˜Jšœ™šœ:™:Icode™$KšœΟn4œ!™k—J™J™AJ˜šΟk ˜ Jšœžœ†˜‘Jšœ ˜ J˜Jšœ˜Jšžœ˜Jšœ ˜ Jšœ ˜ —J˜šœžœž˜Jšžœ'žœ˜KJšžœžœžœ ˜+J˜J™ZJšœΟc=™\JšœV™VJšœ0™0J™J™RJ™IJ™VJ™Z™4J™J™)—JšŸ™šœžœžœžœ˜%Kšžœžœ°Ÿ ˜Ζ—J˜šœžœžœ ˜ K– "Cedar" stylešœ˜K– "Cedar" stylešœ˜K– "Cedar" stylešœ˜JšœŸ ˜—J˜š œžœžœ(žœ2žœžœžœ žœžœžœ˜΅Kšœ%˜%Kšœžœ˜Kšœžœ žœžœ˜IJšœ˜Jšœ žœ˜J˜šœžœ˜JšŸ"˜"J™7—J™J™Jšœ!˜!J™Jšœ žœ žœ žœ ˜7šžœ+žœžœ˜8K– "Cedar" stylešœ;˜;K– "Cedar" style˜%K– "Cedar" style˜#K– "Cedar" stylešœ-˜-K– "Cedar" style˜K– "Cedar" stylešœ žœžœ žœ˜šžœžœ˜Kš žœžœžœžœžœŸ˜<—šžœ žœžœ˜Kšžœ$žœžœ˜0K˜Kš žœžœžœžœžœžœ ˜Ošžœžœ$˜EKšžœ žœ?˜SKšžœžœ ˜—Kšžœžœžœ Ÿ˜CKšžœ˜šž˜šœ*˜*Kšœ'˜'——Kšžœ˜—Kšœ"˜"Kšžœ˜—J˜Jšœ™J˜šžœžœžœž˜K˜Kšœžœžœ˜Kšœžœžœ˜K˜Kšžœžœžœžœ˜Kšœ˜Kšœ˜K˜@Kšžœ6žœ žœ˜Mšžœ5žœ˜=Kšœ˜Kšœ˜šžœžœžœ˜BKšœ'˜'Kšžœ˜ —šžœžœžœ˜AKšœ'˜'Kšžœ˜ —KšžœŸ˜šž˜Kšœžœ˜ ——šž˜Kšžœ žœžœžœ˜K˜PK˜Kšžœ˜—šž˜Kšžœ žœžœžœ˜K˜PKšœ˜Kšžœ˜—K˜@Kšžœ6žœ žœ˜Ošžœ5žœ˜=Kšœ˜Kšœ˜šžœžœžœ˜AKšœ'˜'Kšžœ˜ —šžœžœžœ˜AKšœ'˜'Kšžœ˜ —KšžœŸ˜šž˜Kšœžœ˜ ——Kšžœ˜—K˜šœžœ˜Kšœ ™ K™K™—Kšœ'˜'šžœžœžœž˜&Kšœ'˜'Kšžœ˜—JšœŸ˜—J˜J™.J™Jšœ žœžœžœ˜K– "Cedar" stylešœ žœžœžœ˜K– "Cedar" style˜– "Cedar" stylešœ6˜6K– "Cedar" stylešœ žœ˜K– "Cedar" stylešœ žœ˜K– "Cedar" stylešžœ žœžœ ˜K– "Cedar" stylešžœžœžœ ˜,K– "Cedar" stylešžœžœžœ˜*K– "Cedar" stylešžœ#žœžœ ˜;K– "Cedar" stylešžœ#žœžœ˜8K– "Cedar" stylešžœŸ˜K– "Cedar" stylešœŸ˜—J˜šœžœ(žœ˜EJšžœ ˜šœ&˜&Jšœžœ˜ Jšœ*žœ˜GJšœ"ŸœŸ˜(—J˜Jšœ žœ˜Jšœ%˜%J˜JšœŸœŸ˜—– "Cedar" styleš œžœ ˜Jšœ žœžœ žœ˜– "Cedar" styleš œžœžœžœžœžœ˜7K– "Cedar" stylešœ žœ˜!K– "Cedar" stylešžœžœŸ˜—šžœ%˜'K– "Cedar" stylešžœ%˜)K– "Cedar" stylešžœ&˜*—– "Cedar" stylešžœ žœž˜Kšœžœžœ˜(Kšœ˜Kšžœ žœ˜—Kšœ˜Kšœ˜JšœŸ˜—š œžœ#žœ˜;Jšžœžœ žœžœ"˜@K– "Cedar" style˜ K– "Cedar" stylešœ˜K– "Cedar" stylešœ˜K– "Cedar" stylešœ˜K– "Cedar" stylešœ˜K– "Cedar" styleš œžœ žœžœžœ˜UK– "Cedar" styleš œžœ žœžœžœ˜SK– "Cedar" styleš œžœ žœžœžœ˜TK– "Cedar" styleš œžœ žœžœžœ˜TK– "Cedar" stylešœ ˜ K– "Cedar" stylešœ!˜!K– "Cedar" stylešœ ˜ K– "Cedar" stylešœ!˜!K– "Cedar" style˜K– "Cedar" stylešœ˜K– "Cedar" stylešœ˜K– "Cedar" stylešœ˜K– "Cedar" stylešœŸœ˜—J˜šœžœB˜V– "Cedar" stylešžœ ˜K– "Cedar" stylešžœžœ žœžœ"˜@K– "Cedar" stylešœ ˜ K– "Cedar" style˜ K– "Cedar" stylešœ#žœ˜'K– "Cedar" style˜>K– "Cedar" style˜8K– "Cedar" stylešœ žœŸ ˜2K– "Cedar" style˜K– "Cedar" style˜K– "Cedar" stylešœ˜K– "Cedar" stylešœ9˜9K– "Cedar" stylešœ9˜9K– "Cedar" style˜K– "Cedar" style˜– "Cedar" stylešžœžœ.˜:K– "Cedar" stylešœ*˜*—– "Cedar" stylešžœžœ.˜:K– "Cedar" stylešœ*˜*—– "Cedar" stylešžœžœ.˜:K– "Cedar" stylešœ*˜*—– "Cedar" stylešžœžœ.˜:K– "Cedar" stylešœ*˜*—K– "Cedar" style˜K– "Cedar" stylešœžœžœ˜MK– "Cedar" stylešœžœžœ˜JK– "Cedar" stylešœžœžœ˜NK– "Cedar" stylešœžœžœ˜K– "Cedar" stylešžœžœ˜K– "Cedar" stylešœžœ!˜8K– "Cedar" stylešœžœ ˜7K– "Cedar" stylešœ˜K– "Cedar" stylešœ˜K– "Cedar" stylešœžœ&˜/K– "Cedar" stylešœ˜K– "Cedar" stylešœ˜—– "Cedar" stylešžœžœ˜K– "Cedar" stylešœžœ!˜8K– "Cedar" stylešœžœ!˜9K– "Cedar" stylešœ˜K– "Cedar" stylešœ˜K– "Cedar" stylešœžœ&˜/K– "Cedar" stylešœ˜K– "Cedar" stylešœ˜—– "Cedar" stylešžœžœ˜K– "Cedar" stylešœžœ!˜9K– "Cedar" stylešœžœ!˜9K– "Cedar" stylešœ˜K– "Cedar" stylešœ˜K– "Cedar" stylešœžœ&˜/K– "Cedar" stylešœ˜K– "Cedar" stylešœ˜—– "Cedar" stylešžœžœ˜K– "Cedar" stylešœžœ ˜8K– "Cedar" stylešœžœ!˜8K– "Cedar" stylešœ˜K– "Cedar" stylešœ˜K– "Cedar" stylešœžœ&˜/K– "Cedar" stylešœ˜K– "Cedar" stylešœ˜—K– "Cedar" styleš œžœžœ žœ žœžœ žœ˜XK– "Cedar" styleš œžœžœ žœ žœžœ žœ ˜YK– "Cedar" styleš œžœžœ žœ žœžœ žœ˜XK– "Cedar" styleš œžœžœ žœ žœžœ žœ ˜YK– "Cedar" stylešœ_˜_K– "Cedar" stylešœQ˜QK– "Cedar" style˜K– "Cedar" stylešœ˜K– "Cedar" stylešœ˜K– "Cedar" stylešœ˜K– "Cedar" stylešœŸ˜——J˜– "Cedar" styleš œžœžœžœ žœ7žœ ˜…K– "Cedar" stylešžœžœ8˜CK– "Cedar" stylešœŸ ˜—š œžœ˜&šžœž˜Kšœ˜Kšœ˜KšžœžœŸ˜$——– "Cedar" styleš œžœ-žœ ˜Q– "Cedar" stylešžœžœ˜ K– "Cedar" stylešžœžœžœ˜(K– "Cedar" stylešžœžœžœŸ˜?——K– "Cedar" stylešœ/™/K– "Cedar" style˜– "Cedar" styleš œžœ˜/K– "Cedar" styleš žœ žœžœžœžœ˜4K– "Cedar" styleš žœ žœžœžœžœ˜4K– "Cedar" stylešœ˜K– "Cedar" stylešœ˜K– "Cedar" stylešœŸœ˜—K– "Cedar" style™– "Cedar" styleš œžœ˜/šžœ'˜+Jšœ-žœ˜1Kšžœ žœžœžœY˜vKšžœ žœžœžœX˜uKšžœ žœžœžœX˜uKšžœ žœžœžœX˜uKšœˆ˜ˆKšœŸœ Ÿ˜——K– "Cedar" style™K– "Cedar" style˜K– "Cedar" style™0K– "Cedar" stylešœ žœžœ ˜!K– "Cedar" stylešœ žœžœžœžœžœ žœžœ˜aK– "Cedar" stylešœ žœžœ ˜K– "Cedar" stylešœ žœžœžœ5žœžœ žœžœ žœ žœžœ˜ΈK– "Cedar" stylešœžœ˜*K– "Cedar" style˜K– "Cedar" styleš œžœžœžœžœŸ ˜L– "Cedar" styleš œžœžœ&žœžœžœžœ˜€K– "Cedar" stylešœ*žœ>˜kK– "Cedar" stylešžœŸ˜$—– "Cedar" styleš œžœžœžœ ˜BK– "Cedar" stylešœžœ˜– "Cedar" styleš žœžœžœžœžœž˜2Kšœ žœ˜&Kšžœ˜—šžœ žœ3˜CKšžœA˜E—Kšœ˜– "Cedar" styleš žœžœžœžœžœž˜2Kšžœžœžœ˜&šžœ˜Kšžœ#˜'Kšžœ3˜7—Kšžœ˜—Kšžœ0žœžœŸ˜NKšœŸ˜—– "Cedar" stylešœžœžœ˜GK– "Cedar" stylešœžœ˜ K– "Cedar" stylešžœžœžœ˜"– "Cedar" stylešžœžœžœ˜+K– "Cedar" styleš žœžœžœ žœžœŸ˜V—K– "Cedar" stylešœžœ˜"K– "Cedar" stylešžœ žœ+˜:K– "Cedar" stylešœ˜K– "Cedar" stylešœ˜K– "Cedar" stylešžœ˜ K– "Cedar" stylešœŸ ˜—– "Cedar" stylešœžœ-˜EK– "Cedar" style˜!– "Cedar" styleš žœžœžœžœžœž˜=Kšœ˜Kšžœ˜—– "Cedar" styleš žœžœžœžœžœž˜=Kšœ˜Kšžœ˜—Kšœžœ˜K– "Cedar" stylešœŸ˜—– "Cedar" styleš œžœ0˜@K– "Cedar" stylešœžœžœ˜– "Cedar" stylešœžœžœžœ˜-K– "Cedar" stylešžœ$˜*K– "Cedar" stylešœŸ ˜ —K– "Cedar" stylešžœ!žœžœ˜.K– "Cedar" stylešžœžœžœ˜K– "Cedar" stylešœ˜K– "Cedar" stylešœD˜D– "Cedar" stylešžœ ˜K– "Cedar" stylešžœžœ'žœžœžœžœžœ˜‹K– "Cedar" stylešžœžœ'žœžœžœžœžœ˜Œ—– "Cedar" stylešžœžœžœž˜(K– "Cedar" styleš žœ žœžœ žœžœ˜0Kšžœžœ žœžœ˜CKšžœ˜—KšœŸ˜—– "Cedar" stylešœžœžœžœ ˜@K– "Cedar" stylešžœŸ ˜0—K– "Cedar" style˜– "Cedar" styleš œžœžœžœžœžœ˜RK– "Cedar" stylešœžœžœ ˜ – "Cedar" stylešœžœ˜K– "Cedar" style˜K– "Cedar" styleš œžœžœ žœžœžœ ˜H– "Cedar" stylešœžœžœžœ˜K– "Cedar" stylešžœ7˜;K– "Cedar" stylešžœ˜—K– "Cedar" stylešœ/˜/K– "Cedar" stylešœŸ ˜ —– "Cedar" stylešœžœ˜.K– "Cedar" stylešœ ˜ – "Cedar" stylešœžœžœžœ˜:K– "Cedar" stylešœžœ ˜K– "Cedar" stylešœžœ˜– "Cedar" stylešœžœžœ˜K– "Cedar" stylešœ#˜#K– "Cedar" stylešœ"˜"K– "Cedar" stylešžœžœ˜—– "Cedar" stylešžœž˜šœžœž˜K˜/K˜.Kšžœ˜—šœžœž˜K˜/K˜.Kšžœ˜—Kšžœžœ˜—K– "Cedar" stylešžœž œ˜)K– "Cedar" stylešœŸ˜ —– "Cedar" styleš œžœžœžœžœžœ˜CK– "Cedar" stylešœžœžœžœ˜-K– "Cedar" style•StartOfExpansion[]š œžœžœžœžœžœ˜YK– "Cedar" stylešœžœžœžœ˜#– "Cedar" stylešžœžœžœ žœžœ)žœžœ žœ žœž˜‰K–[]šœžœ5˜>Kšžœ<žœžœŸ˜YKšœžœž œ˜7Kšœ˜Kšžœ˜—KšžœŸ˜—K– "Cedar" stylešœ;˜;K– "Cedar" stylešœŸ˜—– "Cedar" stylešžœžœžœž˜Kšžœžœžœ˜4Kšžœ˜—– "Cedar" stylešžœžœžœž˜Kšžœžœžœ˜/Kšžœ˜—Kšžœ˜ K– "Cedar" stylešœŸ ˜—K– "Cedar" style˜K– "Cedar" style˜K– "Cedar" style˜K– "Cedar" style˜K– "Cedar" stylešžœ˜——…—>Œea