Index: Singular/LIB/sheafcoh.lib
===================================================================
--- Singular/LIB/sheafcoh.lib	(revision 88e5d02561990a0b8b126978b31a19f6dcb68b1c)
+++ Singular/LIB/sheafcoh.lib	(revision 821b2695ea63204befbe039e7efc56c2b7f7f662)
@@ -1,4 +1,4 @@
 ///////////////////////////////////////////////////////////////////////////////
-version="$Id: sheafcoh.lib,v 1.16 2009-04-07 16:18:06 seelisch Exp $";
+version="$Id: sheafcoh.lib,v 1.17 2009-04-10 19:28:58 motsak Exp $";
 category="Commutative Algebra";
 info="
@@ -10,4 +10,5 @@
 PROCEDURES:
  truncate(phi,d);        truncation of coker(phi) at d
+ truncateFast(phi,d);    truncation of coker(phi) at d (fast+ experimental)
  CM_regularity(M);       Castelnuovo-Mumford regularity of coker(M)
  sheafCohBGG(M,l,h);     cohomology of sheaf associated to coker(M)
@@ -15,4 +16,5 @@
  sheafCoh(M,l,h);        cohomology of sheaf associated to coker(M)
  dimH(i,M,d);            compute h^i(F(d)), F sheaf associated to coker(M)
+ dimGradedPart()
 
 AUXILIARY PROCEDURES:
@@ -26,4 +28,24 @@
 LIB "nctools.lib";
 LIB "homolog.lib";
+
+
+///////////////////////////////////////////////////////////////////////////////
+// testing for consistency of the library:
+proc testSheafCohLibrary()
+{
+  printlevel = printlevel + 1;
+  example truncate;
+  example truncateFast;
+  example CM_regularity;
+  example sheafCoh;
+  example sheafCohBGG;
+  example dimH;
+  example dimGradedPart;
+  example sheafCohBGG2;
+  example getStructureSheaf;
+  printlevel = printlevel - 1;
+}
+
+
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -40,32 +62,6 @@
 }
 
