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

a := seq();
b := seq();

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

c := 0;
for i to 10 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 [1, 2] in seq([1, 2]) <> true then
      print(tostring(c), 'in')
   fi;
   if [1, 2] in seq() <> false then
      print(tostring(c), 'in')
   fi;
   if 1:2 in seq(1:2) <> true then
      print(tostring(c), 'in')
   fi;
   if 1:2 in seq() <> false then
      print(tostring(c), 'in')
   fi;
   if seq(1, 2) in seq(seq(1, 2)) <> true then
      print(tostring(c), 'in')
   fi;
   if seq(1, 2) in seq() <> false then
      print(tostring(c), 'in')
   fi;
   if reg(1, 2) in seq(reg(1, 2)) <> true then
      print(tostring(c), 'in')
   fi;
   if reg(1, 2) in seq() <> false then
      print(tostring(c), 'in')
   fi;
   if a intersect b <> a then
      print(tostring(c), 'intersect')
   fi;
   if a minus b <> seq() 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;
   if bintersect(a, b) <> a then
      print(tostring(c), 'bintersect')
   fi;
   if bminus(a, b) <> seq() then
      print(tostring(c), 'bminus')
   fi;
   if not(bisequal(a, b)) then
      print(tostring(c), 'bminus')
   fi;
   if getentry(a, 1) <> -100 then
      print(tostring(c), 'getentry')
   fi;
   if getentry(a, -1) <> null then
      print(tostring(c), 'getentry')
   fi;
   d := copy(a);
   insert 0 into d;
   if duplicates(d) <> seq(0) then
      print(tostring(c), 'duplicates')
   fi;
   clear d;
   d := copy(a);
   if a <> unique(d) then
      print(tostring(c), 'unique')
   fi;
   a1 := seq(); b1 := seq(); c1 := seq();
   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;
   d := [];
   for i to 1000 do insert i into d od;
   if qsadd(d) <> 333833500 then
      print(tostring(c), 'qsadd')
   fi;
   if sadd(d) <> 500500 then
      print(tostring(c), 'sadd, 1')
   fi;
   clear d;
   d := seq();
   for i from -100 to 100 do insert i^2 into d od;
   if sadd(d) <> sadd(map(<< x -> x^2 >>, a)) then
      print(tostring(c), 'sadd, 2')
   fi;
   clear d;
   a2 := seq(1, 2);
   b2 := seq(1, 2);
   if zip(<< (x, y) ->  x + y >>, a2, b2) <> seq(2, 4) then
      print(tostring(c), 'zip')
   fi;
   b2 := seq(3, 6);
   if map(<< (x) ->  x^2 >>, b2) <> seq(9, 36) then
      print(tostring(c), 'map')
   fi;
   if reduce(<< item, accumulator -> item + accumulator >>, seq(1, 2, 3, 4), 0) <> 10 then
      print(tostring(c), 'reduce')
   fi;
   a3 := seq();
   b3 := seq();
   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 := 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 := 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;
   if countitems(<< x -> x > 500 >>, a3) <> 500 then
      print(tostring(c), 'countitems')
   fi;
   a4 := seq('a', 'a', 1000, 'a');
   if whereis(a4, 'a') <> seq(1, 2, 4) then
      print(tostring(c), 'whereis')
   fi;
   a5 := seq();
   insert a5 into a5
   if environ.isselfref(a5) <> true then
      print(tostring(c), 'environ.isselfref')
   fi;
   if smul(seq(1.0, 1.1, 1.2, 1.3, 1.4, 1.5)) <> 3.6036 then
      print(tostring(c), 'smul')
   fi
od;

a := seq('a', 'b', 'c', 'd');
to 50 do
   c1 := join(a);
   c2 := join(a, '+', 2, 3);
od;
if c1 <> 'abcd' then print('error in join') fi;
if c2 <> 'b+c' then print('error in join') fi;


# seq bug with inserts and subsequent deletions (earlier than Agena 1.0.6)
a := seq();

for i to 128 do
   insert i into a;
   delete i from a
od;

if filled(a) then print('Error in seqs/delete') fi;

for i to 128 do
   insert i into a;
   if top(a) <> i then print('error in top') fi;
   if bottom(a) <> i then print('error in bottom') fi;
   pop top from a;
   pop bottom from a
od;

if filled(a) then print('Error in seqs/pop') fi;

a := seq(10, 20, 30, 40, 50);
for i to 128 do
   c := a[2 to 3]
od;

if c <> seq(20, 30) then print('error in new sublists/seqs, 1') fi;

for i to 128 do
   local c1 := a[2 to 3]
   c := c1
od;

if c <> seq(20, 30) then print('error in new sublists/seqs, 2') fi;

f := proc(x, a, b) is
   return x[a to b]
end;

for i to 128 do
   local c1 := f(a, 2, 3)
   c := c1
od;

if c <> seq(20, 30) then print('error in new sublists/seqs, 3') fi;

a := seq('a', 'b', 'c');
for i to 1k do
   c := values(a, 1, 2, 3)
od;
if a <> c then error('error in values/sequence') fi;

x := nseq(1, 100);

for i to 16 do
   rotate bottom x
od;

for i to 16 do
   rotate top x
od;

if x <> nseq(1, 100) then
   print('Error in rotate statement, 1')
fi;

for i from 100 to 1 by -1 do
   if pop(x) <> i then
      print('Error in pop statement, 1')
   fi
od;

if x <> seq() then
   print('Error in pop statement, 2')
fi;

to 10 do
   s := seq(1, 2, 3);
   exchange s;
   duplicate s
od;

if s <> seq(1, 3, 2, 2) then
   print('Error in duplicate/exchange statement')
fi;

if (/ 0 1 2 -3 zero one two three '2and3' \) <>
   seq(0, 1, 2, -3, 'zero', 'one', 'two', 'three', '2and3') then
   print('Error in (/')
fi;

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

# delete all global variables
clear a, a1, a2, a3, a4, a5, b, b1, b2, b3, c, c1, c2, c3, c4, f, i, k, str, p, q, s, t, v, x;

