source: git/kernel/kutil.cc @ 7245240

spielwiese
Last change on this file since 7245240 was 7245240, checked in by Oliver Wienand <wienand@…>, 16 years ago
stratChangeTailRing für gcd/strong polys git-svn-id: file:///usr/local/Singular/svn/trunk@10853 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 173.5 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: kutil.cc,v 1.100 2008-07-09 08:26:30 wienand 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  assume(atR >= 0);
1269  poly m1, m2, 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  while (! kCheckStrongCreation(atR, m1, i, m2, strat) )
1283  {
1284    memset(&(strat->P), 0, sizeof(strat->P));
1285    kStratChangeTailRing(strat);
1286    strat->P = *(strat->R[atR]);
1287    p_LmFree(m1, strat->tailRing);
1288    p_LmFree(m2, strat->tailRing);
1289    p_LmFree(gcd, currRing);
1290    k_GetStrongLeadTerms(p, strat->S[i], currRing, m1, m2, gcd, strat->tailRing);
1291  }
1292  pSetCoeff0(m1, s);
1293  pSetCoeff0(m2, t);
1294  pSetCoeff0(gcd, d);
1295
1296#ifdef KDEBUG
1297  if (TEST_OPT_DEBUG)
1298  {
1299    Print("t = %d; s = %d; d = %d\n", nInt(t), nInt(s), nInt(d));
1300    PrintS("m1 = ");
1301    p_wrp(m1, strat->tailRing);
1302    PrintS(" ; m2 = ");
1303    p_wrp(m2, strat->tailRing);
1304    PrintS(" ; gcd = ");
1305    wrp(gcd);
1306    PrintS("\n--- create strong gcd poly: ");
1307    Print("\n p: ", i);
1308    wrp(p);
1309    Print("\n strat->S[%d]: ", i);
1310    wrp(strat->S[i]);
1311    PrintS(" ---> ");
1312  }
1313#endif
1314
1315  pNext(gcd) = p_Add_q(pp_Mult_mm(pNext(p), m1, strat->tailRing), pp_Mult_mm(pNext(strat->S[i]), m2, strat->tailRing), strat->tailRing);
1316  p_LmDelete(m1, strat->tailRing);
1317  p_LmDelete(m2, strat->tailRing);
1318
1319#ifdef KDEBUG
1320    if (TEST_OPT_DEBUG)
1321    {
1322      wrp(gcd);
1323      PrintLn();
1324    }
1325#endif
1326
1327  LObject h;
1328  h.p = gcd;
1329  h.tailRing = strat->tailRing;
1330  int posx;
1331  h.pCleardenom();
1332    strat->initEcart(&h);
1333    if (strat->Ll==-1)
1334      posx =0;
1335    else
1336      posx = strat->posInL(strat->L,strat->Ll,&h,strat);
1337    h.sev = pGetShortExpVector(h.p);
1338    h.t_p = k_LmInit_currRing_2_tailRing(h.p, strat->tailRing);
1339    enterL(&strat->L,&strat->Ll,&strat->Lmax,h,posx);
1340  return TRUE;
1341}
1342#endif
1343
1344/*2
1345* put the pair (s[i],p)  into the set B, ecart=ecart(p)
1346*/
1347
1348
1349void enterOnePair (int i,poly p,int ecart, int isFromQ,kStrategy strat, int atR = -1)
1350{
1351  assume(i<=strat->sl);
1352  if (strat->interred_flag) return;
1353
1354  int      l,j,compare;
1355  LObject  Lp;
1356  Lp.i_r = -1;
1357
1358#ifdef KDEBUG
1359  Lp.ecart=0; Lp.length=0;
1360#endif
1361  /*- computes the lcm(s[i],p) -*/
1362  Lp.lcm = pInit();
1363
1364  pLcm(p,strat->S[i],Lp.lcm);
1365  pSetm(Lp.lcm);
1366
1367#define MYTEST 0
1368
1369#ifdef HAVE_PLURAL
1370  const BOOLEAN bIsPluralRing = rIsPluralRing(currRing);
1371  const BOOLEAN bIsSCA        = rIsSCA(currRing) && strat->z2homog; // for Z_2 prod-crit
1372  const BOOLEAN bNCProdCrit   = ( !bIsPluralRing || bIsSCA ); // commutative or homogeneous SCA
1373
1374#else
1375  const BOOLEAN bIsPluralRing = FALSE;
1376  const BOOLEAN bIsSCA        = FALSE;
1377  const BOOLEAN bNCProdCrit   = TRUE;
1378#endif
1379
1380
1381  if (strat->sugarCrit && bNCProdCrit)
1382  {
1383    if((!((strat->ecartS[i]>0)&&(ecart>0)))
1384    && pHasNotCF(p,strat->S[i]))
1385    {
1386    /*
1387    *the product criterion has applied for (s,p),
1388    *i.e. lcm(s,p)=product of the leading terms of s and p.
1389    *Suppose (s,r) is in L and the leading term
1390    *of p divides lcm(s,r)
1391    *(==> the leading term of p divides the leading term of r)
1392    *but the leading term of s does not divide the leading term of r
1393    *(notice that tis condition is automatically satisfied if r is still
1394    *in S), then (s,r) can be cancelled.
1395    *This should be done here because the
1396    *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
1397    *
1398    *Moreover, skipping (s,r) holds also for the noncommutative case.
1399    */
1400      strat->cp++;
1401      pLmFree(Lp.lcm);
1402      Lp.lcm=NULL;
1403      return;
1404    }
1405    else
1406      Lp.ecart = si_max(ecart,strat->ecartS[i]);
1407    if (strat->fromT && (strat->ecartS[i]>ecart))
1408    {
1409      pLmFree(Lp.lcm);
1410      Lp.lcm=NULL;
1411      return;
1412      /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
1413    }
1414    /*
1415    *the set B collects the pairs of type (S[j],p)
1416    *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
1417    *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
1418    *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
1419    */
1420    {
1421      j = strat->Bl;
1422      loop
1423      {
1424        if (j < 0)  break;
1425        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
1426        if ((compare==1)
1427        &&(sugarDivisibleBy(strat->B[j].ecart,Lp.ecart)))
1428        {
1429          strat->c3++;
1430          if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1431          {
1432            pLmFree(Lp.lcm);
1433            return;
1434          }
1435          break;
1436        }
1437        else
1438        if ((compare ==-1)
1439        && sugarDivisibleBy(Lp.ecart,strat->B[j].ecart))
1440        {
1441          deleteInL(strat->B,&strat->Bl,j,strat);
1442          strat->c3++;
1443        }
1444        j--;
1445      }
1446    }
1447  }
1448  else /*sugarcrit*/
1449  {
1450    if (bNCProdCrit)
1451    {
1452      // if currRing->nc_type!=quasi (or skew)
1453      // TODO: enable productCrit for super commutative algebras...
1454      if(/*(strat->ak==0) && productCrit(p,strat->S[i])*/
1455      pHasNotCF(p,strat->S[i]))
1456      {
1457      /*
1458      *the product criterion has applied for (s,p),
1459      *i.e. lcm(s,p)=product of the leading terms of s and p.
1460      *Suppose (s,r) is in L and the leading term
1461      *of p devides lcm(s,r)
1462      *(==> the leading term of p devides the leading term of r)
1463      *but the leading term of s does not devide the leading term of r
1464      *(notice that tis condition is automatically satisfied if r is still
1465      *in S), then (s,r) can be canceled.
1466      *This should be done here because the
1467      *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
1468      */
1469          strat->cp++;
1470          pLmFree(Lp.lcm);
1471          Lp.lcm=NULL;
1472          return;
1473      }
1474      if (strat->fromT && (strat->ecartS[i]>ecart))
1475      {
1476        pLmFree(Lp.lcm);
1477        Lp.lcm=NULL;
1478        return;
1479        /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
1480      }
1481      /*
1482      *the set B collects the pairs of type (S[j],p)
1483      *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
1484      *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
1485      *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
1486      */
1487      for(j = strat->Bl;j>=0;j--)
1488      {
1489        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
1490        if (compare==1)
1491        {
1492          strat->c3++;
1493          if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1494          {
1495            pLmFree(Lp.lcm);
1496            return;
1497          }
1498          break;
1499        }
1500        else
1501        if (compare ==-1)
1502        {
1503          deleteInL(strat->B,&strat->Bl,j,strat);
1504          strat->c3++;
1505        }
1506      }
1507    }
1508  }
1509  /*
1510  *the pair (S[i],p) enters B if the spoly != 0
1511  */
1512  /*-  compute the short s-polynomial -*/
1513  if (strat->fromT && !TEST_OPT_INTSTRATEGY)
1514    pNorm(p);
1515
1516  if ((strat->S[i]==NULL) || (p==NULL))
1517    return;
1518
1519  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (strat->fromQ[i]!=0))
1520    Lp.p=NULL;
1521  else
1522  {
1523    #ifdef HAVE_PLURAL
1524    if ( bIsPluralRing )
1525    {
1526      if(pHasNotCF(p, strat->S[i]))
1527      {
1528//         if(ncRingType(currRing) == nc_lie)
1529//         {
1530//             // generalized prod-crit for lie-type
1531//             strat->cp++;
1532//             Lp.p = nc_p_Bracket_qq(pCopy(p),strat->S[i]);
1533//         }
1534//         else
1535        if( bIsSCA )
1536        {
1537            // product criterion for homogeneous case in SCA
1538            strat->cp++;
1539            Lp.p = NULL;
1540        }
1541        else
1542          Lp.p = // nc_CreateSpoly(strat->S[i],p,currRing);
1543                 nc_CreateShortSpoly(strat->S[i], p, currRing); 
1544      }
1545      else
1546        Lp.p = // nc_CreateSpoly(strat->S[i],p,currRing);
1547                nc_CreateShortSpoly(strat->S[i], p, currRing); 
1548
1549     
1550#if MYTEST
1551      if (TEST_OPT_DEBUG)
1552      {
1553        PrintS("strat->S[i]: "); pWrite(strat->S[i]);
1554        PrintS("p: "); pWrite(p);
1555        PrintS("SPoly: "); pWrite(Lp.p);
1556      }
1557#endif     
1558     
1559    }
1560    else
1561    #endif
1562    {
1563      assume(!rIsPluralRing(currRing));
1564      Lp.p = ksCreateShortSpoly(strat->S[i], p, strat->tailRing);
1565#if MYTEST
1566      if (TEST_OPT_DEBUG)
1567      {
1568        PrintS("strat->S[i]: "); pWrite(strat->S[i]);
1569        PrintS("p: "); pWrite(p);
1570        PrintS("commutative SPoly: "); pWrite(Lp.p);
1571      }
1572#endif     
1573
1574      }
1575  }
1576  if (Lp.p == NULL)
1577  {
1578    /*- the case that the s-poly is 0 -*/
1579    if (strat->pairtest==NULL) initPairtest(strat);
1580    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
1581    strat->pairtest[strat->sl+1] = TRUE;
1582    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
1583    /*
1584    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
1585    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
1586    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
1587    *term of p devides the lcm(s,r)
1588    *(this canceling should be done here because
1589    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
1590    *the first case is handeled in chainCrit
1591    */
1592    if (Lp.lcm!=NULL) pLmFree(Lp.lcm);
1593  }
1594  else
1595  {
1596    /*- the pair (S[i],p) enters B -*/
1597    Lp.p1 = strat->S[i];
1598    Lp.p2 = p;
1599
1600//    if ( !bIsPluralRing ) // !!!!
1601    assume(pNext(Lp.p)==NULL);
1602    pNext(Lp.p) = strat->tail; // !!!
1603
1604    if (atR >= 0)
1605    {
1606      Lp.i_r1 = strat->S_2_R[i];
1607      Lp.i_r2 = atR;
1608    }
1609    else
1610    {
1611      Lp.i_r1 = -1;
1612      Lp.i_r2 = -1;
1613    }
1614    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
1615
1616    if (TEST_OPT_INTSTRATEGY)
1617    {
1618      if (!bIsPluralRing)
1619        nDelete(&(Lp.p->coef));
1620    }
1621
1622    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
1623    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
1624  }
1625}
1626
1627/*2
1628* put the pair (s[i],p) into the set L, ecart=ecart(p)
1629* in the case that s forms a SB of (s)
1630*/
1631void enterOnePairSpecial (int i,poly p,int ecart,kStrategy strat, int atR = -1)
1632{
1633  //PrintS("try ");wrp(strat->S[i]);PrintS(" and ");wrp(p);PrintLn();
1634  if(pHasNotCF(p,strat->S[i]))
1635  {
1636    //PrintS("prod-crit\n");
1637    #ifdef HAVE_PLURAL
1638    if((!rIsPluralRing(currRing)) || (rIsSCA(currRing) && strat->z2homog))
1639    #endif
1640    {
1641      //PrintS("prod-crit\n");
1642      strat->cp++;
1643      return;
1644    }
1645  }
1646
1647  int      l,j,compare;
1648  LObject  Lp;
1649  Lp.i_r = -1;
1650
1651  Lp.lcm = pInit();
1652  pLcm(p,strat->S[i],Lp.lcm);
1653  pSetm(Lp.lcm);
1654  for(j = strat->Ll;j>=0;j--)
1655  {
1656    compare=pDivComp(strat->L[j].lcm,Lp.lcm);
1657    if ((compare==1) || (pLmEqual(strat->L[j].lcm,Lp.lcm)))
1658    {
1659      //PrintS("c3-crit\n");
1660      strat->c3++;
1661      pLmFree(Lp.lcm);
1662      return;
1663    }
1664    else if (compare ==-1)
1665    {
1666      //Print("c3-crit with L[%d]\n",j);
1667      deleteInL(strat->L,&strat->Ll,j,strat);
1668      strat->c3++;
1669    }
1670  }
1671  /*-  compute the short s-polynomial -*/
1672
1673  #ifdef HAVE_PLURAL
1674  if (rIsPluralRing(currRing))
1675  {
1676    Lp.p = nc_CreateShortSpoly(strat->S[i],p); // ??? strat->tailRing?
1677  }
1678  else
1679  #endif
1680    Lp.p = ksCreateShortSpoly(strat->S[i],p,strat->tailRing);
1681
1682  if (Lp.p == NULL)
1683  {
1684     //PrintS("short spoly==NULL\n");
1685     pLmFree(Lp.lcm);
1686  }
1687  else
1688  {
1689    /*- the pair (S[i],p) enters L -*/
1690    Lp.p1 = strat->S[i];
1691    Lp.p2 = p;
1692    if (atR >= 0)
1693    {
1694      Lp.i_r1 = strat->S_2_R[i];
1695      Lp.i_r2 = atR;
1696    }
1697    else
1698    {
1699      Lp.i_r1 = -1;
1700      Lp.i_r2 = -1;
1701    }
1702    assume(pNext(Lp.p) == NULL);
1703    pNext(Lp.p) = strat->tail;
1704    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
1705    if (TEST_OPT_INTSTRATEGY)
1706    {
1707      nDelete(&(Lp.p->coef));
1708    }
1709    l = strat->posInL(strat->L,strat->Ll,&Lp,strat);
1710    //Print("-> L[%d]\n",l);
1711    enterL(&strat->L,&strat->Ll,&strat->Lmax,Lp,l);
1712  }
1713}
1714
1715/*2
1716*the pairset B of pairs of type (s[i],p) is complete now. It will be updated
1717*using the chain-criterion in B and L and enters B to L
1718*/
1719void chainCrit (poly p,int ecart,kStrategy strat)
1720{
1721  int i,j,l;
1722
1723  /*
1724  *pairtest[i] is TRUE if spoly(S[i],p) == 0.
1725  *In this case all elements in B such
1726  *that their lcm is divisible by the leading term of S[i] can be canceled
1727  */
1728  if (strat->pairtest!=NULL)
1729  {
1730    {
1731      /*- i.e. there is an i with pairtest[i]==TRUE -*/
1732      for (j=0; j<=strat->sl; j++)
1733      {
1734        if (strat->pairtest[j])
1735        {
1736          for (i=strat->Bl; i>=0; i--)
1737          {
1738            if (pDivisibleBy(strat->S[j],strat->B[i].lcm))
1739            {
1740              deleteInL(strat->B,&strat->Bl,i,strat);
1741              strat->c3++;
1742            }
1743          }
1744        }
1745      }
1746    }
1747    omFreeSize(strat->pairtest,(strat->sl+2)*sizeof(BOOLEAN));
1748    strat->pairtest=NULL;
1749  }
1750  if (strat->Gebauer || strat->fromT)
1751  {
1752    if (strat->sugarCrit)
1753    {
1754    /*
1755    *suppose L[j] == (s,r) and p/lcm(s,r)
1756    *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
1757    *and in case the sugar is o.k. then L[j] can be canceled
1758    */
1759      for (j=strat->Ll; j>=0; j--)
1760      {
1761        if (sugarDivisibleBy(ecart,strat->L[j].ecart)
1762        && ((pNext(strat->L[j].p) == strat->tail) || (pOrdSgn==1))
1763        && pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1764        {
1765          if (strat->L[j].p == strat->tail)
1766          {
1767              deleteInL(strat->L,&strat->Ll,j,strat);
1768              strat->c3++;
1769          }
1770        }
1771      }
1772      /*
1773      *this is GEBAUER-MOELLER:
1774      *in B all elements with the same lcm except the "best"
1775      *(i.e. the last one in B with this property) will be canceled
1776      */
1777      j = strat->Bl;
1778      loop /*cannot be changed into a for !!! */
1779      {
1780        if (j <= 0) break;
1781        i = j-1;
1782        loop
1783        {
1784          if (i <  0) break;
1785          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
1786          {
1787            strat->c3++;
1788            if (sugarDivisibleBy(strat->B[j].ecart,strat->B[i].ecart))
1789            {
1790              deleteInL(strat->B,&strat->Bl,i,strat);
1791              j--;
1792            }
1793            else
1794            {
1795              deleteInL(strat->B,&strat->Bl,j,strat);
1796              break;
1797            }
1798          }
1799          i--;
1800        }
1801        j--;
1802      }
1803    }
1804    else /*sugarCrit*/
1805    {
1806      /*
1807      *suppose L[j] == (s,r) and p/lcm(s,r)
1808      *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
1809      *and in case the sugar is o.k. then L[j] can be canceled
1810      */
1811      for (j=strat->Ll; j>=0; j--)
1812      {
1813        if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1814        {
1815          if ((pNext(strat->L[j].p) == strat->tail)||(pOrdSgn==1))
1816          {
1817            deleteInL(strat->L,&strat->Ll,j,strat);
1818            strat->c3++;
1819          }
1820        }
1821      }
1822      /*
1823      *this is GEBAUER-MOELLER:
1824      *in B all elements with the same lcm except the "best"
1825      *(i.e. the last one in B with this property) will be canceled
1826      */
1827      j = strat->Bl;
1828      loop   /*cannot be changed into a for !!! */
1829      {
1830        if (j <= 0) break;
1831        for(i=j-1; i>=0; i--)
1832        {
1833          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
1834          {
1835            strat->c3++;
1836            deleteInL(strat->B,&strat->Bl,i,strat);
1837            j--;
1838          }
1839        }
1840        j--;
1841      }
1842    }
1843    /*
1844    *the elements of B enter L/their order with respect to B is kept
1845    *j = posInL(L,j,B[i]) would permutate the order
1846    *if once B is ordered different from L
1847    *then one should use j = posInL(L,Ll,B[i])
1848    */
1849    j = strat->Ll+1;
1850    for (i=strat->Bl; i>=0; i--)
1851    {
1852      j = strat->posInL(strat->L,j-1,&(strat->B[i]),strat);
1853      enterL(&strat->L,&strat->Ll,&strat->Lmax,strat->B[i],j);
1854    }
1855    strat->Bl = -1;
1856  }
1857  else
1858  {
1859    for (j=strat->Ll; j>=0; j--)
1860    {
1861      if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1862      {
1863        if ((pNext(strat->L[j].p) == strat->tail)||(pOrdSgn==1))
1864        {
1865          deleteInL(strat->L,&strat->Ll,j,strat);
1866          strat->c3++;
1867        }
1868      }
1869    }
1870    /*
1871    *this is our MODIFICATION of GEBAUER-MOELLER:
1872    *First the elements of B enter L,
1873    *then we fix a lcm and the "best" element in L
1874    *(i.e the last in L with this lcm and of type (s,p))
1875    *and cancel all the other elements of type (r,p) with this lcm
1876    *except the case the element (s,r) has also the same lcm
1877    *and is on the worst position with respect to (s,p) and (r,p)
1878    */
1879    /*
1880    *B enters to L/their order with respect to B is permutated for elements
1881    *B[i].p with the same leading term
1882    */
1883    j = strat->Ll;
1884    for (i=strat->Bl; i>=0; i--)
1885    {
1886      j = strat->posInL(strat->L,j,&(strat->B[i]),strat);
1887      enterL(&strat->L,&strat->Ll,&strat->Lmax,strat->B[i],j);
1888    }
1889    strat->Bl = -1;
1890    j = strat->Ll;
1891    loop  /*cannot be changed into a for !!! */
1892    {
1893      if (j <= 0)
1894      {
1895        /*now L[0] cannot be canceled any more and the tail can be removed*/
1896        if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
1897        break;
1898      }
1899      if (strat->L[j].p2 == p)
1900      {
1901        i = j-1;
1902        loop
1903        {
1904          if (i < 0)  break;
1905          if ((strat->L[i].p2 == p) && pLmEqual(strat->L[j].lcm,strat->L[i].lcm))
1906          {
1907            /*L[i] could be canceled but we search for a better one to cancel*/
1908            strat->c3++;
1909            if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
1910            && (pNext(strat->L[l].p) == strat->tail)
1911            && (!pLmEqual(strat->L[i].p,strat->L[l].p))
1912            && pDivisibleBy(p,strat->L[l].lcm))
1913            {
1914              /*
1915              *"NOT equal(...)" because in case of "equal" the element L[l]
1916              *is "older" and has to be from theoretical point of view behind
1917              *L[i], but we do not want to reorder L
1918              */
1919              strat->L[i].p2 = strat->tail;
1920              /*
1921              *L[l] will be canceled, we cannot cancel L[i] later on,
1922              *so we mark it with "tail"
1923              */
1924              deleteInL(strat->L,&strat->Ll,l,strat);
1925              i--;
1926            }
1927            else
1928            {
1929              deleteInL(strat->L,&strat->Ll,i,strat);
1930            }
1931            j--;
1932          }
1933          i--;
1934        }
1935      }
1936      else if (strat->L[j].p2 == strat->tail)
1937      {
1938        /*now L[j] cannot be canceled any more and the tail can be removed*/
1939        strat->L[j].p2 = p;
1940      }
1941      j--;
1942    }
1943  }
1944}
1945
1946/*2
1947*(s[0],h),...,(s[k],h) will be put to the pairset L
1948*/
1949void initenterpairs (poly h,int k,int ecart,int isFromQ,kStrategy strat, int atR = -1)
1950{
1951
1952  if ((strat->syzComp==0)
1953  || (pGetComp(h)<=strat->syzComp))
1954  {
1955    int j;
1956    BOOLEAN new_pair=FALSE;
1957
1958    if (pGetComp(h)==0)
1959    {
1960      /* for Q!=NULL: build pairs (f,q),(f1,f2), but not (q1,q2)*/
1961      if ((isFromQ)&&(strat->fromQ!=NULL))
1962      {
1963        for (j=0; j<=k; j++)
1964        {
1965          if (!strat->fromQ[j])
1966          {
1967            new_pair=TRUE;
1968            enterOnePair(j,h,ecart,isFromQ,strat, atR);
1969          //Print("j:%d, Ll:%d\n",j,strat->Ll);
1970          }
1971        }
1972      }
1973      else
1974      {
1975        new_pair=TRUE;
1976        for (j=0; j<=k; j++)
1977        {
1978          enterOnePair(j,h,ecart,isFromQ,strat, atR);
1979          //Print("j:%d, Ll:%d\n",j,strat->Ll);
1980        }
1981      }
1982    }
1983    else
1984    {
1985      for (j=0; j<=k; j++)
1986      {
1987        if ((pGetComp(h)==pGetComp(strat->S[j]))
1988        || (pGetComp(strat->S[j])==0))
1989        {
1990          new_pair=TRUE;
1991          enterOnePair(j,h,ecart,isFromQ,strat, atR);
1992        //Print("j:%d, Ll:%d\n",j,strat->Ll);
1993        }
1994      }
1995    }
1996
1997    if (new_pair) chainCrit(h,ecart,strat);
1998
1999  }
2000}
2001
2002#ifdef HAVE_RINGS
2003/*2
2004*the pairset B of pairs of type (s[i],p) is complete now. It will be updated
2005*using the chain-criterion in B and L and enters B to L
2006*/
2007void chainCritRing (poly p,int ecart,kStrategy strat)
2008{
2009  int i,j,l;
2010  /*
2011  *pairtest[i] is TRUE if spoly(S[i],p) == 0.
2012  *In this case all elements in B such
2013  *that their lcm is divisible by the leading term of S[i] can be canceled
2014  */
2015  if (strat->pairtest!=NULL)
2016  {
2017    {
2018      /*- i.e. there is an i with pairtest[i]==TRUE -*/
2019      for (j=0; j<=strat->sl; j++)
2020      {
2021        if (strat->pairtest[j])
2022        {
2023          for (i=strat->Bl; i>=0; i--)
2024          {
2025            if (pDivisibleBy(strat->S[j],strat->B[i].lcm))
2026            {
2027#ifdef KDEBUG
2028              if (TEST_OPT_DEBUG)
2029              {
2030                PrintS("--- chain criterion func chainCritRing type 1\n");
2031                PrintS("strat->S[j]:");
2032                wrp(strat->S[j]);
2033                PrintS("  strat->B[i].lcm:");
2034                wrp(strat->B[i].lcm);
2035                PrintLn();
2036              }
2037#endif
2038              deleteInL(strat->B,&strat->Bl,i,strat);
2039              strat->c3++;
2040            }
2041          }
2042        }
2043      }
2044    }
2045    omFreeSize(strat->pairtest,(strat->sl+2)*sizeof(BOOLEAN));
2046    strat->pairtest=NULL;
2047  }
2048  assume(!(strat->Gebauer || strat->fromT));
2049  for (j=strat->Ll; j>=0; j--)
2050  {
2051    if (strat->L[j].lcm != NULL && nDivBy(pGetCoeff(strat->L[j].lcm), pGetCoeff(p)))
2052    {
2053      if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
2054      {
2055        if ((pNext(strat->L[j].p) == strat->tail) || (pOrdSgn==1))
2056        {
2057          deleteInL(strat->L,&strat->Ll,j,strat);
2058          strat->c3++;
2059#ifdef KDEBUG
2060              if (TEST_OPT_DEBUG)
2061              {
2062                PrintS("--- chain criterion func chainCritRing type 2\n");
2063                PrintS("strat->L[j].p:");
2064                wrp(strat->L[j].p);
2065                PrintS("  p:");
2066                wrp(p);
2067                PrintLn();
2068              }
2069#endif
2070        }
2071      }
2072    }
2073  }
2074  /*
2075  *this is our MODIFICATION of GEBAUER-MOELLER:
2076  *First the elements of B enter L,
2077  *then we fix a lcm and the "best" element in L
2078  *(i.e the last in L with this lcm and of type (s,p))
2079  *and cancel all the other elements of type (r,p) with this lcm
2080  *except the case the element (s,r) has also the same lcm
2081  *and is on the worst position with respect to (s,p) and (r,p)
2082  */
2083  /*
2084  *B enters to L/their order with respect to B is permutated for elements
2085  *B[i].p with the same leading term
2086  */
2087  j = strat->Ll;
2088  for (i=strat->Bl; i>=0; i--)
2089  {
2090    j = strat->posInL(strat->L,j,&(strat->B[i]),strat);
2091    enterL(&strat->L,&strat->Ll,&strat->Lmax,strat->B[i],j);
2092  }
2093  strat->Bl = -1;
2094  j = strat->Ll;
2095  loop  /*cannot be changed into a for !!! */
2096  {
2097    if (j <= 0)
2098    {
2099      /*now L[0] cannot be canceled any more and the tail can be removed*/
2100      if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
2101      break;
2102    }
2103    if (strat->L[j].p2 == p) // Was the element added from B?
2104    {
2105      i = j-1;
2106      loop
2107      {
2108        if (i < 0)  break;
2109        // Element is from B and has the same lcm as L[j]
2110        if ((strat->L[i].p2 == p) && nDivBy(pGetCoeff(strat->L[j].lcm), pGetCoeff(strat->L[i].lcm))
2111             && pLmEqual(strat->L[j].lcm,strat->L[i].lcm))
2112        {
2113          /*L[i] could be canceled but we search for a better one to cancel*/
2114          strat->c3++;
2115#ifdef KDEBUG
2116          if (TEST_OPT_DEBUG)
2117          {
2118            PrintS("--- chain criterion func chainCritRing type 3\n");
2119            PrintS("strat->L[j].lcm:");
2120            wrp(strat->L[j].lcm);
2121            PrintS("  strat->L[i].lcm:");
2122            wrp(strat->L[i].lcm);
2123            PrintLn();
2124          }
2125#endif
2126          if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
2127          && (pNext(strat->L[l].p) == strat->tail)
2128          && (!pLmEqual(strat->L[i].p,strat->L[l].p))
2129          && pDivisibleBy(p,strat->L[l].lcm))
2130          {
2131            /*
2132            *"NOT equal(...)" because in case of "equal" the element L[l]
2133            *is "older" and has to be from theoretical point of view behind
2134            *L[i], but we do not want to reorder L
2135            */
2136            strat->L[i].p2 = strat->tail;
2137            /*
2138            *L[l] will be canceled, we cannot cancel L[i] later on,
2139            *so we mark it with "tail"
2140            */
2141            deleteInL(strat->L,&strat->Ll,l,strat);
2142            i--;
2143          }
2144          else
2145          {
2146            deleteInL(strat->L,&strat->Ll,i,strat);
2147          }
2148          j--;
2149        }
2150        i--;
2151      }
2152    }
2153    else if (strat->L[j].p2 == strat->tail)
2154    {
2155      /*now L[j] cannot be canceled any more and the tail can be removed*/
2156      strat->L[j].p2 = p;
2157    }
2158    j--;
2159  }
2160}
2161#endif
2162
2163#ifdef HAVE_RING2TOM
2164long ind2(long arg)
2165{
2166  long ind = 0;
2167  if (arg <= 0) return 0;
2168  while (arg%2 == 0)
2169  {
2170    arg = arg / 2;
2171    ind++;
2172  }
2173  return ind;
2174}
2175
2176long ind_fact_2(long arg)
2177{
2178  long ind = 0;
2179  if (arg <= 0) return 0;
2180  if (arg%2 == 1) { arg--; }
2181  while (arg > 0)
2182  {
2183    ind += ind2(arg);
2184    arg = arg - 2;
2185  }
2186  return ind;
2187}
2188#endif
2189
2190#ifdef HAVE_VANIDEAL
2191long twoPow(long arg)
2192{
2193  return 1L << arg;
2194}
2195
2196/*2
2197* put the pair (p, f) in B and f in T
2198*/
2199void enterOneZeroPairRing (poly f, poly t_p, poly p, int ecart, kStrategy strat, int atR = -1)
2200{
2201  int      l,j,compare,compareCoeff;
2202  LObject  Lp;
2203
2204  if (strat->interred_flag) return;
2205#ifdef KDEBUG
2206  Lp.ecart=0; Lp.length=0;
2207#endif
2208  /*- computes the lcm(s[i],p) -*/
2209  Lp.lcm = pInit();
2210
2211  pLcm(p,f,Lp.lcm);
2212  pSetm(Lp.lcm);
2213  pSetCoeff(Lp.lcm, nLcm(pGetCoeff(p), pGetCoeff(f), currRing));
2214  assume(!strat->sugarCrit);
2215  assume(!strat->fromT);
2216  /*
2217  *the set B collects the pairs of type (S[j],p)
2218  *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p) != lcm(r,p)
2219  *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
2220  *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
2221  */
2222  for(j = strat->Bl;j>=0;j--)
2223  {
2224    compare=pDivCompRing(strat->B[j].lcm,Lp.lcm);
2225    compareCoeff = nDivComp(pGetCoeff(strat->B[j].lcm), pGetCoeff(Lp.lcm));
2226    if (compareCoeff == 0 || compare == compareCoeff)
2227    {
2228      if (compare == 1)
2229      {
2230        strat->c3++;
2231        pLmDelete(Lp.lcm);
2232        return;
2233      }
2234      else
2235      if (compare == -1)
2236      {
2237        deleteInL(strat->B,&strat->Bl,j,strat);
2238        strat->c3++;
2239      }
2240    }
2241    if (compare == pDivComp_EQUAL)
2242    {
2243      // Add hint for same LM and direction of LC (later) (TODO Oliver)
2244      if (compareCoeff == 1)
2245      {
2246        strat->c3++;
2247        pLmDelete(Lp.lcm);
2248        return;
2249      }
2250      else
2251      if (compareCoeff == -1)
2252      {
2253        deleteInL(strat->B,&strat->Bl,j,strat);
2254        strat->c3++;
2255      }
2256    }
2257  }
2258  /*
2259  *the pair (S[i],p) enters B if the spoly != 0
2260  */
2261  /*-  compute the short s-polynomial -*/
2262  if ((f==NULL) || (p==NULL)) return;
2263  pNorm(p);
2264  {
2265    Lp.p = ksCreateShortSpoly(f, p, strat->tailRing);
2266  }
2267  if (Lp.p == NULL) //deactivated, as we are adding pairs with zeropoly and not from S
2268  {
2269    /*- the case that the s-poly is 0 -*/
2270//    if (strat->pairtest==NULL) initPairtest(strat);
2271//    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
2272//    strat->pairtest[strat->sl+1] = TRUE;
2273    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
2274    /*
2275    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
2276    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
2277    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
2278    *term of p devides the lcm(s,r)
2279    *(this canceling should be done here because
2280    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
2281    *the first case is handeled in chainCrit
2282    */
2283    if (Lp.lcm!=NULL) pLmDelete(Lp.lcm);
2284  }
2285  else
2286  {
2287    /*- the pair (S[i],p) enters B -*/
2288    Lp.p1 = f;
2289    Lp.p2 = p;
2290
2291    pNext(Lp.p) = strat->tail;
2292
2293    LObject tmp_h(f, currRing, strat->tailRing);
2294    tmp_h.SetShortExpVector();
2295    strat->initEcart(&tmp_h);
2296    tmp_h.sev = pGetShortExpVector(tmp_h.p);
2297    tmp_h.t_p = t_p;
2298
2299    enterT(tmp_h, strat, strat->tl + 1);
2300
2301    if (atR >= 0)
2302    {
2303      Lp.i_r2 = atR;
2304      Lp.i_r1 = strat->tl;
2305    }
2306
2307    strat->initEcartPair(&Lp,f,p,0/*strat->ecartS[i]*/,ecart);     // Attention: TODO: break ecart
2308    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
2309    enterL(&strat->B, &strat->Bl, &strat->Bmax, Lp, l);
2310  }
2311}
2312
2313/* Helper for kCreateZeroPoly
2314 * enumerating the exponents
2315ring r = 2^2, (a, b, c), lp; ideal G0 = system("createG0"); ideal G = interred(G0); ncols(G0); ncols(G);
2316 */
2317
2318int nextZeroSimplexExponent (long exp[], long ind[], long cexp[], long cind[], long* cabsind, long step[], long bound, long N)
2319/* gives the next exponent from the set H_1 */
2320{
2321  long add = ind2(cexp[1] + 2);
2322  if ((*cabsind < bound) && (*cabsind - step[1] + add < bound))
2323  {
2324    cexp[1] += 2;
2325    cind[1] += add;
2326    *cabsind += add;
2327  }
2328  else
2329  {
2330    // cabsind >= habsind
2331    if (N == 1) return 0;
2332    int i = 1;
2333    while (exp[i] == cexp[i] && i <= N) i++;
2334    cexp[i] = exp[i];
2335    *cabsind -= cind[i];
2336    cind[i] = ind[i];
2337    step[i] = 500000;
2338    *cabsind += cind[i];
2339    // Print("in: %d\n", *cabsind);
2340    i += 1;
2341    if (i > N) return 0;
2342    do
2343    {
2344      step[1] = 500000;
2345      for (int j = i + 1; j <= N; j++)
2346      {
2347        if (step[1] > step[j]) step[1] = step[j];
2348      }
2349      add = ind2(cexp[i] + 2);
2350      if (*cabsind - step[1] + add >= bound)
2351      {
2352        cexp[i] = exp[i];
2353        *cabsind -= cind[i];
2354        cind[i] = ind[i];
2355        *cabsind += cind[i];
2356        step[i] = 500000;
2357        i += 1;
2358        if (i > N) return 0;
2359      }
2360      else step[1] = -1;
2361    } while (step[1] != -1);
2362    step[1] = 500000;
2363    cexp[i] += 2;
2364    cind[i] += add;
2365    *cabsind += add;
2366    if (add < step[i]) step[i] = add;
2367    for (i = 2; i <= N; i++)
2368    {
2369      if (step[1] > step[i]) step[1] = step[i];
2370    }
2371  }
2372  return 1;
2373}
2374
2375/*
2376 * Creates the zero Polynomial on position exp
2377 * long exp[] : exponent of leading term
2378 * cabsind    : total 2-ind of exp (if -1 will be computed)
2379 * poly* t_p  : will hold the LT in tailRing
2380 * leadRing   : ring for the LT
2381 * tailRing   : ring for the tail
2382 */
2383
2384poly kCreateZeroPoly(long exp[], long cabsind, poly* t_p, ring leadRing, ring tailRing)
2385{
2386
2387  poly zeroPoly = NULL;
2388
2389  number tmp1;
2390  poly tmp2, tmp3;
2391
2392  if (cabsind == -1)
2393  {
2394    cabsind = 0;
2395    for (int i = 1; i <= leadRing->N; i++)
2396    {
2397      cabsind += ind_fact_2(exp[i]);
2398    }
2399//    Print("cabsind: %d\n", cabsind);
2400  }
2401  if (cabsind < leadRing->ch)
2402  {
2403    zeroPoly = p_ISet(twoPow(leadRing->ch - cabsind), tailRing);
2404  }
2405  else
2406  {
2407    zeroPoly = p_ISet(1, tailRing);
2408  }
2409  for (int i = 1; i <= leadRing->N; i++)
2410  {
2411    for (long j = 1; j <= exp[i]; j++)
2412    {
2413      tmp1 = nInit(j);
2414      tmp2 = p_ISet(1, tailRing);
2415      p_SetExp(tmp2, i, 1, tailRing);
2416      p_Setm(tmp2, tailRing);
2417      if (nIsZero(tmp1))
2418      { // should nowbe obsolet, test ! TODO OLIVER
2419        zeroPoly = p_Mult_q(zeroPoly, tmp2, tailRing);
2420      }
2421      else
2422      {
2423        tmp3 = p_NSet(nCopy(tmp1), tailRing);
2424        zeroPoly = p_Mult_q(zeroPoly, p_Add_q(tmp3, tmp2, tailRing), tailRing);
2425      }
2426    }
2427  }
2428  tmp2 = p_NSet(nCopy(pGetCoeff(zeroPoly)), leadRing);
2429  for (int i = 1; i <= leadRing->N; i++)
2430  {
2431    pSetExp(tmp2, i, p_GetExp(zeroPoly, i, tailRing));
2432  }
2433  p_Setm(tmp2, leadRing);
2434  *t_p = zeroPoly;
2435  zeroPoly = pNext(zeroPoly);
2436  pNext(*t_p) = NULL;
2437  pNext(tmp2) = zeroPoly;
2438  return tmp2;
2439}
2440
2441// #define OLI_DEBUG
2442
2443/*
2444 * Generate the s-polynomial for the virtual set of zero-polynomials
2445 */
2446
2447void initenterzeropairsRing (poly p, int ecart, kStrategy strat, int atR)
2448{
2449  // Initialize
2450  long exp[50];            // The exponent of \hat{X} (basepoint)
2451  long cexp[50];           // The current exponent for iterating over all
2452  long ind[50];            // The power of 2 in the i-th component of exp
2453  long cind[50];           // analog for cexp
2454  long mult[50];           // How to multiply the elements of G
2455  long cabsind = 0;        // The abs. index of cexp, i.e. the sum of cind
2456  long habsind = 0;        // The abs. index of the coefficient of h
2457  long step[50];           // The last increases
2458  for (int i = 1; i <= currRing->N; i++)
2459  {
2460    exp[i] = p_GetExp(p, i, currRing);
2461    if (exp[i] & 1 != 0)
2462    {
2463      exp[i] = exp[i] - 1;
2464      mult[i] = 1;
2465    }
2466    cexp[i] = exp[i];
2467    ind[i] = ind_fact_2(exp[i]);
2468    cabsind += ind[i];
2469    cind[i] = ind[i];
2470    step[i] = 500000;
2471  }
2472  step[1] = 500000;
2473  habsind = ind2((long) p_GetCoeff(p, currRing));
2474  long bound = currRing->ch - habsind;
2475#ifdef OLI_DEBUG
2476  PrintS("-------------\npoly  :");
2477  wrp(p);
2478  Print("\nexp   : (%d, %d)\n", exp[1] + mult[1], exp[2] + mult[1]);
2479  Print("cexp  : (%d, %d)\n", cexp[1], cexp[2]);
2480  Print("cind  : (%d, %d)\n", cind[1], cind[2]);
2481  Print("bound : %d\n", bound);
2482  Print("cind  : %d\n", cabsind);
2483#endif
2484  if (cabsind == 0)
2485  {
2486    if (!(nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N)))
2487    {
2488      return;
2489    }
2490  }
2491  // Now the whole simplex
2492  do
2493  {
2494    // Build s-polynomial
2495    // 2**ind-def * mult * g - exp-def * h
2496    poly t_p;
2497    poly zeroPoly = kCreateZeroPoly(cexp, cabsind, &t_p, currRing, strat->tailRing);
2498#ifdef OLI_DEBUG
2499    Print("%d, (%d, %d), ind = (%d, %d)\n", cabsind, cexp[1], cexp[2], cind[1], cind[2]);
2500    Print("zPoly : ");
2501    wrp(zeroPoly);
2502    Print("\n");
2503#endif
2504    enterOneZeroPairRing(zeroPoly, t_p, p, ecart, strat, atR);
2505  }
2506  while ( nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N) );
2507}
2508
2509/*
2510 * Create the Groebner basis of the vanishing polynomials.
2511 */
2512
2513ideal createG0()
2514{
2515  // Initialize
2516  long exp[50];            // The exponent of \hat{X} (basepoint)
2517  long cexp[50];           // The current exponent for iterating over all
2518  long ind[50];            // The power of 2 in the i-th component of exp
2519  long cind[50];           // analog for cexp
2520  long mult[50];           // How to multiply the elements of G
2521  long cabsind = 0;        // The abs. index of cexp, i.e. the sum of cind
2522  long habsind = 0;        // The abs. index of the coefficient of h
2523  long step[50];           // The last increases
2524  for (int i = 1; i <= currRing->N; i++)
2525  {
2526    exp[i] = 0;
2527    cexp[i] = exp[i];
2528    ind[i] = 0;
2529    step[i] = 500000;
2530    cind[i] = ind[i];
2531  }
2532  long bound = currRing->ch;
2533  step[1] = 500000;
2534#ifdef OLI_DEBUG
2535  PrintS("-------------\npoly  :");
2536//  wrp(p);
2537  Print("\nexp   : (%d, %d)\n", exp[1] + mult[1], exp[2] + mult[1]);
2538  Print("cexp  : (%d, %d)\n", cexp[1], cexp[2]);
2539  Print("cind  : (%d, %d)\n", cind[1], cind[2]);
2540  Print("bound : %d\n", bound);
2541  Print("cind  : %d\n", cabsind);
2542#endif
2543  if (cabsind == 0)
2544  {
2545    if (!(nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N)))
2546    {
2547      return idInit(1, 1);
2548    }
2549  }
2550  ideal G0 = idInit(1, 1);
2551  // Now the whole simplex
2552  do
2553  {
2554    // Build s-polynomial
2555    // 2**ind-def * mult * g - exp-def * h
2556    poly t_p;
2557    poly zeroPoly = kCreateZeroPoly(cexp, cabsind, &t_p, currRing, currRing);
2558#ifdef OLI_DEBUG
2559    Print("%d, (%d, %d), ind = (%d, %d)\n", cabsind, cexp[1], cexp[2], cind[1], cind[2]);
2560    Print("zPoly : ");
2561    wrp(zeroPoly);
2562    Print("\n");
2563#endif
2564    // Add to ideal
2565    pEnlargeSet(&(G0->m), IDELEMS(G0), 1);
2566    IDELEMS(G0) += 1;
2567    G0->m[IDELEMS(G0) - 1] = zeroPoly;
2568  }
2569  while ( nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N) );
2570  idSkipZeroes(G0);
2571  return G0;
2572}
2573#endif
2574
2575#ifdef HAVE_RINGS
2576/*2
2577*(s[0],h),...,(s[k],h) will be put to the pairset L
2578*/
2579void initenterpairsRing (poly h,int k,int ecart,int isFromQ,kStrategy strat, int atR = -1)
2580{
2581
2582  if ((strat->syzComp==0) || (pGetComp(h)<=strat->syzComp))
2583  {
2584    int j;
2585    BOOLEAN new_pair=FALSE;
2586
2587    if (pGetComp(h)==0)
2588    {
2589      /* for Q!=NULL: build pairs (f,q),(f1,f2), but not (q1,q2)*/
2590      if ((isFromQ)&&(strat->fromQ!=NULL))
2591      {
2592        for (j=0; j<=k; j++)
2593        {
2594          if (!strat->fromQ[j])
2595          {
2596            new_pair=TRUE;
2597            Print("TODO Oliver --- j:%d, Ll:%d\n",j,strat->Ll);
2598            enterOnePairRing(j,h,ecart,isFromQ,strat, atR);
2599          }
2600        }
2601      }
2602      else
2603      {
2604        new_pair=TRUE;
2605        for (j=0; j<=k; j++)
2606        {
2607          // Print("j:%d, Ll:%d\n",j,strat->Ll);
2608          enterOnePairRing(j,h,ecart,isFromQ,strat, atR);
2609        }
2610      }
2611    }
2612    else
2613    {
2614      for (j=0; j<=k; j++)
2615      {
2616        if ((pGetComp(h)==pGetComp(strat->S[j])) || (pGetComp(strat->S[j])==0))
2617        {
2618          new_pair=TRUE;
2619          Print("TODO Oliver --- j:%d, Ll:%d\n",j,strat->Ll);
2620          enterOnePairRing(j,h,ecart,isFromQ,strat, atR);
2621        }
2622      }
2623    }
2624
2625    if (new_pair) chainCritRing(h,ecart,strat);
2626
2627  }
2628/*
2629ring r=256,(x,y,z),dp;
2630ideal I=12xz-133y, 2xy-z;
2631*/
2632
2633}
2634
2635/*2
2636*(s[0],h),...,(s[k],h) will be put to the pairset L
2637*/
2638void initenterstrongPairs (poly h,int k,int ecart,int isFromQ,kStrategy strat, int atR = -1)
2639{
2640
2641  if (!nIsOne(pGetCoeff(h)))
2642  {
2643    int j;
2644    BOOLEAN new_pair=FALSE;
2645
2646    for (j=0; j<=k; j++)
2647    {
2648      // Print("j:%d, Ll:%d\n",j,strat->Ll);
2649//      if (((unsigned long) pGetCoeff(h) % (unsigned long) pGetCoeff(strat->S[j]) != 0) &&
2650//         ((unsigned long) pGetCoeff(strat->S[j]) % (unsigned long) pGetCoeff(h) != 0))
2651      {
2652        if (enterOneStrongPoly(j,h,ecart,isFromQ,strat, atR))
2653          new_pair=TRUE;
2654      }
2655    }
2656  }
2657/*
2658ring r=256,(x,y,z),dp;
2659ideal I=12xz-133y, 2xy-z;
2660*/
2661
2662}
2663
2664/*2
2665* Generates spoly(0, h) if applicable. Assumes ring in Z/2^n.
2666*/
2667void enterExtendedSpoly(poly h,kStrategy strat)
2668{
2669  if (nIsOne(pGetCoeff(h))) return;
2670  number gcd;
2671  bool go = false;
2672  if (nDivBy((number) 0, pGetCoeff(h)))
2673  {
2674    gcd = nIntDiv((number) 0, pGetCoeff(h));
2675    go = true;
2676  }
2677  else
2678    gcd = nGcd((number) 0, pGetCoeff(h), strat->tailRing);
2679  if (go || !nIsOne(gcd))
2680  {
2681    poly p = h->next;
2682    if (!go)
2683    {
2684      number tmp = gcd;
2685      gcd = nIntDiv(0, gcd);
2686      nDelete(&tmp);
2687    }
2688    p = pp_Mult_nn(p, gcd, strat->tailRing);
2689    nDelete(&gcd);
2690
2691    if (p != NULL)
2692    {
2693      if (TEST_OPT_PROT)
2694      {
2695        PrintS("Z");
2696      }
2697#ifdef KDEBUG
2698      if (TEST_OPT_DEBUG)
2699      {
2700        PrintS("--- create zero spoly: ");
2701        wrp(h);
2702        PrintS(" ---> ");
2703      }
2704#endif
2705      poly tmp = pInit();
2706      pSetCoeff0(tmp, pGetCoeff(p));
2707      for (int i = 1; i <= currRing->N; i++)
2708      {
2709        pSetExp(tmp, i, p_GetExp(p, i, strat->tailRing));
2710      }
2711      p_Setm(tmp, currRing);
2712      p = p_LmFreeAndNext(p, strat->tailRing);
2713      pNext(tmp) = p;
2714      LObject h;
2715      h.p = tmp;
2716      h.tailRing = strat->tailRing;
2717      int posx;
2718      if (h.p!=NULL)
2719      {
2720        if (TEST_OPT_INTSTRATEGY)
2721        {
2722          //pContent(h.p);
2723          h.pCleardenom(); // also does a pContent
2724        }
2725        else
2726        {
2727          h.pNorm();
2728        }
2729        strat->initEcart(&h);
2730        if (strat->Ll==-1)
2731          posx =0;
2732        else
2733          posx = strat->posInL(strat->L,strat->Ll,&h,strat);
2734        h.sev = pGetShortExpVector(h.p);
2735        h.t_p = k_LmInit_currRing_2_tailRing(h.p, strat->tailRing);
2736        if (pNext(p) != NULL)
2737        {
2738          // What does this? (Oliver)
2739          // pShallowCopyDeleteProc p_shallow_copy_delete
2740          //      = pGetShallowCopyDeleteProc(strat->tailRing, new_tailRing);
2741          // pNext(p) = p_shallow_copy_delete(pNext(p),
2742          //              currRing, strat->tailRing, strat->tailRing->PolyBin);
2743        }
2744#ifdef KDEBUG
2745        if (TEST_OPT_DEBUG)
2746        {
2747          wrp(tmp);
2748          PrintLn();
2749        }
2750#endif
2751        enterL(&strat->L,&strat->Ll,&strat->Lmax,h,posx);
2752      }
2753    }
2754  }
2755  nDelete(&gcd);
2756}
2757
2758void clearSbatch (poly h,int k,int pos,kStrategy strat)
2759{
2760  int j = pos;
2761  if ( (!strat->fromT)
2762  && (1//(strat->syzComp==0)
2763    //||(pGetComp(h)<=strat->syzComp)))
2764  ))
2765  {
2766    // Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
2767    unsigned long h_sev = pGetShortExpVector(h);
2768    loop
2769    {
2770      if (j > k) break;
2771      clearS(h,h_sev, &j,&k,strat);
2772      j++;
2773    }
2774    // Print("end clearS sl=%d\n",strat->sl);
2775  }
2776}
2777
2778/*2
2779* Generates a sufficient set of spolys (maybe just a finite generating
2780* set of the syzygys)
2781*/
2782void superenterpairs (poly h,int k,int ecart,int pos,kStrategy strat, int atR)
2783{
2784    assume (rField_is_Ring(currRing));
2785    // enter also zero divisor * poly, if this is non zero and of smaller degree
2786    if (!(rField_is_Domain(currRing))) enterExtendedSpoly(h, strat);
2787    initenterpairsRing(h, k, ecart, 0, strat, atR);
2788    initenterstrongPairs(h, k, ecart, 0, strat, atR);
2789    clearSbatch(h, k, pos, strat);
2790}
2791#endif
2792
2793/*2
2794*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
2795*superfluous elements in S will be deleted
2796*/
2797void enterpairs (poly h,int k,int ecart,int pos,kStrategy strat, int atR)
2798{
2799  int j=pos;
2800
2801#ifdef HAVE_RINGS
2802  assume (!rField_is_Ring(currRing));
2803#endif
2804
2805  initenterpairs(h,k,ecart,0,strat, atR);
2806  if ( (!strat->fromT)
2807  && ((strat->syzComp==0)
2808    ||(pGetComp(h)<=strat->syzComp)))
2809  {
2810    //Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
2811    unsigned long h_sev = pGetShortExpVector(h);
2812    loop
2813    {
2814      if (j > k) break;
2815      clearS(h,h_sev, &j,&k,strat);
2816      j++;
2817    }
2818    //Print("end clearS sl=%d\n",strat->sl);
2819  }
2820 // PrintS("end enterpairs\n");
2821}
2822
2823/*2
2824*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
2825*superfluous elements in S will be deleted
2826*/
2827void enterpairsSpecial (poly h,int k,int ecart,int pos,kStrategy strat, int atR = -1)
2828{
2829  int j;
2830
2831  for (j=0; j<=k; j++)
2832  {
2833    if ((pGetComp(h)==pGetComp(strat->S[j]))
2834    || (0==pGetComp(strat->S[j])))
2835    {
2836      enterOnePairSpecial(j,h,ecart,strat, atR);
2837    }
2838  }
2839//   #ifdef HAVE_PLURAL
2840  if (!rIsPluralRing(currRing))
2841//   #endif
2842  {
2843    j=pos;
2844    loop
2845    {
2846      unsigned long h_sev = pGetShortExpVector(h);
2847      if (j > k) break;
2848      clearS(h,h_sev,&j,&k,strat);
2849      j++;
2850    }
2851  }
2852}
2853
2854/*2
2855*reorders  s with respect to posInS,
2856*suc is the first changed index or zero
2857*/
2858
2859void reorderS (int* suc,kStrategy strat)
2860{
2861  int i,j,at,ecart, s2r;
2862  int fq=0;
2863  unsigned long sev;
2864  poly  p;
2865  int new_suc=strat->sl+1;
2866  i= *suc;
2867  if (i<0) i=0;
2868
2869  for (; i<=strat->sl; i++)
2870  {
2871    at = posInS(strat,i-1,strat->S[i],strat->ecartS[i]);
2872    if (at != i)
2873    {
2874      if (new_suc > at) new_suc = at;
2875      p = strat->S[i];
2876      ecart = strat->ecartS[i];
2877      sev = strat->sevS[i];
2878      s2r = strat->S_2_R[i];
2879      if (strat->fromQ!=NULL) fq=strat->fromQ[i];
2880      for (j=i; j>=at+1; j--)
2881      {
2882        strat->S[j] = strat->S[j-1];
2883        strat->ecartS[j] = strat->ecartS[j-1];
2884        strat->sevS[j] = strat->sevS[j-1];
2885        strat->S_2_R[j] = strat->S_2_R[j-1];
2886      }
2887      strat->S[at] = p;
2888      strat->ecartS[at] = ecart;
2889      strat->sevS[at] = sev;
2890      strat->S_2_R[at] = s2r;
2891      if (strat->fromQ!=NULL)
2892      {
2893        for (j=i; j>=at+1; j--)
2894        {
2895          strat->fromQ[j] = strat->fromQ[j-1];
2896        }
2897        strat->fromQ[at]=fq;
2898      }
2899    }
2900  }
2901  if (new_suc <= strat->sl) *suc=new_suc;
2902  else                      *suc=-1;
2903}
2904
2905
2906/*2
2907*looks up the position of p in set
2908*set[0] is the smallest with respect to the ordering-procedure deg/pComp
2909* Assumption: posInS only depends on the leading term
2910*             otherwise, bba has to be changed
2911*/
2912int posInS (const kStrategy strat, const int length,const poly p,
2913            const int ecart_p)
2914{
2915  if(length==-1) return 0;
2916  polyset set=strat->S;
2917  int i;
2918  int an = 0;
2919  int en = length;
2920  int cmp_int = pOrdSgn;
2921  int pc=pGetComp(p);
2922  if ((currRing->MixedOrder)
2923#if 0
2924  || ((strat->ak>0) && ((currRing->order[0]==ringorder_c)||((currRing->order[0]==ringorder_C))))
2925#endif
2926  )
2927  {
2928    int o=pWTotaldegree(p);
2929    int oo=pWTotaldegree(set[length]);
2930
2931    if ((oo<o)
2932    || ((o==oo) && (pLmCmp(set[length],p)!= cmp_int)))
2933      return length+1;
2934
2935    loop
2936    {
2937      if (an >= en-1)
2938      {
2939        if ((pWTotaldegree(set[an])>=o) && (pLmCmp(set[an],p) == cmp_int))
2940        {
2941          return an;
2942        }
2943        return en;
2944      }
2945      i=(an+en) / 2;
2946      if ((pWTotaldegree(set[i])>=o) && (pLmCmp(set[i],p) == cmp_int)) en=i;
2947      else                              an=i;
2948    }
2949  }
2950  else
2951  {
2952#ifdef HAVE_RINGS
2953    if (rField_is_Ring(currRing))
2954    {
2955      if (pLmCmp(set[length],p)== -cmp_int)
2956        return length+1;
2957      int cmp;
2958      loop
2959      {
2960        if (an >= en-1)
2961        {
2962          cmp = pLmCmp(set[an],p);
2963          if (cmp == cmp_int)  return an;
2964          if (cmp == -cmp_int) return en;
2965          if (nDivBy(pGetCoeff(p), pGetCoeff(set[an]))) return en;
2966          return an;
2967        }
2968        i = (an+en) / 2;
2969        cmp = pLmCmp(set[i],p);
2970        if (cmp == cmp_int)         en = i;
2971        else if (cmp == -cmp_int)   an = i;
2972        else
2973        {
2974          if (nDivBy(pGetCoeff(p), pGetCoeff(set[i]))) an = i;
2975          else en = i;
2976        }
2977      }
2978    }
2979    else
2980#endif
2981    if (pLmCmp(set[length],p)== -cmp_int)
2982      return length+1;
2983
2984    loop
2985    {
2986      if (an >= en-1)
2987      {
2988        if (pLmCmp(set[an],p) == cmp_int) return an;
2989        if (pLmCmp(set[an],p) == -cmp_int) return en;
2990        if ((cmp_int!=1)
2991        && ((strat->ecartS[an])>ecart_p))
2992          return an;
2993        return en;
2994      }
2995      i=(an+en) / 2;
2996      if (pLmCmp(set[i],p) == cmp_int) en=i;
2997      else if (pLmCmp(set[i],p) == -cmp_int) an=i;
2998      else
2999      {
3000        if ((cmp_int!=1)
3001        &&((strat->ecartS[i])<ecart_p))
3002          en=i;
3003        else
3004          an=i;
3005      }
3006    }
3007  }
3008}
3009
3010
3011/*2
3012* looks up the position of p in set
3013* the position is the last one
3014*/
3015int posInT0 (const TSet set,const int length,LObject &p)
3016{
3017  return (length+1);
3018}
3019
3020
3021/*2
3022* looks up the position of p in T
3023* set[0] is the smallest with respect to the ordering-procedure
3024* pComp
3025*/
3026int posInT1 (const TSet set,const int length,LObject &p)
3027{
3028  if (length==-1) return 0;
3029
3030  if (pLmCmp(set[length].p,p.p)!= pOrdSgn) return length+1;
3031
3032  int i;
3033  int an = 0;
3034  int en= length;
3035
3036  loop
3037  {
3038    if (an >= en-1)
3039    {
3040      if (pLmCmp(set[an].p,p.p) == pOrdSgn) return an;
3041      return en;
3042    }
3043    i=(an+en) / 2;
3044    if (pLmCmp(set[i].p,p.p) == pOrdSgn) en=i;
3045    else                                 an=i;
3046  }
3047}
3048
3049/*2
3050* looks up the position of p in T
3051* set[0] is the smallest with respect to the ordering-procedure
3052* length
3053*/
3054int posInT2 (const TSet set,const int length,LObject &p)
3055{
3056  if (length==-1)
3057    return 0;
3058  if (set[length].length<p.length)
3059    return length+1;
3060
3061  int i;
3062  int an = 0;
3063  int en= length;
3064
3065  loop
3066  {
3067    if (an >= en-1)
3068    {
3069      if (set[an].length>p.length) return an;
3070      return en;
3071    }
3072    i=(an+en) / 2;
3073    if (set[i].length>p.length) en=i;
3074    else                        an=i;
3075  }
3076}
3077
3078/*2
3079* looks up the position of p in T
3080* set[0] is the smallest with respect to the ordering-procedure
3081* totaldegree,pComp
3082*/
3083int posInT11 (const TSet set,const int length,LObject &p)
3084/*{
3085 * int j=0;
3086 * int o;
3087 *
3088 * o = p.GetpFDeg();
3089 * loop
3090 * {
3091 *   if ((pFDeg(set[j].p) > o)
3092 *   || ((pFDeg(set[j].p) == o) && (pLmCmp(set[j].p,p.p) == pOrdSgn)))
3093 *   {
3094 *     return j;
3095 *   }
3096 *   j++;
3097 *   if (j > length) return j;
3098 * }
3099 *}
3100 */
3101{
3102  if (length==-1) return 0;
3103
3104  int o = p.GetpFDeg();
3105  int op = set[length].GetpFDeg();
3106
3107  if ((op < o)
3108  || ((op == o) && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
3109    return length+1;
3110
3111  int i;
3112  int an = 0;
3113  int en= length;
3114
3115  loop
3116  {
3117    if (an >= en-1)
3118    {
3119      op= set[an].GetpFDeg();
3120      if ((op > o)
3121      || (( op == o) && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
3122        return an;
3123      return en;
3124    }
3125    i=(an+en) / 2;
3126    op = set[i].GetpFDeg();
3127    if (( op > o)
3128    || (( op == o) && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
3129      en=i;
3130    else
3131      an=i;
3132  }
3133}
3134
3135/*2 Pos for rings T: Here I am
3136* looks up the position of p in T
3137* set[0] is the smallest with respect to the ordering-procedure
3138* totaldegree,pComp
3139*/
3140int posInTrg0 (const TSet set,const int length,LObject &p)
3141{
3142  if (length==-1) return 0;
3143  int o = p.GetpFDeg();
3144  int op = set[length].GetpFDeg();
3145  int i;
3146  int an = 0;
3147  int en = length;
3148  int cmp_int = pOrdSgn;
3149  if ((op < o) || (pLmCmp(set[length].p,p.p)== -cmp_int))
3150    return length+1;
3151  int cmp;
3152  loop
3153  {
3154    if (an >= en-1)
3155    {
3156      op = set[an].GetpFDeg();
3157      if (op > o) return an;
3158      if (op < 0) return en;
3159      cmp = pLmCmp(set[an].p,p.p);
3160      if (cmp == cmp_int)  return an;
3161      if (cmp == -cmp_int) return en;
3162      if (nGreater(pGetCoeff(p.p), pGetCoeff(set[an].p))) return en;
3163      return an;
3164    }
3165    i = (an + en) / 2;
3166    op = set[i].GetpFDeg();
3167    if (op > o)       en = i;
3168    else if (op < o)  an = i;
3169    else
3170    {
3171      cmp = pLmCmp(set[i].p,p.p);
3172      if (cmp == cmp_int)                                     en = i;
3173      else if (cmp == -cmp_int)                               an = i;
3174      else if (nGreater(pGetCoeff(p.p), pGetCoeff(set[i].p))) an = i;
3175      else                                                    en = i;
3176    }
3177  }
3178}
3179/*
3180  int o = p.GetpFDeg();
3181  int op = set[length].GetpFDeg();
3182
3183  if ((op < o)
3184  || ((op == o) && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
3185    return length+1;
3186
3187  int i;
3188  int an = 0;
3189  int en= length;
3190
3191  loop
3192  {
3193    if (an >= en-1)
3194    {
3195      op= set[an].GetpFDeg();
3196      if ((op > o)
3197      || (( op == o) && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
3198        return an;
3199      return en;
3200    }
3201    i=(an+en) / 2;
3202    op = set[i].GetpFDeg();
3203    if (( op > o)
3204    || (( op == o) && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
3205      en=i;
3206    else
3207      an=i;
3208  }
3209}
3210  */
3211/*2
3212* looks up the position of p in T
3213* set[0] is the smallest with respect to the ordering-procedure
3214* totaldegree,pComp
3215*/
3216int posInT110 (const TSet set,const int length,LObject &p)
3217{
3218  if (length==-1) return 0;
3219
3220  int o = p.GetpFDeg();
3221  int op = set[length].GetpFDeg();
3222
3223  if (( op < o)
3224  || (( op == o) && (set[length].length<p.length))
3225  || (( op == o) && (set[length].length == p.length)
3226     && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
3227    return length+1;
3228
3229  int i;
3230  int an = 0;
3231  int en= length;
3232  loop
3233  {
3234    if (an >= en-1)
3235    {
3236      op = set[an].GetpFDeg();
3237      if (( op > o)
3238      || (( op == o) && (set[an].length > p.length))
3239      || (( op == o) && (set[an].length == p.length)
3240         && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
3241        return an;
3242      return en;
3243    }
3244    i=(an+en) / 2;
3245    op = set[i].GetpFDeg();
3246    if (( op > o)
3247    || (( op == o) && (set[i].length > p.length))
3248    || (( op == o) && (set[i].length == p.length)
3249       && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
3250      en=i;
3251    else
3252      an=i;
3253  }
3254}
3255
3256/*2
3257* looks up the position of p in set
3258* set[0] is the smallest with respect to the ordering-procedure
3259* pFDeg
3260*/
3261int posInT13 (const TSet set,const int length,LObject &p)
3262{
3263  if (length==-1) return 0;
3264
3265  int o = p.GetpFDeg();
3266
3267  if (set[length].GetpFDeg() <= o)
3268    return length+1;
3269
3270  int i;
3271  int an = 0;
3272  int en= length;
3273  loop
3274  {
3275    if (an >= en-1)
3276    {
3277      if (set[an].GetpFDeg() > o)
3278        return an;
3279      return en;
3280    }
3281    i=(an+en) / 2;
3282    if (set[i].GetpFDeg() > o)
3283      en=i;
3284    else
3285      an=i;
3286  }
3287}
3288
3289// determines the position based on: 1.) Ecart 2.) pLength
3290int posInT_EcartpLength(const TSet set,const int length,LObject &p)
3291{
3292  if (length==-1) return 0;
3293
3294  int op=p.ecart;
3295  int ol = p.GetpLength();
3296
3297  int oo=set[length].ecart;
3298  if ((oo < op) || ((oo==op) && (set[length].length < ol)))
3299    return length+1;
3300
3301  int i;
3302  int an = 0;
3303  int en= length;
3304  loop
3305    {
3306      if (an >= en-1)
3307      {
3308        int oo=set[an].ecart;
3309        if((oo > op)
3310           || ((oo==op) && (set[an].pLength > ol)))
3311          return an;
3312        return en;
3313      }
3314      i=(an+en) / 2;
3315      int oo=set[i].ecart;
3316      if ((oo > op)
3317          || ((oo == op) && (set[i].pLength > ol)))
3318        en=i;
3319      else
3320        an=i;
3321    }
3322}
3323
3324/*2
3325* looks up the position of p in set
3326* set[0] is the smallest with respect to the ordering-procedure
3327* maximaldegree, pComp
3328*/
3329int posInT15 (const TSet set,const int length,LObject &p)
3330/*{
3331 *int j=0;
3332 * int o;
3333 *
3334 * o = p.GetpFDeg()+p.ecart;
3335 * loop
3336 * {
3337 *   if ((set[j].GetpFDeg()+set[j].ecart > o)
3338 *   || ((set[j].GetpFDeg()+set[j].ecart == o)
3339 *     && (pLmCmp(set[j].p,p.p) == pOrdSgn)))
3340 *   {
3341 *     return j;
3342 *   }
3343 *   j++;
3344 *   if (j > length) return j;
3345 * }
3346 *}
3347 */
3348{
3349  if (length==-1) return 0;
3350
3351  int o = p.GetpFDeg() + p.ecart;
3352  int op = set[length].GetpFDeg()+set[length].ecart;
3353
3354  if ((op < o)
3355  || ((op == o)
3356     && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
3357    return length+1;
3358
3359  int i;
3360  int an = 0;
3361  int en= length;
3362  loop
3363  {
3364    if (an >= en-1)
3365    {
3366      op = set[an].GetpFDeg()+set[an].ecart;
3367      if (( op > o)
3368      || (( op  == o) && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
3369        return an;
3370      return en;
3371    }
3372    i=(an+en) / 2;
3373    op = set[i].GetpFDeg()+set[i].ecart;
3374    if (( op > o)
3375    || (( op == o) && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
3376      en=i;
3377    else
3378      an=i;
3379  }
3380}
3381
3382/*2
3383* looks up the position of p in set
3384* set[0] is the smallest with respect to the ordering-procedure
3385* pFDeg+ecart, ecart, pComp
3386*/
3387int posInT17 (const TSet set,const int length,LObject &p)
3388/*
3389*{
3390* int j=0;
3391* int  o;
3392*
3393*  o = p.GetpFDeg()+p.ecart;
3394*  loop
3395*  {
3396*    if ((pFDeg(set[j].p)+set[j].ecart > o)
3397*    || (((pFDeg(set[j].p)+set[j].ecart == o)
3398*      && (set[j].ecart < p.ecart)))
3399*    || ((pFDeg(set[j].p)+set[j].ecart == o)
3400*      && (set[j].ecart==p.ecart)
3401*      && (pLmCmp(set[j].p,p.p)==pOrdSgn)))
3402*      return j;
3403*    j++;
3404*    if (j > length) return j;
3405*  }
3406* }
3407*/
3408{
3409  if (length==-1) return 0;
3410
3411  int o = p.GetpFDeg() + p.ecart;
3412  int op = set[length].GetpFDeg()+set[length].ecart;
3413
3414  if ((op < o)
3415  || (( op == o) && (set[length].ecart > p.ecart))
3416  || (( op == o) && (set[length].ecart==p.ecart)
3417     && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
3418    return length+1;
3419
3420  int i;
3421  int an = 0;
3422  int en= length;
3423  loop
3424  {
3425    if (an >= en-1)
3426    {
3427      op = set[an].GetpFDeg()+set[an].ecart;
3428      if (( op > o)
3429      || (( op == o) && (set[an].ecart < p.ecart))
3430      || (( op  == o) && (set[an].ecart==p.ecart)
3431         && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
3432        return an;
3433      return en;
3434    }
3435    i=(an+en) / 2;
3436    op = set[i].GetpFDeg()+set[i].ecart;
3437    if ((op > o)
3438    || (( op == o) && (set[i].ecart < p.ecart))
3439    || (( op == o) && (set[i].ecart == p.ecart)
3440       && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
3441      en=i;
3442    else
3443      an=i;
3444  }
3445}
3446/*2
3447* looks up the position of p in set
3448* set[0] is the smallest with respect to the ordering-procedure
3449* pGetComp, pFDeg+ecart, ecart, pComp
3450*/
3451int posInT17_c (const TSet set,const int length,LObject &p)
3452{
3453  if (length==-1) return 0;
3454
3455  int cc = (-1+2*currRing->order[0]==ringorder_c);
3456  /* cc==1 for (c,..), cc==-1 for (C,..) */
3457  int o = p.GetpFDeg() + p.ecart;
3458  int c = pGetComp(p.p)*cc;
3459
3460  if (pGetComp(set[length].p)*cc < c)
3461    return length+1;
3462  if (pGetComp(set[length].p)*cc == c)
3463  {
3464    int op = set[length].GetpFDeg()+set[length].ecart;
3465    if ((op < o)
3466    || ((op == o) && (set[length].ecart > p.ecart))
3467    || ((op == o) && (set[length].ecart==p.ecart)
3468       && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
3469      return length+1;
3470  }
3471
3472  int i;
3473  int an = 0;
3474  int en= length;
3475  loop
3476  {
3477    if (an >= en-1)
3478    {
3479      if (pGetComp(set[an].p)*cc < c)
3480        return en;
3481      if (pGetComp(set[an].p)*cc == c)
3482      {
3483        int op = set[an].GetpFDeg()+set[an].ecart;
3484        if ((op > o)
3485        || ((op == o) && (set[an].ecart < p.ecart))
3486        || ((op == o) && (set[an].ecart==p.ecart)
3487           && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
3488          return an;
3489      }
3490      return en;
3491    }
3492    i=(an+en) / 2;
3493    if (pGetComp(set[i].p)*cc > c)
3494      en=i;
3495    else if (pGetComp(set[i].p)*cc == c)
3496    {
3497      int op = set[i].GetpFDeg()+set[i].ecart;
3498      if ((op > o)
3499      || ((op == o) && (set[i].ecart < p.ecart))
3500      || ((op == o) && (set[i].ecart == p.ecart)
3501         && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
3502        en=i;
3503      else
3504        an=i;
3505    }
3506    else
3507      an=i;
3508  }
3509}
3510
3511/*2
3512* looks up the position of p in set
3513* set[0] is the smallest with respect to
3514* ecart, pFDeg, length
3515*/
3516int posInT19 (const TSet set,const int length,LObject &p)
3517{
3518  if (length==-1) return 0;
3519
3520  int o = p.ecart;
3521  int op=p.GetpFDeg();
3522
3523  if (set[length].ecart < o)
3524    return length+1;
3525  if (set[length].ecart == o)
3526  {
3527     int oo=set[length].GetpFDeg();
3528     if ((oo < op) || ((oo==op) && (set[length].length < p.length)))
3529       return length+1;
3530  }
3531
3532  int i;
3533  int an = 0;
3534  int en= length;
3535  loop
3536  {
3537    if (an >= en-1)
3538    {
3539      if (set[an].ecart > o)
3540        return an;
3541      if (set[an].ecart == o)
3542      {
3543         int oo=set[an].GetpFDeg();
3544         if((oo > op)
3545         || ((oo==op) && (set[an].length > p.length)))
3546           return an;
3547      }
3548      return en;
3549    }
3550    i=(an+en) / 2;
3551    if (set[i].ecart > o)
3552      en=i;
3553    else if (set[i].ecart == o)
3554    {
3555       int oo=set[i].GetpFDeg();
3556       if ((oo > op)
3557       || ((oo == op) && (set[i].length > p.length)))
3558         en=i;
3559       else
3560        an=i;
3561    }
3562    else
3563      an=i;
3564  }
3565}
3566
3567/*2
3568*looks up the position of polynomial p in set
3569*set[length] is the smallest element in set with respect
3570*to the ordering-procedure pComp
3571*/
3572int posInLSpecial (const LSet set, const int length,
3573                   LObject *p,const kStrategy strat)
3574{
3575  if (length<0) return 0;
3576
3577  int d=p->GetpFDeg();
3578  int op=set[length].GetpFDeg();
3579
3580  if ((op > d)
3581  || ((op == d) && (p->p1!=NULL)&&(set[length].p1==NULL))
3582  || (pLmCmp(set[length].p,p->p)== pOrdSgn))
3583     return length+1;
3584
3585  int i;
3586  int an = 0;
3587  int en= length;
3588  loop
3589  {
3590    if (an >= en-1)
3591    {
3592      op=set[an].GetpFDeg();
3593      if ((op > d)
3594      || ((op == d) && (p->p1!=NULL) && (set[an].p1==NULL))
3595      || (pLmCmp(set[an].p,p->p)== pOrdSgn))
3596         return en;
3597      return an;
3598    }
3599    i=(an+en) / 2;
3600    op=set[i].GetpFDeg();
3601    if ((op>d)
3602    || ((op==d) && (p->p1!=NULL) && (set[i].p1==NULL))
3603    || (pLmCmp(set[i].p,p->p) == pOrdSgn))
3604      an=i;
3605    else
3606      en=i;
3607  }
3608}
3609
3610/*2
3611*looks up the position of polynomial p in set
3612*set[length] is the smallest element in set with respect
3613*to the ordering-procedure pComp
3614*/
3615int posInL0 (const LSet set, const int length,
3616             LObject* p,const kStrategy strat)
3617{
3618  if (length<0) return 0;
3619
3620  if (pLmCmp(set[length].p,p->p)== pOrdSgn)
3621    return length+1;
3622
3623  int i;
3624  int an = 0;
3625  int en= length;
3626  loop
3627  {
3628    if (an >= en-1)
3629    {
3630      if (pLmCmp(set[an].p,p->p) == pOrdSgn) return en;
3631      return an;
3632    }
3633    i=(an+en) / 2;
3634    if (pLmCmp(set[i].p,p->p) == pOrdSgn) an=i;
3635    else                                 en=i;
3636    /*aend. fuer lazy == in !=- machen */
3637  }
3638}
3639
3640/*2
3641* looks up the position of polynomial p in set
3642* e is the ecart of p
3643* set[length] is the smallest element in set with respect
3644* to the ordering-procedure totaldegree,pComp
3645*/
3646int posInL11 (const LSet set, const int length,
3647              LObject* p,const kStrategy strat)
3648/*{
3649 * int j=0;
3650 * int o;
3651 *
3652 * o = p->GetpFDeg();
3653 * loop
3654 * {
3655 *   if (j > length)            return j;
3656 *   if ((set[j].GetpFDeg() < o)) return j;
3657 *   if ((set[j].GetpFDeg() == o) && (pLmCmp(set[j].p,p->p) == -pOrdSgn))
3658 *   {
3659 *     return j;
3660 *   }
3661 *   j++;
3662 * }
3663 *}
3664 */
3665{
3666  if (length<0) return 0;
3667
3668  int o = p->GetpFDeg();
3669  int op = set[length].GetpFDeg();
3670
3671  if ((op > o)
3672  || ((op == o) && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
3673    return length+1;
3674  int i;
3675  int an = 0;
3676  int en= length;
3677  loop
3678  {
3679    if (an >= en-1)
3680    {
3681      op = set[an].GetpFDeg();
3682      if ((op > o)
3683      || ((op == o) && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
3684        return en;
3685      return an;
3686    }
3687    i=(an+en) / 2;
3688    op = set[i].GetpFDeg();
3689    if ((op > o)
3690    || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
3691      an=i;
3692    else
3693      en=i;
3694  }
3695}
3696
3697/*2 Position for rings L: Here I am
3698* looks up the position of polynomial p in set
3699* e is the ecart of p
3700* set[length] is the smallest element in set with respect
3701* to the ordering-procedure totaldegree,pComp
3702*/
3703inline int getIndexRng(long coeff)
3704{
3705  if (coeff == 0) return -1;
3706  long tmp = coeff;
3707  int ind = 0;
3708  while (tmp % 2 == 0)
3709  {
3710    tmp = tmp / 2;
3711    ind++;
3712  }
3713  return ind;
3714}
3715
3716int posInLrg0 (const LSet set, const int length,
3717              LObject* p,const kStrategy strat)
3718/*          if (nGreater(pGetCoeff(p), pGetCoeff(set[an]))) return en;
3719        if (pLmCmp(set[i],p) == cmp_int)         en = i;
3720        else if (pLmCmp(set[i],p) == -cmp_int)   an = i;
3721        else
3722        {
3723          if (nGreater(pGetCoeff(p), pGetCoeff(set[i]))) an = i;
3724          else en = i;
3725        }*/
3726{
3727  if (length < 0) return 0;
3728
3729  int o = p->GetpFDeg();
3730  int op = set[length].GetpFDeg();
3731
3732  if ((op > o) || ((op == o) && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
3733    return length + 1;
3734  int i;
3735  int an = 0;
3736  int en = length;
3737  loop
3738  {
3739    if (an >= en - 1)
3740    {
3741      op = set[an].GetpFDeg();
3742      if ((op > o) || ((op == o) && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
3743        return en;
3744      return an;
3745    }
3746    i = (an+en) / 2;
3747    op = set[i].GetpFDeg();
3748    if ((op > o) || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
3749      an = i;
3750    else
3751      en = i;
3752  }
3753}
3754
3755/*{
3756  if (length < 0) return 0;
3757
3758  int o = p->GetpFDeg();
3759  int op = set[length].GetpFDeg();
3760
3761  int inde = getIndexRng((unsigned long) pGetCoeff(set[length].p));
3762  int indp = getIndexRng((unsigned long) pGetCoeff(p->p));
3763  int inda;
3764  int indi;
3765
3766  if ((inda > indp) || ((inda == inde) && ((op > o) || ((op == o) && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))))
3767    return length + 1;
3768  int i;
3769  int an = 0;
3770  inda = getIndexRng((unsigned long) pGetCoeff(set[an].p));
3771  int en = length;
3772  loop
3773  {
3774    if (an >= en-1)
3775    {
3776      op = set[an].GetpFDeg();
3777      if ((indp > inda) || ((indp == inda) && ((op > o) || ((op == o) && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))))
3778        return en;
3779      return an;
3780    }
3781    i = (an + en) / 2;
3782    indi = getIndexRng((unsigned long) pGetCoeff(set[i].p));
3783    op = set[i].GetpFDeg();
3784    if ((indi > indp) || ((indi == indp) && ((op > o) || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))))
3785    // if ((op > o) || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
3786    {
3787      an = i;
3788      inda = getIndexRng((unsigned long) pGetCoeff(set[an].p));
3789    }
3790    else
3791      en = i;
3792  }
3793} */
3794
3795/*2
3796* looks up the position of polynomial p in set
3797* set[length] is the smallest element in set with respect
3798* to the ordering-procedure totaldegree,pLength0
3799*/
3800int posInL110 (const LSet set, const int length,
3801               LObject* p,const kStrategy strat)
3802{
3803  if (length<0) return 0;
3804
3805  int o = p->GetpFDeg();
3806  int op = set[length].GetpFDeg();
3807
3808  if ((op > o)
3809  || ((op == o) && (set[length].length >p->length))
3810  || ((op == o) && (set[length].length <= p->length)
3811     && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
3812    return length+1;
3813  int i;
3814  int an = 0;
3815  int en= length;
3816  loop
3817  {
3818    if (an >= en-1)
3819    {
3820      op = set[an].GetpFDeg();
3821      if ((op > o)
3822      || ((op == o) && (set[an].length >p->length))
3823      || ((op == o) && (set[an].length <=p->length)
3824         && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
3825        return en;
3826      return an;
3827    }
3828    i=(an+en) / 2;
3829    op = set[i].GetpFDeg();
3830    if ((op > o)
3831    || ((op == o) && (set[i].length > p->length))
3832    || ((op == o) && (set[i].length <= p->length)
3833       && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
3834      an=i;
3835    else
3836      en=i;
3837  }
3838}
3839
3840/*2
3841* looks up the position of polynomial p in set
3842* e is the ecart of p
3843* set[length] is the smallest element in set with respect
3844* to the ordering-procedure totaldegree
3845*/
3846int posInL13 (const LSet set, const int length,
3847              LObject* p,const kStrategy strat)
3848{
3849  if (length<0) return 0;
3850
3851  int o = p->GetpFDeg();
3852
3853  if (set[length].GetpFDeg() > o)
3854    return length+1;
3855
3856  int i;
3857  int an = 0;
3858  int en= length;
3859  loop
3860  {
3861    if (an >= en-1)
3862    {
3863      if (set[an].GetpFDeg() >= o)
3864        return en;
3865      return an;
3866    }
3867    i=(an+en) / 2;
3868    if (set[i].GetpFDeg() >= o)
3869      an=i;
3870    else
3871      en=i;
3872  }
3873}
3874
3875/*2
3876* looks up the position of polynomial p in set
3877* e is the ecart of p
3878* set[length] is the smallest element in set with respect
3879* to the ordering-procedure maximaldegree,pComp
3880*/
3881int posInL15 (const LSet set, const int length,
3882              LObject* p,const kStrategy strat)
3883/*{
3884 * int j=0;
3885 * int o;
3886 *
3887 * o = p->ecart+p->GetpFDeg();
3888 * loop
3889 * {
3890 *   if (j > length)                       return j;
3891 *   if (set[j].GetpFDeg()+set[j].ecart < o) return j;
3892 *   if ((set[j].GetpFDeg()+set[j].ecart == o)
3893 *   && (pLmCmp(set[j].p,p->p) == -pOrdSgn))
3894 *   {
3895 *     return j;
3896 *   }
3897 *   j++;
3898 * }
3899 *}
3900 */
3901{
3902  if (length<0) return 0;
3903
3904  int o = p->GetpFDeg() + p->ecart;
3905  int op = set[length].GetpFDeg() + set[length].ecart;
3906
3907  if ((op > o)
3908  || ((op == o) && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
3909    return length+1;
3910  int i;
3911  int an = 0;
3912  int en= length;
3913  loop
3914  {
3915    if (an >= en-1)
3916    {
3917      op = set[an].GetpFDeg() + set[an].ecart;
3918      if ((op > o)
3919      || ((op == o) && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
3920        return en;
3921      return an;
3922    }
3923    i=(an+en) / 2;
3924    op = set[i].GetpFDeg() + set[i].ecart;
3925    if ((op > o)
3926    || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
3927      an=i;
3928    else
3929      en=i;
3930  }
3931}
3932
3933/*2
3934* looks up the position of polynomial p in set
3935* e is the ecart of p
3936* set[length] is the smallest element in set with respect
3937* to the ordering-procedure totaldegree
3938*/
3939int posInL17 (const LSet set, const int length,
3940              LObject* p,const kStrategy strat)
3941{
3942  if (length<0) return 0;
3943
3944  int o = p->GetpFDeg() + p->ecart;
3945
3946  if ((set[length].GetpFDeg() + set[length].ecart > o)
3947  || ((set[length].GetpFDeg() + set[length].ecart == o)
3948     && (set[length].ecart > p->ecart))
3949  || ((set[length].GetpFDeg() + set[length].ecart == o)
3950     && (set[length].ecart == p->ecart)
3951     && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
3952    return length+1;
3953  int i;
3954  int an = 0;
3955  int en= length;
3956  loop
3957  {
3958    if (an >= en-1)
3959    {
3960      if ((set[an].GetpFDeg() + set[an].ecart > o)
3961      || ((set[an].GetpFDeg() + set[an].ecart == o)
3962         && (set[an].ecart > p->ecart))
3963      || ((set[an].GetpFDeg() + set[an].ecart == o)
3964         && (set[an].ecart == p->ecart)
3965         && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
3966        return en;
3967      return an;
3968    }
3969    i=(an+en) / 2;
3970    if ((set[i].GetpFDeg() + set[i].ecart > o)
3971    || ((set[i].GetpFDeg() + set[i].ecart == o)
3972       && (set[i].ecart > p->ecart))
3973    || ((set[i].GetpFDeg() +set[i].ecart == o)
3974       && (set[i].ecart == p->ecart)
3975       && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
3976      an=i;
3977    else
3978      en=i;
3979  }
3980}
3981/*2
3982* looks up the position of polynomial p in set
3983* e is the ecart of p
3984* set[length] is the smallest element in set with respect
3985* to the ordering-procedure pComp
3986*/
3987int posInL17_c (const LSet set, const int length,
3988                LObject* p,const kStrategy strat)
3989{
3990  if (length<0) return 0;
3991
3992  int cc = (-1+2*currRing->order[0]==ringorder_c);
3993  /* cc==1 for (c,..), cc==-1 for (C,..) */
3994  int c = pGetComp(p->p)*cc;
3995  int o = p->GetpFDeg() + p->ecart;
3996
3997  if (pGetComp(set[length].p)*cc > c)
3998    return length+1;
3999  if (pGetComp(set[length].p)*cc == c)
4000  {
4001    if ((set[length].GetpFDeg() + set[length].ecart > o)
4002    || ((set[length].GetpFDeg() + set[length].ecart == o)
4003       && (set[length].ecart > p->ecart))
4004    || ((set[length].GetpFDeg() + set[length].ecart == o)
4005       && (set[length].ecart == p->ecart)
4006       && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
4007      return length+1;
4008  }
4009  int i;
4010  int an = 0;
4011  int en= length;
4012  loop
4013  {
4014    if (an >= en-1)
4015    {
4016      if (pGetComp(set[an].p)*cc > c)
4017        return en;
4018      if (pGetComp(set[an].p)*cc == c)
4019      {
4020        if ((set[an].GetpFDeg() + set[an].ecart > o)
4021        || ((set[an].GetpFDeg() + set[an].ecart == o)
4022           && (set[an].ecart > p->ecart))
4023        || ((set[an].GetpFDeg() + set[an].ecart == o)
4024           && (set[an].ecart == p->ecart)
4025           && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
4026          return en;
4027      }
4028      return an;
4029    }
4030    i=(an+en) / 2;
4031    if (pGetComp(set[i].p)*cc > c)
4032      an=i;
4033    else if (pGetComp(set[i].p)*cc == c)
4034    {
4035      if ((set[i].GetpFDeg() + set[i].ecart > o)
4036      || ((set[i].GetpFDeg() + set[i].ecart == o)
4037         && (set[i].ecart > p->ecart))
4038      || ((set[i].GetpFDeg() +set[i].ecart == o)
4039         && (set[i].ecart == p->ecart)
4040         && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
4041        an=i;
4042      else
4043        en=i;
4044    }
4045    else
4046      en=i;
4047  }
4048}
4049
4050/***************************************************************
4051 *
4052 * Tail reductions
4053 *
4054 ***************************************************************/
4055TObject*
4056kFindDivisibleByInS(kStrategy strat, int pos, LObject* L, TObject *T,
4057                    long ecart)
4058{
4059  int j = 0;
4060  const unsigned long not_sev = ~L->sev;
4061  const unsigned long* sev = strat->sevS;
4062  poly p;
4063  ring r;
4064  L->GetLm(p, r);
4065
4066  assume(~not_sev == p_GetShortExpVector(p, r));
4067
4068  if (r == currRing)
4069  {
4070    loop
4071    {
4072      if (j > pos) return NULL;
4073#if defined(PDEBUG) || defined(PDIV_DEBUG)
4074      if (p_LmShortDivisibleBy(strat->S[j], sev[j], p, not_sev, r) &&
4075          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
4076        break;
4077#else
4078      if (!(sev[j] & not_sev) &&
4079          (ecart== LONG_MAX || ecart>= strat->ecartS[j]) &&
4080          p_LmDivisibleBy(strat->S[j], p, r))
4081        break;
4082
4083#endif
4084      j++;
4085    }
4086    // if called from NF, T objects do not exist:
4087    if (strat->tl < 0 || strat->S_2_R[j] == -1)
4088    {
4089      T->Set(strat->S[j], r, strat->tailRing);
4090      return T;
4091    }
4092    else
4093    {
4094/////      assume (j >= 0 && j <= strat->tl && strat->S_2_T(j) != NULL
4095/////      && strat->S_2_T(j)->p == strat->S[j]); // wrong?
4096//      assume (j >= 0 && j <= strat->sl && strat->S_2_T(j) != NULL && strat->S_2_T(j)->p == strat->S[j]);
4097      return strat->S_2_T(j);
4098    }
4099  }
4100  else
4101  {
4102    TObject* t;
4103    loop
4104    {
4105      if (j > pos) return NULL;
4106      assume(strat->S_2_R[j] != -1);
4107#if defined(PDEBUG) || defined(PDIV_DEBUG)
4108      t = strat->S_2_T(j);
4109      assume(t != NULL && t->t_p != NULL && t->tailRing == r);
4110      if (p_LmShortDivisibleBy(t->t_p, sev[j], p, not_sev, r) &&
4111          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
4112        return t;
4113#else
4114      if (! (sev[j] & not_sev) && (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
4115      {
4116        t = strat->S_2_T(j);
4117        assume(t != NULL && t->t_p != NULL && t->tailRing == r && t->p == strat->S[j]);
4118        if (p_LmDivisibleBy(t->t_p, p, r)) return t;
4119      }
4120#endif
4121      j++;
4122    }
4123  }
4124}
4125
4126poly redtail (LObject* L, int pos, kStrategy strat)
4127{
4128  poly h, hn;
4129  int j;
4130  unsigned long not_sev;
4131  strat->redTailChange=FALSE;
4132
4133  poly p = L->p;
4134  if (strat->noTailReduction || pNext(p) == NULL)
4135    return p;
4136
4137  LObject Ln(strat->tailRing);
4138  TObject* With;
4139  // placeholder in case strat->tl < 0
4140  TObject  With_s(strat->tailRing);
4141  h = p;
4142  hn = pNext(h);
4143  long op = strat->tailRing->pFDeg(hn, strat->tailRing);
4144  long e;
4145  int l;
4146  BOOLEAN save_HE=strat->kHEdgeFound;
4147  strat->kHEdgeFound |=
4148    ((Kstd1_deg>0) && (op<=Kstd1_deg)) || TEST_OPT_INFREDTAIL;
4149
4150  while(hn != NULL)
4151  {
4152    op = strat->tailRing->pFDeg(hn, strat->tailRing);
4153    if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
4154    e = strat->tailRing->pLDeg(hn, &l, strat->tailRing) - op;
4155    loop
4156    {
4157      Ln.Set(hn, strat->tailRing);
4158      Ln.sev = p_GetShortExpVector(hn, strat->tailRing);
4159      if (strat->kHEdgeFound)
4160        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
4161      else
4162        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s, e);
4163      if (With == NULL) break;
4164      With->length=0;
4165      With->pLength=0;
4166      strat->redTailChange=TRUE;
4167      if (ksReducePolyTail(L, With, h, strat->kNoetherTail()))
4168      {
4169        // reducing the tail would violate the exp bound
4170        if (kStratChangeTailRing(strat, L))
4171        {
4172          strat->kHEdgeFound = save_HE;
4173          return redtail(L, pos, strat);
4174        }
4175        else
4176          return NULL;
4177      }
4178      hn = pNext(h);
4179      if (hn == NULL) goto all_done;
4180      op = strat->tailRing->pFDeg(hn, strat->tailRing);
4181      if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
4182      e = strat->tailRing->pLDeg(hn, &l, strat->tailRing) - op;
4183    }
4184    h = hn;
4185    hn = pNext(h);
4186  }
4187
4188  all_done:
4189  if (strat->redTailChange)
4190  {
4191    L->last = 0;
4192    L->pLength = 0;
4193  }
4194  strat->kHEdgeFound = save_HE;
4195  return p;
4196}
4197
4198poly redtail (poly p, int pos, kStrategy strat)
4199{
4200  LObject L(p, currRing);
4201  return redtail(&L, pos, strat);
4202}
4203
4204poly redtailBba (LObject* L, int pos, kStrategy strat, BOOLEAN withT, BOOLEAN normalize)
4205{
4206#define REDTAIL_CANONICALIZE 100
4207  strat->redTailChange=FALSE;
4208  if (strat->noTailReduction) return L->GetLmCurrRing();
4209  poly h, p;
4210  p = h = L->GetLmTailRing();
4211  if ((h==NULL) || (pNext(h)==NULL))
4212    return L->GetLmCurrRing();
4213
4214  TObject* With;
4215  // placeholder in case strat->tl < 0
4216  TObject  With_s(strat->tailRing);
4217
4218  LObject Ln(pNext(h), strat->tailRing);
4219  Ln.pLength = L->GetpLength() - 1;
4220
4221  pNext(h) = NULL;
4222  if (L->p != NULL) pNext(L->p) = NULL;
4223  L->pLength = 1;
4224
4225  Ln.PrepareRed(strat->use_buckets);
4226
4227  int cnt=REDTAIL_CANONICALIZE;
4228  while(!Ln.IsNull())
4229  {
4230    loop
4231    {
4232      Ln.SetShortExpVector();
4233      if (withT)
4234      {
4235        int j;
4236        j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln);
4237        if (j < 0) break;
4238        With = &(strat->T[j]);
4239      }
4240      else
4241      {
4242        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
4243        if (With == NULL) break;
4244      }
4245      cnt--;
4246      if (cnt==0)
4247      {
4248        cnt=REDTAIL_CANONICALIZE; 
4249        poly tmp=Ln.CanonicalizeP(); 
4250        if (normalize) 
4251        {
4252          Ln.Normalize();
4253          //pNormalize(tmp);
4254          //if (TEST_OPT_PROT) { PrintS("n"); mflush(); }
4255        }
4256      }
4257      if (normalize && (!TEST_OPT_INTSTRATEGY) && (!nIsOne(pGetCoeff(With->p))))
4258      {
4259        With->pNorm();
4260      }
4261      strat->redTailChange=TRUE;
4262      if (ksReducePolyTail(L, With, &Ln))
4263      {
4264        // reducing the tail would violate the exp bound
4265        //  set a flag and hope for a retry (in bba)
4266        strat->completeReduce_retry=TRUE;
4267        do
4268        {
4269          pNext(h) = Ln.LmExtractAndIter();
4270          pIter(h);
4271          L->pLength++;
4272        } while (!Ln.IsNull());
4273        goto all_done;
4274      }
4275      if (Ln.IsNull()) goto all_done;
4276      if (! withT) With_s.Init(currRing);
4277    }
4278    pNext(h) = Ln.LmExtractAndIter();
4279    pIter(h);
4280    pNormalize(h);
4281    L->pLength++;
4282  }
4283
4284  all_done:
4285  Ln.Delete();
4286  if (L->p != NULL) pNext(L->p) = pNext(p);
4287
4288  if (strat->redTailChange)
4289  {
4290    L->last = NULL;
4291    L->length = 0;
4292  }
4293
4294  //if (TEST_OPT_PROT) { PrintS("N"); mflush(); }
4295  //L->Normalize(); // HANNES: should have a test
4296  kTest_L(L);
4297  return L->GetLmCurrRing();
4298}
4299
4300/*2
4301*checks the change degree and write progress report
4302*/
4303void message (int i,int* reduc,int* olddeg,kStrategy strat, int red_result)
4304{
4305  if (i != *olddeg)
4306  {
4307    Print("%d",i);
4308    *olddeg = i;
4309  }
4310  if (K_TEST_OPT_OLDSTD)
4311  {
4312    if (strat->Ll != *reduc)
4313    {
4314      if (strat->Ll != *reduc-1)
4315        Print("(%d)",strat->Ll+1);
4316      else
4317        PrintS("-");
4318      *reduc = strat->Ll;
4319    }
4320    else
4321      PrintS(".");
4322    mflush();
4323  }
4324  else
4325  {
4326    if (red_result == 0)
4327      PrintS("-");
4328    else if (red_result < 0)
4329      PrintS(".");
4330    if ((red_result > 0) || ((strat->Ll % 100)==99))
4331    {
4332      if (strat->Ll != *reduc && strat->Ll > 0)
4333      {
4334        Print("(%d)",strat->Ll+1);
4335        *reduc = strat->Ll;
4336      }
4337    }
4338  }
4339}
4340
4341/*2
4342*statistics
4343*/
4344void messageStat (int srmax,int lrmax,int hilbcount,kStrategy strat)
4345{
4346  //PrintS("\nUsage/Allocation of temporary storage:\n");
4347  //Print("%d/%d polynomials in standard base\n",srmax,IDELEMS(Shdl));
4348  //Print("%d/%d polynomials in set L (for lazy alg.)",lrmax+1,strat->Lmax);
4349  Print("product criterion:%d chain criterion:%d\n",strat->cp,strat->c3);
4350  if (hilbcount!=0) Print("hilbert series criterion:%d\n",hilbcount);
4351  /* in usual case strat->cv is 0, it gets changed only in shift routines */
4352  if (strat->cv!=0) Print("shift V criterion:%d\n",strat->cv);
4353  /*mflush();*/
4354}
4355
4356#ifdef KDEBUG
4357/*2
4358*debugging output: all internal sets, if changed
4359*for testing purpuse only/has to be changed for later use
4360*/
4361void messageSets (kStrategy strat)
4362{
4363  int i;
4364  if (strat->news)
4365  {
4366    PrintS("set S");
4367    for (i=0; i<=strat->sl; i++)
4368    {
4369      Print("\n  %d:",i);
4370      p_wrp(strat->S[i], currRing, strat->tailRing);
4371    }
4372    strat->news = FALSE;
4373  }
4374  if (strat->newt)
4375  {
4376    PrintS("\nset T");
4377    for (i=0; i<=strat->tl; i++)
4378    {
4379      Print("\n  %d:",i);
4380      strat->T[i].wrp();
4381      Print(" o:%d e:%d l:%d",
4382        strat->T[i].pFDeg(),strat->T[i].ecart,strat->T[i].length);
4383    }
4384    strat->newt = FALSE;
4385  }
4386  PrintS("\nset L");
4387  for (i=strat->Ll; i>=0; i--)
4388  {
4389    Print("\n%d:",i);
4390    p_wrp(strat->L[i].p1, currRing, strat->tailRing);
4391    PrintS("  ");
4392    p_wrp(strat->L[i].p2, currRing, strat->tailRing);
4393    PrintS(" lcm: ");p_wrp(strat->L[i].lcm, currRing);
4394    PrintS("\n  p : ");
4395    strat->L[i].wrp();
4396    Print("  o:%d e:%d l:%d",
4397          strat->L[i].pFDeg(),strat->L[i].ecart,strat->L[i].length);
4398  }
4399  PrintLn();
4400}
4401
4402#endif
4403
4404
4405/*2
4406*construct the set s from F
4407*/
4408void initS (ideal F, ideal Q,kStrategy strat)
4409{
4410  int   i,pos;
4411
4412  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
4413  else i=setmaxT;
4414  strat->ecartS=initec(i);
4415  strat->sevS=initsevS(i);
4416  strat->S_2_R=initS_2_R(i);
4417  strat->fromQ=NULL;
4418  strat->Shdl=idInit(i,F->rank);
4419  strat->S=strat->Shdl->m;
4420  /*- put polys into S -*/
4421  if (Q!=NULL)
4422  {
4423    strat->fromQ=initec(i);
4424    memset(strat->fromQ,0,i*sizeof(int));
4425    for (i=0; i<IDELEMS(Q); i++)
4426    {
4427      if (Q->m[i]!=NULL)
4428      {
4429        LObject h;
4430        h.p = pCopy(Q->m[i]);
4431        if (TEST_OPT_INTSTRATEGY)
4432        {
4433          //pContent(h.p);
4434          h.pCleardenom(); // also does a pContent
4435        }
4436        else
4437        {
4438          h.pNorm();
4439        }
4440        if (pOrdSgn==-1)
4441        {
4442          deleteHC(&h, strat);
4443        }
4444        if (h.p!=NULL)
4445        {
4446          strat->initEcart(&h);
4447          if (strat->sl==-1)
4448            pos =0;
4449          else
4450          {
4451            pos = posInS(strat,strat->sl,h.p,h.ecart);
4452          }
4453          h.sev = pGetShortExpVector(h.p);
4454          strat->enterS(h,pos,strat,-1);
4455          strat->fromQ[pos]=1;
4456        }
4457      }
4458    }
4459  }
4460  for (i=0; i<IDELEMS(F); i++)
4461  {
4462    if (F->m[i]!=NULL)
4463    {
4464      LObject h;
4465      h.p = pCopy(F->m[i]);
4466      if (pOrdSgn==-1)
4467      {
4468        cancelunit(&h);  /*- tries to cancel a unit -*/
4469        deleteHC(&h, strat);
4470      }
4471      if (TEST_OPT_INTSTRATEGY)
4472      {
4473        //pContent(h.p);
4474        h.pCleardenom(); // also does a pContent
4475      }
4476      else
4477      {
4478        h.pNorm();
4479      }
4480      if (h.p!=NULL)
4481      {
4482        strat->initEcart(&h);
4483        if (strat->sl==-1)
4484          pos =0;
4485        else
4486          pos = posInS(strat,strat->sl,h.p,h.ecart);
4487        h.sev = pGetShortExpVector(h.p);
4488        strat->enterS(h,pos,strat,-1);
4489      }
4490    }
4491  }
4492  /*- test, if a unit is in F -*/
4493  if ((strat->sl>=0)
4494#ifdef HAVE_RINGS
4495       && nIsUnit(pGetCoeff(strat->S[0]))
4496#endif
4497       && pIsConstant(strat->S[0]))
4498  {
4499    while (strat->sl>0) deleteInS(strat->sl,strat);
4500  }
4501}
4502
4503void initSL (ideal F, ideal Q,kStrategy strat)
4504{
4505  int   i,pos;
4506
4507  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
4508  else i=setmaxT;
4509  strat->ecartS=initec(i);
4510  strat->sevS=initsevS(i);
4511  strat->S_2_R=initS_2_R(i);
4512  strat->fromQ=NULL;
4513  strat->Shdl=idInit(i,F->rank);
4514  strat->S=strat->Shdl->m;
4515  /*- put polys into S -*/
4516  if (Q!=NULL)
4517  {
4518    strat->fromQ=initec(i);
4519    memset(strat->fromQ,0,i*sizeof(int));
4520    for (i=0; i<IDELEMS(Q); i++)
4521    {
4522      if (Q->m[i]!=NULL)
4523      {
4524        LObject h;
4525        h.p = pCopy(Q->m[i]);
4526        if (pOrdSgn==-1)
4527        {
4528          deleteHC(&h,strat);
4529        }
4530        if (TEST_OPT_INTSTRATEGY)
4531        {
4532          //pContent(h.p);
4533          h.pCleardenom(); // also does a pContent
4534        }
4535        else
4536        {
4537          h.pNorm();
4538        }
4539        if (h.p!=NULL)
4540        {
4541          strat->initEcart(&h);
4542          if (strat->sl==-1)
4543            pos =0;
4544          else
4545          {
4546            pos = posInS(strat,strat->sl,h.p,h.ecart);
4547          }
4548          h.sev = pGetShortExpVector(h.p);
4549          strat->enterS(h,pos,strat,-1);
4550          strat->fromQ[pos]=1;
4551        }
4552      }
4553    }
4554  }
4555  for (i=0; i<IDELEMS(F); i++)
4556  {
4557    if (F->m[i]!=NULL)
4558    {
4559      LObject h;
4560      h.p = pCopy(F->m[i]);
4561      if (h.p!=NULL)
4562      {
4563        if (pOrdSgn==-1)
4564        {
4565          cancelunit(&h);  /*- tries to cancel a unit -*/
4566          deleteHC(&h, strat);
4567        }
4568        if (h.p!=NULL)
4569        {
4570          if (TEST_OPT_INTSTRATEGY)
4571          {
4572            //pContent(h.p);
4573            h.pCleardenom(); // also does a pContent
4574          }
4575          else
4576          {
4577            h.pNorm();
4578          }
4579          strat->initEcart(&h);
4580          if (strat->Ll==-1)
4581            pos =0;
4582          else
4583            pos = strat->posInL(strat->L,strat->Ll,&h,strat);
4584          h.sev = pGetShortExpVector(h.p);
4585          enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
4586        }
4587      }
4588    }
4589  }
4590  /*- test, if a unit is in F -*/
4591
4592  if ((strat->Ll>=0) 
4593#ifdef HAVE_RINGS
4594       && nIsUnit(pGetCoeff(strat->L[strat->Ll].p))
4595#endif
4596       && pIsConstant(strat->L[strat->Ll].p))
4597  {
4598    while (strat->Ll>0) deleteInL(strat->L,&strat->Ll,strat->Ll-1,strat);
4599  }
4600}
4601
4602
4603/*2
4604*construct the set s from F and {P}
4605*/
4606void initSSpecial (ideal F, ideal Q, ideal P,kStrategy strat)
4607{
4608  int   i,pos;
4609
4610  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
4611  else i=setmaxT;
4612  i=((i+IDELEMS(F)+IDELEMS(P)+15)/16)*16;
4613  strat->ecartS=initec(i);
4614  strat->sevS=initsevS(i);
4615  strat->S_2_R=initS_2_R(i);
4616  strat->fromQ=NULL;
4617  strat->Shdl=idInit(i,F->rank);
4618  strat->S=strat->Shdl->m;
4619
4620  /*- put polys into S -*/
4621  if (Q!=NULL)
4622  {
4623    strat->fromQ=initec(i);
4624    memset(strat->fromQ,0,i*sizeof(int));
4625    for (i=0; i<IDELEMS(Q); i++)
4626    {
4627      if (Q->m[i]!=NULL)
4628      {
4629        LObject h;
4630        h.p = pCopy(Q->m[i]);
4631        //if (TEST_OPT_INTSTRATEGY)
4632        //{
4633        //  //pContent(h.p);
4634        //  h.pCleardenom(); // also does a pContent
4635        //}
4636        //else
4637        //{
4638        //  h.pNorm();
4639        //}
4640        if (pOrdSgn==-1)
4641        {
4642          deleteHC(&h,strat);
4643        }
4644        if (h.p!=NULL)
4645        {
4646          strat->initEcart(&h);
4647          if (strat->sl==-1)
4648            pos =0;
4649          else
4650          {
4651            pos = posInS(strat,strat->sl,h.p,h.ecart);
4652          }
4653          h.sev = pGetShortExpVector(h.p);
4654          strat->enterS(h,pos,strat, strat->tl+1);
4655          enterT(h, strat);
4656          strat->fromQ[pos]=1;
4657        }
4658      }
4659    }
4660  }
4661  /*- put polys into S -*/
4662  for (i=0; i<IDELEMS(F); i++)
4663  {
4664    if (F->m[i]!=NULL)
4665    {
4666      LObject h;
4667      h.p = pCopy(F->m[i]);
4668      if (pOrdSgn==-1)
4669      {
4670        deleteHC(&h,strat);
4671      }
4672      else
4673      {
4674        h.p=redtailBba(h.p,strat->sl,strat);
4675      }
4676      if (h.p!=NULL)
4677      {
4678        strat->initEcart(&h);
4679        if (strat->sl==-1)
4680          pos =0;
4681        else
4682          pos = posInS(strat,strat->sl,h.p,h.ecart);
4683        h.sev = pGetShortExpVector(h.p);
4684        strat->enterS(h,pos,strat, strat->tl+1);
4685        enterT(h,strat);
4686      }
4687    }
4688  }
4689  for (i=0; i<IDELEMS(P); i++)
4690  {
4691    if (P->m[i]!=NULL)
4692    {
4693      LObject h;
4694      h.p=pCopy(P->m[i]);
4695      if (TEST_OPT_INTSTRATEGY)
4696      {
4697        h.pCleardenom();
4698      }
4699      else
4700      {
4701        h.pNorm();
4702      }
4703      if(strat->sl>=0)
4704      {
4705        if (pOrdSgn==1)
4706        {
4707          h.p=redBba(h.p,strat->sl,strat);
4708          if (h.p!=NULL)
4709          {
4710            h.p=redtailBba(h.p,strat->sl,strat);
4711          }
4712        }
4713        else
4714        {
4715          h.p=redMora(h.p,strat->sl,strat);
4716        }
4717        if(h.p!=NULL)
4718        {
4719          strat->initEcart(&h);
4720          if (TEST_OPT_INTSTRATEGY)
4721          {
4722            h.pCleardenom();
4723          }
4724          else
4725          {
4726            h.is_normalized = 0;
4727            h.pNorm();
4728          }
4729          h.sev = pGetShortExpVector(h.p);
4730          h.SetpFDeg();
4731          pos = posInS(strat,strat->sl,h.p,h.ecart);
4732          enterpairsSpecial(h.p,strat->sl,h.ecart,pos,strat,strat->tl+1);
4733          strat->enterS(h,pos,strat, strat->tl+1);
4734          enterT(h,strat);
4735        }
4736      }
4737      else
4738      {
4739        h.sev = pGetShortExpVector(h.p);
4740        strat->initEcart(&h);
4741        strat->enterS(h,0,strat, strat->tl+1);
4742        enterT(h,strat);
4743      }
4744    }
4745  }
4746}
4747/*2
4748* reduces h using the set S
4749* procedure used in cancelunit1
4750*/
4751static poly redBba1 (poly h,int maxIndex,kStrategy strat)
4752{
4753  int j = 0;
4754  unsigned long not_sev = ~ pGetShortExpVector(h);
4755
4756  while (j <= maxIndex)
4757  {
4758    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j],h, not_sev))
4759       return ksOldSpolyRedNew(strat->S[j],h,strat->kNoetherTail());
4760    else j++;
4761  }
4762  return h;
4763}
4764
4765/*2
4766*tests if p.p=monomial*unit and cancels the unit
4767*/
4768void cancelunit1 (LObject* p,int *suc, int index,kStrategy strat )
4769{
4770  int k;
4771  poly r,h,h1,q;
4772
4773  if (!pIsVector((*p).p) && ((*p).ecart != 0))
4774  {
4775    k = 0;
4776    h1 = r = pCopy((*p).p);
4777    h =pNext(r);
4778    loop
4779    {
4780      if (h==NULL)
4781      {
4782        pDelete(&r);
4783        pDelete(&(pNext((*p).p)));
4784        (*p).ecart = 0;
4785        (*p).length = 1;
4786        (*suc)=0;
4787        return;
4788      }
4789      if (!pDivisibleBy(r,h))
4790      {
4791        q=redBba1(h,index ,strat);
4792        if (q != h)
4793        {
4794          k++;
4795          pDelete(&h);
4796          pNext(h1) = h = q;
4797        }
4798        else
4799        {
4800          pDelete(&r);
4801          return;
4802        }
4803      }
4804      else
4805      {
4806        h1 = h;
4807        pIter(h);
4808      }
4809      if (k > 10)
4810      {
4811        pDelete(&r);
4812        return;
4813      }
4814    }
4815  }
4816}
4817
4818#if 0
4819/*2
4820* reduces h using the elements from Q in the set S
4821* procedure used in updateS
4822* must not be used for elements of Q or elements of an ideal !
4823*/
4824static poly redQ (poly h, int j, kStrategy strat)
4825{
4826  int start;
4827  unsigned long not_sev = ~ pGetShortExpVector(h);
4828  while ((j <= strat->sl) && (pGetComp(strat->S[j])!=0)) j++;
4829  start=j;
4830  while (j<=strat->sl)
4831  {
4832    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev))
4833    {
4834      h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
4835      if (h==NULL) return NULL;
4836      j = start;
4837      not_sev = ~ pGetShortExpVector(h);
4838    }
4839    else j++;
4840  }
4841  return h;
4842}
4843#endif
4844
4845/*2
4846* reduces h using the set S
4847* procedure used in updateS
4848*/
4849static poly redBba (poly h,int maxIndex,kStrategy strat)
4850{
4851  int j = 0;
4852  unsigned long not_sev = ~ pGetShortExpVector(h);
4853
4854  while (j <= maxIndex)
4855  {
4856    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev))
4857    {
4858      h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
4859      if (h==NULL) return NULL;
4860      j = 0;
4861      not_sev = ~ pGetShortExpVector(h);    }
4862    else j++;
4863  }
4864  return h;
4865}
4866
4867/*2
4868* reduces h using the set S
4869*e is the ecart of h
4870*procedure used in updateS
4871*/
4872static poly redMora (poly h,int maxIndex,kStrategy strat)
4873{
4874  int  j=0;
4875  int  e,l;
4876  unsigned long not_sev = ~ pGetShortExpVector(h);
4877
4878  if (maxIndex >= 0)
4879  {
4880    e = pLDeg(h,&l,currRing)-pFDeg(h,currRing);
4881    do
4882    {
4883      if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev)
4884      && ((e >= strat->ecartS[j]) || strat->kHEdgeFound))
4885      {
4886#ifdef KDEBUG
4887        if (TEST_OPT_DEBUG)
4888          {PrintS("reduce ");wrp(h);Print(" with S[%d] (",j);wrp(strat->S[j]);}
4889#endif
4890        h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
4891#ifdef KDEBUG
4892        if(TEST_OPT_DEBUG)
4893          {PrintS(")\nto "); wrp(h); PrintLn();}
4894#endif
4895        // pDelete(&h);
4896        if (h == NULL) return NULL;
4897        e = pLDeg(h,&l,currRing)-pFDeg(h,currRing);
4898        j = 0;
4899        not_sev = ~ pGetShortExpVector(h);
4900      }
4901      else j++;
4902    }
4903    while (j <= maxIndex);
4904  }
4905  return h;
4906}
4907
4908/*2
4909*updates S:
4910*the result is a set of polynomials which are in
4911*normalform with respect to S
4912*/
4913void updateS(BOOLEAN toT,kStrategy strat)
4914{
4915  LObject h;
4916  int i, suc=0;
4917  poly redSi=NULL;
4918  BOOLEAN change,any_change;
4919//  Print("nach initS: updateS start mit sl=%d\n",(strat->sl));
4920//  for (i=0; i<=(strat->sl); i++)
4921//  {
4922//    Print("s%d:",i);
4923//    if (strat->fromQ!=NULL) Print("(Q:%d) ",strat->fromQ[i]);
4924//    pWrite(strat->S[i]);
4925//  }
4926//  Print("pOrdSgn=%d\n", pOrdSgn);
4927  any_change=FALSE;
4928  if (pOrdSgn==1)
4929  {
4930    while (suc != -1)
4931    {
4932      i=suc+1;
4933      while (i<=strat->sl)
4934      {
4935        change=FALSE;
4936        if (((strat->fromQ==NULL) || (strat->fromQ[i]==0)) && (i>0))
4937        {
4938          redSi = pHead(strat->S[i]);
4939          strat->S[i] = redBba(strat->S[i],i-1,strat);
4940          //if ((strat->ak!=0)&&(strat->S[i]!=NULL))
4941          //  strat->S[i]=redQ(strat->S[i],i+1,strat); /*reduce S[i] mod Q*/
4942          if (pCmp(redSi,strat->S[i])!=0)
4943          {
4944            change=TRUE;
4945            any_change=TRUE;
4946            #ifdef KDEBUG
4947            if (TEST_OPT_DEBUG)
4948            {
4949              PrintS("reduce:");
4950              wrp(redSi);PrintS(" to ");p_wrp(strat->S[i], currRing, strat->tailRing);PrintLn();
4951            }
4952            #endif
4953            if (TEST_OPT_PROT)
4954            {
4955              if (strat->S[i]==NULL)
4956                PrintS("V");
4957              else
4958                PrintS("v");
4959              mflush();
4960            }
4961          }
4962          pDeleteLm(&redSi);
4963          if (strat->S[i]==NULL)
4964          {
4965            deleteInS(i,strat);
4966            i--;
4967          }
4968          else if (change)
4969          {
4970            if (TEST_OPT_INTSTRATEGY)
4971            {
4972              //pContent(strat->S[i]);
4973              pCleardenom(strat->S[i]);// also does a pContent
4974            }
4975            else
4976            {
4977              pNorm(strat->S[i]);
4978            }
4979            strat->sevS[i] = pGetShortExpVector(strat->S[i]);
4980          }
4981        }
4982        i++;
4983      }
4984      if (any_change) reorderS(&suc,strat);
4985      else break;
4986    }
4987    if (toT)
4988    {
4989      for (i=0; i<=strat->sl; i++)
4990      {
4991        if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
4992        {
4993          h.p = redtailBba(strat->S[i],i-1,strat);
4994          if (TEST_OPT_INTSTRATEGY)
4995          {
4996            pCleardenom(h.p);// also does a pContent
4997          }
4998        }
4999        else
5000        {
5001          h.p = strat->S[i];
5002        }
5003        strat->initEcart(&h);
5004        if (strat->honey)
5005        {
5006          strat->ecartS[i] = h.ecart;
5007        }
5008        if (strat->sevS[i] == 0) {strat->sevS[i] = pGetShortExpVector(h.p);}
5009        else assume(strat->sevS[i] == pGetShortExpVector(h.p));
5010        h.sev = strat->sevS[i];
5011        /*puts the elements of S also to T*/
5012        enterT(h,strat);
5013        strat->S_2_R[i] = strat->tl;
5014      }
5015    }
5016  }
5017  else
5018  {
5019    while (suc != -1)
5020    {
5021      i=suc;
5022      while (i<=strat->sl)
5023      {
5024        change=FALSE;
5025        if (((strat->fromQ==NULL) || (strat->fromQ[i]==0)) && (i>0))
5026        {
5027          redSi=pHead((strat->S)[i]);
5028          (strat->S)[i] = redMora((strat->S)[i],i-1,strat);
5029          if ((strat->S)[i]==NULL)
5030          {
5031            deleteInS(i,strat);
5032            i--;
5033          }
5034          else if (pCmp((strat->S)[i],redSi)!=0)
5035          {
5036            any_change=TRUE;
5037            h.p = strat->S[i];
5038            strat->initEcart(&h);
5039            strat->ecartS[i] = h.ecart;
5040            if (TEST_OPT_INTSTRATEGY)
5041            {
5042              pCleardenom(strat->S[i]);// also does a pContent
5043            }
5044            else
5045            {
5046              pNorm(strat->S[i]); // == h.p
5047            }
5048            h.sev =  pGetShortExpVector(h.p);
5049            strat->sevS[i] = h.sev;
5050          }
5051          pDeleteLm(&redSi);
5052          kTest(strat);
5053        }
5054        i++;
5055      }
5056#ifdef KDEBUG
5057      kTest(strat);
5058#endif
5059      if (any_change) reorderS(&suc,strat);
5060      else { suc=-1; break; }
5061      if (h.p!=NULL)
5062      {
5063        if (!strat->kHEdgeFound)
5064        {
5065          /*strat->kHEdgeFound =*/ HEckeTest(h.p,strat);
5066        }
5067        if (strat->kHEdgeFound)
5068          newHEdge(strat->S,strat);
5069      }
5070    }
5071    for (i=0; i<=strat->sl; i++)
5072    {
5073      if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
5074      {
5075        strat->S[i] = h.p = redtail(strat->S[i],strat->sl,strat);
5076        strat->initEcart(&h);
5077        strat->ecartS[i] = h.ecart;
5078        h.sev = pGetShortExpVector(h.p);
5079        strat->sevS[i] = h.sev;
5080      }
5081      else
5082      {
5083        h.p = strat->S[i];
5084        h.ecart=strat->ecartS[i];
5085        h.sev = strat->sevS[i];
5086        h.length = h.pLength = pLength(h.p);
5087      }
5088      if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
5089        cancelunit1(&h,&suc,strat->sl,strat);
5090      h.SetpFDeg();
5091      /*puts the elements of S also to T*/
5092      enterT(h,strat);
5093      strat->S_2_R[i] = strat->tl;
5094    }
5095    if (suc!= -1) updateS(toT,strat);
5096  }
5097#ifdef KDEBUG
5098  kTest(strat);
5099#endif
5100}
5101
5102
5103/*2
5104* -puts p to the standardbasis s at position at
5105* -saves the result in S
5106*/
5107void enterSBba (LObject p,int atS,kStrategy strat, int atR)
5108{
5109  int i;
5110  strat->news = TRUE;
5111  /*- puts p to the standardbasis s at position at -*/
5112  if (strat->sl == IDELEMS(strat->Shdl)-1)
5113  {
5114    strat->sevS = (unsigned long*) omRealloc0Size(strat->sevS,
5115                                    IDELEMS(strat->Shdl)*sizeof(unsigned long),
5116                                    (IDELEMS(strat->Shdl)+setmaxTinc)
5117                                                  *sizeof(unsigned long));
5118    strat->ecartS = (intset)omReallocSize(strat->ecartS,
5119                                          IDELEMS(strat->Shdl)*sizeof(int),
5120                                          (IDELEMS(strat->Shdl)+setmaxTinc)
5121                                                  *sizeof(int));
5122    strat->S_2_R = (int*) omRealloc0Size(strat->S_2_R,
5123                                         IDELEMS(strat->Shdl)*sizeof(int),
5124                                         (IDELEMS(strat->Shdl)+setmaxTinc)
5125                                                  *sizeof(int));
5126    if (strat->lenS!=NULL)
5127      strat->lenS=(int*)omRealloc0Size(strat->lenS,
5128                                       IDELEMS(strat->Shdl)*sizeof(int),
5129                                       (IDELEMS(strat->Shdl)+setmaxTinc)
5130                                                 *sizeof(int));
5131    if (strat->lenSw!=NULL)
5132      strat->lenSw=(wlen_type*)omRealloc0Size(strat->lenSw,
5133                                       IDELEMS(strat->Shdl)*sizeof(wlen_type),
5134                                       (IDELEMS(strat->Shdl)+setmaxTinc)
5135                                                 *sizeof(wlen_type));
5136    if (strat->fromQ!=NULL)
5137    {
5138      strat->fromQ = (intset)omReallocSize(strat->fromQ,
5139                                    IDELEMS(strat->Shdl)*sizeof(int),
5140                                    (IDELEMS(strat->Shdl)+setmaxTinc)*sizeof(int));
5141    }
5142    pEnlargeSet(&strat->S,IDELEMS(strat->Shdl),setmaxTinc);
5143    IDELEMS(strat->Shdl)+=setmaxTinc;
5144    strat->Shdl->m=strat->S;
5145  }
5146  if (atS <= strat->sl)
5147  {
5148#ifdef ENTER_USE_MEMMOVE
5149// #if 0
5150    memmove(&(strat->S[atS+1]), &(strat->S[atS]),
5151            (strat->sl - atS + 1)*sizeof(poly));
5152    memmove(&(strat->ecartS[atS+1]), &(strat->ecartS[atS]),
5153            (strat->sl - atS + 1)*sizeof(int));
5154    memmove(&(strat->sevS[atS+1]), &(strat->sevS[atS]),
5155            (strat->sl - atS + 1)*sizeof(unsigned long));
5156    memmove(&(strat->S_2_R[atS+1]), &(strat->S_2_R[atS]),
5157            (strat->sl - atS + 1)*sizeof(int));
5158    if (strat->lenS!=NULL)
5159    memmove(&(strat->lenS[atS+1]), &(strat->lenS[atS]),
5160            (strat->sl - atS + 1)*sizeof(int));
5161    if (strat->lenSw!=NULL)
5162    memmove(&(strat->lenSw[atS+1]), &(strat->lenSw[atS]),
5163            (strat->sl - atS + 1)*sizeof(wlen_type));
5164#else
5165    for (i=strat->sl+1; i>=atS+1; i--)
5166    {
5167      strat->S[i] = strat->S[i-1];
5168      strat->ecartS[i] = strat->ecartS[i-1];
5169      strat->sevS[i] = strat->sevS[i-1];
5170      strat->S_2_R[i] = strat->S_2_R[i-1];
5171    }
5172    if (strat->lenS!=NULL)
5173    for (i=strat->sl+1; i>=atS+1; i--)
5174      strat->lenS[i] = strat->lenS[i-1];
5175    if (strat->lenSw!=NULL)
5176    for (i=strat->sl+1; i>=atS+1; i--)
5177      strat->lenSw[i] = strat->lenSw[i-1];
5178#endif
5179  }
5180  if (strat->fromQ!=NULL)
5181  {
5182#ifdef ENTER_USE_MEMMOVE
5183    memmove(&(strat->fromQ[atS+1]), &(strat->fromQ[atS]),
5184                  (strat->sl - atS + 1)*sizeof(int));
5185#else
5186    for (i=strat->sl+1; i>=atS+1; i--)
5187    {
5188      strat->fromQ[i] = strat->fromQ[i-1];
5189    }
5190#endif
5191    strat->fromQ[atS]=0;
5192  }
5193
5194  /*- save result -*/
5195  strat->S[atS] = p.p;
5196  if (strat->honey) strat->ecartS[atS] = p.ecart;
5197  if (p.sev == 0)
5198    p.sev = pGetShortExpVector(p.p);
5199  else
5200    assume(p.sev == pGetShortExpVector(p.p));
5201  strat->sevS[atS] = p.sev;
5202  strat->ecartS[atS] = p.ecart;
5203  strat->S_2_R[atS] = atR;
5204  strat->sl++;
5205}
5206
5207/*2
5208* puts p to the set T at position atT
5209*/
5210void enterT(LObject p, kStrategy strat, int atT)
5211{
5212  int i;
5213
5214  pp_Test(p.p, currRing, p.tailRing);
5215  assume(strat->tailRing == p.tailRing);
5216  // redMoraNF complains about this -- but, we don't really
5217  // neeed this so far
5218  assume(p.pLength == 0 || pLength(p.p) == p.pLength);
5219  assume(p.FDeg == p.pFDeg());
5220  assume(!p.is_normalized || nIsOne(pGetCoeff(p.p)));
5221
5222#ifdef KDEBUG 
5223  // do not put an LObject twice into T:
5224  for(i=strat->tl;i>=0;i--)
5225  {
5226    if (p.p==strat->T[i].p) 
5227    {
5228      printf("already in T at pos %d of %d, atT=%d\n",i,strat->tl,atT);
5229      return;
5230    }
5231  }
5232#endif 
5233  strat->newt = TRUE;
5234  if (atT < 0)
5235    atT = strat->posInT(strat->T, strat->tl, p);
5236  if (strat->tl == strat->tmax-1)
5237    enlargeT(strat->T,strat->R,strat->sevT,strat->tmax,setmaxTinc);
5238  if (atT <= strat->tl)
5239  {
5240#ifdef ENTER_USE_MEMMOVE
5241    memmove(&(strat->T[atT+1]), &(strat->T[atT]),
5242            (strat->tl-atT+1)*sizeof(TObject));
5243    memmove(&(strat->sevT[atT+1]), &(strat->sevT[atT]),
5244            (strat->tl-atT+1)*sizeof(unsigned long));
5245#endif
5246    for (i=strat->tl+1; i>=atT+1; i--)
5247    {
5248#ifndef ENTER_USE_MEMMOVE
5249      strat->T[i] = strat->T[i-1];
5250      strat->sevT[i] = strat->sevT[i-1];
5251#endif
5252      strat->R[strat->T[i].i_r] = &(strat->T[i]);
5253    }
5254  }
5255
5256  if (strat->tailBin != NULL && (pNext(p.p) != NULL))
5257  {
5258    pNext(p.p)=p_ShallowCopyDelete(pNext(p.p),
5259                                   (strat->tailRing != NULL ?
5260                                    strat->tailRing : currRing),
5261                                   strat->tailBin);
5262    if (p.t_p != NULL) pNext(p.t_p) = pNext(p.p);
5263  }
5264  strat->T[atT] = (TObject) p;
5265
5266  if (strat->tailRing != currRing && pNext(p.p) != NULL)
5267    strat->T[atT].max = p_GetMaxExpP(pNext(p.p), strat->tailRing);
5268  else
5269    strat->T[atT].max = NULL;
5270
5271  strat->tl++;
5272  strat->R[strat->tl] = &(strat->T[atT]);
5273  strat->T[atT].i_r = strat->tl;
5274  assume(p.sev == 0 || pGetShortExpVector(p.p) == p.sev);
5275  strat->sevT[atT] = (p.sev == 0 ? pGetShortExpVector(p.p) : p.sev);
5276  kTest_T(&(strat->T[atT]));
5277}
5278
5279void initHilbCrit(ideal F, ideal Q, intvec **hilb,kStrategy strat)
5280{
5281  if (strat->homog!=isHomog)
5282  {
5283    *hilb=NULL;
5284  }
5285}
5286
5287void initBuchMoraCrit(kStrategy strat)
5288{
5289  strat->sugarCrit =        TEST_OPT_SUGARCRIT;
5290  // obachman: Hmm.. I need BTEST1(2) for notBuckets ..
5291  //  strat->Gebauer =          BTEST1(2) || strat->homog || strat->sugarCrit;
5292  strat->Gebauer =          strat->homog || strat->sugarCrit;
5293  strat->honey =            !strat->homog || strat->sugarCrit || TEST_OPT_WEIGHTM;
5294  if (TEST_OPT_NOT_SUGAR) strat->honey = FALSE;
5295  strat->pairtest = NULL;
5296  /* alway use tailreduction, except:
5297  * - in local rings, - in lex order case, -in ring over extensions */
5298  strat->noTailReduction = !TEST_OPT_REDTAIL;
5299
5300#ifdef HAVE_PLURAL
5301  // and r is plural_ring
5302  if( rIsPluralRing(currRing) || (rIsSCA(currRing) && !strat->z2homog) )
5303  {    //or it has non-quasi-comm type... later
5304    strat->sugarCrit = FALSE;
5305    strat->Gebauer = FALSE;
5306    strat->honey = FALSE;
5307  }
5308#endif
5309
5310#ifdef HAVE_RINGS
5311  // Coefficient ring?
5312  if (rField_is_Ring(currRing))
5313  {
5314    strat->sugarCrit = FALSE;
5315    strat->Gebauer = FALSE ;
5316    strat->honey = FALSE;
5317  }
5318#endif
5319  #ifdef KDEBUG
5320  if (TEST_OPT_DEBUG)
5321  {
5322    if (strat->homog) PrintS("ideal/module is homogeneous\n");
5323    else              PrintS("ideal/module is not homogeneous\n");
5324  }
5325  #endif
5326}
5327
5328BOOLEAN kPosInLDependsOnLength(int (*pos_in_l)
5329                               (const LSet set, const int length,
5330                                LObject* L,const kStrategy strat))
5331{
5332  if (pos_in_l == posInL110 ||
5333      pos_in_l == posInL10)
5334    return TRUE;
5335
5336  return FALSE;
5337}
5338
5339void initBuchMoraPos (kStrategy strat)
5340{
5341  if (pOrdSgn==1)
5342  {
5343    if (strat->honey)
5344    {
5345      strat->posInL = posInL15;
5346      // ok -- here is the deal: from my experiments for Singular-2-0
5347      // I conclude that that posInT_EcartpLength is the best of
5348      // posInT15, posInT_EcartFDegpLength, posInT_FDegLength, posInT_pLength
5349      // see the table at the end of this file
5350      if (K_TEST_OPT_OLDSTD)
5351        strat->posInT = posInT15;
5352      else
5353        strat->posInT = posInT_EcartpLength;
5354    }
5355    else if (pLexOrder && !TEST_OPT_INTSTRATEGY)
5356    {
5357      strat->posInL = posInL11;
5358      strat->posInT = posInT11;
5359    }
5360    else if (TEST_OPT_INTSTRATEGY)
5361    {
5362      strat->posInL = posInL11;
5363      strat->posInT = posInT11;
5364    }
5365    else
5366    {
5367      strat->posInL = posInL0;
5368      strat->posInT = posInT0;
5369    }
5370    //if (strat->minim>0) strat->posInL =posInLSpecial;
5371    if (strat->homog)
5372    {
5373       strat->posInL = posInL110;
5374       strat->posInT = posInT110;
5375    }
5376  }
5377  else
5378  {
5379    if (strat->homog)
5380    {
5381      strat->posInL = posInL11;
5382      strat->posInT = posInT11;
5383    }
5384    else
5385    {
5386      if ((currRing->order[0]==ringorder_c)
5387      ||(currRing->order[0]==ringorder_C))
5388      {
5389        strat->posInL = posInL17_c;
5390        strat->posInT = posInT17_c;
5391      }
5392      else
5393      {
5394        strat->posInL = posInL17;
5395        strat->posInT = posInT17;
5396      }
5397    }
5398  }
5399  if (strat->minim>0) strat->posInL =posInLSpecial;
5400  // for further tests only
5401  if ((BTEST1(11)) || (BTEST1(12)))
5402    strat->posInL = posInL11;
5403  else if ((BTEST1(13)) || (BTEST1(14)))
5404    strat->posInL = posInL13;
5405  else if ((BTEST1(15)) || (BTEST1(16)))
5406    strat->posInL = posInL15;
5407  else if ((BTEST1(17)) || (BTEST1(18)))
5408    strat->posInL = posInL17;
5409  if (BTEST1(11))
5410    strat->posInT = posInT11;
5411  else if (BTEST1(13))
5412    strat->posInT = posInT13;
5413  else if (BTEST1(15))
5414    strat->posInT = posInT15;
5415  else if ((BTEST1(17)))
5416    strat->posInT = posInT17;
5417  else if ((BTEST1(19)))
5418    strat->posInT = posInT19;
5419  else if (BTEST1(12) || BTEST1(14) || BTEST1(16) || BTEST1(18))
5420    strat->posInT = posInT1;
5421#ifdef HAVE_RINGS
5422  if (rField_is_Ring(currRing))
5423  {
5424    strat->posInL = posInL11;
5425    strat->posInT = posInT11;
5426  }
5427#endif
5428  strat->posInLDependsOnLength = kPosInLDependsOnLength(strat->posInL);
5429}
5430
5431void initBuchMora (ideal F,ideal Q,kStrategy strat)
5432{
5433  strat->interpt = BTEST1(OPT_INTERRUPT);
5434  strat->kHEdge=NULL;
5435  if (pOrdSgn==1) strat->kHEdgeFound=FALSE;
5436  /*- creating temp data structures------------------- -*/
5437  strat->cp = 0;
5438  strat->c3 = 0;
5439  strat->tail = pInit();
5440  /*- set s -*/
5441  strat->sl = -1;
5442  /*- set L -*/
5443  strat->Lmax = setmaxL;
5444  strat->Ll = -1;
5445  strat->L = initL();
5446  /*- set B -*/
5447  strat->Bmax = setmaxL;
5448  strat->Bl = -1;
5449  strat->B = initL();
5450  /*- set T -*/
5451  strat->tl = -1;
5452  strat->tmax = setmaxT;
5453  strat->T = initT();
5454  strat->R = initR();
5455  strat->sevT = initsevT();
5456  /*- init local data struct.---------------------------------------- -*/
5457  strat->P.ecart=0;
5458  strat->P.length=0;
5459  if (pOrdSgn==-1)
5460  {
5461    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
5462    if (strat->kNoether!=NULL) pSetComp(strat->kNoetherTail(), strat->ak);
5463  }
5464  if(TEST_OPT_SB_1)
5465  {
5466    int i;
5467    ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
5468    for (i=strat->newIdeal;i<IDELEMS(F);i++)
5469    {
5470      P->m[i-strat->newIdeal] = F->m[i];
5471      F->m[i] = NULL;
5472    }
5473    initSSpecial(F,Q,P,strat);
5474    for (i=strat->newIdeal;i<IDELEMS(F);i++)
5475    {
5476      F->m[i] = P->m[i-strat->newIdeal];
5477      P->m[i-strat->newIdeal] = NULL;
5478    }
5479    idDelete(&P);
5480  }
5481  else
5482  {
5483    /*Shdl=*/initSL(F, Q,strat); /*sets also S, ecartS, fromQ */
5484    // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
5485  }
5486  strat->kIdeal = NULL;
5487  strat->fromT = FALSE;
5488  strat->noTailReduction = !TEST_OPT_REDTAIL;
5489  if (!TEST_OPT_SB_1)
5490  {
5491    updateS(TRUE,strat);
5492  }
5493  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
5494  strat->fromQ=NULL;
5495}
5496
5497void exitBuchMora (kStrategy strat)
5498{
5499  /*- release temp data -*/
5500  cleanT(strat);
5501  omFreeSize(strat->T,(strat->tmax)*sizeof(TObject));
5502  omFreeSize(strat->R,(strat->tmax)*sizeof(TObject*));
5503  omFreeSize(strat->sevT, (strat->tmax)*sizeof(unsigned long));
5504  omFreeSize(strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
5505  omFreeSize(strat->sevS,IDELEMS(strat->Shdl)*sizeof(int));
5506  omFreeSize(strat->S_2_R,IDELEMS(strat->Shdl)*sizeof(int));
5507  /*- set L: should be empty -*/
5508  omFreeSize(strat->L,(strat->Lmax)*sizeof(LObject));
5509  /*- set B: should be empty -*/
5510  omFreeSize(strat->B,(strat->Bmax)*sizeof(LObject));
5511  pDeleteLm(&strat->tail);
5512  strat->syzComp=0;
5513  if (strat->kIdeal!=NULL)
5514  {
5515    omFreeBin(strat->kIdeal, sleftv_bin);
5516    strat->kIdeal=NULL;
5517  }
5518}
5519
5520/*2
5521* in the case of a standardbase of a module over a qring:
5522* replace polynomials in i by ak vectors,
5523* (the polynomial * unit vectors gen(1)..gen(ak)
5524* in every case (also for ideals:)
5525* deletes divisible vectors/polynomials
5526*/
5527void updateResult(ideal r,ideal Q, kStrategy strat)
5528{
5529  int l;
5530  if (strat->ak>0)
5531  {
5532    for (l=IDELEMS(r)-1;l>=0;l--)
5533    {
5534      if ((r->m[l]!=NULL) && (pGetComp(r->m[l])==0))
5535      {
5536        pDelete(&r->m[l]); // and set it to NULL
5537      }
5538    }
5539    int q;
5540    poly p;
5541    for (l=IDELEMS(r)-1;l>=0;l--)
5542    {
5543      if ((r->m[l]!=NULL)
5544      && (strat->syzComp>0)
5545      && (pGetComp(r->m[l])<=strat->syzComp))
5546      {
5547        for(q=IDELEMS(Q)-1; q>=0;q--)
5548        {
5549          if ((Q->m[q]!=NULL)
5550          &&(pLmDivisibleBy(Q->m[q],r->m[l])))
5551          {
5552            if (TEST_OPT_REDSB)
5553            {
5554              p=r->m[l];
5555              r->m[l]=kNF(Q,NULL,p);
5556              pDelete(&p);
5557            }
5558            else
5559            {
5560              pDelete(&r->m[l]); // and set it to NULL
5561            }
5562            break;
5563          }
5564        }
5565      }
5566    }
5567  }
5568  else
5569  {
5570    int q;
5571    poly p;
5572    for (l=IDELEMS(r)-1;l>=0;l--)
5573    {
5574      if (r->m[l]!=NULL)
5575      {
5576        for(q=IDELEMS(Q)-1; q>=0;q--)
5577        {
5578          if ((Q->m[q]!=NULL)
5579          &&(pLmEqual(r->m[l],Q->m[q])))
5580          {
5581            if (TEST_OPT_REDSB)
5582            {
5583              p=r->m[l];
5584              r->m[l]=kNF(Q,NULL,p);
5585              pDelete(&p);
5586            }
5587            else
5588            {
5589              pDelete(&r->m[l]); // and set it to NULL
5590            }
5591            break;
5592          }
5593        }
5594      }
5595    }
5596  }
5597  idSkipZeroes(r);
5598}
5599
5600void completeReduce (kStrategy strat, BOOLEAN withT)
5601{
5602  int i;
5603  int low = (pOrdSgn == 1 ? 1 : 0);
5604  LObject L;
5605
5606#ifdef KDEBUG
5607  // need to set this: during tailreductions of T[i], T[i].max is out of
5608  // sync
5609  sloppy_max = TRUE;
5610#endif
5611
5612  strat->noTailReduction = FALSE;
5613  if (TEST_OPT_PROT)
5614  {
5615    PrintLn();
5616    if (timerv) writeTime("standard base computed:");
5617  }
5618  if (TEST_OPT_PROT)
5619  {
5620    Print("(S:%d)",strat->sl);mflush();
5621  }
5622  for (i=strat->sl; i>=low; i--)
5623  {
5624    TObject* T_j = strat->s_2_t(i);
5625    if (T_j != NULL)
5626    {
5627      L = *T_j;
5628      poly p;
5629      if (pOrdSgn == 1)
5630        strat->S[i] = redtailBba(&L, i-1, strat, withT);
5631      else
5632        strat->S[i] = redtail(&L, strat->sl, strat);
5633
5634      if (strat->redTailChange && strat->tailRing != currRing)
5635      {
5636        if (T_j->max != NULL) p_LmFree(T_j->max, strat->tailRing);
5637        if (pNext(T_j->p) != NULL)
5638          T_j->max = p_GetMaxExpP(pNext(T_j->p), strat->tailRing);
5639        else
5640          T_j->max = NULL;
5641      }
5642      if (TEST_OPT_INTSTRATEGY)
5643        T_j->pCleardenom();
5644    }
5645    else
5646    {
5647      assume(currRing == strat->tailRing);
5648      if (pOrdSgn == 1)
5649        strat->S[i] = redtailBba(strat->S[i], i-1, strat, withT);
5650      else
5651        strat->S[i] = redtail(strat->S[i], strat->sl, strat);
5652      if (TEST_OPT_INTSTRATEGY)
5653        pCleardenom(strat->S[i]);
5654    }
5655    if (TEST_OPT_PROT)
5656      PrintS("-");
5657  }
5658  if (TEST_OPT_PROT) PrintLn();
5659#ifdef KDEBUG
5660  sloppy_max = FALSE;
5661#endif
5662}
5663
5664
5665/*2
5666* computes the new strat->kHEdge and the new pNoether,
5667* returns TRUE, if pNoether has changed
5668*/
5669BOOLEAN newHEdge(polyset S, kStrategy strat)
5670{
5671  int i,j;
5672  poly newNoether;
5673
5674#if 0
5675  if (currRing->weight_all_1)
5676    scComputeHC(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
5677  else
5678    scComputeHCw(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
5679#else   
5680  scComputeHC(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
5681#endif 
5682  if (strat->t_kHEdge != NULL) p_LmFree(strat->t_kHEdge, strat->tailRing);
5683  if (strat->tailRing != currRing)
5684    strat->t_kHEdge = k_LmInit_currRing_2_tailRing(strat->kHEdge, strat->tailRing);
5685  /* compare old and new noether*/
5686  newNoether = pLmInit(strat->kHEdge);
5687  j = pFDeg(newNoether,currRing);
5688  for (i=1; i<=pVariables; i++)
5689  {
5690    if (pGetExp(newNoether, i) > 0) pDecrExp(newNoether,i);
5691  }
5692  pSetm(newNoether);
5693  if (j < strat->HCord) /*- statistics -*/
5694  {
5695    if (TEST_OPT_PROT)
5696    {
5697      Print("H(%d)",j);
5698      mflush();
5699    }
5700    strat->HCord=j;
5701    #ifdef KDEBUG
5702    if (TEST_OPT_DEBUG)
5703    {
5704      Print("H(%d):",j);
5705      wrp(strat->kHEdge);
5706      PrintLn();
5707    }
5708    #endif
5709  }
5710  if (pCmp(strat->kNoether,newNoether)!=1)
5711  {
5712    pDelete(&strat->kNoether);
5713    strat->kNoether=newNoether;
5714    if (strat->t_kNoether != NULL) p_LmFree(strat->t_kNoether, strat->tailRing);
5715    if (strat->tailRing != currRing)
5716      strat->t_kNoether = k_LmInit_currRing_2_tailRing(strat->kNoether, strat->tailRing);
5717
5718    return TRUE;
5719  }
5720  pLmFree(newNoether);
5721  return FALSE;
5722}
5723
5724/***************************************************************
5725 *
5726 * Routines related for ring changes during std computations
5727 *
5728 ***************************************************************/
5729BOOLEAN kCheckSpolyCreation(LObject *L, kStrategy strat, poly &m1, poly &m2)
5730{
5731  assume(L->p1 != NULL && L->p2 != NULL);
5732  // shift changes: from 0 to -1
5733  assume(L->i_r1 >= -1 && L->i_r1 <= strat->tl);
5734  assume(L->i_r2 >= -1 && L->i_r2 <= strat->tl);
5735  assume(strat->tailRing != currRing);
5736
5737  if (! k_GetLeadTerms(L->p1, L->p2, currRing, m1, m2, strat->tailRing))
5738    return FALSE;
5739  // shift changes: extra case inserted
5740  if ((L->i_r1 == -1) || (L->i_r2 == -1) )
5741  {
5742    return TRUE;
5743  }
5744  poly p1_max = (strat->R[L->i_r1])->max;
5745  poly p2_max = (strat->R[L->i_r2])->max;
5746
5747  if ((p1_max != NULL && !p_LmExpVectorAddIsOk(m1, p1_max, strat->tailRing)) ||
5748      (p2_max != NULL && !p_LmExpVectorAddIsOk(m2, p2_max, strat->tailRing)))
5749  {
5750    p_LmFree(m1, strat->tailRing);
5751    p_LmFree(m2, strat->tailRing);
5752    m1 = NULL;
5753    m2 = NULL;
5754    return FALSE;
5755  }
5756  return TRUE;
5757}
5758
5759#ifdef HAVE_RINGS
5760/***************************************************************
5761 *
5762 * Checks, if we can compute the gcd poly / strong pair
5763 * gcd-poly = m1 * R[atR] + m2 * S[atS]
5764 *
5765 ***************************************************************/
5766BOOLEAN kCheckStrongCreation(int atR, poly m1, int atS, poly m2, kStrategy strat)
5767{
5768  assume(strat->S_2_R[atS] >= -1 && strat->S_2_R[atS] <= strat->tl);
5769  assume(strat->tailRing != currRing);
5770
5771  poly p1_max = (strat->R[atR])->max;
5772  poly p2_max = (strat->R[strat->S_2_R[atS]])->max;
5773
5774  if ((p1_max != NULL && !p_LmExpVectorAddIsOk(m1, p1_max, strat->tailRing)) ||
5775      (p2_max != NULL && !p_LmExpVectorAddIsOk(m2, p2_max, strat->tailRing)))
5776  {
5777    return FALSE;
5778  }
5779  return TRUE;
5780}
5781#endif
5782
5783BOOLEAN kStratChangeTailRing(kStrategy strat, LObject *L, TObject* T, unsigned long expbound)
5784{
5785  if (expbound == 0) expbound = strat->tailRing->bitmask << 1;
5786  if (expbound >= currRing->bitmask) return FALSE;
5787  ring new_tailRing = rModifyRing(currRing,
5788                                  // Hmmm .. the condition pFDeg == pDeg
5789                                  // might be too strong
5790#ifdef HAVE_RINGS
5791                                  (strat->homog && pFDeg == pDeg && !(rField_is_Ring(currRing))), // TODO Oliver
5792#else
5793                                  (strat->homog && pFDeg == pDeg),
5794#endif
5795                                  !strat->ak,
5796                                  expbound);
5797  if (new_tailRing == currRing) return TRUE;
5798
5799  strat->pOrigFDeg_TailRing = new_tailRing->pFDeg;
5800  strat->pOrigLDeg_TailRing = new_tailRing->pLDeg;
5801
5802  if (currRing->pFDeg != currRing->pFDegOrig)
5803  {
5804    new_tailRing->pFDeg = currRing->pFDeg;
5805    new_tailRing->pLDeg = currRing->pLDeg;
5806  }
5807
5808  if (TEST_OPT_PROT)
5809    Print("[%lu:%d", (unsigned long) new_tailRing->bitmask, new_tailRing->ExpL_Size);
5810  kTest_TS(strat);
5811  assume(new_tailRing != strat->tailRing);
5812  pShallowCopyDeleteProc p_shallow_copy_delete
5813    = pGetShallowCopyDeleteProc(strat->tailRing, new_tailRing);
5814
5815  omBin new_tailBin = omGetStickyBinOfBin(new_tailRing->PolyBin);
5816
5817  int i;
5818  for (i=0; i<=strat->tl; i++)
5819  {
5820    strat->T[i].ShallowCopyDelete(new_tailRing, new_tailBin,
5821                                  p_shallow_copy_delete);
5822  }
5823  for (i=0; i<=strat->Ll; i++)
5824  {
5825    assume(strat->L[i].p != NULL);
5826    if (pNext(strat->L[i].p) != strat->tail)
5827      strat->L[i].ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
5828  }
5829  if (strat->P.t_p != NULL ||
5830      (strat->P.p != NULL && pNext(strat->P.p) != strat->tail))
5831    strat->P.ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
5832
5833  if (L != NULL && L->tailRing != new_tailRing)
5834  {
5835    if (L->i_r < 0)
5836      L->ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
5837    else
5838    {
5839      assume(L->i_r <= strat->tl);
5840      TObject* t_l = strat->R[L->i_r];
5841      assume(t_l != NULL);
5842      L->tailRing = new_tailRing;
5843      L->p = t_l->p;
5844      L->t_p = t_l->t_p;
5845      L->max = t_l->max;
5846    }
5847  }
5848
5849  if (T != NULL && T->tailRing != new_tailRing && T->i_r < 0)
5850    T->ShallowCopyDelete(new_tailRing, new_tailBin, p_shallow_copy_delete);
5851
5852  omMergeStickyBinIntoBin(strat->tailBin, strat->tailRing->PolyBin);
5853  if (strat->tailRing != currRing)
5854    rKillModifiedRing(strat->tailRing);
5855
5856  strat->tailRing = new_tailRing;
5857  strat->tailBin = new_tailBin;
5858  strat->p_shallow_copy_delete
5859    = pGetShallowCopyDeleteProc(currRing, new_tailRing);
5860
5861  if (strat->kHEdge != NULL)
5862  {
5863    if (strat->t_kHEdge != NULL)
5864      p_LmFree(strat->t_kHEdge, strat->tailRing);
5865    strat->t_kHEdge=k_LmInit_currRing_2_tailRing(strat->kHEdge, new_tailRing);
5866  }
5867
5868  if (strat->kNoether != NULL)
5869  {
5870    if (strat->t_kNoether != NULL)
5871      p_LmFree(strat->t_kNoether, strat->tailRing);
5872    strat->t_kNoether=k_LmInit_currRing_2_tailRing(strat->kNoether,
5873                                                   new_tailRing);
5874  }
5875  kTest_TS(strat);
5876  if (TEST_OPT_PROT)
5877    PrintS("]");
5878  return TRUE;
5879}
5880
5881void kStratInitChangeTailRing(kStrategy strat)
5882{
5883  unsigned long l = 0;
5884  int i;
5885  Exponent_t e;
5886  ring new_tailRing;
5887
5888  assume(strat->tailRing == currRing);
5889
5890  for (i=0; i<= strat->Ll; i++)
5891  {
5892    l = p_GetMaxExpL(strat->L[i].p, currRing, l);
5893  }
5894  for (i=0; i<=strat->tl; i++)
5895  {
5896    // Hmm ... this we could do in one Step
5897    l = p_GetMaxExpL(strat->T[i].p, currRing, l);
5898  }
5899  if (rField_is_Ring(currRing))
5900  {
5901    l *= 2;
5902  }
5903  e = p_GetMaxExp(l, currRing);
5904  if (e <= 1) e = 2;
5905
5906  kStratChangeTailRing(strat, NULL, NULL, e);
5907}
5908
5909skStrategy::skStrategy()
5910{
5911  memset(this, 0, sizeof(skStrategy));
5912#ifndef NDEBUG
5913  strat_nr++;
5914  nr=strat_nr;
5915  if (strat_fac_debug) Print("s(%d) created\n",nr);
5916#endif
5917  tailRing = currRing;
5918  P.tailRing = currRing;
5919  tl = -1;
5920  sl = -1;
5921#ifdef HAVE_LM_BIN
5922  lmBin = omGetStickyBinOfBin(currRing->PolyBin);
5923#endif
5924#ifdef HAVE_TAIL_BIN
5925  tailBin = omGetStickyBinOfBin(currRing->PolyBin);
5926#endif
5927  pOrigFDeg = pFDeg;
5928  pOrigLDeg = pLDeg;
5929}
5930
5931
5932skStrategy::~skStrategy()
5933{
5934  if (lmBin != NULL)
5935    omMergeStickyBinIntoBin(lmBin, currRing->PolyBin);
5936  if (tailBin != NULL)
5937    omMergeStickyBinIntoBin(tailBin,
5938                            (tailRing != NULL ? tailRing->PolyBin:
5939                             currRing->PolyBin));
5940  if (t_kHEdge != NULL)
5941    p_LmFree(t_kHEdge, tailRing);
5942  if (t_kNoether != NULL)
5943    p_LmFree(t_kNoether, tailRing);
5944
5945  if (currRing != tailRing)
5946    rKillModifiedRing(tailRing);
5947  pRestoreDegProcs(pOrigFDeg, pOrigLDeg);
5948}
5949
5950#if 0
5951Timings for the different possibilities of posInT:
5952            T15           EDL         DL          EL            L         1-2-3
5953Gonnet      43.26       42.30       38.34       41.98       38.40      100.04
5954Hairer_2_1   1.11        1.15        1.04        1.22        1.08        4.7
5955Twomat3      1.62        1.69        1.70        1.65        1.54       11.32
5956ahml         4.48        4.03        4.03        4.38        4.96       26.50
5957c7          15.02       13.98       15.16       13.24       17.31       47.89
5958c8         505.09      407.46      852.76      413.21      499.19        n/a
5959f855        12.65        9.27       14.97        8.78       14.23       33.12
5960gametwo6    11.47       11.35       14.57       11.20       12.02       35.07
5961gerhard_3    2.73        2.83        2.93        2.64        3.12        6.24
5962ilias13     22.89       22.46       24.62       20.60       23.34       53.86
5963noon8       40.68       37.02       37.99       36.82       35.59      877.16
5964rcyclic_19  48.22       42.29       43.99       45.35       51.51      204.29
5965rkat9       82.37       79.46       77.20       77.63       82.54      267.92
5966schwarz_11  16.46       16.81       16.76       16.81       16.72       35.56
5967test016     16.39       14.17       14.40       13.50       14.26       34.07
5968test017     34.70       36.01       33.16       35.48       32.75       71.45
5969test042     10.76       10.99       10.27       11.57       10.45       23.04
5970test058      6.78        6.75        6.51        6.95        6.22        9.47
5971test066     10.71       10.94       10.76       10.61       10.56       19.06
5972test073     10.75       11.11       10.17       10.79        8.63       58.10
5973test086     12.23       11.81       12.88       12.24       13.37       66.68
5974test103      5.05        4.80        5.47        4.64        4.89       11.90
5975test154     12.96       11.64       13.51       12.46       14.61       36.35
5976test162     65.27       64.01       67.35       59.79       67.54      196.46
5977test164      7.50        6.50        7.68        6.70        7.96       17.13
5978virasoro     3.39        3.50        3.35        3.47        3.70        7.66
5979#endif
5980
5981
5982#ifdef HAVE_MORE_POS_IN_T
5983// determines the position based on: 1.) Ecart 2.) FDeg 3.) pLength
5984int posInT_EcartFDegpLength(const TSet set,const int length,LObject &p)
5985{
5986
5987  if (length==-1) return 0;
5988
5989  int o = p.ecart;
5990  int op=p.GetpFDeg();
5991  int ol = p.GetpLength();
5992
5993  if (set[length].ecart < o)
5994    return length+1;
5995  if (set[length].ecart == o)
5996  {
5997     int oo=set[length].GetpFDeg();
5998     if ((oo < op) || ((oo==op) && (set[length].length < ol)))
5999       return length+1;
6000  }
6001
6002  int i;
6003  int an = 0;
6004  int en= length;
6005  loop
6006  {
6007    if (an >= en-1)
6008    {
6009      if (set[an].ecart > o)
6010        return an;
6011      if (set[an].ecart == o)
6012      {
6013         int oo=set[an].GetpFDeg();
6014         if((oo > op)
6015         || ((oo==op) && (set[an].pLength > ol)))
6016           return an;
6017      }
6018      return en;
6019    }
6020    i=(an+en) / 2;
6021    if (set[i].ecart > o)
6022      en=i;
6023    else if (set[i].ecart == o)
6024    {
6025       int oo=set[i].GetpFDeg();
6026       if ((oo > op)
6027       || ((oo == op) && (set[i].pLength > ol)))
6028         en=i;
6029       else
6030        an=i;
6031    }
6032    else
6033      an=i;
6034  }
6035}
6036
6037// determines the position based on: 1.) FDeg 2.) pLength
6038int posInT_FDegpLength(const TSet set,const int length,LObject &p)
6039{
6040
6041  if (length==-1) return 0;
6042
6043  int op=p.GetpFDeg();
6044  int ol = p.GetpLength();
6045
6046  int oo=set[length].GetpFDeg();
6047  if ((oo < op) || ((oo==op) && (set[length].length < ol)))
6048    return length+1;
6049
6050  int i;
6051  int an = 0;
6052  int en= length;
6053  loop
6054    {
6055      if (an >= en-1)
6056      {
6057        int oo=set[an].GetpFDeg();
6058        if((oo > op)
6059           || ((oo==op) && (set[an].pLength > ol)))
6060          return an;
6061        return en;
6062      }
6063      i=(an+en) / 2;
6064      int oo=set[i].GetpFDeg();
6065      if ((oo > op)
6066          || ((oo == op) && (set[i].pLength > ol)))
6067        en=i;
6068      else
6069        an=i;
6070    }
6071}
6072
6073
6074// determines the position based on: 1.) Ecart 2.) FDeg 3.) pLength
6075int posInT_pLength(const TSet set,const int length,LObject &p)
6076{
6077  if (length==-1)
6078    return 0;
6079  if (set[length].length<p.length)
6080    return length+1;
6081
6082  int i;
6083  int an = 0;
6084  int en= length;
6085  int ol = p.GetpLength();
6086
6087  loop
6088  {
6089    if (an >= en-1)
6090    {
6091      if (set[an].pLength>ol) return an;
6092      return en;
6093    }
6094    i=(an+en) / 2;
6095    if (set[i].pLength>ol) en=i;
6096    else                        an=i;
6097  }
6098}
6099#endif
6100
6101#ifdef HAVE_SHIFTBBA
6102poly pMove2CurrTail(poly p, kStrategy strat)
6103{
6104  /* assume: p is completely in currRing */
6105  /* produces an object with LM in curring
6106     and TAIL in tailring */
6107  if (pNext(p)!=NULL)
6108  {
6109    pNext(p) = prMoveR(pNext(p), /* src */ currRing, /* dest */ strat->tailRing);
6110  }
6111  return(p);
6112}
6113#endif
6114
6115#ifdef HAVE_SHIFTBBA
6116poly pMoveCurrTail2poly(poly p, kStrategy strat)
6117{
6118  /* assume: p has  LM in curring and TAIL in tailring */
6119  /* convert it to complete currRing */
6120
6121  /* check that LM is in currRing */
6122  assume(p_LmCheckIsFromRing(p, currRing));
6123
6124  if (pNext(p)!=NULL)
6125  {
6126    pNext(p) = prMoveR(pNext(p), /* src */ strat->tailRing, /* dest */currRing);
6127  }
6128  return(p);
6129}
6130#endif
6131
6132#ifdef HAVE_SHIFTBBA
6133poly pCopyL2p(LObject H, kStrategy strat)
6134{
6135    /* restores a poly in currRing from LObject */
6136    LObject h = H;
6137    h.Copy();
6138    poly p;
6139    if (h.p == NULL)
6140    {
6141      if (h.t_p != NULL)
6142      {
6143         p = prMoveR(h.t_p, /* source ring: */ strat->tailRing, /* dest. ring: */ currRing);
6144        return(p);
6145      }
6146      else
6147      {
6148        /* h.tp == NULL -> the object is NULL */
6149        return(NULL);
6150      }
6151    }
6152    /* we're here if h.p != NULL */
6153    if (h.t_p == NULL)
6154    {
6155       /* then h.p is the whole poly in currRing */
6156       p = h.p;
6157      return(p);
6158    }
6159    /* we're here if h.p != NULL and h.t_p != NULL */
6160    // clean h.p, get poly from t_p
6161     pNext(h.p)=NULL;
6162     pDelete(&h.p);
6163     p = prMoveR(h.t_p, /* source ring: */ strat->tailRing,
6164                         /* dest. ring: */ currRing);
6165     // no need to clean h: we re-used the polys
6166    return(p);
6167}
6168#endif
6169
6170//LObject pCopyp2L(poly p, kStrategy strat)
6171//{
6172    /* creates LObject from the poly in currRing */
6173  /* actually put p into L.p and make L.t_p=NULL : does not work */
6174 
6175//}
6176
6177// poly pCopyL2p(LObject H, kStrategy strat)
6178// {
6179//   /* restores a poly in currRing from LObject */
6180//   LObject h = H;
6181//   h.Copy();
6182//   poly p;
6183//   if (h.p == NULL)
6184//   {
6185//     if (h.t_p != NULL)
6186//     {
6187//       p = p_ShallowCopyDelete(h.t_p, (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
6188//       return(p);
6189//     }
6190//     else
6191//     {
6192//       /* h.tp == NULL -> the object is NULL */
6193//       return(NULL);
6194//     }
6195//   }
6196//   /* we're here if h.p != NULL */
6197
6198//   if (h.t_p == NULL)
6199//   {
6200//     /* then h.p is the whole poly in tailRing */
6201//     if (strat->tailBin != NULL && (pNext(h.p) != NULL))
6202//     {
6203//       p = p_ShallowCopyDelete(h.p, (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
6204//     }
6205//     return(p);
6206//   }
6207//   /* we're here if h.p != NULL and h.t_p != NULL */
6208//   p = pCopy(pHead(h.p)); // in currRing
6209//   if (strat->tailBin != NULL && (pNext(h.p) != NULL))
6210//   {
6211//     //    pNext(p) = p_ShallowCopyDelete(pNext(h.t_p), (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
6212//     poly pp = p_Copy(pNext(h.p), strat->tailRing);
6213//     //    poly p3 = p_Copy(pNext(h.p), currRing); // error
6214//       // p_ShallowCopyDelete(pNext(h.p), currRing, strat->tailBin); // the same as pp
6215//     poly p5 = p_ShallowCopyDelete(pNext(h.p), strat->tailRing, strat->tailBin);
6216//     pNext(p) = p_ShallowCopyDelete(h.t_p, strat->tailRing, strat->tailBin);
6217//     poly p4 = p_Copy(h.t_p, strat->tailRing);
6218//     //    if (p.t_p != NULL) pNext(p.t_p) = pNext(p.p);
6219//   }
6220//   //  pTest(p);
6221//   return(p);
6222// }
6223
6224#ifdef HAVE_SHIFTBBA
6225/* including the self pairs */
6226void updateSShift(kStrategy strat,int uptodeg,int lV)
6227{
6228  /* to use after updateS(toT=FALSE,strat) */
6229  /* fills T with shifted elt's of S */
6230  int i;
6231  LObject h;
6232  int atT = -1; // or figure out smth better
6233  strat->tl = -1; // init
6234  for (i=0; i<=strat->sl; i++)
6235  {
6236    memset(&h,0,sizeof(h));
6237    h.p =  strat->S[i]; // lm in currRing, tail in TR
6238    strat->initEcart(&h);
6239    h.sev = strat->sevS[i];
6240    h.t_p = NULL;
6241    h.GetTP(); // creates correct t_p
6242    /*puts the elements of S with their shifts to T*/
6243    //    int atT, int uptodeg, int lV)
6244    strat->S_2_R[i] = strat->tl + 1; // the el't with shift 0 will be inserted first
6245    // need a small check for above; we insert >=1 elements
6246    // insert this check into kTest_TS ?
6247    enterTShift(h,strat,atT,uptodeg,lV);
6248  }
6249  /* what about setting strat->tl? */
6250}
6251#endif
6252
6253#ifdef HAVE_SHIFTBBA
6254void initBuchMoraShift (ideal F,ideal Q,kStrategy strat)
6255{
6256  strat->interpt = BTEST1(OPT_INTERRUPT);
6257  strat->kHEdge=NULL;
6258  if (pOrdSgn==1) strat->kHEdgeFound=FALSE;
6259  /*- creating temp data structures------------------- -*/
6260  strat->cp = 0;
6261  strat->c3 = 0;
6262  strat->cv = 0;
6263  strat->tail = pInit();
6264  /*- set s -*/
6265  strat->sl = -1;
6266  /*- set L -*/
6267  strat->Lmax = setmaxL;
6268  strat->Ll = -1;
6269  strat->L = initL();
6270  /*- set B -*/
6271  strat->Bmax = setmaxL;
6272  strat->Bl = -1;
6273  strat->B = initL();
6274  /*- set T -*/
6275  strat->tl = -1;
6276  strat->tmax = setmaxT;
6277  strat->T = initT();
6278  strat->R = initR();
6279  strat->sevT = initsevT();
6280  /*- init local data struct.---------------------------------------- -*/
6281  strat->P.ecart=0;
6282  strat->P.length=0;
6283  if (pOrdSgn==-1)
6284  {
6285    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
6286    if (strat->kNoether!=NULL) pSetComp(strat->kNoetherTail(), strat->ak);
6287  }
6288  if(TEST_OPT_SB_1)
6289  {
6290    int i;
6291    ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
6292    for (i=strat->newIdeal;i<IDELEMS(F);i++)
6293    {
6294      P->m[i-strat->newIdeal] = F->m[i];
6295      F->m[i] = NULL;
6296    }
6297    initSSpecial(F,Q,P,strat);
6298    for (i=strat->newIdeal;i<IDELEMS(F);i++)
6299    {
6300      F->m[i] = P->m[i-strat->newIdeal];
6301      P->m[i-strat->newIdeal] = NULL;
6302    }
6303    idDelete(&P);
6304  }
6305  else
6306  {
6307    /*Shdl=*/initSL(F, Q,strat); /*sets also S, ecartS, fromQ */
6308    // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
6309  }
6310  strat->kIdeal = NULL;
6311  strat->fromT = FALSE;
6312  strat->noTailReduction = !TEST_OPT_REDTAIL;
6313  if (!TEST_OPT_SB_1)
6314  {
6315    /* the only change: we do not fill the set T*/
6316    updateS(FALSE,strat);
6317  }
6318  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
6319  strat->fromQ=NULL;
6320  /* more changes: fill the set T with all the shifts of elts of S*/
6321  /* is done by other procedure */
6322}
6323#endif
6324
6325#ifdef HAVE_SHIFTBBA
6326/*1
6327* put the pairs (sh \dot s[i],p)  into the set B, ecart=ecart(p)
6328*/
6329void enterOnePairManyShifts (int i, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int uptodeg, int lV)
6330{
6331  /* p comes from strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
6332
6333  assume(p_LmCheckIsFromRing(p,currRing));
6334  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
6335
6336  /* cycles through all shifts of s[i] until uptodeg - lastVblock(s[i]) */
6337  /* that is create the pairs (f, s \dot g)  */
6338
6339  poly qq = strat->S[i]; //  lm in currRing, tail in tailRing
6340
6341  //  poly q = pCopy(pHead(strat->S[i])); // lm in currRing
6342  //  pNext(q) = prCopyR(pNext(strat->S[i]),strat->tailRing,currRing); // zero shift
6343
6344 /* determine how many elements we have to insert for a given s[i] */
6345  /* x(0)y(1)z(2) : lastVblock-1=2, to add until lastVblock=uptodeg-1 */
6346  /* hence, a total number of elt's to add is: */
6347  /*  int toInsert = 1 + (uptodeg-1) - (pLastVblock(p.p, lV) -1);  */
6348  int toInsert =  itoInsert(qq, uptodeg,  lV, strat->tailRing);
6349
6350#ifdef KDEBUG
6351    if (TEST_OPT_DEBUG)
6352    {
6353      //      Print("entered ManyShifts: with toInsert=%d",toInsert); PrintLn();
6354    }
6355#endif
6356
6357  assume(i<=strat->sl); // from OnePair
6358  if (strat->interred_flag) return; // ?
6359
6360  /* these vars hold for all shifts of s[i] */
6361  int ecartq = 0; //Hans says it's ok; we're in the homog case, no ecart
6362 
6363  int qfromQ;
6364  if (strat->fromQ != NULL)
6365  {
6366    qfromQ = strat->fromQ[i]; 
6367  }
6368  else
6369  {
6370    qfromQ = -1;
6371  }
6372
6373  int j;
6374
6375  poly q, s;
6376
6377  // for the 0th shift: insert the orig. pair
6378  enterOnePairShift(qq, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, j, i, uptodeg, lV);
6379
6380  for (j=1; j<= toInsert; j++) 
6381  {
6382    //    q = pLPshift(strat->S[i],j,uptodeg,lV);
6383    q = p_LPshiftT(qq, j, uptodeg, lV, strat, currRing); 
6384    //    q = p_mLPshift(qq,j,uptodeg,lV,currRing); // lm in currRing, shift this monomial
6385    //    s = p_LPshift(pNext(qq), j, uptodeg, lV, strat->tailRing); // from tailRing
6386    //    pNext(q) = s; // in tailRing
6387    /* here we need to call enterOnePair with two polys ... */
6388
6389#ifdef KDEBUG
6390    if (TEST_OPT_DEBUG)
6391    {
6392      //      PrintS("ManyShifts: calling enterOnePairShift(q,p)");      PrintLn();
6393    }
6394#endif
6395    enterOnePairShift(q, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, j, i, uptodeg, lV);
6396  }
6397}
6398#endif
6399
6400#ifdef HAVE_SHIFTBBA
6401/*1
6402* put the pairs (sh \dot qq,p)  into the set B, ecart=ecart(p)
6403* despite the name, not only self shifts
6404*/
6405void enterOnePairSelfShifts (poly qq, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int uptodeg, int lV)
6406{
6407
6408  /* format: p,qq are in LObject form: lm in CR, tail in TR */
6409  /* for true self pairs qq ==p  */
6410  /* we test both qq and p */
6411  assume(p_LmCheckIsFromRing(qq,currRing));
6412  assume(p_CheckIsFromRing(pNext(qq),strat->tailRing));
6413  assume(p_LmCheckIsFromRing(p,currRing));
6414  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
6415
6416  /* since this proc is applied twice for (h, s*g) and (g,s*h), init j with 1 only */
6417
6418  //  int j = 0;
6419  int j = 1;
6420
6421  /* for such self pairs start with 1, not with 0 */
6422  if (qq == p) j=1;
6423
6424  /* should cycle through all shifts of q until uptodeg - lastVblock(q) */
6425  /* that is create the pairs (f, s \dot g)  */
6426
6427  int toInsert =  itoInsert(qq, uptodeg,  lV, strat->tailRing);
6428
6429#ifdef KDEBUG
6430    if (TEST_OPT_DEBUG)
6431    {
6432      //      Print("entered SelfShifts: with toInsert=%d",toInsert); PrintLn();
6433    }
6434#endif
6435
6436  poly q, s;
6437
6438  if (strat->interred_flag) return; // ?
6439
6440  /* these vars hold for all shifts of s[i] */
6441  int ecartq = 0; //Hans says it's ok; we're in the homog case, no ecart
6442  int qfromQ = 0; // strat->fromQ[i];
6443
6444  for (; j<= toInsert; j++)
6445  {
6446    //    q = pLPshift(strat->S[i],j,uptodeg,lV);
6447    /* we increase shifts by one; must delete q there*/
6448    //    q = qq; q = pMoveCurrTail2poly(q,strat);
6449    //    q = pLPshift(q,j,uptodeg,lV); //,currRing);
6450    q = p_LPshiftT(qq, j, uptodeg, lV, strat, currRing);
6451    //    q = p_mLPshift(qq,j,uptodeg,lV,currRing); // lm in currRing, shift this monomial
6452    //    s = p_LPshift(pNext(qq), j, uptodeg, lV, strat->tailRing); // from tailRing
6453    //    pNext(q) = s; // in tailRing
6454    /* here we need to call enterOnePair with two polys ... */
6455#ifdef KDEBUG
6456    if (TEST_OPT_DEBUG)
6457    {
6458      //      PrintS("SelfShifts: calling enterOnePairShift(q,p)");      PrintLn();
6459    }
6460#endif
6461    enterOnePairShift(q, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, j, -1, uptodeg, lV);
6462  }
6463}
6464#endif
6465
6466#ifdef HAVE_SHIFTBBA
6467/*2
6468* put the pair (q,p)  into the set B, ecart=ecart(p), q is the shift of some s[i]
6469*/
6470void enterOnePairShift (poly q, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int ecartq, int qisFromQ, int shiftcount, int ifromS, int uptodeg, int lV)
6471{
6472
6473  /* Format: q and p are like strat->P.p, so lm in CR, tail in TR */
6474
6475  /* check this Formats: */
6476  assume(p_LmCheckIsFromRing(q,currRing));
6477  assume(p_CheckIsFromRing(pNext(q),strat->tailRing));
6478  assume(p_LmCheckIsFromRing(p,currRing));
6479  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
6480
6481#ifdef KDEBUG
6482    if (TEST_OPT_DEBUG)
6483    {
6484//       PrintS("enterOnePairShift(q,p) invoked with q = ");
6485//       wrp(q); //      wrp(pHead(q));
6486//       PrintS(", p = ");
6487//       wrp(p); //wrp(pHead(p));
6488//       PrintLn();
6489    }
6490#endif
6491
6492  /* poly q stays for s[i], ecartq = ecart(q), qisFromQ = applies to q */
6493
6494  int qfromQ = qisFromQ;
6495
6496  /* need additionally: int up_to_degree, poly V0 with the variables in (0)  or just the number lV = the length of the first block */
6497
6498  if (strat->interred_flag) return;
6499
6500  int      l,j,compare;
6501  LObject  Lp;
6502  Lp.i_r = -1;
6503
6504#ifdef KDEBUG
6505  Lp.ecart=0; Lp.length=0;
6506#endif
6507  /*- computes the lcm(s[i],p) -*/
6508  Lp.lcm = pInit();
6509
6510  pLcm(p,q, Lp.lcm); // q is what was strat->S[i], so a poly in LM/TR presentation
6511  pSetm(Lp.lcm);
6512
6513  /* apply the V criterion */
6514  if (!isInV(Lp.lcm, lV))
6515  {
6516#ifdef KDEBUG
6517    if (TEST_OPT_DEBUG)
6518    {
6519      PrintS("V crit applied to q = ");
6520      wrp(q); //      wrp(pHead(q));
6521      PrintS(", p = ");
6522      wrp(p); //wrp(pHead(p));
6523      PrintLn();
6524    }
6525#endif
6526    pLmFree(Lp.lcm);
6527    Lp.lcm=NULL;
6528    /* + counter for applying the V criterion */
6529    strat->cv++;
6530    return;
6531  }
6532
6533  const BOOLEAN bIsPluralRing = rIsPluralRing(currRing);
6534  const BOOLEAN bIsSCA        = rIsSCA(currRing) && strat->z2homog; // for prod-crit
6535  const BOOLEAN bNCProdCrit   = ( !bIsPluralRing || bIsSCA ); // commutative or homogeneous SCA
6536
6537  if (strat->sugarCrit && bNCProdCrit)
6538  {
6539    if((!((ecartq>0)&&(ecart>0)))
6540    && pHasNotCF(p,q))
6541    {
6542    /*
6543    *the product criterion has applied for (s,p),
6544    *i.e. lcm(s,p)=product of the leading terms of s and p.
6545    *Suppose (s,r) is in L and the leading term
6546    *of p divides lcm(s,r)
6547    *(==> the leading term of p divides the leading term of r)
6548    *but the leading term of s does not divide the leading term of r
6549    *(notice that this condition is automatically satisfied if r is still
6550    *in S), then (s,r) can be cancelled.
6551    *This should be done here because the
6552    *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
6553    *
6554    *Moreover, skipping (s,r) holds also for the noncommutative case.
6555    */
6556      strat->cp++;
6557      pLmFree(Lp.lcm);
6558      Lp.lcm=NULL;
6559      return;
6560    }
6561    else
6562      Lp.ecart = si_max(ecart,ecartq);
6563    if (strat->fromT && (ecartq>ecart))
6564    {
6565      pLmFree(Lp.lcm);
6566      Lp.lcm=NULL;
6567      return;
6568      /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
6569    }
6570    /*
6571    *the set B collects the pairs of type (S[j],p)
6572    *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
6573    *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
6574    *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
6575    */
6576    {
6577      j = strat->Bl;
6578      loop
6579      {
6580        if (j < 0)  break;
6581        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
6582        if ((compare==1)
6583        &&(sugarDivisibleBy(strat->B[j].ecart,Lp.ecart)))
6584        {
6585          strat->c3++;
6586          if ((strat->fromQ==NULL) || (isFromQ==0) || (qfromQ==0))
6587          {
6588            pLmFree(Lp.lcm);
6589            return;
6590          }
6591          break;
6592        }
6593        else
6594        if ((compare ==-1)
6595        && sugarDivisibleBy(Lp.ecart,strat->B[j].ecart))
6596        {
6597          deleteInL(strat->B,&strat->Bl,j,strat);
6598          strat->c3++;
6599        }
6600        j--;
6601      }
6602    }
6603  }
6604  else /*sugarcrit*/
6605  {
6606    if (bNCProdCrit)
6607    {
6608      // if currRing->nc_type!=quasi (or skew)
6609      // TODO: enable productCrit for super commutative algebras...
6610      if(/*(strat->ak==0) && productCrit(p,strat->S[i])*/
6611      pHasNotCF(p,q))
6612      {
6613      /*
6614      *the product criterion has applied for (s,p),
6615      *i.e. lcm(s,p)=product of the leading terms of s and p.
6616      *Suppose (s,r) is in L and the leading term
6617      *of p devides lcm(s,r)
6618      *(==> the leading term of p devides the leading term of r)
6619      *but the leading term of s does not devide the leading term of r
6620      *(notice that tis condition is automatically satisfied if r is still
6621      *in S), then (s,r) can be canceled.
6622      *This should be done here because the
6623      *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
6624      */
6625          strat->cp++;
6626          pLmFree(Lp.lcm);
6627          Lp.lcm=NULL;
6628          return;
6629      }
6630      if (strat->fromT && (ecartq>ecart))
6631      {
6632        pLmFree(Lp.lcm);
6633        Lp.lcm=NULL;
6634        return;
6635        /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
6636      }
6637      /*
6638      *the set B collects the pairs of type (S[j],p)
6639      *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
6640      *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
6641      *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
6642      */
6643      for(j = strat->Bl;j>=0;j--)
6644      {
6645        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
6646        if (compare==1)
6647        {
6648          strat->c3++;
6649          if ((strat->fromQ==NULL) || (isFromQ==0) || (qfromQ==0))
6650          {
6651            pLmFree(Lp.lcm);
6652            return;
6653          }
6654          break;
6655        }
6656        else
6657        if (compare ==-1)
6658        {
6659          deleteInL(strat->B,&strat->Bl,j,strat);
6660          strat->c3++;
6661        }
6662      }
6663    }
6664  }
6665  /*
6666  *the pair (S[i],p) enters B if the spoly != 0
6667  */
6668  /*-  compute the short s-polynomial -*/
6669  if (strat->fromT && !TEST_OPT_INTSTRATEGY)
6670    pNorm(p);
6671  if ((q==NULL) || (p==NULL))
6672    return;
6673  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (qfromQ!=0))
6674    Lp.p=NULL;
6675  else
6676  {
6677//     if ( bIsPluralRing )
6678//     {
6679//       if(pHasNotCF(p, q))
6680//       {
6681//         if(ncRingType(currRing) == nc_lie)
6682//         {
6683//             // generalized prod-crit for lie-type
6684//             strat->cp++;
6685//             Lp.p = nc_p_Bracket_qq(pCopy(p),q);
6686//         }
6687//         else
6688//         if( bIsSCA )
6689//         {
6690//             // product criterion for homogeneous case in SCA
6691//             strat->cp++;
6692//             Lp.p = NULL;
6693//         }
6694//         else
6695//           Lp.p = nc_CreateSpoly(q,p,currRing); // ?
6696//       }
6697//       else  Lp.p = nc_CreateSpoly(q,p,currRing);
6698//     }
6699//     else
6700//     {
6701   
6702    /* ksCreateShortSpoly needs two Lobject-kind presentations */
6703    /* p is already in this form, so convert q */
6704    //    q = pMove2CurrTail(q, strat);
6705    Lp.p = ksCreateShortSpoly(q, p, strat->tailRing);
6706      //  }
6707  }
6708  if (Lp.p == NULL)
6709  {
6710    /*- the case that the s-poly is 0 -*/
6711    /* TEMPORARILY DISABLED FOR SHIFTS because there is no i*/
6712//      if (strat->pairtest==NULL) initPairtest(strat);
6713//      strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
6714//      strat->pairtest[strat->sl+1] = TRUE;
6715    /* END _ TEMPORARILY DISABLED FOR SHIFTS */
6716    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
6717    /*
6718    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
6719    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
6720    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
6721    *term of p devides the lcm(s,r)
6722    *(this canceling should be done here because
6723    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
6724    *the first case is handeled in chainCrit
6725    */
6726    if (Lp.lcm!=NULL) pLmFree(Lp.lcm);
6727  }
6728  else
6729  {
6730    /*- the pair (S[i],p) enters B -*/
6731    /* both of them should have their LM in currRing and TAIL in tailring */
6732    Lp.p1 = q;  // already in the needed form
6733    Lp.p2 = p; // already in the needed form
6734
6735    if ( !bIsPluralRing )
6736      pNext(Lp.p) = strat->tail;
6737
6738    /* TEMPORARILY DISABLED FOR SHIFTS because there's no i*/
6739    /* at the beginning we DO NOT set atR = -1 ANYMORE*/
6740    if ( (atR >= 0) && (shiftcount==0) && (ifromS >=0) )
6741    {
6742      Lp.i_r1 = kFindInT(Lp.p1,strat); //strat->S_2_R[ifromS];
6743      Lp.i_r2 = atR;
6744    }
6745    else
6746    {
6747      /* END _ TEMPORARILY DISABLED FOR SHIFTS */
6748      Lp.i_r1 = -1;
6749      Lp.i_r2 = -1;
6750     }
6751    strat->initEcartPair(&Lp,q,p,ecartq,ecart);
6752
6753    if (TEST_OPT_INTSTRATEGY)
6754    {
6755      if (!bIsPluralRing)
6756        nDelete(&(Lp.p->coef));
6757    }
6758
6759    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
6760    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
6761  }
6762}
6763#endif
6764
6765#ifdef HAVE_SHIFTBBA
6766/*2
6767*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
6768*superfluous elements in S will be deleted
6769*/
6770void enterpairsShift (poly h,int k,int ecart,int pos,kStrategy strat, int atR,int uptodeg, int lV)
6771{
6772  /* h is strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
6773  /* Q: what is exactly the strat->fromT ? A: a local case trick; don't need it yet*/
6774  int j=pos;
6775
6776#ifdef HAVE_RINGS
6777  assume (!rField_is_Ring(currRing));
6778#endif
6779  initenterpairsShift(h,k,ecart,0,strat, atR,uptodeg,lV);
6780  if ( (!strat->fromT)
6781  && ((strat->syzComp==0)
6782    ||(pGetComp(h)<=strat->syzComp)))
6783  {
6784    //Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
6785    unsigned long h_sev = pGetShortExpVector(h);
6786    loop
6787    {
6788      if (j > k) break;
6789      clearS(h,h_sev, &j,&k,strat);
6790      j++;
6791    }
6792    //Print("end clearS sl=%d\n",strat->sl);
6793  }
6794 // PrintS("end enterpairs\n");
6795}
6796#endif
6797
6798#ifdef HAVE_SHIFTBBA
6799/*3
6800*(s[0], s \dot h),...,(s[k],s \dot h) will be put to the pairset L
6801* also the pairs (h, s\dot s[0]), ..., (h, s\dot s[k]) enter L
6802* additionally we put the pairs (h, s \sdot h) for s>=1 to L
6803*/
6804void initenterpairsShift (poly h,int k,int ecart,int isFromQ, kStrategy strat, int atR, int uptodeg, int lV)
6805{
6806  /* h comes from strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
6807  //  atR = -1;
6808  if ((strat->syzComp==0)
6809  || (pGetComp(h)<=strat->syzComp))
6810  {
6811    int j;
6812    BOOLEAN new_pair=FALSE;
6813
6814    if (pGetComp(h)==0)
6815    {
6816      /* for Q!=NULL: build pairs (f,q),(f1,f2), but not (q1,q2)*/
6817      if ((isFromQ)&&(strat->fromQ!=NULL))
6818      {
6819        for (j=0; j<=k; j++)
6820        {
6821          if (!strat->fromQ[j])
6822          {
6823            new_pair=TRUE;
6824            enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR,uptodeg,lV);
6825            // other side pairs:
6826            enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
6827          //Print("j:%d, Ll:%d\n",j,strat->Ll);
6828          }
6829        }
6830      }
6831      else
6832      {
6833        new_pair=TRUE;
6834        for (j=0; j<=k; j++)
6835        {
6836          enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR,uptodeg,lV);
6837          // other side pairs
6838          enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
6839        }
6840        /* HERE we put (h, s*h) pairs */
6841       /* enterOnePairSelfShifts (poly qq, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int uptodeg, int lV); */
6842       enterOnePairSelfShifts (h, h, ecart, isFromQ, strat, atR, uptodeg, lV);
6843      }
6844    }
6845    else
6846    {
6847      for (j=0; j<=k; j++)
6848      {
6849        if ((pGetComp(h)==pGetComp(strat->S[j]))
6850        || (pGetComp(strat->S[j])==0))
6851        {
6852          new_pair=TRUE;
6853          enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR, uptodeg, lV);
6854          // other side pairs
6855          enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
6856        //Print("j:%d, Ll:%d\n",j,strat->Ll);
6857        }
6858      }
6859      /* HERE we put (h, s*h) pairs */
6860      enterOnePairSelfShifts (h, h, ecart, isFromQ, strat, atR, uptodeg, lV);
6861    }
6862
6863    if (new_pair) chainCrit(h,ecart,strat);
6864
6865  }
6866}
6867#endif
6868
6869#ifdef HAVE_SHIFTBBA
6870/*2
6871* puts p to the set T, starting with the at position atT
6872* and inserts all admissible shifts of p
6873*/
6874void enterTShift(LObject p, kStrategy strat, int atT, int uptodeg, int lV)
6875{
6876  /* determine how many elements we have to insert */
6877  /* x(0)y(1)z(2) : lastVblock-1=2, to add until lastVblock=uptodeg-1 */
6878  /* hence, a total number of elt's to add is: */
6879  /*  int toInsert = 1 + (uptodeg-1) - (pLastVblock(p.p, lV) -1);  */
6880
6881  int toInsert =  itoInsert(p.p, uptodeg,  lV, strat->tailRing);
6882
6883#ifdef PDEBUG
6884  //  Print("enterTShift uses toInsert: %d", toInsert);  PrintLn();
6885#endif
6886  int i;
6887
6888  if (atT < 0)
6889    atT = strat->posInT(strat->T, strat->tl, p);
6890 
6891  /* can call enterT in a sequence, e.g. */
6892
6893  /* shift0 = it's our model for further shifts */
6894  enterT(p,strat,atT);
6895  LObject qq;
6896  for (i=1; i<=toInsert; i++) // toIns - 1?
6897  {
6898    qq       = p; //qq.Copy();
6899    qq.p    = NULL; 
6900    qq.t_p = p_LPshift(p.t_p, i, uptodeg, lV, strat->tailRing); // direct shift
6901    qq.GetP();
6902    // update q.sev
6903    qq.sev = pGetShortExpVector(qq.p);
6904    /* enter it into T, first el't is with the shift 0 */
6905    // compute the position for qq
6906    atT = strat->posInT(strat->T, strat->tl, qq);
6907    enterT(qq,strat,atT);
6908  }
6909/* Q: what to do with this one in the orig enterT ? */
6910/*  strat->R[strat->tl] = &(strat->T[atT]); */
6911/* Solution: it is done by enterT each time separately */
6912}
6913#endif
6914
6915#ifdef HAVE_SHIFTBBA
6916poly redtailBbaShift (LObject* L, int pos, kStrategy strat, BOOLEAN withT, BOOLEAN normalize)
6917{
6918  /* for the shift case need to run it with withT = TRUE */
6919  strat->redTailChange=FALSE;
6920  if (strat->noTailReduction) return L->GetLmCurrRing();
6921  poly h, p;
6922  p = h = L->GetLmTailRing();
6923  if ((h==NULL) || (pNext(h)==NULL))
6924    return L->GetLmCurrRing();
6925
6926  TObject* With;
6927  // placeholder in case strat->tl < 0
6928  TObject  With_s(strat->tailRing);
6929
6930  LObject Ln(pNext(h), strat->tailRing);
6931  Ln.pLength = L->GetpLength() - 1;
6932
6933  pNext(h) = NULL;
6934  if (L->p != NULL) pNext(L->p) = NULL;
6935  L->pLength = 1;
6936
6937  Ln.PrepareRed(strat->use_buckets);
6938
6939  while(!Ln.IsNull())
6940  {
6941    loop
6942    {
6943      Ln.SetShortExpVector();
6944      if (withT)
6945      {
6946        int j;
6947        j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln);
6948        if (j < 0) break;
6949        With = &(strat->T[j]);
6950      }
6951      else
6952      {
6953        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
6954        if (With == NULL) break;
6955      }
6956      if (normalize && (!TEST_OPT_INTSTRATEGY) && (!nIsOne(pGetCoeff(With->p))))
6957      {
6958        With->pNorm();
6959        //if (TEST_OPT_PROT) { PrintS("n"); mflush(); }
6960      }
6961      strat->redTailChange=TRUE;
6962      if (ksReducePolyTail(L, With, &Ln))
6963      {
6964        // reducing the tail would violate the exp bound
6965        //  set a flag and hope for a retry (in bba)
6966        strat->completeReduce_retry=TRUE;
6967        do
6968        {
6969          pNext(h) = Ln.LmExtractAndIter();
6970          pIter(h);
6971          L->pLength++;
6972        } while (!Ln.IsNull());
6973        goto all_done;
6974      }
6975      if (Ln.IsNull()) goto all_done;
6976      if (! withT) With_s.Init(currRing);
6977    }
6978    pNext(h) = Ln.LmExtractAndIter();
6979    pIter(h);
6980    L->pLength++;
6981  }
6982
6983  all_done:
6984  Ln.Delete();
6985  if (L->p != NULL) pNext(L->p) = pNext(p);
6986
6987  if (strat->redTailChange)
6988  {
6989    L->last = NULL;
6990    L->length = 0;
6991  }
6992  L->Normalize(); // HANNES: should have a test
6993  kTest_L(L);
6994  return L->GetLmCurrRing();
6995}
6996#endif
Note: See TracBrowser for help on using the repository browser.