-// returns transposed Jacobian of a module M
-static proc tJacobian(module M)
-{
-  M = transpose(M);
-
-  int N = nvars(basering);
-  int k = ncols(M);
-  int r = nrows(M);
-
-  module Result;
-  Result[N*k] = 0;
-
-  int i, j;
-  int l = 1;
-
-  for( j = 1; j <= N; j++ ) // for all variables
-  {
-    for( i = 1; i <= k; i++ ) // for every v \in transpose(M)
-    {
-      Result[l] = diff(M[i], var(j));
-      l++;
-    }
-  }
-
-  return(Result);
-}
-
-
+
+///////////////////////////////////////////////////////////////////////////////
 /**
   let M = { w_1, ..., w_k }, k = size(M) == ncols(M), n = nvars(currRing).
@@ -91,4 +87,6 @@
 static proc TensorModuleMult(int m, module M)
 {
+  return( system("tensorModuleMult", m, M) ); // trick!
+
   int n = nvars(basering);
   int k = ncols(M);
@@ -142,4 +140,12 @@
   return(j);
 }
+
+///////////////////////////////////////////////////////////////////////////////
+static proc min(int i,int j)
+{
+  if(i>j){return(j);}
+  return(i);
+}
+
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -171,5 +177,5 @@
   int i,m,dummy;
   int s = nrows(phi);
-  module L;
+  module L; // TOO BIG!!!
   for (i=1; i<=s; i++) {
     if (d>v[i]) {
@@ -218,4 +224,174 @@
 ///////////////////////////////////////////////////////////////////////////////
 
+proc truncateFast(module M, int d)
+"USAGE:   truncateFast(M,d);  M module, d int
+ASSUME:  @code{M} is graded, and it comes assigned with an admissible degree
+         vector as an attribute 'isHomog'
+RETURN:  module
+NOTE:    Output is a presentation matrix for the truncation of coker(M)
+         at d.
+         Fast + experimental version. M shoud be a SB!
+DISPLAY: If @code{printlevel}>=1, step-by step timings will be printed.
+         If @code{printlevel}>=2 we add progress debug messages 
+         if @code{printlevel}>=3, even all intermediate results...
+EXAMPLE: example truncateFast; shows an example
+KEYWORDS: truncated module
+"
+{
+//  int PL = printlevel + 1;
+  int PL = printlevel - voice + 2;
+
+  dbprint(PL-1, "// truncateFast(M: "+ string(nrows(M)) + " x " + string(ncols(M)) +", " + string(d) + "):");
+  dbprint(PL-2, M);
+  
+  intvec save = option(get);
+  if( PL >= 2 )
+  {
+    option(prot);    
+    option(mem);    
+  }
+
+  int tTruncateBegin=timer;
+
+  if (attrib(M,"isSB")!=1)
+  {
+    ERROR("M must be a standard basis!");
+  };
+
+  dbprint(PL-1, "// M is a SB! ");
+
+  if ( typeof(attrib(M,"isHomog"))=="string" ) {
+    if (size(M)==0) {
+      // assign weights 0 to generators of R^n (n=nrows(M))
+      intvec v;
+      v[nrows(M)]=0;
+      attrib(M,"isHomog",v);
+    }
+    else {
+      ERROR("No admissible degree vector assigned");
+    }
+  }
+  else {
+   intvec v=attrib(M,"isHomog");
+  }
+
+  dbprint(PL-1, "// weighting(M): ["+ string(v) + "]");
+
+  int i,m,dummy;
+  int s = nrows(M);
+
+   int tKBaseBegin = timer;
+    module L = kbase(M, d); // TODO: check whether this is always correct!?!
+
+
+    dbprint(PL-1, "// L = kbase(M,d): "+string(nrows(L)) + " x " + string(ncols(L)) +"");
+    dbprint(PL-2, L);
+    dbprint(PL-1, "// weighting(L): ["+ string(attrib(L, "isHomog")) + "]");
+
+   int tModuloBegin = timer;
+    L = modulo(L,M);
+
+    dbprint(PL-1, "// L = modulo(L,M): "+string(nrows(L)) + " x " + string(ncols(L)) +"");
+    dbprint(PL-2, L);
+    dbprint(PL-1, "// weighting(L): ["+ string(attrib(L, "isHomog")) + "]");
+
+   int tPruneBegin = timer;
+    L = prune(L);
+
+    dbprint(PL-1, "// L = prune(L): "+string(nrows(L)) + " x " + string(ncols(L)) +"");
+    dbprint(PL-2, L);
+    dbprint(PL-1, "// weighting(L): ["+ string(attrib(L, "isHomog")) + "]");
+
+   int tPruneEnd = timer;
+    L = minbase(L);
+   int tMinBaseEnd = timer;
+
+    dbprint(PL-1, "// L = minbase(L): "+string(nrows(L)) + " x " + string(ncols(L)) +"");
+    dbprint(PL-2, L);
+    dbprint(PL-1, "// weighting(L): ["+ string(attrib(L, "isHomog")) + "]");
+
+
+
+
+  if (size(L)!=0)
+  {
+
+    // it only remains to set the degrees for L:
+    // ------------------------------------------
+    m = v[1];
+    for(i=2; i<=size(v); i++) {  if(v[i]<m) { m = v[i]; } }
+    dummy = homog(L);
+    intvec vv = attrib(L,"isHomog");
+    if (d>m) { vv = vv+d; }
+    else     { vv = vv+m; }
+    attrib(L,"isHomog",vv);
+  }
+
+  int tTruncateEnd=timer;
+  
+  dbprint(PL-1, "// corrected weighting(L): ["+ string(attrib(L, "isHomog")) + "]");
+
+
+  if(PL > 0)
+  {
+  "
+  -------------- TIMINGS --------------
+  Trunc        Time: ", tTruncateEnd - tTruncateBegin, "
+    :: Before .Time: ", tKBaseBegin - tTruncateBegin, "
+    :: kBase   Time: ", tModuloBegin - tKBaseBegin, "
+    :: Modulo  Time: ", tPruneBegin - tModuloBegin, "
+    :: Prune   Time: ", tPruneEnd - tPruneBegin, "
+    :: Minbase Time: ", tMinBaseEnd - tPruneEnd, "
+    :: After  .Time: ", tTruncateEnd - tMinBaseEnd;
+  }
+  
+  option(set, save);
+
+  return(L);
+}
+example
+{"EXAMPLE:";
+   echo = 2;
+   ring R=0,(x,y,z,u,v),dp;
+   module M=maxideal(3);
+   homog(M);
+   // compute presentation matrix for truncated module (R/<x,y,z,u>^3)_(>=2)
+   int t=timer;
+   module M2t=truncate(M,2);
+   t = timer - t;
+   "// Simple truncate: ", t;
+   t=timer;
+   module M2=truncateFast(std(M),2);
+   t = timer - t;
+   "// Fast truncate: ", t;
+   print(M2);
+   "// Check: M2t == M2?: ", size(NF(M2, std(M2t))) + size(NF(M2t, std(M2)));
+
+   dimGradedPart(M2,1);
+   dimGradedPart(M2,2);
+   // this should coincide with:
+   dimGradedPart(M,2);
+   // shift grading by 1:
+   intvec v=1;
+   attrib(M,"isHomog",v);
+   t=timer;
+   M2t=truncate(M,2);
+   t = timer - t;
+   "// Simple truncate: ", t;
+   t=timer;
+   M2=truncateFast(std(M),2);
+   t = timer - t;
+   "// Fast truncate: ", t;
+   print(M2);
+   "// Check: M2t == M2?: ", size(NF(M2, std(M2t))) + size(NF(M2t, std(M2))); //?
+   dimGradedPart(M2,3);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+
+
+
+
 proc dimGradedPart(module phi, int d)
 "USAGE:   dimGradedPart(M,d);  M module, d int
@@ -304,5 +480,13 @@
     }
   }
-  def L = mres(M,0);
+  
+  if( attrib(CM_regularity,"Algorithm") != "mres" )
+  {
+    def L = minres( res(M,0) ); // let's try it out!
+  } else
+  {
+    def L = mres(M,0);
+  }
+  
   intmat BeL = betti(L);
   int r = nrows(module(matrix(BeL)));  // last non-zero row
@@ -445,4 +629,74 @@
 }
 
+
+///////////////////////////////////////////////////////////////////////////////
+static proc showResult( def R, int l, int h )
+{
+  int PL = printlevel - voice + 2;
+// int PL = printlevel + 1;
+
+  intmat Betti;
+  if(typeof(R)=="resolution")
+  {
+    Betti = betti(R);
+  } else
+  {
+    if(typeof(R)!="intmat")
+    {
+      ERROR("Wrong input!!!");
+    };
+
+    Betti = R;  
+  }  
+
+  int n=nvars(basering)-1;
+  int ell = l + n;
+
+  int k     = ncols(Betti);
+  int row   = nrows(Betti);
+  int shift = attrib(Betti,"rowShift") + (k + ell - 1);
+
+  intmat newBetti[ n + 1 ][ h - l + 1 ];
+
+  int i, j;
+
+  for (j=1; j<=row; j++) {
+    for (i=l; i<=h; i++) {
+      if( (n+2-shift-j)>0 ) {
+
+        if (  (k+1-j-i+ell-shift>0) and (j+i-ell+shift>=1)) {
+          newBetti[n+2-shift-j,i-l+1]=Betti[j,k+1-j-i+ell-shift];
+        }
+        else { newBetti[n+2-shift-j,i-l+1]=-1; }
+
+      }
+    }
+  }
+
+  int iWTH = h-l+1;
+  for (j=2; j<=n+1; j++) {
+    for (i=1; i<min(j, iWTH); i++) {
+      newBetti[j,i]=-1;
+    }
+  }
+  int d = k - h + ell - 1;
+  for (j=1; j<=n; j++) {
+    for (i=iWTH; i>=k+j; i--) {
+      newBetti[j,i]=-1;
+    }
+  }
+
+  if( PL > 0 )
+  {
+    "Cohomology table:";
+    displayCohom(newBetti, l, h, n);
+  }
+
+  return(newBetti);
+}
+///////////////////////////////////////////////////////////////////////////////
+
+
+
 ///////////////////////////////////////////////////////////////////////////////
 proc sheafCohBGG2(module M,int l,int h)
@@ -468,4 +722,7 @@
          refers to a negative entry (= dimension not yet determined).
          refers to a not computed dimension. @*
+         If @code{printlevel}>=1, step-by step timings will be printed.
+         If @code{printlevel}>=2 we add progress debug messages 
+         if @code{printlevel}>=3, even all intermediate results...
 NOTE:    This procedure is based on the Bernstein-Gel'fand-Gel'fand
          correspondence and on Tate resolution ( see [Eisenbud, Floystad,
@@ -480,84 +737,219 @@
 "
 {
+  int PL = printlevel - voice + 2;
+//  int PL = printlevel;
+
+  dbprint(PL-1, "// sheafCohBGG2(M: "+ string(nrows(M)) + " x " + string(ncols(M)) +", " + string(l) + ", " + string(h) + "):");
+  dbprint(PL-2, M);
+
+  intvec save = option(get);
+  
+  if( PL >= 2 )
+  {
+    option(prot);    
+    option(mem);    
+  }
+
+  def isCoker = attrib(M, "isCoker");
+  if( typeof(isCoker) == "int" )    
+  {
+    if( isCoker > 0 )
+    {
+      dbprint(PL-1, "We are going to assume that M is given by coker matrix (that is, M is not a submodule presentation!)");
+    }
+  }
+
+           
   int i,j,k,row,col;
+  
   if( typeof(attrib(M,"isHomog"))!="intvec" ) {
      if (size(M)==0) { attrib(M,"isHomog",0); }
      else { ERROR("No admissible degree vector assigned"); }
   }
-  intvec ivOptionsSave = option(get);
+
+  dbprint(PL-1, "// weighting(M): ["+ string(attrib(M, "isHomog")) + "]");
+  
   option(redSB); option(redTail);
 
-  int n=nvars(basering)-1;
-  int ell=l+n;
   def R=basering;
-  int reg = CM_regularity(M);
-  int bound=max(reg+1,h-1);
-  module MT=truncate(M,bound);
+
+  int n = nvars(R) - 1;
+  int ell = l + n;
+
+  
+/////////////////////////////////////////////////////////////////////////////
+// computations 
+
+  int tBegin=timer;
+  int reg   = CM_regularity(M);
+  int tCMEnd = timer;
+
+  dbprint(PL-1, "// CM_reg(M): "+ string(reg));
+
+  int bound = max(reg + 1, h - 1);
+
+  dbprint(PL-1, "// bound: "+ string(bound));
+
+  ///////////////////////////////////////////////////////////////
+  int tSTDBegin=timer;
+  M = std(M); // for kbase! // NOTE: this should be after CM_regularity, since otherwise CM_regularity computes JUST TOOOOOOO LONG sometimes (see Reg_Hard examples!)
+  int tSTDEnd = timer;
+
+  dbprint(PL-1, "// M = std(M: "+string(nrows(M)) + " x " + string(ncols(M))  + ")");
+  dbprint(PL-2, M);
+  dbprint(PL-1, "// weighting(M): ["+ string(attrib(M, "isHomog")) + "]");  
+
+
+  printlevel = printlevel + 1;
+  int tTruncateBegin=timer;
+  module MT = truncateFast(M, bound);
+  int tTruncateEnd=timer;
+  printlevel = printlevel - 1;
+
+  dbprint(PL-1, "// MT = truncateFast(M: "+string(nrows(MT)) + " x " + string(ncols(MT)) +", " + string(bound) + ")");
+  dbprint(PL-2, MT);
+  dbprint(PL-1, "// weighting(MT): ["+ string(attrib(MT, "isHomog")) + "]");  
+  
   int m=nrows(MT);
-  MT = tJacobian(MT); // transpose(jacobM(MT));
-  MT=syz(MT);
-
+
+  ///////////////////////////////////////////////////////////////
+  int tTransposeJacobBegin=timer;
+  MT = jacob(MT); // ! :(
+  int tTransposeJacobEnd=timer;
+
+
+  dbprint(PL-1, "// MT = jacob(MT: "+string(nrows(MT)) + " x " + string(ncols(MT))  + ")");
+  dbprint(PL-2, MT);
+  dbprint(PL-1, "// weighting(MT): ["+ string(attrib(MT, "isHomog")) + "]");  
+  
+
+  int tSyzBegin=timer;
+  MT = syz(MT);
+  int tSyzEnd=timer; 
+
+
+  dbprint(PL-1, "// MT = syz(MT: "+string(nrows(MT)) + " x " + string(ncols(MT))  + ")");
+  dbprint(PL-2, MT);
+  dbprint(PL-1, "// weighting(MT): ["+ string(attrib(MT, "isHomog")) + "]");  
+
+  
+  int tMatrixOppBegin=timer;
   module SS = TensorModuleMult(m, MT);
-
+  int tMatrixOppEnd=timer;  
+
+  dbprint(PL-1, "// SS = TensorModuleMult("+ string(m)+ ", MT: "+string(nrows(MT)) + " x " + string(ncols(MT))  + ")");
+  dbprint(PL-2, SS);
+  dbprint(PL-1, "// weighting(SS): ["+ string(attrib(SS, "isHomog")) + "]");  
+  
+  
   //--- to the exterior algebra
   def AR = Exterior(); setring AR;
 
+  dbprint(PL-1, "// Test: var(1) * var(1): "+ string(var(1) * var(1)));
+
+  int maxbound = max(1, bound - ell + 1);
+//  int maxbound = max(1, bound - l + 1); // As In M2!!!
+
+  dbprint(PL-1, "// maxbound: "+ string(maxbound));
+  
+  //--- here we are with our matrix
   module EM=imap(R,SS);
   intvec w;
-  //--- here we are with our matrix
-  int bound1=max(1,bound-ell+1);
   for (i=1; i<=nrows(EM); i++)
   {
      w[i]=-bound-1;
   }
+
   attrib(EM,"isHomog",w);
-  resolution RE = minres(nres(EM,bound1));
-  intmat Betti=betti(RE);
-  k=ncols(Betti);
-  row=nrows(Betti);
-  int shift=attrib(Betti,"rowShift")+(k+ell-1);
-  intmat newBetti[n+1][h-l+1];
-  for (j=1; j<=row; j++) {
-    for (i=l; i<=h; i++) {
-      if ((k+1-j-i+ell-shift>0) and (j+i-ell+shift>=1)) {
-        newBetti[n+2-shift-j,i-l+1]=Betti[j,k+1-j-i+ell-shift];
-      }
-      else { newBetti[n+2-shift-j,i-l+1]=-1; }
-    }
-  }
-  for (j=2; j<=n+1; j++) {
-    for (i=1; i<j; i++) {
-      newBetti[j,i]=-1;
-    }
-  }
-  int d=k-h+ell-1;
-  for (j=1; j<=n; j++) {
-    for (i=h-l+1; i>=k+j; i--) {
-      newBetti[j,i]=-1;
-    }
-  }
-  displayCohom(newBetti,l,h,n);
-
+
+  
+
+  ///////////////////////////////////////////////////////////////
+
+  dbprint(PL-1, "// EM: "+string(nrows(EM)) + " x " + string(ncols(EM))  + ")");
+  dbprint(PL-2, EM);
+  dbprint(PL-1, "// weighting(EM): ["+ string(attrib(EM, "isHomog")) + "]");  
+  
+
+  int tResulutionBegin=timer;
+  resolution RE = nres(EM, maxbound); 
+  int tMinResBegin=timer;
+  RE = minres(RE);   
+  int tBettiBegin=timer;
+  intmat Betti = betti(RE); // betti(RE, 1);?
+  int tResulutionEnd=timer;
+  
+  int tEnd = tResulutionEnd;
+
+  if( PL > 0 )
+  {
+    "
+        ----      RESULTS  ----  
+        Tate Resolution (Length: ", size(RE), "): 
+    ";
+    RE;
+    "Betti numbers for Tate resolution (diagonal cohomology table):";
+    print(Betti, "betti"); // Diagonal form!
+  };
+
+  
+  printlevel = printlevel + 1;
+  Betti = showResult(Betti, l, h ); // Show usual form of cohomology table
+  printlevel = printlevel - 1;
+
+  
+  if(PL > 0)
+  {
+  "
+      ----      TIMINGS     -------
+      Trunc      Time: ", tTruncateEnd - tTruncateBegin, "
+      Reg        Time: ", tCMEnd - tBegin, "
+      kStd       Time: ", tSTDEnd - tSTDBegin, "
+      Jacob      Time: ", tTransposeJacobEnd - tTransposeJacobBegin, "
+      Syz        Time: ", tSyzEnd - tSyzBegin, "
+      Mat        Time: ", tMatrixOppEnd - tMatrixOppBegin, "
+      ------------------------------  
+      Res        Time: ", tResulutionEnd - tResulutionBegin, "
+      :: NRes    Time: ", tMinResBegin - tResulutionBegin, "
+      :: MinRes .Time: ", tBettiBegin - tMinResBegin, "
+      :: Betti  .Time: ", tResulutionEnd - tBettiBegin, "
+      ---------------------------------------------------------
+      Total Time: ", tEnd - tBegin, "
+      ---------------------------------------------------------
+      ";
+  };
+  
   setring R;
-  option(set, ivOptionsSave);
-
-  return(newBetti);
+
+  option(set, save);
+
+  return(Betti);
 }
 example
 {"EXAMPLE:";
    echo = 2;
+   int pl = printlevel;
    // cohomology of structure sheaf on P^4:
    //-------------------------------------------
-   ring r=0,x(1..5),dp;
-   module M=0;
-   def A=sheafCohBGG2(0,-9,4);
+   ring r=32001,x(1..5),dp;
+   module M= getStructureSheaf();
+
+   int t = timer;
+   def A=sheafCohBGG(0,-9,4);
+   timer - t;
+   
+   printlevel = voice; A=sheafCohBGG2(0,-9,4); printlevel = pl;
+   
    // cohomology of cotangential bundle on P^3:
    //-------------------------------------------
-   ring R=0,(x,y,z,u),dp;
-   resolution T1=mres(maxideal(1),0);
-   module M=T1[3];
-   intvec v=2,2,2,2,2,2;
-   attrib(M,"isHomog",v);
-   def B=sheafCohBGG2(M,-8,4);
+   ring R=32001,(x,y,z,u),dp;
+
+   module M = getCotangentialBundle();
+   
+   int t = timer;
+   def B=sheafCohBGG(M,-8,4);
+   timer - t;
+   
+   printlevel = voice; B=sheafCohBGG2(M,-8,4); printlevel = pl;
 }
 
@@ -790,4 +1182,144 @@
 }
 ///////////////////////////////////////////////////////////////////////////////
+
+proc getStructureSheaf(list #)
+{
+
+  if( size(#) == 0 )
+  {
+
+    module M = 0;
+    intvec v = 0;
+    attrib(M,"isHomog",v);
+    homog(M);
+
+    attrib(M, "isCoker", 1);
+
+    attrib(M);    
+    return(M);
+  };
+
+  
+
+
+  
+  if( typeof(#[1]) == "ideal")
+  {
+
+
+    ideal I = #[1];
+
+    if( size(#) == 2 )
+    {
+      if( typeof(#[2]) == "int" )
+      {
+        if( #[2] != 0 )
+        {
+          qring @@@@QQ = std(I);
+
+          module M = getStructureSheaf();
+          
+          export M;
+
+//          keepring @@@@QQ; // This is a bad idea... :(
+          return (@@@@QQ);
+        }
+      }
+    }
+
+/*
+    // This seems to be wrong!!!
+    module M = I * gen(1);
+    homog(M);
+    
+    M = modulo(gen(1), module(I * gen(1))); // basering^1 / I 
+
+    homog(M);
+    
+    attrib(M, "isCoker", 1);
+
+    attrib(M);
+    return(M);
+*/    
+  }   
+  
+  ERROR("Wrong argument");
+  
+}   
+example
+{"EXAMPLE:";
+   echo = 2; int pl = printlevel;
+   printlevel = voice;
+
+
+   ////////////////////////////////////////////////////////////////////////////////
+   ring r;
+   module M = getStructureSheaf();
+   "Basering: ";
+   basering;
+   "Module: ", string(M), ", grading is given by weights: ", attrib(M, "isHomog");
+
+   def A=sheafCohBGG2(M,-9,9); 
+   print(A);
+   
+   ////////////////////////////////////////////////////////////////////////////////
+   setring r;
+   module M = getStructureSheaf(ideal(var(1)), 0);
+   
+   "Basering: ";
+   basering;
+   "Module: ", string(M), ", grading is given by weights: ", attrib(M, "isHomog");
+
+   def A=sheafCohBGG2(M,-9,9); 
+   print(A);
+
+   ////////////////////////////////////////////////////////////////////////////////
+   setring r;
+   def Q = getStructureSheaf(ideal(var(1)), 1); // returns a new ring!
+   setring Q; // M was exported in the new ring!
+   
+   "Basering: ";
+   basering;
+   "Module: ", string(M), ", grading is given by weights: ", attrib(M, "isHomog");
+
+   def A=sheafCohBGG2(M,-9,9); 
+   print(A);
+
+   printlevel = pl;
+}
+
+
+proc getCotangentialBundle()
+{
+  resolution T1=mres(maxideal(1),3);
+  module M=T1[3];
+  attrib(M,"isHomog");
+  homog(M);
+  attrib(M, "isCoker", 1);
+  attrib(M);
+  return (M);
+};
+
+proc getIdealSheafPullback(ideal I, ideal pi)
+{
+  def save = basering;
+  map P = save, pi;
+  return( P(I) );
+}
+
+// TODO: set attributes!
+
+
+proc getIdealSheaf(ideal I)
+{
+  resolution FI = mres(I,2); // Syz + grading...
+  module M = FI[2];
+  attrib(M, "isCoker", 1);
+  attrib(M);
+  return(M);
+};
+
+
+
 
 
