<> <> DIRECTORY Asserting, LichenDataOps, LichenDataStructure, LichenSetTheory, LichenTransforms, Rope; LichenFlattenning: CEDAR PROGRAM IMPORTS Asserting, LichenDataOps, LichenDataStructure, LichenSetTheory, Rope EXPORTS LichenTransforms = BEGIN OPEN LichenDataOps, LichenDataStructure, LichenSetTheory; ExpandVertex: PUBLIC PROC [child: CellInstance] RETURNS [roleToSib: RefSeq--role ct: CellType ~ child.type; parent: CellType ~ child.containingCT; u: Unorganized ~ ct.asUnorganized; roles: INT ~ u.containedInstances.Size[]; promote: Mapper--part of ct SetPromotion: PROC [inner, outer: Wire] ~ { IF inner=NIL OR outer=NIL THEN ERROR; IF NOT promote.PutMapping[inner, outer] THEN ERROR; 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]; }; role: INT _ 0; MoveCell: PROC [ra: REF ANY] ~ { ci: CellInstance ~ NARROW[ra]; sib: CellInstance ~ Instantiate[ci.type, parent, CrossNames[child.other, ci.other]]; GetPromotion: PROC [vi, uvo: Vertex, port: Port] RETURNS [vo: Vertex] ~ { IF (vo _ NARROW[promote.Map[vi]])#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 Asserting.AssertionsAbout[nameReln, vi.other] ELSE CrossNames[child.other, vi.other]]; IF NOT promote.PutMapping[wi, wo] THEN ERROR; 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, Asserting.AssertionsAbout[nameReln, vi.other]]; PromoteIM: PROC [q: Port, wi: Vertex] ~ {[] _ GetPromotion[wi, io, q]}; IF NOT promote.PutMapping[ii, io] THEN ERROR; 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[role] _ sib; EnumerateImmediateConnections[ci, PromoteEdge]; role _ role+1; }; roleToSib _ CreateRefSeq[roles]; EnumerateTopConnections[child, NotePorting]; u.containedInstances.Enumerate[MoveCell]; DeleteVertex[child]; }; CrossNames: PROC [outer, inner: Assertions] RETURNS [crossed: Assertions] ~ { Crossit: PROC [a1: Assertion] ~ { outerName: ROPE ~ NARROW[Asserting.TermOf[a1]]; Finish: PROC [a2: Assertion] ~ { innerName: ROPE ~ NARROW[Asserting.TermOf[a2]]; name: ROPE ~ outerName.Cat["/", innerName]; crossed _ Asserting.Assert1[nameReln, name, crossed]; }; Asserting.EnumerateAssertionsAbout[nameReln, inner, Finish]; }; crossed _ NIL; Asserting.EnumerateAssertionsAbout[nameReln, outer, Crossit]; crossed _ crossed; }; Flatten: PUBLIC PROC [root: CellType, expand: Filter--of CellInstance--] ~ { action: BOOL _ TRUE; MaybeExpand: PROC [ra: REF ANY] ~ { ci: CellInstance ~ NARROW[ra]; IF expand.HasMember[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.