source: git/kernel/kutil.cc @ 930ea8

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