write('Testing sets ...\n\n');
t := time();

a := {};
b := {};

for i from -1k to 1k do
   insert i into a;
   insert i into b
od;

c := 0;
for i to 50 do
   inc c;
   if a <> b then
      print(tostring(c) & '>1|', '<>')
   fi;
   if not(a = b) then
      print(tostring(c) & '>2|', '=')
   fi;
   if not(a == b) then
      print(tostring(c) & '>3|', '==')
   fi;
   insert 'a' into a;
   if a = b then
      print(tostring(c) & '>4|', '<>')
   fi;
   if a = b then
      print(tostring(c) & '>5|', '=')
   fi;
   if a == b then
      print(tostring(c) & '>6|', '==')
   fi;
   delete 'a' from a;
   d := copy(a);
   if a <> d then
      print(tostring(c) & '>7|', 'copy <>')
   fi;
   if not(a = d) then
      print(tostring(c) & '>8|', 'not/=')
   fi;
   if not(a == d) then
      print(tostring(c) & '>9|', 'not/==')
   fi;
   if size(a) <> size(d) then
      print(tostring(c), 'size')
   fi;
   if not(filled(a)) then
      print(tostring(c), 'filled')
   fi;
   if 'a' in a then
      print(tostring(c), 'in')
   fi;
   if not(0 in a) then
      print(tostring(c), 'in')
   fi;
   if not('a' notin a) then
      print(tostring(c), 'notin')
   fi;
   if 0 notin a then
      print(tostring(c), 'notin')
   fi;
   if a intersect b <> a then
      print(tostring(c), 'intersect')
   fi;
   if a minus b <> {} then
      print(tostring(c), 'minus')
   fi;
   insert 'a' into b;
   if not(a subset b) then
      print(tostring(c), 'subset')
   fi;
   if not(a xsubset b) then
      print(tostring(c), 'xsubset')
   fi;
   delete 'a' from b;
   a1 := {}; b1 := {}; c1 := {};
   for i from 1 to 100 do
      insert i into a1;
      insert i+100 into b1;
   od;
   for i from 1 to 200 do
      insert i into c1
   od;
   if a1 union b1 <> c1 then
      print(tostring(c), 'union')
   fi;
   str := 'if tables.indices(a) <> tables.indices(b) then';
   if join(toseq(str)) <> str then
      print(tostring(c), 'join')
   fi;
   b2 := {3, 6};
   if map(<< (x) ->  x^2 >>, b2) <> {9, 36} then
      print(tostring(c), 'map')
   fi;
   if reduce(<< item, accumulator -> item + accumulator >>, {1, 2, 3, 4}, 0) <> 10 then
      print(tostring(c), 'reduce')
   fi;
   a3 := {};
   b3 := {};
   for i to 1000 do
      insert i into a3;
      if i > 500 then
         insert i into b3
      fi
   od;
   if select(<< x -> x > 500 >>, a3) <> b3 then
      print(tostring(c), 'select, 1')
   fi;
   c3 := toset(nseq(2, 1000, 2));  # sequence of even numbers
   if select( << x -> even(x) >>, a3, newarray=true) <> c3 then
      print(tostring(c), 'select, 2')
   fi;
   c4 := toset(nseq(1, 1000, 2));
   if remove(<< x -> even(x) >>, a3) <> c4 then
      print(tostring(c), 'remove, 1')
   fi;
   if remove(<< x -> even(x) >>, a3, newarray=true) <> c4 then
      print(tostring(c), 'remove, 2')
   fi;
   if remove(<< x, y -> even(x-y) >>, a3, 1, newarray=true) <> c3 then
      print(tostring(c), 'remove, 3')
   fi;
   p, q := selectremove(<< x -> even(x) >>, a3);
   if p <> c3 then
      print(tostring(c), 'selectremove, 1')
   fi;
   if q <> c4 then
      print(tostring(c), 'selectremove, 2')
   fi;
   p, q := selectremove(<< x -> even(x) >>, a3, newarray=true);
   if p <> c3 then
      print(tostring(c), 'selectremove, 3')
   fi;
   if q <> c4 then
      print(tostring(c), 'selectremove, 4')
   fi;
   a5 := {};
   insert a5 into a5
   if environ.isselfref(a5) <> true then
      print(tostring(c), 'environ.isselfref')
   fi;
   a5 := {}
   for i to 1k do
      rawset(a5, i, i);
   od;
   for i to 1k do
      rawset(a5, i, null);
   od;
   if a5 <> {} then
      print(tostring(c), 'rawset')
   fi
   for i to 1k do
      a5[i] := i
   od;
   for i to 1k do
      a5[i] := null
   od;
   if a5 <> {} then
      print(tostring(c), 'rawset')
   fi
od;

writeline('\nDone in ' & time()-t & ' seconds');


# delete all global variables
clear a, a1, a3, a5, b, b1, b3, c, c1, c3, c4, d, i, p, q, str, t;
