Package $ext -- Ext Modules Alias Ext := $ext; Define About() PrintLn " KeyWords : Ext, Depth Author : A.Damiano E-mail : alberto@tlc185.com Version : CoCoA 4.6 Date : May 2006 Thanks To: The author is thankful to M.Kreuzer and L. Robbiano for their extreme patience. The author is also thankful to A.Bigatti for teaching him how to transform his raw code into a package and for her constant support. " End; -- About -----------------[ Manual ]---------------------- Define Man() PrintLn " ------------------[ PRELIMINARIES ]------------------- This is a new version with respect to the ext.pckg that was distributed with CoCoA 4.3 and 4.4 VERY IMPORTANT: only homogeneous modules are supported. Use non-homogeneous objects at your own risk! Main differences with the previous version include: 1) SHIFTS have been removed, consequently only standard homogeneous modules and quotients are supported 2) as a consequence of 1), the type Tagged(""shifted"") has been removed. Ext will just be a Tagged(""Quotient"") 3) The former functions Presentation(), HomPresentation() and Ker(Presentation) have been removed 4) The algorithm uses Res() to compute the maps needed, and not SyzOfGens any longer, believed to cause troubles 5) The function Ext always has THREE variables, see syntax... Finally, please note that this package is still being tested so please report bugs to alberto@tlc185.com ---------------------[ SYNTAX of EXT ]---------------------- Some directions on how to use these functions: Ext.Ext(I: INT, M: Tagged(""Quotient""), N: Tagged(""Quotient"")):Tagged(""Quotient""); Ext.Ext(I: LIST, M: Tagged(""Quotient""), N: Tagged(""Quotient"")):Tagged(""ExtList""); NOTE:in the second form I is a LIST of non-negative integers of type INT and the output is a LIST of pairs (lists of two elements) of the type [J,E] where J is an element of I and E the corresponding Ext module calculated using Ext(J,M,N). In this case the modules are printed in a ""nicer way"". IMPORTANT:the only exception to M or N (or even the output) is when they are either a zero module or a free module. In these cases their type is MOD. This function calculates a presentation (i.e. a quotient of a free module) for the module Ext^I_R(M,N) , where R is the current R using the maps Phi*_n in the dual of a minimal free resolution and presenting Ker(Phi*_I)/Im(Phi*_{I-1}) as a quotient using syzygies. If the Ext module required is zero, it will simply return Module([0]); -------------------------- The variable I could also be a LIST of non-negative integers. In this case the function Ext(...) prints all the Ext modules correpsonding to the integers in I. The output is of special type Tagged(""ExtList"") which is basically just a list so that it can be assigned to a variable and each component of the list can be utilized individually. NOTE:The input is pretty flexible in terms of what you can use for M and N. Definitely if you need to use a zero module (do you really?) you can define it in as is, for example as M:=Module([0]); or N:=Ideal(0); This is in fact not the only way to define a zero module: one could use M:=R^2/Module([1,0],[0,1]); or N:=R/Ideal(1); or other things like that. Ext(...) should recognize that and return the zero module right away. It is also possible to just use a free module as M or N. Just define something like M:=R^3; or N:=Module([1,0],[0,1]); etc. VERY IMPORTANT: CoCoA cannot accept the ring R as one of the inputs, so if you want to calculate the module Ext^I_R(M,R) you need to type something like Ext.Ext(I,M,Ideal(1)); or Ext.Ext(I,M,R^1); or Ext.Ext(I,M,R/Ideal(0)); or using any other way to define the free module R^1 that may come to your mind, -hopefully- this will be recognized as R^1. Let me know if you find a sintax that is not supported, those are always the most tedious cases to handle. Note that in this case there is a special function called to calculate Ext that should be a little faster than the original version of the Ext package. I would consider in future updates having a specific function Ext_R(I,M) for this particular (and most used) case, like Singular does. ------------------[ EXAMPLES using EXT ]------------------ Use R::=Q[x,y,z]; I:=Ideal(x^5,y^3,z^2); Ideal(0):(I); Ideal(0) ------------------------------- Hom.Hom(R^1/Module(I),R^1); -- from Hom package, see $contrib/hom Module([0]) ------------------------------- Ext.Ext(0,R/I,R^1); --- all those things should be isomorphic Module([0]) ------------------------------- Ext.Ext(0..4,R/I,R/Ideal(0)); Ext^0 = Module([0]) Ext^1 = Module([0]) Ext^2 = Module([0]) Ext^3 = R^1/Module([x^5], [-y^3], [z^2]) Ext^4 = Module([0]) ------------------------------- N:=Module([x^2,y],[x+z,0]); Ext.Ext(0..4,R/I,R^2/N); Ext^0 = Module([0]) Ext^1 = Module([0]) Ext^2 = R^8/Module([0, 0, 0, -1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0], [1, x - z, 0, 0, 0, 0, 0, 0], [0, 0, y, x - z, 1, 0, 0, 0], [0, 0, y, x - z, 0, 0, 0, 0], [0, x^3, 0, 0, 0, x + z, 0, 0], [y^2, 0, -z^2, 0, 0, 0, 0, 0], [0, x^4 - x^3z, 0, 0, 0, -z^2, -1, 0], [-y^3z, x^2y^3 - xy^3z + y^3z^2, 0, -x^4 + x^3z - x^2z^2, 0, y^3, 0, 0], [0, x^4 - x^3z, 0, 0, 0, -z^2, 0, 0], [0, 0, 0, 0, 0, 0, 0, -1], [-y^2z^3, -x^4y^2 + x^3y^2z, x^5 + z^5, 0, 0, y^2z^2, 0, 0]) Ext^3 = R^2/Module([x^5, 0], [0, x^5], [-y^3, 0], [0, -y^3], [z^2, 0], [0, z^2], [x^2, y], [x + z, 0]) Ext^4 = Module([0]) ------------------------------- As you can see the Ext^2 is not presented minimally. This is an issue I will try to resolve for the next version. ------------------[ SYNTAXT of DEPTH ]------------------- The function Depth(...) has a double sintax: Ext.Depth(I: IDEAL, M: Tagged(""Quotient"")): INT; or Ext.Depth(M: Tagged(""Quotient""): INT; It calculates the I-depth of the module M. I is a homogeneous IDEAL and M is a nonzero module, expressed in the same way you would use for the function Ext, so it has to be either free or a quotient of the type R^s/W. However, M does not have to be necessarily homogeneous. If I is not specified like in the second form, then we assume that I is the maximal ideal generated by the indeterminates. If M is homogeneous and I is the ideal generated by the indeterminates (or if it is not specified), then the function Depth uses the Auslander-Buchsbaum formula: Depth_I(M)=N-pd(M) where N is the number of intederminates and pd(M) is the lenght of a minimal free resolution of M. Otherwise, it calculates the modules Ext^I_R(R/I,M) and return the first index I such that Ext^I is not zero. -------------------[ EXAMPLES using DEPTH ]----------------------- Use R::=Q[x,y,z]; Ext.Depth(Ideal(1)); -- it's the (x,y,z)-depth of the entire ring so it's 3 3 ------------------------------- I:=Ideal(x^5,y^3,z^2); --- let's check that it is zerodimensional and CM Dim(R/I); Ext.Depth(R/I); 0 ------------------------------- 0 ------------------------------- N:=Module([x^2,y],[x+z,0]); Ext.Depth(I,R^2/N); --- a max reg sequence would be (z^2,y^3) 2 ------------------------------- Use R::=Q[x,y,z,t,u,v]; N:=Module([x,y],[-y,x],[z,t],[-t,z],[u,v],[-v,u]); -- Cauchy-Riemann system in three complex vars! --- is it CM? Depth(R^2/N); Dim(R^2/N); 3 ------------------------------- 3 ------------------------------- --- yes! M:=Module([x,y,z],[t,v,u]); Res(R^3/M); 0 --> R^2(-1) --> R^3 ------------------------------- Ext.Depth(R^3/M); -- using Auslander Buchsbaum 6-1=5 5 ------------------------------- Dim(R^3/M); -- not CM 6 ------------------------------- Depth(Ideal(x,y,z,t),R^2/N); -- can you find a reg sequence here? 2 ------------------------------- Please send your (always very appreciated) comments, questions, bugs reports and ideas to alberto@tlc185.com " End; --- Man ----------------------[ MAIN FUNCTIONS ]----------------------------- Define Ext(I,RM,RN); -- I:= a positive INTeger I, or a LIST of positive INTegers, and two QUOTIENT modules (may be zeromodules) -- O:= a presentation of the module Ext^I_R(RM,RN) if I is an Integer -- -- if I is a list it PRINTS (only prints!!) all modules Ext^J_R(RM,RN) for each J in I -- If Type(I)=LIST Then Exts:=[[J,Ext.Ext(J,RM,RN)]|J In I]; Return Ext.Tagged(Exts,"ExtList"); Elsif Type(I)=INT Then If I<0 Then Error("Ext: Index must be positive");EndIf; If Ext.IsZeroModule(RM) Or Ext.IsZeroModule(RN) Then Return Module([0]); Elsif Ext.IsFreeModule(RM) Then If IsZero(I) Then S:=NumComps(RM); T:=NumComps(RN); If Ext.IsFreeModule(RN) Then Return R^(S*T);EndIf; N:=@RN; U:=Ext.SpecialHom(S,N); Return Ext.MinimalPresentation(CurrentRing()^(S*T)/U); Else Return Module([0]); EndIf; Else ---- RM is not a free module so it is of the type R^S/M M:=@RM; ResM:=Res(M); If Ext.IsFreeModule(RN) And NumComps(RN)=1 Then --- Then it is Ext^I(R^S/M,R) Return Ext.MinimalPresentation(Ext.NoShiftExt_FromRes(I,ResM)); Elsif Ext.IsFreeModule(RN) Then N:=Ext.ZeroModule(RN); Return Ext.MinimalPresentation(Ext.NoShiftExt_RM_RN_FromRes(I,ResM,N)); Else N:=@RN; Return Ext.MinimalPresentation(Ext.NoShiftExt_RM_RN_FromRes(I,ResM,N)); EndIf; EndIf; Else Error("Ext: first argument must be INT or LIST of INT"); EndIf; EndDefine; ---------------------- DEPTH Define Depth(...); If Len(ARGV)=2 Then I:=ARGV[1]; M:=ARGV[2]; Elsif Len(ARGV)=1 Then M:=ARGV[1]; I:=Ideal(Indets()); Else Error("Bad arguments: expected a module and (optional) an ideal"); EndIf; If Type(M)<>TAGGED("Quotient") Then Error("Depth: quotient ideal or module required");EndIf; M:=Tagged(Module(@M),"Quotient"); If Ext.IsZeroModule(M) Then Error("Depth: nonzero module required");EndIf; If I=Ideal(Indets()) And IsHomog(@M) Then ResMod:=Res(M); ResLen:=Len(ResMod[2]); Return NumIndets()-ResLen+1; Else N := NumIndets(); D := 0; ResIdeal:=Res(I); P := Ext.NoShiftExt_RM_RN_FromRes(D,ResIdeal,@M); While DLIST And Type(E[1])<>VECTOR Then If Len(E)R^s as a LIST of generators of Im(Phi) -- O: LIST of Generators For Ker(Phi)as constructed In prop 3.3.1 W:=Ext.PhiToModule(Phi); S:=SyzOfGens(W); ToKeep:=Len(Phi); Return [Ext.Truncate(V,ToKeep)|V In Gens(S)]; EndDefine; Define NoShiftKer(Phi,N); -- I: A map Phi:R^r-->R^s/N as a LIST of generators of Im(Phi) -- O: LIST of Generators For Ker(Phi) as constructed In prop 3.3.1 W:=Ext.PhiToModule(Phi); V:=Module(Concat(W.Gens,N.Gens)); S:=SyzOfGens(V); ToKeep:=Len(Phi);-- r; Return [Ext.Truncate(V,ToKeep)|V In Gens(S)]; EndDefine; Define NoShiftQuotient(M,N); -- I: two modules M And N -- O: a presentation of the quotient M/(M intersection N), tagged "quotient" -- Using ??? If M=N Then Return Module([0]);EndIf; G:=Gens(M); H:=Gens(N); All:=Concat(G,H); S:=Syz(All); ToKeep:=Len(G); Denominator:=Module([Ext.Truncate(V,ToKeep)|V In Gens(S)]); Minimalize(Denominator); Return (Tagged(Denominator,"Quotient")); EndDefine; -- NoShiftQuotient -------------------- EXT --------------- Define NoShiftExt_FromRes(I,RES); -- I: a free resolution For a module M -- O: a presentation of Ext^I_R(M,R); Maps:=Ext.MapsFromRes(RES); Dual:=Ext.DualComplex(Maps,[0]); DualMaps:=Dual[1]; If IsZero(I) Then RealMod:=Ext.PhiToModule(Maps[1]);----------------------RealMod; -- Return Tagged(RealMod,"Quotient"); Return $hom.HomR_MR_N(RealMod,Module([1])); ElsIf I