<> <> DIRECTORY AbSets, Basics, BiRels, LichenArrayStuff, LichenDataOps, LichenDataStructure, Rope, SetBasics; LichenNewArrayImpl2: CEDAR PROGRAM IMPORTS AbSets, BiRels, LichenArrayStuff, LichenDataStructure, SetBasics = BEGIN OPEN LichenDataOps, LichenDataStructure, LichenArrayStuff, Sets:AbSets; Array: TYPE ~ LichenDataStructure.Array; Cycle: TYPE ~ LORA --where elements are StatEdges, and the first element is the StatEdge at the lowest address--; cycleSpace: SetBasics.Space ~ SetBasics.CreateLORASpace[NIL, LIST[SetBasics.refs]]; FindSimpleCycles: PROC [a: Array] RETURNS [c seenVerts: Set ~ Sets.CreateHashSet[]; Start: PROC [sv: StatVertex] RETURNS [BOOL] ~ { IF NOT seenVerts.AddA[sv] THEN RETURN [FALSE]; {inPath: Set--of StatVertex-- ~ Sets.CreateHashSet[]; stack: LORA _ NIL; ExploreFrom: PROC [sv: StatVertex] ~ { [] _ seenVerts.AddA[sv]; IF inPath.AddA[sv] THEN { CrossEdge: PROC [se: StatEdge, ob: BOOL] RETURNS [BOOL] ~ { stack _ CONS[se, stack]; ExploreFrom[se.vs[ob]]; stack _ stack.rest; RETURN [FALSE]}; stack _ CONS[sv, stack]; IF ScanStatEdgesFrom[a.statrep, sv, CrossEdge].found THEN ERROR; stack _ stack.rest; } ELSE { head, min, minPrev, tail: Cycle _ NIL; setPrev: BOOL _ FALSE; at: StatVertex _ sv; FOR sp: LORA _ stack, sp.rest.rest DO se: StatEdge ~ NARROW[sp.first]; next: StatVertex ~ NARROW[sp.rest.first]; b: BOOL ~ at = se.vs[TRUE]; IF se.vs[b] # at THEN ERROR; head _ CONS[se, head]; IF tail=NIL THEN tail _ head; IF min=NIL OR LOOPHOLE[head.first, INT] < LOOPHOLE[min.first, INT] THEN {min _ head; setPrev _ TRUE} ELSE IF setPrev THEN {minPrev _ head; setPrev _ FALSE}; IF next=sv THEN EXIT; ENDLOOP; IF setPrev THEN min _ head ELSE { IF minPrev.rest#min THEN ERROR; tail.rest _ head; minPrev.rest _ NIL}; [] _ c }; IF NOT inPath.RemA[sv] THEN ERROR; }; ExploreFrom[sv]; RETURN [FALSE]}}; c IF ScanStatVertices[a, Start].found THEN ERROR; RETURN}; HasHardBasis: PROC [act: CellType] RETURNS [BOOL] ~ { IF act.asArray=NIL THEN RETURN [FALSE]; {a: Array ~ act.asArray; c basis: ARRAY Dim OF NATURAL _ ALL[NATURAL.LAST]; Pass1: PROC [left, right: REF ANY] ~ { cycle: Cycle ~ NARROW[left]; IF IF {dim: Dim ~ IF basis[dim] _ MIN[ Pass2: PROC [pair: BiRels.Pair] RETURNS [BOOL] ~ { RETURN [ c RETURN [c END.