# this is the source of the test file. The test file is produced by:
# gap < test.src


if CompareVersionNumbers( VERSION, "4.5" )  then
    testfile := "test";
elif CompareVersionNumbers( VERSION, "4.4" )  then
    testfile := "test_4_4";
else
    testfile := "test_4_3";
fi;

LogTo( testfile );

# Start

START_TEST( "Test of the singular package" );
SizeScreen([80]);;
if not IsBound(LoadPackage) and IsBound(RequirePackage)  then
    LoadPackage := RequirePackage;
fi;
LoadPackage("singular");
SetInfoLevel( InfoSingular, 1 );
StartSingular();

ValidatePackageInfo( Filename( DirectoriesPackageLibrary( "singular", "" ), "PackageInfo.g" ) );

# Examples from README file

R:=PolynomialRing( Rationals, ["x", "y", "z"] : new );
gen:=GeneratorsOfLeftOperatorRingWithOne(R);
x:=gen[1];
y:=gen[2];
z:=gen[3];
pol1:=-3*x*z^3+x^3+x*y*z;
pol2:=-3*x^2*z^3+x^4+x^2*y*z-3*x*z^3+x^3+x*y*z;
pol3:=x*y+x*z+x+y+z;
I:=Ideal( R, [ pol1, pol2, pol3] );
SingularSetBaseRing( R );
J:=SingularInterface( "jacob", [ pol1 ], "ideal" );
GeneratorsOfTwoSidedIdeal( J );
SingularInterface( "dim", [ I ], "int" );
std:=SingularInterface( "std", [ I ], "ideal" );
GeneratorsOfTwoSidedIdeal( std );
GroebnerBasis( I );
HasTrivialGroebnerBasis( I );
SingularLibrary( "general.lib");
GcdUsingSingular( pol1, pol2, pol3 );
FactorsUsingSingularNC( pol1 );
FactorsUsingSingular( pol2 );


# Examples from manual

SetInfoLevel( InfoSingular, 2 );
G:= SymmetricGroup( 3 );
R:= PolynomialRing( GF(2), 3 );
gens:=GeneratorsOfInvariantRing( R, G );
I:= Ideal( R, gens );
GB:=GroebnerBasis( I );
R:= PolynomialRing( Rationals, ["x","y","z"] : old );
i:= IndeterminatesOfPolynomialRing(R);
x:= i[1];
y:= i[2];
z:= i[3];
r:= [ x*y*z -x^2*z, x^2*y*z-x*y^2*z-x*y*z^2, x*y-x*z-y*z];
I:= Ideal( R, r );
GroebnerBasis( I );
R:= PolynomialRing( Rationals, 3 );
i:= IndeterminatesOfPolynomialRing( R );
pols:= [i[1]+i[2]+i[3], i[1]*i[2]+i[1]*i[3]+i[2]*i[3], i[1]*i[2]*i[3]];
o:= MonomialLexOrdering();
GBASIS:= GAPGBASIS;
gg:=GroebnerBasis( pols, o );   # This is the internal GAP method.
GBASIS:= SINGULARGBASIS;
gs:=GroebnerBasis( pols, o );
(gg[1]=gs[1] and -gg[4]=gs[2] and gg[5]=gs[3]) or (gg[5]=gs[1] and -gg[4]=gs[2] and gg[1]=gs[3]);
I:=Ideal(R, gs);
SingularInterface("reduce", [ gg[2], I ], "poly" );
SingularInterface("reduce", [ gg[3], I ], "poly" );
gs[2] in I;
R:= PolynomialRing( GaussianRationals, ["x","y","z"] : old );
i:= IndeterminatesOfPolynomialRing(R);
x:= i[1];
y:= i[2];
z:= i[3];
f:= (x*y-z)*(x*y*z+y^2*z+x^2*z);
g:= (x*y-z)*(x*y*z^2+x*y^2*z+x^2*y*z);
I:= Ideal( R, [f,g] );
HasTrivialGroebnerBasis( I );
R:= PolynomialRing( Rationals, ["x","y","z"] : old );
i:= IndeterminatesOfPolynomialRing(R);
x:= i[1];
y:= i[2];
z:= i[3];
f:= (x*y-z)*(x*y*z+y^2*z+x^2*z);
g:= (x*y-z)*(x*y*z^2+x*y^2*z+x^2*y*z);
SingularSetBaseRing( R );
GcdUsingSingular( f, g );
f:= (x*y-z)*(x*y*z+y^2*z+x^2*z);
SingularSetBaseRing( R );
FactorsUsingSingularNC( f );
m:=[[1,1,1],[0,1,1],[0,0,1]]*One(GF(3));
G:= Group( [m] );
R:= PolynomialRing( GF(3), 3 );
GeneratorsOfInvariantRing( R, G );
R:= PolynomialRing( Rationals, ["x","y","z"] : old );
i:= IndeterminatesOfPolynomialRing(R);
x:= i[1];
y:= i[2];
z:= i[3];
f:= (x*y-z)*(x*y*z+y^2*z+x^2*z);
g:= (x*y-z)*(x*y*z^2+x*y^2*z+x^2*y*z);
I:= Ideal( R, [f,g] );
SingularLibrary("primdec.lib");
pd:=SingularInterface("primdecGTZ", [ I ], "def" );
List(pd,x->List(x,GeneratorsOfTwoSidedIdeal));


# ParseSingProcToGapFunction

SingCommandInStreamOutStream( "", "proc a1 () { return ( 35 ) };" );
SingCommandInStreamOutStream( "", "proc a2 (e2) { return ( a1 ) };" );
SingCommandInStreamOutStream( "", "proc a3 (e3) { return ( a2 ) };" );
f := SingularInterface( "a3", [ 1 ], "proc" );
g := f( 10 );
g(  );
SingCommandInStreamOutStream( "",
 "proc asd ( t ) { return (t+1 ) ;return();};" );
