Index: Singular/LIB/schreyer.lib
===================================================================
--- Singular/LIB/schreyer.lib	(revision 2c16b81352589f222e0e327ed8ce64db62736728)
+++ Singular/LIB/schreyer.lib	(revision 14e93b441b4c859a8d51eeeb99f68c2ff924c4bd)
@@ -1578,116 +1578,177 @@
   }
 
-  def a; bigint c; int r, k; poly aa;
-
-  int @LEAD2SYZ = 0;
-  if( typeof( attrib(basering, "LEAD2SYZ") ) == "int" )
-  {
-    @LEAD2SYZ = attrib(basering, "LEAD2SYZ");
-  }
-
-  int @TAILREDSYZ = 1;
-  if( typeof( attrib(basering, "TAILREDSYZ") ) == "int" )
-  {
-    @TAILREDSYZ = attrib(basering, "TAILREDSYZ");
-  }
-
-  int @HYBRIDNF = 0;
-  if( typeof( attrib(basering, "HYBRIDNF") ) == "int" )
-  {
-    @HYBRIDNF = attrib(basering, "HYBRIDNF");
-  }
-
-  module LL;
-  def a2; int r2; poly aa2;  
-
-  /// Get the critical leading syzygy terms
-  if( @LEAD2SYZ ) // & 2nd syz. term
-  {
-    module LL2;
-    (LL, LL2) = SSCompute2LeadingSyzygyTerms(L); // ++ 
-  } else
-  {
-    LL = SSComputeLeadingSyzygyTerms(L);
-  }
-
-  module TT, SYZ; def spoly;
-
-  if( size(LL) > 0 )
-  {
-    list LS;
-
-    if( @TAILREDSYZ)
-    {
-      LS = list(LL);
-    }
-
-    vector @tail;
-
-    for(k = ncols(LL); k > 0; k-- )
-    {
-      // leading syz. term:
-      a = LL[k]; c = leadcomp(a); r = int(c); aa = leadmonomial(a);
-      //    "A: ", a, " --->>>> ", aa, " **** [", r, "]: ";
-
-      // NF reduction:
-      if( !@HYBRIDNF )
+  list @res = ComputeSyzygy(L, T); 
+
+  module @LL = @res[1]; module @TT = @res[2];
+
+  if( @KERCHECK )
+  {
+    if( typeof( attrib(basering, "SYZCHECK") ) == "int" )
+    {
+      int @SYZCHECK = attrib(basering, "SYZCHECK");
+    } else
+    {
+      int @SYZCHECK = @DEBUG;
+    }
+
+    int @LEAD2SYZ = 1;
+    if( typeof( attrib(basering, "LEAD2SYZ") ) == "int" )
+    {
+      @LEAD2SYZ = attrib(basering, "LEAD2SYZ");
+    }
+
+    int @TAILREDSYZ = 1;
+    if( typeof( attrib(basering, "TAILREDSYZ") ) == "int" )
+    {
+      @TAILREDSYZ = attrib(basering, "TAILREDSYZ");
+    }
+
+    int @HYBRIDNF = 0;
+    if( typeof( attrib(basering, "HYBRIDNF") ) == "int" )
+    {
+      @HYBRIDNF = attrib(basering, "HYBRIDNF");
+    }
+
+    module LL;
+
+    /// Get the critical leading syzygy terms
+    if( @LEAD2SYZ ) // & 2nd syz. term
+    {
+      module LL2;
+      (LL, LL2) = SSCompute2LeadingSyzygyTerms(L); 
+    } else
+    {
+      LL = SSComputeLeadingSyzygyTerms(L);
+    }
+
+    module TT, SYZ;
+
+    vector a, a2; bigint c; int r; poly aa;
+
+    if( size(LL) > 0 )
+    {
+      list LS;
+
+      if( @TAILREDSYZ)
       {
-        /// TODO: save shortcut (aa) * T[r] -> ?
-        @tail = SSTraverseTail(aa, T[r], L, T, LS);
-  // //      @tail = SSTraverseTail(a, L, T, LS);
-
-        // get the 2nd syzygy term...
-
-        if( @LEAD2SYZ ) // with the 2nd syz. term:
-        {      
-          a2 = LL2[k]; c = leadcomp(a2); r2 = int(c); aa2 = leadmonomial(a2);
-
-          @tail = @tail + a2 + 
-               /// TODO: save shortcut (aa2) * T[r2] -> ?
-               SSTraverseTail(aa2, T[r2], L, T, LS);
-  // //               SSTraverseTail(a2, L, T, LS);
-        } else
+        LS = list(LL);
+      }
+
+      vector @tail;
+
+      for(int k = ncols(LL); k > 0; k-- )
+      {
+        // leading syz. term:
+        a = LL[k]; c = leadcomp(a); r = int(c); aa = leadmonomial(a);
+
+        // NF reduction:
+        if( !@HYBRIDNF ) // Traverse approach:
+        {        
+          @tail = SSTraverseTail(aa, T[r], L, T, LS);
+
+          // get the 2nd syzygy term...
+          if( @LEAD2SYZ ) // with the 2nd syz. term:
+          {      
+            a2 = LL2[k]; c = leadcomp(a2); r = int(c); aa = leadmonomial(a2);
+
+            @tail = a2 + @tail + SSTraverseTail(aa, T[r], L, T, LS);
+          } else
+          {
+            @tail = @tail + SSReduceTerm(aa, L[r], a, L, T, LS);
+          }
+
+        } else // Hybrid approach:
         {
-          @tail = @tail +
-                  SSReduceTerm(aa, L[r], a, L, T, LS);
-  // //                  SSReduceTerm(a, L, T, LS);
+
+          // get the 2nd syzygy term...
+          if( @LEAD2SYZ )
+          {
+            a2 = LL2[k];
+          } else
+          {
+            a2 = SSFindReducer( aa * L[r], a, L, LS);
+          }
+
+          if ( (@SYZCHECK || @DEBUG) )
+          {
+            if( size(a2) == 0 ) // if syzterm == 0!!!!
+            {
+              "ERROR in SSComputeSyzygy: could not find the 2nd syzygy term during the hybrid NF!!!";
+              $
+            }
+          }
+
+          @tail = SSSchreyerSyzygyNF(a, a2, L, T, LS);
         }
-      } else
-      {
-        if( @LEAD2SYZ )
-        {
-          a2 = LL2[k];
-        } else
-        {
-          a2 = SSFindReducer( aa * L[r], a, L, LS);
-        }
-
-        if ( (@SYZCHECK || @DEBUG) )
-        {
-          if( size(a2) == 0 ) // if syzterm == 0!!!!
-          {
-            "ERROR: could not find the 2nd syzygy term during the hybrid NF!!!";
-            $
-          }
-        }
-
-        @tail = SSSchreyerSyzygyNF(a, a2, L, T, LS);
+
+        TT[k] = @tail;
+        SYZ[k] = a + @tail;
       }
-      
-      TT[k] = @tail;
-      SYZ[k] = a + @tail;
-    }
-  }
-
+    }
+
+    if( ncols(LL) != ncols(@LL) )
+    {
+      "ERROR in SSComputeSyzygy: wrong leading syzygies!?";
+      "";
+      L; T;
+      "";
+      type(LL);
+      type(@LL);
+      $
+    }
+
+    if( ncols(TT) != ncols(@TT) )
+    {
+      "ERROR in SSComputeSyzygy: wrong tail syzygies!?";
+      "";
+      L; T;
+      "";
+      type(LL);
+      type(@LL);
+      "";
+      type(TT);
+      type(@TT);
+      $
+    }
+    
+    if( size( module( matrix(LL) - matrix(@LL) ) ) != 0 )
+    {
+      "ERROR in SSComputeSyzygy: wrong leading syzygies!?";
+      "";
+      L; T;
+      "";
+      type(LL);
+      type(@LL);
+      $
+    }
+
+
+    if( size( module( matrix(TT) - matrix(@TT) ) ) != 0 )
+    {
+      "ERROR in SSComputeSyzygy: wrong tail syzygies!?";
+      TT; @TT;
+      L; T;
+      $
+    }   
+    
+  }
+
+  module @SYZ;
+  
+  for(int @k = ncols(@LL); @k > 0; @k-- )
+  {
+    @SYZ[@k] = @LL[@k] + @TT[@k];
+  }
+  
   if( @DEBUG )
   {
     "SSComputeSyzygy::Output";
 
-    "SYZ: "; SYZ;
-    "LL: "; LL;
-    "TT: "; TT;
-  }
-
-  return (SYZ, LL, TT);
+//    "SYZ: "; @SYZ;
+    "LL: "; @LL;
+    "TT: "; @TT;
+  }
+
+  return (@SYZ, @LL, @TT);
 }
 
