
/* Test script for the Yacas computer algebra system.
 * Copyright 1999 Ayal Pinkus
 *
 */


curline:=0;
Function("Next",{aLeft})
[
 NewLine();
 curline++;
 Write(curline);
 WriteString(". ");
 WriteString(aLeft); WriteString(" : ");
];
Function("Testing",{aLeft})
[
 WriteString(aLeft); Space();
];












Clear(a,b);

Next("Testing some internal functions");

Verify(aa-aa,0);
Testing("Apply");
Verify(Apply("+",{2,3}),5);
[
  Local(x,y);
  Verify(Apply({{x,y},x+y},{2,3}),5);
  Verify(x,x);
  Verify(y,y);

  Testing("ThreadingListables");
  x:={bb,cc,dd};
  Verify(Sin(aa*x),{Sin(aa*bb),Sin(aa*cc),Sin(aa*dd)});
];

Testing("Bases");
Verify(ToBase(16,255),ff);
Verify(FromBase(2,100),4);

Testing("Length");
Verify(Length({a,b}),2);
Verify(Length({}),0);

Testing("Nth");
Verify(Nth({a,b},1),a);
Verify({a,b,c}[[2]],b);

Testing("Concat");
Verify(Concat({a,b},{c,d}),{a,b,c,d});
Verify(Hold(Concat({a,b},{c,d})),Concat({a,b},{c,d}));

Testing("ListOperations");
Verify(Head({a,b,c}),a);
Verify(Tail({a,b,c}),{b,c});
Verify(DestructiveReverse({a,b,c}),{c,b,a});
Verify(UnList({a,b,c}),a(b,c));
Verify(Listify(a(b,c)),{a,b,c});

Verify(Delete({a,b,c},2),{a,c});
Verify(Insert({a,c},2,b),{a,b,c});

Testing("BooleanOperations");
Verify(False And False,False);
Verify(True And False,False);
Verify(False And True,False);
Verify(True And True,True);

Verify(False Or False,False);
Verify(True Or False,True);
Verify(False Or True,True);
Verify(True Or True,True);

Verify(Not(True),False);
Verify(Not(False),True);

Verify(Equals(a,b),False);
Verify(Equals(a,a),True);
Verify(Equals({a,b},{a}),False);
Verify(Equals({a,b},{a,b}),True);

Testing("NumberCompares");
Verify(LessThan(2,3),True);
Verify(LessThan(3,2),False);
Verify(GreaterThan(2,3),False);
Verify(GreaterThan(3,2),True);

Verify(.1<2,True);
Verify(0.1<2,True);
Verify(.3<2,True);
Verify(.1>2,False);
Verify(0.1>2,False);
Verify(.3>2,False);

Verify(2<.1,False);
Verify(2<0.1,False);
Verify(2<.3,False);
Verify(2>.1,True);
Verify(2>0.1,True);
Verify(2>.3,True);


Verify(Atom("a"),a);
Verify(String(a),"a");

Testing("Predicates");
Verify(IsFunction(a(b)),True);
Verify(IsFunction(a),False);
Verify(IsList({a,b,c}),True);
Verify(IsList(a),False);
Verify(IsAtom({a,b,c}),False);
Verify(IsAtom(a),True);
Verify(IsAtom(123),True);

Verify(IsNumber(123),True);
Verify(IsNumber(123.123),True);
Verify(IsNumber(a),False);
Verify(IsNumber({a}),False);

Verify(IsInteger(123),True);
Verify(IsInteger(123.123),False);
Verify(IsInteger(a),False);
Verify(IsInteger({a}),False);

Testing("IntegerOperations");
Verify(1<<10,1024);
Verify(1024>>10,1);
Verify(Mod(10,3),1);
Verify(Div(10,3),3);
Verify(MathGcd(55,10),5);

Testing("LocalVariables");
[
  Verify(IsBound({}),False);
  Local(a);
  Verify(IsBound(a),False);
  a:=1;
  Verify(IsBound(a),True);
  Clear(a);
  Verify(IsBound(a),False);
];

Testing("MapSingle");
Verify(MapSingle("!",{1,2,3,4}),{1,2,6,24});


