source: git/kernel/kutil.cc @ 37a4c3

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