DIRECTORY AbSets, BiRels, IntStuff, LichenDataOps, LichenDataStructure, LichenTransforms; LichenFlattenning: CEDAR PROGRAM IMPORTS AbSets, BiRels, IntStuff, LichenDataOps, LichenDataStructure EXPORTS LichenTransforms, LichenDataOps = BEGIN OPEN LichenDataOps, LichenDataStructure, Sets:AbSets; ExpandVertex: PUBLIC PROC [child: CellInstance] RETURNS [roleToSib: Seq--role f sibling: CellInstance--] ~ { ct: CellType ~ child.type; parent: CellType ~ child.containingCT; u: Unorganized ~ ct.asUnorganized; roles: INT ~ u.containedInstances.Size[].EN; promote: VarFunction--part of ct _ part of parent-- ~ BiRels.CreateHashFn[]; SetPromotion: PROC [inner, outer: Wire] ~ { IF inner=NIL OR outer=NIL THEN ERROR; promote.AddNewAA[inner, outer]; inner _ inner.FirstChildWire[]; outer _ outer.FirstChildWire[]; WHILE inner#NIL AND outer#NIL DO SetPromotion[inner, outer]; inner _ inner.NextChildWire[]; outer _ outer.NextChildWire[]; ENDLOOP; IF inner#NIL OR outer#NIL THEN ERROR; }; NotePorting: PROC [p: Port, w: Wire] ~ { SetPromotion[p.wire, w]; }; MoveCell: PROC [ra: Sets.Value] ~ { ci: CellInstance ~ NARROW[ra.VA]; sib: CellInstance ~ Instantiate[ci.type, parent, CrossNames[child.VertexNames, ci.VertexNames]]; GetPromotion: PROC [vi, uvo: Vertex, port: Port] RETURNS [vo: Vertex] ~ { IF (vo _ NARROW[promote.ApplyA[vi].MDA])#NIL THEN RETURN; WITH vi SELECT FROM wi: Wire => { uwo: Wire ~ WITH uvo SELECT FROM x: Wire => x, ENDCASE => NIL; wo: Wire ~ vo _ CreateWire[parent, uwo, IF uwo#NIL THEN [vi.VertexNames.Copy.data.VA] ELSE CrossNames[child.VertexNames, vi.VertexNames]]; promote.AddNewAA[wi, wo]; WITH uvo SELECT FROM x: Intermediary => AddEdge[[x, wo], port]; ENDCASE => NULL; FOR cwi: Wire _ wi.FirstChildWire, cwi.NextChildWire WHILE cwi # NIL DO [] _ GetPromotion[cwi, wo, NIL] ENDLOOP; }; ii: Intermediary => { io: Intermediary ~ vo _ CreateIntermediary[uvo, wireward, parent, port, [vi.VertexNames.Copy.data.VA]]; PromoteIM: PROC [q: Port, wi: Vertex] ~ {[] _ GetPromotion[wi, io, q]}; promote.AddNewAA[ii, io]; EnumerateImmediateConnections[ii, PromoteIM, [FALSE, TRUE]]; }; cii: CellInstance => ERROR; ENDCASE => ERROR; IF vo=NIL THEN ERROR; }; PromoteEdge: PROC [p: Port, v: Vertex] ~ { w: Vertex ~ GetPromotion[v, sib, p]; AddEdge[[sib, w], p]; }; roleToSib.AppendA[sib]; EnumerateImmediateConnections[ci, PromoteEdge]; }; roleToSib _ CreateSeq[oneToOne: TRUE]; EnumerateTopConnections[child, NotePorting]; u.containedInstances.Enumerate[MoveCell]; DeleteVertex[child]; roleToSib _ roleToSib.Freeze; }; CrossNames: PUBLIC PROC [outer, inner: Set--of SteppyName--] RETURNS [ListData] ~ { crossed: Set--of SteppyName-- ~ Setify[CreateSteppyNames[]]; Crossit: PROC [v1: Sets.Value] ~ { innerName: SteppyName ~ VSn[v1]; glob: BOOL _ FALSE; Finish: PROC [v2: Sets.Value] ~ { outerName: SteppyName ~ VSn[v2]; name: SteppyName ~ SNCat[outerName, innerName]; new: BOOL ~ crossed.AddElt[SnV[name]]; RETURN}; IF innerName.grade.global THEN {[] _ crossed.AddElt[SnV[innerName]]; RETURN}; outer.Enumerate[Finish]; RETURN}; inner.Enumerate[Crossit]; RETURN [[crossed.data.VA]]}; Flatten: PUBLIC PROC [root: CellType, expand: ConstFilter--of CellInstance--] ~ { action: BOOL _ TRUE; MaybeExpand: PROC [ra: Sets.Value] ~ { ci: CellInstance ~ NARROW[ra.VA]; IF expand.HasMemA[ci] THEN { action _ TRUE; [] _ ExpandVertex[ci]; }; }; u: Unorganized ~ root.asUnorganized; IF u=NIL THEN ERROR; WHILE action DO action _ FALSE; u.containedInstances.Enumerate[MaybeExpand]; ENDLOOP; root _ root; }; END. `LichenFlattenning.Mesa Last tweaked by Mike Spreitzer on February 2, 1988 10:46:41 am PST Κ‹– "cedar" style˜code™K™B—K˜KšΟk œP˜YK˜šΠbxœœ˜ Kšœ=˜DKšœ ˜'K˜—K˜Kšœœ%Οnœ˜;K˜š Ÿ œœœœΟcΠcm œ˜lK˜Kšœ&˜&Kšœ"˜"Kšœœœ˜,Kšœ  ‘ œ˜LšŸ œœ˜+Kš œœœœœœ˜%Kšœ˜Kšœ˜Kšœ˜š œœœœ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ˜—Kš œœœœœœ˜%K˜—šŸ œœ˜(K˜Kšœ˜—šŸœœ˜#Kšœœœ˜!K˜`šŸ œœœ˜IKš œœœœœœ˜9šœœ˜˜ Kš œ œœœœœ˜>Kš œ(œœœœœ0˜ŠKšœ˜šœœ˜K˜*Kšœœ˜—Kš œ2œœœœœ˜pK˜—˜Kšœbœ˜gKšŸ œœ8˜GKšœ˜Kšœ.œœ˜