DIRECTORY AbSets, AMBridge, Asserting, Basics, BiRels, Convert, FS, GList, Interpreter, InterpreterOps, IntHashTable, IntStuff, IO, LichenArrayStuff, LichenDataOps, LichenDataStructure, LichenNavigation, LichenPrinting, List, ProcessProps, Rope, SetBasics, StructuredStreams, SymTab, TiogaAccess, UnparserBuffer, ViewerIO; LichenData2Impl: CEDAR PROGRAM IMPORTS AbSets, AMBridge, Asserting, BiRels, Convert, FS, InterpreterOps, IntStuff, IO, LichenArrayStuff, LichenDataOps, LichenDataStructure, LichenNavigation, List, ProcessProps, Rope, SetBasics, StructuredStreams, SymTab, TiogaAccess, UnparserBuffer EXPORTS LichenArrayStuff, LichenDataStructure, LichenDataOps, LichenPrinting = BEGIN OPEN LichenDataOps, LichenPrinting, LichenArrayStuff, LichenDataStructure, Sets:AbSets, Ints:IntStuff, SS:StructuredStreams, UB:UnparserBuffer; DimName: ARRAY Dim OF ROPE = [Foo: "Foo", Bar: "Bar"]; step: ROPE = "."; Describe: PUBLIC PROC [subject: REF ANY, relativeTo: REF ANY _ NIL, nameGen: NameGenerator _ NIL] RETURNS [name: ROPE] = { name _ UnparseSteppyName[SteppyDescribe[subject, relativeTo, nameGen]]; RETURN}; SteppyDescribe: PUBLIC PROC [subject: REF ANY, relativeTo: REF ANY _ NIL, nameGen: NameGenerator _ NIL] RETURNS [name: SteppyName] = { GetShort: PROC [oldAssns: Assertions] RETURNS [newAssns: Assertions, name: ROPE] = { name _ NARROW[Asserting.FnVal[nameReln, newAssns _ oldAssns]]; IF name = NIL THEN { name _ nameGen.GenerateName[nameGen.data, subject]; WITH subject SELECT FROM v: Vertex => KnowVertexName[v, LSn[LIST[name]]]; ENDCASE => newAssns _ Asserting.Assert1[nameReln, name, newAssns]; name _ name}; RETURN}; IF nameGen = NIL THEN nameGen _ defaultNameGen; IF subject = relativeTo THEN name _ noName ELSE WITH subject SELECT FROM d: Design => { short: ROPE; [d.other, short] _ GetShort[d.other]; name _ LSn[LIST[short]]; RETURN}; ct: CellType => { short: ROPE; [ct.otherPublic, short] _ GetShort[ct.otherPublic]; name _ LSn[LIST[short]]; IF ct.designs.HasMemA[relativeTo] OR ct.designs.Empty THEN NULL ELSE name _ SNCat[SteppyDescribe[GetADesign[ct], relativeTo, nameGen], name]; RETURN}; v: Vertex => { parent: REF ANY; IF v.VertexNames.Empty THEN KnowVertexName[v, name _ LSn[LIST[nameGen.GenerateName[nameGen.data, subject]]]] ELSE name _ VSn[v.VertexNames.First[].Val]; WITH v SELECT FROM ci: CellInstance => parent _ v.containingCT; im: Intermediary => parent _ ImParent[im]; w: Wire => parent _ WireContainer[w]; ENDCASE => ERROR; IF relativeTo#parent AND parent#NIL THEN name _ SNCat[SteppyDescribe[parent, relativeTo, nameGen], name]; RETURN}; port: Port => { parent: REF ANY ~ port.parent; IF port.PortNames.Empty THEN [] _ KnowPortName[port, name _ LSn[LIST[nameGen.GenerateName[nameGen.data, subject]]]] ELSE name _ VSn[port.PortNames.First[].Val]; IF relativeTo#parent AND parent#NIL THEN name _ SNCat[SteppyDescribe[parent, relativeTo, nameGen], name]; RETURN}; ENDCASE => ERROR; }; GetADesign: PROC [ct: CellType] RETURNS [d: Design] = { RETURN [NARROW[ct.designs.AnElt[].MDA]]}; WireContainer: PROC [w: Wire] RETURNS [container: REF ANY] = { container _ SELECT w.containingWire FROM NIL => w.containingCT, ENDCASE => w.containingWire; }; genBland: NameGenerator = NEW [NameGeneratorPrivate _ [ GenerateBlandName, NEW [NameCountsPrivate _ []] ]]; NameCounts: TYPE = REF NameCountsPrivate; NameCountsPrivate: TYPE = RECORD [ design, cellType, port, vertex: INT _ 0 ]; GenerateBlandName: PROC [data, subject: REF ANY] RETURNS [name: ROPE] = { nc: NameCounts = NARROW[data]; name _ GenByCount[nc, "#", subject]; }; GenByCount: PROC [nc: NameCounts, sep: ROPE, subject: REF ANY] RETURNS [name: ROPE] = { n: INT _ 0; WITH subject SELECT FROM d: Design => {n _ nc.design _ nc.design + 1; name _ "D"}; ct: CellType => {n _ nc.cellType _ nc.cellType + 1; name _ "CT"}; p: Port => {n _ nc.port _ nc.port + 1; name _ "P"}; v: Vertex => {n _ nc.vertex _ nc.vertex + 1; name _ "V"}; ENDCASE => ERROR; name _ name.Cat[sep, Convert.RopeFromInt[n]]; }; genSymbol: NameGenerator = NEW [NameGeneratorPrivate _ [ GenerateSymbolName, NEW [TVNameGeneratorPrivate _ [ nc: NEW [NameCountsPrivate _ []], symbols: LIST[SymTab.Create[]] ]] ]]; TVNameGenerator: TYPE = REF TVNameGeneratorPrivate; TVNameGeneratorPrivate: TYPE = RECORD [ nc: NameCounts, symbols: Interpreter.SymbolsList ]; GenerateSymbolName: PROC [data, subject: REF ANY] RETURNS [name: ROPE] = { tvng: TVNameGenerator ~ NARROW[data]; evalHead: InterpreterOps.EvalHead ~ NARROW[List.Assoc[$EvalHead, ProcessProps.GetPropList[]]]; syms: Interpreter.SymbolsList ~ IF evalHead#NIL AND evalHead.specials#NIL THEN evalHead.specials ELSE tvng.symbols; name _ Rope.Concat[IF syms=tvng.symbols THEN "&&" ELSE "&", GenByCount[tvng.nc, "", subject]]; TRUSTED {InterpreterOps.RegisterTV[ name: name, tv: AMBridge.TVForReferent[WITH subject SELECT FROM d: Design => NEW [Design _ d], ct: CellType => NEW [CellType _ ct], p: Port => NEW [Port _ p], v: Vertex => NEW [Vertex _ v], ENDCASE => ERROR], symbolsList: syms]}; RETURN}; defaultNameGen: NameGenerator ~ genSymbol; PrintObject: PROC [to: IO.STREAM, united: BOOL, PrintIt: PROC] = { SS.Bp[to, IF united THEN united ELSE lookLeft, printStep]; SS.Begin[to]; PrintIt[!UNWIND => SS.End[to]]; SS.End[to]; }; PrintRope: PROC [to: IO.STREAM, united: BOOL, rope: ROPE] = { SS.Bp[to, IF united THEN united ELSE lookLeft, printStep]; SS.Begin[to]; to.PutRope[rope !UNWIND => SS.End[to]]; SS.End[to]; }; printStep: INT _ 2; printWidth: INT _ 76; PrintDesignOnFile: PUBLIC PROC [design: Design, nameGen: NameGenerator _ NIL, fileName: ROPE _ NIL, tioga: BOOL _ FALSE, pacify: IO.STREAM _ NIL, Filter: CellTypeFilter _ NIL] = { realFileName: ROPE = IF fileName # NIL THEN fileName ELSE Rope.Cat[Describe[design], ".design"]; ss, fs: IO.STREAM; taw: TiogaAccess.Writer; IF tioga THEN { taw _ TiogaAccess.Create[]; ss _ SS.Create[UB.NewInittedHandle[[output: [access[taw, printStep]], margin: printWidth]]]; } ELSE { fs _ FS.StreamOpen[fileName: realFileName, accessOptions: create, keep: 10]; ss _ SS.Create[UB.NewInittedHandle[[output: [stream[fs]], margin: printWidth]]]; }; PrintDesignSubset[ss, design, nameGen, pacify, Filter]; IF tioga THEN TiogaAccess.WriteFile[taw, realFileName] ELSE IO.Close[fs]; ss.Close[]; }; PrintDesign: PUBLIC PROC [to: IO.STREAM, design: Design, nameGen: NameGenerator _ NIL, pacify: IO.STREAM _ NIL] = { PrintDesignSubset[to, design, nameGen, pacify, NIL]; }; PrintDesignSubset: PUBLIC PROC [to: IO.STREAM, design: Design, nameGen: NameGenerator _ NIL, pacify: IO.STREAM _ NIL, Filter: CellTypeFilter _ NIL] = { n: NAT _ 0; CTPrint: PROC [ra: Sets.Value] = { ct: CellType = NARROW[ra.VA]; Inner: PROC = { IF pacify#NIL THEN pacify.PutF["%g: %g ", [integer[n _ n+1]], [rope[Describe[ct, design, nameGen]]]]; PrintCellType[to, ct, nameGen]; IF pacify#NIL THEN pacify.PutRope[" .\n"]; }; IF Filter=NIL OR Filter[ct] THEN PrintObject[to, TRUE, Inner]; }; IF pacify#NIL AND Filter=NIL THEN pacify.PutF["Total: %g\n", [integer[design.cellTypes.Size.EN]]]; IF NOT SS.IsAnSS[to] THEN to _ SS.Create[UB.NewInittedHandle[[output: [stream[to]], margin: printWidth]]]; to.PutF["%g: Design {", [rope[Describe[design, NIL, nameGen]]]]; design.cellTypes.Enumerate[CTPrint]; to.PutF["}"]; }; PrintNameAndAliases: PROC [to: IO.STREAM, name: ROPE, names: Set--of SteppyName--] ~ { first, second: BOOL _ TRUE; PerName: PROC [val: Sets.Value] ~ { name: SteppyName ~ VSn[val]; IF first THEN first _ FALSE ELSE { IF second THEN second _ FALSE ELSE to.PutRope[","]; SS.Bp[to, width, printStep, " "]; to.PutRope[UnparseSteppyName[name]]; }; RETURN}; to.PutRope[name]; IF names.Size[Ints.two].Compare[Ints.one]>equal THEN { to.PutRope["(a.k.a."]; names.Enumerate[PerName]; to.PutRope[")"]; }; RETURN}; PrintCellType: PUBLIC PROC [to: IO.STREAM, ct: CellType, nameGen: NameGenerator _ NIL] = { PortPrint: PROC = { to.PutF["port: "]; PrintPort[to, ct.port, nameGen]; }; IWPrint: PROC = { to.PutF["internal wire: "]; PrintWire[to, ct.asUnorganized.internalWire, nameGen]; }; CIPrint: PROC = { to.PutF["contained instances: "]; PrintInstances[to, ct.asUnorganized.containedInstances, ct.asUnorganized.mirror, nameGen]; }; AyPrint: PROC = { to.PutRope["asArray: "]; PrintArray[to, ct, nameGen] }; IF NOT SS.IsAnSS[to] THEN to _ SS.Create[UB.NewInittedHandle[[output: [stream[to]], margin: printWidth]]]; to.PutRope[Describe[ct, GetADesign[ct], nameGen]]; to.PutRope[": CellType["]; PrintObject[to, TRUE, PortPrint]; IF ct.asUnorganized # NIL THEN { to.PutRope[", "]; PrintObject[to, TRUE, IWPrint]; to.PutRope[", "]; PrintObject[to, TRUE, CIPrint]; }; IF ct.asArray # NIL THEN { to.PutRope[", "]; PrintObject[to, TRUE, AyPrint]; }; to.PutRope["]"]; }; limitPort: BOOL _ TRUE; portLimit: NAT _ 69; MaybePrintSeq: PROC [to: IO.STREAM, parent: REF ANY, toKids: Function--parent _ Seq of child--, toName: Function--child _ SteppyName--] RETURNS [did: BOOL] ~ { kids: Seq--of child-- ~ BiRels.DeRef[toKids.ApplyA[parent].MA]; bounds: Ints.Interval ~ kids.GetIntDom[]; is: BOOL _ TRUE; FOR i: INT IN [bounds.min .. bounds.max] DO child: REF ANY ~ kids.ApplyI[i].MDA; IF child=NIL THEN EXIT; {name: SteppyName ~ VSn[toName.ApplyA[child].DVal[noNameVal]]; IF name.steps#NIL AND name.steps.rest=NIL THEN WITH name.steps.first SELECT FROM x: REF INT => IF x^ = i THEN { grandKids: Seq ~ BiRels.DeRef[toKids.ApplyA[child].MA]; IF grandKids.Empty THEN LOOP; }; x: ROPE => NULL; ENDCASE => ERROR; EXIT; };REPEAT FINISHED => { IF bounds.min=0 THEN to.PutF["*%g", [integer[bounds.max+1]]] ELSE to.PutF["*%g..%g", [integer[bounds.min]], [integer[bounds.max]]]; RETURN [TRUE]}; ENDLOOP; RETURN [FALSE]}; PrintPort: PUBLIC PROC [to: IO.STREAM, port: Port, nameGen: NameGenerator _ NIL] = { first: BOOL _ TRUE; i: INT _ 0; PrintNameAndAliases[to, Describe[port, port.parent, nameGen], port.PortNames]; IF port.FirstChildPort[] = NIL THEN RETURN; IF MaybePrintSeq[to, port, LichenNavigation.portToChildren, LichenNavigation.bestPortShortName] THEN RETURN; to.PutRope["["]; FOR subPort: Port _ port.FirstChildPort[], subPort.NextChildPort[] WHILE subPort#NIL DO PortPrint: PROC = {PrintPort[to, subPort, nameGen]}; PrintElipsis: PROC = {to.PutF["..%g.., ", [integer[i-portLimit]]]}; IF (NOT limitPort) OR i < portLimit OR subPort.NextChildPort[] = NIL THEN { IF first THEN first _ FALSE ELSE to.PutRope[", "]; IF limitPort AND i > portLimit THEN PrintObject[to, FALSE, PrintElipsis]; PrintObject[to, FALSE, PortPrint] }; i _ i + 1; ENDLOOP; to.PutRope["]"]; }; PrintWire: PUBLIC PROC [to: IO.STREAM, wire: Wire, nameGen: NameGenerator _ NIL] = { first: BOOL _ TRUE; PrintNameAndAliases[to, Describe[wire, WireContainer[wire], nameGen], wire.VertexNames]; IF wire.FirstChildWire[] = NIL THEN RETURN; IF MaybePrintSeq[to, wire, LichenNavigation.wireToChildren, LichenNavigation.bestVertexShortName] THEN RETURN; to.PutRope["["]; FOR subWire: Wire _ wire.FirstChildWire[], subWire.NextChildWire[] WHILE subWire # NIL DO WirePrint: PROC = {PrintWire[to, subWire, nameGen]}; IF first THEN first _ FALSE ELSE to.PutRope[", "]; PrintObject[to, FALSE, WirePrint]; ENDLOOP; to.PutRope["]"]; }; PrintInstances: PUBLIC PROC [to: IO.STREAM, set: Set--OF CellInstance--, mirror: CellInstance, nameGen: NameGenerator _ NIL] = { first: BOOL _ TRUE; PrintIt: PROC [val: REF ANY] = { ci: CellInstance = NARROW[val]; IPrint: PROC = {PrintInstance[to, ci, nameGen]}; IF first THEN first _ FALSE ELSE to.PutRope[", "]; PrintObject[to, TRUE, IPrint]; }; to.PutRope["["]; set.EnumA[PrintIt]; IF printMirror THEN PrintIt[mirror]; to.PutRope["]"]; }; printMirror: BOOL _ TRUE; PrintInstance: PUBLIC PROC [to: IO.STREAM, ci: CellInstance, nameGen: NameGenerator _ NIL] = { PrintConnections: PROC [v: Vertex] = { first: BOOL _ TRUE; PrintConnection: PROC [port: Port, w: Vertex] = { CPrint: PROC = { to.PutRope[Describe[port, port.parent, nameGen]]; to.PutRope[": "]; WITH w SELECT FROM im: Intermediary => { subbing, first, allSame: BOOL _ TRUE; wi, pi, num: INT _ 0; parent, theOne: Wire _ NIL; TestConnection: PROC [p: Port, u: Vertex] ~ { ow: Wire ~ WITH u SELECT FROM x: Wire => x, x: Intermediary => NIL, x: CellInstance => ERROR, ENDCASE => ERROR; IF ow=NIL THEN subbing _ FALSE; IF allSame THEN { IF ow=NIL THEN allSame _ FALSE ELSE IF theOne=NIL THEN theOne _ ow ELSE IF theOne#ow THEN allSame _ FALSE}; num _ num+1; IF NOT subbing THEN RETURN; {pn: SteppyName ~ VSn[p.PortNames.First.DVal[noNameVal]]; IF pn.grade.subs=1 AND pn.grade.nonsubs=0 THEN WITH pn.steps.first SELECT FROM x: REF INT => { wn: SteppyName ~ VSn[ow.VertexNames.First.DVal[noNameVal]]; IF wn.grade.subs=1 AND wn.grade.nonsubs=0 THEN WITH wn.steps.first SELECT FROM y: REF INT => IF first THEN {wi _ y^; pi _ x^; first _ FALSE; parent _ ow.containingWire; RETURN} ELSE {IF y^ = (wi _ wi+1) AND x^ = (pi _ pi+1) AND parent=ow.containingWire THEN RETURN}; y: ROPE => NULL; ENDCASE => ERROR; }; x: ROPE => NULL; ENDCASE => ERROR; subbing _ FALSE; RETURN}}; EnumerateImmediateConnections[im, TestConnection, [cellward: FALSE, wireward: TRUE]]; IF subbing THEN to.PutF["%g[%g..%g]", [rope[Describe[parent, ci.containingCT.asUnorganized.internalWire, nameGen]]], [integer[wi+1-num]], [integer[wi]]] ELSE IF allSame AND theOne#NIL THEN to.PutF["%g*%g", [integer[num]], [rope[Describe[theOne, ci.containingCT.asUnorganized.internalWire, nameGen]]]] ELSE PrintConnections[im]; }; wire: Wire => { to.PutRope[Describe[wire, ci.containingCT.asUnorganized.internalWire, nameGen]]; }; ci: CellInstance => ERROR; ENDCASE => ERROR; }; IF first THEN first _ FALSE ELSE to.PutRope[", "]; PrintObject[to, FALSE, CPrint]; }; to.PutRope["["]; EnumerateImmediateConnections[v, PrintConnection, [cellward: FALSE, wireward: TRUE]]; to.PutRope["]"]; }; PrintNameAndAliases[to, Describe[ci, ci.containingCT, nameGen], ci.VertexNames]; to.PutF[": %g", [rope[Describe[ci.type, GetADesign[ci.type], nameGen]]] ]; PrintConnections[ci]; }; Array: TYPE ~ LichenDataStructure.Array; printStatRep: BOOL _ TRUE; printDumbRep: BOOL _ FALSE; PrintArray: PUBLIC PROC [to: IO.STREAM, ct: CellType, nameGen: NameGenerator _ NIL] = { a: Array = ct.asArray; groupName: VarFunction = BiRels.CreateHashFn[]; nGroups: NAT _ 0; BasePrint: PROC = { to.PutF["base period = [%g, %g]", [integer[a.basePeriod[Foo]]], [integer[a.basePeriod[Bar]]]]}; StatPrint: PROC = { to.PutRope["static graph = ["]; PrintStatRep[to, a, nameGen]; to.PutRope["]"]; }; to.PutF["{%g BY %g OF %g, ", [integer[a.size2[Foo]]], [integer[a.size2[Bar]]], [rope[Describe[a.eltType, GetADesign[ct], nameGen]]] ]; PrintObject[to, FALSE, BasePrint]; IF printStatRep THEN { to.PutRope[", "]; PrintObject[to, TRUE, StatPrint]; }; IF printDumbRep THEN ERROR nyet; to.PutRope["}"]; }; PrintStatRep: PROC [to: IO.STREAM, a: Array, nameGen: NameGenerator] ~ { firstEdge: BOOL _ TRUE; PrintEdge: PROC [val: REF ANY] ~ { se: StatEdge ~ NARROW[val]; IF firstEdge THEN firstEdge _ FALSE ELSE to.PutRope[", "]; PrintRope[to, TRUE, FmtStatEdge[se, a, nameGen]]; RETURN}; a.statrep.edges.EnumA[PrintEdge, fwd]; RETURN}; FmtStatEdge: PUBLIC PROC [se: StatEdge, a: Array _ NIL, nameGen: NameGenerator _ NIL] RETURNS [ROPE] ~ { Fmt: PROC [b: BOOL] RETURNS [ans: ROPE] ~ { ep: Port ~ se.vs[b].port; ans _ Describe[ep, PortCCT[ep].port, nameGen]; IF a=NIL OR a.basePeriod#ALL[1] THEN ans _ ans.Concat[Rope.Cat["@<", Convert.RopeFromInt[se.vs[b].phase[Foo]], ",", Convert.RopeFromInt[se.vs[b].phase[Bar]], ">"]]; RETURN}; RETURN Rope.Cat[Fmt[FALSE], " -> ", Fmt[TRUE], " by ", FmtInt2[a, se.d]]}; FmtRange2: PROC [a: Array, r: Range2] RETURNS [asRope: ROPE] = { RETURN [SELECT TRUE FROM a.size2[Bar]=1 => FmtRange[r[Foo]], a.size2[Foo]=1 => FmtRange[r[Bar]], ENDCASE => FmtRange[r[Foo]].Cat[":", FmtRange[r[Bar]]] ]}; FmtRange: PUBLIC PROC [r: Range] RETURNS [asRope: ROPE] = { asRope _ Convert.RopeFromInt[r.min]; IF r.min+1 # r.maxPlusOne THEN asRope _ asRope.Cat["~", Convert.RopeFromInt[r.maxPlusOne-1]]; }; FmtInt2: PROC [a: Array, i2: Int2] RETURNS [ROPE] ~ { RETURN [SELECT TRUE FROM a=NIL => IO.PutFR["<%g, %g>", [integer[i2[Foo]]], [integer[i2[Bar]]]], a.size2[Bar]=1 => Convert.RopeFromInt[i2[Foo]], a.size2[Foo]=1 => Convert.RopeFromInt[i2[Bar]], ENDCASE => IO.PutFR["<%g, %g>", [integer[i2[Foo]]], [integer[i2[Bar]]]] ]}; IsArray: PROC [ct: CellType] RETURNS [pass: BOOL] = {pass _ ct.asArray # NIL}; Is1D: PROC [ct: CellType] RETURNS [BOOL] ~ {RETURN [ct.asArray#NIL AND (ct.asArray.size2[Foo]=1 OR ct.asArray.size2[Bar]=1)]}; Is2D: PROC [ct: CellType] RETURNS [BOOL] ~ {RETURN [ct.asArray#NIL AND ct.asArray.size2[Foo]#1 AND ct.asArray.size2[Bar]#1]}; PrintArrays: PROC [to: IO.STREAM, design: Design, nameGen: NameGenerator _ NIL, pacify: IO.STREAM _ NIL] = { PrintDesignSubset[to, design, nameGen, pacify, IsArray]; }; PrintIncompletes: PROC [to: IO.STREAM, design: Design, nameGen: NameGenerator _ NIL, pacify: IO.STREAM _ NIL] = { PrintDesignSubset[to, design, nameGen, pacify, IsIncompleteArray]; }; IndexVertexNames: PUBLIC PROC [v: Vertex, names: Set _ Sets.nilSet] = { ct: CellType = v.containingCT; pbn: VarFunction = BiRels.DeRef[Asserting.FnVal[partsByNameKey, ct.otherPrivate]].AsVar; top: BOOL ~ WITH v SELECT FROM x: CellInstance => TRUE, x: Intermediary => FALSE, x: Wire => x.containingCT.asUnorganized.internalWire=x.containingWire, ENDCASE => ERROR; PerName: PROC [namev: Sets.Value] ~ { IF pbn.AddPair[[namev, AV[v]], BiRels.addIfNew].had[leftToRight]=different THEN ERROR; }; IF pbn=BiRels.nilBiRel OR NOT top THEN RETURN; IF names=Sets.nilSet THEN names _ v.VertexNames; names.Enumerate[PerName]; RETURN}; UnindexVertexNames: PUBLIC PROC [v: Vertex] = { ct: CellType = v.containingCT; pbn: VarFunction = BiRels.DeRef[Asserting.FnVal[partsByNameKey, ct.otherPrivate]].AsVar; top: BOOL ~ WITH v SELECT FROM x: CellInstance => TRUE, x: Intermediary => FALSE, x: Wire => x.containingCT.asUnorganized.internalWire=x.containingWire, ENDCASE => ERROR; PerName: PROC [namev: Sets.Value] ~ { IF pbn.RemPair[[namev, AV[v]]].had[leftToRight]=different THEN ERROR; }; IF pbn=BiRels.nilBiRel OR NOT top THEN RETURN; v.VertexNames.Enumerate[PerName]; RETURN}; FetchVertex: PUBLIC PROC [ct: CellType, name: SteppyName] RETURNS [v: Vertex] ~ { pbn: Function ~ BiRels.DeRef[Asserting.FnVal[partsByNameKey, ct.otherPrivate]]; v _ NARROW[pbn.Apply[SnV[name]].MDA]; RETURN}; KnowVertexName: PUBLIC PROC [v: Vertex, name: SteppyName] = { ct: CellType = v.containingCT; pbn: VarFunction = BiRels.DeRef[Asserting.FnVal[partsByNameKey, ct.otherPrivate]].AsVar; top: BOOL ~ WITH v SELECT FROM x: CellInstance => TRUE, x: Intermediary => FALSE, x: Wire => x.containingCT.asUnorganized.internalWire=x.containingWire, ENDCASE => ERROR; IF top AND pbn#BiRels.nilBiRel THEN { IF pbn.AddPair[[SnV[name], AV[v]]].had[leftToRight]=different THEN ERROR; }; IF NOT v.VertexNames.AddElt[SnV[name]] THEN ERROR; RETURN}; ForgetVertexName: PUBLIC PROC [v: Vertex, name: SteppyName] = { ct: CellType = v.containingCT; pbn: VarFunction = BiRels.DeRef[Asserting.FnVal[partsByNameKey, ct.otherPrivate]].AsVar; last: Assertions _ NIL; next: Assertions _ v.other; top: BOOL ~ WITH v SELECT FROM x: CellInstance => TRUE, x: Intermediary => FALSE, x: Wire => x.containingCT.asUnorganized.internalWire=x.containingWire, ENDCASE => ERROR; IF top AND pbn#BiRels.nilBiRel THEN { IF pbn.RemPair[[SnV[name], AV[v]]].had[leftToRight]#same THEN ERROR; }; IF NOT v.VertexNames.RemElt[SnV[name]] THEN ERROR; RETURN}; END. ^LichenData2Impl.Mesa Last tweaked by Mike Spreitzer on February 2, 1988 1:18:42 pm PST �Êݘ™Icode™A—J˜KšÏk œ7�œ>�œÀ˜ÂK˜šÐbxœ�œ�˜Kš�œ/�œ�œ¥˜ûKš�œE˜LKšœ˜—K˜Kš �œ�œGÏnœŸœ �œ�œ˜•K˜KšŸœ�œ�œ�œ˜6K˜Kšœ�œ˜K˜šŸœ�œ�œ �œ�œ�œ�œ�œ�œ�œ�œ˜zKšœG˜GKš�œ˜—K˜šŸœ�œ�œ �œ�œ�œ�œ�œ�œ�œ˜†šŸœ�œ�œ�œ˜TKšœ�œ1˜>š�œ�œ�œ˜K˜3š�œ �œ�˜Kšœ#�œ ˜0Kš�œ;˜B—K˜ —Kš�œ˜—Kš�œ �œ�œ˜/š �œ�œ�œ�œ �œ�˜H˜Kšœ�œ˜ K˜%Kšœ �œ ˜Kš�œ˜—˜Kšœ�œ˜ Kšœ3˜3Kšœ �œ ˜Kš �œ �œ�œ�œ�œI˜�Kš�œ˜—˜Kšœ�œ�œ˜Kš�œ�œ�œ0�œ'˜˜š�œ�œ�˜K˜,Kšœ*˜*Kšœ%˜%Kš�œ�œ˜—Kš�œ�œ�œ�œA˜iKš�œ˜—˜Kšœ�œ�œ˜Kš�œ�œ$�œ0�œ(˜ Kš�œ�œ�œ�œA˜iKš�œ˜—Kš�œ�œ˜—Kšœ˜—K˜šŸ œ�œ�œ˜7Kš�œ�œ�œ˜)—K˜š Ÿ œ�œ �œ �œ�œ˜>šœ �œ�˜(Kš�œ˜Kš�œ˜—K˜—K˜šœ�œ˜7K˜Kš�œ˜K˜—K˜Kšœ �œ�œ˜)šœ�œ�œ˜"Kšœ �œ˜'K˜—K˜š Ÿœ�œ�œ�œ�œ�œ˜IKšœ�œ˜K˜$K˜—K˜šŸ œ�œ�œ �œ�œ�œ�œ˜WKšœ�œ˜ š�œ �œ�˜K˜9K˜AK˜3K˜9Kš�œ�œ˜—K˜-K˜—K˜šœ�œ˜8K˜š�œ˜Kšœ�œ˜!Kšœ �œ˜K˜—K˜—K˜Kšœ�œ�œ˜3šœ�œ�œ˜'K˜Kšœ ˜ K˜—K˜š Ÿœ�œ�œ�œ�œ�œ˜JKšœ�œ˜%Kšœ$�œ4˜^Kš œ �œ �œ�œ�œ�œ�œ˜sKšœ�œ�œ�œ(˜^š�œ˜#K˜ šœ�œ �œ�˜3Kšœ �œ˜Kšœ�œ˜$Kšœ �œ ˜Kšœ �œ˜Kš�œ�œ˜—Kšœ˜—Kš�œ˜—K˜Kšœ*˜*K˜šŸ œ�œ�œ�œ �œŸœ�œ˜BKš�œ�œ�œ�œ˜:Kš�œ ˜ Kšœ �œ�œ ˜Kš�œ ˜ K˜—K˜š Ÿ œ�œ�œ�œ �œ�œ˜=Kš�œ�œ�œ�œ˜:Kš�œ ˜ Kšœ�œ�œ ˜'Kš�œ ˜ K˜—K˜Kšœ �œ˜Kšœ �œ˜K˜šŸœ�œ�œ+�œ �œ�œ �œ�œ �œ�œ�œŸœ�œ˜³Kš œ�œ�œ �œ�œ �œ'˜`Kšœ�œ�œ˜K˜š�œ˜š�œ˜Kšœ˜Kšœ�œ�œK˜\K˜—š�œ˜Kšœ�œE˜LKšœ�œ�œ?˜PK˜——Kšœ7˜7Kš�œ�œ*�œ�œ ˜IK˜ K˜—K˜šŸ œ�œ�œ�œ�œ+�œ �œ�œ�œ˜sKšœ/�œ˜4Kšœ˜—K˜šŸœ�œ�œ�œ�œ+�œ �œ�œ�œŸœ�œ˜—Kšœ�œ˜ šŸœ�œ˜"Kšœ�œ�œ˜šŸœ�œ˜Kš�œ�œ�œS˜eKšœ˜Kš�œ�œ�œ˜*Kšœ˜—Kš �œ�œ�œ �œ�œ ˜>K˜—Kš �œ�œ�œ�œ�œ;�œ˜bKš �œ�œ�œ �œ�œ�œ?˜jKšœ/�œ˜@Kšœ$˜$K˜ K˜—K˜š Ÿœ�œ�œ�œ�œ Ïcœ˜VKšœ�œ�œ˜šŸœ�œ˜#Kšœ˜š�œ�œ �œ�œ˜"Kš�œ�œ �œ�œ˜3Kš�œ˜!Kšœ$˜$K˜—Kš�œ˜—Kšœ˜š�œ.�œ˜6K˜K˜K˜K˜—Kš�œ˜—K˜š Ÿ œ�œ�œ�œ�œ)�œ˜ZšŸ œ�œ˜K˜K˜ K˜—šŸœ�œ˜K˜Kšœ6˜6K˜—šŸœ�œ˜K˜!KšœZ˜ZK˜—šŸœ�œ˜K˜Kšœ˜K˜—Kš �œ�œ�œ �œ�œ�œ?˜jKšœ2˜2Kšœ˜Kšœ�œ ˜!š�œ�œ�œ˜ Kšœ"�œ ˜1Kšœ"�œ ˜1K˜—š�œ�œ�œ˜Kšœ"�œ ˜1K˜—K˜K˜—K˜Kšœ �œ�œ˜Kšœ �œ˜K˜šŸ œ�œ�œ�œ �œ�œ  Ðcm œ ¡  œ�œ�œ˜ŸKšœ   œ&�œ˜?Kšœ)˜)Kšœ�œ�œ˜š�œ�œ�œ�˜+Kšœ�œ�œ�œ˜$Kš�œ�œ�œ�œ˜Kšœ>˜>š�œ �œ�œ�œ�œ�œ�œ�˜Pš œ�œ�œ�œ�œ˜Kšœ3�œ˜7Kš�œ�œ�œ˜K˜—Kšœ�œ�œ˜Kš�œ�œ˜—Kš�œ˜šœ�œ�œ˜š�œ ˜Kš�œ(˜,Kš�œB˜F—Kš�œ�œ˜—Kš�œ˜—Kš�œ�œ˜—K˜š Ÿ œ�œ�œ�œ�œ'�œ˜TKšœ�œ�œ˜Kšœ�œ˜ KšœN˜NKš�œ�œ�œ�œ˜+Kš�œ^�œ�œ˜lK˜š�œ@�œ �œ�˜WKšŸ œ�œ%˜4KšŸ œ�œ1˜Cš �œ�œ �œ�œ�œ�œ˜KKš�œ�œ �œ�œ˜2Kš�œ �œ�œ�œ˜IKšœ�œ ˜!Kšœ˜—K˜ Kš�œ˜—K˜K˜—K˜š Ÿ œ�œ�œ�œ�œ'�œ˜TKšœ�œ�œ˜KšœX˜XKš�œ�œ�œ�œ˜+Kš�œ`�œ�œ˜nK˜š�œ@�œ �œ�˜YKšŸ œ�œ%˜4Kš�œ�œ �œ�œ˜2Kšœ�œ ˜"Kš�œ˜—K˜K˜—K˜šŸœ�œ�œ�œ�œ  œ1�œ˜€Kšœ�œ�œ˜šŸœ�œ�œ�œ˜ Kšœ�œ˜KšŸœ�œ$˜0Kš�œ�œ �œ�œ˜2Kšœ�œ ˜K˜—K˜K˜Kš�œ �œ˜$K˜K˜Kšœ �œ�œ˜—K˜š Ÿ œ�œ�œ�œ�œ-�œ˜^šŸœ�œ˜&Kšœ�œ�œ˜šŸœ�œ˜1šŸœ�œ˜K˜1K˜š�œ�œ�˜˜Kšœ�œ�œ˜%Kšœ �œ˜Kšœ�œ˜šŸœ�œ˜-šœ �œ�œ�˜K˜ Kšœ�œ˜Kšœ�œ˜Kš�œ�œ˜—Kš�œ�œ�œ �œ˜š�œ �œ˜Kš�œ�œ�œ �˜Kš�œ�œ�œ�œ ˜#Kš�œ�œ �œ �œ˜(—K˜ Kš�œ�œ �œ�œ˜Kšœ9˜9š �œ�œ�œ�œ�œ�˜Nšœ�œ�œ˜Kšœ;˜;š �œ�œ�œ�œ�œ�˜Nšœ�œ�œ�œ˜Kš�œ�œ�œ˜JKš �œ�œ�œ�œ�œ�œ˜Y—Kšœ�œ�œ˜Kš�œ�œ˜—K˜—Kšœ�œ�œ˜Kš�œ�œ˜—Kšœ �œ˜Kš�œ˜ —Kšœ=�œ �œ˜UKš�œ �œ‰˜˜Kš �œ�œ �œ�œ�œp˜“Kš�œ˜K˜—˜KšœP˜PK˜—Kšœ�œ˜Kš�œ�œ˜—K˜—Kš�œ�œ �œ�œ˜2Kšœ�œ ˜K˜—K˜Kšœ=�œ �œ˜UK˜K˜—KšœP˜PKšœJ˜JK˜K˜—K˜Kšœ�œ˜(K˜Kšœ�œ�œ˜Kšœ�œ�œ˜K˜š Ÿ œ�œ�œ�œ�œ)�œ˜WKšœ˜Kšœ/˜/Kšœ �œ˜šŸ œ�œ˜Kšœ_˜_—šŸ œ�œ˜K˜K˜K˜K˜—˜K˜1Kšœ4˜4K˜—Kšœ�œ ˜"š�œ�œ˜K˜Kšœ�œ ˜!K˜—Kš�œ�œ�œ˜ K˜K˜—K˜šŸ œ�œ�œ�œ'˜HKšœ �œ�œ˜šŸ œ�œ�œ�œ˜"Kšœ�œ˜Kš�œ �œ �œ�œ˜:Kšœ�œ˜1Kš�œ˜—Kšœ&˜&Kš�œ˜—K˜šŸ œ�œ�œ�œ�œ�œ�œ˜hš Ÿœ�œ�œ�œ�œ˜+K˜K˜.Kš �œ�œ�œ�œ�œ€˜¤Kš�œ˜—Kš�œ�œ�œÏgœ˜J—K˜šŸ œ�œ�œ �œ˜@š�œ�œ�œ�˜Kšœ#˜#Kšœ#˜#Kš�œ/˜6K˜——K˜š Ÿœ�œ�œ �œ �œ˜;K˜$Kš�œ�œ?˜]K˜—K˜šŸœ�œ�œ�œ˜5š�œ�œ�œ�˜Kšœ�œ�œ;˜FK˜/K˜/Kš�œ�œ:˜GK˜——K˜Kš Ÿœ�œ�œ�œ�œ˜NK˜šŸœ�œ�œ�œ˜(Kš œ�œ �œ�œ�œ˜U—K˜šŸœ�œ�œ�œ˜(Kš œ�œ �œ�œ�œ˜T—K˜šŸ œ�œ�œ�œ+�œ �œ�œ�œ˜lKšœ8˜8Kšœ˜—K˜šŸœ�œ�œ�œ+�œ �œ�œ�œ˜qKšœB˜BKšœ˜—K˜šŸœ�œ�œ*˜GK˜KšœX˜Xšœ�œ�œ�œ�˜Kšœ�œ˜Kšœ�œ˜KšœF˜FKš�œ�œ˜—šŸœ�œ˜%Kš�œ�œ2�œ�œ˜VK˜—Kš �œ�œ�œ�œ�œ˜.Kš�œ�œ˜0Kšœ˜Kš�œ˜—K˜šŸœ�œ�œ˜/K˜KšœX˜Xšœ�œ�œ�œ�˜Kšœ�œ˜Kšœ�œ˜KšœF˜FKš�œ�œ˜—šŸœ�œ˜%Kš�œ�œ!�œ�œ˜EK˜—Kš �œ�œ�œ�œ�œ˜.Kšœ!˜!Kš�œ˜—K˜šŸ œ�œ�œ"�œ˜QKšœO˜OKšœ�œ�œ˜%Kš�œ˜—K˜šŸœ�œ�œ"˜=K˜KšœX˜Xšœ�œ�œ�œ�˜Kšœ�œ˜Kšœ�œ˜KšœF˜FKš�œ�œ˜—š�œ�œ�œ˜%Kš�œ<�œ�œ˜IKšœ˜—Kš�œ�œ!�œ�œ˜2Kš�œ˜—K˜šŸœ�œ�œ"˜?K˜KšœX˜XKšœ�œ˜K˜šœ�œ�œ�œ�˜Kšœ�œ˜Kšœ�œ˜KšœF˜FKš�œ�œ˜—š�œ�œ�œ˜%Kš�œ7�œ�œ˜DKšœ˜—Kš�œ�œ!�œ�œ˜2Kš�œ˜—K˜Kš�œ˜—…—KÄcÿ