<> <> DIRECTORY AbSets, BasicTime, BiRels, Interpreter, LichenDataStructure, LichenIntBasics, Rope, RopeHash, SetBasics; LichenDataImpl1B: CEDAR PROGRAM IMPORTS AbSets, BiRels, LichenDataStructure, SetBasics EXPORTS LichenDataStructure = BEGIN OPEN IB:LichenIntBasics, IB, LichenDataStructure, Sets:AbSets; ClassOfPart: PUBLIC PROC [part: Part] RETURNS [PartClass] ~ { WITH part SELECT FROM p: Port => RETURN [p]; w: Wire => RETURN [w]; ci: CellInstance => RETURN [i]; ENDCASE => ERROR}; Sub: PUBLIC PROC [d: Design, x: PW, i: LNAT] RETURNS [PW] ~ { kids: Seq ~ BiRels.DeRef[d.sub.ApplyA[x].MA]; RETURN [kids.ApplyI[i].MA]}; PIndex: PUBLIC PROC [d: Design, ep: Port, parent: Port _ NIL] RETURNS [LNAT] ~ { IF parent=NIL THEN parent _ d.PParent[ep]; {children: Seq--of child-- ~ BiRels.DeRef[d.sub.ApplyA[parent].MA]; RETURN [children.Lookup[AV[ep]].MI]}}; WIndex: PUBLIC PROC [d: Design, ew: Wire, parent: Wire _ NIL] RETURNS [LNAT] ~ { IF parent=NIL THEN parent _ d.WParent[ew]; {children: Seq--of child-- ~ BiRels.DeRef[d.sub.ApplyA[parent].MA]; RETURN [children.Lookup[AV[ew]].MI]}}; SubseqIndex: PUBLIC PROC [d: Design, kids: Seq] RETURNS [ssi: SubsIndex _ [NIL, FALSE, FALSE, FALSE, 0]] ~ { parentskids: Seq _ nilBiRel; first: BOOL _ TRUE; PerKid: PROC [pair: BiRels.Pair] RETURNS [BOOL] ~ { index: INT ~ pair[left].VI; kid: PW ~ pair[right].VA; IF first THEN { first _ FALSE; ssi.parent _ d.parent.ApplyA[kid].MDA; IF ssi.parent=NIL THEN RETURN [FALSE]; ssi.sub _ TRUE; parentskids _ BiRels.DeRef[d.sub.ApplyA[ssi.parent].MA]; ssi.offset _ parentskids.Lookup[AV[kid]].MI - index; RETURN [FALSE]} ELSE { ssi.multiparents _ ssi.multiparents OR d.parent.ApplyA[kid].MDA # ssi.parent; ssi.sub _ ssi.sub AND (NOT ssi.multiparents) AND parentskids.ApplyI[index + ssi.offset].MDA = kid; RETURN[ssi.multiparents]}; }; [] _ kids.Scan[PerKid, BiRels.leftFwd]; ssi.full _ ssi.sub AND ssi.offset=0 AND parentskids.Size=kids.Size; RETURN}; ExportableKids: PUBLIC PROC [ct: CellType, kids: Seq--of Wire--] RETURNS [BOOL] ~ { RETURN [kids.SkipTo[ct.asu.stuck].found]}; TopParts: PUBLIC PROC [ct: CellType, class: PWClass] RETURNS [Set] ~ { RETURN[ ct.d.cct[class].MappingA[ct, rightToLeft].Intersection[ct.d.isTop]]}; EnumCTParts: PUBLIC PROC [ct: CellType, class: PartClass, atomic, composite: BOOL, Consume: PROC [Part]] ~ { PassPart: PROC [v: Sets.Value] ~ { part: REF ANY ~ v.VA; IF (atomic AND composite) OR (IF ct.d.Atomic[part] THEN atomic ELSE composite) THEN Consume[v.VA]; RETURN}; IF atomic OR composite THEN ct.d.cct[class].EnumerateMapping[AV[ct], PassPart, rightToLeft]; RETURN}; NonPublicDescendants: PUBLIC PROC [ct: CellType, w: Wire] RETURNS [Set] ~ { RETURN [PWDescendants[ct.d, w].Difference[ct.asu.publics]]}; Subcells: PUBLIC PROC [ct: CellType] RETURNS [Set--of CellInstance--] ~ { RETURN ct.d.cct[i].MappingA[ct, rightToLeft]}; TypeSites: PUBLIC PROC [ct: CellType] RETURNS [Set--of Cell--] ~ { RETURN [Subcells[ct].Union[Sets.CreateSingleA[ct, ct.d.eSpace]]]}; SiteConns: PUBLIC PROC [site: Cell] RETURNS [conns: Fn--Port WITH site SELECT FROM ct: CellType => conns _ ct.asu.exports; ci: CellInstance => conns _ ci.conns; ENDCASE => ERROR; RETURN}; CTParts: PUBLIC PROC [ct: CellType, class: PartClass] RETURNS [Set] ~ { RETURN [ct.d.cct[class].MappingA[ct, rightToLeft]]}; ConndWire: PUBLIC PROC [c: Cell, p: Port] RETURNS [Wire] ~ { WITH c SELECT FROM ct: CellType => { IF ct.asu=NIL THEN ERROR; RETURN [NARROW[ct.asu.exports.ApplyA[p].MDA]]}; ci: CellInstance => RETURN [NARROW[ci.conns.ApplyA[p].MDA]]; ENDCASE => ERROR; }; AConndPort: PUBLIC PROC [c: Cell, w: Wire] RETURNS [Port] ~ { conns: Fn--Port ct: CellType => ct.asu.exports, ci: CellInstance => ci.conns, ENDCASE => ERROR; RETURN [NARROW[conns.Lookup[goal: AV[w], order: Sets.alleq].MDA]]}; NFetchCellType: PUBLIC PROC [d: Design, name: ROPE] RETURNS [CellType] ~ {RETURN d.FetchCellType[name]}; EnumerateUses: PUBLIC PROC [ct: CellType, Consume: PROC [CellUse]] ~ { Convert: PROC [civ: Sets.Value] ~ {Consume[civ.VA]; RETURN}; ct.d.arrayElt.EnumerateMapping[AV[ct], Convert, rightToLeft]; ct.d.ciType.EnumerateMapping[AV[ct], Convert, rightToLeft]; RETURN}; Start: PROC ~ { RETURN}; Start[]; END.