<> <> DIRECTORY AbSets, BiRels, LichenDataOps, LichenIntBasics, LichenDataStructure, Rope, SetBasics; LichenChecking: CEDAR PROGRAM IMPORTS AbSets, BiRels, LichenDataStructure, SetBasics = BEGIN OPEN LichenDataOps, LichenDataStructure, Sets:AbSets; CheckDesign: PUBLIC PROC [d: Design] = { CheckSubscript: PROC [pw, kidsa: REF ANY] ~ { class: PWClass ~ ClassOfPart[pw]; cct: CellType ~ NARROW[d.cct[class].ApplyA[pw].MA]; kids: Seq--of PW-- ~ BiRels.DeRef[kidsa]; CheckKid: PROC [index: INT, kid: PW] ~ { IF class # ClassOfPart[kid] THEN Error["Broken"]; IF d.cct[class].ApplyA[kid].MA # cct THEN Error["Broken"]; IF NOT d.parent.HasAA[kid, pw] THEN Error["Broken"]; RETURN}; kids.EnumIA[CheckKid]; RETURN}; PerCellType: PROC [ra: REF ANY] = { ct: CellType ~ NARROW[ra]; IF ct.d # d THEN Error["Broken"]; CheckCellType[ct]; }; d.cellTypes.EnumA[PerCellType]; RETURN}; CheckCellType: PUBLIC PROC [ct: CellType] = { d: Design ~ ct.d; IF NOT d.cellTypes.HasMemA[ct] THEN Error["Broken"]; IF (ct.asArray#NIL) # d.arrayElt.HasMapA[ct] THEN Error["Broken"]; IF ct.asu # NIL THEN { CheckSubcell: PROC [ra: REF ANY] ~ { ci: CellInstance ~ NARROW[ra]; ict: CellType ~ d.CiT[ci]; typePorts: Set ~ ict.CTParts[p]; atomics: Set ~ typePorts.Intersection[d.isAtomic]; IF NOT atomics.Difference[ci.conns.SetOn[left]].Empty THEN Error["Broken"]; RETURN}; ct.Subcells.EnumA[CheckSubcell]; }; RETURN}; END.