[Oberon] OBNC Sets incorrect output

Diego Sardina dsar at eml.cc
Sun Mar 20 17:58:11 CET 2022


On Sun, Mar 20, 2022, at 4:44 PM, Joe Turner wrote:
> 
> [...] Anyway, I'll look around for a library, or I guess it wouldn't be too hard to write one myself using an array of boolean.
> 

Or an array of SET ;-)


MODULE Sets;

  IMPORT SYSTEM;

  CONST size = SYSTEM.SIZE(SET) * 8;

  PROCEDURE Clear* (VAR s: ARRAY OF SET);
    VAR i: INTEGER;
  BEGIN
    FOR i := 0 TO LEN(s)-1 DO s[i] := {} END
  END Clear;

  PROCEDURE Fill* (VAR s: ARRAY OF SET);
    VAR i: INTEGER;
  BEGIN
    FOR i := 0 TO LEN(s)-1 DO s[i] := {0 .. size-1} END
  END Fill;

  PROCEDURE Include* (VAR s: ARRAY OF SET; x: INTEGER);
  BEGIN
    (* ASSERT(x DIV size < LEN(s)); *)
    INCL(s[x DIV size], x MOD size)
  END Include;

  PROCEDURE Exclude* (VAR s: ARRAY OF SET; x: INTEGER);
  BEGIN
    (* ASSERT(x DIV size < LEN(s)); *)
    EXCL(s[x DIV size], x MOD size)
  END Exclude;

  PROCEDURE In* (s: ARRAY OF SET; x: INTEGER): BOOLEAN;
  BEGIN
    (* ASSERT(x DIV size < LEN(s)); *)
    RETURN x MOD size IN s[x DIV size]
  END In;

  PROCEDURE Subset* (s1, s2: ARRAY OF SET): BOOLEAN;
    VAR i: INTEGER;
  BEGIN
    (* ASSERT(LEN(s1) <= LEN(s2)); *)
    i := 0;
    WHILE (i < LEN(s1)) & (s1[i] + s2[i] = s1[i]) DO INC(i) END;
    RETURN i = LEN(s1)
  END Subset;

  PROCEDURE Count* (s: ARRAY OF SET): INTEGER;
    VAR i, n: INTEGER;
  BEGIN
    n := 0;
    FOR i := 0 TO (LEN(s)*size)-1 DO
      IF (i MOD size) IN s[i DIV size] THEN INC(n) END
    END;
    RETURN n
  END Count;

  PROCEDURE Empty* (s: ARRAY OF SET): BOOLEAN;
    VAR i: INTEGER;
  BEGIN
    i := 0;
    WHILE (i < LEN(s)) & (s[i] = {}) DO INC(i) END;
    RETURN i = LEN(s)
  END Empty;

  PROCEDURE Same* (s1, s2: ARRAY OF SET): BOOLEAN;
    VAR i: INTEGER;
  BEGIN
    (* ASSERT(LEN(s1) = LEN(s2)); *)
    i := 0;
    WHILE (i < LEN(s1)) & (s1[i] = s2[i]) DO INC(i) END;
    RETURN i = LEN(s1)
  END Same;

  PROCEDURE Distinct* (s1, s2: ARRAY OF SET): BOOLEAN;
    VAR i: INTEGER;
  BEGIN
    (* ASSERT(LEN(s1) = LEN(s2)); *)
    i := 0;
    WHILE (i < LEN(s1)) & (s1[i] * s2[i] = {}) DO INC(i) END;
    RETURN i = LEN(s1)
  END Distinct;

  PROCEDURE Union* (VAR s1, s2: ARRAY OF SET);
    VAR i: INTEGER;
  BEGIN
    FOR i := 0 TO LEN(s1)-1 DO s1[i] := s1[i] + s2[i] END
  END Union;

  PROCEDURE Difference* (VAR s1, s2: ARRAY OF SET);
    VAR i: INTEGER;
  BEGIN
    FOR i := 0 TO LEN(s1) DO s1[i] := s1[i] - s2[i] END
  END Difference;

  PROCEDURE Intersection* (VAR s1, s2, s3: ARRAY OF SET);
    VAR i: INTEGER;
  BEGIN
    FOR i := 0 TO LEN(s1) DO s3[i] := s1[i] * s2[i] END
  END Intersection;

END Sets.


More information about the Oberon mailing list