/////////////////////////////////////////////////////////////////////////////// version="$Id: hopftools.lib,v 0.3 2010/05/20 $"; category="Noncommutative"; info=" LIBRARY: hopftools.lib Hopf algebras tools AUTHORS: Gomez-Torrecillas, J., gomezj@ugr.es @* Lobillo, F.J., jlobillo@ugr.es SUPPORT: MAIN PROCEDURES: isCoassociative(d,r); returns the ideal of relations in the coassociativity diagram, so d is isCoassociative if and only if this algorithm returns 0 isAlgebraMap(d,r); returns the ideal of relations that should be cero in order to say that d is an algebra map, so d is isCoassociative if and only if this algorithm returns 0 isCounitary(d,e,r); returns the ideals of relations in the isCounitary diagram, so d,e are isCounitary if and only if this algorithm returns 0,0 isAntipode(d,e,s,r); returns the ideals of relations in the antipode diagram, so s in an antipode for d,r if and only if this algorithm returns 0,0 isBiideal(I,d,e); isHopfideal(I,d,e,s); AUXILIARY PROCEDURES: ringSquare([r]); returns r^2 = r tensor r for a given ring/qring r ringCube([r]); returns r^3 = r tensor r tensor r for a given ring/qring r ringPower(n[,r]); returns r^n = r^{n-1} tensor r for a given ring/qring r ringPowerFD(n,l,r); returns r^n = r^{n-1} tensor r for a given ring/qring r, where each copy of r is identified with a character in the list l baseField([r]); returns the baseField of r (default basering) as baseField[x]/(x) idealSquareExpansion(i); "; LIB "ring.lib"; // change of variables LIB "nctools.lib"; // for noncommutative operations /////////////////////////////////////////////////////////////////////////////// proc ringSquare(list #) "USAGE: ringSquare([r]); r=ring/qring RETURN: ring R, where R is the tensor product of the ring r [default r=basering] by itself PURPOSE: this is the codomain of the comultiplication NOTE: The conflict between variables is solved renaming the variables of both factors adding (1) or (2) to the name of the variables. This proc uses 'execute' or calls a procedure using 'execute'. SEE ALSO: ringCube, ringPowerFD EXAMPLE: example ringSquare; shows examples" { //def @basering=basering; // Input checking if( size(#)==0 ) { def @currentring=basering; } if( size(#)==1 ) { if( (typeof(#[1])=="ring") or (typeof(#[1])=="qring") ) { def @currentring=#[1]; } else { ERROR( "Error: Input must be a ring or qring." ); } } if( size(#)!=0 and size(#)!=1 ) { ERROR( "Error: At most one input" ); } // End of input checking def @r=ringPowerFD(2,list("1","2"),@currentring); return(@r); setring @basering; } example { "EXAMPLE:";echo=2; LIB "ncalg.lib"; def A=makeQsl2(); setring(A); qring Uqsl2 = Qideal; Uqsl2; def Uqsl2sq = ringSquare(Uqsl2); setring(Uqsl2sq); Uqsl2sq; def B = ringSquare(A); print(ncRelations(B)[2]); } /////////////////////////////////////////////////////////////////////////////// proc ringCube(list #) "USAGE: ringCube([r]); r=ring/qring RETURN: ring R, where R is the tensor product of the ring r [default r=basering] by itself two times PURPOSE: this is the codomain of the isCoassociative comultiplication diagram NOTE: The conflict between variables is solved renaming the variables of both factors adding (1), (2) or (3) to the name of the variables. This proc uses 'execute' or calls a procedure using 'execute'. SEE ALSO: ringSquare, ringPowerFD EXAMPLE: example ringCube; shows examples" { def @basering=basering; // Input checking if( size(#)==0 ) { def @currentring=basering; } if( size(#)==1 ) { if( (typeof(#[1])=="ring") or (typeof(#[1])=="qring") ) { def @currentring=#[1]; } else { ERROR( "Error: Input must be a ring or qring." ); } } // End of input checking def @r=ringPowerFD(3,list("1","2","3"),@currentring); return(@r); setring @basering; } example { "EXAMPLE:";echo=2; LIB "ncalg.lib"; def A=makeQsl2(); setring(A); qring Uqsl2 = Qideal; Uqsl2; def Uqsl2sq = ringCube(Uqsl2); setring(Uqsl2sq); Uqsl2sq; def B = ringSquare(A); def C = ringCube(A); print(ncRelations(C)[2]); } /////////////////////////////////////////////////////////////////////////////// proc ringPower(int n, list #) "USAGE: ringPower(n,[r]); n=int, r=ring/qring RETURN: ring R, where R is the tensor product of the ring r [default r=basering] by itself n times NOTE: The conflict between variables is solved renaming the variables of both factors adding (1), (2), ..., (n) to the name of the variables. This proc uses 'execute' or calls a procedure using 'execute'. SEE ALSO: ringSquare, ringCube, ringPowerFD EXAMPLE: example ringPower; shows examples" { def @basering=basering; // Input checking if( size(#)==0 ) { def @currentring=basering; } if( size(#)==1 ) { if( (typeof(#[1])=="ring") or (typeof(#[1])=="qring") ) { def @currentring=#[1]; } else { ERROR( "Error: Second input must be a ring or qring." ); } } if( n<=0 ) //Type is chacked at input { ERROR("Error: The exponent should be an integer greater than 0"); } // End of input checking list @listaaux; for(int @j=1; @j<=n; @j=@j+1) { @listaaux = @listaaux + list(string(@j)); } def @r=ringPowerFD(n,@listaaux,@currentring); return(@r); setring @basering; } example { "EXAMPLE:";echo=2; LIB "ncalg.lib"; def A=makeUsl2(); setring(A); def B = ringPower(4,A); } /////////////////////////////////////////////////////////////////////////////// // No olvidar pasar a static //static proc ringPowerFD(list #) proc ringPowerFD(list #) "USAGE: ringPowerFD(n,l,r); n=int, l=list, r=ring/qring RETURN: ring R, where R is the tensor product of the ring r by itself n times NOTE: The conflict between variables is solved renaming the variables of both factors adding (l[1]), (l[2]), ..., (l[n]) to the name of the variables. This proc uses 'execute' or calls a procedure using 'execute'. SEE ALSO: ringSquare, ringCube EXAMPLE: example ringPowerFD; shows examples" { // No input checking since it is static def @@n=#[1]; def @@l=#[2]; def @currentring=#[3]; string @copynewvars; int @i,@j; int @isNCflag=isNC(); // important data to be transferred to all parts setring @currentring; list @listring=ringlist(@currentring); def @minpolystr=string(@listring[1][4][1]); // This is included because there is a bug in changevar in version 3-1-1 list @listofvars=@listring[2]; ideal @currentringqideal=@listring[4]; if( @isNCflag==1 ) { // noncommutative case matrix @currentringCoefsMatrix=@listring[5]; matrix @currentringTailsMatrix=@listring[6]; } list @PBWlistring=@listring; @PBWlistring[4]=ideal(0); def @currentPBWring=ring(@PBWlistring); //Qideal have to be ignored because nc_algebra works only in rings def @auxPBWring=@currentPBWring; // listofcopies contains a list of the n different copies of current ring list listofcopies=list(); for(@j=1; @j<=@@n; @j=@j+1) { //new variables for the new copy of the current ring @copynewvars=""; for(@i=1; @i<=nvars(@currentPBWring); @i=@i+1) { @copynewvars = @copynewvars+","+@listofvars[@i]+"("+@@l[@j]+")"; }; @copynewvars = @copynewvars[2..size(@copynewvars)]; //first , should be deleted // definition of the copy @auxPBWring = changevar(@copynewvars,@currentPBWring); // There is a bug with changevar, minpoly is not translated, so we must include the minpoly. setring(@auxPBWring); execute("minpoly="+@minpolystr+";"); setring(@currentring); // Previous three lines can be removed if the bug is corrected setring(@auxPBWring); // if( @isNCflag==1 ) { matrix @auxCoefsMatrix = fetch(@currentring,@currentringCoefsMatrix); matrix @auxTailsMatrix = fetch(@currentring,@currentringTailsMatrix); @auxPBWring = nc_algebra(@auxCoefsMatrix,@auxTailsMatrix); setring(@auxPBWring); } qring @auxring=fetch(@currentring,@currentringqideal); setring(@currentring); listofcopies=listofcopies+list(@auxring); kill @auxring; }; kill @auxPBWring; kill @currentPBWring; def @r = listofcopies[1]; for(@j=2; @j<=@@n; @j=@j+1) { @r = @r+listofcopies[@j]; }; return(@r); } //example //{ // "EXAMPLE:";echo=2; // LIB "ncalg.lib"; // def A=makeUsl2(); // setring(A); // def B = ringPowerFD(4,list(string(4),string(3),string(2),string(1)),A); B; //} /////////////////////////////////////////////////////////////////////////////// proc isAlgebraMap(list #) "USAGE: isAlgebraMap(d,r[,r']); d=string/map, r,r'=ring/qring RETURN: a string with the generators of an ideal I, where I is the ideal of relations in the image of d. So d is an algebra map if output is 0 NOTE: r has to be the domain of the map defined by the d, it has to be included because preimage does not work on noncommutative rings. The codomain is r' (if provided) or basering The map in introduced as a string because in isCounitary and isAntipode procedures maps have to be introduced as strings This proc uses 'execute' or calls a procedure using 'execute'. SEE ALSO: isCoassociative,isCounitary,isAntipode EXAMPLE: example isAlgebraMap; shows examples" { def @basering=basering; // Input checking and initial assignements if( (size(#)<2) or (size(#)>3) ) { ERROR( "Error: Bad number of arguments, call me with 2 or 3 inputs" ); } else { if( (typeof(#[2])=="ring") or (typeof(#[2])=="qring") ) { def @domain=#[2]; } else { ERROR( "Error: second argument have to be a ring/qring" ); } // Cambiar esto // A ver, si hay dos argumentos entonces compruebo si la entrada es map o string, y si es map la convierto a string, si hay tres argumentos solo vale como entrada string if( size(#)==2 ) { def @image=basering; setring @image; if( typeof(#[1])=="string" ) { def @mapstring=#[1]; execute("map @map=@domain,"+@mapstring+";"); print( "If the first argument is a string that does not represent a map from the second argument to basering unexpected results can be obtained" ); } else { if( typeof(#[1])=="map" ) { def @map=#[1]; } else { ERROR( "Error: If two arguments are provided the first one must be a map or a string representing a map from the second argument to basering" ); } } } else { if( (typeof(#[3])=="ring") or (typeof(#[3])=="qring") ) { def @image=#[3]; } else { ERROR( "Error: third argument have to be a ring/qring" ); } setring @image; if( typeof(#[1])=="string" ) { def @mapstring=#[1]; execute("map @map=@domain,"+@mapstring+";"); print( "If this string does not represent a map from the second argument to basering (or to the third argument if it exists), unexpected results can be obtained" ); } else { ERROR( "Error: If three arguments are provided the first one must be string representing a map from the second argument to the third" ); } } } // End of input checking ideal @flag; setring(@domain); int @i,@j; poly @temp,@vi,@vj; for(@i=1; @i<=nvars(@domain)-1; @i=@i+1) { for(@j=@i+1; @j<=nvars(@domain); @j=@j+1) { @temp = var(@j)*var(@i); @vi = var(@i); @vj = var(@j); setring(@image); @flag=@flag,@map(@vj)*@map(@vi)-@map(@temp); setring(@domain); }; }; ideal @qideal=ringlist(@domain)[4]; for(@i=1; @i<=size(@qideal); @i=@i+1) { @temp = @qideal[@i]; setring(@image); @flag=@flag,@map(@temp); setring(@domain); }; setring(@image); return(string(std(@flag))); setring(@basering); } example { "EXAMPLE:";echo=2; LIB "ncalg.lib";def Uqsl2op=opposite(Uqsl2); setring Uqsl2; map antipode=Uqsl2op,Ke,Kf,-Ke*F,-E*Kf; def sstr=string(antipode); def A=makeQsl2(); setring A; qring Uqsl2=Qideal; def Uqsl2sq=ringSquare(Uqsl2); setring Uqsl2sq; map delta=Uqsl2,E(1)*Ke(2)+E(2),F(1)+Kf(1)*F(2),Ke(1)*Ke(2),Kf(1)*Kf(2); def dstr=string(delta); isAlgebraMap(dstr,Uqsl2); map delta2=Uqsl2,E(1)+E(2),F(1)+F(2),Ke(1)*Ke(2),Kf(1)*Kf(2); def dstr2=string(delta2); isAlgebraMap(dstr2,Uqsl2); } ////////////////////////////////////////////////////////////////////////////// // Falta comprobar las entradas proc isCoassociative(list #) "USAGE: isCoassociative(d,r); d=string, r=ring/qring RETURN: a string with the generators of an ideal I, where I is the ideal of obstructions to coassociativity NOTE: r has to be the domain of the map defined by the string d, it has to be included because preimage does not work on noncommutative rings. The map in introduced as a string because in isCounitary and isAntipode procedures maps have to be introduced as strings. This proc uses 'execute' or calls a procedure using 'execute'. SEE ALSO: isAlgebraMap, isCounitary, isAntipode EXAMPLE: example isCoassociative; shows examples" { def @basering=basering; def @domain=#[2]; def @square=ringSquare(@domain); def @cube=ringCube(@domain); string @imgstring=""; setring @square; int @i; def @deltastring=#[1]; execute("map @delta=@domain,"+@deltastring+";"); for(@i=1; @i<=nvars(@domain); @i=@i+1) { @imgstring = @imgstring + "," + string(@delta[@i]); }; setring(@domain); for(@i=1; @i<=nvars(@domain); @i=@i+1) { @imgstring = @imgstring+","+string(var(@i))+"(3)"; }; string @deltaleftstring="map @deltaleft=@square"+@imgstring+";"; setring(@cube); // int @i; execute(@deltaleftstring); def @squareshift=ringPowerFD(2,list("2","3"),@domain); setring @squareshift; def @deltashift=fetch(@square,@delta); setring @domain; @imgstring=""; for(@i=1; @i<=nvars(@domain); @i=@i+1) { @imgstring = @imgstring+","+string(var(@i))+"(1)"; }; setring @squareshift; for(@i=1; @i<=nvars(@domain); @i=@i+1) { @imgstring = @imgstring + "," + string(@deltashift[@i]); }; string @deltarightstring="map @deltaright=@square"+@imgstring+";"; setring(@cube); execute(@deltarightstring); ideal @flag; for(@i=1; @i<=nvars(@domain); @i=@i+1) { @flag = @flag,@deltaleft(@delta)[@i]-@deltaright(@delta)[@i]; }; return(string(std(@flag))); setring @basering; } example { "EXAMPLE:";echo=2; LIB "ncalg.lib"; def A=makeQsl2(); setring A; qring Uqsl2=Qideal; def Uqsl2sq=ringSquare(Uqsl2); setring Uqsl2sq; map delta=Uqsl2,E(1)*Ke(2)+E(2),F(1)+Kf(1)*F(2),Ke(1)*Ke(2),Kf(1)*Kf(2); def dstr=string(delta); isCoassociative(dstr,Uqsl2); map delta2=Uqsl2,E(1)*Ke(2)-E(2),F(1)-Kf(1)*F(2),Ke(1)*Ke(2),Kf(1)*Kf(2); def dstr2=string(delta2); isCoassociative(dstr2,Uqsl2); } ////////////////////////////////////////////////////////////////////////////// // Falta comprobar las entradas proc baseField(list #) "USAGE: baseField([r]); r=ring/qring RETURN: ring R, where R is baseField[x]/(x) [default r=basering] PURPOSE: this is the codomain of the counit NOTE: This proc uses 'execute' or calls a procedure using 'execute'. SEE ALSO: ringSquare EXAMPLE: example baseField; shows examples" { if( size(#)==0 ) { def @currentring=basering; } if( size(#)==1 ) { def @currentring=#[1]; } string @fieldstring="("+charstr(@currentring)+")"; @fieldstring="ring @fieldpoly="+@fieldstring+",(dummy),dp;"; execute(@fieldstring); ideal @i=dummy; qring @r=std(@i); return(@r); } example { "EXAMPLE:";echo=2; LIB "ncalg.lib"; def A=makeQsl2(5); setring(A); qring Uqsl2 = Qideal; Uqsl2; def B = baseField(); setring B; B; } /////////////////////////////////////////////////////////////////////////////// // Falta comprobar las entradas proc isCounitary(list #) "USAGE: isCounitary(d,e,r); d,e=string, r=ring/qring RETURN: a list with two strings with the generators of the ideals of obstructions to left and right Counitarity NOTE: r has to be the domain of the map associated to the strings d and e. The codomain of d is ringSquare(r), and the codomain of e baseField(r). They have to be included. Maps are introduced as strings because codomains are different. This proc uses 'execute' or calls a procedure using 'execute'. SEE ALSO: isAlgebraMap, isCoassociative, isAntipode EXAMPLE: example isAlgebraMap; shows examples" { def @basering=basering; def @domain=#[3]; def @square=ringSquare(@domain); int @i; setring @square; def @deltastring=#[1]; execute("map @delta=@domain,"+@deltastring+";"); def @field=baseField(@domain); setring @field; def @epsilonstring=#[2]; execute("map @epsilon=@domain,"+@epsilonstring+";"); setring @domain; map @edprod; execute("@edprod=@square,"+@epsilonstring+","+varstr(@domain)+";"); ideal @leftflag; for(@i=1; @i<=nvars(@domain); @i=@i+1) { @leftflag=@leftflag,@edprod(@delta)[@i]-var(@i); }; setring @domain; execute("@edprod=@square,"+varstr(@domain)+","+@epsilonstring+";"); ideal @rightflag; for(@i=1; @i<=nvars(@domain); @i=@i+1) { @rightflag=@rightflag,@edprod(@delta)[@i]-var(@i); }; return(list(string(std(@leftflag)),string(std(@rightflag)))); setring @basering; } example { "EXAMPLE:";echo=2; LIB "ncalg.lib"; def A=makeQsl2(); setring A; qring Uqsl2=Qideal; def Uqsl2sq=ringSquare(Uqsl2); setring Uqsl2sq; map delta=Uqsl2,E(1)*Ke(2)+E(2),F(1)+Kf(1)*F(2),Ke(1)*Ke(2),Kf(1)*Kf(2); def dstr=string(delta); def field=baseField(Uqsl2); setring field; map epsilon=Uqsl2,0,0,1,1; def estr=string(epsilon); isCounitary(dstr,estr,Uqsl2); map epsilon2=Uqsl2,1,1,0,0; def estr2=string(epsilon2); isCounitary(dstr,estr2,Uqsl2); } ////////////////////////////////////////////////////////////////////////////// //// En el caso conmutativo es mejor reescribirlo sin usar el algebra opuesta // Falta comprobar las entradas proc isAntipode(list #) "USAGE: isAntipode(d,e,s,r); d,e,s=string, r,rr,f=ring/qring RETURN: a list with two strings, each string contains the list of the generators of two ideals I,J, where I and J are the ideal of obstructions to the left and right antipode property NOTE: r has to be the domain of the map associated to the strings e and d, and the codomain of s. The codomain of d is ringSquare(r), and the codomain of e is baseField(r). The domain of s is opposite(r). They have to be included. Maps are introduced as strings because codomains are different. This proc uses 'execute' or calls a procedure using 'execute'. SEE ALSO: isAlgebraMap, isCoassociative, isCounitary EXAMPLE: example isAntipode; shows examples" { int @i; def @basering=basering; def @domain=#[4]; def @square=ringSquare(@domain); setring @square; def @deltastring=#[1]; execute("map @delta=@domain,"+@deltastring+";"); def @field=baseField(@domain); setring @field; def @epsilonstring=#[2]; execute("map @epsilon=@domain,"+@epsilonstring+";"); setring @domain; execute("map @epsilonunit=@domain,"+@epsilonstring+";"); int @isNCflag=isNC(); if( @isNCflag==1 ) { def @opposite=opposite(@domain); def @antipodestring=#[3]; execute("map @antipode=@opposite,"+@antipodestring+";"); string @antipodestring=""; for(@i=1; @i<=nvars(@domain); @i=@i+1) //Turns the definition of the antipode map { poly @temp1=var(@i); setring @opposite; poly @temp2=oppose(@domain,@temp1); setring @domain; @antipodestring=@antipodestring+","+string(@antipode(@temp2)); } @antipodestring=@antipodestring[2..size(@antipodestring)]; } else { def @antipodestring=#[3]; execute("map @antipode=@domain,"+@antipodestring+";"); } string @leftantipodestring=@antipodestring+","+varstr(@domain); string @rightantipodestring=varstr(@domain)+","+@antipodestring; execute("map @leftantipode=@square,"+@leftantipodestring+";"); execute("map @rightantipode=@square,"+@rightantipodestring+";"); ideal @leftflag; for(@i=1; @i<=nvars(@domain); @i=@i+1) { // @leftflag = @leftflag,reduce(@leftantipode(@delta)[@i]-@epsilonunit[@i],0); @leftflag = @leftflag,@leftantipode(@delta)[@i]-@epsilonunit[@i]; }; ideal @rightflag; for(@i=1; @i<=nvars(@domain); @i=@i+1) { // @rightflag = @rightflag,reduce(@rightantipode(@delta)[@i]-@epsilonunit[@i],0); @rightflag = @rightflag,@rightantipode(@delta)[@i]-@epsilonunit[@i]; }; return(list(string(std(@leftflag)),string(std(@rightflag)))); setring @basering; } example { "EXAMPLE:";echo=2; LIB "ncalg.lib"; def A=makeQsl2(); setring A; qring Uqsl2=Qideal; def Uqsl2sq=ringSquare(Uqsl2); setring Uqsl2sq; map delta=Uqsl2,E(1)*Ke(2)+E(2),F(1)+Kf(1)*F(2),Ke(1)*Ke(2),Kf(1)*Kf(2); def dstr=string(delta); def field=baseField(Uqsl2); setring field; map epsilon=Uqsl2,0,0,1,1; def estr=string(epsilon); def Uqsl2op=opposite(Uqsl2); setring Uqsl2; map antipode=Uqsl2op,Ke,Kf,-Ke*F,-E*Kf; def sstr=string(antipode); isAntipode(dstr,estr,sstr,Uqsl2); map antipode2=Uqsl2op,Ke,Kf,-F,-E; def sstr2=string(antipode2); isAntipode(dstr,estr,sstr2,Uqsl2); } ////////////////////////////////////////////////////////////////////////////// proc idealSquareExpansion(ideal @I) "USAGE: idealSquareExpansion(i); i=ideal, RETURN: a list with three strings. Let r be the basering of i. The first string contains the generators of (i tensor r) as an ideal in (r tensor r). The second string contains the generators of (r tensor i) as an ideal in (r tensor r). The third one contains the generators of (i tensor r) plus (r tensor i) PURPOSE: This extensions are needed to check if a given ideal is a left, right or twosided coideal. NOTE: The output is a string because the output are not ideals in the basering. This proc uses 'execute' or calls a procedure using 'execute'. SEE ALSO: ringSquare, EXAMPLE: example idealSquareExpansion; shows examples" { def @currentring=basering; def @square=ringSquare(@currentring); def @@(1) = ringPowerFD(1,list(string(1)),@currentring); def @@(2) = ringPowerFD(1,list(string(2)),@currentring); setring @@(1); ideal @I(1) = fetch(@currentring,@I); def @Istr(1) = string(@I(1)); setring @@(2); ideal @I(2) = fetch(@currentring,@I); def @Istr(2) = string(@I(2)); //setring @square; //execute("ideal @Ileft="+@Istr(1)+";"); //execute("ideal @Iright="+@Istr(2)+";"); //def @Itwo = @Ileft + @Iright; //list @@l = list(@Ileft,@Iright,@Itwo); list @@l = list(@Istr(1),@Istr(2),@Istr(1)+","+@Istr(2)); return(@@l); setring @currentring; } example { "EXAMPLE:";echo=2; } ////////////////////////////////////////////////////////////////////////////// proc isBiideal(ideal @I, string @deltastr, @epsilonstr) "USAGE: isBiideal(i,d); i=ideal, d=string RETURN: PURPOSE: NOTE: This proc uses 'execute' or calls a procedure using 'execute'. SEE ALSO: ringSquare, idealSquareExtension, EXAMPLE: example isBiideal; shows examples" { def @currentring=basering; def @square=ringSquare(@currentring); def @field=baseField(@currentring); def @RIplusIRstr=idealSquareExpansion(@I)[3]; setring @square; list @@l; execute("ideal @RIplusIR = "+@RIplusIRstr+";"); @RIplusIR = std(@RIplusIR); // print(@RIplusIR); execute("map @delta=@currentring,"+@deltastr+";"); // print(@delta); @@l = insert(@@l,string(reduce(@delta(@I),@RIplusIR)+0),size(@@l)); // Falta la counidad setring @field; execute("map @epsilon=@currentring,"+@epsilonstr+";"); @@l = insert(@@l,string(@epsilon(@I)+0),size(@@l)); return(@@l); setring @currentring; } example { "EXAMPLE:";echo=2; } ////////////////////////////////////////////////////////////////////////////// proc isHopfideal(ideal @I, string @deltastr, @epsilonstr, @antipodestr) "USAGE: isHopfideal(i,d); i=ideal, d=string RETURN: PURPOSE: NOTE: This proc uses 'execute' or calls a procedure using 'execute'. SEE ALSO: ringSquare, idealSquareExtension, EXAMPLE: example isBiideal; shows examples" { def @currentring=basering; list @@l = isBiideal(@I, @deltastr, @epsilonstr); int @isNCflag=isNC(); if( @isNCflag==1 ) { def @oppositering = opposite(@currentring); execute("map @antipode=@oppositering,"+@antipodestr+";"); setring @oppositering; def @Iop = oppose(@currentring,@I); setring @currentring; @@l = insert(@@l,string(reduce(@antipode(@Iop),@I)+0),size(@@l)); @@l = insert(@@l,"noncommutative",size(@@l)); } else { execute("map @antipode=@currentring,"+@antipodestr+";"); @@l = insert(@@l,string(reduce(@antipode(@I),@I)+0),size(@@l)); @@l = insert(@@l,"commutative",size(@@l)); } return(@@l); setring @currentring; } example { "EXAMPLE:";echo=2; }