source: git/kernel/kutil.cc @ 6c98d52

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