IMPLEMENTATION MODULE Set2;

FROM List IMPORT List;
IMPORT SYSTEM;

  CLASS Set2(Element);
  
    VAR
      TheList: List(Element);
      
    REDEFINE METHOD CREATE;
      BEGIN
      TheList.CREATE;
      END CREATE;
      
    METHOD Find(El: Element): INTEGER;
      BEGIN
      RESULT := -1;
      FOR i := 0 TO TheList.Size - 1 WHILE RESULT < 0 DO
        IF TheList.Get(i) = El THEN
          RESULT := i;
          END;
        END;
      END Find;
      
    METHOD Add(El: Element);
      VAR
        i: INTEGER;
      BEGIN
      i := Find(El);
      IF i = -1 THEN
        TheList.Append(El);
        END;
      END Add;
      
    METHOD Remove(El: Element);
      VAR
        i: INTEGER; 
      BEGIN
      i := Find (El);
      IF i >= 0 THEN
        TheList.Delete(i);
        END;
      END Remove;
      
    METHOD Row: ARRAY OF Element;
      BEGIN
      RESULT.CREATE (TheList.Size);
      FOR i := 0 TO TheList.Size - 1 DO
        RESULT[i] := TheList.Get(i);
        END;
      END Row;
      
    METHOD Intersects (Other: Set2(Element)): BOOLEAN;
      BEGIN
      FOR i := 0 TO TheList.Size - 1 WHILE NOT RESULT DO
        RESULT := Other.Find(TheList.Get(i)) <> -1;
        END;
      END Intersects;
      
    METHOD Intersection (Other: Set2(Element)): Set2(Element);
      BEGIN
      RESULT.CREATE;
      FOR i := 0 TO TheList.Size - 1 DO
        IF Other.Find(TheList.Get(i)) <> -1 THEN
          RESULT.TheList.Append(TheList.Get(i));
          END;
        END;
      END Intersection;
      
    METHOD Union (Other: Set2(Element)): Set2(Element);
      BEGIN
      RESULT.CREATE;
      RESULT := Other.CLONE;
      FOR i := 0 TO Other.Size - 1 DO
        IF RESULT.Find(Other.TheList.Get(i)) = -1 THEN
          RESULT.TheList.Append(Other.TheList.Get(i));
          END;
        END;
      END Union;          

    METHOD DoUnion (Other: Set2(Element));
      BEGIN
      FOR i := 0 TO Other.Size - 1 DO
        IF THIS.Find(Other.TheList.Get(i)) = -1 THEN
          THIS.TheList.Append(Other.TheList.Get(i));
          END;
        END;
      END DoUnion;
      
    REDEFINE METHOD CLONE (Other: Set2(Element));
      BEGIN
      Other.TheList := TheList.CLONE;
      END CLONE;
      
    METHOD Size: INTEGER;
      BEGIN
      RESULT := TheList.Size;
      END Size;
      
  END Set2;

END Set2;
