source: git/kernel/kutil.cc @ 5572c1

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