Index: kernel/gr_kstd2.cc
===================================================================
--- kernel/gr_kstd2.cc	(revision 1cc61e18c0d6c70b177099c23a52159afb280bb4)
+++ kernel/gr_kstd2.cc	(revision 86016dc267659b0c4d7155a4accd5fb595c04de7)
@@ -2,5 +2,5 @@
 *  Computer Algebra System SINGULAR     *
 ****************************************/
-/* $Id: gr_kstd2.cc,v 1.10 2007-01-11 10:10:37 Singular Exp $ */
+/* $Id: gr_kstd2.cc,v 1.11 2007-01-31 23:51:23 motsak Exp $ */
 /*
 *  ABSTRACT -  Kernel: noncomm. alg. of Buchberger
@@ -11,4 +11,5 @@
 #ifdef HAVE_PLURAL
 
+#define PLURAL_INTERNAL_DECLARATIONS
 
 #include "omalloc.h"
@@ -750,5 +751,5 @@
 #endif
 
-void gr_initBba(ideal F, kStrategy strat)
+void nc_gr_initBba(ideal F, kStrategy strat)
 {
   assume(rIsPluralRing(currRing));
@@ -826,5 +827,5 @@
   // initHilbCrit(F,Q,&hilb,strat);
   /* in plural we don't need Hilb yet */
-  gr_initBba(F,strat);
+  nc_gr_initBba(F,strat);
   initBuchMoraPos(strat);
   /*set enterS, spSpolyShort, reduce, red, initEcart, initEcartPair*/
@@ -861,5 +862,5 @@
       pLmFree(strat->P.p);
       /* the real one */
-      if ((currRing->nc->type==nc_lie) && pHasNotCF(strat->P.p1,strat->P.p2)) /* prod crit */
+      if ((ncRingType(currRing)==nc_lie) && pHasNotCF(strat->P.p1,strat->P.p2)) /* prod crit */
       {
         strat->cp++;
@@ -922,5 +923,5 @@
               strat->enterS(strat->P,pos,strat,-1);
             }
-            if (hilb!=NULL) khCheck(Q,w,hilb,hilbeledeg,hilbcount,strat);
+//            if (hilb!=NULL) khCheck(Q,w,hilb,hilbeledeg,hilbcount,strat);
           }
           if (strat->P.lcm!=NULL) pLmFree(strat->P.lcm);
@@ -933,6 +934,16 @@
   }
   if (TEST_OPT_DEBUG) messageSets(strat);
+
   /* complete reduction of the standard basis--------- */
-  if (TEST_OPT_REDSB) completeReduce(strat);
+  if (TEST_OPT_REDSB){
+     completeReduce(strat); // ???
+
+//    ideal I = strat->Shdl;
+//    ideal erg = kInterRed(I,Q);
+//    assume(I!=erg);
+//    id_Delete(&I, currRing);
+//    strat->Shdl = erg;
+  }
+
   /* release temp data-------------------------------- */
   exitBuchMora(strat);
@@ -949,4 +960,6 @@
   if (TEST_OPT_PROT) messageStat(srmax,lrmax,hilbcount,strat);
   if (Q!=NULL) updateResult(strat->Shdl,Q,strat);
+
+
 #ifdef PDEBUG
 /* for counting number of pairs [enterL] in Plural */
Index: kernel/gring.cc
===================================================================
--- kernel/gring.cc	(revision 1cc61e18c0d6c70b177099c23a52159afb280bb4)
+++ kernel/gring.cc	(revision 86016dc267659b0c4d7155a4accd5fb595c04de7)
@@ -7,7 +7,8 @@
  *  Author:  levandov (Viktor Levandovsky)
  *  Created: 8/00 - 11/00
- *  Version: $Id: gring.cc,v 1.38 2007-01-25 19:42:26 motsak Exp $
+ *  Version: $Id: gring.cc,v 1.39 2007-01-31 23:51:23 motsak Exp $
  *******************************************************************/
 #include "mod2.h"
+
 #ifdef HAVE_PLURAL
 #define PLURAL_INTERNAL_DECLARATIONS
@@ -26,4 +27,5 @@
 
 #include "gring.h"
+#include "sca.h"
 
 // dirty tricks:
@@ -36,5 +38,53 @@
 
 
-
+// some forward declarations:
+
+
+// polynomial multiplication functions for p_Procs : 
+poly gnc_pp_Mult_mm(const poly p, const poly m, const ring r, poly &last);
+poly gnc_p_Mult_mm(poly p, const poly m, const ring r);
+poly gnc_mm_Mult_p(const poly m, poly p, const ring r);
+poly gnc_mm_Mult_pp(const poly m, const poly p, const ring r);
+
+
+// set pProcs for r and global variable p_Procs as for general non-commutative algebras.
+void gnc_p_ProcsSet(ring rGR, p_Procs_s* p_Procs);
+
+/* syzygies : */
+poly gnc_CreateSpolyOld(const poly p1, const poly p2/*, poly spNoether*/, const ring r);
+poly gnc_ReduceSpolyOld(const poly p1, poly p2/*, poly spNoether*/, const ring r);
+
+poly gnc_CreateSpolyNew(const poly p1, const poly p2/*, poly spNoether*/, const ring r);
+poly gnc_ReduceSpolyNew(const poly p1, poly p2/*, poly spNoether*/, const ring r);
+
+
+
+void gnc_kBucketPolyRedNew(kBucket_pt b, poly p, number *c);
+void gnc_kBucketPolyRed_ZNew(kBucket_pt b, poly p, number *c);
+
+void gnc_kBucketPolyRedOld(kBucket_pt b, poly p, number *c);
+void gnc_kBucketPolyRed_ZOld(kBucket_pt b, poly p, number *c);
+
+
+// poly gnc_ReduceSpolyNew(poly p1, poly p2, poly spNoether, const ring r);
+// void gnc_ReduceSpolyTail(poly p1, poly q, poly q2, poly spNoether, const ring r);
+
+// void nc_kBucketPolyRed(kBucket_pt b, poly p); 
+
+ideal gnc_gr_mora(const ideal, const ideal, const intvec *, const intvec *, kStrategy); // Not yet!
+ideal gnc_gr_bba (const ideal F, const ideal Q, const intvec *, const intvec *, kStrategy strat);
+
+
+#if 0
+// deprecated functions:
+//  poly gnc_p_Minus_mm_Mult_qq_ign(poly p, const poly m, poly q, int & d1, poly d2, const ring ri, poly &d3);
+//  poly gnc_p_Minus_mm_Mult_qq(poly p, const poly m, poly q, const ring r);
+//  poly nc_p_Minus_mm_Mult_qq(poly p, const poly m, const poly q, int &lp, int lq, const ring r);
+//  poly nc_p_Plus_mm_Mult_qq (poly p, const poly m, const poly q, int &lp, int lq, const ring r);
+#endif
+
+
+
+///////////////////////////////////////////////////////////////////////////////
 poly nc_p_Minus_mm_Mult_qq(poly p, const poly m, const poly q, int &lp,
                                     const int, const poly, const ring r)
@@ -325,5 +375,5 @@
   int cpower=0;
 
-  if (r->nc->type==nc_skew)
+  if (ncRingType(r)==nc_skew)
   {
     if (r->nc->IsSkewConstant==1)
@@ -1130,5 +1180,5 @@
 #endif
   /* pSetComp(m,r)=0? */
-  poly   N  = mm_Mult_p(m, p_Head(p1,r), r);
+  poly   N  = nc_mm_Mult_p(m, p_Head(p1,r), r);
   number C  = n_Copy( p_GetCoeff(N,  r), r);
   number cF = n_Copy( p_GetCoeff(p2, r),r);
@@ -1184,5 +1234,5 @@
 
   /* pSetComp(m,r)=0? */
-  poly   N  = mm_Mult_p(m, p_Head(p1,r), r);
+  poly   N  = nc_mm_Mult_p(m, p_Head(p1,r), r);
 
   number C  = n_Copy( p_GetCoeff(N,  r), r);
@@ -1238,5 +1288,5 @@
     return(NULL);
   }