/* Example: using the for function. */
Function("count",{from,to})
[
   Local(i);
   Local(sum);
   Set(sum,0);
   For(i:=from,i<to,i:=i+1)
   [
     Set(sum,sum+i); 
   ];
   sum;
];

Testing("Function definitions");
Verify(count(1,11),55);

TryRetract("count",2);

[
  Local(l);
  l:={1,2,3};
  DestructiveDelete(l,1);
  Verify(l,{2,3});
  DestructiveInsert(l,1,1);
  Verify(l,{1,2,3});
  l[[1]] := 2;
  Verify(l,{2,2,3});
  l[[1]] := 1;
  DestructiveDelete(l,3);
  Verify(l,{1,2});
  DestructiveInsert(l,3,3);
  Verify(l,{1,2,3});
  DestructiveDelete(FlatCopy(l),1);
  Verify(l,{1,2,3});
];

Verify(Table(i!,i,1,4,1),{1,2,6,24});
Verify(Permutations({a,b,c}),{{a,b,c},{a,c,b},{c,a,b},{b,a,c},{b,c,a},{c,b,a}});

Verify(Type(Cos(x)),"Cos");
Verify(NrArgs(Cos(x)),1);
Verify(Contains({a,b,c},b),True);
Verify(Contains({a,b,c},d),False);
Verify(Append({a,b,c},d),{a,b,c,d});
Verify(RemoveDuplicates({a,b,b,c}),{a,b,c});
Verify(Count({a,b,b,c},b),2);
Verify(VarList(x*Cos(x)),{x});


Next("Testing math stuff");
Verify(1*a,a);
Verify(a*1,a);
Verify(0*a,0);
Verify(a*0,0);
Verify(aa-aa,0);

Verify(2+3,5);
Verify(2*3,6);

Verify(2+3*4,14);
Verify(3*4+2,14);
Verify(3*(4+2),18);
Verify((4+2)*3,18);

Verify(15/5,3);

 Verify(-2+3,1);
Verify(-2.01+3.01,1);

Verify(0+a,a);
Verify(a+0,a);

Verify(4!,24);
Verify(Bin(2,1),2);

Testing("Derivatives");
Verify(D(x) a,0);
Verify(D(x) x,1);
Verify(D(x) x+x,2);
Verify(D(x) x*x,2*x);
Verify(D(x) D(x) Sin(x),-Sin(x));

Verify(Apply("+",{2,3}),5);

Testing("BubbleSort");
Verify(BubbleSort({2,3,1},"<"),{1,2,3});
Verify(BubbleSort({2,3,1},">"),{3,2,1});

Testing("LeviCivita");
Verify(LeviCivita({1,2,3}),1);
Verify(LeviCivita({2,1,3}),-1);
Verify(LeviCivita({1,1,3}),0);

Testing("VectorProducts");
[
  Local(l,m,n);
  l:={1,0,0};
  m:={0,1,0};
  n:={0,0,1};

  Verify(l X m, {0,0,1});
  Verify(m X n, {1,0,0});
  Verify(n X l, {0,1,0});
  Verify(l X n, {0,-1,0});

  Verify(l . m, 0);
  Verify(m . n, 0);
  Verify(n . l, 0);

  Verify(l . l, 1);
];

Testing("UnaryFunctionInverses");
Verify(Sin(ArcSin(a)),a);
Verify(Cos(ArcCos(a)),a);
Verify(Tan(ArcTan(a)),a);
Verify(ArcSin(Sin(a)),a);
Verify(ArcCos(Cos(a)),a);
Verify(ArcTan(Tan(a)),a);

Verify(2+I*3,Complex(2,3));
Verify(Re(2+I*3),2);
Verify(Im(2+I*3),3);
Verify(ZeroVector(3),{0,0,0});
Verify(BaseVector(2,3),{0,1,0});
Verify(Identity(3),{{1,0,0},{0,1,0},{0,0,1}});

Testing("Solve");
Verify(Solve(a+x*y=z,x),(z-a)/y);
/*TODO PSolve, MatrixSolve*/



