Set
is a generic interface defining sets of Elem.T
's.
GENERIC MODULESet is an abstract type, but many of it's operations can be implemented reasonably efficiently independently of any specific representation decisison. Those are defined here. Of course, subtypes may choose representations that offer the possibility of more efficient implementations, and would therefore override these methods.Set (Elem);
REVEAL T = Public BRANDED OBJECT OVERRIDES isEmpty := IsEmpty; subset := Subset; equal := Equal; intersect := Intersect; union := Union; intersection := Intersection; diff := Diff; unionD := UnionD; intersectionD := IntersectionD; diffD := DiffD; END; PROCEDUREIsEmpty (s: T): BOOLEAN = BEGIN RETURN s.size() = 0 END IsEmpty; PROCEDURESubset (s: T; s2: T): BOOLEAN = BEGIN IF s.size() > s2.size() THEN RETURN FALSE ELSE VAR iter := s.iterate(); e: Elem.T; BEGIN WHILE iter.next(e) DO IF NOT s2.member(e) THEN RETURN FALSE END (* IF *) END (* WHILE *) END (* BEGIN *); RETURN TRUE END (* IF *) END Subset; PROCEDUREEqual (s1, s2: T): BOOLEAN = BEGIN RETURN s1.size() = s2.size() AND s1.subset(s2) AND s2.subset(s1) END Equal; PROCEDUREIntersect (s: T; s2: T): BOOLEAN = BEGIN (* Make "s" the smaller. *) IF s.size() > s2.size() THEN VAR tmp := s; BEGIN s := s2; s := tmp END END (* IF *); VAR iter := s.iterate(); e: Elem.T; BEGIN WHILE iter.next(e) DO IF s2.member(e) THEN RETURN TRUE END (* IF *) END (* WHILE *); RETURN FALSE END (* BEGIN *) END Intersect; PROCEDUREUnion (s1: T; s2: T): T = VAR s3 := s1.copy(); BEGIN RETURN s3.unionD(s2) END Union; PROCEDUREIntersection (s1: T; s2: T): T = VAR s3 := s1.copy(); BEGIN RETURN s3.intersectionD(s2) END Intersection; PROCEDUREDiff (s1: T; s2: T): T = VAR s3 := s1.copy(); BEGIN RETURN s3.diffD(s2) END Diff; PROCEDUREUnionD (s1: T; s2: T): T = VAR iter := s2.iterate(); e: Elem.T; BEGIN WHILE iter.next(e) DO EVAL s1.insert(e) END (* WHILE *); RETURN s1 END UnionD; PROCEDUREIntersectionD (s1: T; s2: T): T = VAR iter := s1.iterate(); e: Elem.T; BEGIN WHILE iter.next(e) DO IF NOT s2.member(e) THEN EVAL s1.delete(e) END (* IF *) END (* WHILE *); RETURN s1 END IntersectionD; PROCEDUREDiffD (s1: T; s2: T): T = VAR iter := s1.iterate(); e: Elem.T; BEGIN WHILE iter.next(e) DO IF s2.member(e) THEN EVAL s1.delete(e) END (* IF *) END (* WHILE *); RETURN s1 END DiffD; BEGIN END Set.