
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("Boolean Operations");
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(IsEqual(a,b),False);
Verify(IsEqual(a,a),True);
Verify(IsEqual({a,b},{a}),False);
Verify(IsEqual({a,b},{a,b}),True);

Testing("NumberCompares");
Verify(IsLessThan(2,3),True);
Verify(IsLessThan(3,2),False);
Verify(IsGreaterThan(2,3),False);
Verify(IsGreaterThan(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);

Testing("comparisons in exponential notation");
// some of these failed
Verify(1e-5 < 1, True);
Verify(1e-5 < 2e-5, True);
Verify(1e-1 < 2e-1, True);
Verify(1e-15 < 2e-15, True);
Verify(1e-5 < 1e-10, False);
Verify(1e-5 < 1e-2, True);
Verify(-1e-5 < 1e-5, True);
Verify(-1e-5 < 1e-6, True);
Verify(1e-5 = 2e-5, False);
Verify(1e-5 = 1e-6, False);
Verify(1e-15 > 0, True);
Verify(1e-5 > 0, True);
Verify(1e-4 > 0, True);
Verify(1e-3 > 0, True);
Verify(1e-2 > 0, True);
Verify(1e-1 > 0, True);
Verify(1e5 > 0, True);

BuiltinPrecisionSet(32);
Verify(1.0000000000000000000000000000111 > 1, True);
Verify(0.999999999999999999999999999992 < 1, True);
BuiltinPrecisionSet(10);

Verify(IsLessThan(-1e-115, 0), True);
Verify(IsLessThan(-1e-15, 0), True);
Verify(IsLessThan(-1e-10, 0), True);
Verify(IsLessThan(-1e-5, 0), True);
Verify(IsLessThan(-1e-1, 0), True);

Testing("Matrix predicates");
Verify(IsHermitian({{0,I},{-I,0}}),True);
Verify(IsHermitian({{0,I},{-I,1}}),True);
Verify(IsHermitian({{0,I},{-2*I,0}}),False);

Verify(IsUnitary({{0,I},{-I,0}}),True);
Verify(IsUnitary({{0,I},{-I,1}}),False);
Verify(IsUnitary({{0,I},{-2*I,0}}),False);

Verify(IsVariable(a),True);
Verify(IsVariable(Sin(a)),False);
Verify(IsVariable(2),False);
Verify(IsVariable(-2),False);
Verify(IsVariable(2.1),False);


Verify(HasExpr(a*b+1,1),True);
Verify(HasExpr(a+Sin(b*c),c),True);
Verify(HasExpr(a*b+1,2),False);
Verify(HasExpr(a*b+f({b,c}),f),False);
Verify(HasExprArith(a*b+1,ToAtom("+")),False);
Verify(HasExprArith(a*b+1,1),True);
Verify(HasExprArith(a+Sin(b*c),c),False);
Verify(HasExprArith(a+Sin(b*c),Sin(b*c)),True);
Verify(HasExprArith(a*b+f({b,c}),c),False);

Verify(HasFunc(a*b+1,*),True);
Verify(HasFunc(a+Sin(b*c),*),True);
Verify(HasFunc(a*b+1,List),False);
Verify(HasFunc(a*b+f({b,c}),List),True);
Verify(HasFuncArith(a*b+1,ToAtom("+")),True);
Verify(HasFuncArith(a+Sin(b*c),*),False);
Verify(HasFuncArith(a+Sin(b*c),Sin),True);
Verify(HasFuncArith(a*b+f({b,c}),List),False);

Verify(IsGaussianInteger(3+4*I),True );
Verify(IsGaussianInteger(5),True);
Verify(IsGaussianInteger(1.1), False );
Verify(IsGaussianPrime(5+2*I),True );
Verify(IsGaussianPrime(13), False );
Verify(IsGaussianPrime(0), False );
Verify(IsGaussianPrime(3.5), False );
Verify(IsGaussianPrime(2+3.1*I), False );
Verify(IsPerfect(2305843008139952128), True );
Verify(IsPerfect(137438691328),True );
Verify(IsPerfect(234325),False );

Testing("IsConstant");

Verify(IsConstant(Pi), True);
Verify(IsConstant(Exp(1)+Sqrt(3)), True);
Verify(IsConstant(x), False);
Verify(IsConstant(Infinity), True);
Verify(IsConstant(-Infinity), True);
Verify(IsConstant(Undefined), True);

Testing("-- IsScalar");
Verify(IsScalar(a),True);
Verify(IsScalar({a}),False);

Testing("-- IsVector");
Verify(IsVector(1),False);
Verify(IsVector(a),False);
Verify(IsVector(Sin(a)+2),False);
Verify(IsVector({}),True);
Verify(IsVector({{}}),False);
Verify(IsVector({1,2,a,4}),True);
Verify(IsVector({1,{2,a},4}),False);
Verify(IsVector({{a,b,c}}),False);

Testing("-- IsVector(IsNumber)");
Verify(IsVector(IsNumber,1),False);
Verify(IsVector(IsNumber,{}),True);
Verify(IsVector(IsNumber,{a,b,c}),False);
Verify(IsVector(IsNumber,{a,2,c}),False);
Verify(IsVector(IsNumber,{2,2.5,4}),True);
Verify(IsVector(IsNumber,{Pi,2,3}),False);
Verify(IsVector(IsNumber,{{1},{2}}),False);

Testing("-- Matrix Predicates");

Testing("---- IsMatrix");
Verify(IsMatrix(1),False);
Verify(IsMatrix({}),False);
Verify(IsMatrix({a,b}),False);
Verify(IsMatrix({{}}),True);
Verify(IsMatrix({{a}}),True);
Verify(IsMatrix({{{a}}}),False);
Verify(IsMatrix({{},a}),False);
Verify(IsMatrix({{a},b}),False);
Verify(IsMatrix({{},{}}),True);
Verify(IsMatrix({{{}},{}}),False);
Verify(IsMatrix({{},{{}}}),False);
Verify(IsMatrix({{a,b},{c}}),False);
Verify(IsMatrix({{a,b},{c,d}}),True);
Verify(IsMatrix({{a,b},{c,{d}}}),False);
Verify(IsMatrix({{{}}}), False);
Verify(IsMatrix({{{a}}}), False);
Verify(IsMatrix({{{{a}}},{{{b}}}}),False);

Testing("---- IsMatrix(IsInteger)");
Verify(IsMatrix(IsInteger,{{a,1}}),False);
Verify(IsMatrix(IsInteger,{{1,2}}),True);
Verify(IsMatrix(IsInteger,{{1,2/3}}),False);
Verify(IsMatrix(IsInteger,{{1,2,3},{4,5,6}}),True);
Verify(IsMatrix(IsInteger,{{1,{2},3},{4,5,6}}),False);
Verify(IsMatrix(IsInteger,{{1,2,3},{4,5}}),False);
Verify(IsMatrix(IsInteger,{{Sin(1),2,3},{4,5,6}}),False);
Verify(IsMatrix(IsInteger,{{Sin(0),2,3},{4,5,6}}),True);

Testing("---- IsSquareMatrix");
Verify(IsSquareMatrix({{}}),False);
Verify(IsSquareMatrix({{a}}),True);
Verify(IsSquareMatrix({{},{}}),False);
Verify(IsSquareMatrix({{a,b}}),False);
Verify(IsSquareMatrix({{a,b},{c,d}}),True);
Verify(IsSquareMatrix({{a,b},{c,d},{e,f}}),False);
Verify(IsSquareMatrix({{a,b,c},{d,e,f},{g,h,i}}),True);
Verify(IsSquareMatrix({{a,b,c},{d,e,f}}),False);
Verify(IsSquareMatrix({{{a,b}},{{c,d}}}), False);