-  if ((r->nc->type==nc_lie) && pHasNotCF(p1,p2)) /* prod crit */
+  if ((ncRingType(r)==nc_lie) && pHasNotCF(p1,p2)) /* prod crit */
   {
     return(nc_p_Bracket_qq(pCopy(p2),p1));
@@ -1264,7 +1314,7 @@
   p_Delete(&pL,r);
   /* zero exponents ! */
-  poly M1    = mm_Mult_p(m1,p_Head(p1,r),r);
+  poly M1    = nc_mm_Mult_p(m1,p_Head(p1,r),r);
   number C1  = n_Copy(p_GetCoeff(M1,r),r);
-  poly M2    = mm_Mult_p(m2,p_Head(p2,r),r);
+  poly M2    = nc_mm_Mult_p(m2,p_Head(p2,r),r);
   number C2  = n_Copy(p_GetCoeff(M2,r),r);
   /* GCD stuff */
@@ -1292,9 +1342,9 @@
   poly tmp=p_Copy(p1,r);
   tmp=p_LmDeleteAndNext(tmp,r);
-  M1=mm_Mult_p(m1,tmp,r);
+  M1=nc_mm_Mult_p(m1,tmp,r);
   tmp=p_Copy(p2,r);
   tmp=p_LmDeleteAndNext(tmp,r);
   M2=p_Add_q(M2,M1,r);
-  M1=mm_Mult_p(m2,tmp,r);
+  M1=nc_mm_Mult_p(m2,tmp,r);
   M2=p_Add_q(M2,M1,r);
   p_Delete(&m1,r);
@@ -1360,6 +1410,6 @@
 
   /* zero exponents !? */
-  poly M1    = mm_Mult_p(m1,p_Head(p1,r),r); // M1 = m1 * lt(p1)
-  poly M2    = mm_Mult_p(m2,p_Head(p2,r),r); // M2 = m2 * lt(p2)
+  poly M1    = nc_mm_Mult_p(m1,p_Head(p1,r),r); // M1 = m1 * lt(p1)
+  poly M2    = nc_mm_Mult_p(m2,p_Head(p2,r),r); // M2 = m2 * lt(p2)
 
   if(M1 == NULL || M2 == NULL)
@@ -1419,9 +1469,9 @@
   poly tmp=p_Copy(p1,r);                         // tmp = p1
   tmp=p_LmDeleteAndNext(tmp,r);                  // tmp = tail(p1)
-  M1 = mm_Mult_p(m1,tmp,r);                      // M1 = m1 * tail(p1), delete tmp
+  M1 = nc_mm_Mult_p(m1,tmp,r);                      // M1 = m1 * tail(p1), delete tmp
   tmp=p_Copy(p2,r);                              // tmp = p2
   tmp=p_LmDeleteAndNext(tmp,r);                  // tmp = tail(p2)
   M2=p_Add_q(M2,M1,r);                           // M2 = spoly(lt(p1), lt(p2)) + m1 * tail(p1), delete M1
-  M1 = mm_Mult_p(m2,tmp,r);                      // M1 = m2 * tail(p2), detele tmp
+  M1 = nc_mm_Mult_p(m2,tmp,r);                      // M1 = m2 * tail(p2), detele tmp
   M2=p_Add_q(M2,M1,r);                           // M2 = spoly(lt(p1), lt(p2)) + m1 * tail(p1) + m2*tail(p2)
                                                  // delete M1
@@ -1464,5 +1514,5 @@
   poly M = nc_mm_Mult_pp(m, p1,r);
   number C=p_GetCoeff(M,r);
-  M=p_Add_q(M,mm_Mult_p(m,p_LmDeleteAndNext(p_Copy(p1,r),r),r),r); // _pp?
+  M=p_Add_q(M,nc_mm_Mult_p(m,p_LmDeleteAndNext(p_Copy(p1,r),r),r),r); // _pp?
   q=p_Mult_nn(q,C,r);
   number MinusOne=n_Init(-1,r);
@@ -2043,5 +2093,5 @@
       for(j=i+1;j<=rN;j++)
       {
-    id_Delete((ideal *)&(r->nc->MT[UPMATELEM(i,j,rN)]),r->nc->basering);
+        id_Delete((ideal *)&(r->nc->MT[UPMATELEM(i,j,rN)]),r->nc->basering);
       }
     }
@@ -2052,11 +2102,18 @@
   id_Delete((ideal *)&(r->nc->C),r->nc->basering);
   id_Delete((ideal *)&(r->nc->D),r->nc->basering);
+  
+  if( rIsSCA(r) && (r->nc->SCAQuotient() != NULL) )
+  {
+    id_Delete(&r->nc->SCAQuotient(), r->nc->basering);    
+  }
+
   r->nc->basering->ref--;
-  if (r->nc->basering<=0)
+  
+  if (r->nc->basering->ref<=0)
   {
     rKill(r->nc->basering);
   }
-  omFreeSize((ADDRESS)r->nc,sizeof(nc_struct));
-  r->nc=NULL;
+  
+  ncCleanUp(r);
 }
 
@@ -2254,5 +2311,5 @@
   r->nc->basering = r;
   r->ref++;
-  r->nc->type = nc_undef;
+  ncRingType(r, nc_undef);
 
   /* initialition of the matrix C */
@@ -2313,9 +2370,9 @@
     if (nIsOne(nN))
     {
-      r->nc->type = nc_lie;
+      ncRingType(r, nc_lie);
     }
     else
     {
-      r->nc->type = nc_general;
+      ncRingType(r, nc_general);
     }
     r->nc->IsSkewConstant = 1;
@@ -2361,9 +2418,9 @@
     if ( (tmpIsSkewConstant) && (nIsOne(pN)) )
     {
-      r->nc->type = nc_lie;
+      ncRingType(r, nc_lie);
     }
     else
     {
-      r->nc->type = nc_general;
+      ncRingType(r, nc_general);
     }
   }
@@ -2376,11 +2433,11 @@
     if (DN  == NULL)
     {
-      if ( (r->nc->type == nc_lie) || (r->nc->type == nc_undef) )
-      {
-    r->nc->type = nc_comm; /* it was nc_skew earlier */
+      if ( (ncRingType(r) == nc_lie) || (ncRingType(r) == nc_undef) )
+      {
+        ncRingType(r, nc_comm); /* it was nc_skew earlier */
       }
       else /* nc_general, nc_skew */
       {
-    r->nc->type = nc_skew;
+        ncRingType(r, nc_skew);
       }
     }
@@ -2418,4 +2475,5 @@
 }
 
+//////////////////////////////////////////////////////////////////////////////
 BOOLEAN nc_InitMultiplication(ring r)
 {
@@ -2426,5 +2484,5 @@
   if (rVar(r)==1)
   {
-    r->nc->type=nc_comm;
+    ncRingType(r, nc_comm);
     r->nc->IsSkewConstant=1;
     return FALSE;
@@ -2483,5 +2541,5 @@
     }
   }
-  if (r->nc->type==nc_undef)
+  if (ncRingType(r)==nc_undef)
   {
     if (IsNonComm==1)
@@ -2493,5 +2551,5 @@
     if (IsNonComm==0)
     {
-      r->nc->type=nc_skew; /* TODO: check whether it is commutative */
+      ncRingType(r, nc_skew); /* TODO: check whether it is commutative */
       r->nc->IsSkewConstant=tmpIsSkewConstant;
     }
@@ -2499,6 +2557,5 @@
   r->nc->COM=COM;
 
-  SetProcsGNC(r, r->p_Procs);
-
+  gnc_p_ProcsSet(r, r->p_Procs);
 
   if (WeChangeRing)
@@ -2509,7 +2566,6 @@
 }
 
-void SetProcsGNC(ring& rGR, p_Procs_s* p_Procs)
-{
-
+void gnc_p_ProcsSet(ring rGR, p_Procs_s* p_Procs)
+{
   // "commutative"
   rGR->p_Procs->p_Mult_mm  = gnc_p_Mult_mm;
@@ -2522,5 +2578,5 @@
 
 
-  // non-commutaitve
+  // non-commutaitve multiplication by monomial from the left
   rGR->nc->p_Procs.mm_Mult_p   = gnc_mm_Mult_p;
   rGR->nc->p_Procs.mm_Mult_pp  = gnc_mm_Mult_pp;
@@ -2540,4 +2596,5 @@
   rGR->nc->p_Procs.BucketPolyRed_Z= gnc_kBucketPolyRed_ZOld;
 #else
+  // A bit cleaned up and somewhat rewritten functions...
   rGR->nc->p_Procs.SPoly       = gnc_CreateSpolyNew;
   rGR->nc->p_Procs.ReduceSPoly = gnc_ReduceSpolyNew;
@@ -2551,4 +2608,5 @@
 
 #if 0
+    // Old Stuff
     p_Procs->p_Mult_mm   = gnc_p_Mult_mm;
     _p_procs->p_Mult_mm  = gnc_p_Mult_mm;
@@ -2570,4 +2628,20 @@
 #endif
 }
+
+
+// set pProcs table for rGR and global variable p_Procs
+void nc_p_ProcsSet(ring rGR, p_Procs_s* p_Procs)
+{
+  assume(rIsPluralRing(rGR));
+  assume(p_Procs!=NULL);
+
+  gnc_p_ProcsSet(rGR, p_Procs);
+
+  if(rIsSCA(rGR))
+  {
+    sca_p_ProcsSet(rGR, p_Procs);
+  }
+}
+
 
 
@@ -2604,5 +2678,5 @@
       pSetExpV(pre,PRE);
       pSetm(pre);
-      res = mm_Mult_p(pre,res,currRing);
+      res = nc_mm_Mult_p(pre,res,currRing);
       /* multiply with suffix */
       suf = pOne();
@@ -2855,6 +2929,9 @@
   r->nc->ref = 1;
   r->nc->basering = r;
-  r->nc->type = nc_comm;
+  ncRingType(r, nc_comm);
   r->nc->IsSkewConstant = 1;
+  
+  // no reference increment to the base commutative ring???
+  
   matrix C = mpNew(r->N,r->N);
   matrix D = mpNew(r->N,r->N);
@@ -2996,4 +3073,13 @@
 }
 
