source: git/kernel/kutil.cc @ d772c3

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