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: NAT _ 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: NAT]= { 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: NAT] ={ 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: NAT, maxChWidth: BOOL] RETURNS [IPCTG.Ref] ={ ctg: IPCTG.Ref _ IPCTG.Create[]; makeCh: PROC[c: Cluster] ={ r: Misc.Interval _ c.range; width: NAT _ 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 --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 ########## -- Κ!>˜Jšœ™šœ:™:Icode™$—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šž™šΟnœœœœ˜%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•StartOfExpansion[]– "Cedar" styleš œœœœœœ˜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šœ˜——…—>Œdκ