+
+
+bool nc_SetupQuotient(ring rGR, const ring rG)
+{
+  // currently only super-commutative extension deals with factors. 
+  return sca_SetupQuotient(rGR, rG);
+}
+
+
 #endif
 
Index: kernel/gring.h
===================================================================
--- kernel/gring.h	(revision 1cc61e18c0d6c70b177099c23a52159afb280bb4)
+++ kernel/gring.h	(revision 86016dc267659b0c4d7155a4accd5fb595c04de7)
@@ -4,5 +4,5 @@
 *  Computer Algebra System SINGULAR     *
 ****************************************/
-/* $Id: gring.h,v 1.17 2007-01-11 11:27:25 Singular Exp $ */
+/* $Id: gring.h,v 1.18 2007-01-31 23:51:24 motsak Exp $ */
 /*
 * ABSTRACT additional defines etc for --with-plural
@@ -10,49 +10,40 @@
 
 #ifdef HAVE_PLURAL
-#include "structs.h"
-#include "ring.h"
+
+#include <structs.h>
+#include <ring.h>
 
 /* the part, related to the interface */
 BOOLEAN nc_CallPlural(matrix CC, matrix DD, poly CN, poly DN, ring r);
+
 BOOLEAN nc_CheckOrdCondition(matrix D, ring r);
 BOOLEAN nc_CheckSubalgebra(poly PolyVar, ring r);
-BOOLEAN nc_InitMultiplication(ring r);
+BOOLEAN nc_InitMultiplication(ring r); // should call nc_p_ProcsSet!
 BOOLEAN rIsLikeOpposite(ring rBase, ring rCandidate);
 
-// set pProcs for r and global variable p_Procs
-void SetProcsGNC(ring& rGR, p_Procs_s* p_Procs);
 
-ring nc_rCreateNCcomm(ring r);
-void ncKill(ring r);
-void ncCleanUp(ring r); /* smaller than kill */
+// set pProcs table for rGR and global variable p_Procs
+// this should be used by p_ProcsSet in p_Procs_Set.h
+void nc_p_ProcsSet(ring rGR, p_Procs_s* p_Procs);
 
-/* poly functions defined in p_Procs : */
-
-/* other routines we need in addition : */
-// poly gnc_p_Minus_mm_Mult_qq(poly p, const poly m, poly q, const ring r);
-
-// #define PLURAL_INTERNAL_DECLARATIONS
-
-#ifdef PLURAL_INTERNAL_DECLARATIONS
-// // poly gnc_p_Minus_mm_Mult_qq_ign(poly p, const poly m, poly q, int & d1, poly d2, const ring ri, poly &d3);
+// this function should be used inside QRing definition!
+// we go from rG into factor ring rGR with factor ideal rGR->qideal.
+bool nc_SetupQuotient(ring rGR, const ring rG);
 
 
-poly gnc_pp_Mult_mm(const poly p, const poly m, const ring r, poly &last);
-poly gnc_p_Mult_mm(poly p, const poly m, const ring r);
-poly gnc_mm_Mult_p(const poly m, poly p, const ring r);
-poly gnc_mm_Mult_pp(const poly m, const poly p, const ring r);
-#endif
+// used by "rSum" from ring.cc only! 
+// purpose init nc structure for initially commutative ring:
+// "creates a commutative nc extension; "converts" comm.ring to a Plural ring"
+ring nc_rCreateNCcomm(ring r); 
+
+void ncCleanUp(ring r); /* smaller than kill */
+void ncKill(ring r);
 
 
-
-// // for p_Minus_mm_Mult_qq in pInline2.h
-// poly nc_p_Minus_mm_Mult_qq(poly p, const poly m, const poly q, int &lp, int lq, const ring r);
-// // for p_Plus_mm_Mult_qq in pInline2.h
-// poly nc_p_Plus_mm_Mult_qq (poly p, const poly m, const poly q, int &lp, int lq, const ring r);
-
-
-//
+// for p_Minus_mm_Mult_qq in pInline2.h
 poly nc_p_Minus_mm_Mult_qq(poly p, const poly m, const poly q, int &lp,
                                     const int, const poly, const ring r);
