source: git/kernel/kutil.cc @ ecededc

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