source: git/kernel/GBEngine/kutil.cc @ 009bd5

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