+
+// // for p_Plus_mm_Mult_qq in pInline2.h
 // returns p + m*q destroys p, const: q, m
 poly nc_p_Plus_mm_Mult_qq(poly p, const poly m, const poly q, int &lp,
@@ -76,33 +67,4 @@
 void nc_PolyPolyRed(poly &b, poly p, number *c);
 poly nc_CreateShortSpoly(poly p1, poly p2, const ring r=currRing);
-
-
-#define PLURAL_INTERNAL_DECLARATIONS
-#ifdef PLURAL_INTERNAL_DECLARATIONS
-/* syzygies : */
-poly gnc_CreateSpolyOld(const poly p1, const poly p2/*, poly spNoether*/, const ring r);
-poly gnc_ReduceSpolyOld(const poly p1, poly p2/*, poly spNoether*/, const ring r);
-
-poly gnc_CreateSpolyNew(const poly p1, const poly p2/*, poly spNoether*/, const ring r);
-poly gnc_ReduceSpolyNew(const poly p1, poly p2/*, poly spNoether*/, const ring r);
-
-
-
-void gnc_kBucketPolyRedNew(kBucket_pt b, poly p, number *c);
-void gnc_kBucketPolyRed_ZNew(kBucket_pt b, poly p, number *c);
-
-void gnc_kBucketPolyRedOld(kBucket_pt b, poly p, number *c);
-void gnc_kBucketPolyRed_ZOld(kBucket_pt b, poly p, number *c);
-
-
-// poly gnc_ReduceSpolyNew(poly p1, poly p2, poly spNoether, const ring r);
-// void gnc_ReduceSpolyTail(poly p1, poly q, poly q2, poly spNoether, const ring r);
-
-/* void nc_kBucketPolyRed(kBucket_pt b, poly p); */
-void gr_initBba(ideal F,kStrategy strat);
-
-ideal gnc_gr_bba (const ideal F, const ideal Q, const intvec *, const intvec *, kStrategy strat);
-ideal gnc_gr_mora(const ideal, const ideal, const intvec *, const intvec *, kStrategy); // Not yet!
-#endif
 
 
@@ -159,5 +121,5 @@
 
 // returns m*p, does destroy p, preserves m
-inline poly mm_Mult_p(const poly m, poly p, const ring r)
+inline poly nc_mm_Mult_p(const poly m, poly p, const ring r)
 {
   assume(rIsPluralRing(r));
@@ -226,4 +188,12 @@
 #define UPMATELEM(i,j,nVar) ( (nVar * ((i)-1) - ((i) * ((i)-1))/2 + (j)-1)-(i) )
 
-#endif
-#endif
+
+#ifdef PLURAL_INTERNAL_DECLARATIONS
+
+// we need nc_gr_initBba for sca_gr_bba and gr_bba.
+void nc_gr_initBba(ideal F,kStrategy strat); 
+
+#endif // PLURAL_INTERNAL_DECLARATIONS
+
+#endif // HAVE_PLURAL :(
+#endif // 
Index: kernel/ideals.cc
===================================================================
--- kernel/ideals.cc	(revision 1cc61e18c0d6c70b177099c23a52159afb280bb4)
+++ kernel/ideals.cc	(revision 86016dc267659b0c4d7155a4accd5fb595c04de7)
@@ -2,5 +2,5 @@
 *  Computer Algebra System SINGULAR     *
 ****************************************/
-/* $Id: ideals.cc,v 1.37 2007-01-24 10:00:55 Singular Exp $ */
+/* $Id: ideals.cc,v 1.38 2007-01-31 23:51:24 motsak Exp $ */
 /*
 * ABSTRACT - all basic methods to manipulate ideals
@@ -2314,5 +2314,5 @@
     /* the subalgebra to be intersected with */
   {
-    if (currRing->nc->type!=nc_skew) /* in (quasi)-commutative algebras every subalgebra is admissible */
+    if (ncRingType(currRing)!=nc_skew) /* in (quasi)-commutative algebras every subalgebra is admissible */
     {
       if (nc_CheckSubalgebra(delVar,currRing))
Index: kernel/maps.cc
===================================================================
--- kernel/maps.cc	(revision 1cc61e18c0d6c70b177099c23a52159afb280bb4)
+++ kernel/maps.cc	(revision 86016dc267659b0c4d7155a4accd5fb595c04de7)
@@ -2,5 +2,5 @@
 *  Computer Algebra System SINGULAR     *
 ****************************************/
-/* $Id: maps.cc,v 1.5 2005-09-05 12:30:29 Singular Exp $ */
+/* $Id: maps.cc,v 1.6 2007-01-31 23:51:24 motsak Exp $ */
 /*
 * ABSTRACT - the mapping of polynomials to other rings
@@ -258,5 +258,5 @@
     omFreeSize(names, (currRing->N)*sizeof(char*)); names=NULL;
     memset(&tmpR,0,sizeof(tmpR));
-    if ((rIsPluralRing(sourcering)) && (sourcering->nc->type!=nc_comm)) 
+    if ((rIsPluralRing(sourcering)) && (ncRingType(sourcering)!=nc_comm)) 
     {
       Werror("Sorry, not yet implemented for noncomm. rings");
Index: kernel/pInline2.h
===================================================================
--- kernel/pInline2.h	(revision 1cc61e18c0d6c70b177099c23a52159afb280bb4)
+++ kernel/pInline2.h	(revision 86016dc267659b0c4d7155a4accd5fb595c04de7)
@@ -7,5 +7,5 @@
  *  Author:  obachman (Olaf Bachmann)
  *  Created: 8/00
- *  Version: $Id: pInline2.h,v 1.9 2007-01-11 11:27:25 Singular Exp $
+ *  Version: $Id: pInline2.h,v 1.10 2007-01-31 23:51:24 motsak Exp $
  *******************************************************************/
 #ifndef PINLINE2_H
@@ -596,5 +596,5 @@
 #ifdef HAVE_PLURAL
     if (rIsPluralRing(r))
-      q = mm_Mult_p(p, q, r);
+      q = nc_mm_Mult_p(p, q, r);
     else
 #endif /* HAVE_PLURAL */
Index: kernel/p_Procs_Set.h
===================================================================
--- kernel/p_Procs_Set.h	(revision 1cc61e18c0d6c70b177099c23a52159afb280bb4)
+++ kernel/p_Procs_Set.h	(revision 86016dc267659b0c4d7155a4accd5fb595c04de7)
@@ -12,9 +12,12 @@
  *  Author:  obachman (Olaf Bachmann)
  *  Created: 12/00
- *  Version: $Id: p_Procs_Set.h,v 1.11 2007-01-15 17:13:59 Singular Exp $
+ *  Version: $Id: p_Procs_Set.h,v 1.12 2007-01-31 23:51:24 motsak Exp $
  *******************************************************************/
 #include "modulop.h"
 
-#include "sca.h"
+#ifdef HAVE_PLURAL
+// for nc_p_ProcsSet:
+#include "gring.h"
+#endif
 
 
@@ -176,15 +179,8 @@
          r->OrdSgn == 1 || r->LexOrder);
 */
-  #ifdef HAVE_PLURAL
+#ifdef HAVE_PLURAL
   if (rIsPluralRing(r))
-  {
-    SetProcsGNC(r, _p_procs);
-
-    if(rIsSCA(r))
-    {
-      SetProcsSCA(r, _p_procs);
-    }
-  }
-  #endif
+    nc_p_ProcsSet(r, _p_procs); // Setup non-commutative p_Procs table!
+#endif
 }
 
Index: kernel/ring.cc
===================================================================
--- kernel/ring.cc	(revision 1cc61e18c0d6c70b177099c23a52159afb280bb4)
+++ kernel/ring.cc	(revision 86016dc267659b0c4d7155a4accd5fb595c04de7)
@@ -2,5 +2,5 @@
 *  Computer Algebra System SINGULAR     *
 ****************************************/
-/* $Id: ring.cc,v 1.55 2007-01-29 18:08:21 Singular Exp $ */
+/* $Id: ring.cc,v 1.56 2007-01-31 23:51:24 motsak Exp $ */
 
 /*
@@ -26,4 +26,5 @@
 #ifdef HAVE_PLURAL
 #include "gring.h"
+#include "sca.h"
 #endif
 #include "maps.h"
@@ -390,6 +391,21 @@
     else PrintS(" ...");
 #ifdef PDEBUG
-    Print("\n//   noncommutative type:%d",r->nc->type);
+    Print("\n//   noncommutative type:%d", (int)ncRingType(r));
     Print("\n//   is skew constant:%d",r->nc->IsSkewConstant);
+    if( rIsSCA(r) )
+    {
+      Print("\n//   alternating variables: [%d, %d]", scaFirstAltVar(r), scaLastAltVar(r));
+      const ideal Q = r->nc->SCAQuotient(); // resides within r!
+      if (Q!=NULL)
+      {
+        PrintS("\n//   quotient of sca by ideal");
+        if (r==currRing)
+        {
+          PrintLn();
+          iiWriteMatrix((matrix)Q,"__",1);
+        }
+        else PrintS(" ...");
+      }
+    }
     Print("\n//   ref:%d",r->nc->ref);
 #endif
@@ -1157,17 +1173,17 @@
     if ( !R2_is_nc ) nc_rCreateNCcomm(R2);
     /* nc->type's */
-    sum->nc->type = nc_undef;
-    nc_type t1 = R1->nc->type, t2 = R2->nc->type;
-    if ( t1==t2) sum->nc->type = t1;
+    ncRingType(sum, nc_undef);
+    nc_type t1 = ncRingType(R1), t2 = ncRingType(R2);
+    if ( t1==t2) ncRingType(sum, t1);
     else
     {
-      if ( (t1==nc_general) || (t2==nc_general) ) sum->nc->type = nc_general;
-    }
-    if (sum->nc->type == nc_undef) /* not yet done */
+      if ( (t1==nc_general) || (t2==nc_general) ) ncRingType(sum, nc_general);
+    }
+    if (ncRingType(sum) == nc_undef) /* not yet done */
     {
       switch (t1)
       {
         case nc_comm:
-          sum->nc->type = t2;
+          ncRingType(sum, t2);
           break;
         case nc_lie:
@@ -1175,7 +1191,7 @@
           {
             case nc_skew:
-              sum->nc->type = nc_general;  break;
+              ncRingType(sum, nc_general);  break;
             case nc_comm:
-              sum->nc->type = nc_lie;  break;
+              ncRingType(sum, nc_lie);  break;
             default:
               /*sum->nc->type = nc_undef;*/  break;
@@ -1186,7 +1202,7 @@
           {
             case nc_lie:
-              sum->nc->type = nc_lie;  break;
+              ncRingType(sum, nc_lie);  break;
             case nc_comm:
-              sum->nc->type = nc_skew;  break;
+              ncRingType(sum, nc_skew);  break;
             default:
               /*sum->nc->type = nc_undef;*/  break;
@@ -1197,5 +1213,5 @@
       }
     }
-    if (sum->nc->type == nc_undef)
+    if (ncRingType(sum) == nc_undef)
       WarnS("Error on recognizing nc types");
     /* multiplication matrices business: */
@@ -3950,5 +3966,5 @@
   r->nc->ref      = 1; /* in spite of rCopy(src)? */
   r->nc->basering = r;
-  r->nc->type     =  src->nc->type;
+  ncRingType(r, ncRingType(src));
   int *perm       = (int *)omAlloc0((rVar(r)+1)*sizeof(int));
   int *par_perm   = NULL;
Index: kernel/ring.h
===================================================================
--- kernel/ring.h	(revision 1cc61e18c0d6c70b177099c23a52159afb280bb4)
+++ kernel/ring.h	(revision 86016dc267659b0c4d7155a4accd5fb595c04de7)
@@ -7,5 +7,5 @@
 * ABSTRACT - the interpreter related ring operations
 */
-/* $Id: ring.h,v 1.16 2007-01-11 10:27:04 Singular Exp $ */
+/* $Id: ring.h,v 1.17 2007-01-31 23:51:25 motsak Exp $ */
 
 /* includes */
@@ -33,12 +33,13 @@
 ring   rEnvelope(ring r);
 
+// we must always have this test!
+inline bool rIsPluralRing(const ring r)
+{
 #ifdef HAVE_PLURAL
-inline BOOLEAN rIsPluralRing(ring r)
-{
-  return ((r != NULL) && (r->nc != NULL) && (r->nc->type != nc_error));
-}
-#else
-#define rIsPluralRing(R) 0
-#endif
+  return (r != NULL) && (r->nc != NULL) && (r->nc->type != nc_error); 
+#else
+  return false;
+#endif
+}
 
 
Index: kernel/sca.cc
===================================================================
--- kernel/sca.cc	(revision 1cc61e18c0d6c70b177099c23a52159afb280bb4)
+++ kernel/sca.cc	(revision 86016dc267659b0c4d7155a4accd5fb595c04de7)
@@ -7,5 +7,5 @@
  *  Author:  motsak (Oleksandr Motsak)
  *  Created: 2006/12/18
- *  Version: $Id: sca.cc,v 1.7 2007-01-25 16:36:50 Singular Exp $
+ *  Version: $Id: sca.cc,v 1.8 2007-01-31 23:51:25 motsak Exp $
  *******************************************************************/
 
@@ -43,6 +43,31 @@
 
 
-//   scaFirstAltVar( r, 0 );
-//   scaLastAltVar( r, 0 );
+// poly functions defined in p_Procs :
+
+// return pPoly * pMonom; preserve pPoly and pMonom.
+poly sca_pp_Mult_mm(const poly pPoly, const poly pMonom, const ring rRing, poly &);
+
+// return pMonom * pPoly; preserve pPoly and pMonom.
+poly sca_mm_Mult_pp(const poly pMonom, const poly pPoly, const ring rRing);
+
+// return pPoly * pMonom; preserve pMonom, destroy or reuse pPoly.
+poly sca_p_Mult_mm(poly pPoly, const poly pMonom, const ring rRing);
+
+// return pMonom * pPoly; preserve pMonom, destroy or reuse pPoly.
+poly sca_mm_Mult_p(const poly pMonom, poly pPoly, const ring rRing);
+
+
+// compute the spolynomial of p1 and p2
+poly sca_SPoly(const poly p1, const poly p2, const ring r);
+poly sca_ReduceSpoly(const poly p1, poly p2, const ring r);
+
+// Modified Plural's Buchberger's algorithmus.
+ideal sca_gr_bba(const ideal F, const ideal Q, const intvec *, const intvec *, kStrategy strat);
+
+// Modified modern Sinuglar Buchberger's algorithm.
+ideal sca_bba(const ideal F, const ideal Q, const intvec *w, const intvec *, kStrategy strat);
+
+// Modified modern Sinuglar Mora's algorithm.
+ideal sca_mora(const ideal F, const ideal Q, const intvec *w, const intvec *, kStrategy strat);
 
 
@@ -280,5 +305,5 @@
     assume( scaFirstAltVar(rRing) <= i );
 
-    if( p_GetExp(pMonom, i, rRing) ) // result is zero!
+    if( p_GetExp(pMonom, i, rRing) != 0 ) // => result is zero!
       return NULL;
 
@@ -939,5 +964,13 @@
   assume(rIsSCA(currRing));
 
-  BOOLEAN bIdHomog = id_IsYHomogeneous(F, currRing);
+  const unsigned int m_iFirstAltVar = scaFirstAltVar(currRing);
+  const unsigned int m_iLastAltVar  = scaLastAltVar(currRing);
+  
+  ideal tempF = id_KillSquares(F, m_iFirstAltVar, m_iLastAltVar, currRing);
+  const ideal tempQ = currRing->nc->SCAQuotient();
+
+  BOOLEAN bIdHomog = id_IsBiHomogeneous(tempF, m_iFirstAltVar, m_iLastAltVar, currRing);
+
+  assume( !bIdHomog || strat->homog ); //  bIdHomog =====[implies]>>>>> strat->homog
 
   strat->homog = strat->homog && bIdHomog;
@@ -952,8 +985,8 @@
   {
     Print("ideal F: \n");
-    for (int i = 0; i < F->idelems(); i++)
+    for (int i = 0; i < tempF->idelems(); i++)
     {
       Print("; F[%d] = ", i+1);
-      p_Write(F->m[i], currRing);
+      p_Write(tempF->m[i], currRing);
     }
     Print(";\n");
@@ -976,5 +1009,5 @@
   initBuchMoraCrit(strat); // set Gebauer, honey, sugarCrit
 
-  gr_initBba(F,strat); // set enterS, red, initEcart, initEcartPair
+  nc_gr_initBba(tempF,strat); // set enterS, red, initEcart, initEcartPair
 
   initBuchMoraPos(strat);
@@ -983,5 +1016,5 @@
   // ?? set spSpolyShort, reduce ???
 
-  initBuchMora(F, NULL, strat); // Q  = squares!!!!!!!
+  initBuchMora(tempF, tempQ, strat); // currRing->nc->SCAQuotient() instead of Q == squares!!!!!!!
 
   strat->posInT=posInT110; // !!!
@@ -989,10 +1022,4 @@
   srmax = strat->sl;
   reduc = olddeg = lrmax = 0;
-
-
-  const unsigned int m_iFirstAltVar = scaFirstAltVar(currRing);
-  const unsigned int m_iLastAltVar  = scaLastAltVar(currRing);
-
-
 
 
@@ -1061,20 +1088,22 @@
     if (strat->sl > srmax) srmax = strat->sl;
 
-    ////////////// children !!!!!!!!!!!!!
-
     const poly save = strat->P.p;
 
-//     if( save != NULL )
-    {
-
 #ifdef PDEBUG
       p_Test(save, currRing);
 #endif
-
+    assume( save != NULL );
+    
+    // SCA Specials:
+
+    {
       const poly pNext = pNext(save);
-
+      
+      if( pNext != NULL )
       for( unsigned int i = m_iFirstAltVar; i <= m_iLastAltVar; i++ )
-      if( pGetExp(save, i)!=0 )
+      if( p_GetExp(save, i, currRing) != 0 )
       {
+        assume(p_GetExp(save, i, currRing) == 1);
+        
         const poly tt = sca_pp_Mult_xi_pp(i, pNext, currRing);
 
@@ -1114,6 +1143,5 @@
 //         if(h.IsNull()) continue;
 
-
-  //       poly save = p_Copy(h.p, currRing);
+//         poly save = p_Copy(h.p, currRing);
 
         int pos;
@@ -1158,5 +1186,7 @@
   if (TEST_OPT_PROT) messageStat(srmax,lrmax,hilbcount,strat);
 
-//  if (Q!=NULL) updateResult(strat->Shdl,Q,strat);
+  if (tempQ!=NULL) updateResult(strat->Shdl,tempQ,strat);
+  
+  id_Delete(&tempF, currRing);
 
 
@@ -1166,5 +1196,5 @@
 
     ideal I = strat->Shdl;
-    ideal erg = kInterRed(I,NULL);
+    ideal erg = kInterRed(I,tempQ);
     assume(I!=erg);
     id_Delete(&I, currRing);
@@ -1174,15 +1204,4 @@
 
 #if 0
-  {
-    Print("ideal S: \n");
-    for (int i = 0; i < F->idelems(); i++)
-    {
-      Print("; S[%d] = ", 1+i);
-      p_Write(F->m[i], currRing);
-    }
-    Print(";\n");
-    PrintLn();
-  }
-
    PrintS("</sca::bba>\n");
 #endif
@@ -1192,8 +1211,12 @@
 
 
-// is this an exterior algebra or a commuunative polynomial ring \otimes exterior algebra?
-// we should check whether qr->qideal is of the form: y_i^2, y_{i+1}^2, \ldots, y_j^2 (j > i)
-//.if yes, setup qr->nc->type, etc.
-bool sca_SetupSCA(ring& rGR, const ring rG)
+// should be used only inside nc_SetupQuotient!
+// Check whether this our case:
+//  1. rG is  a commutative polynomial ring \otimes anticommutative algebra
+//  2. factor ideal rGR->qideal contains squares of all alternating variables.
+// 
+// if yes, make rGR a super-commutative algebra!
+// NOTE: Factors of SuperCommutative Algebras are supported this way!
+bool sca_SetupQuotient(ring rGR, const ring rG)
 {
 //   return false; // test Plural
@@ -1208,135 +1231,54 @@
 
   const int N = rG->N;
+
   if(N < 2)
     return false;
 
-  // skew-commutative + constant skew? => no tensor products at the moment!!! Only exterior algebras are supported!
-
-//   if( rG->nc->D != NULL )
-//     return false;
-
   if(ncRingType(rG) != nc_skew)
     return false;
 
-//   if(rG->nc->IsSkewConstant != 1)
-//     return false;
-//
-//   if(!n_IsMOne(p_GetCoeff(MATELEM(rG->nc->COM,1,2),rG->nc->basering), rG->nc->basering)) // COM live in basering!
-//     return false;
-
-
-  assume(rGR->qideal != NULL);
-
-  // sort qr->qideal:
-
-  // for sanity
-  ring rSaveRing = currRing;
-
-  bool bWeChangeRing = false;
-  if(currRing != rG)
-  {
-    rChangeCurrRing(rG);
-    bWeChangeRing = true;
-  }
-
-  const ideal idQuotient = rGR->qideal;
-  const int   iQSize = idQuotient->idelems();
-
-  intvec *iv = idSort(idQuotient, FALSE); // by lex, currRing dependent!!! :(
-  assume(iv != NULL);
-
-  // check for y_{iAltVarStart}^2, y_{iAltVarStart+1}^2, \ldots, y_{iAltVarEnd}^2 (iAltVarEnd > iAltVarStart)
-  bool bSCA = true;
-
-  int iAltVarStart = -1;
-  int iAltVarEnd   = -1;
-
-  for(int i = 0; i < iQSize; i++)
-  {
-    const poly t = idQuotient->m[(*iv)[i]-1];
-
-    if( pNext(t) != NULL )
-    {
-      bSCA = false;
-      break;
-    }
-
-    const int iComp = p_GetComp(t, rG);
-
-    if( iComp > 0 )
-    {
-      bSCA = false;
-      break;
-    }
-
-    int iV = -1;
-
-    for (int j = N; j; j--)
-    {
-      const int e = p_GetExp (t, j, rGR);
-
-      if( e > 0 )
-      {
-        if( (e != 2) || (iV != -1) )
-        {
-          bSCA = false;
-          break;
-        }
-
-        iV = j;
-      }
-    }
-
-    if(!bSCA) break;
-
-    if(iV == -1)
-    {
-      bSCA = false;
-      break;
-    }
-
-    if(iAltVarStart == -1)
-    {
-      iAltVarStart = iV;
-      iAltVarEnd   = iV;
-    } else
-    {
-      if((iAltVarStart-1) == iV)
-      {
-        iAltVarStart = iV;
-      } else
-      if((iAltVarEnd+1) == iV)
-      {
-        iAltVarEnd = iV;
+  if(rGR->qideal == NULL) // there will be a factor!
+    return false;
+
+  if(rG->qideal != NULL) // we cannot change from factor to factor!
+    return false;
+
+
+  int iAltVarEnd = -1;
+  int iAltVarStart   = N+1;
+
+  const ring rBase = rG->nc->basering;
+  const matrix C   = rG->nc->C; // live in rBase!
+
+  for(int i = 1; i < N; i++)
+  {
+    for(int j = i + 1; j <= N; j++)
+    {
+      assume(MATELEM(C,i,j) != NULL); // after CallPlural!
+      number c = p_GetCoeff(MATELEM(C,i,j), rBase);
+      
+      if( n_IsMOne(c, rBase) )
+      {        
+        if( i < iAltVarStart) 
+          iAltVarStart = i;
+          
+        if( j > iAltVarEnd)
+          iAltVarEnd = j;
       } else
       {
-        bSCA = false;
-        break;
+        if( !n_IsOne(c, rBase) )
+        {
+#ifdef PDEBUG
+//           Print("Wrong Coeff at: [%d, %d]\n", i, j);
+#endif
+          return false;
+        }
       }
     }
   }
 
-  // cleanup:
-  delete iv;
-
-  if (bWeChangeRing)
-  {
-    rChangeCurrRing(rSaveRing);
-  }
-
-
-  if(!bSCA) return false;
-
-  assume( 1            <= iAltVarStart );
-  assume( iAltVarStart <= iAltVarEnd   );
-  assume( iAltVarEnd   <= N            );
-
-#ifdef PDEBUG
-//   Print("AltVars: [%d, %d]\n", iAltVarStart, iAltVarEnd);
-#endif
-
-  const ring rBase = rG->nc->basering;
-  const matrix C   = rG->nc->C; // live in rBase!
-
+  if( (iAltVarEnd == -1) || (iAltVarStart == (N+1)) )
+    return false; // either no alternating varables, or a single one => we are in commutative case!
+  
   for(int i = 1; i < N; i++)
   {
@@ -1344,5 +1286,5 @@
     {
       assume(MATELEM(C,i,j) != NULL); // after CallPlural!
-      number c = p_GetCoeff(MATELEM(C,i,j), rBase);
+      number c = p_GetCoeff(MATELEM(C,i,j), rBase);      
 
       if( (iAltVarStart <= i) && (j <= iAltVarEnd) ) // S <= i < j <= E
@@ -1368,7 +1310,68 @@
   }
 
+  assume( 1            <= iAltVarStart );
+  assume( iAltVarStart < iAltVarEnd   );
+  assume( iAltVarEnd   <= N            );
+
+  bool bWeChangeRing = false;
+  // for sanity
+  ring rSaveRing = currRing;
+
+  if(rSaveRing != rG)
+  {
+    rChangeCurrRing(rG);
+    bWeChangeRing = true;
+  }
+
+  assume(rGR->qideal != NULL);
+  assume(rG->qideal == NULL);
+  
+  const ideal idQuotient = rGR->qideal;
+
+  // check for 
+  // y_{iAltVarStart}^2, y_{iAltVarStart+1}^2, \ldots, y_{iAltVarEnd}^2  (iAltVarEnd > iAltVarStart) 
+  // to be within quotient ideal.
+
+  bool bSCA = true;
+
+  for ( int i = iAltVarStart; (i <= iAltVarEnd) && bSCA; i++ )
+  {
+    poly square = p_ISet(1, rSaveRing);
+    p_SetExp(square, i, 2, rSaveRing); // square = var(i)^2.
+    p_Setm(square, rSaveRing);
+
+    // square = NF( var(i)^2 | Q )
+    // NOTE: rSaveRing == currRing now! 
+    // NOTE: there is no better way to check this in general!
+    square = kNF(idQuotient, NULL, square, 0, 0); 
+    
+    if( square != NULL ) // var(i)^2 is not in Q?
+    {
+      p_Delete(&square, rSaveRing);
+      bSCA = false;      
+    }    
+  }
+  
+
+  if (bWeChangeRing)
+  {
+    rChangeCurrRing(rSaveRing);
+  }
+
+  if(!bSCA) return false;
+  
+
+
+#ifdef PDEBUG
+//  Print("AltVars: [%d, %d]\n", iAltVarStart, iAltVarEnd);
+#endif
+
+
   //////////////////////////////////////////////////////////////////////////
-  // ok... let's setup it!!!
+  // ok... here we go. let's setup it!!!
   //////////////////////////////////////////////////////////////////////////
+  ideal tempQ = id_KillSquares(idQuotient, iAltVarStart, iAltVarEnd, rG); // in rG!!!
+
+  rGR->nc->SCAQuotient() = idrMoveR(tempQ, rG, rGR); // deletes tempQ!
 
   ncRingType( rGR, nc_exterior );
@@ -1377,9 +1380,9 @@
   scaLastAltVar( rGR, iAltVarEnd );
 
-  // ????????????????????????????????????????????????????????????????????????????????
-  // check ordering!!! alternating variables must be bigger than all other variables?
-
-  SetProcsSCA(rGR, rGR->p_Procs);
-
+
+
+  sca_p_ProcsSet(rGR, rGR->p_Procs);
+
+  
   return true;
 }
@@ -1418,5 +1421,10 @@
   assume(rIsSCA(currRing));
 
-  BOOLEAN bIdHomog = id_IsYHomogeneous(F, currRing);
+  const unsigned int m_iFirstAltVar = scaFirstAltVar(currRing);
+  const unsigned int m_iLastAltVar  = scaLastAltVar(currRing);
+
+  BOOLEAN bIdHomog = id_IsBiHomogeneous(F, m_iFirstAltVar, m_iLastAltVar, currRing);
+
+  assume( !bIdHomog || strat->homog ); //  bIdHomog =====[implies]>>>>> strat->homog
 
   strat->homog = strat->homog && bIdHomog;
@@ -1442,5 +1450,5 @@
 //   initHilbCrit(F, Q, &hilb, strat);
 
-//  gr_initBba(F,strat);
+//  nc_gr_initBba(F,strat);
   initBba(F, strat); // set enterS, red, initEcart, initEcartPair
 
@@ -1476,8 +1484,4 @@
   ///////////////////////////////////////////////////////////////
   // SCA:
-  const unsigned short m_iFirstAltVar = scaFirstAltVar(currRing);
-  const unsigned short m_iLastAltVar  = scaLastAltVar(currRing);
-
-
 
   /* compute------------------------------------------------------- */
@@ -1643,7 +1647,9 @@
 
 //       if(0)
-      for( unsigned short i = m_iFirstAltVar; i <= m_iLastAltVar; i++ )
-      if( p_GetExp(pSave, i, currRing) )
+      for( unsigned int i = m_iFirstAltVar; i <= m_iLastAltVar; i++ )
+      if( p_GetExp(pSave, i, currRing) != 0 )
       {
+        assume(p_GetExp(pSave, i, currRing) == 1);
+        
         const poly pNew = sca_pp_Mult_xi_pp(i, pNext, currRing);
 
@@ -1783,67 +1789,4 @@
 
 
-
-// y-Degree
-inline long p_yDegree(const poly p, const ring r)
-{
-  assume(rIsSCA(r));
-
-  const unsigned short m_iFirstAltVar = scaFirstAltVar(r);
-  const unsigned short m_iLastAltVar  = scaLastAltVar(r);
-
-  long sum = 0;
-
-  for(int i = m_iFirstAltVar; i <= m_iLastAltVar; i++)
-    sum += p_GetExp(p, i, r);
-
-  return sum;
-}
-
-
-
-
-/**2
- * tests whether p is sca-homogeneous without respect to the actual weigths(=>all ones)
- */
-BOOLEAN p_IsYHomogeneous(const poly p, const ring r)
-{
-  assume(rIsSCA(r));
-
-  if( p == NULL ) return TRUE;
-
-  poly q = p;
-
-  const long o = p_yDegree(q, r);
-  pIter(q);
-
-  while( q != NULL )
-  {
-    if (p_yDegree(q,r) != o) return FALSE;
-    pIter(q);
-  }
-
-  return TRUE;
-}
-
-
-/*2
-*returns true if id is y-homogenous without respect to the aktual weights(=> all ones)
-*/
-BOOLEAN id_IsYHomogeneous(const ideal id, const ring r)
-{
-  if (id == NULL) return TRUE;
-
-  const int iSize = IDELEMS(id);
-
-  if (iSize == 0) return TRUE;
-
-  BOOLEAN b = TRUE;
-
-  for(int i = iSize - 1; (i >= 0 ) && b; i--)
-    b = p_IsYHomogeneous(id->m[i], r);
-
-  return b;
-}
-
 // //////////////////////////////////////////////////////////////////////////////
 // sca mora...
@@ -1884,5 +1827,16 @@
 ideal sca_mora(const ideal F, const ideal Q, const intvec *w, const intvec *, kStrategy strat)
 {
-  BOOLEAN bIdHomog = id_IsYHomogeneous(F, currRing);
+  assume(rIsSCA(currRing));
+
+  const unsigned int m_iFirstAltVar = scaFirstAltVar(currRing);
+  const unsigned int m_iLastAltVar  = scaLastAltVar(currRing);
+  
+  ideal tempF = id_KillSquares(F, m_iFirstAltVar, m_iLastAltVar, currRing);
+  
+  const ideal tempQ = currRing->nc->SCAQuotient();
+
+  BOOLEAN bIdHomog = id_IsBiHomogeneous(tempF, m_iFirstAltVar, m_iLastAltVar, currRing);
+
+  assume( !bIdHomog || strat->homog ); //  bIdHomog =====[implies]>>>>> strat->homog
 
   strat->homog = strat->homog && bIdHomog;
@@ -1891,5 +1845,4 @@
   assume( strat->homog == bIdHomog );
 #endif /*PDEBUG*/
-
 
 #ifdef HAVE_ASSUME
@@ -1897,4 +1850,5 @@
   sca_mora_loop_count = 0;
 #endif
+
 #ifdef KDEBUG
   om_Opts.MinTrack = 5;
@@ -1911,7 +1865,7 @@
   initBuchMoraCrit(strat);
 //   initHilbCrit(F,NULL,&hilb,strat); // no Q!
-  initMora(F,strat);
+  initMora(tempF, strat);
   initBuchMoraPos(strat);
-  /*Shdl=*/initBuchMora(F,NULL,strat); // no Q!
+  /*Shdl=*/initBuchMora(tempF, tempQ, strat); // temp Q, F!
 //   if (TEST_OPT_FASTHC) missingAxis(&strat->lastAxis,strat);
   /*updateS in initBuchMora has Hecketest
@@ -1951,8 +1905,4 @@
 #endif
 
-
-  // 4SCA:
-  const unsigned short m_iFirstAltVar = scaFirstAltVar(currRing);
-  const unsigned short m_iLastAltVar  = scaLastAltVar(currRing);
 
   while (strat->Ll >= 0)
@@ -2052,7 +2002,7 @@
       const poly pNext = pNext(pSave);
 
-//       if(0)
-      for( unsigned short i = m_iFirstAltVar; i <= m_iLastAltVar; i++ )
-      if( p_GetExp(pSave, i, currRing) )
+      if(pNext != NULL)
+      for( unsigned int i = m_iFirstAltVar; i <= m_iLastAltVar; i++ )
+      if( p_GetExp(pSave, i, currRing) != 0 )
       {
 
@@ -2142,6 +2092,9 @@
     }
   }
-//   if (Q!=NULL) updateResult(strat->Shdl,Q,strat);
+  if (tempQ!=NULL) updateResult(strat->Shdl,tempQ,strat);
   idTest(strat->Shdl);
+  
+  id_Delete( &tempF, currRing);
+  
   return (strat->Shdl);
 }
@@ -2152,5 +2105,5 @@
 
 
-void SetProcsSCA(ring& rGR, p_Procs_s* p_Procs)
+void sca_p_ProcsSet(ring rGR, p_Procs_s* p_Procs)
 {
 
@@ -2214,3 +2167,213 @@
 #endif
 }
-#endif
+
+
+// bi-Degree (x, y) of lm(p)
+// Y are ones from iFirstAltVar up to iLastAltVar
+inline void p_GetSCADegree(const poly p, 
+  const unsigned int iFirstAltVar, const unsigned int iLastAltVar, 
+  long& dx, long& dy, const ring r)
+{
+  const unsigned int N  = r->N;
+
+  int i = 1;
+  
+  dx = 0;
+  dy = 0;
+  
+  for(; i < iFirstAltVar; i++)
+    dx += p_GetExp(p, i, r);
+
+  for(; i <= iLastAltVar; i++)
+    dy += p_GetExp(p, i, r);
+
+  for(; i <= N; i++)
+    dx += p_GetExp(p, i, r);
+}
+
+// tests whether p is bi-homogeneous without respect to the actual weigths(=>all ones)
+// Polynomial is bi-homogeneous iff all monomials have the same bi-degree (x,y).
+// Y are ones from iFirstAltVar up to iLastAltVar
+bool p_IsBiHomogeneous(const poly p, 
+  const unsigned int iFirstAltVar, const unsigned int iLastAltVar, 
+  const ring r)
+{
+  if( p == NULL ) return true;
+
+  poly q = p;
+
+
+  long dx, dy;
+
+  p_GetSCADegree( q, iFirstAltVar, iLastAltVar, dx, dy, r); // get bi degree of lm(p)
+
+  pIter(q);
+
+  for(; q != NULL; pIter(q) )
+  {
+    long x, y;    
+    
+    p_GetSCADegree( q, iFirstAltVar, iLastAltVar, x, y, r); // get bi degree of q
+    
+    if ( (x != dx) || (y != dy) ) return false;
+  }
+
+  return true;
+}
+
+
+// returns true if id is bi-homogenous without respect to the aktual weights(=> all ones)
+bool id_IsBiHomogeneous(const ideal id, 
+  const unsigned int iFirstAltVar, const unsigned int iLastAltVar, 
+  const ring r)
+{
+  if (id == NULL) return true; // zero ideal
+
+  const int iSize = IDELEMS(id);
+
+  if (iSize == 0) return true;
+
+  bool b = true;
+
+  for(int i = iSize - 1; (i >= 0 ) && b; i--)
+    b = p_IsBiHomogeneous(id->m[i], iFirstAltVar, iLastAltVar, r);
+
+  return b;
+}
+
+
+
+
+// reduce term lt(m) modulo <y_i^2> , i = iFirstAltVar .. iLastAltVar:
+// either create a copy of m or return NULL
+inline poly m_KillSquares(const poly m, 
+  const unsigned int iFirstAltVar, const unsigned int iLastAltVar, 
+  const ring r)
+{  
+#ifdef PDEBUG
+  p_Test(m, r);
+
+#if 0
+  Print("m_KillSquares, m = "); // !
+  p_Write(m, r);
+#endif
+#endif
+
+  assume( m != NULL );
+
+  for(int k = iFirstAltVar; k <= iLastAltVar; k++)
+    if( p_GetExp(m, k, r) > 1 )
+      return NULL;  
+  
+  return p_Head(m, r);
+}
+
+
+// reduce polynomial p modulo <y_i^2> , i = iFirstAltVar .. iLastAltVar
+poly p_KillSquares(const poly p, 
+  const unsigned int iFirstAltVar, const unsigned int iLastAltVar, 
+  const ring r)
+{  
+#ifdef PDEBUG
+  p_Test(p, r);
+
+#if 0
+  Print("p_KillSquares, p = "); // !
+  p_Write(p, r);
+#endif
+#endif
+
+
+  if( p == NULL )
+    return NULL;
+
+  poly pResult = NULL;
+  poly* ppPrev = &pResult;
+
+  for( poly q = p; q!= NULL; pIter(q) )
+  {
+#ifdef PDEBUG
+    p_Test(q, r);
+#endif
+
+    // terms will be in the same order because of quasi-ordering!    
+    poly v = m_KillSquares(q, iFirstAltVar, iLastAltVar, r);
+
+    if( v != NULL )
+    {
+      *ppPrev = v;
+      ppPrev = &pNext(v);
+    }
+
+  }
+
+#ifdef PDEBUG
+  p_Test(pResult, r);
+#if 0
+  Print("p_KillSquares => "); // !
+  p_Write(pResult, r);
+#endif
+#endif
+
+  return(pResult);
+}
+  
+
+
+
+// reduces ideal id modulo <y_i^2> , i = iFirstAltVar .. iLastAltVar
+// returns the reduced ideal or zero ideal. 
+ideal id_KillSquares(const ideal id, 
+  const unsigned int iFirstAltVar, const unsigned int iLastAltVar, 
+  const ring r)
+{
+  if (id == NULL) return id; // zero ideal
+
+  const int iSize = id->idelems();
+
+  if (iSize == 0) return id;
+ 
+  ideal temp = idInit(iSize, 1);
+  
+#if 0
+   PrintS("<id_KillSquares>\n");
+  {
+    Print("ideal id: \n");
+    for (int i = 0; i < id->idelems(); i++)
+    {
+      Print("; id[%d] = ", i+1);
+      p_Write(id->m[i], r);
+    }
+    Print(";\n");
+    PrintLn();
+  }
+#endif
+  
+
+  for (int j = 0; j < iSize; j++)
+    temp->m[j] = p_KillSquares(id->m[j], iFirstAltVar, iLastAltVar, r);
+
+  idSkipZeroes(temp);
+
+#if 0
+   PrintS("<id_KillSquares>\n");
+  {
+    Print("ideal temp: \n");
+    for (int i = 0; i < temp->idelems(); i++)
+    {
+      Print("; temp[%d] = ", i+1);
+      p_Write(temp->m[i], r);
+    }
+    Print(";\n");
+    PrintLn();
+  }
+   PrintS("</id_KillSquares>\n");
+#endif
+
+  return temp;
+}
+
+
+
+
+#endif
Index: kernel/sca.h
===================================================================
--- kernel/sca.h	(revision 1cc61e18c0d6c70b177099c23a52159afb280bb4)
+++ kernel/sca.h	(revision 86016dc267659b0c4d7155a4accd5fb595c04de7)
@@ -5,24 +5,23 @@
 *  Computer Algebra System SINGULAR     *
 ****************************************/
-/* $Id: sca.h,v 1.6 2007-01-12 11:08:42 Singular Exp $ */
+/* $Id: sca.h,v 1.7 2007-01-31 23:51:25 motsak Exp $ */
 
+#include <ring.h>
 #include <gring.h>
+#include <structs.h>
+
+
+// we must always have this test!
+inline bool rIsSCA(const ring r)
+{
 #ifdef HAVE_PLURAL
-#include <structs.h>
-// #include <polys-impl.h>
-// #include <ring.h>
+  return rIsPluralRing(r) && (ncRingType(r) == nc_exterior);
+#else
+  return false;
+#endif
+}
 
-inline bool rIsSCA(ring r)
-{
-  if(!rIsPluralRing(r))
-    return false;
-
-  const bool result = (ncRingType(r) == nc_exterior);
-
-//   if( result )
-//     assume( ((scaFirstAltVar(r) != 0) && (scaLastAltVar(r) != 0)) );
-
-  return(result);
-}
+#ifdef HAVE_PLURAL
+#include <gring.h>
 
 
@@ -41,4 +40,6 @@
 };
 
+
+// The following inlines are just helpers for setup functions.
 inline void scaFirstAltVar(ring r, int n)
 {
@@ -66,63 +67,57 @@
 
 // set pProcs for r and the variable p_Procs
-// should be used by p_ProcsSet in "p_Procs_Set.h"
-void SetProcsSCA(ring& rGR, p_Procs_s* p_Procs);
+// should be used by nc_p_ProcsSet in "gring.h"
+void sca_p_ProcsSet(ring rGR, p_Procs_s* p_Procs);
+
+//////////////////////////////////////////////////////////////////////////////////////
+
+// tests whether p is bi-homogeneous without respect to the actual weigths(=>all ones)
+// Polynomial is bi-homogeneous iff all monomials have the same bi-degree (x,y).
+// Y are ones from iFirstAltVar up to iLastAltVar
+bool p_IsBiHomogeneous(const poly p, 
+  const unsigned int iFirstAltVar, const unsigned int iLastAltVar, 
+  const ring r);
+
+//////////////////////////////////////////////////////////////////////////////////////
+
+// returns true if id is bi-homogenous without respect to the aktual weights(=> all ones)
+// Ideal is bi-homogeneous iff all its generators are bi-homogeneous.
+bool id_IsBiHomogeneous(const ideal id, 
+  const unsigned int iFirstAltVar, const unsigned int iLastAltVar, 
+  const ring r);
+
+//////////////////////////////////////////////////////////////////////////////////////
+
+// reduce polynomial p modulo <y_i^2> , i = iFirstAltVar .. iLastAltVar
+poly p_KillSquares(const poly p, 
+  const unsigned int iFirstAltVar, const unsigned int iLastAltVar, 
+  const ring r); 
+
+//////////////////////////////////////////////////////////////////////////////////////
+
+// reduce ideal id modulo <y_i^2> , i = iFirstAltVar .. iLastAltVar
+ideal id_KillSquares(const ideal id, 
+  const unsigned int iFirstAltVar, const unsigned int iLastAltVar, 
+  const ring r); 
 
 
-// is this an exterior algebra or a commutative polynomial ring \otimes exterior algebra?
-// we should check whether qr->qideal is of the form: y_i^2, y_{i+1}^2, \ldots, y_j^2 (j > i)
-// if yes, setup qr->nc->type, etc.
-// should be used inside QRing definition!
-// NOTE: (&TODO): Factors of SuperCommutative Algebras are not supported this way!
-bool sca_SetupSCA(ring& rGR, const ring rG);
+#ifdef PLURAL_INTERNAL_DECLARATIONS
 
+// should be used only inside nc_SetupQuotient!
+// Check whether this our case:
+//  1. rG is  a commutative polynomial ring \otimes anticommutative algebra
+//  2. factor ideal rGR->qideal contains squares of all alternating variables.
+// 
+// if yes, make rGR a super-commutative algebra!
+// NOTE: Factors of SuperCommutative Algebras are supported this way!
+bool sca_SetupQuotient(ring rGR, const ring rG);
 
-
-
-// tests whether p is sca(y)-homogeneous without respect to the actual weigths(=>all ones)
-BOOLEAN p_IsYHomogeneous(const poly p, const ring r);
-
-// returns true if id is sca(y)-homogenous without respect to the aktual weights(=> all ones)
-BOOLEAN id_IsYHomogeneous(const ideal id, const ring r);
-
-
-
-// #define PLURAL_INTERNAL_DECLARATIONS
-
-#ifdef PLURAL_INTERNAL_DECLARATIONS
-// poly functions defined in p_Procs :
-
-// return pPoly * pMonom; preserve pPoly and pMonom.
-poly sca_pp_Mult_mm(const poly pPoly, const poly pMonom, const ring rRing, poly &);
-
-// return pMonom * pPoly; preserve pPoly and pMonom.
-poly sca_mm_Mult_pp(const poly pMonom, const poly pPoly, const ring rRing);
-
-// return pPoly * pMonom; preserve pMonom, destroy or reuse pPoly.
-poly sca_p_Mult_mm(poly pPoly, const poly pMonom, const ring rRing);
-
-// return pMonom * pPoly; preserve pMonom, destroy or reuse pPoly.
-poly sca_mm_Mult_p(const poly pMonom, poly pPoly, const ring rRing);
-
-
-// compute the spolynomial of p1 and p2
-poly sca_SPoly(const poly p1, const poly p2, const ring r);
-poly sca_ReduceSpoly(const poly p1, poly p2, const ring r);
-
-// Modified Plural's Buchberger's algorithmus.
-ideal sca_gr_bba(const ideal F, const ideal Q, const intvec *, const intvec *, kStrategy strat);
-
-// Modified modern Sinuglar Buchberger's algorithm.
-ideal sca_bba(const ideal F, const ideal Q, const intvec *w, const intvec *, kStrategy strat);
-
-// Modified modern Sinuglar Mora's algorithm.
-ideal sca_mora(const ideal F, const ideal Q, const intvec *w, const intvec *, kStrategy strat);
-#endif
+#endif // PLURAL_INTERNAL_DECLARATIONS
 
 
 #else
-#define rIsSCA(R) 0
-#define scaFirstAltVar(R) 0
-#define scaLastAltVar(R) 0
+// these must not be used at all. 
+// #define scaFirstAltVar(R) 0
+// #define scaLastAltVar(R) 0
 #endif
 #endif // #ifndef GRING_SUPER_COMMUTATIVE_ALGEBRA_H
Index: kernel/structs.h
===================================================================
--- kernel/structs.h	(revision 1cc61e18c0d6c70b177099c23a52159afb280bb4)
+++ kernel/structs.h	(revision 86016dc267659b0c4d7155a4accd5fb595c04de7)
@@ -4,5 +4,5 @@
 *  Computer Algebra System SINGULAR     *
 ****************************************/
-/* $Id: structs.h,v 1.29 2007-01-11 11:27:26 Singular Exp $ */
+/* $Id: structs.h,v 1.30 2007-01-31 23:51:25 motsak Exp $ */
 /*
 * ABSTRACT
@@ -462,5 +462,9 @@
     // iAltVarsStart, iAltVarsEnd are only used together with nc_type=nc_exterior
     // 1 <= iAltVarsStart <= iAltVarsEnd <= r->N
-    unsigned int iFirstAltVar, iLastAltVar;
+    unsigned int iFirstAltVar, iLastAltVar; // = 0 by default
+    
+    // for factors of super-commutative algebras we need 
+    // the part of general quotient ideal modulo squares!    
+    ideal idSCAQuotient; // = NULL by default.
 
   public:
@@ -470,4 +474,6 @@
     inline unsigned int FirstAltVar() const { return (iFirstAltVar); };
     inline unsigned int LastAltVar () const { return (iLastAltVar ); };
+
+    inline ideal& SCAQuotient() { return (idSCAQuotient); };
 
   public:
