source: git/kernel/kutil.cc @ a539ad

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