source: git/kernel/kutil.cc @ 9f6d76

spielwiese
Last change on this file since 9f6d76 was 9f6d76, checked in by Hans Schönemann <hannes@…>, 15 years ago
*hannes: syntax git-svn-id: file:///usr/local/Singular/svn/trunk@10851 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 172.9 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: kutil.cc,v 1.99 2008-07-08 13:29:46 Singular Exp $ */
5/*
6* ABSTRACT: kernel: utils for kStd
7*/
8
9// #define PDEBUG 2
10// #define PDIV_DEBUG
11#include <stdlib.h>
12#include <string.h>
13#include "mod2.h"
14#include <mylimits.h>
15#include "structs.h"
16#include "gring.h"
17#include "sca.h"
18#ifdef KDEBUG
19#undef KDEBUG
20#define KDEBUG 2
21#endif
22
23#ifdef HAVE_RING2TOM
24#include "ideals.h"
25#endif
26
27// define if enterL, enterT should use memmove instead of doing it manually
28// on topgun, this is slightly faster (see monodromy_l.tst, homog_gonnet.sing)
29#ifndef SunOS_4
30#define ENTER_USE_MEMMOVE
31#endif
32
33// define, if the my_memmove inlines should be used instead of
34// system memmove -- it does not seem to pay off, though
35// #define ENTER_USE_MYMEMMOVE
36
37#include "kutil.h"
38#include "kbuckets.h"
39#include "febase.h"
40#include "omalloc.h"
41#include "numbers.h"
42#include "polys.h"
43#include "ring.h"
44#include "ideals.h"
45#include "timer.h"
46//#include "cntrlc.h"
47#include "stairc.h"
48#include "kstd1.h"
49#include "pShallowCopyDelete.h"
50
51/* shiftgb stuff */
52#include "shiftgb.h"
53#include "prCopy.h"
54
55#ifdef KDEBUG
56#undef KDEBUG
57#define KDEBUG 2
58#endif
59
60
61#ifdef ENTER_USE_MYMEMMOVE
62inline void _my_memmove_d_gt_s(unsigned long* d, unsigned long* s, long l)
63{
64  register unsigned long* _dl = (unsigned long*) d;
65  register unsigned long* _sl = (unsigned long*) s;
66  register long _i = l - 1;
67
68  do
69  {
70    _dl[_i] = _sl[_i];
71    _i--;
72  }
73  while (_i >= 0);
74}
75
76inline void _my_memmove_d_lt_s(unsigned long* d, unsigned long* s, long l)
77{
78  register long _ll = l;
79  register unsigned long* _dl = (unsigned long*) d;
80  register unsigned long* _sl = (unsigned long*) s;
81  register long _i = 0;
82
83  do
84  {
85    _dl[_i] = _sl[_i];
86    _i++;
87  }
88  while (_i < _ll);
89}
90
91inline void _my_memmove(void* d, void* s, long l)
92{
93  unsigned long _d = (unsigned long) d;
94  unsigned long _s = (unsigned long) s;
95  unsigned long _l = ((l) + SIZEOF_LONG - 1) >> LOG_SIZEOF_LONG;
96
97  if (_d > _s) _my_memmove_d_gt_s(_d, _s, _l);
98  else _my_memmove_d_lt_s(_d, _s, _l);
99}
100
101#undef memmove
102#define memmove(d,s,l) _my_memmove(d, s, l)
103#endif
104
105static poly redMora (poly h,int maxIndex,kStrategy strat);
106static poly redBba (poly h,int maxIndex,kStrategy strat);
107
108#ifdef HAVE_RINGS
109#define pDivComp_EQUAL 2
110#define pDivComp_LESS 1
111#define pDivComp_GREATER -1
112#define pDivComp_INCOMP 0
113/* Checks the relation of LM(p) and LM(q)
114     LM(p) = LM(q) => return pDivComp_EQUAL
115     LM(p) | LM(q) => return pDivComp_LESS
116     LM(q) | LM(p) => return pDivComp_GREATER
117     else return pDivComp_INCOMP */
118static inline int pDivCompRing(poly p, poly q)
119{
120  if (pGetComp(p) == pGetComp(q))
121  {
122    BOOLEAN a=FALSE, b=FALSE;
123    int i;
124    unsigned long la, lb;
125    unsigned long divmask = currRing->divmask;
126    for (i=0; i<currRing->VarL_Size; i++)
127    {
128      la = p->exp[currRing->VarL_Offset[i]];
129      lb = q->exp[currRing->VarL_Offset[i]];
130      if (la != lb)
131      {
132        if (la < lb)
133        {
134          if (b) return pDivComp_INCOMP;
135          if (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask))
136            return pDivComp_INCOMP;
137          a = TRUE;
138        }
139        else
140        {
141          if (a) return pDivComp_INCOMP;
142          if (((la & divmask) ^ (lb & divmask)) != ((la - lb) & divmask))
143            return pDivComp_INCOMP;
144          b = TRUE;
145        }
146      }
147    }
148    if (a) return pDivComp_LESS;
149    if (b) return pDivComp_GREATER;
150    if (!a & !b) return pDivComp_EQUAL;
151  }
152  return 0;
153}
154#endif
155
156static inline int pDivComp(poly p, poly q)
157{
158  if (pGetComp(p) == pGetComp(q))
159  {
160    BOOLEAN a=FALSE, b=FALSE;
161    int i;
162    unsigned long la, lb;
163    unsigned long divmask = currRing->divmask;
164    for (i=0; i<currRing->VarL_Size; i++)
165    {
166      la = p->exp[currRing->VarL_Offset[i]];
167      lb = q->exp[currRing->VarL_Offset[i]];
168      if (la != lb)
169      {
170        if (la < lb)
171        {
172          if (b) return 0;
173          if (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask))
174            return 0;
175          a = TRUE;
176        }
177        else
178        {
179          if (a) return 0;
180          if (((la & divmask) ^ (lb & divmask)) != ((la - lb) & divmask))
181            return 0;
182          b = TRUE;
183        }
184      }
185    }
186    if (a) return 1;
187    if (b) return -1;
188  }
189  return 0;
190}
191
192
193BITSET  test=(BITSET)0;
194int     HCord;
195int     Kstd1_deg;
196int     mu=32000;
197
198/*2
199*deletes higher monomial of p, re-compute ecart and length
200*works only for orderings with ecart =pFDeg(end)-pFDeg(start)
201*/
202void deleteHC(LObject *L, kStrategy strat, BOOLEAN fromNext)
203{
204  if (strat->kHEdgeFound)
205  {
206    kTest_L(L);
207    poly p1;
208    poly p = L->GetLmTailRing();
209    int l = 1;
210    kBucket_pt bucket = NULL;
211    if (L->bucket != NULL)
212    {
213      kBucketClear(L->bucket, &pNext(p), &L->pLength);
214      L->pLength++;
215      bucket = L->bucket;
216      L->bucket = NULL;
217      L->last = NULL;
218    }
219
220    if (!fromNext && p_Cmp(p,strat->kNoetherTail(), L->tailRing) == -1)
221    {
222      L->Delete();
223      L->Clear();
224      L->ecart = -1;
225      if (bucket != NULL) kBucketDestroy(&bucket);
226      return;
227    }
228    p1 = p;
229    while (pNext(p1)!=NULL)
230    {
231      if (p_LmCmp(pNext(p1), strat->kNoetherTail(), L->tailRing) == -1)
232      {
233        L->last = p1;
234        p_Delete(&pNext(p1), L->tailRing);
235        if (p1 == p)
236        {
237          if (L->t_p != NULL)
238          {
239            assume(L->p != NULL && p == L->t_p);
240            pNext(L->p) = NULL;
241          }
242          L->max  = NULL;
243        }
244        else if (fromNext)
245          L->max  = p_GetMaxExpP(pNext(L->p), L->tailRing ); // p1;
246        //if (L->pLength != 0)
247        L->pLength = l;
248        // Hmmm when called from updateT, then only
249        // reset ecart when cut
250        if (fromNext)
251          L->ecart = L->pLDeg() - L->GetpFDeg();
252        break;
253      }
254      l++;
255      pIter(p1);
256    }
257    if (! fromNext)
258    {
259      L->SetpFDeg();
260      L->ecart = L->pLDeg(strat->LDegLast) - L->GetpFDeg();
261    }
262    if (bucket != NULL)
263    {
264      if (L->pLength > 1)
265      {
266        kBucketInit(bucket, pNext(p), L->pLength - 1);
267        pNext(p) = NULL;
268        if (L->t_p != NULL) pNext(L->t_p) = NULL;
269        L->pLength = 0;
270        L->bucket = bucket;
271        L->last = NULL;
272      }
273      else
274        kBucketDestroy(&bucket);
275    }
276    kTest_L(L);
277  }
278}
279
280void deleteHC(poly* p, int* e, int* l,kStrategy strat)
281{
282  LObject L(*p, currRing, strat->tailRing);
283
284  deleteHC(&L, strat);
285  *p = L.p;
286  *e = L.ecart;
287  *l = L.length;
288  if (L.t_p != NULL) p_LmFree(L.t_p, strat->tailRing);
289}
290
291/*2
292*tests if p.p=monomial*unit and cancels the unit
293*/
294void cancelunit (LObject* L,BOOLEAN inNF)
295{
296  int  i;
297  poly h;
298
299  if(currRing->OrdSgn != -1) return;
300  if(TEST_OPT_CANCELUNIT) return;
301
302  ring r = L->tailRing;
303  poly p = L->GetLmTailRing();
304
305  if(p_GetComp(p, r) != 0 && !p_OneComp(p, r)) return;
306
307  if (L->ecart != 0)
308  {
309//    for(i=r->N;i>0;i--)
310//    {
311//      if ((p_GetExp(p,i,r)>0) && (rIsPolyVar(i, r)==TRUE)) return;
312//    }
313    h = pNext(p);
314    loop
315    {
316      if (h==NULL)
317      {
318        p_Delete(&pNext(p), r);
319        if (!inNF)
320        {
321          number eins=nInit(1);
322          if (L->p != NULL)  pSetCoeff(L->p,eins);
323          else if (L->t_p != NULL) nDelete(&pGetCoeff(L->t_p));
324          if (L->t_p != NULL) pSetCoeff0(L->t_p,eins);
325        }
326        L->ecart = 0;
327        L->length = 1;
328        //if (L->pLength > 0)
329        L->pLength = 1;
330        if (L->last != NULL) L->last = p;
331
332        if (L->t_p != NULL && pNext(L->t_p) != NULL)
333          pNext(L->t_p) = NULL;
334        if (L->p != NULL && pNext(L->p) != NULL)
335          pNext(L->p) = NULL;
336        return;
337      }
338      i = 0;
339      loop
340      {
341        i++;
342        if (p_GetExp(p,i,r) > p_GetExp(h,i,r)) return ; // does not divide
343        if (i == r->N) break; // does divide, try next monom
344      }
345      pIter(h);
346    }
347  }
348}
349
350/*2
351*pp is the new element in s
352*returns TRUE (in strat->kHEdgeFound) if
353*-HEcke is allowed
354*-we are in the last componente of the vector
355*-on all axis are monomials (all elements in NotUsedAxis are FALSE)
356*returns FALSE for pLexOrderings,
357*assumes in module case an ordering of type c* !!
358* HEckeTest is only called with strat->kHEdgeFound==FALSE !
359*/
360void HEckeTest (poly pp,kStrategy strat)
361{
362  int   j,k,p;
363
364  strat->kHEdgeFound=FALSE;
365  if (pLexOrder || currRing->MixedOrder)
366  {
367    return;
368  }
369  if (strat->ak > 1)           /*we are in the module case*/
370  {
371    return; // until ....
372    //if (!pVectorOut)     /*pVectorOut <=> order = c,* */
373    //  return FALSE;
374    //if (pGetComp(pp) < strat->ak) /* ak is the number of the last component */
375    //  return FALSE;
376  }
377  k = 0;
378  p=pIsPurePower(pp);
379  if (p!=0) strat->NotUsedAxis[p] = FALSE;
380  /*- the leading term of pp is a power of the p-th variable -*/
381  for (j=pVariables;j>0; j--)
382  {
383    if (strat->NotUsedAxis[j])
384    {
385      return;
386    }
387  }
388  strat->kHEdgeFound=TRUE;
389}
390
391/*2
392*utilities for TSet, LSet
393*/
394inline static intset initec (const int maxnr)
395{
396  return (intset)omAlloc(maxnr*sizeof(int));
397}
398
399inline static unsigned long* initsevS (const int maxnr)
400{
401  return (unsigned long*)omAlloc0(maxnr*sizeof(unsigned long));
402}
403inline static int* initS_2_R (const int maxnr)
404{
405  return (int*)omAlloc0(maxnr*sizeof(int));
406}
407
408static inline void enlargeT (TSet &T, TObject** &R, unsigned long* &sevT,
409                             int &length, const int incr)
410{
411  assume(T!=NULL);
412  assume(sevT!=NULL);
413  assume(R!=NULL);
414  assume((length+incr) > 0);
415
416  int i;
417  T = (TSet)omRealloc0Size(T, length*sizeof(TObject),
418                           (length+incr)*sizeof(TObject));
419
420  sevT = (unsigned long*) omReallocSize(sevT, length*sizeof(long*),
421                           (length+incr)*sizeof(long*));
422
423  R = (TObject**)omRealloc0Size(R,length*sizeof(TObject*),
424                                (length+incr)*sizeof(TObject*));
425  for (i=length-1;i>=0;i--) R[T[i].i_r] = &(T[i]);
426  length += incr;
427}
428
429void cleanT (kStrategy strat)
430{
431  int i,j;
432  poly  p;
433  assume(currRing == strat->tailRing || strat->tailRing != NULL);
434
435  pShallowCopyDeleteProc p_shallow_copy_delete =
436    (strat->tailRing != currRing ?
437     pGetShallowCopyDeleteProc(strat->tailRing, currRing) :
438     NULL);
439
440  for (j=0; j<=strat->tl; j++)
441  {
442    p = strat->T[j].p;
443    strat->T[j].p=NULL;
444    if (strat->T[j].max != NULL)
445      p_LmFree(strat->T[j].max, strat->tailRing);
446    i = -1;
447    loop
448    {
449      i++;
450      if (i>strat->sl)
451      {
452        if (strat->T[j].t_p != NULL)
453        {
454          p_Delete(&(strat->T[j].t_p), strat->tailRing);
455          p_LmFree(p, currRing);
456        }
457        else
458          pDelete(&p);
459        break;
460      }
461      if (p == strat->S[i])
462      {
463        if (strat->T[j].t_p != NULL)
464        {
465          assume(p_shallow_copy_delete != NULL);
466          pNext(p) = p_shallow_copy_delete(pNext(p),strat->tailRing,currRing,
467                                           currRing->PolyBin);
468          p_LmFree(strat->T[j].t_p, strat->tailRing);
469        }
470        break;
471      }
472    }
473  }
474  strat->tl=-1;
475}
476
477//LSet initL ()
478//{
479//  int i;
480//  LSet l = (LSet)omAlloc(setmaxL*sizeof(LObject));
481//  return l;
482//}
483
484static inline void enlargeL (LSet* L,int* length,const int incr)
485{
486  assume((*L)!=NULL);
487  assume((length+incr)>0);
488
489  *L = (LSet)omReallocSize((*L),(*length)*sizeof(LObject),
490                                   ((*length)+incr)*sizeof(LObject));
491  (*length) += incr;
492}
493
494void initPairtest(kStrategy strat)
495{
496  strat->pairtest = (BOOLEAN *)omAlloc0((strat->sl+2)*sizeof(BOOLEAN));
497}
498
499/*2
500*test whether (p1,p2) or (p2,p1) is in L up position length
501*it returns TRUE if yes and the position k
502*/
503BOOLEAN isInPairsetL(int length,poly p1,poly p2,int*  k,kStrategy strat)
504{
505  LObject *p=&(strat->L[length]);
506
507  *k = length;
508  loop
509  {
510    if ((*k) < 0) return FALSE;
511    if (((p1 == (*p).p1) && (p2 == (*p).p2))
512    ||  ((p1 == (*p).p2) && (p2 == (*p).p1)))
513      return TRUE;
514    (*k)--;
515    p--;
516  }
517}
518
519/*2
520*in B all pairs have the same element p on the right
521*it tests whether (q,p) is in B and returns TRUE if yes
522*and the position k
523*/
524BOOLEAN isInPairsetB(poly q,int*  k,kStrategy strat)
525{
526  LObject *p=&(strat->B[strat->Bl]);
527
528  *k = strat->Bl;
529  loop
530  {
531    if ((*k) < 0) return FALSE;
532    if (q == (*p).p1)
533      return TRUE;
534    (*k)--;
535    p--;
536  }
537}
538
539int kFindInT(poly p, TSet T, int tlength)
540{
541  int i;
542
543  for (i=0; i<=tlength; i++)
544  {
545    if (T[i].p == p) return i;
546  }
547  return -1;
548}
549
550int kFindInT(poly p, kStrategy strat)
551{
552  int i;
553  do
554  {
555    i = kFindInT(p, strat->T, strat->tl);
556    if (i >= 0) return i;
557    strat = strat->next;
558  }
559  while (strat != NULL);
560  return -1;
561}
562
563#ifdef KDEBUG
564
565void sTObject::wrp()
566{
567  if (t_p != NULL) p_wrp(t_p, tailRing);
568  else if (p != NULL) p_wrp(p, currRing, tailRing);
569  else ::wrp(NULL);
570}
571
572#define kFalseReturn(x) do { if (!x) return FALSE;} while (0)
573
574// check that Lm's of a poly from T are "equal"
575static const char* kTest_LmEqual(poly p, poly t_p, ring tailRing)
576{
577  int i;
578  for (i=1; i<=tailRing->N; i++)
579  {
580    if (p_GetExp(p, i, currRing) != p_GetExp(t_p, i, tailRing))
581      return "Lm[i] different";
582  }
583  if (p_GetComp(p, currRing) != p_GetComp(t_p, tailRing))
584    return "Lm[0] different";
585  if (pNext(p) != pNext(t_p))
586    return "Lm.next different";
587  if (pGetCoeff(p) != pGetCoeff(t_p))
588    return "Lm.coeff different";
589  return NULL;
590}
591
592static BOOLEAN sloppy_max = FALSE;
593BOOLEAN kTest_T(TObject * T, ring strat_tailRing, int i, char TN)
594{
595  ring tailRing = T->tailRing;
596  if (strat_tailRing == NULL) strat_tailRing = tailRing;
597  r_assume(strat_tailRing == tailRing);
598
599  poly p = T->p;
600  ring r = currRing;
601
602  if (T->p == NULL && T->t_p == NULL && i >= 0)
603    return dReportError("%c[%d].poly is NULL", TN, i);
604
605  if (T->tailRing != currRing)
606  {
607    if (T->t_p == NULL && i > 0)
608      return dReportError("%c[%d].t_p is NULL", TN, i);
609    pFalseReturn(p_Test(T->t_p, T->tailRing));
610    if (T->p != NULL) pFalseReturn(p_LmTest(T->p, currRing));
611    if (T->p != NULL && T->t_p != NULL)
612    {
613      const char* msg = kTest_LmEqual(T->p, T->t_p, T->tailRing);
614      if (msg != NULL)
615        return dReportError("%c[%d] %s", TN, i, msg);
616      r = T->tailRing;
617      p = T->t_p;
618    }
619    if (T->p == NULL)
620    {
621      p = T->t_p;
622      r = T->tailRing;
623    }
624    if (T->t_p != NULL && i >= 0 && TN == 'T')
625    {
626      if (pNext(T->t_p) == NULL)
627      {
628        if (T->max != NULL)
629          return dReportError("%c[%d].max is not NULL as it should be", TN, i);
630      }
631      else
632      {
633        if (T->max == NULL)
634          return dReportError("%c[%d].max is NULL", TN, i);
635        if (pNext(T->max) != NULL)
636          return dReportError("pNext(%c[%d].max) != NULL", TN, i);
637
638        pFalseReturn(p_CheckPolyRing(T->max, tailRing));
639        omCheckBinAddrSize(T->max, (tailRing->PolyBin->sizeW)*SIZEOF_LONG);
640#if KDEBUG > 0
641        if (! sloppy_max)
642        {
643          poly test_max = p_GetMaxExpP(pNext(T->t_p), tailRing);
644          p_Setm(T->max, tailRing);
645          p_Setm(test_max, tailRing);
646          BOOLEAN equal = p_ExpVectorEqual(T->max, test_max, tailRing);
647          if (! equal)
648            return dReportError("%c[%d].max out of sync", TN, i);
649          p_LmFree(test_max, tailRing);
650        }
651#endif
652      }
653    }
654  }
655  else
656  {
657    if (T->max != NULL)
658      return dReportError("%c[%d].max != NULL but tailRing == currRing",TN,i);
659    if (T->t_p != NULL)
660      return dReportError("%c[%d].t_p != NULL but tailRing == currRing",TN,i);
661    if (T->p == NULL && i > 0)
662      return dReportError("%c[%d].p is NULL", TN, i);
663    pFalseReturn(p_Test(T->p, currRing));
664  }
665
666  if (i >= 0 && T->pLength != 0 && T->pLength != pLength(p))
667  {
668    int l=T->pLength;
669    T->pLength=pLength(p);
670    return dReportError("%c[%d] pLength error: has %d, specified to have %d",
671                        TN, i , pLength(p), l);
672  }
673
674  // check FDeg,  for elements in L and T
675  if (i >= 0 && (TN == 'T' || TN == 'L'))
676  {
677    // FDeg has ir element from T of L set
678    if (T->FDeg  != T->pFDeg())
679    {
680      int d=T->FDeg;
681      T->FDeg=T->pFDeg();
682      return dReportError("%c[%d] FDeg error: has %d, specified to have %d",
683                          TN, i , T->pFDeg(), d);
684    }
685  }
686
687  // check is_normalized for elements in T
688  if (i >= 0 && TN == 'T')
689  {
690    if (T->is_normalized && ! nIsOne(pGetCoeff(p)))
691      return dReportError("T[%d] is_normalized error", i);
692
693  }
694  return TRUE;
695}
696
697BOOLEAN kTest_L(LObject *L, ring strat_tailRing,
698                BOOLEAN testp, int lpos, TSet T, int tlength)
699{
700  if (testp)
701  {
702    poly pn = NULL;
703    if (L->bucket != NULL)
704    {
705      kFalseReturn(kbTest(L->bucket));
706      r_assume(L->bucket->bucket_ring == L->tailRing);
707      if (L->p != NULL && pNext(L->p) != NULL)
708      {
709        pn = pNext(L->p);
710        pNext(L->p) = NULL;
711      }
712    }
713    kFalseReturn(kTest_T(L, strat_tailRing, lpos, 'L'));
714    if (pn != NULL)
715      pNext(L->p) = pn;
716
717    ring r;
718    poly p;
719    L->GetLm(p, r);
720    if (L->sev != 0 && p_GetShortExpVector(p, r) != L->sev)
721    {
722      return dReportError("L[%d] wrong sev: has %o, specified to have %o",
723                          lpos, p_GetShortExpVector(p, r), L->sev);
724    }
725    if (lpos > 0 && L->last != NULL && pLast(p) != L->last)
726    {
727      return dReportError("L[%d] last wrong: has %p specified to have %p",
728                          lpos, pLast(p), L->last);
729    }
730  }
731  if (L->p1 == NULL)
732  {
733    // L->p2 either NULL or "normal" poly
734    pFalseReturn(pp_Test(L->p2, currRing, L->tailRing));
735  }
736  else if (tlength > 0 && T != NULL && (lpos >=0))
737  {
738    // now p1 and p2 must be != NULL and must be contained in T
739    int i;
740    i = kFindInT(L->p1, T, tlength);
741    if (i < 0)
742      return dReportError("L[%d].p1 not in T",lpos);
743    i = kFindInT(L->p2, T, tlength);
744    if (i < 0)
745      return dReportError("L[%d].p2 not in T",lpos);
746  }
747  return TRUE;
748}
749
750BOOLEAN kTest (kStrategy strat)
751{
752  int i;
753
754  // test P
755  kFalseReturn(kTest_L(&(strat->P), strat->tailRing,
756                       (strat->P.p != NULL && pNext(strat->P.p)!=strat->tail),
757                       -1, strat->T, strat->tl));
758
759  // test T
760  if (strat->T != NULL)
761  {
762    for (i=0; i<=strat->tl; i++)
763    {
764      kFalseReturn(kTest_T(&(strat->T[i]), strat->tailRing, i, 'T'));
765      if (strat->sevT[i] != pGetShortExpVector(strat->T[i].p))
766        return dReportError("strat->sevT[%d] out of sync", i);
767    }
768  }
769
770  // test L
771  if (strat->L != NULL)
772  {
773    for (i=0; i<=strat->Ll; i++)
774    {
775      kFalseReturn(kTest_L(&(strat->L[i]), strat->tailRing,
776                           strat->L[i].Next() != strat->tail, i,
777                           strat->T, strat->tl));
778      if (strat->use_buckets && strat->L[i].Next() != strat->tail &&
779          strat->L[i].Next() != NULL && strat->L[i].p1 != NULL)
780      {
781        assume(strat->L[i].bucket != NULL);
782      }
783    }
784  }
785
786  // test S
787  if (strat->S != NULL)
788    kFalseReturn(kTest_S(strat));
789
790  return TRUE;
791}
792
793BOOLEAN kTest_S(kStrategy strat)
794{
795  int i;
796  BOOLEAN ret = TRUE;
797  for (i=0; i<=strat->sl; i++)
798  {
799    if (strat->S[i] != NULL &&
800        strat->sevS[i] != pGetShortExpVector(strat->S[i]))
801    {
802      return dReportError("S[%d] wrong sev: has %o, specified to have %o",
803                          i , pGetShortExpVector(strat->S[i]), strat->sevS[i]);
804    }
805  }
806  return ret;
807}
808
809
810
811BOOLEAN kTest_TS(kStrategy strat)
812{
813  int i, j;
814  BOOLEAN ret = TRUE;
815  kFalseReturn(kTest(strat));
816
817  // test strat->R, strat->T[i].i_r
818  for (i=0; i<=strat->tl; i++)
819  {
820    if (strat->T[i].i_r < 0 || strat->T[i].i_r > strat->tl)
821      return dReportError("strat->T[%d].i_r == %d out of bounds", i,
822                          strat->T[i].i_r);
823    if (strat->R[strat->T[i].i_r] != &(strat->T[i]))
824      return dReportError("T[%d].i_r with R out of sync", i);
825  }
826  // test containment of S inT
827  if (strat->S != NULL)
828  {
829    for (i=0; i<=strat->sl; i++)
830    {
831      j = kFindInT(strat->S[i], strat->T, strat->tl);
832      if (j < 0)
833        return dReportError("S[%d] not in T", i);
834      if (strat->S_2_R[i] != strat->T[j].i_r)
835        return dReportError("S_2_R[%d]=%d != T[%d].i_r=%d\n",
836                            i, strat->S_2_R[i], j, strat->T[j].i_r);
837    }
838  }
839  // test strat->L[i].i_r1
840  for (i=0; i<=strat->Ll; i++)
841  {
842    if (strat->L[i].p1 != NULL && strat->L[i].p2)
843    {
844      if (strat->L[i].i_r1 < 0 ||
845          strat->L[i].i_r1 > strat->tl ||
846          strat->L[i].T_1(strat)->p != strat->L[i].p1)
847        return dReportError("L[%d].i_r1 out of sync", i);
848      if (strat->L[i].i_r2 < 0 ||
849          strat->L[i].i_r2 > strat->tl ||
850          strat->L[i].T_2(strat)->p != strat->L[i].p2);
851    }
852    else
853    {
854      if (strat->L[i].i_r1 != -1)
855        return dReportError("L[%d].i_r1 out of sync", i);
856      if (strat->L[i].i_r2 != -1)
857        return dReportError("L[%d].i_r2 out of sync", i);
858    }
859    if (strat->L[i].i_r != -1)
860      return dReportError("L[%d].i_r out of sync", i);
861  }
862  return TRUE;
863}
864
865#endif // KDEBUG
866
867/*2
868*cancels the i-th polynomial in the standardbase s
869*/
870void deleteInS (int i,kStrategy strat)
871{
872#ifdef ENTER_USE_MEMMOVE
873  memmove(&(strat->S[i]), &(strat->S[i+1]), (strat->sl - i)*sizeof(poly));
874  memmove(&(strat->ecartS[i]),&(strat->ecartS[i+1]),(strat->sl - i)*sizeof(int));
875  memmove(&(strat->sevS[i]),&(strat->sevS[i+1]),(strat->sl - i)*sizeof(long));
876  memmove(&(strat->S_2_R[i]),&(strat->S_2_R[i+1]),(strat->sl - i)*sizeof(int));
877#else
878  int j;
879  for (j=i; j<strat->sl; j++)
880  {
881    strat->S[j] = strat->S[j+1];
882    strat->ecartS[j] = strat->ecartS[j+1];
883    strat->sevS[j] = strat->sevS[j+1];
884    strat->S_2_R[j] = strat->S_2_R[j+1];
885  }
886#endif
887  if (strat->lenS!=NULL)
888  {
889#ifdef ENTER_USE_MEMMOVE
890    memmove(&(strat->lenS[i]),&(strat->lenS[i+1]),(strat->sl - i)*sizeof(int));
891#else
892    for (j=i; j<strat->sl; j++) strat->lenS[j] = strat->lenS[j+1];
893#endif
894  }
895  if (strat->lenSw!=NULL)
896  {
897#ifdef ENTER_USE_MEMMOVE
898    memmove(&(strat->lenSw[i]),&(strat->lenSw[i+1]),(strat->sl - i)*sizeof(wlen_type));
899#else
900    for (j=i; j<strat->sl; j++) strat->lenSw[j] = strat->lenSw[j+1];
901#endif
902  }
903  if (strat->fromQ!=NULL)
904  {
905#ifdef ENTER_USE_MEMMOVE
906    memmove(&(strat->fromQ[i]),&(strat->fromQ[i+1]),(strat->sl - i)*sizeof(int));
907#else
908    for (j=i; j<strat->sl; j++)
909    {
910      strat->fromQ[j] = strat->fromQ[j+1];
911    }
912#endif
913  }
914  strat->S[strat->sl] = NULL;
915  strat->sl--;
916}
917
918/*2
919*cancels the j-th polynomial in the set
920*/
921void deleteInL (LSet set, int *length, int j,kStrategy strat)
922{
923  if (set[j].lcm!=NULL)
924  {
925#ifdef HAVE_RINGS
926    if (pGetCoeff(set[j].lcm) != NULL)
927      pLmDelete(set[j].lcm);
928    else
929#endif
930      pLmFree(set[j].lcm);
931  }
932  if (set[j].p!=NULL)
933  {
934    if (pNext(set[j].p) == strat->tail)
935    {
936#ifdef HAVE_RINGS
937      if (pGetCoeff(set[j].p) != NULL)
938        pLmDelete(set[j].p);
939      else
940#endif
941        pLmFree(set[j].p);
942      /*- tail belongs to several int spolys -*/
943    }
944    else
945    {
946      // search p in T, if it is there, do not delete it
947      if (pOrdSgn != -1 || kFindInT(set[j].p, strat) < 0)
948      {
949        // assure that for global orderings kFindInT fails
950        assume(pOrdSgn == -1 || kFindInT(set[j].p, strat) < 0);
951        set[j].Delete();
952      }
953    }
954  }
955  if (*length > 0 && j < *length)
956  {
957#ifdef ENTER_USE_MEMMOVE
958    memmove(&(set[j]), &(set[j+1]), (*length - j)*sizeof(LObject));
959#else
960    int i;
961    for (i=j; i < (*length); i++)
962      set[i] = set[i+1];
963#endif
964  }
965#ifdef KDEBUG
966  memset(&(set[*length]),0,sizeof(LObject));
967#endif
968  (*length)--;
969}
970
971/*2
972*enters p at position at in L
973*/
974void enterL (LSet *set,int *length, int *LSetmax, LObject p,int at)
975{
976#ifdef PDEBUG
977  /*  zaehler++; */
978#endif /*PDEBUG*/
979  int i;
980  // this should be corrected
981  assume(p.FDeg == p.pFDeg());
982
983  if ((*length)>=0)
984  {
985    if ((*length) == (*LSetmax)-1) enlargeL(set,LSetmax,setmaxLinc);
986    if (at <= (*length))
987#ifdef ENTER_USE_MEMMOVE
988      memmove(&((*set)[at+1]), &((*set)[at]), ((*length)-at+1)*sizeof(LObject));
989#else
990    for (i=(*length)+1; i>=at+1; i--) (*set)[i] = (*set)[i-1];
991#endif
992  }
993  else at = 0;
994  (*set)[at] = p;
995  (*length)++;
996}
997
998/*2
999* computes the normal ecart;
1000* used in mora case and if pLexOrder & sugar in bba case
1001*/
1002void initEcartNormal (LObject* h)
1003{
1004  h->FDeg = h->pFDeg();
1005  h->ecart = h->pLDeg() - h->FDeg;
1006  // h->length is set by h->pLDeg
1007  h->length=h->pLength=pLength(h->p);
1008}
1009
1010void initEcartBBA (LObject* h)
1011{
1012  h->FDeg = h->pFDeg();
1013  (*h).ecart = 0;
1014  h->length=h->pLength=pLength(h->p);
1015}
1016
1017void initEcartPairBba (LObject* Lp,poly f,poly g,int ecartF,int ecartG)
1018{
1019  Lp->FDeg = Lp->pFDeg();
1020  (*Lp).ecart = 0;
1021  (*Lp).length = 0;
1022}
1023
1024void initEcartPairMora (LObject* Lp,poly f,poly g,int ecartF,int ecartG)
1025{
1026  Lp->FDeg = Lp->pFDeg();
1027  (*Lp).ecart = si_max(ecartF,ecartG);
1028  (*Lp).ecart = (*Lp).ecart- (Lp->FDeg -pFDeg((*Lp).lcm,currRing));
1029  (*Lp).length = 0;
1030}
1031
1032/*2
1033*if ecart1<=ecart2 it returns TRUE
1034*/
1035static inline BOOLEAN sugarDivisibleBy(int ecart1, int ecart2)
1036{
1037  return (ecart1 <= ecart2);
1038}
1039
1040#ifdef HAVE_RINGS
1041/*2
1042* put the pair (s[i],p)  into the set B, ecart=ecart(p) (ring case)
1043*/
1044void enterOnePairRing (int i,poly p,int ecart, int isFromQ,kStrategy strat, int atR = -1)
1045{
1046  assume(i<=strat->sl);
1047  int      l,j,compare,compareCoeff;
1048  LObject  Lp;
1049
1050  if (strat->interred_flag) return;
1051#ifdef KDEBUG
1052  Lp.ecart=0; Lp.length=0;
1053#endif
1054  /*- computes the lcm(s[i],p) -*/
1055  Lp.lcm = pInit();
1056  pSetCoeff0(Lp.lcm, nLcm(pGetCoeff(p), pGetCoeff(strat->S[i]), currRing));
1057  // Lp.lcm == 0
1058  if (nIsZero(pGetCoeff(Lp.lcm)))
1059  {
1060#ifdef KDEBUG
1061      if (TEST_OPT_DEBUG)
1062      {
1063        PrintS("--- Lp.lcm == 0\n");
1064        PrintS("p:");
1065        wrp(p);
1066        Print("  strat->S[%d]:", i);
1067        wrp(strat->S[i]);
1068        PrintLn();
1069      }
1070#endif
1071      strat->cp++;
1072      pLmDelete(Lp.lcm);
1073      return;
1074  }
1075  // basic product criterion
1076  pLcm(p,strat->S[i],Lp.lcm);
1077  pSetm(Lp.lcm);
1078  assume(!strat->sugarCrit);
1079  if (pHasNotCF(p,strat->S[i]) && nIsUnit(pGetCoeff(p)) && nIsUnit(pGetCoeff(strat->S[i])))
1080  {
1081#ifdef KDEBUG
1082      if (TEST_OPT_DEBUG)
1083      {
1084        PrintS("--- product criterion func enterOnePairRing type 1\n");
1085        PrintS("p:");
1086        wrp(p);
1087        Print("  strat->S[%d]:", i);
1088        wrp(strat->S[i]);
1089        PrintLn();
1090      }
1091#endif
1092      strat->cp++;
1093      pLmDelete(Lp.lcm);
1094      return;
1095  }
1096  assume(!strat->fromT);
1097  /*
1098  *the set B collects the pairs of type (S[j],p)
1099  *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p) != lcm(r,p)
1100  *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
1101  *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
1102  */
1103  for(j = strat->Bl;j>=0;j--)
1104  {
1105    compare=pDivCompRing(strat->B[j].lcm,Lp.lcm);
1106    compareCoeff = nDivComp(pGetCoeff(strat->B[j].lcm), pGetCoeff(Lp.lcm));
1107    if (compareCoeff == 0 || compare == compareCoeff)
1108    {
1109      if (compare == 1)
1110      {
1111        strat->c3++;
1112#ifdef KDEBUG
1113        if (TEST_OPT_DEBUG)
1114        {
1115          PrintS("--- chain criterion type 1\n");
1116          PrintS("strat->B[j]:");
1117          wrp(strat->B[j].lcm);
1118          PrintS("  Lp.lcm:");
1119          wrp(Lp.lcm);
1120          PrintLn();
1121        }
1122#endif
1123        if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1124        {
1125          pLmDelete(Lp.lcm);
1126          return;
1127        }
1128        break;
1129      }
1130      else
1131      if (compare == -1)
1132      {
1133#ifdef KDEBUG
1134        if (TEST_OPT_DEBUG)
1135        {
1136          PrintS("--- chain criterion type 2\n");
1137          Print("strat->B[%d].lcm:",j);
1138          wrp(strat->B[j].lcm);
1139          PrintS("  Lp.lcm:");
1140          wrp(Lp.lcm);
1141          PrintLn();
1142        }
1143#endif
1144        deleteInL(strat->B,&strat->Bl,j,strat);
1145        strat->c3++;
1146      }
1147    }
1148    if ((compare == pDivComp_EQUAL) && (compareCoeff != 2))
1149    {
1150      if (compareCoeff == pDivComp_LESS)
1151      {
1152#ifdef KDEBUG
1153        if (TEST_OPT_DEBUG)
1154        {
1155          PrintS("--- chain criterion type 3\n");
1156          Print("strat->B[%d].lcm:", j);
1157          wrp(strat->B[j].lcm);
1158          PrintS("  Lp.lcm:");
1159          wrp(Lp.lcm);
1160          PrintLn();
1161        }
1162#endif
1163        strat->c3++;
1164        if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1165        {
1166          pLmDelete(Lp.lcm);
1167          return;
1168        }
1169        break;
1170      }
1171      else
1172      // Add hint for same LM and LC (later) (TODO Oliver)
1173      // if (compareCoeff == pDivComp_GREATER)
1174      {
1175#ifdef KDEBUG
1176        if (TEST_OPT_DEBUG)
1177        {
1178          PrintS("--- chain criterion type 4\n");
1179          Print("strat->B[%d].lcm:", j);
1180          wrp(strat->B[j].lcm);
1181          PrintS("  Lp.lcm:");
1182          wrp(Lp.lcm);
1183          PrintLn();
1184        }
1185#endif
1186        deleteInL(strat->B,&strat->Bl,j,strat);
1187        strat->c3++;
1188      }
1189    }
1190  }
1191  /*
1192  *the pair (S[i],p) enters B if the spoly != 0
1193  */
1194  /*-  compute the short s-polynomial -*/
1195  if ((strat->S[i]==NULL) || (p==NULL)) {
1196#ifdef KDEBUG
1197    if (TEST_OPT_DEBUG)
1198    {
1199      PrintS("--- spoly = NULL\n");
1200    }
1201#endif
1202    pLmDelete(Lp.lcm);
1203    return;
1204  }
1205  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (strat->fromQ[i]!=0))
1206  {
1207    // Is from a previous computed GB, therefore we know that spoly will
1208    // reduce to zero. Oliver.
1209    WarnS("Could we come here? 8738947389");
1210    Lp.p=NULL;
1211  }
1212  else
1213  {
1214    Lp.p = ksCreateShortSpoly(strat->S[i], p, strat->tailRing);
1215  }
1216  if (Lp.p == NULL)
1217  {
1218#ifdef KDEBUG
1219    if (TEST_OPT_DEBUG)
1220    {
1221      PrintS("--- spoly = NULL\n");
1222    }
1223#endif
1224    /*- the case that the s-poly is 0 -*/
1225    if (strat->pairtest==NULL) initPairtest(strat);
1226    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
1227    strat->pairtest[strat->sl+1] = TRUE;
1228    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
1229    /*
1230    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
1231    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
1232    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
1233    *term of p devides the lcm(s,r)
1234    *(this canceling should be done here because
1235    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
1236    *the first case is handeled in chainCrit
1237    */
1238    pLmDelete(Lp.lcm);
1239  }
1240  else
1241  {
1242    /*- the pair (S[i],p) enters B -*/
1243    Lp.p1 = strat->S[i];
1244    Lp.p2 = p;
1245
1246    pNext(Lp.p) = strat->tail;
1247
1248    if (atR >= 0)
1249    {
1250      Lp.i_r2 = atR;
1251      Lp.i_r1 = strat->S_2_R[i];
1252    }
1253    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
1254    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
1255    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
1256  }
1257}
1258
1259
1260/*2
1261* put the  lcm(s[i],p)  into the set B
1262*/
1263
1264BOOLEAN enterOneStrongPoly (int i,poly p,int ecart, int isFromQ,kStrategy strat, int atR = -1)
1265{
1266  number d, s, t;
1267  assume(i<=strat->sl);
1268  LObject  Lp;
1269  poly m1, m2, erg, gcd;
1270
1271  d = nExtGcd(pGetCoeff(p), pGetCoeff(strat->S[i]), &s, &t);
1272
1273  if (nIsZero(s) || nIsZero(t))  // evtl. durch divBy tests ersetzen
1274  {
1275    nDelete(&d);
1276    nDelete(&s);
1277    nDelete(&t);
1278    return FALSE;
1279  }
1280
1281  k_GetStrongLeadTerms(p, strat->S[i], currRing, m1, m2, gcd, strat->tailRing);
1282
1283  pSetCoeff0(m1, s);
1284  pSetCoeff0(m2, t);
1285  pSetCoeff0(gcd, d);
1286
1287
1288#ifdef KDEBUG
1289  if (TEST_OPT_DEBUG)
1290  {
1291    Print("t = %d; s = %d; d = %d\n", nInt(t), nInt(s), nInt(d));
1292    PrintS("m1 = ");
1293    p_wrp(m1, strat->tailRing);
1294    PrintS(" ; m2 = ");
1295    p_wrp(m2, strat->tailRing);
1296    PrintS(" ; gcd = ");
1297    wrp(gcd);
1298    PrintS("\n--- create strong gcd poly: ");
1299    Print("\n p: ", i);
1300    wrp(p);
1301    Print("\n strat->S[%d]: ", i);
1302    wrp(strat->S[i]);
1303    PrintS(" ---> ");
1304  }
1305#endif
1306
1307  erg = p_Add_q(pp_Mult_mm(pNext(p), m1, strat->tailRing), pp_Mult_mm(pNext(strat->S[i]), m2, strat->tailRing), strat->tailRing);
1308  pNext(gcd) = erg;
1309  pLmDelete(m1);
1310  pLmDelete(m2);
1311
1312#ifdef KDEBUG
1313    if (TEST_OPT_DEBUG)
1314    {
1315      wrp(gcd);
1316      PrintLn();
1317    }
1318#endif
1319
1320  LObject h;
1321  h.p = gcd;
1322  h.tailRing = strat->tailRing;
1323  int posx;
1324  if (h.p!=NULL)
1325  {
1326    if (TEST_OPT_INTSTRATEGY)
1327    {
1328      h.pCleardenom(); // also does a pContent
1329    }
1330    else
1331    {
1332      h.pNorm();
1333    }
1334    strat->initEcart(&h);
1335    if (strat->Ll==-1)
1336      posx =0;
1337    else
1338      posx = strat->posInL(strat->L,strat->Ll,&h,strat);
1339    h.sev = pGetShortExpVector(h.p);
1340    h.t_p = k_LmInit_currRing_2_tailRing(h.p, strat->tailRing);
1341    if (pNext(p) != NULL)
1342    {
1343      // What does this? (Oliver)
1344      // pShallowCopyDeleteProc p_shallow_copy_delete
1345      //      = pGetShallowCopyDeleteProc(strat->tailRing, new_tailRing);
1346      // pNext(p) = p_shallow_copy_delete(pNext(p),
1347      //              currRing, strat->tailRing, strat->tailRing->PolyBin);
1348    }
1349    enterL(&strat->L,&strat->Ll,&strat->Lmax,h,posx);
1350  }
1351  return TRUE;
1352}
1353#endif
1354
1355/*2
1356* put the pair (s[i],p)  into the set B, ecart=ecart(p)
1357*/
1358
1359
1360void enterOnePair (int i,poly p,int ecart, int isFromQ,kStrategy strat, int atR = -1)
1361{
1362  assume(i<=strat->sl);
1363  if (strat->interred_flag) return;
1364
1365  int      l,j,compare;
1366  LObject  Lp;
1367  Lp.i_r = -1;
1368
1369#ifdef KDEBUG
1370  Lp.ecart=0; Lp.length=0;
1371#endif
1372  /*- computes the lcm(s[i],p) -*/
1373  Lp.lcm = pInit();
1374
1375  pLcm(p,strat->S[i],Lp.lcm);
1376  pSetm(Lp.lcm);
1377
1378#define MYTEST 0
1379
1380#ifdef HAVE_PLURAL
1381  const BOOLEAN bIsPluralRing = rIsPluralRing(currRing);
1382  const BOOLEAN bIsSCA        = rIsSCA(currRing) && strat->z2homog; // for Z_2 prod-crit
1383  const BOOLEAN bNCProdCrit   = ( !bIsPluralRing || bIsSCA ); // commutative or homogeneous SCA
1384
1385#else
1386  const BOOLEAN bIsPluralRing = FALSE;
1387  const BOOLEAN bIsSCA        = FALSE;
1388  const BOOLEAN bNCProdCrit   = TRUE;
1389#endif
1390
1391
1392  if (strat->sugarCrit && bNCProdCrit)
1393  {
1394    if((!((strat->ecartS[i]>0)&&(ecart>0)))
1395    && pHasNotCF(p,strat->S[i]))
1396    {
1397    /*
1398    *the product criterion has applied for (s,p),
1399    *i.e. lcm(s,p)=product of the leading terms of s and p.
1400    *Suppose (s,r) is in L and the leading term
1401    *of p divides lcm(s,r)
1402    *(==> the leading term of p divides the leading term of r)
1403    *but the leading term of s does not divide the leading term of r
1404    *(notice that tis condition is automatically satisfied if r is still
1405    *in S), then (s,r) can be cancelled.
1406    *This should be done here because the
1407    *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
1408    *
1409    *Moreover, skipping (s,r) holds also for the noncommutative case.
1410    */
1411      strat->cp++;
1412      pLmFree(Lp.lcm);
1413      Lp.lcm=NULL;
1414      return;
1415    }
1416    else
1417      Lp.ecart = si_max(ecart,strat->ecartS[i]);
1418    if (strat->fromT && (strat->ecartS[i]>ecart))
1419    {
1420      pLmFree(Lp.lcm);
1421      Lp.lcm=NULL;
1422      return;
1423      /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
1424    }
1425    /*
1426    *the set B collects the pairs of type (S[j],p)
1427    *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
1428    *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
1429    *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
1430    */
1431    {
1432      j = strat->Bl;
1433      loop
1434      {
1435        if (j < 0)  break;
1436        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
1437        if ((compare==1)
1438        &&(sugarDivisibleBy(strat->B[j].ecart,Lp.ecart)))
1439        {
1440          strat->c3++;
1441          if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1442          {
1443            pLmFree(Lp.lcm);
1444            return;
1445          }
1446          break;
1447        }
1448        else
1449        if ((compare ==-1)
1450        && sugarDivisibleBy(Lp.ecart,strat->B[j].ecart))
1451        {
1452          deleteInL(strat->B,&strat->Bl,j,strat);
1453          strat->c3++;
1454        }
1455        j--;
1456      }
1457    }
1458  }
1459  else /*sugarcrit*/
1460  {
1461    if (bNCProdCrit)
1462    {
1463      // if currRing->nc_type!=quasi (or skew)
1464      // TODO: enable productCrit for super commutative algebras...
1465      if(/*(strat->ak==0) && productCrit(p,strat->S[i])*/
1466      pHasNotCF(p,strat->S[i]))
1467      {
1468      /*
1469      *the product criterion has applied for (s,p),
1470      *i.e. lcm(s,p)=product of the leading terms of s and p.
1471      *Suppose (s,r) is in L and the leading term
1472      *of p devides lcm(s,r)
1473      *(==> the leading term of p devides the leading term of r)
1474      *but the leading term of s does not devide the leading term of r
1475      *(notice that tis condition is automatically satisfied if r is still
1476      *in S), then (s,r) can be canceled.
1477      *This should be done here because the
1478      *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
1479      */
1480          strat->cp++;
1481          pLmFree(Lp.lcm);
1482          Lp.lcm=NULL;
1483          return;
1484      }
1485      if (strat->fromT && (strat->ecartS[i]>ecart))
1486      {
1487        pLmFree(Lp.lcm);
1488        Lp.lcm=NULL;
1489        return;
1490        /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
1491      }
1492      /*
1493      *the set B collects the pairs of type (S[j],p)
1494      *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
1495      *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
1496      *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
1497      */
1498      for(j = strat->Bl;j>=0;j--)
1499      {
1500        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
1501        if (compare==1)
1502        {
1503          strat->c3++;
1504          if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1505          {
1506            pLmFree(Lp.lcm);
1507            return;
1508          }
1509          break;
1510        }
1511        else
1512        if (compare ==-1)
1513        {
1514          deleteInL(strat->B,&strat->Bl,j,strat);
1515          strat->c3++;
1516        }
1517      }
1518    }
1519  }
1520  /*
1521  *the pair (S[i],p) enters B if the spoly != 0
1522  */
1523  /*-  compute the short s-polynomial -*/
1524  if (strat->fromT && !TEST_OPT_INTSTRATEGY)
1525    pNorm(p);
1526
1527  if ((strat->S[i]==NULL) || (p==NULL))
1528    return;
1529
1530  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (strat->fromQ[i]!=0))
1531    Lp.p=NULL;
1532  else
1533  {
1534    #ifdef HAVE_PLURAL
1535    if ( bIsPluralRing )
1536    {
1537      if(pHasNotCF(p, strat->S[i]))
1538      {
1539//         if(ncRingType(currRing) == nc_lie)
1540//         {
1541//             // generalized prod-crit for lie-type
1542//             strat->cp++;
1543//             Lp.p = nc_p_Bracket_qq(pCopy(p),strat->S[i]);
1544//         }
1545//         else
1546        if( bIsSCA )
1547        {
1548            // product criterion for homogeneous case in SCA
1549            strat->cp++;
1550            Lp.p = NULL;
1551        }
1552        else
1553          Lp.p = // nc_CreateSpoly(strat->S[i],p,currRing);
1554                 nc_CreateShortSpoly(strat->S[i], p, currRing); 
1555      }
1556      else
1557        Lp.p = // nc_CreateSpoly(strat->S[i],p,currRing);
1558                nc_CreateShortSpoly(strat->S[i], p, currRing); 
1559
1560     
1561#if MYTEST
1562      if (TEST_OPT_DEBUG)
1563      {
1564        PrintS("strat->S[i]: "); pWrite(strat->S[i]);
1565        PrintS("p: "); pWrite(p);
1566        PrintS("SPoly: "); pWrite(Lp.p);
1567      }
1568#endif     
1569     
1570    }
1571    else
1572    #endif
1573    {
1574      assume(!rIsPluralRing(currRing));
1575      Lp.p = ksCreateShortSpoly(strat->S[i], p, strat->tailRing);
1576#if MYTEST
1577      if (TEST_OPT_DEBUG)
1578      {
1579        PrintS("strat->S[i]: "); pWrite(strat->S[i]);
1580        PrintS("p: "); pWrite(p);
1581        PrintS("commutative SPoly: "); pWrite(Lp.p);
1582      }
1583#endif     
1584
1585      }
1586  }
1587  if (Lp.p == NULL)
1588  {
1589    /*- the case that the s-poly is 0 -*/
1590    if (strat->pairtest==NULL) initPairtest(strat);
1591    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
1592    strat->pairtest[strat->sl+1] = TRUE;
1593    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
1594    /*
1595    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
1596    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
1597    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
1598    *term of p devides the lcm(s,r)
1599    *(this canceling should be done here because
1600    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
1601    *the first case is handeled in chainCrit
1602    */
1603    if (Lp.lcm!=NULL) pLmFree(Lp.lcm);
1604  }
1605  else
1606  {
1607    /*- the pair (S[i],p) enters B -*/
1608    Lp.p1 = strat->S[i];
1609    Lp.p2 = p;
1610
1611//    if ( !bIsPluralRing ) // !!!!
1612    assume(pNext(Lp.p)==NULL);
1613    pNext(Lp.p) = strat->tail; // !!!
1614
1615    if (atR >= 0)
1616    {
1617      Lp.i_r1 = strat->S_2_R[i];
1618      Lp.i_r2 = atR;
1619    }
1620    else
1621    {
1622      Lp.i_r1 = -1;
1623      Lp.i_r2 = -1;
1624    }
1625    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
1626
1627    if (TEST_OPT_INTSTRATEGY)
1628    {
1629      if (!bIsPluralRing)
1630        nDelete(&(Lp.p->coef));
1631    }
1632
1633    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
1634    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
1635  }
1636}
1637
1638/*2
1639* put the pair (s[i],p) into the set L, ecart=ecart(p)
1640* in the case that s forms a SB of (s)
1641*/
1642void enterOnePairSpecial (int i,poly p,int ecart,kStrategy strat, int atR = -1)
1643{
1644  //PrintS("try ");wrp(strat->S[i]);PrintS(" and ");wrp(p);PrintLn();
1645  if(pHasNotCF(p,strat->S[i]))
1646  {
1647    //PrintS("prod-crit\n");
1648    #ifdef HAVE_PLURAL
1649    if((!rIsPluralRing(currRing)) || (rIsSCA(currRing) && strat->z2homog))
1650    #endif
1651    {
1652      //PrintS("prod-crit\n");
1653      strat->cp++;
1654      return;
1655    }
1656  }
1657
1658  int      l,j,compare;
1659  LObject  Lp;
1660  Lp.i_r = -1;
1661
1662  Lp.lcm = pInit();
1663  pLcm(p,strat->S[i],Lp.lcm);
1664  pSetm(Lp.lcm);
1665  for(j = strat->Ll;j>=0;j--)
1666  {
1667    compare=pDivComp(strat->L[j].lcm,Lp.lcm);
1668    if ((compare==1) || (pLmEqual(strat->L[j].lcm,Lp.lcm)))
1669    {
1670      //PrintS("c3-crit\n");
1671      strat->c3++;
1672      pLmFree(Lp.lcm);
1673      return;
1674    }
1675    else if (compare ==-1)
1676    {
1677      //Print("c3-crit with L[%d]\n",j);
1678      deleteInL(strat->L,&strat->Ll,j,strat);
1679      strat->c3++;
1680    }
1681  }
1682  /*-  compute the short s-polynomial -*/
1683
1684  #ifdef HAVE_PLURAL
1685  if (rIsPluralRing(currRing))
1686  {
1687    Lp.p = nc_CreateShortSpoly(strat->S[i],p); // ??? strat->tailRing?
1688  }
1689  else
1690  #endif
1691    Lp.p = ksCreateShortSpoly(strat->S[i],p,strat->tailRing);
1692
1693  if (Lp.p == NULL)
1694  {
1695     //PrintS("short spoly==NULL\n");
1696     pLmFree(Lp.lcm);
1697  }
1698  else
1699  {
1700    /*- the pair (S[i],p) enters L -*/
1701    Lp.p1 = strat->S[i];
1702    Lp.p2 = p;
1703    if (atR >= 0)
1704    {
1705      Lp.i_r1 = strat->S_2_R[i];
1706      Lp.i_r2 = atR;
1707    }
1708    else
1709    {
1710      Lp.i_r1 = -1;
1711      Lp.i_r2 = -1;
1712    }
1713    assume(pNext(Lp.p) == NULL);
1714    pNext(Lp.p) = strat->tail;
1715    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
1716    if (TEST_OPT_INTSTRATEGY)
1717    {
1718      nDelete(&(Lp.p->coef));
1719    }
1720    l = strat->posInL(strat->L,strat->Ll,&Lp,strat);
1721    //Print("-> L[%d]\n",l);
1722    enterL(&strat->L,&strat->Ll,&strat->Lmax,Lp,l);
1723  }
1724}
1725
1726/*2
1727*the pairset B of pairs of type (s[i],p) is complete now. It will be updated
1728*using the chain-criterion in B and L and enters B to L
1729*/
1730void chainCrit (poly p,int ecart,kStrategy strat)
1731{
1732  int i,j,l;
1733
1734  /*
1735  *pairtest[i] is TRUE if spoly(S[i],p) == 0.
1736  *In this case all elements in B such
1737  *that their lcm is divisible by the leading term of S[i] can be canceled
1738  */
1739  if (strat->pairtest!=NULL)
1740  {
1741    {
1742      /*- i.e. there is an i with pairtest[i]==TRUE -*/
1743      for (j=0; j<=strat->sl; j++)
1744      {
1745        if (strat->pairtest[j])
1746        {
1747          for (i=strat->Bl; i>=0; i--)
1748          {
1749            if (pDivisibleBy(strat->S[j],strat->B[i].lcm))
1750            {
1751              deleteInL(strat->B,&strat->Bl,i,strat);
1752              strat->c3++;
1753            }
1754          }
1755        }
1756      }
1757    }
1758    omFreeSize(strat->pairtest,(strat->sl+2)*sizeof(BOOLEAN));
1759    strat->pairtest=NULL;
1760  }
1761  if (strat->Gebauer || strat->fromT)
1762  {
1763    if (strat->sugarCrit)
1764    {
1765    /*
1766    *suppose L[j] == (s,r) and p/lcm(s,r)
1767    *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
1768    *and in case the sugar is o.k. then L[j] can be canceled
1769    */
1770      for (j=strat->Ll; j>=0; j--)
1771      {
1772        if (sugarDivisibleBy(ecart,strat->L[j].ecart)
1773        && ((pNext(strat->L[j].p) == strat->tail) || (pOrdSgn==1))
1774        && pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1775        {
1776          if (strat->L[j].p == strat->tail)
1777          {
1778              deleteInL(strat->L,&strat->Ll,j,strat);
1779              strat->c3++;
1780          }
1781        }
1782      }
1783      /*
1784      *this is GEBAUER-MOELLER:
1785      *in B all elements with the same lcm except the "best"
1786      *(i.e. the last one in B with this property) will be canceled
1787      */
1788      j = strat->Bl;
1789      loop /*cannot be changed into a for !!! */
1790      {
1791        if (j <= 0) break;
1792        i = j-1;
1793        loop
1794        {
1795          if (i <  0) break;
1796          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
1797          {
1798            strat->c3++;
1799            if (sugarDivisibleBy(strat->B[j].ecart,strat->B[i].ecart))
1800            {
1801              deleteInL(strat->B,&strat->Bl,i,strat);
1802              j--;
1803            }
1804            else
1805            {
1806              deleteInL(strat->B,&strat->Bl,j,strat);
1807              break;
1808            }
1809          }
1810          i--;
1811        }
1812        j--;
1813      }
1814    }
1815    else /*sugarCrit*/
1816    {
1817      /*
1818      *suppose L[j] == (s,r) and p/lcm(s,r)
1819      *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
1820      *and in case the sugar is o.k. then L[j] can be canceled
1821      */
1822      for (j=strat->Ll; j>=0; j--)
1823      {
1824        if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1825        {
1826          if ((pNext(strat->L[j].p) == strat->tail)||(pOrdSgn==1))
1827          {
1828            deleteInL(strat->L,&strat->Ll,j,strat);
1829            strat->c3++;
1830          }
1831        }
1832      }
1833      /*
1834      *this is GEBAUER-MOELLER:
1835      *in B all elements with the same lcm except the "best"
1836      *(i.e. the last one in B with this property) will be canceled
1837      */
1838      j = strat->Bl;
1839      loop   /*cannot be changed into a for !!! */
1840      {
1841        if (j <= 0) break;
1842        for(i=j-1; i>=0; i--)
1843        {
1844          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
1845          {
1846            strat->c3++;
1847            deleteInL(strat->B,&strat->Bl,i,strat);
1848            j--;
1849          }
1850        }
1851        j--;
1852      }
1853    }
1854    /*
1855    *the elements of B enter L/their order with respect to B is kept
1856    *j = posInL(L,j,B[i]) would permutate the order
1857    *if once B is ordered different from L
1858    *then one should use j = posInL(L,Ll,B[i])
1859    */
1860    j = strat->Ll+1;
1861    for (i=strat->Bl; i>=0; i--)
1862    {
1863      j = strat->posInL(strat->L,j-1,&(strat->B[i]),strat);
1864      enterL(&strat->L,&strat->Ll,&strat->Lmax,strat->B[i],j);
1865    }
1866    strat->Bl = -1;
1867  }
1868  else
1869  {
1870    for (j=strat->Ll; j>=0; j--)
1871    {
1872      if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1873      {
1874        if ((pNext(strat->L[j].p) == strat->tail)||(pOrdSgn==1))
1875        {
1876          deleteInL(strat->L,&strat->Ll,j,strat);
1877          strat->c3++;
1878        }
1879      }
1880    }
1881    /*
1882    *this is our MODIFICATION of GEBAUER-MOELLER:
1883    *First the elements of B enter L,
1884    *then we fix a lcm and the "best" element in L
1885    *(i.e the last in L with this lcm and of type (s,p))
1886    *and cancel all the other elements of type (r,p) with this lcm
1887    *except the case the element (s,r) has also the same lcm
1888    *and is on the worst position with respect to (s,p) and (r,p)
1889    */
1890    /*
1891    *B enters to L/their order with respect to B is permutated for elements
1892    *B[i].p with the same leading term
1893    */
1894    j = strat->Ll;
1895    for (i=strat->Bl; i>=0; i--)
1896    {
1897      j = strat->posInL(strat->L,j,&(strat->B[i]),strat);
1898      enterL(&strat->L,&strat->Ll,&strat->Lmax,strat->B[i],j);
1899    }
1900    strat->Bl = -1;
1901    j = strat->Ll;
1902    loop  /*cannot be changed into a for !!! */
1903    {
1904      if (j <= 0)
1905      {
1906        /*now L[0] cannot be canceled any more and the tail can be removed*/
1907        if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
1908        break;
1909      }
1910      if (strat->L[j].p2 == p)
1911      {
1912        i = j-1;
1913        loop
1914        {
1915          if (i < 0)  break;
1916          if ((strat->L[i].p2 == p) && pLmEqual(strat->L[j].lcm,strat->L[i].lcm))
1917          {
1918            /*L[i] could be canceled but we search for a better one to cancel*/
1919            strat->c3++;
1920            if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
1921            && (pNext(strat->L[l].p) == strat->tail)
1922            && (!pLmEqual(strat->L[i].p,strat->L[l].p))
1923            && pDivisibleBy(p,strat->L[l].lcm))
1924            {
1925              /*
1926              *"NOT equal(...)" because in case of "equal" the element L[l]
1927              *is "older" and has to be from theoretical point of view behind
1928              *L[i], but we do not want to reorder L
1929              */
1930              strat->L[i].p2 = strat->tail;
1931              /*
1932              *L[l] will be canceled, we cannot cancel L[i] later on,
1933              *so we mark it with "tail"
1934              */
1935              deleteInL(strat->L,&strat->Ll,l,strat);
1936              i--;
1937            }
1938            else
1939            {
1940              deleteInL(strat->L,&strat->Ll,i,strat);
1941            }
1942            j--;
1943          }
1944          i--;
1945        }
1946      }
1947      else if (strat->L[j].p2 == strat->tail)
1948      {
1949        /*now L[j] cannot be canceled any more and the tail can be removed*/
1950        strat->L[j].p2 = p;
1951      }
1952      j--;
1953    }
1954  }
1955}
1956
1957/*2
1958*(s[0],h),...,(s[k],h) will be put to the pairset L
1959*/
1960void initenterpairs (poly h,int k,int ecart,int isFromQ,kStrategy strat, int atR = -1)
1961{
1962
1963  if ((strat->syzComp==0)
1964  || (pGetComp(h)<=strat->syzComp))
1965  {
1966    int j;
1967    BOOLEAN new_pair=FALSE;
1968
1969    if (pGetComp(h)==0)
1970    {
1971      /* for Q!=NULL: build pairs (f,q),(f1,f2), but not (q1,q2)*/
1972      if ((isFromQ)&&(strat->fromQ!=NULL))
1973      {
1974        for (j=0; j<=k; j++)
1975        {
1976          if (!strat->fromQ[j])
1977          {
1978            new_pair=TRUE;
1979            enterOnePair(j,h,ecart,isFromQ,strat, atR);
1980          //Print("j:%d, Ll:%d\n",j,strat->Ll);
1981          }
1982        }
1983      }
1984      else
1985      {
1986        new_pair=TRUE;
1987        for (j=0; j<=k; j++)
1988        {
1989          enterOnePair(j,h,ecart,isFromQ,strat, atR);
1990          //Print("j:%d, Ll:%d\n",j,strat->Ll);
1991        }
1992      }
1993    }
1994    else
1995    {
1996      for (j=0; j<=k; j++)
1997      {
1998        if ((pGetComp(h)==pGetComp(strat->S[j]))
1999        || (pGetComp(strat->S[j])==0))
2000        {
2001          new_pair=TRUE;
2002          enterOnePair(j,h,ecart,isFromQ,strat, atR);
2003        //Print("j:%d, Ll:%d\n",j,strat->Ll);
2004        }
2005      }
2006    }
2007
2008    if (new_pair) chainCrit(h,ecart,strat);
2009
2010  }
2011}
2012
2013#ifdef HAVE_RINGS
2014/*2
2015*the pairset B of pairs of type (s[i],p) is complete now. It will be updated
2016*using the chain-criterion in B and L and enters B to L
2017*/
2018void chainCritRing (poly p,int ecart,kStrategy strat)
2019{
2020  int i,j,l;
2021  /*
2022  *pairtest[i] is TRUE if spoly(S[i],p) == 0.
2023  *In this case all elements in B such
2024  *that their lcm is divisible by the leading term of S[i] can be canceled
2025  */
2026  if (strat->pairtest!=NULL)
2027  {
2028    {
2029      /*- i.e. there is an i with pairtest[i]==TRUE -*/
2030      for (j=0; j<=strat->sl; j++)
2031      {
2032        if (strat->pairtest[j])
2033        {
2034          for (i=strat->Bl; i>=0; i--)
2035          {
2036            if (pDivisibleBy(strat->S[j],strat->B[i].lcm))
2037            {
2038#ifdef KDEBUG
2039              if (TEST_OPT_DEBUG)
2040              {
2041                PrintS("--- chain criterion func chainCritRing type 1\n");
2042                PrintS("strat->S[j]:");
2043                wrp(strat->S[j]);
2044                PrintS("  strat->B[i].lcm:");
2045                wrp(strat->B[i].lcm);
2046                PrintLn();
2047              }
2048#endif
2049              deleteInL(strat->B,&strat->Bl,i,strat);
2050              strat->c3++;
2051            }
2052          }
2053        }
2054      }
2055    }
2056    omFreeSize(strat->pairtest,(strat->sl+2)*sizeof(BOOLEAN));
2057    strat->pairtest=NULL;
2058  }
2059  assume(!(strat->Gebauer || strat->fromT));
2060  for (j=strat->Ll; j>=0; j--)
2061  {
2062    if (strat->L[j].lcm != NULL && nDivBy(pGetCoeff(strat->L[j].lcm), pGetCoeff(p)))
2063    {
2064      if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
2065      {
2066        if ((pNext(strat->L[j].p) == strat->tail) || (pOrdSgn==1))
2067        {
2068          deleteInL(strat->L,&strat->Ll,j,strat);
2069          strat->c3++;
2070#ifdef KDEBUG
2071              if (TEST_OPT_DEBUG)
2072              {
2073                PrintS("--- chain criterion func chainCritRing type 2\n");
2074                PrintS("strat->L[j].p:");
2075                wrp(strat->L[j].p);
2076                PrintS("  p:");
2077                wrp(p);
2078                PrintLn();
2079              }
2080#endif
2081        }
2082      }
2083    }
2084  }
2085  /*
2086  *this is our MODIFICATION of GEBAUER-MOELLER:
2087  *First the elements of B enter L,
2088  *then we fix a lcm and the "best" element in L
2089  *(i.e the last in L with this lcm and of type (s,p))
2090  *and cancel all the other elements of type (r,p) with this lcm
2091  *except the case the element (s,r) has also the same lcm
2092  *and is on the worst position with respect to (s,p) and (r,p)
2093  */
2094  /*
2095  *B enters to L/their order with respect to B is permutated for elements
2096  *B[i].p with the same leading term
2097  */
2098  j = strat->Ll;
2099  for (i=strat->Bl; i>=0; i--)
2100  {
2101    j = strat->posInL(strat->L,j,&(strat->B[i]),strat);
2102    enterL(&strat->L,&strat->Ll,&strat->Lmax,strat->B[i],j);
2103  }
2104  strat->Bl = -1;
2105  j = strat->Ll;
2106  loop  /*cannot be changed into a for !!! */
2107  {
2108    if (j <= 0)
2109    {
2110      /*now L[0] cannot be canceled any more and the tail can be removed*/
2111      if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
2112      break;
2113    }
2114    if (strat->L[j].p2 == p) // Was the element added from B?
2115    {
2116      i = j-1;
2117      loop
2118      {
2119        if (i < 0)  break;
2120        // Element is from B and has the same lcm as L[j]
2121        if ((strat->L[i].p2 == p) && nDivBy(pGetCoeff(strat->L[j].lcm), pGetCoeff(strat->L[i].lcm))
2122             && pLmEqual(strat->L[j].lcm,strat->L[i].lcm))
2123        {
2124          /*L[i] could be canceled but we search for a better one to cancel*/
2125          strat->c3++;
2126#ifdef KDEBUG
2127          if (TEST_OPT_DEBUG)
2128          {
2129            PrintS("--- chain criterion func chainCritRing type 3\n");
2130            PrintS("strat->L[j].lcm:");
2131            wrp(strat->L[j].lcm);
2132            PrintS("  strat->L[i].lcm:");
2133            wrp(strat->L[i].lcm);
2134            PrintLn();
2135          }
2136#endif
2137          if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
2138          && (pNext(strat->L[l].p) == strat->tail)
2139          && (!pLmEqual(strat->L[i].p,strat->L[l].p))
2140          && pDivisibleBy(p,strat->L[l].lcm))
2141          {
2142            /*
2143            *"NOT equal(...)" because in case of "equal" the element L[l]
2144            *is "older" and has to be from theoretical point of view behind
2145            *L[i], but we do not want to reorder L
2146            */
2147            strat->L[i].p2 = strat->tail;
2148            /*
2149            *L[l] will be canceled, we cannot cancel L[i] later on,
2150            *so we mark it with "tail"
2151            */
2152            deleteInL(strat->L,&strat->Ll,l,strat);
2153            i--;
2154          }
2155          else
2156          {
2157            deleteInL(strat->L,&strat->Ll,i,strat);
2158          }
2159          j--;
2160        }
2161        i--;
2162      }
2163    }
2164    else if (strat->L[j].p2 == strat->tail)
2165    {
2166      /*now L[j] cannot be canceled any more and the tail can be removed*/
2167      strat->L[j].p2 = p;
2168    }
2169    j--;
2170  }
2171}
2172#endif
2173
2174#ifdef HAVE_RING2TOM
2175long ind2(long arg)
2176{
2177  long ind = 0;
2178  if (arg <= 0) return 0;
2179  while (arg%2 == 0)
2180  {
2181    arg = arg / 2;
2182    ind++;
2183  }
2184  return ind;
2185}
2186
2187long ind_fact_2(long arg)
2188{
2189  long ind = 0;
2190  if (arg <= 0) return 0;
2191  if (arg%2 == 1) { arg--; }
2192  while (arg > 0)
2193  {
2194    ind += ind2(arg);
2195    arg = arg - 2;
2196  }
2197  return ind;
2198}
2199#endif
2200
2201#ifdef HAVE_VANIDEAL
2202long twoPow(long arg)
2203{
2204  return 1L << arg;
2205}
2206
2207/*2
2208* put the pair (p, f) in B and f in T
2209*/
2210void enterOneZeroPairRing (poly f, poly t_p, poly p, int ecart, kStrategy strat, int atR = -1)
2211{
2212  int      l,j,compare,compareCoeff;
2213  LObject  Lp;
2214
2215  if (strat->interred_flag) return;
2216#ifdef KDEBUG
2217  Lp.ecart=0; Lp.length=0;
2218#endif
2219  /*- computes the lcm(s[i],p) -*/
2220  Lp.lcm = pInit();
2221
2222  pLcm(p,f,Lp.lcm);
2223  pSetm(Lp.lcm);
2224  pSetCoeff(Lp.lcm, nLcm(pGetCoeff(p), pGetCoeff(f), currRing));
2225  assume(!strat->sugarCrit);
2226  assume(!strat->fromT);
2227  /*
2228  *the set B collects the pairs of type (S[j],p)
2229  *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p) != lcm(r,p)
2230  *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
2231  *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
2232  */
2233  for(j = strat->Bl;j>=0;j--)
2234  {
2235    compare=pDivCompRing(strat->B[j].lcm,Lp.lcm);
2236    compareCoeff = nDivComp(pGetCoeff(strat->B[j].lcm), pGetCoeff(Lp.lcm));
2237    if (compareCoeff == 0 || compare == compareCoeff)
2238    {
2239      if (compare == 1)
2240      {
2241        strat->c3++;
2242        pLmDelete(Lp.lcm);
2243        return;
2244      }
2245      else
2246      if (compare == -1)
2247      {
2248        deleteInL(strat->B,&strat->Bl,j,strat);
2249        strat->c3++;
2250      }
2251    }
2252    if (compare == pDivComp_EQUAL)
2253    {
2254      // Add hint for same LM and direction of LC (later) (TODO Oliver)
2255      if (compareCoeff == 1)
2256      {
2257        strat->c3++;
2258        pLmDelete(Lp.lcm);
2259        return;
2260      }
2261      else
2262      if (compareCoeff == -1)
2263      {
2264        deleteInL(strat->B,&strat->Bl,j,strat);
2265        strat->c3++;
2266      }
2267    }
2268  }
2269  /*
2270  *the pair (S[i],p) enters B if the spoly != 0
2271  */
2272  /*-  compute the short s-polynomial -*/
2273  if ((f==NULL) || (p==NULL)) return;
2274  pNorm(p);
2275  {
2276    Lp.p = ksCreateShortSpoly(f, p, strat->tailRing);
2277  }
2278  if (Lp.p == NULL) //deactivated, as we are adding pairs with zeropoly and not from S
2279  {
2280    /*- the case that the s-poly is 0 -*/
2281//    if (strat->pairtest==NULL) initPairtest(strat);
2282//    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
2283//    strat->pairtest[strat->sl+1] = TRUE;
2284    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
2285    /*
2286    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
2287    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
2288    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
2289    *term of p devides the lcm(s,r)
2290    *(this canceling should be done here because
2291    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
2292    *the first case is handeled in chainCrit
2293    */
2294    if (Lp.lcm!=NULL) pLmDelete(Lp.lcm);
2295  }
2296  else
2297  {
2298    /*- the pair (S[i],p) enters B -*/
2299    Lp.p1 = f;
2300    Lp.p2 = p;
2301
2302    pNext(Lp.p) = strat->tail;
2303
2304    LObject tmp_h(f, currRing, strat->tailRing);
2305    tmp_h.SetShortExpVector();
2306    strat->initEcart(&tmp_h);
2307    tmp_h.sev = pGetShortExpVector(tmp_h.p);
2308    tmp_h.t_p = t_p;
2309
2310    enterT(tmp_h, strat, strat->tl + 1);
2311
2312    if (atR >= 0)
2313    {
2314      Lp.i_r2 = atR;
2315      Lp.i_r1 = strat->tl;
2316    }
2317
2318    strat->initEcartPair(&Lp,f,p,0/*strat->ecartS[i]*/,ecart);     // Attention: TODO: break ecart
2319    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
2320    enterL(&strat->B, &strat->Bl, &strat->Bmax, Lp, l);
2321  }
2322}
2323
2324/* Helper for kCreateZeroPoly
2325 * enumerating the exponents
2326ring r = 2^2, (a, b, c), lp; ideal G0 = system("createG0"); ideal G = interred(G0); ncols(G0); ncols(G);
2327 */
2328
2329int nextZeroSimplexExponent (long exp[], long ind[], long cexp[], long cind[], long* cabsind, long step[], long bound, long N)
2330/* gives the next exponent from the set H_1 */
2331{
2332  long add = ind2(cexp[1] + 2);
2333  if ((*cabsind < bound) && (*cabsind - step[1] + add < bound))
2334  {
2335    cexp[1] += 2;
2336    cind[1] += add;
2337    *cabsind += add;
2338  }
2339  else
2340  {
2341    // cabsind >= habsind
2342    if (N == 1) return 0;
2343    int i = 1;
2344    while (exp[i] == cexp[i] && i <= N) i++;
2345    cexp[i] = exp[i];
2346    *cabsind -= cind[i];
2347    cind[i] = ind[i];
2348    step[i] = 500000;
2349    *cabsind += cind[i];
2350    // Print("in: %d\n", *cabsind);
2351    i += 1;
2352    if (i > N) return 0;
2353    do
2354    {
2355      step[1] = 500000;
2356      for (int j = i + 1; j <= N; j++)
2357      {
2358        if (step[1] > step[j]) step[1] = step[j];
2359      }
2360      add = ind2(cexp[i] + 2);
2361      if (*cabsind - step[1] + add >= bound)
2362      {
2363        cexp[i] = exp[i];
2364        *cabsind -= cind[i];
2365        cind[i] = ind[i];
2366        *cabsind += cind[i];
2367        step[i] = 500000;
2368        i += 1;
2369        if (i > N) return 0;
2370      }
2371      else step[1] = -1;
2372    } while (step[1] != -1);
2373    step[1] = 500000;
2374    cexp[i] += 2;
2375    cind[i] += add;
2376    *cabsind += add;
2377    if (add < step[i]) step[i] = add;
2378    for (i = 2; i <= N; i++)
2379    {
2380      if (step[1] > step[i]) step[1] = step[i];
2381    }
2382  }
2383  return 1;
2384}
2385
2386/*
2387 * Creates the zero Polynomial on position exp
2388 * long exp[] : exponent of leading term
2389 * cabsind    : total 2-ind of exp (if -1 will be computed)
2390 * poly* t_p  : will hold the LT in tailRing
2391 * leadRing   : ring for the LT
2392 * tailRing   : ring for the tail
2393 */
2394
2395poly kCreateZeroPoly(long exp[], long cabsind, poly* t_p, ring leadRing, ring tailRing)
2396{
2397
2398  poly zeroPoly = NULL;
2399
2400  number tmp1;
2401  poly tmp2, tmp3;
2402
2403  if (cabsind == -1)
2404  {
2405    cabsind = 0;
2406    for (int i = 1; i <= leadRing->N; i++)
2407    {
2408      cabsind += ind_fact_2(exp[i]);
2409    }
2410//    Print("cabsind: %d\n", cabsind);
2411  }
2412  if (cabsind < leadRing->ch)
2413  {
2414    zeroPoly = p_ISet(twoPow(leadRing->ch - cabsind), tailRing);
2415  }
2416  else
2417  {
2418    zeroPoly = p_ISet(1, tailRing);
2419  }
2420  for (int i = 1; i <= leadRing->N; i++)
2421  {
2422    for (long j = 1; j <= exp[i]; j++)
2423    {
2424      tmp1 = nInit(j);
2425      tmp2 = p_ISet(1, tailRing);
2426      p_SetExp(tmp2, i, 1, tailRing);
2427      p_Setm(tmp2, tailRing);
2428      if (nIsZero(tmp1))
2429      { // should nowbe obsolet, test ! TODO OLIVER
2430        zeroPoly = p_Mult_q(zeroPoly, tmp2, tailRing);
2431      }
2432      else
2433      {
2434        tmp3 = p_NSet(nCopy(tmp1), tailRing);
2435        zeroPoly = p_Mult_q(zeroPoly, p_Add_q(tmp3, tmp2, tailRing), tailRing);
2436      }
2437    }
2438  }
2439  tmp2 = p_NSet(nCopy(pGetCoeff(zeroPoly)), leadRing);
2440  for (int i = 1; i <= leadRing->N; i++)
2441  {
2442    pSetExp(tmp2, i, p_GetExp(zeroPoly, i, tailRing));
2443  }
2444  p_Setm(tmp2, leadRing);
2445  *t_p = zeroPoly;
2446  zeroPoly = pNext(zeroPoly);
2447  pNext(*t_p) = NULL;
2448  pNext(tmp2) = zeroPoly;
2449  return tmp2;
2450}
2451
2452// #define OLI_DEBUG
2453
2454/*
2455 * Generate the s-polynomial for the virtual set of zero-polynomials
2456 */
2457
2458void initenterzeropairsRing (poly p, int ecart, kStrategy strat, int atR)
2459{
2460  // Initialize
2461  long exp[50];            // The exponent of \hat{X} (basepoint)
2462  long cexp[50];           // The current exponent for iterating over all
2463  long ind[50];            // The power of 2 in the i-th component of exp
2464  long cind[50];           // analog for cexp
2465  long mult[50];           // How to multiply the elements of G
2466  long cabsind = 0;        // The abs. index of cexp, i.e. the sum of cind
2467  long habsind = 0;        // The abs. index of the coefficient of h
2468  long step[50];           // The last increases
2469  for (int i = 1; i <= currRing->N; i++)
2470  {
2471    exp[i] = p_GetExp(p, i, currRing);
2472    if (exp[i] & 1 != 0)
2473    {
2474      exp[i] = exp[i] - 1;
2475      mult[i] = 1;
2476    }
2477    cexp[i] = exp[i];
2478    ind[i] = ind_fact_2(exp[i]);
2479    cabsind += ind[i];
2480    cind[i] = ind[i];
2481    step[i] = 500000;
2482  }
2483  step[1] = 500000;
2484  habsind = ind2((long) p_GetCoeff(p, currRing));
2485  long bound = currRing->ch - habsind;
2486#ifdef OLI_DEBUG
2487  PrintS("-------------\npoly  :");
2488  wrp(p);
2489  Print("\nexp   : (%d, %d)\n", exp[1] + mult[1], exp[2] + mult[1]);
2490  Print("cexp  : (%d, %d)\n", cexp[1], cexp[2]);
2491  Print("cind  : (%d, %d)\n", cind[1], cind[2]);
2492  Print("bound : %d\n", bound);
2493  Print("cind  : %d\n", cabsind);
2494#endif
2495  if (cabsind == 0)
2496  {
2497    if (!(nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N)))
2498    {
2499      return;
2500    }
2501  }
2502  // Now the whole simplex
2503  do
2504  {
2505    // Build s-polynomial
2506    // 2**ind-def * mult * g - exp-def * h
2507    poly t_p;
2508    poly zeroPoly = kCreateZeroPoly(cexp, cabsind, &t_p, currRing, strat->tailRing);
2509#ifdef OLI_DEBUG
2510    Print("%d, (%d, %d), ind = (%d, %d)\n", cabsind, cexp[1], cexp[2], cind[1], cind[2]);
2511    Print("zPoly : ");
2512    wrp(zeroPoly);
2513    Print("\n");
2514#endif
2515    enterOneZeroPairRing(zeroPoly, t_p, p, ecart, strat, atR);
2516  }
2517  while ( nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N) );
2518}
2519
2520/*
2521 * Create the Groebner basis of the vanishing polynomials.
2522 */
2523
2524ideal createG0()
2525{
2526  // Initialize
2527  long exp[50];            // The exponent of \hat{X} (basepoint)
2528  long cexp[50];           // The current exponent for iterating over all
2529  long ind[50];            // The power of 2 in the i-th component of exp
2530  long cind[50];           // analog for cexp
2531  long mult[50];           // How to multiply the elements of G
2532  long cabsind = 0;        // The abs. index of cexp, i.e. the sum of cind
2533  long habsind = 0;        // The abs. index of the coefficient of h
2534  long step[50];           // The last increases
2535  for (int i = 1; i <= currRing->N; i++)
2536  {
2537    exp[i] = 0;
2538    cexp[i] = exp[i];
2539    ind[i] = 0;
2540    step[i] = 500000;
2541    cind[i] = ind[i];
2542  }
2543  long bound = currRing->ch;
2544  step[1] = 500000;
2545#ifdef OLI_DEBUG
2546  PrintS("-------------\npoly  :");
2547//  wrp(p);
2548  Print("\nexp   : (%d, %d)\n", exp[1] + mult[1], exp[2] + mult[1]);
2549  Print("cexp  : (%d, %d)\n", cexp[1], cexp[2]);
2550  Print("cind  : (%d, %d)\n", cind[1], cind[2]);
2551  Print("bound : %d\n", bound);
2552  Print("cind  : %d\n", cabsind);
2553#endif
2554  if (cabsind == 0)
2555  {
2556    if (!(nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N)))
2557    {
2558      return idInit(1, 1);
2559    }
2560  }
2561  ideal G0 = idInit(1, 1);
2562  // Now the whole simplex
2563  do
2564  {
2565    // Build s-polynomial
2566    // 2**ind-def * mult * g - exp-def * h
2567    poly t_p;
2568    poly zeroPoly = kCreateZeroPoly(cexp, cabsind, &t_p, currRing, currRing);
2569#ifdef OLI_DEBUG
2570    Print("%d, (%d, %d), ind = (%d, %d)\n", cabsind, cexp[1], cexp[2], cind[1], cind[2]);
2571    Print("zPoly : ");
2572    wrp(zeroPoly);
2573    Print("\n");
2574#endif
2575    // Add to ideal
2576    pEnlargeSet(&(G0->m), IDELEMS(G0), 1);
2577    IDELEMS(G0) += 1;
2578    G0->m[IDELEMS(G0) - 1] = zeroPoly;
2579  }
2580  while ( nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N) );
2581  idSkipZeroes(G0);
2582  return G0;
2583}
2584#endif
2585
2586#ifdef HAVE_RINGS
2587/*2
2588*(s[0],h),...,(s[k],h) will be put to the pairset L
2589*/
2590void initenterpairsRing (poly h,int k,int ecart,int isFromQ,kStrategy strat, int atR = -1)
2591{
2592
2593  if ((strat->syzComp==0) || (pGetComp(h)<=strat->syzComp))
2594  {
2595    int j;
2596    BOOLEAN new_pair=FALSE;
2597
2598    if (pGetComp(h)==0)
2599    {
2600      /* for Q!=NULL: build pairs (f,q),(f1,f2), but not (q1,q2)*/
2601      if ((isFromQ)&&(strat->fromQ!=NULL))
2602      {
2603        for (j=0; j<=k; j++)
2604        {
2605          if (!strat->fromQ[j])
2606          {
2607            new_pair=TRUE;
2608            Print("TODO Oliver --- j:%d, Ll:%d\n",j,strat->Ll);
2609            enterOnePairRing(j,h,ecart,isFromQ,strat, atR);
2610          }
2611        }
2612      }
2613      else
2614      {
2615        new_pair=TRUE;
2616        for (j=0; j<=k; j++)
2617        {
2618          // Print("j:%d, Ll:%d\n",j,strat->Ll);
2619          enterOnePairRing(j,h,ecart,isFromQ,strat, atR);
2620        }
2621      }
2622    }
2623    else
2624    {
2625      for (j=0; j<=k; j++)
2626      {
2627        if ((pGetComp(h)==pGetComp(strat->S[j])) || (pGetComp(strat->S[j])==0))
2628        {
2629          new_pair=TRUE;
2630          Print("TODO Oliver --- j:%d, Ll:%d\n",j,strat->Ll);
2631          enterOnePairRing(j,h,ecart,isFromQ,strat, atR);
2632        }
2633      }
2634    }
2635
2636#ifdef HAVE_VANGB
2637    // initenterzeropairsRing(h, ecart, strat, atR);
2638#endif
2639
2640    if (new_pair) chainCritRing(h,ecart,strat);
2641
2642  }
2643/*
2644ring r=256,(x,y,z),dp;
2645ideal I=12xz-133y, 2xy-z;
2646*/
2647
2648}
2649
2650/*2
2651*(s[0],h),...,(s[k],h) will be put to the pairset L
2652*/
2653void initenterstrongPairs (poly h,int k,int ecart,int isFromQ,kStrategy strat, int atR = -1)
2654{
2655
2656  if (!nIsOne(pGetCoeff(h)))
2657  {
2658    int j;
2659    BOOLEAN new_pair=FALSE;
2660
2661    for (j=0; j<=k; j++)
2662    {
2663      // Print("j:%d, Ll:%d\n",j,strat->Ll);
2664//      if (((unsigned long) pGetCoeff(h) % (unsigned long) pGetCoeff(strat->S[j]) != 0) &&
2665//         ((unsigned long) pGetCoeff(strat->S[j]) % (unsigned long) pGetCoeff(h) != 0))
2666      {
2667        if (enterOneStrongPoly(j,h,ecart,isFromQ,strat, atR))
2668          new_pair=TRUE;
2669      }
2670    }
2671  }
2672/*
2673ring r=256,(x,y,z),dp;
2674ideal I=12xz-133y, 2xy-z;
2675*/
2676
2677}
2678
2679/*2
2680* Generates spoly(0, h) if applicable. Assumes ring in Z/2^n.
2681*/
2682void enterExtendedSpoly(poly h,kStrategy strat)
2683{
2684  if (nIsOne(pGetCoeff(h))) return;
2685  number gcd;
2686  bool go = false;
2687  if (nDivBy((number) 0, pGetCoeff(h)))
2688  {
2689    gcd = nIntDiv((number) 0, pGetCoeff(h));
2690    go = true;
2691  }
2692  else
2693    gcd = nGcd((number) 0, pGetCoeff(h), strat->tailRing);
2694  if (go || !nIsOne(gcd))
2695  {
2696    poly p = h->next;
2697    if (!go)
2698    {
2699      number tmp = gcd;
2700      gcd = nIntDiv(0, gcd);
2701      nDelete(&tmp);
2702    }
2703    p = pp_Mult_nn(p, gcd, strat->tailRing);
2704    nDelete(&gcd);
2705
2706    if (p != NULL)
2707    {
2708      if (TEST_OPT_PROT)
2709      {
2710        PrintS("Z");
2711      }
2712#ifdef KDEBUG
2713      if (TEST_OPT_DEBUG)
2714      {
2715        PrintS("--- create zero spoly: ");
2716        wrp(h);
2717        PrintS(" ---> ");
2718      }
2719#endif
2720      poly tmp = pInit();
2721      pSetCoeff0(tmp, pGetCoeff(p));
2722      for (int i = 1; i <= currRing->N; i++)
2723      {
2724        pSetExp(tmp, i, p_GetExp(p, i, strat->tailRing));
2725      }
2726      p_Setm(tmp, currRing);
2727      p = p_LmFreeAndNext(p, strat->tailRing);
2728      pNext(tmp) = p;
2729      LObject h;
2730      h.p = tmp;
2731      h.tailRing = strat->tailRing;
2732      int posx;
2733      if (h.p!=NULL)
2734      {
2735        if (TEST_OPT_INTSTRATEGY)
2736        {
2737          //pContent(h.p);
2738          h.pCleardenom(); // also does a pContent
2739        }
2740        else
2741        {
2742          h.pNorm();
2743        }
2744        strat->initEcart(&h);
2745        if (strat->Ll==-1)
2746          posx =0;
2747        else
2748          posx = strat->posInL(strat->L,strat->Ll,&h,strat);
2749        h.sev = pGetShortExpVector(h.p);
2750        h.t_p = k_LmInit_currRing_2_tailRing(h.p, strat->tailRing);
2751        if (pNext(p) != NULL)
2752        {
2753          // What does this? (Oliver)
2754          // pShallowCopyDeleteProc p_shallow_copy_delete
2755          //      = pGetShallowCopyDeleteProc(strat->tailRing, new_tailRing);
2756          // pNext(p) = p_shallow_copy_delete(pNext(p),
2757          //              currRing, strat->tailRing, strat->tailRing->PolyBin);
2758        }
2759#ifdef KDEBUG
2760        if (TEST_OPT_DEBUG)
2761        {
2762          wrp(tmp);
2763          PrintLn();
2764        }
2765#endif
2766        enterL(&strat->L,&strat->Ll,&strat->Lmax,h,posx);
2767      }
2768    }
2769  }
2770  nDelete(&gcd);
2771}
2772
2773void clearSbatch (poly h,int k,int pos,kStrategy strat)
2774{
2775  int j = pos;
2776  if ( (!strat->fromT)
2777  && (1//(strat->syzComp==0)
2778    //||(pGetComp(h)<=strat->syzComp)))
2779  ))
2780  {
2781    // Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
2782    unsigned long h_sev = pGetShortExpVector(h);
2783    loop
2784    {
2785      if (j > k) break;
2786      clearS(h,h_sev, &j,&k,strat);
2787      j++;
2788    }
2789    // Print("end clearS sl=%d\n",strat->sl);
2790  }
2791}
2792
2793/*2
2794* Generates a sufficient set of spolys (maybe just a finite generating
2795* set of the syzygys)
2796*/
2797void superenterpairs (poly h,int k,int ecart,int pos,kStrategy strat, int atR)
2798{
2799    assume (rField_is_Ring(currRing));
2800    // enter also zero divisor * poly, if this is non zero and of smaller degree
2801    if (!(rField_is_Domain(currRing))) enterExtendedSpoly(h, strat);
2802    initenterpairsRing(h, k, ecart, 0, strat, atR);
2803    initenterstrongPairs(h, k, ecart, 0, strat, atR);
2804    clearSbatch(h, k, pos, strat);
2805}
2806#endif
2807
2808/*2
2809*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
2810*superfluous elements in S will be deleted
2811*/
2812void enterpairs (poly h,int k,int ecart,int pos,kStrategy strat, int atR)
2813{
2814  int j=pos;
2815
2816#ifdef HAVE_RINGS
2817  assume (!rField_is_Ring(currRing));
2818#endif
2819
2820  initenterpairs(h,k,ecart,0,strat, atR);
2821  if ( (!strat->fromT)
2822  && ((strat->syzComp==0)
2823    ||(pGetComp(h)<=strat->syzComp)))
2824  {
2825    //Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
2826    unsigned long h_sev = pGetShortExpVector(h);
2827    loop
2828    {
2829      if (j > k) break;
2830      clearS(h,h_sev, &j,&k,strat);
2831      j++;
2832    }
2833    //Print("end clearS sl=%d\n",strat->sl);
2834  }
2835 // PrintS("end enterpairs\n");
2836}
2837
2838/*2
2839*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
2840*superfluous elements in S will be deleted
2841*/
2842void enterpairsSpecial (poly h,int k,int ecart,int pos,kStrategy strat, int atR = -1)
2843{
2844  int j;
2845
2846  for (j=0; j<=k; j++)
2847  {
2848    if ((pGetComp(h)==pGetComp(strat->S[j]))
2849    || (0==pGetComp(strat->S[j])))
2850    {
2851      enterOnePairSpecial(j,h,ecart,strat, atR);
2852    }
2853  }
2854//   #ifdef HAVE_PLURAL
2855  if (!rIsPluralRing(currRing))
2856//   #endif
2857  {
2858    j=pos;
2859    loop
2860    {
2861      unsigned long h_sev = pGetShortExpVector(h);
2862      if (j > k) break;
2863      clearS(h,h_sev,&j,&k,strat);
2864      j++;
2865    }
2866  }
2867}
2868
2869/*2
2870*reorders  s with respect to posInS,
2871*suc is the first changed index or zero
2872*/
2873
2874void reorderS (int* suc,kStrategy strat)
2875{
2876  int i,j,at,ecart, s2r;
2877  int fq=0;
2878  unsigned long sev;
2879  poly  p;
2880  int new_suc=strat->sl+1;
2881  i= *suc;
2882  if (i<0) i=0;
2883
2884  for (; i<=strat->sl; i++)
2885  {
2886    at = posInS(strat,i-1,strat->S[i],strat->ecartS[i]);
2887    if (at != i)
2888    {
2889      if (new_suc > at) new_suc = at;
2890      p = strat->S[i];
2891      ecart = strat->ecartS[i];
2892      sev = strat->sevS[i];
2893      s2r = strat->S_2_R[i];
2894      if (strat->fromQ!=NULL) fq=strat->fromQ[i];
2895      for (j=i; j>=at+1; j--)
2896      {
2897        strat->S[j] = strat->S[j-1];
2898        strat->ecartS[j] = strat->ecartS[j-1];
2899        strat->sevS[j] = strat->sevS[j-1];
2900        strat->S_2_R[j] = strat->S_2_R[j-1];
2901      }
2902      strat->S[at] = p;
2903      strat->ecartS[at] = ecart;
2904      strat->sevS[at] = sev;
2905      strat->S_2_R[at] = s2r;
2906      if (strat->fromQ!=NULL)
2907      {
2908        for (j=i; j>=at+1; j--)
2909        {
2910          strat->fromQ[j] = strat->fromQ[j-1];
2911        }
2912        strat->fromQ[at]=fq;
2913      }
2914    }
2915  }
2916  if (new_suc <= strat->sl) *suc=new_suc;
2917  else                      *suc=-1;
2918}
2919
2920
2921/*2
2922*looks up the position of p in set
2923*set[0] is the smallest with respect to the ordering-procedure deg/pComp
2924* Assumption: posInS only depends on the leading term
2925*             otherwise, bba has to be changed
2926*/
2927int posInS (const kStrategy strat, const int length,const poly p,
2928            const int ecart_p)
2929{
2930  if(length==-1) return 0;
2931  polyset set=strat->S;
2932  int i;
2933  int an = 0;
2934  int en = length;
2935  int cmp_int = pOrdSgn;
2936  int pc=pGetComp(p);
2937  if ((currRing->MixedOrder)
2938#if 0
2939  || ((strat->ak>0) && ((currRing->order[0]==ringorder_c)||((currRing->order[0]==ringorder_C))))
2940#endif
2941  )
2942  {
2943    int o=pWTotaldegree(p);
2944    int oo=pWTotaldegree(set[length]);
2945
2946    if ((oo<o)
2947    || ((o==oo) && (pLmCmp(set[length],p)!= cmp_int)))
2948      return length+1;
2949
2950    loop
2951    {
2952      if (an >= en-1)
2953      {
2954        if ((pWTotaldegree(set[an])>=o) && (pLmCmp(set[an],p) == cmp_int))
2955        {
2956          return an;
2957        }
2958        return en;
2959      }
2960      i=(an+en) / 2;
2961      if ((pWTotaldegree(set[i])>=o) && (pLmCmp(set[i],p) == cmp_int)) en=i;
2962      else                              an=i;
2963    }
2964  }
2965  else
2966  {
2967#ifdef HAVE_RINGS
2968    if (rField_is_Ring(currRing))
2969    {
2970      if (pLmCmp(set[length],p)== -cmp_int)
2971        return length+1;
2972      int cmp;
2973      loop
2974      {
2975        if (an >= en-1)
2976        {
2977          cmp = pLmCmp(set[an],p);
2978          if (cmp == cmp_int)  return an;
2979          if (cmp == -cmp_int) return en;
2980          if (nDivBy(pGetCoeff(p), pGetCoeff(set[an]))) return en;
2981          return an;
2982        }
2983        i = (an+en) / 2;
2984        cmp = pLmCmp(set[i],p);
2985        if (cmp == cmp_int)         en = i;
2986        else if (cmp == -cmp_int)   an = i;
2987        else
2988        {
2989          if (nDivBy(pGetCoeff(p), pGetCoeff(set[i]))) an = i;
2990          else en = i;
2991        }
2992      }
2993    }
2994    else
2995#endif
2996    if (pLmCmp(set[length],p)== -cmp_int)
2997      return length+1;
2998
2999    loop
3000    {
3001      if (an >= en-1)
3002      {
3003        if (pLmCmp(set[an],p) == cmp_int) return an;
3004        if (pLmCmp(set[an],p) == -cmp_int) return en;
3005        if ((cmp_int!=1)
3006        && ((strat->ecartS[an])>ecart_p))
3007          return an;
3008        return en;
3009      }
3010      i=(an+en) / 2;
3011      if (pLmCmp(set[i],p) == cmp_int) en=i;
3012      else if (pLmCmp(set[i],p) == -cmp_int) an=i;
3013      else
3014      {
3015        if ((cmp_int!=1)
3016        &&((strat->ecartS[i])<ecart_p))
3017          en=i;
3018        else
3019          an=i;
3020      }
3021    }
3022  }
3023}
3024
3025
3026/*2
3027* looks up the position of p in set
3028* the position is the last one
3029*/
3030int posInT0 (const TSet set,const int length,LObject &p)
3031{
3032  return (length+1);
3033}
3034
3035
3036/*2
3037* looks up the position of p in T
3038* set[0] is the smallest with respect to the ordering-procedure
3039* pComp
3040*/
3041int posInT1 (const TSet set,const int length,LObject &p)
3042{
3043  if (length==-1) return 0;
3044
3045  if (pLmCmp(set[length].p,p.p)!= pOrdSgn) return length+1;
3046
3047  int i;
3048  int an = 0;
3049  int en= length;
3050
3051  loop
3052  {
3053    if (an >= en-1)
3054    {
3055      if (pLmCmp(set[an].p,p.p) == pOrdSgn) return an;
3056      return en;
3057    }
3058    i=(an+en) / 2;
3059    if (pLmCmp(set[i].p,p.p) == pOrdSgn) en=i;
3060    else                                 an=i;
3061  }
3062}
3063
3064/*2
3065* looks up the position of p in T
3066* set[0] is the smallest with respect to the ordering-procedure
3067* length
3068*/
3069int posInT2 (const TSet set,const int length,LObject &p)
3070{
3071  if (length==-1)
3072    return 0;
3073  if (set[length].length<p.length)
3074    return length+1;
3075
3076  int i;
3077  int an = 0;
3078  int en= length;
3079
3080  loop
3081  {
3082    if (an >= en-1)
3083    {
3084      if (set[an].length>p.length) return an;
3085      return en;
3086    }
3087    i=(an+en) / 2;
3088    if (set[i].length>p.length) en=i;
3089    else                        an=i;
3090  }
3091}
3092
3093/*2
3094* looks up the position of p in T
3095* set[0] is the smallest with respect to the ordering-procedure
3096* totaldegree,pComp
3097*/
3098int posInT11 (const TSet set,const int length,LObject &p)
3099/*{
3100 * int j=0;
3101 * int o;
3102 *
3103 * o = p.GetpFDeg();
3104 * loop
3105 * {
3106 *   if ((pFDeg(set[j].p) > o)
3107 *   || ((pFDeg(set[j].p) == o) && (pLmCmp(set[j].p,p.p) == pOrdSgn)))
3108 *   {
3109 *     return j;
3110 *   }
3111 *   j++;
3112 *   if (j > length) return j;
3113 * }
3114 *}
3115 */
3116{
3117  if (length==-1) return 0;
3118
3119  int o = p.GetpFDeg();
3120  int op = set[length].GetpFDeg();
3121
3122  if ((op < o)
3123  || ((op == o) && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
3124    return length+1;
3125
3126  int i;
3127  int an = 0;
3128  int en= length;
3129
3130  loop
3131  {
3132    if (an >= en-1)
3133    {
3134      op= set[an].GetpFDeg();
3135      if ((op > o)
3136      || (( op == o) && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
3137        return an;
3138      return en;
3139    }
3140    i=(an+en) / 2;
3141    op = set[i].GetpFDeg();
3142    if (( op > o)
3143    || (( op == o) && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
3144      en=i;
3145    else
3146      an=i;
3147  }
3148}
3149
3150/*2 Pos for rings T: Here I am
3151* looks up the position of p in T
3152* set[0] is the smallest with respect to the ordering-procedure
3153* totaldegree,pComp
3154*/
3155int posInTrg0 (const TSet set,const int length,LObject &p)
3156{
3157  if (length==-1) return 0;
3158  int o = p.GetpFDeg();
3159  int op = set[length].GetpFDeg();
3160  int i;
3161  int an = 0;
3162  int en = length;
3163  int cmp_int = pOrdSgn;
3164  if ((op < o) || (pLmCmp(set[length].p,p.p)== -cmp_int))
3165    return length+1;
3166  int cmp;
3167  loop
3168  {
3169    if (an >= en-1)
3170    {
3171      op = set[an].GetpFDeg();
3172      if (op > o) return an;
3173      if (op < 0) return en;
3174      cmp = pLmCmp(set[an].p,p.p);
3175      if (cmp == cmp_int)  return an;
3176      if (cmp == -cmp_int) return en;
3177      if (nGreater(pGetCoeff(p.p), pGetCoeff(set[an].p))) return en;
3178      return an;
3179    }
3180    i = (an + en) / 2;
3181    op = set[i].GetpFDeg();
3182    if (op > o)       en = i;
3183    else if (op < o)  an = i;
3184    else
3185    {
3186      cmp = pLmCmp(set[i].p,p.p);
3187      if (cmp == cmp_int)                                     en = i;
3188      else if (cmp == -cmp_int)                               an = i;
3189      else if (nGreater(pGetCoeff(p.p), pGetCoeff(set[i].p))) an = i;
3190      else                                                    en = i;
3191    }
3192  }
3193}
3194/*
3195  int o = p.GetpFDeg();
3196  int op = set[length].GetpFDeg();
3197
3198  if ((op < o)
3199  || ((op == o) && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
3200    return length+1;
3201
3202  int i;
3203  int an = 0;
3204  int en= length;
3205
3206  loop
3207  {
3208    if (an >= en-1)
3209    {
3210      op= set[an].GetpFDeg();
3211      if ((op > o)
3212      || (( op == o) && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
3213        return an;
3214      return en;
3215    }
3216    i=(an+en) / 2;
3217    op = set[i].GetpFDeg();
3218    if (( op > o)
3219    || (( op == o) && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
3220      en=i;
3221    else
3222      an=i;
3223  }
3224}
3225  */
3226/*2
3227* looks up the position of p in T
3228* set[0] is the smallest with respect to the ordering-procedure
3229* totaldegree,pComp
3230*/
3231int posInT110 (const TSet set,const int length,LObject &p)
3232{
3233  if (length==-1) return 0;
3234
3235  int o = p.GetpFDeg();
3236  int op = set[length].GetpFDeg();
3237
3238  if (( op < o)
3239  || (( op == o) && (set[length].length<p.length))
3240  || (( op == o) && (set[length].length == p.length)
3241     && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
3242    return length+1;
3243
3244  int i;
3245  int an = 0;
3246  int en= length;
3247  loop
3248  {
3249    if (an >= en-1)
3250    {
3251      op = set[an].GetpFDeg();
3252      if (( op > o)
3253      || (( op == o) && (set[an].length > p.length))
3254      || (( op == o) && (set[an].length == p.length)
3255         && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
3256        return an;
3257      return en;
3258    }
3259    i=(an+en) / 2;
3260    op = set[i].GetpFDeg();
3261    if (( op > o)
3262    || (( op == o) && (set[i].length > p.length))
3263    || (( op == o) && (set[i].length == p.length)
3264       && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
3265      en=i;
3266    else
3267      an=i;
3268  }
3269}
3270
3271/*2
3272* looks up the position of p in set
3273* set[0] is the smallest with respect to the ordering-procedure
3274* pFDeg
3275*/
3276int posInT13 (const TSet set,const int length,LObject &p)
3277{
3278  if (length==-1) return 0;
3279
3280  int o = p.GetpFDeg();
3281
3282  if (set[length].GetpFDeg() <= o)
3283    return length+1;
3284
3285  int i;
3286  int an = 0;
3287  int en= length;
3288  loop
3289  {
3290    if (an >= en-1)
3291    {
3292      if (set[an].GetpFDeg() > o)
3293        return an;
3294      return en;
3295    }
3296    i=(an+en) / 2;
3297    if (set[i].GetpFDeg() > o)
3298      en=i;
3299    else
3300      an=i;
3301  }
3302}
3303
3304// determines the position based on: 1.) Ecart 2.) pLength
3305int posInT_EcartpLength(const TSet set,const int length,LObject &p)
3306{
3307  if (length==-1) return 0;
3308
3309  int op=p.ecart;
3310  int ol = p.GetpLength();
3311
3312  int oo=set[length].ecart;
3313  if ((oo < op) || ((oo==op) && (set[length].length < ol)))
3314    return length+1;
3315
3316  int i;
3317  int an = 0;
3318  int en= length;
3319  loop
3320    {
3321      if (an >= en-1)
3322      {
3323        int oo=set[an].ecart;
3324        if((oo > op)
3325           || ((oo==op) && (set[an].pLength > ol)))
3326          return an;
3327        return en;
3328      }
3329      i=(an+en) / 2;
3330      int oo=set[i].ecart;
3331      if ((oo > op)
3332          || ((oo == op) && (set[i].pLength > ol)))
3333        en=i;
3334      else
3335        an=i;
3336    }
3337}
3338
3339/*2
3340* looks up the position of p in set
3341* set[0] is the smallest with respect to the ordering-procedure
3342* maximaldegree, pComp
3343*/
3344int posInT15 (const TSet set,const int length,LObject &p)
3345/*{
3346 *int j=0;
3347 * int o;
3348 *
3349 * o = p.GetpFDeg()+p.ecart;
3350 * loop
3351 * {
3352 *   if ((set[j].GetpFDeg()+set[j].ecart > o)
3353 *   || ((set[j].GetpFDeg()+set[j].ecart == o)
3354 *     && (pLmCmp(set[j].p,p.p) == pOrdSgn)))
3355 *   {
3356 *     return j;
3357 *   }
3358 *   j++;
3359 *   if (j > length) return j;
3360 * }
3361 *}
3362 */
3363{
3364  if (length==-1) return 0;
3365
3366  int o = p.GetpFDeg() + p.ecart;
3367  int op = set[length].GetpFDeg()+set[length].ecart;
3368
3369  if ((op < o)
3370  || ((op == o)
3371     && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
3372    return length+1;
3373
3374  int i;
3375  int an = 0;
3376  int en= length;
3377  loop
3378  {
3379    if (an >= en-1)
3380    {
3381      op = set[an].GetpFDeg()+set[an].ecart;
3382      if (( op > o)
3383      || (( op  == o) && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
3384        return an;
3385      return en;
3386    }
3387    i=(an+en) / 2;
3388    op = set[i].GetpFDeg()+set[i].ecart;
3389    if (( op > o)
3390    || (( op == o) && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
3391      en=i;
3392    else
3393      an=i;
3394  }
3395}
3396
3397/*2
3398* looks up the position of p in set
3399* set[0] is the smallest with respect to the ordering-procedure
3400* pFDeg+ecart, ecart, pComp
3401*/
3402int posInT17 (const TSet set,const int length,LObject &p)
3403/*
3404*{
3405* int j=0;
3406* int  o;
3407*
3408*  o = p.GetpFDeg()+p.ecart;
3409*  loop
3410*  {
3411*    if ((pFDeg(set[j].p)+set[j].ecart > o)
3412*    || (((pFDeg(set[j].p)+set[j].ecart == o)
3413*      && (set[j].ecart < p.ecart)))
3414*    || ((pFDeg(set[j].p)+set[j].ecart == o)
3415*      && (set[j].ecart==p.ecart)
3416*      && (pLmCmp(set[j].p,p.p)==pOrdSgn)))
3417*      return j;
3418*    j++;
3419*    if (j > length) return j;
3420*  }
3421* }
3422*/
3423{
3424  if (length==-1) return 0;
3425
3426  int o = p.GetpFDeg() + p.ecart;
3427  int op = set[length].GetpFDeg()+set[length].ecart;
3428
3429  if ((op < o)
3430  || (( op == o) && (set[length].ecart > p.ecart))
3431  || (( op == o) && (set[length].ecart==p.ecart)
3432     && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
3433    return length+1;
3434
3435  int i;
3436  int an = 0;
3437  int en= length;
3438  loop
3439  {
3440    if (an >= en-1)
3441    {
3442      op = set[an].GetpFDeg()+set[an].ecart;
3443      if (( op > o)
3444      || (( op == o) && (set[an].ecart < p.ecart))
3445      || (( op  == o) && (set[an].ecart==p.ecart)
3446         && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
3447        return an;
3448      return en;
3449    }
3450    i=(an+en) / 2;
3451    op = set[i].GetpFDeg()+set[i].ecart;
3452    if ((op > o)
3453    || (( op == o) && (set[i].ecart < p.ecart))
3454    || (( op == o) && (set[i].ecart == p.ecart)
3455       && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
3456      en=i;
3457    else
3458      an=i;
3459  }
3460}
3461/*2
3462* looks up the position of p in set
3463* set[0] is the smallest with respect to the ordering-procedure
3464* pGetComp, pFDeg+ecart, ecart, pComp
3465*/
3466int posInT17_c (const TSet set,const int length,LObject &p)
3467{
3468  if (length==-1) return 0;
3469
3470  int cc = (-1+2*currRing->order[0]==ringorder_c);
3471  /* cc==1 for (c,..), cc==-1 for (C,..) */
3472  int o = p.GetpFDeg() + p.ecart;
3473  int c = pGetComp(p.p)*cc;
3474
3475  if (pGetComp(set[length].p)*cc < c)
3476    return length+1;
3477  if (pGetComp(set[length].p)*cc == c)
3478  {
3479    int op = set[length].GetpFDeg()+set[length].ecart;
3480    if ((op < o)
3481    || ((op == o) && (set[length].ecart > p.ecart))
3482    || ((op == o) && (set[length].ecart==p.ecart)
3483       && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
3484      return length+1;
3485  }
3486
3487  int i;
3488  int an = 0;
3489  int en= length;
3490  loop
3491  {
3492    if (an >= en-1)
3493    {
3494      if (pGetComp(set[an].p)*cc < c)
3495        return en;
3496      if (pGetComp(set[an].p)*cc == c)
3497      {
3498        int op = set[an].GetpFDeg()+set[an].ecart;
3499        if ((op > o)
3500        || ((op == o) && (set[an].ecart < p.ecart))
3501        || ((op == o) && (set[an].ecart==p.ecart)
3502           && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
3503          return an;
3504      }
3505      return en;
3506    }
3507    i=(an+en) / 2;
3508    if (pGetComp(set[i].p)*cc > c)
3509      en=i;
3510    else if (pGetComp(set[i].p)*cc == c)
3511    {
3512      int op = set[i].GetpFDeg()+set[i].ecart;
3513      if ((op > o)
3514      || ((op == o) && (set[i].ecart < p.ecart))
3515      || ((op == o) && (set[i].ecart == p.ecart)
3516         && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
3517        en=i;
3518      else
3519        an=i;
3520    }
3521    else
3522      an=i;
3523  }
3524}
3525
3526/*2
3527* looks up the position of p in set
3528* set[0] is the smallest with respect to
3529* ecart, pFDeg, length
3530*/
3531int posInT19 (const TSet set,const int length,LObject &p)
3532{
3533  if (length==-1) return 0;
3534
3535  int o = p.ecart;
3536  int op=p.GetpFDeg();
3537
3538  if (set[length].ecart < o)
3539    return length+1;
3540  if (set[length].ecart == o)
3541  {
3542     int oo=set[length].GetpFDeg();
3543     if ((oo < op) || ((oo==op) && (set[length].length < p.length)))
3544       return length+1;
3545  }
3546
3547  int i;
3548  int an = 0;
3549  int en= length;
3550  loop
3551  {
3552    if (an >= en-1)
3553    {
3554      if (set[an].ecart > o)
3555        return an;
3556      if (set[an].ecart == o)
3557      {
3558         int oo=set[an].GetpFDeg();
3559         if((oo > op)
3560         || ((oo==op) && (set[an].length > p.length)))
3561           return an;
3562      }
3563      return en;
3564    }
3565    i=(an+en) / 2;
3566    if (set[i].ecart > o)
3567      en=i;
3568    else if (set[i].ecart == o)
3569    {
3570       int oo=set[i].GetpFDeg();
3571       if ((oo > op)
3572       || ((oo == op) && (set[i].length > p.length)))
3573         en=i;
3574       else
3575        an=i;
3576    }
3577    else
3578      an=i;
3579  }
3580}
3581
3582/*2
3583*looks up the position of polynomial p in set
3584*set[length] is the smallest element in set with respect
3585*to the ordering-procedure pComp
3586*/
3587int posInLSpecial (const LSet set, const int length,
3588                   LObject *p,const kStrategy strat)
3589{
3590  if (length<0) return 0;
3591
3592  int d=p->GetpFDeg();
3593  int op=set[length].GetpFDeg();
3594
3595  if ((op > d)
3596  || ((op == d) && (p->p1!=NULL)&&(set[length].p1==NULL))
3597  || (pLmCmp(set[length].p,p->p)== pOrdSgn))
3598     return length+1;
3599
3600  int i;
3601  int an = 0;
3602  int en= length;
3603  loop
3604  {
3605    if (an >= en-1)
3606    {
3607      op=set[an].GetpFDeg();
3608      if ((op > d)
3609      || ((op == d) && (p->p1!=NULL) && (set[an].p1==NULL))
3610      || (pLmCmp(set[an].p,p->p)== pOrdSgn))
3611         return en;
3612      return an;
3613    }
3614    i=(an+en) / 2;
3615    op=set[i].GetpFDeg();
3616    if ((op>d)
3617    || ((op==d) && (p->p1!=NULL) && (set[i].p1==NULL))
3618    || (pLmCmp(set[i].p,p->p) == pOrdSgn))
3619      an=i;
3620    else
3621      en=i;
3622  }
3623}
3624
3625/*2
3626*looks up the position of polynomial p in set
3627*set[length] is the smallest element in set with respect
3628*to the ordering-procedure pComp
3629*/
3630int posInL0 (const LSet set, const int length,
3631             LObject* p,const kStrategy strat)
3632{
3633  if (length<0) return 0;
3634
3635  if (pLmCmp(set[length].p,p->p)== pOrdSgn)
3636    return length+1;
3637
3638  int i;
3639  int an = 0;
3640  int en= length;
3641  loop
3642  {
3643    if (an >= en-1)
3644    {
3645      if (pLmCmp(set[an].p,p->p) == pOrdSgn) return en;
3646      return an;
3647    }
3648    i=(an+en) / 2;
3649    if (pLmCmp(set[i].p,p->p) == pOrdSgn) an=i;
3650    else                                 en=i;
3651    /*aend. fuer lazy == in !=- machen */
3652  }
3653}
3654
3655/*2
3656* looks up the position of polynomial p in set
3657* e is the ecart of p
3658* set[length] is the smallest element in set with respect
3659* to the ordering-procedure totaldegree,pComp
3660*/
3661int posInL11 (const LSet set, const int length,
3662              LObject* p,const kStrategy strat)
3663/*{
3664 * int j=0;
3665 * int o;
3666 *
3667 * o = p->GetpFDeg();
3668 * loop
3669 * {
3670 *   if (j > length)            return j;
3671 *   if ((set[j].GetpFDeg() < o)) return j;
3672 *   if ((set[j].GetpFDeg() == o) && (pLmCmp(set[j].p,p->p) == -pOrdSgn))
3673 *   {
3674 *     return j;
3675 *   }
3676 *   j++;
3677 * }
3678 *}
3679 */
3680{
3681  if (length<0) return 0;
3682
3683  int o = p->GetpFDeg();
3684  int op = set[length].GetpFDeg();
3685
3686  if ((op > o)
3687  || ((op == o) && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
3688    return length+1;
3689  int i;
3690  int an = 0;
3691  int en= length;
3692  loop
3693  {
3694    if (an >= en-1)
3695    {
3696      op = set[an].GetpFDeg();
3697      if ((op > o)
3698      || ((op == o) && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
3699        return en;
3700      return an;
3701    }
3702    i=(an+en) / 2;
3703    op = set[i].GetpFDeg();
3704    if ((op > o)
3705    || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
3706      an=i;
3707    else
3708      en=i;
3709  }
3710}
3711
3712/*2 Position for rings L: Here I am
3713* looks up the position of polynomial p in set
3714* e is the ecart of p
3715* set[length] is the smallest element in set with respect
3716* to the ordering-procedure totaldegree,pComp
3717*/
3718inline int getIndexRng(long coeff)
3719{
3720  if (coeff == 0) return -1;
3721  long tmp = coeff;
3722  int ind = 0;
3723  while (tmp % 2 == 0)
3724  {
3725    tmp = tmp / 2;
3726    ind++;
3727  }
3728  return ind;
3729}
3730
3731int posInLrg0 (const LSet set, const int length,
3732              LObject* p,const kStrategy strat)
3733/*          if (nGreater(pGetCoeff(p), pGetCoeff(set[an]))) return en;
3734        if (pLmCmp(set[i],p) == cmp_int)         en = i;
3735        else if (pLmCmp(set[i],p) == -cmp_int)   an = i;
3736        else
3737        {
3738          if (nGreater(pGetCoeff(p), pGetCoeff(set[i]))) an = i;
3739          else en = i;
3740        }*/
3741{
3742  if (length < 0) return 0;
3743
3744  int o = p->GetpFDeg();
3745  int op = set[length].GetpFDeg();
3746
3747  if ((op > o) || ((op == o) && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
3748    return length + 1;
3749  int i;
3750  int an = 0;
3751  int en = length;
3752  loop
3753  {
3754    if (an >= en - 1)
3755    {
3756      op = set[an].GetpFDeg();
3757      if ((op > o) || ((op == o) && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
3758        return en;
3759      return an;
3760    }
3761    i = (an+en) / 2;
3762    op = set[i].GetpFDeg();
3763    if ((op > o) || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
3764      an = i;
3765    else
3766      en = i;
3767  }
3768}
3769
3770/*{
3771  if (length < 0) return 0;
3772
3773  int o = p->GetpFDeg();
3774  int op = set[length].GetpFDeg();
3775
3776  int inde = getIndexRng((unsigned long) pGetCoeff(set[length].p));
3777  int indp = getIndexRng((unsigned long) pGetCoeff(p->p));
3778  int inda;
3779  int indi;
3780
3781  if ((inda > indp) || ((inda == inde) && ((op > o) || ((op == o) && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))))
3782    return length + 1;
3783  int i;
3784  int an = 0;
3785  inda = getIndexRng((unsigned long) pGetCoeff(set[an].p));
3786  int en = length;
3787  loop
3788  {
3789    if (an >= en-1)
3790    {
3791      op = set[an].GetpFDeg();
3792      if ((indp > inda) || ((indp == inda) && ((op > o) || ((op == o) && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))))
3793        return en;
3794      return an;
3795    }
3796    i = (an + en) / 2;
3797    indi = getIndexRng((unsigned long) pGetCoeff(set[i].p));
3798    op = set[i].GetpFDeg();
3799    if ((indi > indp) || ((indi == indp) && ((op > o) || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))))
3800    // if ((op > o) || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
3801    {
3802      an = i;
3803      inda = getIndexRng((unsigned long) pGetCoeff(set[an].p));
3804    }
3805    else
3806      en = i;
3807  }
3808} */
3809
3810/*2
3811* looks up the position of polynomial p in set
3812* set[length] is the smallest element in set with respect
3813* to the ordering-procedure totaldegree,pLength0
3814*/
3815int posInL110 (const LSet set, const int length,
3816               LObject* p,const kStrategy strat)
3817{
3818  if (length<0) return 0;
3819
3820  int o = p->GetpFDeg();
3821  int op = set[length].GetpFDeg();
3822
3823  if ((op > o)
3824  || ((op == o) && (set[length].length >p->length))
3825  || ((op == o) && (set[length].length <= p->length)
3826     && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
3827    return length+1;
3828  int i;
3829  int an = 0;
3830  int en= length;
3831  loop
3832  {
3833    if (an >= en-1)
3834    {
3835      op = set[an].GetpFDeg();
3836      if ((op > o)
3837      || ((op == o) && (set[an].length >p->length))
3838      || ((op == o) && (set[an].length <=p->length)
3839         && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
3840        return en;
3841      return an;
3842    }
3843    i=(an+en) / 2;
3844    op = set[i].GetpFDeg();
3845    if ((op > o)
3846    || ((op == o) && (set[i].length > p->length))
3847    || ((op == o) && (set[i].length <= p->length)
3848       && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
3849      an=i;
3850    else
3851      en=i;
3852  }
3853}
3854
3855/*2
3856* looks up the position of polynomial p in set
3857* e is the ecart of p
3858* set[length] is the smallest element in set with respect
3859* to the ordering-procedure totaldegree
3860*/
3861int posInL13 (const LSet set, const int length,
3862              LObject* p,const kStrategy strat)
3863{
3864  if (length<0) return 0;
3865
3866  int o = p->GetpFDeg();
3867
3868  if (set[length].GetpFDeg() > o)
3869    return length+1;
3870
3871  int i;
3872  int an = 0;
3873  int en= length;
3874  loop
3875  {
3876    if (an >= en-1)
3877    {
3878      if (set[an].GetpFDeg() >= o)
3879        return en;
3880      return an;
3881    }
3882    i=(an+en) / 2;
3883    if (set[i].GetpFDeg() >= o)
3884      an=i;
3885    else
3886      en=i;
3887  }
3888}
3889
3890/*2
3891* looks up the position of polynomial p in set
3892* e is the ecart of p
3893* set[length] is the smallest element in set with respect
3894* to the ordering-procedure maximaldegree,pComp
3895*/
3896int posInL15 (const LSet set, const int length,
3897              LObject* p,const kStrategy strat)
3898/*{
3899 * int j=0;
3900 * int o;
3901 *
3902 * o = p->ecart+p->GetpFDeg();
3903 * loop
3904 * {
3905 *   if (j > length)                       return j;
3906 *   if (set[j].GetpFDeg()+set[j].ecart < o) return j;
3907 *   if ((set[j].GetpFDeg()+set[j].ecart == o)
3908 *   && (pLmCmp(set[j].p,p->p) == -pOrdSgn))
3909 *   {
3910 *     return j;
3911 *   }
3912 *   j++;
3913 * }
3914 *}
3915 */
3916{
3917  if (length<0) return 0;
3918
3919  int o = p->GetpFDeg() + p->ecart;
3920  int op = set[length].GetpFDeg() + set[length].ecart;
3921
3922  if ((op > o)
3923  || ((op == o) && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
3924    return length+1;
3925  int i;
3926  int an = 0;
3927  int en= length;
3928  loop
3929  {
3930    if (an >= en-1)
3931    {
3932      op = set[an].GetpFDeg() + set[an].ecart;
3933      if ((op > o)
3934      || ((op == o) && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
3935        return en;
3936      return an;
3937    }
3938    i=(an+en) / 2;
3939    op = set[i].GetpFDeg() + set[i].ecart;
3940    if ((op > o)
3941    || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
3942      an=i;
3943    else
3944      en=i;
3945  }
3946}
3947
3948/*2
3949* looks up the position of polynomial p in set
3950* e is the ecart of p
3951* set[length] is the smallest element in set with respect
3952* to the ordering-procedure totaldegree
3953*/
3954int posInL17 (const LSet set, const int length,
3955              LObject* p,const kStrategy strat)
3956{
3957  if (length<0) return 0;
3958
3959  int o = p->GetpFDeg() + p->ecart;
3960
3961  if ((set[length].GetpFDeg() + set[length].ecart > o)
3962  || ((set[length].GetpFDeg() + set[length].ecart == o)
3963     && (set[length].ecart > p->ecart))
3964  || ((set[length].GetpFDeg() + set[length].ecart == o)
3965     && (set[length].ecart == p->ecart)
3966     && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
3967    return length+1;
3968  int i;
3969  int an = 0;
3970  int en= length;
3971  loop
3972  {
3973    if (an >= en-1)
3974    {
3975      if ((set[an].GetpFDeg() + set[an].ecart > o)
3976      || ((set[an].GetpFDeg() + set[an].ecart == o)
3977         && (set[an].ecart > p->ecart))
3978      || ((set[an].GetpFDeg() + set[an].ecart == o)
3979         && (set[an].ecart == p->ecart)
3980         && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
3981        return en;
3982      return an;
3983    }
3984    i=(an+en) / 2;
3985    if ((set[i].GetpFDeg() + set[i].ecart > o)
3986    || ((set[i].GetpFDeg() + set[i].ecart == o)
3987       && (set[i].ecart > p->ecart))
3988    || ((set[i].GetpFDeg() +set[i].ecart == o)
3989       && (set[i].ecart == p->ecart)
3990       && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
3991      an=i;
3992    else
3993      en=i;
3994  }
3995}
3996/*2
3997* looks up the position of polynomial p in set
3998* e is the ecart of p
3999* set[length] is the smallest element in set with respect
4000* to the ordering-procedure pComp
4001*/
4002int posInL17_c (const LSet set, const int length,
4003                LObject* p,const kStrategy strat)
4004{
4005  if (length<0) return 0;
4006
4007  int cc = (-1+2*currRing->order[0]==ringorder_c);
4008  /* cc==1 for (c,..), cc==-1 for (C,..) */
4009  int c = pGetComp(p->p)*cc;
4010  int o = p->GetpFDeg() + p->ecart;
4011
4012  if (pGetComp(set[length].p)*cc > c)
4013    return length+1;
4014  if (pGetComp(set[length].p)*cc == c)
4015  {
4016    if ((set[length].GetpFDeg() + set[length].ecart > o)
4017    || ((set[length].GetpFDeg() + set[length].ecart == o)
4018       && (set[length].ecart > p->ecart))
4019    || ((set[length].GetpFDeg() + set[length].ecart == o)
4020       && (set[length].ecart == p->ecart)
4021       && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
4022      return length+1;
4023  }
4024  int i;
4025  int an = 0;
4026  int en= length;
4027  loop
4028  {
4029    if (an >= en-1)
4030    {
4031      if (pGetComp(set[an].p)*cc > c)
4032        return en;
4033      if (pGetComp(set[an].p)*cc == c)
4034      {
4035        if ((set[an].GetpFDeg() + set[an].ecart > o)
4036        || ((set[an].GetpFDeg() + set[an].ecart == o)
4037           && (set[an].ecart > p->ecart))
4038        || ((set[an].GetpFDeg() + set[an].ecart == o)
4039           && (set[an].ecart == p->ecart)
4040           && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
4041          return en;
4042      }
4043      return an;
4044    }
4045    i=(an+en) / 2;
4046    if (pGetComp(set[i].p)*cc > c)
4047      an=i;
4048    else if (pGetComp(set[i].p)*cc == c)
4049    {
4050      if ((set[i].GetpFDeg() + set[i].ecart > o)
4051      || ((set[i].GetpFDeg() + set[i].ecart == o)
4052         && (set[i].ecart > p->ecart))
4053      || ((set[i].GetpFDeg() +set[i].ecart == o)
4054         && (set[i].ecart == p->ecart)
4055         && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
4056        an=i;
4057      else
4058        en=i;
4059    }
4060    else
4061      en=i;
4062  }
4063}
4064
4065/***************************************************************
4066 *
4067 * Tail reductions
4068 *
4069 ***************************************************************/
4070TObject*
4071kFindDivisibleByInS(kStrategy strat, int pos, LObject* L, TObject *T,
4072                    long ecart)
4073{
4074  int j = 0;
4075  const unsigned long not_sev = ~L->sev;
4076  const unsigned long* sev = strat->sevS;
4077  poly p;
4078  ring r;
4079  L->GetLm(p, r);
4080
4081  assume(~not_sev == p_GetShortExpVector(p, r));
4082
4083  if (r == currRing)
4084  {
4085    loop
4086    {
4087      if (j > pos) return NULL;
4088#if defined(PDEBUG) || defined(PDIV_DEBUG)
4089      if (p_LmShortDivisibleBy(strat->S[j], sev[j], p, not_sev, r) &&
4090          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
4091        break;
4092#else
4093      if (!(sev[j] & not_sev) &&
4094          (ecart== LONG_MAX || ecart>= strat->ecartS[j]) &&
4095          p_LmDivisibleBy(strat->S[j], p, r))
4096        break;
4097
4098#endif
4099      j++;
4100    }
4101    // if called from NF, T objects do not exist:
4102    if (strat->tl < 0 || strat->S_2_R[j] == -1)
4103    {
4104      T->Set(strat->S[j], r, strat->tailRing);
4105      return T;
4106    }
4107    else
4108    {
4109/////      assume (j >= 0 && j <= strat->tl && strat->S_2_T(j) != NULL
4110/////      && strat->S_2_T(j)->p == strat->S[j]); // wrong?
4111//      assume (j >= 0 && j <= strat->sl && strat->S_2_T(j) != NULL && strat->S_2_T(j)->p == strat->S[j]);
4112      return strat->S_2_T(j);
4113    }
4114  }
4115  else
4116  {
4117    TObject* t;
4118    loop
4119    {
4120      if (j > pos) return NULL;
4121      assume(strat->S_2_R[j] != -1);
4122#if defined(PDEBUG) || defined(PDIV_DEBUG)
4123      t = strat->S_2_T(j);
4124      assume(t != NULL && t->t_p != NULL && t->tailRing == r);
4125      if (p_LmShortDivisibleBy(t->t_p, sev[j], p, not_sev, r) &&
4126          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
4127        return t;
4128#else
4129      if (! (sev[j] & not_sev) && (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
4130      {
4131        t = strat->S_2_T(j);
4132        assume(t != NULL && t->t_p != NULL && t->tailRing == r && t->p == strat->S[j]);
4133        if (p_LmDivisibleBy(t->t_p, p, r)) return t;
4134      }
4135#endif
4136      j++;
4137    }
4138  }
4139}
4140
4141poly redtail (LObject* L, int pos, kStrategy strat)
4142{
4143  poly h, hn;
4144  int j;
4145  unsigned long not_sev;
4146  strat->redTailChange=FALSE;
4147
4148  poly p = L->p;
4149  if (strat->noTailReduction || pNext(p) == NULL)
4150    return p;
4151
4152  LObject Ln(strat->tailRing);
4153  TObject* With;
4154  // placeholder in case strat->tl < 0
4155  TObject  With_s(strat->tailRing);
4156  h = p;
4157  hn = pNext(h);
4158  long op = strat->tailRing->pFDeg(hn, strat->tailRing);
4159  long e;
4160  int l;
4161  BOOLEAN save_HE=strat->kHEdgeFound;
4162  strat->kHEdgeFound |=
4163    ((Kstd1_deg>0) && (op<=Kstd1_deg)) || TEST_OPT_INFREDTAIL;
4164
4165  while(hn != NULL)
4166  {
4167    op = strat->tailRing->pFDeg(hn, strat->tailRing);
4168    if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
4169    e = strat->tailRing->pLDeg(hn, &l, strat->tailRing) - op;
4170    loop
4171    {
4172      Ln.Set(hn, strat->tailRing);
4173      Ln.sev = p_GetShortExpVector(hn, strat->tailRing);
4174      if (strat->kHEdgeFound)
4175        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
4176      else
4177        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s, e);
4178      if (With == NULL) break;
4179      With->length=0;
4180      With->pLength=0;
4181      strat->redTailChange=TRUE;
4182      if (ksReducePolyTail(L, With, h, strat->kNoetherTail()))
4183      {
4184        // reducing the tail would violate the exp bound
4185        if (kStratChangeTailRing(strat, L))
4186        {
4187          strat->kHEdgeFound = save_HE;
4188          return redtail(L, pos, strat);
4189        }
4190        else
4191          return NULL;
4192      }
4193      hn = pNext(h);
4194      if (hn == NULL) goto all_done;
4195      op = strat->tailRing->pFDeg(hn, strat->tailRing);
4196      if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
4197      e = strat->tailRing->pLDeg(hn, &l, strat->tailRing) - op;
4198    }
4199    h = hn;
4200    hn = pNext(h);
4201  }
4202
4203  all_done:
4204  if (strat->redTailChange)
4205  {
4206    L->last = 0;
4207    L->pLength = 0;
4208  }
4209  strat->kHEdgeFound = save_HE;
4210  return p;
4211}
4212
4213poly redtail (poly p, int pos, kStrategy strat)
4214{
4215  LObject L(p, currRing);
4216  return redtail(&L, pos, strat);
4217}
4218
4219poly redtailBba (LObject* L, int pos, kStrategy strat, BOOLEAN withT, BOOLEAN normalize)
4220{
4221#define REDTAIL_CANONICALIZE 100
4222  strat->redTailChange=FALSE;
4223  if (strat->noTailReduction) return L->GetLmCurrRing();
4224  poly h, p;
4225  p = h = L->GetLmTailRing();
4226  if ((h==NULL) || (pNext(h)==NULL))
4227    return L->GetLmCurrRing();
4228
4229  TObject* With;
4230  // placeholder in case strat->tl < 0
4231  TObject  With_s(strat->tailRing);
4232
4233  LObject Ln(pNext(h), strat->tailRing);
4234  Ln.pLength = L->GetpLength() - 1;
4235
4236  pNext(h) = NULL;
4237  if (L->p != NULL) pNext(L->p) = NULL;
4238  L->pLength = 1;
4239
4240  Ln.PrepareRed(strat->use_buckets);
4241
4242  int cnt=REDTAIL_CANONICALIZE;
4243  while(!Ln.IsNull())
4244  {
4245    loop
4246    {
4247      Ln.SetShortExpVector();
4248      if (withT)
4249      {
4250        int j;
4251        j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln);
4252        if (j < 0) break;
4253        With = &(strat->T[j]);
4254      }
4255      else
4256      {
4257        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
4258        if (With == NULL) break;
4259      }
4260      cnt--;
4261      if (cnt==0)
4262      {
4263        cnt=REDTAIL_CANONICALIZE; 
4264        poly tmp=Ln.CanonicalizeP(); 
4265        if (normalize) 
4266        {
4267          Ln.Normalize();
4268          //pNormalize(tmp);
4269          //if (TEST_OPT_PROT) { PrintS("n"); mflush(); }
4270        }
4271      }
4272      if (normalize && (!TEST_OPT_INTSTRATEGY) && (!nIsOne(pGetCoeff(With->p))))
4273      {
4274        With->pNorm();
4275      }
4276      strat->redTailChange=TRUE;
4277      if (ksReducePolyTail(L, With, &Ln))
4278      {
4279        // reducing the tail would violate the exp bound
4280        //  set a flag and hope for a retry (in bba)
4281        strat->completeReduce_retry=TRUE;
4282        do
4283        {
4284          pNext(h) = Ln.LmExtractAndIter();
4285          pIter(h);
4286          L->pLength++;
4287        } while (!Ln.IsNull());
4288        goto all_done;
4289      }
4290      if (Ln.IsNull()) goto all_done;
4291      if (! withT) With_s.Init(currRing);
4292    }
4293    pNext(h) = Ln.LmExtractAndIter();
4294    pIter(h);
4295    pNormalize(h);
4296    L->pLength++;
4297  }
4298
4299  all_done:
4300  Ln.Delete();
4301  if (L->p != NULL) pNext(L->p) = pNext(p);
4302
4303  if (strat->redTailChange)
4304  {
4305    L->last = NULL;
4306    L->length = 0;
4307  }
4308
4309  //if (TEST_OPT_PROT) { PrintS("N"); mflush(); }
4310  //L->Normalize(); // HANNES: should have a test
4311  kTest_L(L);
4312  return L->GetLmCurrRing();
4313}
4314
4315/*2
4316*checks the change degree and write progress report
4317*/
4318void message (int i,int* reduc,int* olddeg,kStrategy strat, int red_result)
4319{
4320  if (i != *olddeg)
4321  {
4322    Print("%d",i);
4323    *olddeg = i;
4324  }
4325  if (K_TEST_OPT_OLDSTD)
4326  {
4327    if (strat->Ll != *reduc)
4328    {
4329      if (strat->Ll != *reduc-1)
4330        Print("(%d)",strat->Ll+1);
4331      else
4332        PrintS("-");
4333      *reduc = strat->Ll;
4334    }
4335    else
4336      PrintS(".");
4337    mflush();
4338  }
4339  else
4340  {
4341    if (red_result == 0)
4342      PrintS("-");
4343    else if (red_result < 0)
4344      PrintS(".");
4345    if ((red_result > 0) || ((strat->Ll % 100)==99))
4346    {
4347      if (strat->Ll != *reduc && strat->Ll > 0)
4348      {
4349        Print("(%d)",strat->Ll+1);
4350        *reduc = strat->Ll;
4351      }
4352    }
4353  }
4354}
4355
4356/*2
4357*statistics
4358*/
4359void messageStat (int srmax,int lrmax,int hilbcount,kStrategy strat)
4360{
4361  //PrintS("\nUsage/Allocation of temporary storage:\n");
4362  //Print("%d/%d polynomials in standard base\n",srmax,IDELEMS(Shdl));
4363  //Print("%d/%d polynomials in set L (for lazy alg.)",lrmax+1,strat->Lmax);
4364  Print("product criterion:%d chain criterion:%d\n",strat->cp,strat->c3);
4365  if (hilbcount!=0) Print("hilbert series criterion:%d\n",hilbcount);
4366  /* in usual case strat->cv is 0, it gets changed only in shift routines */
4367  if (strat->cv!=0) Print("shift V criterion:%d\n",strat->cv);
4368  /*mflush();*/
4369}
4370
4371#ifdef KDEBUG
4372/*2
4373*debugging output: all internal sets, if changed
4374*for testing purpuse only/has to be changed for later use
4375*/
4376void messageSets (kStrategy strat)
4377{
4378  int i;
4379  if (strat->news)
4380  {
4381    PrintS("set S");
4382    for (i=0; i<=strat->sl; i++)
4383    {
4384      Print("\n  %d:",i);
4385      p_wrp(strat->S[i], currRing, strat->tailRing);
4386    }
4387    strat->news = FALSE;
4388  }
4389  if (strat->newt)
4390  {
4391    PrintS("\nset T");
4392    for (i=0; i<=strat->tl; i++)
4393    {
4394      Print("\n  %d:",i);
4395      strat->T[i].wrp();
4396      Print(" o:%d e:%d l:%d",
4397        strat->T[i].pFDeg(),strat->T[i].ecart,strat->T[i].length);
4398    }
4399    strat->newt = FALSE;
4400  }
4401  PrintS("\nset L");
4402  for (i=strat->Ll; i>=0; i--)
4403  {
4404    Print("\n%d:",i);
4405    p_wrp(strat->L[i].p1, currRing, strat->tailRing);
4406    PrintS("  ");
4407    p_wrp(strat->L[i].p2, currRing, strat->tailRing);
4408    PrintS(" lcm: ");p_wrp(strat->L[i].lcm, currRing);
4409    PrintS("\n  p : ");
4410    strat->L[i].wrp();
4411    Print("  o:%d e:%d l:%d",
4412          strat->L[i].pFDeg(),strat->L[i].ecart,strat->L[i].length);
4413  }
4414  PrintLn();
4415}
4416
4417#endif
4418
4419
4420/*2
4421*construct the set s from F
4422*/
4423void initS (ideal F, ideal Q,kStrategy strat)
4424{
4425  int   i,pos;
4426
4427  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
4428  else i=setmaxT;
4429  strat->ecartS=initec(i);
4430  strat->sevS=initsevS(i);
4431  strat->S_2_R=initS_2_R(i);
4432  strat->fromQ=NULL;
4433  strat->Shdl=idInit(i,F->rank);
4434  strat->S=strat->Shdl->m;
4435  /*- put polys into S -*/
4436  if (Q!=NULL)
4437  {
4438    strat->fromQ=initec(i);
4439    memset(strat->fromQ,0,i*sizeof(int));
4440    for (i=0; i<IDELEMS(Q); i++)
4441    {
4442      if (Q->m[i]!=NULL)
4443      {
4444        LObject h;
4445        h.p = pCopy(Q->m[i]);
4446        if (TEST_OPT_INTSTRATEGY)
4447        {
4448          //pContent(h.p);
4449          h.pCleardenom(); // also does a pContent
4450        }
4451        else
4452        {
4453          h.pNorm();
4454        }
4455        if (pOrdSgn==-1)
4456        {
4457          deleteHC(&h, strat);
4458        }
4459        if (h.p!=NULL)
4460        {
4461          strat->initEcart(&h);
4462          if (strat->sl==-1)
4463            pos =0;
4464          else
4465          {
4466            pos = posInS(strat,strat->sl,h.p,h.ecart);
4467          }
4468          h.sev = pGetShortExpVector(h.p);
4469          strat->enterS(h,pos,strat,-1);
4470          strat->fromQ[pos]=1;
4471        }
4472      }
4473    }
4474  }
4475  for (i=0; i<IDELEMS(F); i++)
4476  {
4477    if (F->m[i]!=NULL)
4478    {
4479      LObject h;
4480      h.p = pCopy(F->m[i]);
4481      if (pOrdSgn==-1)
4482      {
4483        cancelunit(&h);  /*- tries to cancel a unit -*/
4484        deleteHC(&h, strat);
4485      }
4486      if (TEST_OPT_INTSTRATEGY)
4487      {
4488        //pContent(h.p);
4489        h.pCleardenom(); // also does a pContent
4490      }
4491      else
4492      {
4493        h.pNorm();
4494      }
4495      if (h.p!=NULL)
4496      {
4497        strat->initEcart(&h);
4498        if (strat->sl==-1)
4499          pos =0;
4500        else
4501          pos = posInS(strat,strat->sl,h.p,h.ecart);
4502        h.sev = pGetShortExpVector(h.p);
4503        strat->enterS(h,pos,strat,-1);
4504      }
4505    }
4506  }
4507  /*- test, if a unit is in F -*/
4508  if ((strat->sl>=0)
4509#ifdef HAVE_RINGS
4510       && nIsUnit(pGetCoeff(strat->S[0]))
4511#endif
4512       && pIsConstant(strat->S[0]))
4513  {
4514    while (strat->sl>0) deleteInS(strat->sl,strat);
4515  }
4516}
4517
4518void initSL (ideal F, ideal Q,kStrategy strat)
4519{
4520  int   i,pos;
4521
4522  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
4523  else i=setmaxT;
4524  strat->ecartS=initec(i);
4525  strat->sevS=initsevS(i);
4526  strat->S_2_R=initS_2_R(i);
4527  strat->fromQ=NULL;
4528  strat->Shdl=idInit(i,F->rank);
4529  strat->S=strat->Shdl->m;
4530  /*- put polys into S -*/
4531  if (Q!=NULL)
4532  {
4533    strat->fromQ=initec(i);
4534    memset(strat->fromQ,0,i*sizeof(int));
4535    for (i=0; i<IDELEMS(Q); i++)
4536    {
4537      if (Q->m[i]!=NULL)
4538      {
4539        LObject h;
4540        h.p = pCopy(Q->m[i]);
4541        if (pOrdSgn==-1)
4542        {
4543          deleteHC(&h,strat);
4544        }
4545        if (TEST_OPT_INTSTRATEGY)
4546        {
4547          //pContent(h.p);
4548          h.pCleardenom(); // also does a pContent
4549        }
4550        else
4551        {
4552          h.pNorm();
4553        }
4554        if (h.p!=NULL)
4555        {
4556          strat->initEcart(&h);
4557          if (strat->sl==-1)
4558            pos =0;
4559          else
4560          {
4561            pos = posInS(strat,strat->sl,h.p,h.ecart);
4562          }
4563          h.sev = pGetShortExpVector(h.p);
4564          strat->enterS(h,pos,strat,-1);
4565          strat->fromQ[pos]=1;
4566        }
4567      }
4568    }
4569  }
4570  for (i=0; i<IDELEMS(F); i++)
4571  {
4572    if (F->m[i]!=NULL)
4573    {
4574      LObject h;
4575      h.p = pCopy(F->m[i]);
4576      if (h.p!=NULL)
4577      {
4578        if (pOrdSgn==-1)
4579        {
4580          cancelunit(&h);  /*- tries to cancel a unit -*/
4581          deleteHC(&h, strat);
4582        }
4583        if (h.p!=NULL)
4584        {
4585          if (TEST_OPT_INTSTRATEGY)
4586          {
4587            //pContent(h.p);
4588            h.pCleardenom(); // also does a pContent
4589          }
4590          else
4591          {
4592            h.pNorm();
4593          }
4594          strat->initEcart(&h);
4595          if (strat->Ll==-1)
4596            pos =0;
4597          else
4598            pos = strat->posInL(strat->L,strat->Ll,&h,strat);
4599          h.sev = pGetShortExpVector(h.p);
4600          enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
4601        }
4602      }
4603    }
4604  }
4605  /*- test, if a unit is in F -*/
4606
4607  if ((strat->Ll>=0) 
4608#ifdef HAVE_RINGS
4609       && nIsUnit(pGetCoeff(strat->L[strat->Ll].p))
4610#endif
4611       && pIsConstant(strat->L[strat->Ll].p))
4612  {
4613    while (strat->Ll>0) deleteInL(strat->L,&strat->Ll,strat->Ll-1,strat);
4614  }
4615}
4616
4617
4618/*2
4619*construct the set s from F and {P}
4620*/
4621void initSSpecial (ideal F, ideal Q, ideal P,kStrategy strat)
4622{
4623  int   i,pos;
4624
4625  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
4626  else i=setmaxT;
4627  i=((i+IDELEMS(F)+IDELEMS(P)+15)/16)*16;
4628  strat->ecartS=initec(i);
4629  strat->sevS=initsevS(i);
4630  strat->S_2_R=initS_2_R(i);
4631  strat->fromQ=NULL;
4632  strat->Shdl=idInit(i,F->rank);
4633  strat->S=strat->Shdl->m;
4634
4635  /*- put polys into S -*/
4636  if (Q!=NULL)
4637  {
4638    strat->fromQ=initec(i);
4639    memset(strat->fromQ,0,i*sizeof(int));
4640    for (i=0; i<IDELEMS(Q); i++)
4641    {
4642      if (Q->m[i]!=NULL)
4643      {
4644        LObject h;
4645        h.p = pCopy(Q->m[i]);
4646        //if (TEST_OPT_INTSTRATEGY)
4647        //{
4648        //  //pContent(h.p);
4649        //  h.pCleardenom(); // also does a pContent
4650        //}
4651        //else
4652        //{
4653        //  h.pNorm();
4654        //}
4655        if (pOrdSgn==-1)
4656        {
4657          deleteHC(&h,strat);
4658        }
4659        if (h.p!=NULL)
4660        {
4661          strat->initEcart(&h);
4662          if (strat->sl==-1)
4663            pos =0;
4664          else
4665          {
4666            pos = posInS(strat,strat->sl,h.p,h.ecart);
4667          }
4668          h.sev = pGetShortExpVector(h.p);
4669          strat->enterS(h,pos,strat, strat->tl+1);
4670          enterT(h, strat);
4671          strat->fromQ[pos]=1;
4672        }
4673      }
4674    }
4675  }
4676  /*- put polys into S -*/
4677  for (i=0; i<IDELEMS(F); i++)
4678  {
4679    if (F->m[i]!=NULL)
4680    {
4681      LObject h;
4682      h.p = pCopy(F->m[i]);
4683      if (pOrdSgn==-1)
4684      {
4685        deleteHC(&h,strat);
4686      }
4687      else
4688      {
4689        h.p=redtailBba(h.p,strat->sl,strat);
4690      }
4691      if (h.p!=NULL)
4692      {
4693        strat->initEcart(&h);
4694        if (strat->sl==-1)
4695          pos =0;
4696        else
4697          pos = posInS(strat,strat->sl,h.p,h.ecart);
4698        h.sev = pGetShortExpVector(h.p);
4699        strat->enterS(h,pos,strat, strat->tl+1);
4700        enterT(h,strat);
4701      }
4702    }
4703  }
4704  for (i=0; i<IDELEMS(P); i++)
4705  {
4706    if (P->m[i]!=NULL)
4707    {
4708      LObject h;
4709      h.p=pCopy(P->m[i]);
4710      if (TEST_OPT_INTSTRATEGY)
4711      {
4712        h.pCleardenom();
4713      }
4714      else
4715      {
4716        h.pNorm();
4717      }
4718      if(strat->sl>=0)
4719      {
4720        if (pOrdSgn==1)
4721        {
4722          h.p=redBba(h.p,strat->sl,strat);
4723          if (h.p!=NULL)
4724          {
4725            h.p=redtailBba(h.p,strat->sl,strat);
4726          }
4727        }
4728        else
4729        {
4730          h.p=redMora(h.p,strat->sl,strat);
4731        }
4732        if(h.p!=NULL)
4733        {
4734          strat->initEcart(&h);
4735          if (TEST_OPT_INTSTRATEGY)
4736          {
4737            h.pCleardenom();
4738          }
4739          else
4740          {
4741            h.is_normalized = 0;
4742            h.pNorm();
4743          }
4744          h.sev = pGetShortExpVector(h.p);
4745          h.SetpFDeg();
4746          pos = posInS(strat,strat->sl,h.p,h.ecart);
4747          enterpairsSpecial(h.p,strat->sl,h.ecart,pos,strat,strat->tl+1);
4748          strat->enterS(h,pos,strat, strat->tl+1);
4749          enterT(h,strat);
4750        }
4751      }
4752      else
4753      {
4754        h.sev = pGetShortExpVector(h.p);
4755        strat->initEcart(&h);
4756        strat->enterS(h,0,strat, strat->tl+1);
4757        enterT(h,strat);
4758      }
4759    }
4760  }
4761}
4762/*2
4763* reduces h using the set S
4764* procedure used in cancelunit1
4765*/
4766static poly redBba1 (poly h,int maxIndex,kStrategy strat)
4767{
4768  int j = 0;
4769  unsigned long not_sev = ~ pGetShortExpVector(h);
4770
4771  while (j <= maxIndex)
4772  {
4773    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j],h, not_sev))
4774       return ksOldSpolyRedNew(strat->S[j],h,strat->kNoetherTail());
4775    else j++;
4776  }
4777  return h;
4778}
4779
4780/*2
4781*tests if p.p=monomial*unit and cancels the unit
4782*/
4783void cancelunit1 (LObject* p,int *suc, int index,kStrategy strat )
4784{
4785  int k;
4786  poly r,h,h1,q;
4787
4788  if (!pIsVector((*p).p) && ((*p).ecart != 0))
4789  {
4790    k = 0;
4791    h1 = r = pCopy((*p).p);
4792    h =pNext(r);
4793    loop
4794    {
4795      if (h==NULL)
4796      {
4797        pDelete(&r);
4798        pDelete(&(pNext((*p).p)));
4799        (*p).ecart = 0;
4800        (*p).length = 1;
4801        (*suc)=0;
4802        return;
4803      }
4804      if (!pDivisibleBy(r,h))
4805      {
4806        q=redBba1(h,index ,strat);
4807        if (q != h)
4808        {
4809          k++;
4810          pDelete(&h);
4811          pNext(h1) = h = q;
4812        }
4813        else
4814        {
4815          pDelete(&r);
4816          return;
4817        }
4818      }
4819      else
4820      {
4821        h1 = h;
4822        pIter(h);
4823      }
4824      if (k > 10)
4825      {
4826        pDelete(&r);
4827        return;
4828      }
4829    }
4830  }
4831}
4832
4833#if 0
4834/*2
4835* reduces h using the elements from Q in the set S
4836* procedure used in updateS
4837* must not be used for elements of Q or elements of an ideal !
4838*/
4839static poly redQ (poly h, int j, kStrategy strat)
4840{
4841  int start;
4842  unsigned long not_sev = ~ pGetShortExpVector(h);
4843  while ((j <= strat->sl) && (pGetComp(strat->S[j])!=0)) j++;
4844  start=j;
4845  while (j<=strat->sl)
4846  {
4847    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev))
4848    {
4849      h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
4850      if (h==NULL) return NULL;
4851      j = start;
4852      not_sev = ~ pGetShortExpVector(h);
4853    }
4854    else j++;
4855  }
4856  return h;
4857}
4858#endif
4859
4860/*2
4861* reduces h using the set S
4862* procedure used in updateS
4863*/
4864static poly redBba (poly h,int maxIndex,kStrategy strat)
4865{
4866  int j = 0;
4867  unsigned long not_sev = ~ pGetShortExpVector(h);
4868
4869  while (j <= maxIndex)
4870  {
4871    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev))
4872    {
4873      h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
4874      if (h==NULL) return NULL;
4875      j = 0;
4876      not_sev = ~ pGetShortExpVector(h);    }
4877    else j++;
4878  }
4879  return h;
4880}
4881
4882/*2
4883* reduces h using the set S
4884*e is the ecart of h
4885*procedure used in updateS
4886*/
4887static poly redMora (poly h,int maxIndex,kStrategy strat)
4888{
4889  int  j=0;
4890  int  e,l;
4891  unsigned long not_sev = ~ pGetShortExpVector(h);
4892
4893  if (maxIndex >= 0)
4894  {
4895    e = pLDeg(h,&l,currRing)-pFDeg(h,currRing);
4896    do
4897    {
4898      if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev)
4899      && ((e >= strat->ecartS[j]) || strat->kHEdgeFound))
4900      {
4901#ifdef KDEBUG
4902        if (TEST_OPT_DEBUG)
4903          {PrintS("reduce ");wrp(h);Print(" with S[%d] (",j);wrp(strat->S[j]);}
4904#endif
4905        h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
4906#ifdef KDEBUG
4907        if(TEST_OPT_DEBUG)
4908          {PrintS(")\nto "); wrp(h); PrintLn();}
4909#endif
4910        // pDelete(&h);
4911        if (h == NULL) return NULL;
4912        e = pLDeg(h,&l,currRing)-pFDeg(h,currRing);
4913        j = 0;
4914        not_sev = ~ pGetShortExpVector(h);
4915      }
4916      else j++;
4917    }
4918    while (j <= maxIndex);
4919  }
4920  return h;
4921}
4922
4923/*2
4924*updates S:
4925*the result is a set of polynomials which are in
4926*normalform with respect to S
4927*/
4928void updateS(BOOLEAN toT,kStrategy strat)
4929{
4930  LObject h;
4931  int i, suc=0;
4932  poly redSi=NULL;
4933  BOOLEAN change,any_change;
4934//  Print("nach initS: updateS start mit sl=%d\n",(strat->sl));
4935//  for (i=0; i<=(strat->sl); i++)
4936//  {
4937//    Print("s%d:",i);
4938//    if (strat->fromQ!=NULL) Print("(Q:%d) ",strat->fromQ[i]);
4939//    pWrite(strat->S[i]);
4940//  }
4941//  Print("pOrdSgn=%d\n", pOrdSgn);
4942  any_change=FALSE;
4943  if (pOrdSgn==1)
4944  {
4945    while (suc != -1)
4946    {
4947      i=suc+1;
4948      while (i<=strat->sl)
4949      {
4950        change=FALSE;
4951        if (((strat->fromQ==NULL) || (strat->fromQ[i]==0)) && (i>0))
4952        {
4953          redSi = pHead(strat->S[i]);
4954          strat->S[i] = redBba(strat->S[i],i-1,strat);
4955          //if ((strat->ak!=0)&&(strat->S[i]!=NULL))
4956          //  strat->S[i]=redQ(strat->S[i],i+1,strat); /*reduce S[i] mod Q*/
4957          if (pCmp(redSi,strat->S[i])!=0)
4958          {
4959            change=TRUE;
4960            any_change=TRUE;
4961            #ifdef KDEBUG
4962            if (TEST_OPT_DEBUG)
4963            {
4964              PrintS("reduce:");
4965              wrp(redSi);PrintS(" to ");p_wrp(strat->S[i], currRing, strat->tailRing);PrintLn();
4966            }
4967            #endif
4968            if (TEST_OPT_PROT)
4969            {
4970              if (strat->S[i]==NULL)
4971                PrintS("V");
4972              else
4973                PrintS("v");
4974              mflush();
4975            }
4976          }
4977          pDeleteLm(&redSi);
4978          if (strat->S[i]==NULL)
4979          {
4980            deleteInS(i,strat);
4981            i--;
4982          }
4983          else if (change)
4984          {
4985            if (TEST_OPT_INTSTRATEGY)
4986            {
4987              //pContent(strat->S[i]);
4988              pCleardenom(strat->S[i]);// also does a pContent
4989            }
4990            else
4991            {
4992              pNorm(strat->S[i]);
4993            }
4994            strat->sevS[i] = pGetShortExpVector(strat->S[i]);
4995          }
4996        }
4997        i++;
4998      }
4999      if (any_change) reorderS(&suc,strat);
5000      else break;
5001    }
5002    if (toT)
5003    {
5004      for (i=0; i<=strat->sl; i++)
5005      {
5006        if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
5007        {
5008          h.p = redtailBba(strat->S[i],i-1,strat);
5009          if (TEST_OPT_INTSTRATEGY)
5010          {
5011            pCleardenom(h.p);// also does a pContent
5012          }
5013        }
5014        else
5015        {
5016          h.p = strat->S[i];
5017        }
5018        strat->initEcart(&h);
5019        if (strat->honey)
5020        {
5021          strat->ecartS[i] = h.ecart;
5022        }
5023        if (strat->sevS[i] == 0) {strat->sevS[i] = pGetShortExpVector(h.p);}
5024        else assume(strat->sevS[i] == pGetShortExpVector(h.p));
5025        h.sev = strat->sevS[i];
5026        /*puts the elements of S also to T*/
5027        enterT(h,strat);
5028        strat->S_2_R[i] = strat->tl;
5029      }
5030    }
5031  }
5032  else
5033  {
5034    while (suc != -1)
5035    {
5036      i=suc;
5037      while (i<=strat->sl)
5038      {
5039        change=FALSE;
5040        if (((strat->fromQ==NULL) || (strat->fromQ[i]==0)) && (i>0))
5041        {
5042          redSi=pHead((strat->S)[i]);
5043          (strat->S)[i] = redMora((strat->S)[i],i-1,strat);
5044          if ((strat->S)[i]==NULL)
5045          {
5046            deleteInS(i,strat);
5047            i--;
5048          }
5049          else if (pCmp((strat->S)[i],redSi)!=0)
5050          {
5051            any_change=TRUE;
5052            h.p = strat->S[i];
5053            strat->initEcart(&h);
5054            strat->ecartS[i] = h.ecart;
5055            if (TEST_OPT_INTSTRATEGY)
5056            {
5057              pCleardenom(strat->S[i]);// also does a pContent
5058            }
5059            else
5060            {
5061              pNorm(strat->S[i]); // == h.p
5062            }
5063            h.sev =  pGetShortExpVector(h.p);
5064            strat->sevS[i] = h.sev;
5065          }
5066          pDeleteLm(&redSi);
5067          kTest(strat);
5068        }
5069        i++;
5070      }
5071#ifdef KDEBUG
5072      kTest(strat);
5073#endif
5074      if (any_change) reorderS(&suc,strat);
5075      else { suc=-1; break; }
5076      if (h.p!=NULL)
5077      {
5078        if (!strat->kHEdgeFound)
5079        {
5080          /*strat->kHEdgeFound =*/ HEckeTest(h.p,strat);
5081        }
5082        if (strat->kHEdgeFound)
5083          newHEdge(strat->S,strat);
5084      }
5085    }
5086    for (i=0; i<=strat->sl; i++)
5087    {
5088      if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
5089      {
5090        strat->S[i] = h.p = redtail(strat->S[i],strat->sl,strat);
5091        strat->initEcart(&h);
5092        strat->ecartS[i] = h.ecart;
5093        h.sev = pGetShortExpVector(h.p);
5094        strat->sevS[i] = h.sev;
5095      }
5096      else
5097      {
5098        h.p = strat->S[i];
5099        h.ecart=strat->ecartS[i];
5100        h.sev = strat->sevS[i];
5101        h.length = h.pLength = pLength(h.p);
5102      }
5103      if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
5104        cancelunit1(&h,&suc,strat->sl,strat);
5105      h.SetpFDeg();
5106      /*puts the elements of S also to T*/
5107      enterT(h,strat);
5108      strat->S_2_R[i] = strat->tl;
5109    }
5110    if (suc!= -1) updateS(toT,strat);
5111  }
5112#ifdef KDEBUG
5113  kTest(strat);
5114#endif
5115}
5116
5117
5118/*2
5119* -puts p to the standardbasis s at position at
5120* -saves the result in S
5121*/
5122void enterSBba (LObject p,int atS,kStrategy strat, int atR)
5123{
5124  int i;
5125  strat->news = TRUE;
5126  /*- puts p to the standardbasis s at position at -*/
5127  if (strat->sl == IDELEMS(strat->Shdl)-1)
5128  {
5129    strat->sevS = (unsigned long*) omRealloc0Size(strat->sevS,
5130                                    IDELEMS(strat->Shdl)*sizeof(unsigned long),
5131                                    (IDELEMS(strat->Shdl)+setmaxTinc)
5132                                                  *sizeof(unsigned long));
5133    strat->ecartS = (intset)omReallocSize(strat->ecartS,
5134                                          IDELEMS(strat->Shdl)*sizeof(int),
5135                                          (IDELEMS(strat->Shdl)+setmaxTinc)
5136                                                  *sizeof(int));
5137    strat->S_2_R = (int*) omRealloc0Size(strat->S_2_R,
5138                                         IDELEMS(strat->Shdl)*sizeof(int),
5139                                         (IDELEMS(strat->Shdl)+setmaxTinc)
5140                                                  *sizeof(int));
5141    if (strat->lenS!=NULL)
5142      strat->lenS=(int*)omRealloc0Size(strat->lenS,
5143                                       IDELEMS(strat->Shdl)*sizeof(int),
5144                                       (IDELEMS(strat->Shdl)+setmaxTinc)
5145                                                 *sizeof(int));
5146    if (strat->lenSw!=NULL)
5147      strat->lenSw=(wlen_type*)omRealloc0Size(strat->lenSw,
5148                                       IDELEMS(strat->Shdl)*sizeof(wlen_type),
5149                                       (IDELEMS(strat->Shdl)+setmaxTinc)
5150                                                 *sizeof(wlen_type));
5151    if (strat->fromQ!=NULL)
5152    {
5153      strat->fromQ = (intset)omReallocSize(strat->fromQ,
5154                                    IDELEMS(strat->Shdl)*sizeof(int),
5155                                    (IDELEMS(strat->Shdl)+setmaxTinc)*sizeof(int));
5156    }
5157    pEnlargeSet(&strat->S,IDELEMS(strat->Shdl),setmaxTinc);
5158    IDELEMS(strat->Shdl)+=setmaxTinc;
5159    strat->Shdl->m=strat->S;
5160  }
5161  if (atS <= strat->sl)
5162  {
5163#ifdef ENTER_USE_MEMMOVE
5164// #if 0
5165    memmove(&(strat->S[atS+1]), &(strat->S[atS]),
5166            (strat->sl - atS + 1)*sizeof(poly));
5167    memmove(&(strat->ecartS[atS+1]), &(strat->ecartS[atS]),
5168            (strat->sl - atS + 1)*sizeof(int));
5169    memmove(&(strat->sevS[atS+1]), &(strat->sevS[atS]),
5170            (strat->sl - atS + 1)*sizeof(unsigned long));
5171    memmove(&(strat->S_2_R[atS+1]), &(strat->S_2_R[atS]),
5172            (strat->sl - atS + 1)*sizeof(int));
5173    if (strat->lenS!=NULL)
5174    memmove(&(strat->lenS[atS+1]), &(strat->lenS[atS]),
5175            (strat->sl - atS + 1)*sizeof(int));
5176    if (strat->lenSw!=NULL)
5177    memmove(&(strat->lenSw[atS+1]), &(strat->lenSw[atS]),
5178            (strat->sl - atS + 1)*sizeof(wlen_type));
5179#else
5180    for (i=strat->sl+1; i>=atS+1; i--)
5181    {
5182      strat->S[i] = strat->S[i-1];
5183      strat->ecartS[i] = strat->ecartS[i-1];
5184      strat->sevS[i] = strat->sevS[i-1];
5185      strat->S_2_R[i] = strat->S_2_R[i-1];
5186    }
5187    if (strat->lenS!=NULL)
5188    for (i=strat->sl+1; i>=atS+1; i--)
5189      strat->lenS[i] = strat->lenS[i-1];
5190    if (strat->lenSw!=NULL)
5191    for (i=strat->sl+1; i>=atS+1; i--)
5192      strat->lenSw[i] = strat->lenSw[i-1];
5193#endif
5194  }
5195  if (strat->fromQ!=NULL)
5196  {
5197#ifdef ENTER_USE_MEMMOVE
5198    memmove(&(strat->fromQ[atS+1]), &(strat->fromQ[atS]),
5199                  (strat->sl - atS + 1)*sizeof(int));
5200#else
5201    for (i=strat->sl+1; i>=atS+1; i--)
5202    {
5203      strat->fromQ[i] = strat->fromQ[i-1];
5204    }
5205#endif
5206    strat->fromQ[atS]=0;
5207  }
5208
5209  /*- save result -*/
5210  strat->S[atS] = p.p;
5211  if (strat->honey) strat->ecartS[atS] = p.ecart;
5212  if (p.sev == 0)
5213    p.sev = pGetShortExpVector(p.p);
5214  else
5215    assume(p.sev == pGetShortExpVector(p.p));
5216  strat->sevS[atS] = p.sev;
5217  strat->ecartS[atS] = p.ecart;
5218  strat->S_2_R[atS] = atR;
5219  strat->sl++;
5220}
5221
5222/*2
5223* puts p to the set T at position atT
5224*/
5225void enterT(LObject p, kStrategy strat, int atT)
5226{
5227  int i;
5228
5229  pp_Test(p.p, currRing, p.tailRing);
5230  assume(strat->tailRing == p.tailRing);
5231  // redMoraNF complains about this -- but, we don't really
5232  // neeed this so far
5233  assume(p.pLength == 0 || pLength(p.p) == p.pLength);
5234  assume(p.FDeg == p.pFDeg());
5235  assume(!p.is_normalized || nIsOne(pGetCoeff(p.p)));
5236
5237#ifdef KDEBUG 
5238  // do not put an LObject twice into T:
5239  for(i=strat->tl;i>=0;i--)
5240  {
5241    if (p.p==strat->T[i].p) 
5242    {
5243      printf("already in T at pos %d of %d, atT=%d\n",i,strat->tl,atT);
5244      return;
5245    }
5246  }
5247#endif 
5248  strat->newt = TRUE;
5249  if (atT < 0)
5250    atT = strat->posInT(strat->T, strat->tl, p);
5251  if (strat->tl == strat->tmax-1)
5252    enlargeT(strat->T,strat->R,strat->sevT,strat->tmax,setmaxTinc);
5253  if (atT <= strat->tl)
5254  {
5255#ifdef ENTER_USE_MEMMOVE
5256    memmove(&(strat->T[atT+1]), &(strat->T[atT]),
5257            (strat->tl-atT+1)*sizeof(TObject));
5258    memmove(&(strat->sevT[atT+1]), &(strat->sevT[atT]),
5259            (strat->tl-atT+1)*sizeof(unsigned long));
5260#endif
5261    for (i=strat->tl+1; i>=atT+1; i--)
5262    {
5263#ifndef ENTER_USE_MEMMOVE
5264      strat->T[i] = strat->T[i-1];
5265      strat->sevT[i] = strat->sevT[i-1];
5266#endif
5267      strat->R[strat->T[i].i_r] = &(strat->T[i]);
5268    }
5269  }
5270
5271  if (strat->tailBin != NULL && (pNext(p.p) != NULL))
5272  {
5273    pNext(p.p)=p_ShallowCopyDelete(pNext(p.p),
5274                                   (strat->tailRing != NULL ?
5275                                    strat->tailRing : currRing),
5276                                   strat->tailBin);
5277    if (p.t_p != NULL) pNext(p.t_p) = pNext(p.p);
5278  }
5279  strat->T[atT] = (TObject) p;
5280
5281  if (strat->tailRing != currRing && pNext(p.p) != NULL)
5282    strat->T[atT].max = p_GetMaxExpP(pNext(p.p), strat->tailRing);
5283  else
5284    strat->T[atT].max = NULL;
5285
5286  strat->tl++;
5287  strat->R[strat->tl] = &(strat->T[atT]);
5288  strat->T[atT].i_r = strat->tl;
5289  assume(p.sev == 0 || pGetShortExpVector(p.p) == p.sev);
5290  strat->sevT[atT] = (p.sev == 0 ? pGetShortExpVector(p.p) : p.sev);
5291  kTest_T(&(strat->T[atT]));
5292}
5293
5294void initHilbCrit(ideal F, ideal Q, intvec **hilb,kStrategy strat)
5295{
5296  if (strat->homog!=isHomog)
5297  {
5298    *hilb=NULL;
5299  }
5300}
5301
5302void initBuchMoraCrit(kStrategy strat)
5303{
5304  strat->sugarCrit =        TEST_OPT_SUGARCRIT;
5305  // obachman: Hmm.. I need BTEST1(2) for notBuckets ..
5306  //  strat->Gebauer =          BTEST1(2) || strat->homog || strat->sugarCrit;
5307  strat->Gebauer =          strat->homog || strat->sugarCrit;
5308  strat->honey =            !strat->homog || strat->sugarCrit || TEST_OPT_WEIGHTM;
5309  if (TEST_OPT_NOT_SUGAR) strat->honey = FALSE;
5310  strat->pairtest = NULL;
5311  /* alway use tailreduction, except:
5312  * - in local rings, - in lex order case, -in ring over extensions */
5313  strat->noTailReduction = !TEST_OPT_REDTAIL;
5314
5315#ifdef HAVE_PLURAL
5316  // and r is plural_ring
5317  if( rIsPluralRing(currRing) || (rIsSCA(currRing) && !strat->z2homog) )
5318  {    //or it has non-quasi-comm type... later
5319    strat->sugarCrit = FALSE;
5320    strat->Gebauer = FALSE;
5321    strat->honey = FALSE;
5322  }
5323#endif
5324
5325#ifdef HAVE_RINGS
5326  // Coefficient ring?
5327  if (rField_is_Ring(currRing))
5328  {
5329    strat->sugarCrit = FALSE;
5330    strat->Gebauer = FALSE ;
5331    strat->honey = FALSE;
5332  }
5333#endif
5334  #ifdef KDEBUG
5335  if (TEST_OPT_DEBUG)
5336  {
5337    if (strat->homog) PrintS("ideal/module is homogeneous\n");
5338    else              PrintS("ideal/module is not homogeneous\n");
5339  }
5340  #endif
5341}
5342
5343BOOLEAN kPosInLDependsOnLength(int (*pos_in_l)
5344                               (const LSet set, const int length,
5345                                LObject* L,const kStrategy strat))
5346{
5347  if (pos_in_l == posInL110 ||
5348      pos_in_l == posInL10)
5349    return TRUE;
5350
5351  return FALSE;
5352}
5353
5354void initBuchMoraPos (kStrategy strat)
5355{
5356  if (pOrdSgn==1)
5357  {
5358    if (strat->honey)
5359    {
5360      strat->posInL = posInL15;
5361      // ok -- here is the deal: from my experiments for Singular-2-0
5362      // I conclude that that posInT_EcartpLength is the best of
5363      // posInT15, posInT_EcartFDegpLength, posInT_FDegLength, posInT_pLength
5364      // see the table at the end of this file
5365      if (K_TEST_OPT_OLDSTD)
5366        strat->posInT = posInT15;
5367      else
5368        strat->posInT = posInT_EcartpLength;
5369    }
5370    else if (pLexOrder && !TEST_OPT_INTSTRATEGY)
5371    {
5372      strat->posInL = posInL11;
5373      strat->posInT = posInT11;
5374    }
5375    else if (TEST_OPT_INTSTRATEGY)
5376    {
5377      strat->posInL = posInL11;
5378      strat->posInT = posInT11;
5379    }
5380    else
5381    {
5382      strat->posInL = posInL0;
5383      strat->posInT = posInT0;
5384    }
5385    //if (strat->minim>0) strat->posInL =posInLSpecial;
5386    if (strat->homog)
5387    {
5388       strat->posInL = posInL110;
5389       strat->posInT = posInT110;
5390    }
5391  }
5392  else
5393  {
5394    if (strat->homog)
5395    {
5396      strat->posInL = posInL11;
5397      strat->posInT = posInT11;
5398    }
5399    else
5400    {
5401      if ((currRing->order[0]==ringorder_c)
5402      ||(currRing->order[0]==ringorder_C))
5403      {
5404        strat->posInL = posInL17_c;
5405        strat->posInT = posInT17_c;
5406      }
5407      else
5408      {
5409        strat->posInL = posInL17;
5410        strat->posInT = posInT17;
5411      }
5412    }
5413  }
5414  if (strat->minim>0) strat->posInL =posInLSpecial;
5415  // for further tests only
5416  if ((BTEST1(11)) || (BTEST1(12)))
5417    strat->posInL = posInL11;
5418  else if ((BTEST1(13)) || (BTEST1(14)))
5419    strat->posInL = posInL13;
5420  else if ((BTEST1(15)) || (BTEST1(16)))
5421    strat->posInL = posInL15;
5422  else if ((BTEST1(17)) || (BTEST1(18)))
5423    strat->posInL = posInL17;
5424  if (BTEST1(11))
5425    strat->posInT = posInT11;
5426  else if (BTEST1(13))
5427    strat->posInT = posInT13;
5428  else if (BTEST1(15))
5429    strat->posInT = posInT15;
5430  else if ((BTEST1(17)))
5431    strat->posInT = posInT17;
5432  else if ((BTEST1(19)))
5433    strat->posInT = posInT19;
5434  else if (BTEST1(12) || BTEST1(14) || BTEST1(16) || BTEST1(18))
5435    strat->posInT = posInT1;
5436#ifdef HAVE_RINGS
5437  if (rField_is_Ring(currRing))
5438  {
5439    strat->posInL = posInL11;
5440    strat->posInT = posInT11;
5441  }
5442#endif
5443  strat->posInLDependsOnLength = kPosInLDependsOnLength(strat->posInL);
5444}
5445
5446void initBuchMora (ideal F,ideal Q,kStrategy strat)
5447{
5448  strat->interpt = BTEST1(OPT_INTERRUPT);
5449  strat->kHEdge=NULL;
5450  if (pOrdSgn==1) strat->kHEdgeFound=FALSE;
5451  /*- creating temp data structures------------------- -*/
5452  strat->cp = 0;
5453  strat->c3 = 0;
5454  strat->tail = pInit();
5455  /*- set s -*/
5456  strat->sl = -1;
5457  /*- set L -*/
5458  strat->Lmax = setmaxL;
5459  strat->Ll = -1;
5460  strat->L = initL();
5461  /*- set B -*/
5462  strat->Bmax = setmaxL;
5463  strat->Bl = -1;
5464  strat->B = initL();
5465  /*- set T -*/
5466  strat->tl = -1;
5467  strat->tmax = setmaxT;
5468  strat->T = initT();
5469  strat->R = initR();
5470  strat->sevT = initsevT();
5471  /*- init local data struct.---------------------------------------- -*/
5472  strat->P.ecart=0;
5473  strat->P.length=0;
5474  if (pOrdSgn==-1)
5475  {
5476    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
5477    if (strat->kNoether!=NULL) pSetComp(strat->kNoetherTail(), strat->ak);
5478  }
5479  if(TEST_OPT_SB_1)
5480  {
5481    int i;
5482    ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
5483    for (i=strat->newIdeal;i<IDELEMS(F);i++)
5484    {
5485      P->m[i-strat->newIdeal] = F->m[i];
5486      F->m[i] = NULL;
5487    }
5488    initSSpecial(F,Q,P,strat);
5489    for (i=strat->newIdeal;i<IDELEMS(F);i++)
5490    {
5491      F->m[i] = P->m[i-strat->newIdeal];
5492      P->m[i-strat->newIdeal] = NULL;
5493    }
5494    idDelete(&P);
5495  }
5496  else
5497  {
5498    /*Shdl=*/initSL(F, Q,strat); /*sets also S, ecartS, fromQ */
5499    // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
5500  }
5501  strat->kIdeal = NULL;
5502  strat->fromT = FALSE;
5503  strat->noTailReduction = !TEST_OPT_REDTAIL;
5504  if (!TEST_OPT_SB_1)
5505  {
5506    updateS(TRUE,strat);
5507  }
5508  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
5509  strat->fromQ=NULL;
5510}
5511
5512void exitBuchMora (kStrategy strat)
5513{
5514  /*- release temp data -*/
5515  cleanT(strat);
5516  omFreeSize(strat->T,(strat->tmax)*sizeof(TObject));
5517  omFreeSize(strat->R,(strat->tmax)*sizeof(TObject*));
5518  omFreeSize(strat->sevT, (strat->tmax)*sizeof(unsigned long));
5519  omFreeSize(strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
5520  omFreeSize(strat->sevS,IDELEMS(strat->Shdl)*sizeof(int));
5521  omFreeSize(strat->S_2_R,IDELEMS(strat->Shdl)*sizeof(int));
5522  /*- set L: should be empty -*/
5523  omFreeSize(strat->L,(strat->Lmax)*sizeof(LObject));
5524  /*- set B: should be empty -*/
5525  omFreeSize(strat->B,(strat->Bmax)*sizeof(LObject));
5526  pDeleteLm(&strat->tail);
5527  strat->syzComp=0;
5528  if (strat->kIdeal!=NULL)
5529  {
5530    omFreeBin(strat->kIdeal, sleftv_bin);
5531    strat->kIdeal=NULL;
5532  }
5533}
5534
5535/*2
5536* in the case of a standardbase of a module over a qring:
5537* replace polynomials in i by ak vectors,
5538* (the polynomial * unit vectors gen(1)..gen(ak)
5539* in every case (also for ideals:)
5540* deletes divisible vectors/polynomials
5541*/
5542void updateResult(ideal r,ideal Q, kStrategy strat)
5543{
5544  int l;
5545  if (strat->ak>0)
5546  {
5547    for (l=IDELEMS(r)-1;l>=0;l--)
5548    {
5549      if ((r->m[l]!=NULL) && (pGetComp(r->m[l])==0))
5550      {
5551        pDelete(&r->m[l]); // and set it to NULL
5552      }
5553    }
5554    int q;
5555    poly p;
5556    for (l=IDELEMS(r)-1;l>=0;l--)
5557    {
5558      if ((r->m[l]!=NULL)
5559      && (strat->syzComp>0)
5560      && (pGetComp(r->m[l])<=strat->syzComp))
5561      {
5562        for(q=IDELEMS(Q)-1; q>=0;q--)
5563        {
5564          if ((Q->m[q]!=NULL)
5565          &&(pLmDivisibleBy(Q->m[q],r->m[l])))
5566          {
5567            if (TEST_OPT_REDSB)
5568            {
5569              p=r->m[l];
5570              r->m[l]=kNF(Q,NULL,p);
5571              pDelete(&p);
5572            }
5573            else
5574            {
5575              pDelete(&r->m[l]); // and set it to NULL
5576            }
5577            break;
5578          }
5579        }
5580      }
5581    }
5582  }
5583  else
5584  {
5585    int q;
5586    poly p;
5587    for (l=IDELEMS(r)-1;l>=0;l--)
5588    {
5589      if (r->m[l]!=NULL)
5590      {
5591        for(q=IDELEMS(Q)-1; q>=0;q--)
5592        {
5593          if ((Q->m[q]!=NULL)
5594          &&(pLmEqual(r->m[l],Q->m[q])))
5595          {
5596            if (TEST_OPT_REDSB)
5597            {
5598              p=r->m[l];
5599              r->m[l]=kNF(Q,NULL,p);
5600              pDelete(&p);
5601            }
5602            else
5603            {
5604              pDelete(&r->m[l]); // and set it to NULL
5605            }
5606            break;
5607          }
5608        }
5609      }
5610    }
5611  }
5612  idSkipZeroes(r);
5613}
5614
5615void completeReduce (kStrategy strat, BOOLEAN withT)
5616{
5617  int i;
5618  int low = (pOrdSgn == 1 ? 1 : 0);
5619  LObject L;
5620
5621#ifdef KDEBUG
5622  // need to set this: during tailreductions of T[i], T[i].max is out of
5623  // sync
5624  sloppy_max = TRUE;
5625#endif
5626
5627  strat->noTailReduction = FALSE;
5628  if (TEST_OPT_PROT)
5629  {
5630    PrintLn();
5631    if (timerv) writeTime("standard base computed:");
5632  }
5633  if (TEST_OPT_PROT)
5634  {
5635    Print("(S:%d)",strat->sl);mflush();
5636  }
5637  for (i=strat->sl; i>=low; i--)
5638  {
5639    TObject* T_j = strat->s_2_t(i);
5640    if (T_j != NULL)
5641    {
5642      L = *T_j;
5643      poly p;
5644      if (pOrdSgn == 1)
5645        strat->S[i] = redtailBba(&L, i-1, strat, withT);
5646      else
5647        strat->S[i] = redtail(&L, strat->sl, strat);
5648
5649      if (strat->redTailChange && strat->tailRing != currRing)
5650      {
5651        if (T_j->max != NULL) p_LmFree(T_j->max, strat->tailRing);
5652        if (pNext(T_j->p) != NULL)
5653          T_j->max = p_GetMaxExpP(pNext(T_j->p), strat->tailRing);
5654        else
5655          T_j->max = NULL;
5656      }
5657      if (TEST_OPT_INTSTRATEGY)
5658        T_j->pCleardenom();
5659    }
5660    else
5661    {
5662      assume(currRing == strat->tailRing);
5663      if (pOrdSgn == 1)
5664        strat->S[i] = redtailBba(strat->S[i], i-1, strat, withT);
5665      else
5666        strat->S[i] = redtail(strat->S[i], strat->sl, strat);
5667      if (TEST_OPT_INTSTRATEGY)
5668        pCleardenom(strat->S[i]);
5669    }
5670    if (TEST_OPT_PROT)
5671      PrintS("-");
5672  }
5673  if (TEST_OPT_PROT) PrintLn();
5674#ifdef KDEBUG
5675  sloppy_max = FALSE;
5676#endif
5677}
5678
5679
5680/*2
5681* computes the new strat->kHEdge and the new pNoether,
5682* returns TRUE, if pNoether has changed
5683*/
5684BOOLEAN newHEdge(polyset S, kStrategy strat)
5685{
5686  int i,j;
5687  poly newNoether;
5688
5689#if 0
5690  if (currRing->weight_all_1)
5691    scComputeHC(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
5692  else
5693    scComputeHCw(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
5694#else   
5695  scComputeHC(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
5696#endif 
5697  if (strat->t_kHEdge != NULL) p_LmFree(strat->t_kHEdge, strat->tailRing);
5698  if (strat->tailRing != currRing)
5699    strat->t_kHEdge = k_LmInit_currRing_2_tailRing(strat->kHEdge, strat->tailRing);
5700  /* compare old and new noether*/
5701  newNoether = pLmInit(strat->kHEdge);
5702  j = pFDeg(newNoether,currRing);
5703  for (i=1; i<=pVariables; i++)
5704  {
5705    if (pGetExp(newNoether, i) > 0) pDecrExp(newNoether,i);
5706  }
5707  pSetm(newNoether);
5708  if (j < strat->HCord) /*- statistics -*/
5709  {
5710    if (TEST_OPT_PROT)
5711    {
5712      Print("H(%d)",j);
5713      mflush();
5714    }
5715    strat->HCord=j;
5716    #ifdef KDEBUG
5717    if (TEST_OPT_DEBUG)
5718    {
5719      Print("H(%d):",j);
5720      wrp(strat->kHEdge);
5721      PrintLn();
5722    }
5723    #endif
5724  }
5725  if (pCmp(strat->kNoether,newNoether)!=1)
5726  {
5727    pDelete(&strat->kNoether);
5728    strat->kNoether=newNoether;
5729    if (strat->t_kNoether != NULL) p_LmFree(strat->t_kNoether, strat->tailRing);
5730    if (strat->tailRing != currRing)
5731      strat->t_kNoether = k_LmInit_currRing_2_tailRing(strat->kNoether, strat->tailRing);
5732
5733    return TRUE;
5734  }
5735  pLmFree(newNoether);
5736  return FALSE;
5737}
5738
5739/***************************************************************
5740 *
5741 * Routines related for ring changes during std computations
5742 *
5743 ***************************************************************/
5744BOOLEAN kCheckSpolyCreation(LObject *L, kStrategy strat, poly &m1, poly &m2)
5745{
5746  assume(L->p1 != NULL && L->p2 != NULL);
5747  // shift changes: from 0 to -1
5748  assume(L->i_r1 >= -1 && L->i_r1 <= strat->tl);
5749  assume(L->i_r2 >= -1 && L->i_r2 <= strat->tl);
5750  assume(strat->tailRing != currRing);
5751
5752  if (! k_GetLeadTerms(L->p1, L->p2, currRing, m1, m2, strat->tailRing))
5753    return FALSE;
5754  // shift changes: extra case inserted
5755  if ((L->i_r1 == -1) || (L->i_r2 == -1) )
5756  {
5757    return TRUE;
5758  }
5759  poly p1_max = (strat->R[L->i_r1])->max;
5760  poly p2_max = (strat->R[L->i_r2])->max;
5761
5762  if ((p1_max != NULL && !p_LmExpVectorAddIsOk(m1, p1_max, strat->tailRing)) ||
5763      (p2_max != NULL && !p_LmExpVectorAddIsOk(m2, p2_max, strat->tailRing)))
5764  {
5765    p_LmFree(m1, strat->tailRing);
5766    p_LmFree(m2, strat->tailRing);
5767    m1 = NULL;
5768    m2 = NULL;
5769    return FALSE;
5770  }
5771  return TRUE;
5772}
5773
5774BOOLEAN kStratChangeTailRing(kStrategy strat, LObject *L, TObject* T, unsigned long expbound)
5775{
5776  if (expbound == 0) expbound = strat->tailRing->bitmask << 1;
5777  if (expbound >= currRing->bitmask) return FALSE;
5778  ring new_tailRing = rModifyRing(currRing,
5779                                  // Hmmm .. the condition pFDeg == pDeg
5780                                  // might be too strong
5781#ifdef HAVE_RINGS
5782                                  (strat->homog && pFDeg == pDeg && !(rField_is_Ring(currRing))), // TODO Oliver
5783#else
5784                                  (strat->homog && pFDeg == pDeg),
5785#endif
5786                                  !strat->ak,
5787                                  expbound);
5788  if (new_tailRing == currRing) return TRUE;
5789
5790  strat->pOrigFDeg_TailRing = new_tailRing->pFDeg;
5791  strat->pOrigLDeg_TailRing = new_tailRing->pLDeg;
5792
5793  if (currRing->pFDeg != currRing->pFDegOrig)
5794  {
5795    new_tailRing->pFDeg = currRing->pFDeg;
5796    new_tailRing->pLDeg = currRing->pLDeg;
5797  }
5798
5799  if (TEST_OPT_PROT)
5800    Print("[%lu:%d", (unsigned long) new_tailRing->bitmask, new_tailRing->ExpL_Size);
5801  kTest_TS(strat);
5802  assume(new_tailRing != strat->tailRing);
5803  pShallowCopyDeleteProc p_shallow_copy_delete
5804    = pGetShallowCopyDeleteProc(strat->tailRing, new_tailRing);
5805
5806  omBin new_tailBin = omGetStickyBinOfBin(new_tailRing->PolyBin);
5807
5808  int i;
5809  for (i=0; i<=strat->tl; i++)
5810  {
5811    strat->T[i].ShallowCopyDelete(new_tailRing, new_tailBin,
5812                                  p_shallow_copy_delete);
5813  }
5814  for (i=0; i<=strat->Ll; i++)
5815  {
5816    assume(strat->L[i].p != NULL);
5817    if (pNext(strat->L[i].p) != strat->tail)
5818      strat->L[i].ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
5819  }
5820  if (strat->P.t_p != NULL ||
5821      (strat->P.p != NULL && pNext(strat->P.p) != strat->tail))
5822    strat->P.ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
5823
5824  if (L != NULL && L->tailRing != new_tailRing)
5825  {
5826    if (L->i_r < 0)
5827      L->ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
5828    else
5829    {
5830      assume(L->i_r <= strat->tl);
5831      TObject* t_l = strat->R[L->i_r];
5832      assume(t_l != NULL);
5833      L->tailRing = new_tailRing;
5834      L->p = t_l->p;
5835      L->t_p = t_l->t_p;
5836      L->max = t_l->max;
5837    }
5838  }
5839
5840  if (T != NULL && T->tailRing != new_tailRing && T->i_r < 0)
5841    T->ShallowCopyDelete(new_tailRing, new_tailBin, p_shallow_copy_delete);
5842
5843  omMergeStickyBinIntoBin(strat->tailBin, strat->tailRing->PolyBin);
5844  if (strat->tailRing != currRing)
5845    rKillModifiedRing(strat->tailRing);
5846
5847  strat->tailRing = new_tailRing;
5848  strat->tailBin = new_tailBin;
5849  strat->p_shallow_copy_delete
5850    = pGetShallowCopyDeleteProc(currRing, new_tailRing);
5851
5852  if (strat->kHEdge != NULL)
5853  {
5854    if (strat->t_kHEdge != NULL)
5855      p_LmFree(strat->t_kHEdge, strat->tailRing);
5856    strat->t_kHEdge=k_LmInit_currRing_2_tailRing(strat->kHEdge, new_tailRing);
5857  }
5858
5859  if (strat->kNoether != NULL)
5860  {
5861    if (strat->t_kNoether != NULL)
5862      p_LmFree(strat->t_kNoether, strat->tailRing);
5863    strat->t_kNoether=k_LmInit_currRing_2_tailRing(strat->kNoether,
5864                                                   new_tailRing);
5865  }
5866  kTest_TS(strat);
5867  if (TEST_OPT_PROT)
5868    PrintS("]");
5869  return TRUE;
5870}
5871
5872void kStratInitChangeTailRing(kStrategy strat)
5873{
5874  unsigned long l = 0;
5875  int i;
5876  Exponent_t e;
5877  ring new_tailRing;
5878
5879  assume(strat->tailRing == currRing);
5880
5881  for (i=0; i<= strat->Ll; i++)
5882  {
5883    l = p_GetMaxExpL(strat->L[i].p, currRing, l);
5884  }
5885  for (i=0; i<=strat->tl; i++)
5886  {
5887    // Hmm ... this we could do in one Step
5888    l = p_GetMaxExpL(strat->T[i].p, currRing, l);
5889  }
5890  if (rField_is_Ring(currRing))
5891  {
5892    l += 20; // TEMP, TODO OLI
5893    l *= 2;
5894  }
5895  e = p_GetMaxExp(l, currRing);
5896  if (e <= 1) e = 2;
5897
5898  kStratChangeTailRing(strat, NULL, NULL, e);
5899}
5900
5901skStrategy::skStrategy()
5902{
5903  memset(this, 0, sizeof(skStrategy));
5904#ifndef NDEBUG
5905  strat_nr++;
5906  nr=strat_nr;
5907  if (strat_fac_debug) Print("s(%d) created\n",nr);
5908#endif
5909  tailRing = currRing;
5910  P.tailRing = currRing;
5911  tl = -1;
5912  sl = -1;
5913#ifdef HAVE_LM_BIN
5914  lmBin = omGetStickyBinOfBin(currRing->PolyBin);
5915#endif
5916#ifdef HAVE_TAIL_BIN
5917  tailBin = omGetStickyBinOfBin(currRing->PolyBin);
5918#endif
5919  pOrigFDeg = pFDeg;
5920  pOrigLDeg = pLDeg;
5921}
5922
5923
5924skStrategy::~skStrategy()
5925{
5926  if (lmBin != NULL)
5927    omMergeStickyBinIntoBin(lmBin, currRing->PolyBin);
5928  if (tailBin != NULL)
5929    omMergeStickyBinIntoBin(tailBin,
5930                            (tailRing != NULL ? tailRing->PolyBin:
5931                             currRing->PolyBin));
5932  if (t_kHEdge != NULL)
5933    p_LmFree(t_kHEdge, tailRing);
5934  if (t_kNoether != NULL)
5935    p_LmFree(t_kNoether, tailRing);
5936
5937  if (currRing != tailRing)
5938    rKillModifiedRing(tailRing);
5939  pRestoreDegProcs(pOrigFDeg, pOrigLDeg);
5940}
5941
5942#if 0
5943Timings for the different possibilities of posInT:
5944            T15           EDL         DL          EL            L         1-2-3
5945Gonnet      43.26       42.30       38.34       41.98       38.40      100.04
5946Hairer_2_1   1.11        1.15        1.04        1.22        1.08        4.7
5947Twomat3      1.62        1.69        1.70        1.65        1.54       11.32
5948ahml         4.48        4.03        4.03        4.38        4.96       26.50
5949c7          15.02       13.98       15.16       13.24       17.31       47.89
5950c8         505.09      407.46      852.76      413.21      499.19        n/a
5951f855        12.65        9.27       14.97        8.78       14.23       33.12
5952gametwo6    11.47       11.35       14.57       11.20       12.02       35.07
5953gerhard_3    2.73        2.83        2.93        2.64        3.12        6.24
5954ilias13     22.89       22.46       24.62       20.60       23.34       53.86
5955noon8       40.68       37.02       37.99       36.82       35.59      877.16
5956rcyclic_19  48.22       42.29       43.99       45.35       51.51      204.29
5957rkat9       82.37       79.46       77.20       77.63       82.54      267.92
5958schwarz_11  16.46       16.81       16.76       16.81       16.72       35.56
5959test016     16.39       14.17       14.40       13.50       14.26       34.07
5960test017     34.70       36.01       33.16       35.48       32.75       71.45
5961test042     10.76       10.99       10.27       11.57       10.45       23.04
5962test058      6.78        6.75        6.51        6.95        6.22        9.47
5963test066     10.71       10.94       10.76       10.61       10.56       19.06
5964test073     10.75       11.11       10.17       10.79        8.63       58.10
5965test086     12.23       11.81       12.88       12.24       13.37       66.68
5966test103      5.05        4.80        5.47        4.64        4.89       11.90
5967test154     12.96       11.64       13.51       12.46       14.61       36.35
5968test162     65.27       64.01       67.35       59.79       67.54      196.46
5969test164      7.50        6.50        7.68        6.70        7.96       17.13
5970virasoro     3.39        3.50        3.35        3.47        3.70        7.66
5971#endif
5972
5973
5974#ifdef HAVE_MORE_POS_IN_T
5975// determines the position based on: 1.) Ecart 2.) FDeg 3.) pLength
5976int posInT_EcartFDegpLength(const TSet set,const int length,LObject &p)
5977{
5978
5979  if (length==-1) return 0;
5980
5981  int o = p.ecart;
5982  int op=p.GetpFDeg();
5983  int ol = p.GetpLength();
5984
5985  if (set[length].ecart < o)
5986    return length+1;
5987  if (set[length].ecart == o)
5988  {
5989     int oo=set[length].GetpFDeg();
5990     if ((oo < op) || ((oo==op) && (set[length].length < ol)))
5991       return length+1;
5992  }
5993
5994  int i;
5995  int an = 0;
5996  int en= length;
5997  loop
5998  {
5999    if (an >= en-1)
6000    {
6001      if (set[an].ecart > o)
6002        return an;
6003      if (set[an].ecart == o)
6004      {
6005         int oo=set[an].GetpFDeg();
6006         if((oo > op)
6007         || ((oo==op) && (set[an].pLength > ol)))
6008           return an;
6009      }
6010      return en;
6011    }
6012    i=(an+en) / 2;
6013    if (set[i].ecart > o)
6014      en=i;
6015    else if (set[i].ecart == o)
6016    {
6017       int oo=set[i].GetpFDeg();
6018       if ((oo > op)
6019       || ((oo == op) && (set[i].pLength > ol)))
6020         en=i;
6021       else
6022        an=i;
6023    }
6024    else
6025      an=i;
6026  }
6027}
6028
6029// determines the position based on: 1.) FDeg 2.) pLength
6030int posInT_FDegpLength(const TSet set,const int length,LObject &p)
6031{
6032
6033  if (length==-1) return 0;
6034
6035  int op=p.GetpFDeg();
6036  int ol = p.GetpLength();
6037
6038  int oo=set[length].GetpFDeg();
6039  if ((oo < op) || ((oo==op) && (set[length].length < ol)))
6040    return length+1;
6041
6042  int i;
6043  int an = 0;
6044  int en= length;
6045  loop
6046    {
6047      if (an >= en-1)
6048      {
6049        int oo=set[an].GetpFDeg();
6050        if((oo > op)
6051           || ((oo==op) && (set[an].pLength > ol)))
6052          return an;
6053        return en;
6054