source: git/kernel/GBEngine/kutil.cc @ d6adbbd

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