Next("Basic calculations"); 
Verify(3 + 2 , 5);
Verify(3-7, -4);
Verify(1 = 2 , 0 = -1);
Verify(5 ^ 2 , 25);

[
  Local(aa,b);

/* Strangeness: change variable below into a, and the crossproducts
 * later on fail!
 */
  a:={1,2,3};
  b:={3,1,5};
  Verify( a . b , 20);
  Verify(CrossProduct({1,2,3} , {4,2,5}) , {4,7,-6});
];
Verify(aa,Hold(aa));


Next("Inproduct"); 
a:={1,2,3};
b:={3,1,5};
Verify( a . b , 20);

Verify(CrossProduct({1,2,3} , {4,2,5}) , {4,7,-6});
Verify({1,2,3} X {4,2,5},{4,7,-6});


Next("Identity matrices"); 
Verify(Identity(4),
   { {1,  0,  0,  0} ,
     {0,  1,  0,  0} ,
     {0,  0,  1,  0} ,
     {0,  0,  0,  1} });

Next("VarList");
Verify(VarList(x^2+y^3) , {x , y});
Verify(List(1,2,3),{1 , 2 , 3});


Verify(IsZero(0.000),True);

Verify(Factorize(i,1,3,i),6);
Clear(aa,b,c,d);
Verify(Intersection({aa,b,c},{b,c,d}),{b,c});
Verify(Union({aa,b,c},{b,c,d}),{aa,b,c,d});
Verify(Difference({aa,b,c},{b,c,d}),{aa});




Next("Check linear algebra");
/* Normalize */
Testing("Normalize");
Verify(N(Normalize({3,4})),N({3/5,4/5}));
/* DiagonalMatrix */
Testing("DiagonalMatrix");
Verify(DiagonalMatrix({2,3,4}),{{2,0,0},{0,3,0},{0,0,4}});
/* ZeroMatrix */
Testing("ZeroMatrix");
Verify(ZeroMatrix(2,3),{{0,0,0},{0,0,0}});
/* Transpose */
Testing("Transpose");
Verify(Transpose({{a,b},{c,d}}),{{a,c},{b,d}});
/* Determinant */
Testing("Determinant");
Verify(Determinant({{2,3},{3,1}}),-7);

ll:={ {1,2,3},
      {2,-1,4},
      {3,4,3}
    };
/* CoFactor */
Testing("CoFactor");
Verify(N(CoFactor(ll,1,2)),6);
/* Minor */
Testing("Minor");
Verify(N(Minor(ll,1,2)),-6);
/* Inverse */
Testing("Inverse");
Verify(Inverse(ll)*ll,Identity(3));
/* SolveMatrix */
Testing("SolveMatrix");
Verify(ll*SolveMatrix(ll,{1,2,3}),{1,2,3});
/* Trace */
Testing("Trace");
Verify(Trace(ll),1-1+3);
/* IsVector */
Verify(IsVector(ll),True);
Verify(IsVector({1,2,3}),True);
/* IsMatrix */
Verify(IsMatrix(ll),True);
Clear(ll);  

Next("Test rationals");
Verify(2/5,Hold(2/5));
Verify(N(2/5),0.4);
Verify(IsRational(2/5),True);
Verify(Numer(2/5),2);
Verify(Denom(2/5),5);

Verify(ConcatStrings("a","b","c"),"abc");

f1(x,n,m):=(x^n-1)*(x^m-1);
f2(x,n,m):=x^(n+m)-(x^n)-(x^m)+1;

ver(x,n,m):=
[
  WriteString("Checking arithmetic with ");
  Write(x);Space();
  Write(n);Space();
  Write(m);NewLine();
  Verify(f1(x,n,m),f2(x,n,m));
];

ver(10,5,8);
ver(10000000000,5,8);
ver(10,50,80);
ver(10000,50,88);

Next("Polynomials");
Verify(Expand((1+x)^2),1+2*x+x^2);


/*
Verify();
Verify();
Verify();
Verify();
Verify();
Verify();
Verify();
Verify();
Verify();
Verify();
*/


Next("Tests completed");
NewLine();

TryRetract("Next",1);