@@ -2050,4 +2111,5 @@
 
       exportto(Schreyer, Syzextra::SchreyerSyzygyNF);
+      exportto(Schreyer, Syzextra::ComputeSyzygy);
     }
 /*
@@ -2101,4 +2163,5 @@
 
       exportto(Schreyer, Syzextra_g::SchreyerSyzygyNF);
+      exportto(Schreyer, Syzextra_g::ComputeSyzygy);
     }
 */
Index: dyn_modules/syzextra/mod_main.cc
===================================================================
--- dyn_modules/syzextra/mod_main.cc	(revision 2c16b81352589f222e0e327ed8ce64db62736728)
+++ dyn_modules/syzextra/mod_main.cc	(revision 14e93b441b4c859a8d51eeeb99f68c2ff924c4bd)
@@ -1771,4 +1771,171 @@
   return FALSE;
 }
+
+
+
+static void ComputeSyzygy(const ideal L, const ideal T, ideal& LL, ideal& TT, const ring R)
+{
+  assume( R == currRing ); // For attributes :-/
+
+  assume( IDELEMS(L) == IDELEMS(T) );
+  
+#ifndef NDEBUG
+  const BOOLEAN __DEBUG__ = (BOOLEAN)((long)(atGet(currRingHdl,"DEBUG",INT_CMD, (void*)TRUE)));
+#else
+  const BOOLEAN __DEBUG__ = (BOOLEAN)((long)(atGet(currRingHdl,"DEBUG",INT_CMD, (void*)FALSE)));
+#endif
+
+  const BOOLEAN __LEAD2SYZ__ = (BOOLEAN)((long)(atGet(currRingHdl,"LEAD2SYZ",INT_CMD, (void*)1)));
+  const BOOLEAN __TAILREDSYZ__ = (BOOLEAN)((long)(atGet(currRingHdl,"TAILREDSYZ",INT_CMD, (void*)1)));
+  const BOOLEAN __SYZCHECK__ = (BOOLEAN)((long)(atGet(currRingHdl,"SYZCHECK",INT_CMD, (void*)__DEBUG__)));
+
+  const BOOLEAN __HYBRIDNF__ = (BOOLEAN)((long)(atGet(currRingHdl,"HYBRIDNF",INT_CMD, (void*)0)));
+
+
+  if( __LEAD2SYZ__ )
+    LL = Compute2LeadingSyzygyTerms(L, R); // 2 terms!
+  else
+    LL = ComputeLeadingSyzygyTerms(L, R); // 1 term!
+
+  const int size = IDELEMS(LL);
+
+  TT = idInit(size, 0);
+
+  if( size == 1 && LL->m[0] == NULL )
+    return;
+  
+
+  ideal LS = NULL;
+  
+  if( __TAILREDSYZ__ )
+    LS = LL;
+
+  for( int k = size - 1; k >= 0; k-- )
+  {
+    const poly a = LL->m[k]; assume( a != NULL );
+    
+    const int r = p_GetComp(a, R) - 1; 
+    
+    assume( r >= 0 && r < IDELEMS(T) );
+    assume( r >= 0 && r < IDELEMS(L) );
+
+    poly aa = leadmonom(a, R); assume( aa != NULL); // :(    
+    
+    poly a2 = pNext(a);    
+
+    if( a2 != NULL )
+    {
+      TT->m[k] = a2; pNext(a) = NULL;
+    }
+
+    if( ! __HYBRIDNF__ )
+    {
+      poly t = TraverseTail(aa, T->m[r], L, T, LS, R);
+
+      if( a2 != NULL )
+      {
+        assume( __LEAD2SYZ__ );
+
+        const int r2 = p_GetComp(a2, R) - 1; poly aa2 = leadmonom(a2, R); // :(
+
+        assume( r2 >= 0 && r2 < IDELEMS(T) );
+        
+        TT->m[k] = p_Add_q(a2, p_Add_q(t, TraverseTail(aa2, T->m[r2], L, T, LS, R), R), R);
+
+        p_Delete(&aa2, R);
+      } else
+        TT->m[k] = p_Add_q(t, ReduceTerm(aa, L->m[r], a, L, T, LS, R), R);
+
+    } else
+    {
+      if( a2 == NULL )
+      {
+        aa = p_Mult_mm(aa, L->m[r], R);
+        a2 = FindReducer(aa, a, L, LS, R); 
+      }
+      assume( a2 != NULL );
+        
+      TT->m[k] = SchreyerSyzygyNF(a, a2, L, T, LS, R); // will copy a2 :(
+      
+      p_Delete(&a2, R);
+    }
+    p_Delete(&aa, R);    
+  }
+
+  TT->rank = id_RankFreeModule(TT, R);
+}
+
+
+
+// module (N, LL, TT) = SSComputeSyzygy(L, T);
+// Compute Syz(L ++ T) = N = LL ++ TT
+// proc SSComputeSyzygy(def L, def T)
+static BOOLEAN ComputeSyzygy(leftv res, leftv h)
+{
+  const char* usage = "`ComputeSyzygy(<ideal/module>, <ideal/module>])` expected";
+  const ring r = currRing;
+
+  NoReturn(res);
+
+#ifndef NDEBUG
+  const BOOLEAN __DEBUG__ = (BOOLEAN)((long)(atGet(currRingHdl,"DEBUG",INT_CMD, (void*)TRUE)));
+#else
+  const BOOLEAN __DEBUG__ = (BOOLEAN)((long)(atGet(currRingHdl,"DEBUG",INT_CMD, (void*)FALSE)));
+#endif
+
+  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;    
+  }
+
+  const ideal L = (ideal) h->Data();
+
+  assume( IDELEMS(L) > 0 );
+
+  h = h->Next();
+  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;    
+  }
+
+  const ideal T = (ideal) h->Data();
+  assume( IDELEMS(L) == IDELEMS(T) );
+
+
+  h = h->Next(); assume( h == NULL );  
+
+  if( __DEBUG__ )
+  {
+    PrintS("ComputeSyzygy(L, T)::Input: \n");
+
+    PrintS("L: "); dPrint(L, r, r, 0);
+    PrintS("T: "); dPrint(T, r, r, 0);
+  }
+
+  ideal LL, TT;
+
+  ComputeSyzygy(L, T, LL, TT, r);
+
+  lists l = (lists)omAllocBin(slists_bin); l->Init(2);
+
+  l->m[0].rtyp = MODUL_CMD; l->m[0].data = reinterpret_cast<void *>(LL);
+
+  l->m[1].rtyp = MODUL_CMD; l->m[1].data = reinterpret_cast<void *>(TT);
+  
+  res->data = l; res->rtyp = LIST_CMD;
+  
+  if( __DEBUG__ )
+  {
+    PrintS("ComputeSyzygy::Output: ");
+    dPrint(LL, r, r, 0);
+    dPrint(TT, r, r, 0);
+  }
+
+  return FALSE;
+
+}
+
 
 
@@ -2419,4 +2586,5 @@
     
   ADD(psModulFunctions, currPack->libname, "SchreyerSyzygyNF", FALSE, SchreyerSyzygyNF);
+  ADD(psModulFunctions, currPack->libname, "ComputeSyzygy", FALSE, ComputeSyzygy);
   
   //  ADD(psModulFunctions, currPack->libname, "GetAMData", FALSE, GetAMData);