SingCommandInStreamOutStream( "",
 "proc asd2 (){return (asd ) ;return(); };" );
f := SingularInterface( "asd2", [  ], "proc" );
f( 19 );


# Check the conversion of numbers and polynomials for the various
# CoefficientsRing

SingularCommand("proc id_func (a){return (a);}", ""); # id_func = identity
R:=PolynomialRing( GF(32003), ["x"] : old );;
SingularSetBaseRing( R );
SingularInterface("id_func", [Z(32003)], "def");
One(SingularBaseRing);
SingularInterface("id_func", [last], "def");

x:=Indeterminate(Rationals);;
F1:=AlgebraicExtension(Rationals, x^5+4*x+1);
e1:=RootOfDefiningPolynomial(F1);
x:=Indeterminate(GF(5));;
F2:=AlgebraicExtension(GF(5), x^5+4*x+1);
e2:=RootOfDefiningPolynomial(F2);

field_element := [ 
[ Rationals, 23 ],
[ GF(2), Z(2) ],
[ GF(7), Z(7)^2 ],
[ GF(32), Z(32)^3 ],
[ GF(25), Z(25)^4 ],
[ CF(3), -E(3) ],
[ CF(25), Random(CF(25)) ],
[ CF(25), E(5) ],
[ F1, e1^2 + e1 ],
[ F2, e2^3+One(F2) ]
];;

for i in field_element do

    R := PolynomialRing( i[1], 2 );
    SingularSetBaseRing( R );

    # test of numbers
    u1:=i[2];
    u2:=SingularInterface( "id_func", [u1], "def" );
    if u1<>u2 then Error( "wrong conversion of number!\n"); fi;
    u1:=Zero(i[1]);
    u2:=SingularInterface( "id_func", [u1], "def" );
    if u1<>u2 then Error( "wrong conversion of number!\n"); fi;
    u1:=One(i[1]);
    u2:=SingularInterface( "id_func", [u1], "def" );
    if u1<>u2 then Error( "wrong conversion of number!\n"); fi;

    # test of polynomials
    gen := GeneratorsOfLeftOperatorRingWithOne(R);
    p1 := (i[2]*gen[1]+i[2]*gen[2])^4;
    p2 := SingularInterface( "id_func", [p1], "def" );
    if p1<>p2 then Error( "wrong conversion of polynomial!\n"); fi;
    p1:=Zero(R);
    p2:=SingularInterface( "id_func", [p1], "def" );
    if p1<>p2 then Error( "wrong conversion of zero polynomial!\n"); fi;
    p1:=One(R);
    p2:=SingularInterface( "id_func", [p1], "def" );
    if p1<>p2 then Error( "wrong conversion of zero polynomial!\n"); fi;

od;


# test the string conversion
s1:=[32..126];;
s2:=List("$'@", INT_CHAR);;
s1:=Difference(s1,s2);;
s3:=List(s1,CHAR_INT);;
ConvertToStringRep(s3);
s4:=SingularInterface("id_func", [s3], "def");
s3=s4;




# Check the conversion of various types of object

if CompareVersionNumbers(VERSION, "4.4") then
    x:=X(GF(5),"x" : new );
    y:=X(GF(5),"y",[x] : new );
    ring:=PolynomialRing(GF(5),[x,y]);
else
    ring:=PolynomialRing(GF(5),2);
    gen := GeneratorsOfLeftOperatorRingWithOne(ring);
    x:=gen[1];;y:=gen[2];;
fi;
SingularSetBaseRing(ring);

ideal:=Ideal(ring,[x*y, x+y]);
int:=123456;
intmat:=[[12,34],[56,78]];
intvec:=[98765,4321];
map:=AlgebraGeneralMappingByImages(ring,ring,[x,y],[x+y,x-y]);
matrix:=[[x+y, x*y],[x+y+x*y,x^2+y^2]];
module:=LeftModuleByGenerators( ring, [[x+y+x*y,x-y], [x+x^2+x^3,y+x^2+y^3]]);
number:=Z(5)^3;
poly:=x^3+y^3+Z(5)^3*x^2+Z(5)^3*x*y+y^2+Z(5)^3*y;
proc:=function() end;
string:="ciao";
vector:=[x^3+y^3,+(5)^3*x^2+Z(5)^3,x*y+y^2+Z(5)^3*y];

list1 := [ ideal, int, intmat, intvec, map, matrix, module, number,
poly, proc, ring, string, vector];
List( list1, SingularType);

list2 := [ ideal, int, intmat, intvec, matrix, module, number,
poly, string, vector];
list3 := SingularInterface( "id_func", [list2], "def" );

for i in [2,3,4,5,7,8,9,10] do
    if list2[i] <> list3[i] then
       Error( "wrong conversion!\n");
    fi;
od;


# test of GapInterface

cc:=ConvertGapObjToSingObj(matrix);;
SingularCommand(Concatenation( "matrix mm = ", cc),"print(mm)");
SingularCommand(Concatenation( "matrix mm = ", cc), "print(mm, \"%l\")");

GapInterface(TransposedMat, ["mm"], "mm2");
SingularCommand("","transpose(mm2)==mm");



# this should be at the end of the test file:

[ SingularNr.Process, SingularNr.Input, SingularNr.Output ];
SingularBaseRing;
CoefficientsRing( SingularBaseRing );
SingularNames;
SingWriteAndReadUntilDone("1;GAP_Apostrophe();2;GAP_Apostrophe();");
SingularInterface( "string", "GAP_Done", "string" );
SetInfoLevel( InfoSingular, 1 );

STOP_TEST( "test", 10000 );

LogTo();
quit;
