Index: Singular/LIB/schreyer.lib
===================================================================
--- Singular/LIB/schreyer.lib	(revision f6c4596916eaf5784447ac80bd6f9a76c5315bed)
+++ Singular/LIB/schreyer.lib	(revision fe35f2639131fac3e627cc45a86e0395522c0853)
@@ -1271,28 +1271,49 @@
   }
 
-  vector s = [0];
-
-  if( size(t) > 0 )
-  {
-    def product = m * t;
-
-    s = SSFindReducer(product, syzterm, L/*, T*/, #);
-
-    if( size(s) != 0 )
-    {
-      poly b = leadmonomial(s);
-
-      def c = leadcomp(s); int k = int(c);
-
-      s = s + SSTraverseTail(b, T[k], L, T, #); // !!!   
-    }
-  }
+  if( typeof(#[1]) == "module" )
+  {
+    vector ss = ReduceTerm(m, t, syzterm, L, T, #[1]);
+  } else
+  {
+    vector ss = ReduceTerm(m, t, syzterm, L, T);
+  }
+
+  if( @KERCHECK )
+  {
+    vector s = 0;
+
+    if( size(t) > 0 )
+    {
+      def product = m * t;
+
+      s = SSFindReducer(product, syzterm, L, #);
+
+      if( size(s) != 0 )
+      {
+        poly @b = leadmonomial(s);
+
+        def @c = leadcomp(s); int k = int(@c);
+
+        s = s + SSTraverseTail(@b, T[k], L, T, #); // !!!   
+      }
+    }
     
-  if( @DEBUG )
-  {
-    "SSReduceTerm::Output: ", s;
-  }
-  
-  return (s);
+    if( s != ss )
+    {
+      "ERROR in ReduceTerm => old: ", s, " != ker: ", ss;
+      "m: ", m;
+      "t: ", t;
+      "syzterm: ", syzterm;
+      L; T; #;
+      $;
+    }  
+  }
+
+  if( @DEBUG )
+  {
+    "SSReduceTerm::Output: ", ss;
+  }
+  
+  return (ss);
 }
 
@@ -1331,22 +1352,131 @@
   }
 
-  vector s = 0;
-
-  def @l;
+  if( typeof(#[1]) == "module" )
+  {
+    vector ss = TraverseTail(m, @tail, L, T, #[1]);
+  } else
+  {
+    vector ss = TraverseTail(m, @tail, L, T);
+  }
+
+  if( @KERCHECK )
+  {
+    vector s = 0;
+
+    def @l, @p;
+    @p = @tail;
 
   // iterate tail-terms in ANY order!
-  while( size(@tail) > 0 )
-  {
-    @l = lead(@tail);
-    s = s + SSReduceTerm(m, @l, [0], L, T, #); // :(
-    @tail = @tail - @l;
-  }
-
-  if( @DEBUG )
-  {
-    "SSTraverseTail::Output: ", s;
-  }
-  return (s);
-}
+    while( size(@p) > 0 )
+    {
+      @l = lead(@p);
+      s = s + SSReduceTerm(m, @l, [0], L, T, #); // :(
+      @p = @p - @l;
+    }
+    
+    if( s != ss )
+    {
+      "ERROR in TraverseTail => old: ", s, " != ker: ", ss;
+      "m: ", m;
+      "@tail: ", @tail;
+      L; T; #;
+      $;
+    }  
+  }
+
+  if( @DEBUG )
+  {
+    "SSTraverseTail::Output: ", ss;
+  }
+  
+  return (ss);
+}
+
+// -------------------------------------------------------- //
+
+proc SSSchreyerSyzygyNF(vector syz_lead, vector syz_2, def L, def T, list #)
+"
+   Hybrid Syzygy computation: 'reduce' spoly by eliminating _any_ terms
+   while discurding terms of lower order!
+
+   Return the tail syzygy (without: syz_lead, starting with: syz_2)
+"
+{
+  if( typeof( attrib(basering, "DEBUG") ) == "int" )
+  {
+    int @DEBUG = attrib(basering, "DEBUG");
+  } else
+  {
+    int @DEBUG = !system("with", "ndebug");
+  }
+
+  if( @DEBUG )
+  {
+    "SSSchreyerSyzygyNF::Input: ";
+
+    "syzygy_lead: ", syz_lead;
+    "syzygy 2nd : ", syz_2;
+    L; T; 
+    if( size(#) > 0 )
+    {
+      "LSyz: "; #[1];
+    }
+  }
+
+  if( typeof( attrib(basering, "KERCHECK") ) == "int" )
+  {
+    int @KERCHECK = attrib(basering, "KERCHECK");
+  } else
+  {
+    int @KERCHECK = @DEBUG;
+  }
+
+  if( typeof(#[1]) == "module" )
+  {
+    def my = SchreyerSyzygyNF(syz_lead, syz_2, L, T, #[1]);
+  } else
+  {
+    def my = SchreyerSyzygyNF(syz_lead, syz_2, L, T);
+  }
+
+  if( @KERCHECK )
+  {
+    def spoly = leadmonomial(syz_lead) * T[int(leadcomp(syz_lead))] 
+              + leadmonomial(syz_2)    * T[int(leadcomp(syz_2))];
+
+    vector @tail = syz_2;
+
+    while (size(spoly) > 0)
+    {
+      syz_2 = SSFindReducer(lead(spoly), 0, L, #); spoly = Tail(spoly);
+
+      if( size(syz_2) != 0)
+      {          
+        spoly = spoly + leadmonomial(syz_2) * T[int(leadcomp(syz_2))];
+        @tail = @tail + syz_2;
+      }
+    }
+    
+    if( my != @tail )
+    {
+      "ERROR in SchreyerSyzygyNF => old: ", @tail, " != ker: ", my;
+      
+      "syzygy_lead: ", syz_lead;
+      "syzygy 2nd : ", syz_2;
+      
+      L; T; #;
+      $;
+    }
+  }
+
+  if( @DEBUG )
+  {
+    "SSSchreyerSyzygyNF::Output: ", my;
+  }
+  
+  return (my);
+}
+
+
 
 // -------------------------------------------------------- //
@@ -1462,6 +1592,4 @@
       } else
       {
-        spoly = aa * T[r];
-
         if( @LEAD2SYZ )
         {
@@ -1480,24 +1608,6 @@
           }
         }
-        
-        c = leadcomp(a2); r2 = int(c); aa2 = leadmonomial(a2);
-        
-        spoly = spoly + aa2 * T[r2];
-        @tail = a2;
-
-        while (size(spoly) > 0)
-        {
-          a2 = SSFindReducer( lead(spoly), [0], L/*, T*/, LS);
-          spoly = Tail(spoly);
-
-          if( size(a2) != 0)
-          {          
-            c = leadcomp(a2); r2 = int(c); aa2 = leadmonomial(a2);
-
-            spoly = spoly + aa2 * T[r2];
-            @tail = @tail + a2;
-          }
-        }
-        
+
+        @tail = SSSchreyerSyzygyNF(a, a2, L, T, LS);
       }
       
@@ -1872,4 +1982,9 @@
 
       exportto(Schreyer, Syzextra::FindReducer);
+
+      exportto(Schreyer, Syzextra::ReduceTerm);
+      exportto(Schreyer, Syzextra::TraverseTail);
+
+      exportto(Schreyer, Syzextra::SchreyerSyzygyNF);
     }
 /*
@@ -1919,4 +2034,8 @@
       exportto(Schreyer, Syzextra_g::FindReducer);
       
+      exportto(Schreyer, Syzextra_g::ReduceTerm);
+      exportto(Schreyer, Syzextra_g::TraverseTail);
+
+      exportto(Schreyer, Syzextra_g::SchreyerSyzygyNF);
     }
 */
Index: dyn_modules/syzextra/mod_main.cc
===================================================================
--- dyn_modules/syzextra/mod_main.cc	(revision f6c4596916eaf5784447ac80bd6f9a76c5315bed)
+++ dyn_modules/syzextra/mod_main.cc	(revision fe35f2639131fac3e627cc45a86e0395522c0853)
@@ -1097,14 +1097,19 @@
 
 
-/// TODO: save shortcut (syz: |-.->) LM(LM(m) * "t") -> syz?
-/// proc SSFindReducer(def product, def syzterm, def L, def T, list #)
-static BOOLEAN FindReducer(leftv res, leftv h)
-{
-  const char* usage = "`FindReducer(<poly/vector>, <vector/0>, <ideal/module>[,<module>])` expected";
-  const ring r = currRing;
-
-  NoReturn(res);
-
-
+
+static poly FindReducer(poly product, poly syzterm,
+                        ideal L, ideal LS,
+                        const ring r)
+{
+  assume( product != NULL );
+  assume( L != NULL );
+
+  int c = 0;
+
+  if (syzterm != NULL)
+    c = p_GetComp(syzterm, r) - 1;
+
+  assume( c >= 0 && c < IDELEMS(L) );
+  
 #ifndef NDEBUG
   const BOOLEAN __DEBUG__ = (BOOLEAN)((long)(atGet(currRingHdl,"DEBUG",INT_CMD, (void*)TRUE)));
@@ -1113,83 +1118,7 @@
 #endif
 
-  const BOOLEAN __TAILREDSYZ__ = (BOOLEAN)((long)(atGet(currRingHdl,"TAILREDSYZ",INT_CMD, (void*)0)));
-
-  if ((h==NULL) || (h->Typ()!=VECTOR_CMD && h->Typ() !=POLY_CMD) || (h->Data() == NULL))
-  {
-    WerrorS(usage);
-    return TRUE;    
-  }
-    
-  const poly product = (poly) h->Data(); assume (product != NULL);
-
-
-  h = h->Next();
-  if ((h==NULL) || !((h->Typ()==VECTOR_CMD) || (h->Data() == NULL)) )
-  {
-    WerrorS(usage);
-    return TRUE;    
-  }
-
-  const poly syzterm = (poly) h->Data(); h = h->Next();
-
-  int c = 0;
-  
-  if (syzterm != NULL)
-    c = p_GetComp(syzterm, r) - 1;
-  
-  
-  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
-  {
-    WerrorS(usage);
-    return TRUE;    
-  }
-  
-  const ideal L = (ideal) h->Data(); h = h->Next();
-
-  assume( IDELEMS(L) > 0 );
-  assume( c >= 0 && c < IDELEMS(L) );
-
-  
-/*
-  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
-  {
-    WerrorS(usage);
-    return TRUE;    
-  }
-
-  const ideal T = (ideal) h->Data(); h = h->Next();
-*/
-
-  ideal LS = NULL;
-
-  if ((h != NULL) && (h->Typ() ==MODUL_CMD) && (h->Data() != NULL))
-  {
-    LS = (ideal)h->Data();
-    h = h->Next();
-  }
-
-  if( __TAILREDSYZ__ )
-    assume (LS != NULL);
-
-  assume( h == NULL );
-
-  if( __DEBUG__ )
-  {
-    PrintS("FindReducer(product, syzterm, L, T, #)::Input: \n");
-
-    PrintS("product: "); dPrint(product, r, r, 2);
-    PrintS("syzterm: "); dPrint(syzterm, r, r, 2);
-    PrintS("L: "); dPrint(L, r, r, 2);
-//    PrintS("T: "); dPrint(T, r, r, 4);
-
-    if( LS == NULL )
-      PrintS("LS: NULL\n");
-    else
-    {
-      PrintS("LS: "); dPrint(LS, r, r, 2);
-    }
-  }
-
-
+  long debug = __DEBUG__;
+  const BOOLEAN __SYZCHECK__ = (BOOLEAN)((long)(atGet(currRingHdl,"SYZCHECK",INT_CMD, (void*)debug)));   
+  
   if (__SYZCHECK__ && syzterm != NULL)
   {
@@ -1206,8 +1135,5 @@
     p_Delete(&lm, r);    
   }
-
-  
-  res->rtyp = VECTOR_CMD;
-
+  
   // looking for an appropriate diviser q = L[k]...
   for( int k = IDELEMS(L)-1; k>= 0; k-- )
@@ -1235,5 +1161,5 @@
           dPrint(syzterm, r, r, 1);
         }    
-        
+
         p_LmFree(q, r);
         continue;
@@ -1244,5 +1170,5 @@
     {
       BOOLEAN ok = TRUE;
-      
+
       for(int kk = IDELEMS(LS)-1; kk>= 0; kk-- )
       {
@@ -1251,4 +1177,5 @@
         if( p_LmDivisibleBy(pp, q, r) )
         {
+          
           if( __DEBUG__ )
           {
@@ -1261,5 +1188,5 @@
         }
       }
-      
+
       if(!ok)
       {
@@ -1270,19 +1197,577 @@
 
     p_SetCoeff0(q, n_Neg( n_Div( p_GetCoeff(product, r), p_GetCoeff(p, r), r), r), r);
-
-    if( __DEBUG__ )
-    {
-      PrintS("FindReducer::Output: \n");
-      dPrint(q, r, r, 1);
+    return q;
+
+  }
+
+  
+  return NULL;
+}
+
+
+/// TODO: save shortcut (syz: |-.->) LM(LM(m) * "t") -> syz?
+/// proc SSFindReducer(def product, def syzterm, def L, def T, list #)
+static BOOLEAN FindReducer(leftv res, leftv h)
+{
+  const char* usage = "`FindReducer(<poly/vector>, <vector/0>, <ideal/module>[,<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
+
+  const BOOLEAN __TAILREDSYZ__ = (BOOLEAN)((long)(atGet(currRingHdl,"TAILREDSYZ",INT_CMD, (void*)0)));
+
+  if ((h==NULL) || (h->Typ()!=VECTOR_CMD && h->Typ() !=POLY_CMD) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;    
+  }
+    
+  const poly product = (poly) h->Data(); assume (product != NULL);
+
+
+  h = h->Next();
+  if ((h==NULL) || !((h->Typ()==VECTOR_CMD) || (h->Data() == NULL)) )
+  {
+    WerrorS(usage);
+    return TRUE;    
+  }
+
+  poly syzterm = NULL;
+
+  if(h->Typ()==VECTOR_CMD) 
+    syzterm = (poly) h->Data();
+
+
+
+  h = h->Next();
+  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;    
+  }
+  
+  const ideal L = (ideal) h->Data(); h = h->Next();
+
+  assume( IDELEMS(L) > 0 );
+
+  ideal LS = NULL;
+
+  if ((h != NULL) && (h->Typ() ==MODUL_CMD) && (h->Data() != NULL))
+  {
+    LS = (ideal)h->Data();
+    h = h->Next();
+  }
+
+  if( __TAILREDSYZ__ )
+    assume (LS != NULL);
+
+  assume( h == NULL );
+
+  if( __DEBUG__ )
+  {
+    PrintS("FindReducer(product, syzterm, L, T, #)::Input: \n");
+
+    PrintS("product: "); dPrint(product, r, r, 2);
+    PrintS("syzterm: "); dPrint(syzterm, r, r, 2);
+    PrintS("L: "); dPrint(L, r, r, 0);
+//    PrintS("T: "); dPrint(T, r, r, 4);
+
+    if( LS == NULL )
+      PrintS("LS: NULL\n");
+    else
+    {
+      PrintS("LS: "); dPrint(LS, r, r, 0);
+    }
+  }
+
+  res->rtyp = VECTOR_CMD;
+  res->data = FindReducer(product, syzterm, L, LS, r);
+
+  if( __DEBUG__ )
+  {
+    PrintS("FindReducer::Output: \n");
+    dPrint((poly)res->data, r, r, 2);
+  }    
+  
+  return FALSE;   
+  
+}
+
+static poly ReduceTerm(poly multiplier, poly term4reduction, poly syztermCheck,
+                       ideal L, ideal T, ideal LS, const ring r);
+
+static poly TraverseTail(poly multiplier, poly tail, 
+                         ideal L, ideal T, ideal LS,
+                         const ring r)
+{
+  assume( multiplier != NULL );
+
+  assume( L != NULL );
+  assume( T != NULL );
+
+  poly s = NULL;
+
+  // iterate over the tail
+  for(poly p = tail; p != NULL; p = pNext(p))
+    s = p_Add_q(s, ReduceTerm(multiplier, p, NULL, L, T, LS, r), r);  
+    
+  return s;
+}
+
+
+static poly ReduceTerm(poly multiplier, poly term4reduction, poly syztermCheck,
+                       ideal L, ideal T, ideal LS, const ring r)
+{
+  assume( multiplier != NULL );
+  assume( term4reduction != NULL );
+
+
+  assume( L != NULL );
+  assume( T != NULL );
+  
+  // assume(r == currRing); // ?
+
+  // simple implementation with FindReducer:
+  poly s = NULL;
+  
+  if(1)
+  {
+    // NOTE: only LT(term4reduction) should be used in the following:
+    poly product = pp_Mult_mm(multiplier, term4reduction, r);
+    s = FindReducer(product, syztermCheck, L, LS, r);
+    p_Delete(&product, r);
+  }
+
+  if( s == NULL ) // No Reducer?
+    return s;
+
+  poly b = leadmonom(s, r);
+
+  const int c = p_GetComp(s, r) - 1;
+  assume( c >= 0 && c < IDELEMS(T) );
+
+  const poly tail = T->m[c];
+
+  if( tail != NULL )
+    s = p_Add_q(s, TraverseTail(b, tail, L, T, LS, r), r);  
+  
+  return s;
+}
+
+
+static poly SchreyerSyzygyNF(poly syz_lead, poly syz_2, ideal L, ideal T, ideal LS, const ring r)
+{
+  assume( syz_lead != NULL );
+  assume( syz_2 != NULL );
+
+  assume( L != NULL );
+  assume( T != NULL );
+
+  assume( IDELEMS(L) == IDELEMS(T) );
+
+  int  c = p_GetComp(syz_lead, r) - 1;
+
+  assume( c >= 0 && c < IDELEMS(T) );
+
+  poly p = leadmonom(syz_lead, r); // :(  
+  poly spoly = pp_Mult_qq(p, T->m[c], r);
+  p_Delete(&p, r);
+
+  
+  c = p_GetComp(syz_2, r) - 1;
+  assume( c >= 0 && c < IDELEMS(T) );
+
+  p = leadmonom(syz_2, r); // :(
+  spoly = p_Add_q(spoly, pp_Mult_qq(p, T->m[c], r), r);
+  p_Delete(&p, r);
+
+  poly tail = p_Copy(syz_2, r); // TODO: use bucket!?
+
+  while (spoly != NULL)
+  {
+    poly t = FindReducer(spoly, NULL, L, LS, r);
+
+    p_LmDelete(&spoly, r);
+    
+    if( t != NULL )
+    {
+      p = leadmonom(t, r); // :(
+      c = p_GetComp(t, r) - 1;
+
+      assume( c >= 0 && c < IDELEMS(T) );
+      
+      spoly = p_Add_q(spoly, pp_Mult_qq(p, T->m[c], r), r);
+
+      p_Delete(&p, r);
+      
+      tail = p_Add_q(tail, t, r);
     }    
-
-    res->data = q;
-    return FALSE;
-  }
-
-  res->data = NULL;
-  return FALSE;   
-  
-}
+  }
+  
+  return tail;
+}
+
+// proc SchreyerSyzygyNF(vector syz_lead, vector syz_2, def L, def T, list #)
+static BOOLEAN SchreyerSyzygyNF(leftv res, leftv h)
+{
+  const char* usage = "`SchreyerSyzygyNF(<vector>, <vector>, <ideal/module>, <ideal/module>[,<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
+
+  const BOOLEAN __TAILREDSYZ__ = (BOOLEAN)((long)(atGet(currRingHdl,"TAILREDSYZ",INT_CMD, (void*)0)));
+//  const BOOLEAN __LEAD2SYZ__ = (BOOLEAN)((long)(atGet(currRingHdl,"LEAD2SYZ",INT_CMD, (void*)0)));
+  const BOOLEAN __SYZCHECK__ = (BOOLEAN)((long)(atGet(currRingHdl,"SYZCHECK",INT_CMD, (void*)0)));   
+
+  if ((h==NULL) || (h->Typ() != VECTOR_CMD) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;    
+  }
+
+  const poly syz_lead = (poly) h->Data(); assume (syz_lead != NULL);
+
+
+  h = h->Next();
+  if ((h==NULL) || (h->Typ() != VECTOR_CMD) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;    
+  }
+
+  const poly syz_2 = (poly) h->Data(); assume (syz_2 != NULL);
+
+  h = h->Next();
+  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) );
+
+  ideal LS = NULL;
+
+  h = h->Next();
+  if ((h != NULL) && (h->Typ() ==MODUL_CMD) && (h->Data() != NULL))
+  {
+    LS = (ideal)h->Data();
+    h = h->Next();
+  }
+
+  if( __TAILREDSYZ__ )
+    assume (LS != NULL);
+
+  assume( h == NULL );
+
+  if( __DEBUG__ )
+  {
+    PrintS("SchreyerSyzygyNF(syz_lead, syz_2, L, T, #)::Input: \n");
+
+    PrintS("syz_lead: "); dPrint(syz_lead, r, r, 2);
+    PrintS("syz_2: "); dPrint(syz_2, r, r, 2);
+
+    PrintS("L: "); dPrint(L, r, r, 0);
+    PrintS("T: "); dPrint(T, r, r, 0);
+
+    if( LS == NULL )
+      PrintS("LS: NULL\n");
+    else
+    {
+      PrintS("LS: "); dPrint(LS, r, r, 0);
+    }
+  }
+  
+  res->rtyp = VECTOR_CMD;
+  res->data = SchreyerSyzygyNF(syz_lead, syz_2, L, T, LS, r);
+
+  if( __DEBUG__ )
+  {
+    PrintS("SchreyerSyzygyNF::Output: ");
+
+    dPrint((poly)res->data, r, r, 2);
+  }
+
+
+  return FALSE;
+}
+
+
+
+/// TODO: save shortcut (syz: |-.->) LM(m) * "t" -> ?
+/// proc SSReduceTerm(poly m, def t, def syzterm, def L, def T, list #)
+static BOOLEAN ReduceTerm(leftv res, leftv h)
+{
+  const char* usage = "`ReduceTerm(<poly>, <poly/vector>, <vector/0>, <ideal/module>, <ideal/module>[,<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
+
+  const BOOLEAN __TAILREDSYZ__ = (BOOLEAN)((long)(atGet(currRingHdl,"TAILREDSYZ",INT_CMD, (void*)0)));
+//  const BOOLEAN __LEAD2SYZ__ = (BOOLEAN)((long)(atGet(currRingHdl,"LEAD2SYZ",INT_CMD, (void*)0)));
+  const BOOLEAN __SYZCHECK__ = (BOOLEAN)((long)(atGet(currRingHdl,"SYZCHECK",INT_CMD, (void*)0)));   
+
+  if ((h==NULL) || (h->Typ() !=POLY_CMD) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;    
+  }
+
+  const poly multiplier = (poly) h->Data(); assume (multiplier != NULL);
+
+  
+  h = h->Next();
+  if ((h==NULL) || (h->Typ()!=VECTOR_CMD && h->Typ() !=POLY_CMD) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;    
+  }
+
+  const poly term4reduction = (poly) h->Data(); assume( term4reduction != NULL );
+
+  
+  poly syztermCheck = NULL;
+  
+  h = h->Next();
+  if ((h==NULL) || !((h->Typ()==VECTOR_CMD) || (h->Data() == NULL)) )
+  {
+    WerrorS(usage);
+    return TRUE;    
+  }
+
+  if(h->Typ()==VECTOR_CMD) 
+    syztermCheck = (poly) h->Data();
+
+  
+  h = h->Next();
+  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) );
+
+  ideal LS = NULL;
+
+  h = h->Next();
+  if ((h != NULL) && (h->Typ() ==MODUL_CMD) && (h->Data() != NULL))
+  {
+    LS = (ideal)h->Data();
+    h = h->Next();
+  }
+
+  if( __TAILREDSYZ__ )
+    assume (LS != NULL);
+
+  assume( h == NULL );
+
+  if( __DEBUG__ )
+  {
+    PrintS("ReduceTerm(m, t, syzterm, L, T, #)::Input: \n");
+
+    PrintS("m: "); dPrint(multiplier, r, r, 2);
+    PrintS("t: "); dPrint(term4reduction, r, r, 2);
+    PrintS("syzterm: "); dPrint(syztermCheck, r, r, 2);
+    
+    PrintS("L: "); dPrint(L, r, r, 0);
+    PrintS("T: "); dPrint(T, r, r, 0);
+
+    if( LS == NULL )
+      PrintS("LS: NULL\n");
+    else
+    {
+      PrintS("LS: "); dPrint(LS, r, r, 0);
+    }
+  }
+
+
+  if (__SYZCHECK__ && syztermCheck != NULL)
+  {
+    const int c = p_GetComp(syztermCheck, r) - 1;
+    assume( c >= 0 && c < IDELEMS(L) );
+    
+    const poly p = L->m[c];
+    assume( p != NULL ); assume( pNext(p) == NULL );    
+
+    assume( p_EqualPolys(term4reduction, p, r) ); // assume? TODO
+
+
+    poly m = leadmonom(syztermCheck, r);
+    assume( m != NULL ); assume( pNext(m) == NULL );
+
+    assume( p_EqualPolys(multiplier, m, r) ); // assume? TODO
+
+    p_Delete(&m, r);    
+    
+// NOTE:   leadmonomial(syzterm) == m &&  L[leadcomp(syzterm)] == t
+  }
+
+  res->rtyp = VECTOR_CMD;
+  res->data = ReduceTerm(multiplier, term4reduction, syztermCheck, L, T, LS, r);
+
+
+  if( __DEBUG__ )
+  {
+    PrintS("ReduceTerm::Output: ");
+
+    dPrint((poly)res->data, r, r, 2);
+  }
+  
+  
+  return FALSE;
+}
+
+
+
+
+// TODO: store m * @tail -.-^-.-^-.--> ?
+// proc SSTraverseTail(poly m, def @tail, def L, def T, list #)
+static BOOLEAN TraverseTail(leftv res, leftv h)
+{
+  const char* usage = "`TraverseTail(<poly>, <poly/vector>, <ideal/module>, <ideal/module>[,<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
+
+  const BOOLEAN __TAILREDSYZ__ = (BOOLEAN)((long)(atGet(currRingHdl,"TAILREDSYZ",INT_CMD, (void*)1)));
+
+  if ((h==NULL) || (h->Typ() !=POLY_CMD) || (h->Data() == NULL))
+  {
+    WerrorS(usage);
+    return TRUE;    
+  }
+
+  const poly multiplier = (poly) h->Data(); assume (multiplier != NULL);
+
+  h = h->Next();
+  if ((h==NULL) || (h->Typ()!=VECTOR_CMD && h->Typ() !=POLY_CMD))
+  {
+    WerrorS(usage);
+    return TRUE;    
+  }
+
+  const poly tail = (poly) h->Data(); 
+
+  h = h->Next();
+
+  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();
+  
+  ideal LS = NULL;
+
+  if ((h != NULL) && (h->Typ() ==MODUL_CMD) && (h->Data() != NULL))
+  {
+    LS = (ideal)h->Data();
+    h = h->Next();
+  }
+
+  if( __TAILREDSYZ__ )
+    assume (LS != NULL);
+
+  assume( h == NULL );
+
+  if( __DEBUG__ )
+  {
+    PrintS("TraverseTail(m, t, L, T, #)::Input: \n");
+
+    PrintS("m: "); dPrint(multiplier, r, r, 2);
+    PrintS("t: "); dPrint(tail, r, r, 10);
+
+    PrintS("L: "); dPrint(L, r, r, 0);
+    PrintS("T: "); dPrint(T, r, r, 0);
+
+    if( LS == NULL )
+      PrintS("LS: NULL\n");
+    else
+    {
+      PrintS("LS: "); dPrint(LS, r, r, 0);
+    }
+  }
+
+  res->rtyp = VECTOR_CMD;
+  res->data = TraverseTail(multiplier, tail, L, T, LS, r);
+
+
+  if( __DEBUG__ )
+  {
+    PrintS("TraverseTail::Output: ");
+    dPrint((poly)res->data, r, r, 2);
+  }
+
+  return FALSE;
+}
+
+
+
 
 
@@ -1921,5 +2406,11 @@
   ADD(psModulFunctions, currPack->libname, "Sort_c_ds", FALSE, Sort_c_ds);
   ADD(psModulFunctions, currPack->libname, "FindReducer", FALSE, FindReducer);
-  
+
+
+  ADD(psModulFunctions, currPack->libname, "ReduceTerm", FALSE, ReduceTerm);
+  ADD(psModulFunctions, currPack->libname, "TraverseTail", FALSE, TraverseTail);
+
+    
+  ADD(psModulFunctions, currPack->libname, "SchreyerSyzygyNF", FALSE, SchreyerSyzygyNF);
   
   //  ADD(psModulFunctions, currPack->libname, "GetAMData", FALSE, GetAMData);
