source: git/kernel/kutil.cc @ 8fcfae

spielwiese
Last change on this file since 8fcfae was 8fcfae, checked in by Christian Eder, 10 years ago
rewrites rewrite criteria in sba
  • Property mode set to 100644
File size: 249.7 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5* ABSTRACT: kernel: utils for kStd
6*/
7
8// #define PDEBUG 2
9// #define PDIV_DEBUG
10#define KUTIL_CC
11#include <stdlib.h>
12#include <string.h>
13#ifdef HAVE_CONFIG_H
14#include "singularconfig.h"
15#endif /* HAVE_CONFIG_H */
16#include "mod2.h"
17
18#ifndef NDEBUG
19# define MYTEST 0
20#else /* ifndef NDEBUG */
21# define MYTEST 0
22#endif /* ifndef NDEBUG */
23
24
25#include <misc/mylimits.h>
26#include <misc/options.h>
27#include <polys/nc/nc.h>
28#include <polys/nc/sca.h>
29#include <polys/weight.h> /* for kDebugPrint: maxdegreeWecart*/
30#ifdef KDEBUG
31#undef KDEBUG
32#define KDEBUG 2
33#endif
34
35#ifdef DEBUGF5
36#undef DEBUGF5
37//#define DEBUGF5 1
38#endif
39
40#ifdef HAVE_RINGS
41#include <kernel/ideals.h>
42#endif
43
44// define if enterL, enterT should use memmove instead of doing it manually
45// on topgun, this is slightly faster (see monodromy_l.tst, homog_gonnet.sing)
46#ifndef SunOS_4
47#define ENTER_USE_MEMMOVE
48#endif
49
50// define, if the my_memmove inlines should be used instead of
51// system memmove -- it does not seem to pay off, though
52// #define ENTER_USE_MYMEMMOVE
53
54#include <kernel/kutil.h>
55#include <polys/kbuckets.h>
56#include <kernel/febase.h>
57#include <omalloc/omalloc.h>
58#include <coeffs/numbers.h>
59#include <kernel/polys.h>
60#include <polys/monomials/ring.h>
61#include <kernel/ideals.h>
62#include <kernel/timer.h>
63//#include "cntrlc.h"
64#include <kernel/stairc.h>
65#include <kernel/kstd1.h>
66#include <polys/operations/pShallowCopyDelete.h>
67
68/* shiftgb stuff */
69#include <kernel/shiftgb.h>
70#include <polys/prCopy.h>
71
72#ifdef HAVE_RATGRING
73#include <kernel/ratgring.h>
74#endif
75
76#ifdef KDEBUG
77#undef KDEBUG
78#define KDEBUG 2
79#endif
80
81#ifdef DEBUGF5
82#undef DEBUGF5
83#define DEBUGF5 2
84#endif
85
86#define ADIDEBUG 0
87
88denominator_list DENOMINATOR_LIST=NULL;
89
90
91#ifdef ENTER_USE_MYMEMMOVE
92inline void _my_memmove_d_gt_s(unsigned long* d, unsigned long* s, long l)
93{
94  register unsigned long* _dl = (unsigned long*) d;
95  register unsigned long* _sl = (unsigned long*) s;
96  register long _i = l - 1;
97
98  do
99  {
100    _dl[_i] = _sl[_i];
101    _i--;
102  }
103  while (_i >= 0);
104}
105
106inline void _my_memmove_d_lt_s(unsigned long* d, unsigned long* s, long l)
107{
108  register long _ll = l;
109  register unsigned long* _dl = (unsigned long*) d;
110  register unsigned long* _sl = (unsigned long*) s;
111  register long _i = 0;
112
113  do
114  {
115    _dl[_i] = _sl[_i];
116    _i++;
117  }
118  while (_i < _ll);
119}
120
121inline void _my_memmove(void* d, void* s, long l)
122{
123  unsigned long _d = (unsigned long) d;
124  unsigned long _s = (unsigned long) s;
125  unsigned long _l = ((l) + SIZEOF_LONG - 1) >> LOG_SIZEOF_LONG;
126
127  if (_d > _s) _my_memmove_d_gt_s(_d, _s, _l);
128  else _my_memmove_d_lt_s(_d, _s, _l);
129}
130
131#undef memmove
132#define memmove(d,s,l) _my_memmove(d, s, l)
133#endif
134
135static poly redMora (poly h,int maxIndex,kStrategy strat);
136static poly redBba (poly h,int maxIndex,kStrategy strat);
137
138#ifdef HAVE_RINGS
139#define pDivComp_EQUAL 2
140#define pDivComp_LESS 1
141#define pDivComp_GREATER -1
142#define pDivComp_INCOMP 0
143/* Checks the relation of LM(p) and LM(q)
144     LM(p) = LM(q) => return pDivComp_EQUAL
145     LM(p) | LM(q) => return pDivComp_LESS
146     LM(q) | LM(p) => return pDivComp_GREATER
147     else return pDivComp_INCOMP */
148static inline int pDivCompRing(poly p, poly q)
149{
150  if (pGetComp(p) == pGetComp(q))
151  {
152    BOOLEAN a=FALSE, b=FALSE;
153    int i;
154    unsigned long la, lb;
155    unsigned long divmask = currRing->divmask;
156    for (i=0; i<currRing->VarL_Size; i++)
157    {
158      la = p->exp[currRing->VarL_Offset[i]];
159      lb = q->exp[currRing->VarL_Offset[i]];
160      if (la != lb)
161      {
162        if (la < lb)
163        {
164          if (b) return pDivComp_INCOMP;
165          if (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask))
166            return pDivComp_INCOMP;
167          a = TRUE;
168        }
169        else
170        {
171          if (a) return pDivComp_INCOMP;
172          if (((la & divmask) ^ (lb & divmask)) != ((la - lb) & divmask))
173            return pDivComp_INCOMP;
174          b = TRUE;
175        }
176      }
177    }
178    if (a) return pDivComp_LESS;
179    if (b) return pDivComp_GREATER;
180    if (!a & !b) return pDivComp_EQUAL;
181  }
182  return pDivComp_INCOMP;
183}
184#endif
185
186static inline int pDivComp(poly p, poly q)
187{
188  if (pGetComp(p) == pGetComp(q))
189  {
190#ifdef HAVE_RATGRING
191    if (rIsRatGRing(currRing))
192    {
193      if (_p_LmDivisibleByPart(p,currRing,
194                           q,currRing,
195                           currRing->real_var_start, currRing->real_var_end))
196        return 0;
197      return pLmCmp(q,p); // ONLY FOR GLOBAL ORDER!
198    }
199#endif
200    BOOLEAN a=FALSE, b=FALSE;
201    int i;
202    unsigned long la, lb;
203    unsigned long divmask = currRing->divmask;
204    for (i=0; i<currRing->VarL_Size; i++)
205    {
206      la = p->exp[currRing->VarL_Offset[i]];
207      lb = q->exp[currRing->VarL_Offset[i]];
208      if (la != lb)
209      {
210        if (la < lb)
211        {
212          if (b) return 0;
213          if (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask))
214            return 0;
215          a = TRUE;
216        }
217        else
218        {
219          if (a) return 0;
220          if (((la & divmask) ^ (lb & divmask)) != ((la - lb) & divmask))
221            return 0;
222          b = TRUE;
223        }
224      }
225    }
226    if (a) { /*assume(pLmCmp(q,p)==1);*/ return 1; }
227    if (b) { /*assume(pLmCmp(q,p)==-1);*/return -1; }
228    /*assume(pLmCmp(q,p)==0);*/
229  }
230  return 0;
231}
232
233
234int     HCord;
235int     Kstd1_deg;
236int     Kstd1_mu=32000;
237
238/*2
239*deletes higher monomial of p, re-compute ecart and length
240*works only for orderings with ecart =pFDeg(end)-pFDeg(start)
241*/
242void deleteHC(LObject *L, kStrategy strat, BOOLEAN fromNext)
243{
244  if (strat->kHEdgeFound)
245  {
246    assume(kTest_L(L));
247    poly p1;
248    poly p = L->GetLmTailRing();
249    int l = 1;
250    kBucket_pt bucket = NULL;
251    if (L->bucket != NULL)
252    {
253      kBucketClear(L->bucket, &pNext(p), &L->pLength);
254      L->pLength++;
255      bucket = L->bucket;
256      L->bucket = NULL;
257    }
258
259    if (!fromNext && p_Cmp(p,strat->kNoetherTail(), L->tailRing) == -1)
260    {
261      L->Delete();
262      L->Clear();
263      L->ecart = -1;
264      if (bucket != NULL) kBucketDestroy(&bucket);
265      return;
266    }
267    p1 = p;
268    while (pNext(p1)!=NULL)
269    {
270    if (p_LmCmp(pNext(p1), strat->kNoetherTail(), L->tailRing) == -1)
271      {
272        p_Delete(&pNext(p1), L->tailRing);
273        if (p1 == p)
274        {
275          if (L->t_p != NULL)
276          {
277            assume(L->p != NULL && p == L->t_p);
278            pNext(L->p) = NULL;
279          }
280          L->max  = NULL;
281        }
282        else if (fromNext)
283          L->max  = p_GetMaxExpP(pNext(L->p), L->tailRing ); // p1;
284        //if (L->pLength != 0)
285        L->pLength = l;
286        // Hmmm when called from updateT, then only
287        // reset ecart when cut
288        if (fromNext)
289          L->ecart = L->pLDeg() - L->GetpFDeg();
290        break;
291      }
292      l++;
293      pIter(p1);
294    }
295    if (! fromNext)
296    {
297      L->SetpFDeg();
298      L->ecart = L->pLDeg(strat->LDegLast) - L->GetpFDeg();
299    }
300    if (bucket != NULL)
301    {
302      if (L->pLength > 1)
303      {
304        kBucketInit(bucket, pNext(p), L->pLength - 1);
305        pNext(p) = NULL;
306        if (L->t_p != NULL) pNext(L->t_p) = NULL;
307        L->pLength = 0;
308        L->bucket = bucket;
309      }
310      else
311        kBucketDestroy(&bucket);
312    }
313    assume(kTest_L(L));
314  }
315}
316
317void deleteHC(poly* p, int* e, int* l,kStrategy strat)
318{
319  LObject L(*p, currRing, strat->tailRing);
320
321  deleteHC(&L, strat);
322  *p = L.p;
323  *e = L.ecart;
324  *l = L.length;
325  if (L.t_p != NULL) p_LmFree(L.t_p, strat->tailRing);
326}
327
328/*2
329*tests if p.p=monomial*unit and cancels the unit
330*/
331void cancelunit (LObject* L,BOOLEAN inNF)
332{
333  int  i;
334  poly h;
335  number lc;
336
337  if(rHasGlobalOrdering (currRing)) return;
338  if(TEST_OPT_CANCELUNIT) return;
339
340  ring r = L->tailRing;
341  poly p = L->GetLmTailRing();
342
343#ifdef HAVE_RINGS
344    if (rField_is_Ring(currRing) && (currRing->OrdSgn == -1))
345                  lc = p_GetCoeff(p,r);
346#endif
347
348#ifdef HAVE_RINGS_LOC
349  // Leading coef have to be a unit
350  if ( !(nIsUnit(p_GetCoeff(p, r))) ) return;
351#endif
352
353  if(p_GetComp(p, r) != 0 && !p_OneComp(p, r)) return;
354
355//    for(i=r->N;i>0;i--)
356//    {
357//      if ((p_GetExp(p,i,r)>0) && (rIsPolyVar(i, r)==TRUE)) return;
358//    }
359  h = pNext(p);
360
361  loop
362  {
363    if (h==NULL)
364    {
365      p_Delete(&pNext(p), r);
366      if (!inNF)
367      {
368             number eins;
369              #ifdef HAVE_RINGS
370              if (rField_is_Ring(currRing) && (currRing->OrdSgn == -1))
371                              eins = nCopy(lc);
372                    else
373                     #endif
374              eins=nInit(1);
375              if (L->p != NULL)  pSetCoeff(L->p,eins);
376        else if (L->t_p != NULL) nDelete(&pGetCoeff(L->t_p));
377        if (L->t_p != NULL) pSetCoeff0(L->t_p,eins);
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        pNext(L->t_p) = NULL;
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      ///should check also if the lc is a zero divisor, if it divides all the others
399      if (rField_is_Ring(currRing) && currRing->OrdSgn == -1)
400              if(n_DivBy(p_GetCoeff(h,r->cf),lc,r->cf) == 0)
401                      return;
402      #endif
403      if (i == r->N) break; // does divide, try next monom
404    }
405    pIter(h);
406  }
407}
408
409/*2
410*pp is the new element in s
411*returns TRUE (in strat->kHEdgeFound) if
412*-HEcke is allowed
413*-we are in the last componente of the vector
414*-on all axis are monomials (all elements in NotUsedAxis are FALSE)
415*returns FALSE for pLexOrderings,
416*assumes in module case an ordering of type c* !!
417* HEckeTest is only called with strat->kHEdgeFound==FALSE !
418*/
419void HEckeTest (poly pp,kStrategy strat)
420{
421  int   j,/*k,*/p;
422
423  strat->kHEdgeFound=FALSE;
424  if (currRing->pLexOrder || currRing->MixedOrder)
425  {
426    return;
427  }
428  if (strat->ak > 1)           /*we are in the module case*/
429  {
430    return; // until ....
431    //if (!pVectorOut)     /*pVectorOut <=> order = c,* */
432    //  return FALSE;
433    //if (pGetComp(pp) < strat->ak) /* ak is the number of the last component */
434    //  return FALSE;
435  }
436  // k = 0;
437  p=pIsPurePower(pp);
438  if (p!=0) strat->NotUsedAxis[p] = FALSE;
439  /*- the leading term of pp is a power of the p-th variable -*/
440  for (j=(currRing->N);j>0; j--)
441  {
442    if (strat->NotUsedAxis[j])
443    {
444      return;
445    }
446  }
447  strat->kHEdgeFound=TRUE;
448}
449
450/*2
451*utilities for TSet, LSet
452*/
453inline static intset initec (const int maxnr)
454{
455  return (intset)omAlloc(maxnr*sizeof(int));
456}
457
458inline static unsigned long* initsevS (const int maxnr)
459{
460  return (unsigned long*)omAlloc0(maxnr*sizeof(unsigned long));
461}
462inline static int* initS_2_R (const int maxnr)
463{
464  return (int*)omAlloc0(maxnr*sizeof(int));
465}
466
467static inline void enlargeT (TSet &T, TObject** &R, unsigned long* &sevT,
468                             int &length, const int incr)
469{
470  assume(T!=NULL);
471  assume(sevT!=NULL);
472  assume(R!=NULL);
473  assume((length+incr) > 0);
474
475  int i;
476  T = (TSet)omRealloc0Size(T, length*sizeof(TObject),
477                           (length+incr)*sizeof(TObject));
478
479  sevT = (unsigned long*) omReallocSize(sevT, length*sizeof(long*),
480                           (length+incr)*sizeof(long*));
481
482  R = (TObject**)omRealloc0Size(R,length*sizeof(TObject*),
483                                (length+incr)*sizeof(TObject*));
484  for (i=length-1;i>=0;i--) R[T[i].i_r] = &(T[i]);
485  length += incr;
486}
487
488void cleanT (kStrategy strat)
489{
490  int i,j;
491  poly  p;
492  assume(currRing == strat->tailRing || strat->tailRing != NULL);
493
494  pShallowCopyDeleteProc p_shallow_copy_delete =
495    (strat->tailRing != currRing ?
496     pGetShallowCopyDeleteProc(strat->tailRing, currRing) :
497     NULL);
498
499  for (j=0; j<=strat->tl; j++)
500  {
501    p = strat->T[j].p;
502    strat->T[j].p=NULL;
503    if (strat->T[j].max != NULL)
504    {
505      p_LmFree(strat->T[j].max, strat->tailRing);
506    }
507    i = -1;
508    loop
509    {
510      i++;
511      if (i>strat->sl)
512      {
513        if (strat->T[j].t_p != NULL)
514        {
515          p_Delete(&(strat->T[j].t_p), strat->tailRing);
516          p_LmFree(p, currRing);
517        }
518        else
519          pDelete(&p);
520        break;
521      }
522      if (p == strat->S[i])
523      {
524        if (strat->T[j].t_p != NULL)
525        {
526          assume(p_shallow_copy_delete != NULL);
527          pNext(p) = p_shallow_copy_delete(pNext(p),strat->tailRing,currRing,
528                                           currRing->PolyBin);
529          p_LmFree(strat->T[j].t_p, strat->tailRing);
530        }
531        break;
532      }
533    }
534  }
535  strat->tl=-1;
536}
537
538//LSet initL ()
539//{
540//  int i;
541//  LSet l = (LSet)omAlloc(setmaxL*sizeof(LObject));
542//  return l;
543//}
544
545static inline void enlargeL (LSet* L,int* length,const int incr)
546{
547  assume((*L)!=NULL);
548  assume((length+incr)>0);
549
550  *L = (LSet)omReallocSize((*L),(*length)*sizeof(LObject),
551                                   ((*length)+incr)*sizeof(LObject));
552  (*length) += incr;
553}
554
555void initPairtest(kStrategy strat)
556{
557  strat->pairtest = (BOOLEAN *)omAlloc0((strat->sl+2)*sizeof(BOOLEAN));
558}
559
560/*2
561*test whether (p1,p2) or (p2,p1) is in L up position length
562*it returns TRUE if yes and the position k
563*/
564BOOLEAN isInPairsetL(int length,poly p1,poly p2,int*  k,kStrategy strat)
565{
566  LObject *p=&(strat->L[length]);
567
568  *k = length;
569  loop
570  {
571    if ((*k) < 0) return FALSE;
572    if (((p1 == (*p).p1) && (p2 == (*p).p2))
573    ||  ((p1 == (*p).p2) && (p2 == (*p).p1)))
574      return TRUE;
575    (*k)--;
576    p--;
577  }
578}
579
580/*2
581*in B all pairs have the same element p on the right
582*it tests whether (q,p) is in B and returns TRUE if yes
583*and the position k
584*/
585BOOLEAN isInPairsetB(poly q,int*  k,kStrategy strat)
586{
587  LObject *p=&(strat->B[strat->Bl]);
588
589  *k = strat->Bl;
590  loop
591  {
592    if ((*k) < 0) return FALSE;
593    if (q == (*p).p1)
594      return TRUE;
595    (*k)--;
596    p--;
597  }
598}
599
600int kFindInT(poly p, TSet T, int tlength)
601{
602  int i;
603
604  for (i=0; i<=tlength; i++)
605  {
606    if (T[i].p == p) return i;
607  }
608  return -1;
609}
610
611int kFindInT(poly p, kStrategy strat)
612{
613  int i;
614  do
615  {
616    i = kFindInT(p, strat->T, strat->tl);
617    if (i >= 0) return i;
618    strat = strat->next;
619  }
620  while (strat != NULL);
621  return -1;
622}
623
624#ifdef KDEBUG
625
626void sTObject::wrp()
627{
628  if (t_p != NULL) p_wrp(t_p, tailRing);
629  else if (p != NULL) p_wrp(p, currRing, tailRing);
630  else ::wrp(NULL);
631}
632
633#define kFalseReturn(x) do { if (!x) return FALSE;} while (0)
634
635// check that Lm's of a poly from T are "equal"
636static const char* kTest_LmEqual(poly p, poly t_p, ring tailRing)
637{
638  int i;
639  for (i=1; i<=tailRing->N; i++)
640  {
641    if (p_GetExp(p, i, currRing) != p_GetExp(t_p, i, tailRing))
642      return "Lm[i] different";
643  }
644  if (p_GetComp(p, currRing) != p_GetComp(t_p, tailRing))
645    return "Lm[0] different";
646  if (pNext(p) != pNext(t_p))
647    return "Lm.next different";
648  if (pGetCoeff(p) != pGetCoeff(t_p))
649    return "Lm.coeff different";
650  return NULL;
651}
652
653static BOOLEAN sloppy_max = FALSE;
654BOOLEAN kTest_T(TObject * T, ring strat_tailRing, int i, char TN)
655{
656  ring tailRing = T->tailRing;
657  if (strat_tailRing == NULL) strat_tailRing = tailRing;
658  r_assume(strat_tailRing == tailRing);
659
660  poly p = T->p;
661  // ring r = currRing;
662
663  if (T->p == NULL && T->t_p == NULL && i >= 0)
664    return dReportError("%c[%d].poly is NULL", TN, i);
665
666  if (T->tailRing != currRing)
667  {
668    if (T->t_p == NULL && i > 0)
669      return dReportError("%c[%d].t_p is NULL", TN, i);
670    pFalseReturn(p_Test(T->t_p, T->tailRing));
671    if (T->p != NULL) pFalseReturn(p_LmTest(T->p, currRing));
672    if (T->p != NULL && T->t_p != NULL)
673    {
674      const char* msg = kTest_LmEqual(T->p, T->t_p, T->tailRing);
675      if (msg != NULL)
676        return dReportError("%c[%d] %s", TN, i, msg);
677      // r = T->tailRing;
678      p = T->t_p;
679    }
680    if (T->p == NULL)
681    {
682      p = T->t_p;
683      // r = T->tailRing;
684    }
685    if (T->t_p != NULL && i >= 0 && TN == 'T')
686    {
687      if (pNext(T->t_p) == NULL)
688      {
689        if (T->max != NULL)
690          return dReportError("%c[%d].max is not NULL as it should be", TN, i);
691      }
692      else
693      {
694        if (T->max == NULL)
695          return dReportError("%c[%d].max is NULL", TN, i);
696        if (pNext(T->max) != NULL)
697          return dReportError("pNext(%c[%d].max) != NULL", TN, i);
698
699        pFalseReturn(p_CheckPolyRing(T->max, tailRing));
700        omCheckBinAddrSize(T->max, (omSizeWOfBin(tailRing->PolyBin))*SIZEOF_LONG);
701#if KDEBUG > 0
702        if (! sloppy_max)
703        {
704          poly test_max = p_GetMaxExpP(pNext(T->t_p), tailRing);
705          p_Setm(T->max, tailRing);
706          p_Setm(test_max, tailRing);
707          BOOLEAN equal = p_ExpVectorEqual(T->max, test_max, tailRing);
708          if (! equal)
709            return dReportError("%c[%d].max out of sync", TN, i);
710          p_LmFree(test_max, tailRing);
711        }
712#endif
713      }
714    }
715  }
716  else
717  {
718    if (T->max != NULL)
719      return dReportError("%c[%d].max != NULL but tailRing == currRing",TN,i);
720    if (T->t_p != NULL)
721      return dReportError("%c[%d].t_p != NULL but tailRing == currRing",TN,i);
722    if (T->p == NULL && i > 0)
723      return dReportError("%c[%d].p is NULL", TN, i);
724    pFalseReturn(p_Test(T->p, currRing));
725  }
726
727  if (i >= 0 && T->pLength != 0
728  && ! rIsSyzIndexRing(currRing) && T->pLength != pLength(p))
729  {
730    int l=T->pLength;
731    T->pLength=pLength(p);
732    return dReportError("%c[%d] pLength error: has %d, specified to have %d",
733                        TN, i , pLength(p), l);
734  }
735
736  // check FDeg,  for elements in L and T
737  if (i >= 0 && (TN == 'T' || TN == 'L'))
738  {
739    // FDeg has ir element from T of L set
740    if (T->FDeg  != T->pFDeg())
741    {
742      int d=T->FDeg;
743      T->FDeg=T->pFDeg();
744      return dReportError("%c[%d] FDeg error: has %d, specified to have %d",
745                          TN, i , T->pFDeg(), d);
746    }
747  }
748
749  // check is_normalized for elements in T
750  if (i >= 0 && TN == 'T')
751  {
752    if (T->is_normalized && ! nIsOne(pGetCoeff(p)))
753      return dReportError("T[%d] is_normalized error", i);
754
755  }
756  return TRUE;
757}
758
759BOOLEAN kTest_L(LObject *L, ring strat_tailRing,
760                BOOLEAN testp, int lpos, TSet T, int tlength)
761{
762  if (testp)
763  {
764    poly pn = NULL;
765    if (L->bucket != NULL)
766    {
767      kFalseReturn(kbTest(L->bucket));
768      r_assume(L->bucket->bucket_ring == L->tailRing);
769      if (L->p != NULL && pNext(L->p) != NULL)
770      {
771        pn = pNext(L->p);
772        pNext(L->p) = NULL;
773      }
774    }
775    kFalseReturn(kTest_T(L, strat_tailRing, lpos, 'L'));
776    if (pn != NULL)
777      pNext(L->p) = pn;
778
779    ring r;
780    poly p;
781    L->GetLm(p, r);
782    if (L->sev != 0 && p_GetShortExpVector(p, r) != L->sev)
783    {
784      return dReportError("L[%d] wrong sev: has %o, specified to have %o",
785                          lpos, p_GetShortExpVector(p, r), L->sev);
786    }
787  }
788  if (L->p1 == NULL)
789  {
790    // L->p2 either NULL or "normal" poly
791    pFalseReturn(pp_Test(L->p2, currRing, L->tailRing));
792  }
793  else if (tlength > 0 && T != NULL && (lpos >=0))
794  {
795    // now p1 and p2 must be != NULL and must be contained in T
796    int i;
797    i = kFindInT(L->p1, T, tlength);
798    if (i < 0)
799      return dReportError("L[%d].p1 not in T",lpos);
800    i = kFindInT(L->p2, T, tlength);
801    if (i < 0)
802      return dReportError("L[%d].p2 not in T",lpos);
803  }
804  return TRUE;
805}
806
807BOOLEAN kTest (kStrategy strat)
808{
809  int i;
810
811  // test P
812  kFalseReturn(kTest_L(&(strat->P), strat->tailRing,
813                       (strat->P.p != NULL && pNext(strat->P.p)!=strat->tail),
814                       -1, strat->T, strat->tl));
815
816  // test T
817  if (strat->T != NULL)
818  {
819    for (i=0; i<=strat->tl; i++)
820    {
821      kFalseReturn(kTest_T(&(strat->T[i]), strat->tailRing, i, 'T'));
822      if (strat->sevT[i] != pGetShortExpVector(strat->T[i].p))
823        return dReportError("strat->sevT[%d] out of sync", i);
824    }
825  }
826
827  // test L
828  if (strat->L != NULL)
829  {
830    for (i=0; i<=strat->Ll; i++)
831    {
832      kFalseReturn(kTest_L(&(strat->L[i]), strat->tailRing,
833                           strat->L[i].Next() != strat->tail, i,
834                           strat->T, strat->tl));
835      // may be unused
836      //if (strat->use_buckets && strat->L[i].Next() != strat->tail &&
837      //    strat->L[i].Next() != NULL && strat->L[i].p1 != NULL)
838      //{
839      //  assume(strat->L[i].bucket != NULL);
840      //}
841    }
842  }
843
844  // test S
845  if (strat->S != NULL)
846    kFalseReturn(kTest_S(strat));
847
848  return TRUE;
849}
850
851BOOLEAN kTest_S(kStrategy strat)
852{
853  int i;
854  BOOLEAN ret = TRUE;
855  for (i=0; i<=strat->sl; i++)
856  {
857    if (strat->S[i] != NULL &&
858        strat->sevS[i] != pGetShortExpVector(strat->S[i]))
859    {
860      return dReportError("S[%d] wrong sev: has %o, specified to have %o",
861                          i , pGetShortExpVector(strat->S[i]), strat->sevS[i]);
862    }
863  }
864  return ret;
865}
866
867
868
869BOOLEAN kTest_TS(kStrategy strat)
870{
871  int i, j;
872  // BOOLEAN ret = TRUE;
873  kFalseReturn(kTest(strat));
874
875  // test strat->R, strat->T[i].i_r
876  for (i=0; i<=strat->tl; i++)
877  {
878    if (strat->T[i].i_r < 0 || strat->T[i].i_r > strat->tl)
879      return dReportError("strat->T[%d].i_r == %d out of bounds", i,
880                          strat->T[i].i_r);
881    if (strat->R[strat->T[i].i_r] != &(strat->T[i]))
882      return dReportError("T[%d].i_r with R out of sync", i);
883  }
884  // test containment of S inT
885  if (strat->S != NULL)
886  {
887    for (i=0; i<=strat->sl; i++)
888    {
889      j = kFindInT(strat->S[i], strat->T, strat->tl);
890      if (j < 0)
891        return dReportError("S[%d] not in T", i);
892      if (strat->S_2_R[i] != strat->T[j].i_r)
893        return dReportError("S_2_R[%d]=%d != T[%d].i_r=%d\n",
894                            i, strat->S_2_R[i], j, strat->T[j].i_r);
895    }
896  }
897  // test strat->L[i].i_r1
898  for (i=0; i<=strat->Ll; i++)
899  {
900    if (strat->L[i].p1 != NULL && strat->L[i].p2)
901    {
902      if (strat->L[i].i_r1 < 0 ||
903          strat->L[i].i_r1 > strat->tl ||
904          strat->L[i].T_1(strat)->p != strat->L[i].p1)
905        return dReportError("L[%d].i_r1 out of sync", i);
906      if (strat->L[i].i_r2 < 0 ||
907          strat->L[i].i_r2 > strat->tl ||
908          strat->L[i].T_2(strat)->p != strat->L[i].p2);
909    }
910    else
911    {
912      if (strat->L[i].i_r1 != -1)
913        return dReportError("L[%d].i_r1 out of sync", i);
914      if (strat->L[i].i_r2 != -1)
915        return dReportError("L[%d].i_r2 out of sync", i);
916    }
917    if (strat->L[i].i_r != -1)
918      return dReportError("L[%d].i_r out of sync", i);
919  }
920  return TRUE;
921}
922
923#endif // KDEBUG
924
925/*2
926*cancels the i-th polynomial in the standardbase s
927*/
928void deleteInS (int i,kStrategy strat)
929{
930#ifdef ENTER_USE_MEMMOVE
931  memmove(&(strat->S[i]), &(strat->S[i+1]), (strat->sl - i)*sizeof(poly));
932  memmove(&(strat->ecartS[i]),&(strat->ecartS[i+1]),(strat->sl - i)*sizeof(int));
933  memmove(&(strat->sevS[i]),&(strat->sevS[i+1]),(strat->sl - i)*sizeof(unsigned long));
934  memmove(&(strat->S_2_R[i]),&(strat->S_2_R[i+1]),(strat->sl - i)*sizeof(int));
935#else
936  int j;
937  for (j=i; j<strat->sl; j++)
938  {
939    strat->S[j] = strat->S[j+1];
940    strat->ecartS[j] = strat->ecartS[j+1];
941    strat->sevS[j] = strat->sevS[j+1];
942    strat->S_2_R[j] = strat->S_2_R[j+1];
943  }
944#endif
945  if (strat->lenS!=NULL)
946  {
947#ifdef ENTER_USE_MEMMOVE
948    memmove(&(strat->lenS[i]),&(strat->lenS[i+1]),(strat->sl - i)*sizeof(int));
949#else
950    for (j=i; j<strat->sl; j++) strat->lenS[j] = strat->lenS[j+1];
951#endif
952  }
953  if (strat->lenSw!=NULL)
954  {
955#ifdef ENTER_USE_MEMMOVE
956    memmove(&(strat->lenSw[i]),&(strat->lenSw[i+1]),(strat->sl - i)*sizeof(wlen_type));
957#else
958    for (j=i; j<strat->sl; j++) strat->lenSw[j] = strat->lenSw[j+1];
959#endif
960  }
961  if (strat->fromQ!=NULL)
962  {
963#ifdef ENTER_USE_MEMMOVE
964    memmove(&(strat->fromQ[i]),&(strat->fromQ[i+1]),(strat->sl - i)*sizeof(int));
965#else
966    for (j=i; j<strat->sl; j++)
967    {
968      strat->fromQ[j] = strat->fromQ[j+1];
969    }
970#endif
971  }
972  strat->S[strat->sl] = NULL;
973  strat->sl--;
974}
975
976
977/*2
978*cancels the i-th polynomial in the standardbase s
979*/
980void deleteInSSba (int i,kStrategy strat)
981{
982#ifdef ENTER_USE_MEMMOVE
983  memmove(&(strat->S[i]), &(strat->S[i+1]), (strat->sl - i)*sizeof(poly));
984  memmove(&(strat->sig[i]), &(strat->sig[i+1]), (strat->sl - i)*sizeof(poly));
985  memmove(&(strat->ecartS[i]),&(strat->ecartS[i+1]),(strat->sl - i)*sizeof(int));
986  memmove(&(strat->sevS[i]),&(strat->sevS[i+1]),(strat->sl - i)*sizeof(unsigned long));
987  memmove(&(strat->sevSig[i]),&(strat->sevSig[i+1]),(strat->sl - i)*sizeof(unsigned long));
988  memmove(&(strat->S_2_R[i]),&(strat->S_2_R[i+1]),(strat->sl - i)*sizeof(int));
989  memmove(&(strat->fromS[i]),&(strat->fromS[i+1]),(strat->sl - i)*sizeof(int));
990#else
991  int j;
992  for (j=i; j<strat->sl; j++)
993  {
994    strat->S[j] = strat->S[j+1];
995    strat->sig[j] = strat->sig[j+1];
996    strat->ecartS[j] = strat->ecartS[j+1];
997    strat->sevS[j] = strat->sevS[j+1];
998    strat->sevSig[j] = strat->sevSig[j+1];
999    strat->S_2_R[j] = strat->S_2_R[j+1];
1000    strat->fromS[j] = strat->fromS[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].p!=NULL)
1049  {
1050    if (pNext(set[j].p) == strat->tail)
1051    {
1052#ifdef HAVE_RINGS
1053      if (pGetCoeff(set[j].p) != NULL)
1054        pLmDelete(set[j].p);
1055      else
1056#endif
1057        pLmFree(set[j].p);
1058      /*- tail belongs to several int spolys -*/
1059    }
1060    else
1061    {
1062      // search p in T, if it is there, do not delete it
1063      if (currRing->OrdSgn != -1 || kFindInT(set[j].p, strat) < 0)
1064      {
1065        // assure that for global orderings kFindInT fails
1066        assume(currRing->OrdSgn == -1 || kFindInT(set[j].p, strat) < 0);
1067        set[j].Delete();
1068      }
1069    }
1070  }
1071  if (*length > 0 && j < *length)
1072  {
1073#ifdef ENTER_USE_MEMMOVE
1074    memmove(&(set[j]), &(set[j+1]), (*length - j)*sizeof(LObject));
1075#else
1076    int i;
1077    for (i=j; i < (*length); i++)
1078      set[i] = set[i+1];
1079#endif
1080  }
1081#ifdef KDEBUG
1082  memset(&(set[*length]),0,sizeof(LObject));
1083#endif
1084  (*length)--;
1085}
1086
1087/*2
1088*enters p at position at in L
1089*/
1090void enterL (LSet *set,int *length, int *LSetmax, LObject p,int at)
1091{
1092  // this should be corrected
1093  assume(p.FDeg == p.pFDeg());
1094
1095  if ((*length)>=0)
1096  {
1097    if ((*length) == (*LSetmax)-1) enlargeL(set,LSetmax,setmaxLinc);
1098    if (at <= (*length))
1099#ifdef ENTER_USE_MEMMOVE
1100      memmove(&((*set)[at+1]), &((*set)[at]), ((*length)-at+1)*sizeof(LObject));
1101#else
1102    for (i=(*length)+1; i>=at+1; i--) (*set)[i] = (*set)[i-1];
1103#endif
1104  }
1105  else at = 0;
1106  (*set)[at] = p;
1107  (*length)++;
1108}
1109
1110/*2
1111* computes the normal ecart;
1112* used in mora case and if pLexOrder & sugar in bba case
1113*/
1114void initEcartNormal (LObject* h)
1115{
1116  h->FDeg = h->pFDeg();
1117  h->ecart = h->pLDeg() - h->FDeg;
1118  // h->length is set by h->pLDeg
1119  h->length=h->pLength=pLength(h->p);
1120}
1121
1122void initEcartBBA (LObject* h)
1123{
1124  h->FDeg = h->pFDeg();
1125  (*h).ecart = 0;
1126  h->length=h->pLength=pLength(h->p);
1127}
1128
1129void initEcartPairBba (LObject* Lp,poly /*f*/,poly /*g*/,int /*ecartF*/,int /*ecartG*/)
1130{
1131  Lp->FDeg = Lp->pFDeg();
1132  (*Lp).ecart = 0;
1133  (*Lp).length = 0;
1134}
1135
1136void initEcartPairMora (LObject* Lp,poly /*f*/,poly /*g*/,int ecartF,int ecartG)
1137{
1138  Lp->FDeg = Lp->pFDeg();
1139  (*Lp).ecart = si_max(ecartF,ecartG);
1140  (*Lp).ecart = (*Lp).ecart- (Lp->FDeg -p_FDeg((*Lp).lcm,currRing));
1141  (*Lp).length = 0;
1142}
1143
1144/*2
1145*if ecart1<=ecart2 it returns TRUE
1146*/
1147static inline BOOLEAN sugarDivisibleBy(int ecart1, int ecart2)
1148{
1149  return (ecart1 <= ecart2);
1150}
1151
1152#ifdef HAVE_RINGS
1153/*2
1154* put the pair (s[i],p)  into the set B, ecart=ecart(p) (ring case)
1155*/
1156void enterOnePairRing (int i,poly p,int ecart, int isFromQ,kStrategy strat, int atR = -1)
1157{
1158  assume(i<=strat->sl);
1159  int      l,j,compare,compareCoeff;
1160  LObject  Lp;
1161
1162  if (strat->interred_flag) return;
1163#ifdef KDEBUG
1164  Lp.ecart=0; Lp.length=0;
1165#endif
1166  /*- computes the lcm(s[i],p) -*/
1167  Lp.lcm = pInit();
1168  pSetCoeff0(Lp.lcm, n_Lcm(pGetCoeff(p), pGetCoeff(strat->S[i]), currRing->cf));
1169
1170  #if ADIDEBUG
1171  PrintS("\nLp.lcm (lc) = ");pWrite(Lp.lcm);
1172  #endif
1173
1174  // Lp.lcm == 0
1175  if (nIsZero(pGetCoeff(Lp.lcm)))
1176  {
1177#ifdef KDEBUG
1178      if (TEST_OPT_DEBUG)
1179      {
1180        PrintS("--- Lp.lcm == 0\n");
1181        PrintS("p:");
1182        wrp(p);
1183        Print("  strat->S[%d]:", i);
1184        wrp(strat->S[i]);
1185        PrintLn();
1186      }
1187#endif
1188      strat->cp++;
1189      pLmDelete(Lp.lcm);
1190      return;
1191  }
1192  // basic product criterion
1193  pLcm(p,strat->S[i],Lp.lcm);
1194
1195  #if ADIDEBUG
1196  PrintS("\nLp.lcm (lcm) = ");pWrite(Lp.lcm);
1197  #endif
1198
1199  pSetm(Lp.lcm);
1200  assume(!strat->sugarCrit);
1201  if (pHasNotCF(p,strat->S[i]) && n_IsUnit(pGetCoeff(p),currRing->cf)
1202      && n_IsUnit(pGetCoeff(strat->S[i]),currRing->cf))
1203  {
1204#ifdef KDEBUG
1205      if (TEST_OPT_DEBUG)
1206      {
1207        PrintS("--- product criterion func enterOnePairRing type 1\n");
1208        PrintS("p:");
1209        wrp(p);
1210        Print("  strat->S[%d]:", i);
1211        wrp(strat->S[i]);
1212        PrintLn();
1213      }
1214#endif
1215      strat->cp++;
1216      pLmDelete(Lp.lcm);
1217      return;
1218  }
1219  assume(!strat->fromT);
1220  /*
1221  *the set B collects the pairs of type (S[j],p)
1222  *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p) != lcm(r,p)
1223  *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
1224  *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
1225  */
1226  for(j = strat->Bl;j>=0;j--)
1227  {
1228    compare=pDivCompRing(strat->B[j].lcm,Lp.lcm);
1229    compareCoeff = n_DivComp(pGetCoeff(strat->B[j].lcm), pGetCoeff(Lp.lcm), currRing->cf);
1230    if ((compareCoeff == pDivComp_EQUAL) || (compare == compareCoeff))
1231    {
1232      if (compare == 1)
1233      {
1234        strat->c3++;
1235#ifdef KDEBUG
1236        if (TEST_OPT_DEBUG)
1237        {
1238          PrintS("--- chain criterion type 1\n");
1239          PrintS("strat->B[j]:");
1240          wrp(strat->B[j].lcm);
1241          PrintS("  Lp.lcm:");
1242          wrp(Lp.lcm);
1243          PrintLn();
1244        }
1245#endif
1246        if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1247        {
1248          pLmDelete(Lp.lcm);
1249          return;
1250        }
1251        break;
1252      }
1253      else
1254      if (compare == -1)
1255      {
1256#ifdef KDEBUG
1257        if (TEST_OPT_DEBUG)
1258        {
1259          PrintS("--- chain criterion type 2\n");
1260          Print("strat->B[%d].lcm:",j);
1261          wrp(strat->B[j].lcm);
1262          PrintS("  Lp.lcm:");
1263          wrp(Lp.lcm);
1264          PrintLn();
1265        }
1266#endif
1267        deleteInL(strat->B,&strat->Bl,j,strat);
1268        strat->c3++;
1269      }
1270    }
1271    if ((compare == pDivComp_EQUAL) && (compareCoeff != 2))
1272    {
1273      if (compareCoeff == pDivComp_LESS)
1274      {
1275#ifdef KDEBUG
1276        if (TEST_OPT_DEBUG)
1277        {
1278          PrintS("--- chain criterion type 3\n");
1279          Print("strat->B[%d].lcm:", j);
1280          wrp(strat->B[j].lcm);
1281          PrintS("  Lp.lcm:");
1282          wrp(Lp.lcm);
1283          PrintLn();
1284        }
1285#endif
1286        strat->c3++;
1287        if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1288        {
1289          pLmDelete(Lp.lcm);
1290          return;
1291        }
1292        break;
1293      }
1294      else
1295      // Add hint for same LM and LC (later) (TODO Oliver)
1296      // if (compareCoeff == pDivComp_GREATER)
1297      {
1298#ifdef KDEBUG
1299        if (TEST_OPT_DEBUG)
1300        {
1301          PrintS("--- chain criterion type 4\n");
1302          Print("strat->B[%d].lcm:", j);
1303          wrp(strat->B[j].lcm);
1304          PrintS("  Lp.lcm:");
1305          wrp(Lp.lcm);
1306          PrintLn();
1307        }
1308#endif
1309        deleteInL(strat->B,&strat->Bl,j,strat);
1310        strat->c3++;
1311      }
1312    }
1313  }
1314  /*
1315  *the pair (S[i],p) enters B if the spoly != 0
1316  */
1317  /*-  compute the short s-polynomial -*/
1318  if ((strat->S[i]==NULL) || (p==NULL))
1319  {
1320#ifdef KDEBUG
1321    if (TEST_OPT_DEBUG)
1322    {
1323      PrintS("--- spoly = NULL\n");
1324    }
1325#endif
1326    pLmDelete(Lp.lcm);
1327    return;
1328  }
1329  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (strat->fromQ[i]!=0))
1330  {
1331    // Is from a previous computed GB, therefore we know that spoly will
1332    // reduce to zero. Oliver.
1333    WarnS("Could we come here? 8738947389");
1334    Lp.p=NULL;
1335  }
1336  else
1337  {
1338    Lp.p = ksCreateShortSpoly(strat->S[i], p, strat->tailRing);
1339  }
1340  if (Lp.p == NULL)
1341  {
1342#ifdef KDEBUG
1343    if (TEST_OPT_DEBUG)
1344    {
1345      PrintS("--- spoly = NULL\n");
1346    }
1347#endif
1348    /*- the case that the s-poly is 0 -*/
1349    if (strat->pairtest==NULL) initPairtest(strat);
1350    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
1351    strat->pairtest[strat->sl+1] = TRUE;
1352    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
1353    /*
1354    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
1355    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
1356    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
1357    *term of p devides the lcm(s,r)
1358    *(this canceling should be done here because
1359    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
1360    *the first case is handeled in chainCrit
1361    */
1362    pLmDelete(Lp.lcm);
1363  }
1364  else
1365  {
1366    /*- the pair (S[i],p) enters B -*/
1367    Lp.p1 = strat->S[i];
1368    Lp.p2 = p;
1369
1370    pNext(Lp.p) = strat->tail;
1371
1372    if (atR >= 0)
1373    {
1374      Lp.i_r2 = atR;
1375      Lp.i_r1 = strat->S_2_R[i];
1376    }
1377    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
1378    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
1379    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
1380  }
1381}
1382
1383
1384/*2
1385* put the  lcm(s[i],p)  into the set B
1386*/
1387
1388BOOLEAN enterOneStrongPoly (int i,poly p,int /*ecart*/, int /*isFromQ*/,kStrategy strat, int atR = -1)
1389{
1390  number d, s, t;
1391  assume(i<=strat->sl);
1392  assume(atR >= 0);
1393  poly m1, m2, gcd;
1394
1395  d = n_ExtGcd(pGetCoeff(p), pGetCoeff(strat->S[i]), &s, &t, currRing->cf);
1396
1397  if (nIsZero(s) || nIsZero(t))  // evtl. durch divBy tests ersetzen
1398  {
1399    nDelete(&d);
1400    nDelete(&s);
1401    nDelete(&t);
1402    return FALSE;
1403  }
1404
1405  k_GetStrongLeadTerms(p, strat->S[i], currRing, m1, m2, gcd, strat->tailRing);
1406  //p_Test(m1,strat->tailRing);
1407  //p_Test(m2,strat->tailRing);
1408  while (! kCheckStrongCreation(atR, m1, i, m2, strat) )
1409  {
1410    memset(&(strat->P), 0, sizeof(strat->P));
1411    kStratChangeTailRing(strat);
1412    strat->P = *(strat->R[atR]);
1413    p_LmFree(m1, strat->tailRing);
1414    p_LmFree(m2, strat->tailRing);
1415    p_LmFree(gcd, currRing);
1416    k_GetStrongLeadTerms(p, strat->S[i], currRing, m1, m2, gcd, strat->tailRing);
1417  }
1418  pSetCoeff0(m1, s);
1419  pSetCoeff0(m2, t);
1420  pSetCoeff0(gcd, d);
1421  p_Test(m1,strat->tailRing);
1422  p_Test(m2,strat->tailRing);
1423
1424#ifdef KDEBUG
1425  if (TEST_OPT_DEBUG)
1426  {
1427    // Print("t = %d; s = %d; d = %d\n", nInt(t), nInt(s), nInt(d));
1428    PrintS("m1 = ");
1429    p_wrp(m1, strat->tailRing);
1430    PrintS(" ; m2 = ");
1431    p_wrp(m2, strat->tailRing);
1432    PrintS(" ; gcd = ");
1433    wrp(gcd);
1434    PrintS("\n--- create strong gcd poly: ");
1435    Print("\n p: ", i);
1436    wrp(p);
1437    Print("\n strat->S[%d]: ", i);
1438    wrp(strat->S[i]);
1439    PrintS(" ---> ");
1440  }
1441#endif
1442
1443  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);
1444  p_LmDelete(m1, strat->tailRing);
1445  p_LmDelete(m2, strat->tailRing);
1446
1447#ifdef KDEBUG
1448  if (TEST_OPT_DEBUG)
1449  {
1450    wrp(gcd);
1451    PrintLn();
1452  }
1453#endif
1454
1455  LObject h;
1456  h.p = gcd;
1457  h.tailRing = strat->tailRing;
1458  int posx;
1459  h.pCleardenom();
1460  strat->initEcart(&h);
1461  if (strat->Ll==-1)
1462    posx =0;
1463  else
1464    posx = strat->posInL(strat->L,strat->Ll,&h,strat);
1465  h.sev = pGetShortExpVector(h.p);
1466  if (currRing!=strat->tailRing)
1467    h.t_p = k_LmInit_currRing_2_tailRing(h.p, strat->tailRing);
1468  enterL(&strat->L,&strat->Ll,&strat->Lmax,h,posx);
1469  return TRUE;
1470}
1471#endif
1472
1473/*2
1474* put the pair (s[i],p)  into the set B, ecart=ecart(p)
1475*/
1476
1477void enterOnePairNormal (int i,poly p,int ecart, int isFromQ,kStrategy strat, int atR = -1)
1478{
1479  assume(i<=strat->sl);
1480  if (strat->interred_flag) return;
1481
1482  int      l,j,compare;
1483  LObject  Lp;
1484  Lp.i_r = -1;
1485
1486#ifdef KDEBUG
1487  Lp.ecart=0; Lp.length=0;
1488#endif
1489  /*- computes the lcm(s[i],p) -*/
1490  Lp.lcm = pInit();
1491
1492#ifndef HAVE_RATGRING
1493  pLcm(p,strat->S[i],Lp.lcm);
1494#elif defined(HAVE_RATGRING)
1495  //  if (rIsRatGRing(currRing))
1496  pLcmRat(p,strat->S[i],Lp.lcm, currRing->real_var_start); // int rat_shift
1497#endif
1498  pSetm(Lp.lcm);
1499
1500
1501  if (strat->sugarCrit && ALLOW_PROD_CRIT(strat))
1502  {
1503    if((!((strat->ecartS[i]>0)&&(ecart>0)))
1504    && pHasNotCF(p,strat->S[i]))
1505    {
1506    /*
1507    *the product criterion has applied for (s,p),
1508    *i.e. lcm(s,p)=product of the leading terms of s and p.
1509    *Suppose (s,r) is in L and the leading term
1510    *of p divides lcm(s,r)
1511    *(==> the leading term of p divides the leading term of r)
1512    *but the leading term of s does not divide the leading term of r
1513    *(notice that tis condition is automatically satisfied if r is still
1514    *in S), then (s,r) can be cancelled.
1515    *This should be done here because the
1516    *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
1517    *
1518    *Moreover, skipping (s,r) holds also for the noncommutative case.
1519    */
1520      strat->cp++;
1521      pLmFree(Lp.lcm);
1522      Lp.lcm=NULL;
1523      return;
1524    }
1525    else
1526      Lp.ecart = si_max(ecart,strat->ecartS[i]);
1527    if (strat->fromT && (strat->ecartS[i]>ecart))
1528    {
1529      pLmFree(Lp.lcm);
1530      Lp.lcm=NULL;
1531      return;
1532      /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
1533    }
1534    /*
1535    *the set B collects the pairs of type (S[j],p)
1536    *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
1537    *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
1538    *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
1539    */
1540    {
1541      j = strat->Bl;
1542      loop
1543      {
1544        if (j < 0)  break;
1545        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
1546        if ((compare==1)
1547        &&(sugarDivisibleBy(strat->B[j].ecart,Lp.ecart)))
1548        {
1549          strat->c3++;
1550          if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1551          {
1552            pLmFree(Lp.lcm);
1553            return;
1554          }
1555          break;
1556        }
1557        else
1558        if ((compare ==-1)
1559        && sugarDivisibleBy(Lp.ecart,strat->B[j].ecart))
1560        {
1561          deleteInL(strat->B,&strat->Bl,j,strat);
1562          strat->c3++;
1563        }
1564        j--;
1565      }
1566    }
1567  }
1568  else /*sugarcrit*/
1569  {
1570    if (ALLOW_PROD_CRIT(strat))
1571    {
1572      // if currRing->nc_type!=quasi (or skew)
1573      // TODO: enable productCrit for super commutative algebras...
1574      if(/*(strat->ak==0) && productCrit(p,strat->S[i])*/
1575      pHasNotCF(p,strat->S[i]))
1576      {
1577      /*
1578      *the product criterion has applied for (s,p),
1579      *i.e. lcm(s,p)=product of the leading terms of s and p.
1580      *Suppose (s,r) is in L and the leading term
1581      *of p devides lcm(s,r)
1582      *(==> the leading term of p devides the leading term of r)
1583      *but the leading term of s does not devide the leading term of r
1584      *(notice that tis condition is automatically satisfied if r is still
1585      *in S), then (s,r) can be canceled.
1586      *This should be done here because the
1587      *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
1588      */
1589          strat->cp++;
1590          pLmFree(Lp.lcm);
1591          Lp.lcm=NULL;
1592          return;
1593      }
1594      if (strat->fromT && (strat->ecartS[i]>ecart))
1595      {
1596        pLmFree(Lp.lcm);
1597        Lp.lcm=NULL;
1598        return;
1599        /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
1600      }
1601      /*
1602      *the set B collects the pairs of type (S[j],p)
1603      *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
1604      *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
1605      *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
1606      */
1607      for(j = strat->Bl;j>=0;j--)
1608      {
1609        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
1610        if (compare==1)
1611        {
1612          strat->c3++;
1613          if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1614          {
1615            pLmFree(Lp.lcm);
1616            return;
1617          }
1618          break;
1619        }
1620        else
1621        if (compare ==-1)
1622        {
1623          deleteInL(strat->B,&strat->Bl,j,strat);
1624          strat->c3++;
1625        }
1626      }
1627    }
1628  }
1629  /*
1630  *the pair (S[i],p) enters B if the spoly != 0
1631  */
1632  /*-  compute the short s-polynomial -*/
1633  if (strat->fromT && !TEST_OPT_INTSTRATEGY)
1634    pNorm(p);
1635
1636  if ((strat->S[i]==NULL) || (p==NULL))
1637    return;
1638
1639  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (strat->fromQ[i]!=0))
1640    Lp.p=NULL;
1641  else
1642  {
1643    #ifdef HAVE_PLURAL
1644    if ( rIsPluralRing(currRing) )
1645    {
1646      if(pHasNotCF(p, strat->S[i]))
1647      {
1648         if(ncRingType(currRing) == nc_lie)
1649         {
1650             // generalized prod-crit for lie-type
1651             strat->cp++;
1652             Lp.p = nc_p_Bracket_qq(pCopy(p),strat->S[i], currRing);
1653         }
1654         else
1655        if( ALLOW_PROD_CRIT(strat) )
1656        {
1657            // product criterion for homogeneous case in SCA
1658            strat->cp++;
1659            Lp.p = NULL;
1660        }
1661        else
1662        {
1663          Lp.p = // nc_CreateSpoly(strat->S[i],p,currRing);
1664                nc_CreateShortSpoly(strat->S[i], p, currRing);
1665
1666          assume(pNext(Lp.p)==NULL); // TODO: this may be violated whenever ext.prod.crit. for Lie alg. is used
1667          pNext(Lp.p) = strat->tail; // !!!
1668        }
1669      }
1670      else
1671      {
1672        Lp.p = // nc_CreateSpoly(strat->S[i],p,currRing);
1673              nc_CreateShortSpoly(strat->S[i], p, currRing);
1674
1675        assume(pNext(Lp.p)==NULL); // TODO: this may be violated whenever ext.prod.crit. for Lie alg. is used
1676        pNext(Lp.p) = strat->tail; // !!!
1677
1678      }
1679
1680
1681#if MYTEST
1682      if (TEST_OPT_DEBUG)
1683      {
1684        PrintS("enterOnePairNormal::\n strat->S[i]: "); pWrite(strat->S[i]);
1685        PrintS("p: "); pWrite(p);
1686        PrintS("SPoly: "); pWrite(Lp.p);
1687      }
1688#endif
1689
1690    }
1691    else
1692    #endif
1693    {
1694      assume(!rIsPluralRing(currRing));
1695      Lp.p = ksCreateShortSpoly(strat->S[i], p, strat->tailRing);
1696#if MYTEST
1697      if (TEST_OPT_DEBUG)
1698      {
1699        PrintS("enterOnePairNormal::\n strat->S[i]: "); pWrite(strat->S[i]);
1700        PrintS("p: "); pWrite(p);
1701        PrintS("commutative SPoly: "); pWrite(Lp.p);
1702      }
1703#endif
1704
1705      }
1706  }
1707  if (Lp.p == NULL)
1708  {
1709    /*- the case that the s-poly is 0 -*/
1710    if (strat->pairtest==NULL) initPairtest(strat);
1711    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
1712    strat->pairtest[strat->sl+1] = TRUE;
1713    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
1714    /*
1715    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
1716    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
1717    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
1718    *term of p devides the lcm(s,r)
1719    *(this canceling should be done here because
1720    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
1721    *the first case is handeled in chainCrit
1722    */
1723    if (Lp.lcm!=NULL) pLmFree(Lp.lcm);
1724  }
1725  else
1726  {
1727    /*- the pair (S[i],p) enters B -*/
1728    Lp.p1 = strat->S[i];
1729    Lp.p2 = p;
1730
1731    if (
1732        (!rIsPluralRing(currRing))
1733//      ||  (rIsPluralRing(currRing) && (ncRingType(currRing) != nc_lie))
1734       )
1735    {
1736      assume(pNext(Lp.p)==NULL); // TODO: this may be violated whenever ext.prod.crit. for Lie alg. is used
1737      pNext(Lp.p) = strat->tail; // !!!
1738    }
1739
1740    if (atR >= 0)
1741    {
1742      Lp.i_r1 = strat->S_2_R[i];
1743      Lp.i_r2 = atR;
1744    }
1745    else
1746    {
1747      Lp.i_r1 = -1;
1748      Lp.i_r2 = -1;
1749    }
1750    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
1751
1752    if (TEST_OPT_INTSTRATEGY)
1753    {
1754      if (!rIsPluralRing(currRing))
1755        nDelete(&(Lp.p->coef));
1756    }
1757
1758    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
1759    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
1760  }
1761}
1762
1763/*2
1764* put the pair (s[i],p)  into the set B, ecart=ecart(p)
1765* NOTE: here we need to add the signature-based criteria
1766*/
1767
1768#ifdef DEBUGF5
1769void enterOnePairSig (int i, poly p, poly pSig, int from, int ecart, int isFromQ, kStrategy strat, int atR = -1)
1770#else
1771void enterOnePairSig (int i, poly p, poly pSig, int, int ecart, int isFromQ, kStrategy strat, int atR = -1)
1772#endif
1773{
1774  assume(i<=strat->sl);
1775  if (strat->interred_flag) return;
1776
1777  int      l;
1778  poly m1 = NULL,m2 = NULL; // we need the multipliers for the s-polynomial to compute
1779              // the corresponding signatures for criteria checks
1780  LObject  Lp;
1781  // poly last;
1782  poly pSigMult = p_Copy(pSig,currRing);
1783  poly sSigMult = p_Copy(strat->sig[i],currRing);
1784  unsigned long pSigMultNegSev,sSigMultNegSev;
1785  Lp.i_r = -1;
1786
1787#ifdef KDEBUG
1788  Lp.ecart=0; Lp.length=0;
1789#endif
1790  /*- computes the lcm(s[i],p) -*/
1791  Lp.lcm = pInit();
1792  k_GetLeadTerms(p,strat->S[i],currRing,m1,m2,currRing);
1793#ifndef HAVE_RATGRING
1794  pLcm(p,strat->S[i],Lp.lcm);
1795#elif defined(HAVE_RATGRING)
1796  //  if (rIsRatGRing(currRing))
1797  pLcmRat(p,strat->S[i],Lp.lcm, currRing->real_var_start); // int rat_shift
1798#endif
1799  pSetm(Lp.lcm);
1800
1801  // set coeffs of multipliers m1 and m2
1802  pSetCoeff0(m1, nInit(1));
1803  pSetCoeff0(m2, nInit(1));
1804//#if 1
1805#ifdef DEBUGF5
1806  Print("P1  ");
1807  pWrite(pHead(p));
1808  Print("FROM: %d\n", from);
1809  Print("P2  ");
1810  pWrite(pHead(strat->S[i]));
1811  Print("FROM: %d\n", strat->fromS[i]);
1812  Print("M1  ");
1813  pWrite(m1);
1814  Print("M2  ");
1815  pWrite(m2);
1816#endif
1817  // get multiplied signatures for testing
1818  pSigMult = currRing->p_Procs->pp_Mult_mm(pSigMult,m1,currRing);
1819  pSigMultNegSev = ~p_GetShortExpVector(pSigMult,currRing);
1820  sSigMult = currRing->p_Procs->pp_Mult_mm(sSigMult,m2,currRing);
1821  sSigMultNegSev = ~p_GetShortExpVector(sSigMult,currRing);
1822
1823//#if 1
1824#ifdef DEBUGF5
1825  Print("----------------\n");
1826  pWrite(pSigMult);
1827  pWrite(sSigMult);
1828  Print("----------------\n");
1829#endif
1830  // testing by syzCrit = F5 Criterion
1831  // testing by rewCrit1 = Rewritten Criterion
1832  if  ( strat->syzCrit(pSigMult,pSigMultNegSev,strat) ||
1833        strat->syzCrit(sSigMult,sSigMultNegSev,strat)
1834        || strat->rewCrit1(sSigMult,sSigMultNegSev,strat,i+1)
1835      )
1836  {
1837    pDelete(&pSigMult);
1838    pDelete(&sSigMult);
1839    strat->cp++;
1840    pLmFree(Lp.lcm);
1841    Lp.lcm=NULL;
1842    pDelete (&m1);
1843    pDelete (&m2);
1844    return;
1845  }
1846  // in any case Lp is checked up to the next strat->P which is added
1847  // to S right after this critical pair creation.
1848  // NOTE: this even holds if the 2nd generator gives the bigger signature
1849  //       moreover, this improves rewCriterion,
1850  //       i.e. strat->checked > strat->from if and only if the 2nd generator
1851  //       gives the bigger signature.
1852  Lp.checked = strat->sl+1;
1853  int sigCmp = p_LmCmp(pSigMult,sSigMult,currRing);
1854//#if 1
1855#if DEBUGF5
1856  printf("IN PAIR GENERATION - COMPARING SIGS: %d\n",sigCmp);
1857  pWrite(pSigMult);
1858  pWrite(sSigMult);
1859#endif
1860  if(sigCmp==0)
1861  {
1862    // printf("!!!!   EQUAL SIGS   !!!!\n");
1863    // pSig = sSig, delete element due to Rewritten Criterion
1864    strat->cp++;
1865    pDelete(&pSigMult);
1866    pDelete(&sSigMult);
1867    pLmFree(Lp.lcm);
1868    Lp.lcm=NULL;
1869    pDelete (&m1);
1870    pDelete (&m2);
1871    return;
1872  }
1873  // at this point it is clear that the pair will be added to L, since it has
1874  // passed all tests up to now
1875
1876  // store from which element this pair comes from for further tests
1877  Lp.from = strat->sl+1;
1878  if(sigCmp==currRing->OrdSgn)
1879  {
1880    // pSig > sSig
1881    pDelete (&sSigMult);
1882    Lp.sig    = pSigMult;
1883    Lp.sevSig = ~pSigMultNegSev;
1884  }
1885  else
1886  {
1887    // pSig < sSig
1888    pDelete (&pSigMult);
1889    Lp.sig    = sSigMult;
1890    Lp.sevSig = ~sSigMultNegSev;
1891  }
1892// adds buchberger's first criterion
1893  if (pLmCmp(m2,pHead(p)) == 0) {
1894    Lp.prod_crit = TRUE; // Product Criterion
1895#if 0
1896    enterSyz(Lp, strat);
1897    Lp.lcm=NULL;
1898    pDelete (&m1);
1899    pDelete (&m2);
1900    return;
1901#endif
1902  }
1903  pDelete (&m1);
1904  pDelete (&m2);
1905#if DEBUGF5
1906  printf("SIGNATURE OF PAIR:  ");
1907  pWrite(Lp.sig);
1908#endif
1909  /*
1910  *the pair (S[i],p) enters B if the spoly != 0
1911  */
1912  /*-  compute the short s-polynomial -*/
1913  if (strat->fromT && !TEST_OPT_INTSTRATEGY)
1914    pNorm(p);
1915
1916  if ((strat->S[i]==NULL) || (p==NULL))
1917    return;
1918
1919  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (strat->fromQ[i]!=0))
1920    Lp.p=NULL;
1921  else
1922  {
1923    #ifdef HAVE_PLURAL
1924    if ( rIsPluralRing(currRing) )
1925    {
1926      if(pHasNotCF(p, strat->S[i]))
1927      {
1928         if(ncRingType(currRing) == nc_lie)
1929         {
1930             // generalized prod-crit for lie-type
1931             strat->cp++;
1932             Lp.p = nc_p_Bracket_qq(pCopy(p),strat->S[i], currRing);
1933         }
1934         else
1935        if( ALLOW_PROD_CRIT(strat) )
1936        {
1937            // product criterion for homogeneous case in SCA
1938            strat->cp++;
1939            Lp.p = NULL;
1940        }
1941        else
1942        {
1943          Lp.p = // nc_CreateSpoly(strat->S[i],p,currRing);
1944                nc_CreateShortSpoly(strat->S[i], p, currRing);
1945
1946          assume(pNext(Lp.p)==NULL); // TODO: this may be violated whenever ext.prod.crit. for Lie alg. is used
1947          pNext(Lp.p) = strat->tail; // !!!
1948        }
1949      }
1950      else
1951      {
1952        Lp.p = // nc_CreateSpoly(strat->S[i],p,currRing);
1953              nc_CreateShortSpoly(strat->S[i], p, currRing);
1954
1955        assume(pNext(Lp.p)==NULL); // TODO: this may be violated whenever ext.prod.crit. for Lie alg. is used
1956        pNext(Lp.p) = strat->tail; // !!!
1957
1958      }
1959
1960
1961#if MYTEST
1962      if (TEST_OPT_DEBUG)
1963      {
1964        PrintS("enterOnePairNormal::\n strat->S[i]: "); pWrite(strat->S[i]);
1965        PrintS("p: "); pWrite(p);
1966        PrintS("SPoly: "); pWrite(Lp.p);
1967      }
1968#endif
1969
1970    }
1971    else
1972    #endif
1973    {
1974      assume(!rIsPluralRing(currRing));
1975      Lp.p = ksCreateShortSpoly(strat->S[i], p, strat->tailRing);
1976#if MYTEST
1977      if (TEST_OPT_DEBUG)
1978      {
1979        PrintS("enterOnePairNormal::\n strat->S[i]: "); pWrite(strat->S[i]);
1980        PrintS("p: "); pWrite(p);
1981        PrintS("commutative SPoly: "); pWrite(Lp.p);
1982      }
1983#endif
1984
1985      }
1986  }
1987  if (Lp.p == NULL)
1988  {
1989    /*- the case that the s-poly is 0 -*/
1990    if (strat->pairtest==NULL) initPairtest(strat);
1991    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
1992    strat->pairtest[strat->sl+1] = TRUE;
1993    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
1994    /*
1995    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
1996    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
1997    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
1998    *term of p devides the lcm(s,r)
1999    *(this canceling should be done here because
2000    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
2001    *the first case is handeled in chainCrit
2002    */
2003    if (Lp.lcm!=NULL) pLmFree(Lp.lcm);
2004  }
2005  else
2006  {
2007    /*- the pair (S[i],p) enters B -*/
2008    Lp.p1 = strat->S[i];
2009    Lp.p2 = p;
2010
2011    if (
2012        (!rIsPluralRing(currRing))
2013//      ||  (rIsPluralRing(currRing) && (ncRingType(currRing) != nc_lie))
2014       )
2015    {
2016      assume(pNext(Lp.p)==NULL); // TODO: this may be violated whenever ext.prod.crit. for Lie alg. is used
2017      pNext(Lp.p) = strat->tail; // !!!
2018    }
2019
2020    if (atR >= 0)
2021    {
2022      Lp.i_r1 = strat->S_2_R[i];
2023      Lp.i_r2 = atR;
2024    }
2025    else
2026    {
2027      Lp.i_r1 = -1;
2028      Lp.i_r2 = -1;
2029    }
2030    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
2031
2032    if (TEST_OPT_INTSTRATEGY)
2033    {
2034      if (!rIsPluralRing(currRing))
2035        nDelete(&(Lp.p->coef));
2036    }
2037
2038    l = strat->posInLSba(strat->B,strat->Bl,&Lp,strat);
2039    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
2040  }
2041}
2042
2043/*2
2044* put the pair (s[i],p) into the set L, ecart=ecart(p)
2045* in the case that s forms a SB of (s)
2046*/
2047void enterOnePairSpecial (int i,poly p,int ecart,kStrategy strat, int atR = -1)
2048{
2049  //PrintS("try ");wrp(strat->S[i]);PrintS(" and ");wrp(p);PrintLn();
2050  if(pHasNotCF(p,strat->S[i]))
2051  {
2052    //PrintS("prod-crit\n");
2053    if(ALLOW_PROD_CRIT(strat))
2054    {
2055      //PrintS("prod-crit\n");
2056      strat->cp++;
2057      return;
2058    }
2059  }
2060
2061  int      l,j,compare;
2062  LObject  Lp;
2063  Lp.i_r = -1;
2064
2065  Lp.lcm = pInit();
2066  pLcm(p,strat->S[i],Lp.lcm);
2067  pSetm(Lp.lcm);
2068  for(j = strat->Ll;j>=0;j--)
2069  {
2070    compare=pDivComp(strat->L[j].lcm,Lp.lcm);
2071    if ((compare==1) || (pLmEqual(strat->L[j].lcm,Lp.lcm)))
2072    {
2073      //PrintS("c3-crit\n");
2074      strat->c3++;
2075      pLmFree(Lp.lcm);
2076      return;
2077    }
2078    else if (compare ==-1)
2079    {
2080      //Print("c3-crit with L[%d]\n",j);
2081      deleteInL(strat->L,&strat->Ll,j,strat);
2082      strat->c3++;
2083    }
2084  }
2085  /*-  compute the short s-polynomial -*/
2086
2087  #ifdef HAVE_PLURAL
2088  if (rIsPluralRing(currRing))
2089  {
2090    Lp.p = nc_CreateShortSpoly(strat->S[i],p, currRing); // ??? strat->tailRing?
2091  }
2092  else
2093  #endif
2094    Lp.p = ksCreateShortSpoly(strat->S[i],p,strat->tailRing);
2095
2096  if (Lp.p == NULL)
2097  {
2098     //PrintS("short spoly==NULL\n");
2099     pLmFree(Lp.lcm);
2100  }
2101  else
2102  {
2103    /*- the pair (S[i],p) enters L -*/
2104    Lp.p1 = strat->S[i];
2105    Lp.p2 = p;
2106    if (atR >= 0)
2107    {
2108      Lp.i_r1 = strat->S_2_R[i];
2109      Lp.i_r2 = atR;
2110    }
2111    else
2112    {
2113      Lp.i_r1 = -1;
2114      Lp.i_r2 = -1;
2115    }
2116    assume(pNext(Lp.p) == NULL);
2117    pNext(Lp.p) = strat->tail;
2118    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
2119    if (TEST_OPT_INTSTRATEGY)
2120    {
2121      nDelete(&(Lp.p->coef));
2122    }
2123    l = strat->posInL(strat->L,strat->Ll,&Lp,strat);
2124    //Print("-> L[%d]\n",l);
2125    enterL(&strat->L,&strat->Ll,&strat->Lmax,Lp,l);
2126  }
2127}
2128
2129/*2
2130* merge set B into L
2131*/
2132void kMergeBintoL(kStrategy strat)
2133{
2134  int j=strat->Ll+strat->Bl+1;
2135  if (j>strat->Lmax)
2136  {
2137    j=((j+setmaxLinc-1)/setmaxLinc)*setmaxLinc;
2138    strat->L = (LSet)omReallocSize(strat->L,strat->Lmax*sizeof(LObject),
2139                                 j*sizeof(LObject));
2140    strat->Lmax=j;
2141  }
2142  j = strat->Ll;
2143  int i;
2144  for (i=strat->Bl; i>=0; i--)
2145  {
2146    j = strat->posInL(strat->L,j,&(strat->B[i]),strat);
2147    enterL(&strat->L,&strat->Ll,&strat->Lmax,strat->B[i],j);
2148  }
2149  strat->Bl = -1;
2150}
2151
2152/*2
2153* merge set B into L
2154*/
2155void kMergeBintoLSba(kStrategy strat)
2156{
2157  int j=strat->Ll+strat->Bl+1;
2158  if (j>strat->Lmax)
2159  {
2160    j=((j+setmaxLinc-1)/setmaxLinc)*setmaxLinc;
2161    strat->L = (LSet)omReallocSize(strat->L,strat->Lmax*sizeof(LObject),
2162                                 j*sizeof(LObject));
2163    strat->Lmax=j;
2164  }
2165  j = strat->Ll;
2166  int i;
2167  for (i=strat->Bl; i>=0; i--)
2168  {
2169    j = strat->posInLSba(strat->L,j,&(strat->B[i]),strat);
2170    enterL(&strat->L,&strat->Ll,&strat->Lmax,strat->B[i],j);
2171  }
2172  strat->Bl = -1;
2173}
2174/*2
2175*the pairset B of pairs of type (s[i],p) is complete now. It will be updated
2176*using the chain-criterion in B and L and enters B to L
2177*/
2178void chainCritNormal (poly p,int ecart,kStrategy strat)
2179{
2180  int i,j,l;
2181
2182  /*
2183  *pairtest[i] is TRUE if spoly(S[i],p) == 0.
2184  *In this case all elements in B such
2185  *that their lcm is divisible by the leading term of S[i] can be canceled
2186  */
2187  if (strat->pairtest!=NULL)
2188  {
2189    {
2190      /*- i.e. there is an i with pairtest[i]==TRUE -*/
2191      for (j=0; j<=strat->sl; j++)
2192      {
2193        if (strat->pairtest[j])
2194        {
2195          for (i=strat->Bl; i>=0; i--)
2196          {
2197            if (pDivisibleBy(strat->S[j],strat->B[i].lcm))
2198            {
2199              deleteInL(strat->B,&strat->Bl,i,strat);
2200              strat->c3++;
2201            }
2202          }
2203        }
2204      }
2205    }
2206    omFreeSize(strat->pairtest,(strat->sl+2)*sizeof(BOOLEAN));
2207    strat->pairtest=NULL;
2208  }
2209  if (strat->Gebauer || strat->fromT)
2210  {
2211    if (strat->sugarCrit)
2212    {
2213    /*
2214    *suppose L[j] == (s,r) and p/lcm(s,r)
2215    *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
2216    *and in case the sugar is o.k. then L[j] can be canceled
2217    */
2218      for (j=strat->Ll; j>=0; j--)
2219      {
2220        if (sugarDivisibleBy(ecart,strat->L[j].ecart)
2221        && ((pNext(strat->L[j].p) == strat->tail) || (currRing->OrdSgn==1))
2222        && pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
2223        {
2224          if (strat->L[j].p == strat->tail)
2225          {
2226              deleteInL(strat->L,&strat->Ll,j,strat);
2227              strat->c3++;
2228          }
2229        }
2230      }
2231      /*
2232      *this is GEBAUER-MOELLER:
2233      *in B all elements with the same lcm except the "best"
2234      *(i.e. the last one in B with this property) will be canceled
2235      */
2236      j = strat->Bl;
2237      loop /*cannot be changed into a for !!! */
2238      {
2239        if (j <= 0) break;
2240        i = j-1;
2241        loop
2242        {
2243          if (i <  0) break;
2244          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
2245          {
2246            strat->c3++;
2247            if (sugarDivisibleBy(strat->B[j].ecart,strat->B[i].ecart))
2248            {
2249              deleteInL(strat->B,&strat->Bl,i,strat);
2250              j--;
2251            }
2252            else
2253            {
2254              deleteInL(strat->B,&strat->Bl,j,strat);
2255              break;
2256            }
2257          }
2258          i--;
2259        }
2260        j--;
2261      }
2262    }
2263    else /*sugarCrit*/
2264    {
2265      /*
2266      *suppose L[j] == (s,r) and p/lcm(s,r)
2267      *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
2268      *and in case the sugar is o.k. then L[j] can be canceled
2269      */
2270      for (j=strat->Ll; j>=0; j--)
2271      {
2272        if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
2273        {
2274          if ((pNext(strat->L[j].p) == strat->tail)||(currRing->OrdSgn==1))
2275          {
2276            deleteInL(strat->L,&strat->Ll,j,strat);
2277            strat->c3++;
2278          }
2279        }
2280      }
2281      /*
2282      *this is GEBAUER-MOELLER:
2283      *in B all elements with the same lcm except the "best"
2284      *(i.e. the last one in B with this property) will be canceled
2285      */
2286      j = strat->Bl;
2287      loop   /*cannot be changed into a for !!! */
2288      {
2289        if (j <= 0) break;
2290        for(i=j-1; i>=0; i--)
2291        {
2292          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
2293          {
2294            strat->c3++;
2295            deleteInL(strat->B,&strat->Bl,i,strat);
2296            j--;
2297          }
2298        }
2299        j--;
2300      }
2301    }
2302    /*
2303    *the elements of B enter L
2304    */
2305    kMergeBintoL(strat);
2306  }
2307  else
2308  {
2309    for (j=strat->Ll; j>=0; j--)
2310    {
2311      if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
2312      {
2313        if ((pNext(strat->L[j].p) == strat->tail)||(currRing->OrdSgn==1))
2314        {
2315          deleteInL(strat->L,&strat->Ll,j,strat);
2316          strat->c3++;
2317        }
2318      }
2319    }
2320    /*
2321    *this is our MODIFICATION of GEBAUER-MOELLER:
2322    *First the elements of B enter L,
2323    *then we fix a lcm and the "best" element in L
2324    *(i.e the last in L with this lcm and of type (s,p))
2325    *and cancel all the other elements of type (r,p) with this lcm
2326    *except the case the element (s,r) has also the same lcm
2327    *and is on the worst position with respect to (s,p) and (r,p)
2328    */
2329    /*
2330    *B enters to L/their order with respect to B is permutated for elements
2331    *B[i].p with the same leading term
2332    */
2333    kMergeBintoL(strat);
2334    j = strat->Ll;
2335    loop  /*cannot be changed into a for !!! */
2336    {
2337      if (j <= 0)
2338      {
2339        /*now L[0] cannot be canceled any more and the tail can be removed*/
2340        if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
2341        break;
2342      }
2343      if (strat->L[j].p2 == p)
2344      {
2345        i = j-1;
2346        loop
2347        {
2348          if (i < 0)  break;
2349          if ((strat->L[i].p2 == p) && pLmEqual(strat->L[j].lcm,strat->L[i].lcm))
2350          {
2351            /*L[i] could be canceled but we search for a better one to cancel*/
2352            strat->c3++;
2353            if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
2354            && (pNext(strat->L[l].p) == strat->tail)
2355            && (!pLmEqual(strat->L[i].p,strat->L[l].p))
2356            && pDivisibleBy(p,strat->L[l].lcm))
2357            {
2358              /*
2359              *"NOT equal(...)" because in case of "equal" the element L[l]
2360              *is "older" and has to be from theoretical point of view behind
2361              *L[i], but we do not want to reorder L
2362              */
2363              strat->L[i].p2 = strat->tail;
2364              /*
2365              *L[l] will be canceled, we cannot cancel L[i] later on,
2366              *so we mark it with "tail"
2367              */
2368              deleteInL(strat->L,&strat->Ll,l,strat);
2369              i--;
2370            }
2371            else
2372            {
2373              deleteInL(strat->L,&strat->Ll,i,strat);
2374            }
2375            j--;
2376          }
2377          i--;
2378        }
2379      }
2380      else if (strat->L[j].p2 == strat->tail)
2381      {
2382        /*now L[j] cannot be canceled any more and the tail can be removed*/
2383        strat->L[j].p2 = p;
2384      }
2385      j--;
2386    }
2387  }
2388}
2389/*2
2390*the pairset B of pairs of type (s[i],p) is complete now. It will be updated
2391*using the chain-criterion in B and L and enters B to L
2392*/
2393void chainCritSig (poly p,int /*ecart*/,kStrategy strat)
2394{
2395  int i,j,l;
2396  kMergeBintoLSba(strat);
2397  j = strat->Ll;
2398  loop  /*cannot be changed into a for !!! */
2399  {
2400    if (j <= 0)
2401    {
2402      /*now L[0] cannot be canceled any more and the tail can be removed*/
2403      if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
2404      break;
2405    }
2406    if (strat->L[j].p2 == p)
2407    {
2408      i = j-1;
2409      loop
2410      {
2411        if (i < 0)  break;
2412        if ((strat->L[i].p2 == p) && pLmEqual(strat->L[j].lcm,strat->L[i].lcm))
2413        {
2414          /*L[i] could be canceled but we search for a better one to cancel*/
2415          strat->c3++;
2416          if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
2417              && (pNext(strat->L[l].p) == strat->tail)
2418              && (!pLmEqual(strat->L[i].p,strat->L[l].p))
2419              && pDivisibleBy(p,strat->L[l].lcm))
2420          {
2421            /*
2422             *"NOT equal(...)" because in case of "equal" the element L[l]
2423             *is "older" and has to be from theoretical point of view behind
2424             *L[i], but we do not want to reorder L
2425             */
2426            strat->L[i].p2 = strat->tail;
2427            /*
2428             *L[l] will be canceled, we cannot cancel L[i] later on,
2429             *so we mark it with "tail"
2430             */
2431            deleteInL(strat->L,&strat->Ll,l,strat);
2432            i--;
2433          }
2434          else
2435          {
2436            deleteInL(strat->L,&strat->Ll,i,strat);
2437          }
2438          j--;
2439        }
2440        i--;
2441      }
2442    }
2443    else if (strat->L[j].p2 == strat->tail)
2444    {
2445      /*now L[j] cannot be canceled any more and the tail can be removed*/
2446      strat->L[j].p2 = p;
2447    }
2448    j--;
2449  }
2450}
2451#ifdef HAVE_RATGRING
2452void chainCritPart (poly p,int ecart,kStrategy strat)
2453{
2454  int i,j,l;
2455
2456  /*
2457  *pairtest[i] is TRUE if spoly(S[i],p) == 0.
2458  *In this case all elements in B such
2459  *that their lcm is divisible by the leading term of S[i] can be canceled
2460  */
2461  if (strat->pairtest!=NULL)
2462  {
2463    {
2464      /*- i.e. there is an i with pairtest[i]==TRUE -*/
2465      for (j=0; j<=strat->sl; j++)
2466      {
2467        if (strat->pairtest[j])
2468        {
2469          for (i=strat->Bl; i>=0; i--)
2470          {
2471            if (_p_LmDivisibleByPart(strat->S[j],currRing,
2472               strat->B[i].lcm,currRing,
2473               currRing->real_var_start,currRing->real_var_end))
2474            {
2475              if(TEST_OPT_DEBUG)
2476              {
2477                 Print("chain-crit-part: S[%d]=",j);
2478                 p_wrp(strat->S[j],currRing);
2479                 Print(" divide B[%d].lcm=",i);
2480                 p_wrp(strat->B[i].lcm,currRing);
2481                 PrintLn();
2482              }
2483              deleteInL(strat->B,&strat->Bl,i,strat);
2484              strat->c3++;
2485            }
2486          }
2487        }
2488      }
2489    }
2490    omFreeSize(strat->pairtest,(strat->sl+2)*sizeof(BOOLEAN));
2491    strat->pairtest=NULL;
2492  }
2493  if (strat->Gebauer || strat->fromT)
2494  {
2495    if (strat->sugarCrit)
2496    {
2497    /*
2498    *suppose L[j] == (s,r) and p/lcm(s,r)
2499    *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
2500    *and in case the sugar is o.k. then L[j] can be canceled
2501    */
2502      for (j=strat->Ll; j>=0; j--)
2503      {
2504        if (sugarDivisibleBy(ecart,strat->L[j].ecart)
2505        && ((pNext(strat->L[j].p) == strat->tail) || (currRing->OrdSgn==1))
2506        && pCompareChainPart(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
2507        {
2508          if (strat->L[j].p == strat->tail)
2509          {
2510              if(TEST_OPT_DEBUG)
2511              {
2512                 PrintS("chain-crit-part: pCompareChainPart p=");
2513                 p_wrp(p,currRing);
2514                 Print(" delete L[%d]",j);
2515                 p_wrp(strat->L[j].lcm,currRing);
2516                 PrintLn();
2517              }
2518              deleteInL(strat->L,&strat->Ll,j,strat);
2519              strat->c3++;
2520          }
2521        }
2522      }
2523      /*
2524      *this is GEBAUER-MOELLER:
2525      *in B all elements with the same lcm except the "best"
2526      *(i.e. the last one in B with this property) will be canceled
2527      */
2528      j = strat->Bl;
2529      loop /*cannot be changed into a for !!! */
2530      {
2531        if (j <= 0) break;
2532        i = j-1;
2533        loop
2534        {
2535          if (i <  0) break;
2536          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
2537          {
2538            strat->c3++;
2539            if (sugarDivisibleBy(strat->B[j].ecart,strat->B[i].ecart))
2540            {
2541              if(TEST_OPT_DEBUG)
2542              {
2543                 Print("chain-crit-part: sugar B[%d].lcm=",j);
2544                 p_wrp(strat->B[j].lcm,currRing);
2545                 Print(" delete B[%d]",i);
2546                 p_wrp(strat->B[i].lcm,currRing);
2547                 PrintLn();
2548              }
2549              deleteInL(strat->B,&strat->Bl,i,strat);
2550              j--;
2551            }
2552            else
2553            {
2554              if(TEST_OPT_DEBUG)
2555              {
2556                 Print("chain-crit-part: sugar B[%d].lcm=",i);
2557                 p_wrp(strat->B[i].lcm,currRing);
2558                 Print(" delete B[%d]",j);
2559                 p_wrp(strat->B[j].lcm,currRing);
2560                 PrintLn();
2561              }
2562              deleteInL(strat->B,&strat->Bl,j,strat);
2563              break;
2564            }
2565          }
2566          i--;
2567        }
2568        j--;
2569      }
2570    }
2571    else /*sugarCrit*/
2572    {
2573      /*
2574      *suppose L[j] == (s,r) and p/lcm(s,r)
2575      *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
2576      *and in case the sugar is o.k. then L[j] can be canceled
2577      */
2578      for (j=strat->Ll; j>=0; j--)
2579      {
2580        if (pCompareChainPart(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
2581        {
2582          if ((pNext(strat->L[j].p) == strat->tail)||(currRing->OrdSgn==1))
2583          {
2584              if(TEST_OPT_DEBUG)
2585              {
2586                 PrintS("chain-crit-part: sugar:pCompareChainPart p=");
2587                 p_wrp(p,currRing);
2588                 Print(" delete L[%d]",j);
2589                 p_wrp(strat->L[j].lcm,currRing);
2590                 PrintLn();
2591              }
2592            deleteInL(strat->L,&strat->Ll,j,strat);
2593            strat->c3++;
2594          }
2595        }
2596      }
2597      /*
2598      *this is GEBAUER-MOELLER:
2599      *in B all elements with the same lcm except the "best"
2600      *(i.e. the last one in B with this property) will be canceled
2601      */
2602      j = strat->Bl;
2603      loop   /*cannot be changed into a for !!! */
2604      {
2605        if (j <= 0) break;
2606        for(i=j-1; i>=0; i--)
2607        {
2608          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
2609          {
2610              if(TEST_OPT_DEBUG)
2611              {
2612                 Print("chain-crit-part: equal lcm B[%d].lcm=",j);
2613                 p_wrp(strat->B[j].lcm,currRing);
2614                 Print(" delete B[%d]\n",i);
2615              }
2616            strat->c3++;
2617            deleteInL(strat->B,&strat->Bl,i,strat);
2618            j--;
2619          }
2620        }
2621        j--;
2622      }
2623    }
2624    /*
2625    *the elements of B enter L
2626    */
2627    kMergeBintoL(strat);
2628  }
2629  else
2630  {
2631    for (j=strat->Ll; j>=0; j--)
2632    {
2633      if (pCompareChainPart(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
2634      {
2635        if ((pNext(strat->L[j].p) == strat->tail)||(currRing->OrdSgn==1))
2636        {
2637              if(TEST_OPT_DEBUG)
2638              {
2639                 PrintS("chain-crit-part: pCompareChainPart p=");
2640                 p_wrp(p,currRing);
2641                 Print(" delete L[%d]",j);
2642                 p_wrp(strat->L[j].lcm,currRing);
2643                 PrintLn();
2644              }
2645          deleteInL(strat->L,&strat->Ll,j,strat);
2646          strat->c3++;
2647        }
2648      }
2649    }
2650    /*
2651    *this is our MODIFICATION of GEBAUER-MOELLER:
2652    *First the elements of B enter L,
2653    *then we fix a lcm and the "best" element in L
2654    *(i.e the last in L with this lcm and of type (s,p))
2655    *and cancel all the other elements of type (r,p) with this lcm
2656    *except the case the element (s,r) has also the same lcm
2657    *and is on the worst position with respect to (s,p) and (r,p)
2658    */
2659    /*
2660    *B enters to L/their order with respect to B is permutated for elements
2661    *B[i].p with the same leading term
2662    */
2663    kMergeBintoL(strat);
2664    j = strat->Ll;
2665    loop  /*cannot be changed into a for !!! */
2666    {
2667      if (j <= 0)
2668      {
2669        /*now L[0] cannot be canceled any more and the tail can be removed*/
2670        if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
2671        break;
2672      }
2673      if (strat->L[j].p2 == p)
2674      {
2675        i = j-1;
2676        loop
2677        {
2678          if (i < 0)  break;
2679          if ((strat->L[i].p2 == p) && pLmEqual(strat->L[j].lcm,strat->L[i].lcm))
2680          {
2681            /*L[i] could be canceled but we search for a better one to cancel*/
2682            strat->c3++;
2683            if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
2684            && (pNext(strat->L[l].p) == strat->tail)
2685            && (!pLmEqual(strat->L[i].p,strat->L[l].p))
2686            && _p_LmDivisibleByPart(p,currRing,
2687                           strat->L[l].lcm,currRing,
2688                           currRing->real_var_start, currRing->real_var_end))
2689
2690            {
2691              /*
2692              *"NOT equal(...)" because in case of "equal" the element L[l]
2693              *is "older" and has to be from theoretical point of view behind
2694              *L[i], but we do not want to reorder L
2695              */
2696              strat->L[i].p2 = strat->tail;
2697              /*
2698              *L[l] will be canceled, we cannot cancel L[i] later on,
2699              *so we mark it with "tail"
2700              */
2701              if(TEST_OPT_DEBUG)
2702              {
2703                 PrintS("chain-crit-part: divisible_by p=");
2704                 p_wrp(p,currRing);
2705                 Print(" delete L[%d]",l);
2706                 p_wrp(strat->L[l].lcm,currRing);
2707                 PrintLn();
2708              }
2709              deleteInL(strat->L,&strat->Ll,l,strat);
2710              i--;
2711            }
2712            else
2713            {
2714              if(TEST_OPT_DEBUG)
2715              {
2716                 PrintS("chain-crit-part: divisible_by(2) p=");
2717                 p_wrp(p,currRing);
2718                 Print(" delete L[%d]",i);
2719                 p_wrp(strat->L[i].lcm,currRing);
2720                 PrintLn();
2721              }
2722              deleteInL(strat->L,&strat->Ll,i,strat);
2723            }
2724            j--;
2725          }
2726          i--;
2727        }
2728      }
2729      else if (strat->L[j].p2 == strat->tail)
2730      {
2731        /*now L[j] cannot be canceled any more and the tail can be removed*/
2732        strat->L[j].p2 = p;
2733      }
2734      j--;
2735    }
2736  }
2737}
2738#endif
2739
2740/*2
2741*(s[0],h),...,(s[k],h) will be put to the pairset L
2742*/
2743void initenterpairs (poly h,int k,int ecart,int isFromQ,kStrategy strat, int atR = -1)
2744{
2745
2746  if ((strat->syzComp==0)
2747  || (pGetComp(h)<=strat->syzComp))
2748  {
2749    int j;
2750    BOOLEAN new_pair=FALSE;
2751
2752    if (pGetComp(h)==0)
2753    {
2754      /* for Q!=NULL: build pairs (f,q),(f1,f2), but not (q1,q2)*/
2755      if ((isFromQ)&&(strat->fromQ!=NULL))
2756      {
2757        for (j=0; j<=k; j++)
2758        {
2759          if (!strat->fromQ[j])
2760          {
2761            new_pair=TRUE;
2762            strat->enterOnePair(j,h,ecart,isFromQ,strat, atR);
2763          //Print("j:%d, Ll:%d\n",j,strat->Ll);
2764          }
2765        }
2766      }
2767      else
2768      {
2769        new_pair=TRUE;
2770        for (j=0; j<=k; j++)
2771        {
2772        #if ADIDEBUG
2773        PrintS("\n initenterpairs: \n");
2774        PrintS("                ");p_Write(h, strat->tailRing);
2775        PrintS("                ");p_Write(strat->S[j],strat->tailRing);
2776        #endif
2777          strat->enterOnePair(j,h,ecart,isFromQ,strat, atR);
2778          //Print("j:%d, Ll:%d\n",j,strat->Ll);
2779        }
2780      }
2781    }
2782    else
2783    {
2784      for (j=0; j<=k; j++)
2785      {
2786        if ((pGetComp(h)==pGetComp(strat->S[j]))
2787        || (pGetComp(strat->S[j])==0))
2788        {
2789          new_pair=TRUE;
2790          strat->enterOnePair(j,h,ecart,isFromQ,strat, atR);
2791        //Print("j:%d, Ll:%d\n",j,strat->Ll);
2792        }
2793      }
2794    }
2795
2796    if (new_pair)
2797    {
2798#ifdef HAVE_RATGRING
2799      if (currRing->real_var_start>0)
2800        chainCritPart(h,ecart,strat);
2801      else
2802#endif
2803      strat->chainCrit(h,ecart,strat);
2804    }
2805  }
2806}
2807
2808/*2
2809*(s[0],h),...,(s[k],h) will be put to the pairset L
2810*using signatures <= only for signature-based standard basis algorithms
2811*/
2812void initenterpairsSig (poly h,poly hSig,int hFrom,int k,int ecart,int isFromQ,kStrategy strat, int atR = -1)
2813{
2814
2815  if ((strat->syzComp==0)
2816  || (pGetComp(h)<=strat->syzComp))
2817  {
2818    int j;
2819    BOOLEAN new_pair=FALSE;
2820
2821    if (pGetComp(h)==0)
2822    {
2823      /* for Q!=NULL: build pairs (f,q),(f1,f2), but not (q1,q2)*/
2824      if ((isFromQ)&&(strat->fromQ!=NULL))
2825      {
2826        for (j=0; j<=k; j++)
2827        {
2828          if (!strat->fromQ[j])
2829          {
2830            new_pair=TRUE;
2831            enterOnePairSig(j,h,hSig,hFrom,ecart,isFromQ,strat, atR);
2832          //Print("j:%d, Ll:%d\n",j,strat->Ll);
2833          }
2834        }
2835      }
2836      else
2837      {
2838        new_pair=TRUE;
2839        for (j=0; j<=k; j++)
2840        {
2841          enterOnePairSig(j,h,hSig,hFrom,ecart,isFromQ,strat, atR);
2842          //Print("j:%d, Ll:%d\n",j,strat->Ll);
2843        }
2844      }
2845    }
2846    else
2847    {
2848      for (j=0; j<=k; j++)
2849      {
2850        if ((pGetComp(h)==pGetComp(strat->S[j]))
2851        || (pGetComp(strat->S[j])==0))
2852        {
2853          new_pair=TRUE;
2854          enterOnePairSig(j,h,hSig,hFrom,ecart,isFromQ,strat, atR);
2855        //Print("j:%d, Ll:%d\n",j,strat->Ll);
2856        }
2857      }
2858    }
2859
2860    if (new_pair)
2861    {
2862#ifdef HAVE_RATGRING
2863      if (currRing->real_var_start>0)
2864        chainCritPart(h,ecart,strat);
2865      else
2866#endif
2867      strat->chainCrit(h,ecart,strat);
2868    }
2869  }
2870}
2871
2872#ifdef HAVE_RINGS
2873/*2
2874*the pairset B of pairs of type (s[i],p) is complete now. It will be updated
2875*using the chain-criterion in B and L and enters B to L
2876*/
2877void chainCritRing (poly p,int, kStrategy strat)
2878{
2879  int i,j,l;
2880  /*
2881  *pairtest[i] is TRUE if spoly(S[i],p) == 0.
2882  *In this case all elements in B such
2883  *that their lcm is divisible by the leading term of S[i] can be canceled
2884  */
2885  if (strat->pairtest!=NULL)
2886  {
2887    {
2888      /*- i.e. there is an i with pairtest[i]==TRUE -*/
2889      for (j=0; j<=strat->sl; j++)
2890      {
2891        if (strat->pairtest[j])
2892        {
2893          for (i=strat->Bl; i>=0; i--)
2894          {
2895            if (pDivisibleBy(strat->S[j],strat->B[i].lcm))
2896            {
2897#ifdef KDEBUG
2898              if (TEST_OPT_DEBUG)
2899              {
2900                PrintS("--- chain criterion func chainCritRing type 1\n");
2901                PrintS("strat->S[j]:");
2902                wrp(strat->S[j]);
2903                PrintS("  strat->B[i].lcm:");
2904                wrp(strat->B[i].lcm);
2905                PrintLn();
2906              }
2907#endif
2908              deleteInL(strat->B,&strat->Bl,i,strat);
2909              strat->c3++;
2910            }
2911          }
2912        }
2913      }
2914    }
2915    omFreeSize(strat->pairtest,(strat->sl+2)*sizeof(BOOLEAN));
2916    strat->pairtest=NULL;
2917  }
2918  assume(!(strat->Gebauer || strat->fromT));
2919  for (j=strat->Ll; j>=0; j--)
2920  {
2921    if ((strat->L[j].lcm != NULL) && n_DivBy(pGetCoeff(strat->L[j].lcm), pGetCoeff(p), currRing->cf))
2922    {
2923      if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
2924      {
2925        if ((pNext(strat->L[j].p) == strat->tail) || (currRing->OrdSgn==1))
2926        {
2927          deleteInL(strat->L,&strat->Ll,j,strat);
2928          strat->c3++;
2929#ifdef KDEBUG
2930              if (TEST_OPT_DEBUG)
2931              {
2932                PrintS("--- chain criterion func chainCritRing type 2\n");
2933                PrintS("strat->L[j].p:");
2934                wrp(strat->L[j].p);
2935                PrintS("  p:");
2936                wrp(p);
2937                PrintLn();
2938              }
2939#endif
2940        }
2941      }
2942    }
2943  }
2944  /*
2945  *this is our MODIFICATION of GEBAUER-MOELLER:
2946  *First the elements of B enter L,
2947  *then we fix a lcm and the "best" element in L
2948  *(i.e the last in L with this lcm and of type (s,p))
2949  *and cancel all the other elements of type (r,p) with this lcm
2950  *except the case the element (s,r) has also the same lcm
2951  *and is on the worst position with respect to (s,p) and (r,p)
2952  */
2953  /*
2954  *B enters to L/their order with respect to B is permutated for elements
2955  *B[i].p with the same leading term
2956  */
2957  kMergeBintoL(strat);
2958  j = strat->Ll;
2959  loop  /*cannot be changed into a for !!! */
2960  {
2961    if (j <= 0)
2962    {
2963      /*now L[0] cannot be canceled any more and the tail can be removed*/
2964      if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
2965      break;
2966    }
2967    if (strat->L[j].p2 == p) // Was the element added from B?
2968    {
2969      i = j-1;
2970      loop
2971      {
2972        if (i < 0)  break;
2973        // Element is from B and has the same lcm as L[j]
2974        if ((strat->L[i].p2 == p) && n_DivBy(pGetCoeff(strat->L[j].lcm), pGetCoeff(strat->L[i].lcm), currRing->cf)
2975             && pLmEqual(strat->L[j].lcm,strat->L[i].lcm))
2976        {
2977          /*L[i] could be canceled but we search for a better one to cancel*/
2978          strat->c3++;
2979#ifdef KDEBUG
2980          if (TEST_OPT_DEBUG)
2981          {
2982            PrintS("--- chain criterion func chainCritRing type 3\n");
2983            PrintS("strat->L[j].lcm:");
2984            wrp(strat->L[j].lcm);
2985            PrintS("  strat->L[i].lcm:");
2986            wrp(strat->L[i].lcm);
2987            PrintLn();
2988          }
2989#endif
2990          if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
2991          && (pNext(strat->L[l].p) == strat->tail)
2992          && (!pLmEqual(strat->L[i].p,strat->L[l].p))
2993          && pDivisibleBy(p,strat->L[l].lcm))
2994          {
2995            /*
2996            *"NOT equal(...)" because in case of "equal" the element L[l]
2997            *is "older" and has to be from theoretical point of view behind
2998            *L[i], but we do not want to reorder L
2999            */
3000            strat->L[i].p2 = strat->tail;
3001            /*
3002            *L[l] will be canceled, we cannot cancel L[i] later on,
3003            *so we mark it with "tail"
3004            */
3005            deleteInL(strat->L,&strat->Ll,l,strat);
3006            i--;
3007          }
3008          else
3009          {
3010            deleteInL(strat->L,&strat->Ll,i,strat);
3011          }
3012          j--;
3013        }
3014        i--;
3015      }
3016    }
3017    else if (strat->L[j].p2 == strat->tail)
3018    {
3019      /*now L[j] cannot be canceled any more and the tail can be removed*/
3020      strat->L[j].p2 = p;
3021    }
3022    j--;
3023  }
3024}
3025#endif
3026
3027#ifdef HAVE_RINGS
3028long ind2(long arg)
3029{
3030  long ind = 0;
3031  if (arg <= 0) return 0;
3032  while (arg%2 == 0)
3033  {
3034    arg = arg / 2;
3035    ind++;
3036  }
3037  return ind;
3038}
3039
3040long ind_fact_2(long arg)
3041{
3042  long ind = 0;
3043  if (arg <= 0) return 0;
3044  if (arg%2 == 1) { arg--; }
3045  while (arg > 0)
3046  {
3047    ind += ind2(arg);
3048    arg = arg - 2;
3049  }
3050  return ind;
3051}
3052#endif
3053
3054#ifdef HAVE_VANIDEAL
3055long twoPow(long arg)
3056{
3057  return 1L << arg;
3058}
3059
3060/*2
3061* put the pair (p, f) in B and f in T
3062*/
3063void enterOneZeroPairRing (poly f, poly t_p, poly p, int ecart, kStrategy strat, int atR = -1)
3064{
3065  int      l,j,compare,compareCoeff;
3066  LObject  Lp;
3067
3068  if (strat->interred_flag) return;
3069#ifdef KDEBUG
3070  Lp.ecart=0; Lp.length=0;
3071#endif
3072  /*- computes the lcm(s[i],p) -*/
3073  Lp.lcm = pInit();
3074
3075  pLcm(p,f,Lp.lcm);
3076  pSetm(Lp.lcm);
3077  pSetCoeff(Lp.lcm, nLcm(pGetCoeff(p), pGetCoeff(f), currRing));
3078  assume(!strat->sugarCrit);
3079  assume(!strat->fromT);
3080  /*
3081  *the set B collects the pairs of type (S[j],p)
3082  *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p) != lcm(r,p)
3083  *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
3084  *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
3085  */
3086  for(j = strat->Bl;j>=0;j--)
3087  {
3088    compare=pDivCompRing(strat->B[j].lcm,Lp.lcm);
3089    compareCoeff = nDivComp(pGetCoeff(strat->B[j].lcm), pGetCoeff(Lp.lcm));
3090    if (compareCoeff == 0 || compare == compareCoeff)
3091    {
3092      if (compare == 1)
3093      {
3094        strat->c3++;
3095        pLmDelete(Lp.lcm);
3096        return;
3097      }
3098      else
3099      if (compare == -1)
3100      {
3101        deleteInL(strat->B,&strat->Bl,j,strat);
3102        strat->c3++;
3103      }
3104    }
3105    if (compare == pDivComp_EQUAL)
3106    {
3107      // Add hint for same LM and direction of LC (later) (TODO Oliver)
3108      if (compareCoeff == 1)
3109      {
3110        strat->c3++;
3111        pLmDelete(Lp.lcm);
3112        return;
3113      }
3114      else
3115      if (compareCoeff == -1)
3116      {
3117        deleteInL(strat->B,&strat->Bl,j,strat);
3118        strat->c3++;
3119      }
3120    }
3121  }
3122  /*
3123  *the pair (S[i],p) enters B if the spoly != 0
3124  */
3125  /*-  compute the short s-polynomial -*/
3126  if ((f==NULL) || (p==NULL)) return;
3127  pNorm(p);
3128  {
3129    Lp.p = ksCreateShortSpoly(f, p, strat->tailRing);
3130  }
3131  if (Lp.p == NULL) //deactivated, as we are adding pairs with zeropoly and not from S
3132  {
3133    /*- the case that the s-poly is 0 -*/
3134//    if (strat->pairtest==NULL) initPairtest(strat);
3135//    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
3136//    strat->pairtest[strat->sl+1] = TRUE;
3137    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
3138    /*
3139    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
3140    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
3141    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
3142    *term of p devides the lcm(s,r)
3143    *(this canceling should be done here because
3144    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
3145    *the first case is handeled in chainCrit
3146    */
3147    if (Lp.lcm!=NULL) pLmDelete(Lp.lcm);
3148  }
3149  else
3150  {
3151    /*- the pair (S[i],p) enters B -*/
3152    Lp.p1 = f;
3153    Lp.p2 = p;
3154
3155    pNext(Lp.p) = strat->tail;
3156
3157    LObject tmp_h(f, currRing, strat->tailRing);
3158    tmp_h.SetShortExpVector();
3159    strat->initEcart(&tmp_h);
3160    tmp_h.sev = pGetShortExpVector(tmp_h.p);
3161    tmp_h.t_p = t_p;
3162
3163    enterT(tmp_h, strat, strat->tl + 1);
3164
3165    if (atR >= 0)
3166    {
3167      Lp.i_r2 = atR;
3168      Lp.i_r1 = strat->tl;
3169    }
3170
3171    strat->initEcartPair(&Lp,f,p,0/*strat->ecartS[i]*/,ecart);     // Attention: TODO: break ecart
3172    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
3173    enterL(&strat->B, &strat->Bl, &strat->Bmax, Lp, l);
3174  }
3175}
3176
3177/* Helper for kCreateZeroPoly
3178 * enumerating the exponents
3179ring r = 2^2, (a, b, c), lp; ideal G0 = system("createG0"); ideal G = interred(G0); ncols(G0); ncols(G);
3180 */
3181
3182int nextZeroSimplexExponent (long exp[], long ind[], long cexp[], long cind[], long* cabsind, long step[], long bound, long N)
3183/* gives the next exponent from the set H_1 */
3184{
3185  long add = ind2(cexp[1] + 2);
3186  if ((*cabsind < bound) && (*cabsind - step[1] + add < bound))
3187  {
3188    cexp[1] += 2;
3189    cind[1] += add;
3190    *cabsind += add;
3191  }
3192  else
3193  {
3194    // cabsind >= habsind
3195    if (N == 1) return 0;
3196    int i = 1;
3197    while (exp[i] == cexp[i] && i <= N) i++;
3198    cexp[i] = exp[i];
3199    *cabsind -= cind[i];
3200    cind[i] = ind[i];
3201    step[i] = 500000;
3202    *cabsind += cind[i];
3203    // Print("in: %d\n", *cabsind);
3204    i += 1;
3205    if (i > N) return 0;
3206    do
3207    {
3208      step[1] = 500000;
3209      for (int j = i + 1; j <= N; j++)
3210      {
3211        if (step[1] > step[j]) step[1] = step[j];
3212      }
3213      add = ind2(cexp[i] + 2);
3214      if (*cabsind - step[1] + add >= bound)
3215      {
3216        cexp[i] = exp[i];
3217        *cabsind -= cind[i];
3218        cind[i] = ind[i];
3219        *cabsind += cind[i];
3220        step[i] = 500000;
3221        i += 1;
3222        if (i > N) return 0;
3223      }
3224      else step[1] = -1;
3225    } while (step[1] != -1);
3226    step[1] = 500000;
3227    cexp[i] += 2;
3228    cind[i] += add;
3229    *cabsind += add;
3230    if (add < step[i]) step[i] = add;
3231    for (i = 2; i <= N; i++)
3232    {
3233      if (step[1] > step[i]) step[1] = step[i];
3234    }
3235  }
3236  return 1;
3237}
3238
3239/*
3240 * Creates the zero Polynomial on position exp
3241 * long exp[] : exponent of leading term
3242 * cabsind    : total 2-ind of exp (if -1 will be computed)
3243 * poly* t_p  : will hold the LT in tailRing
3244 * leadRing   : ring for the LT
3245 * tailRing   : ring for the tail
3246 */
3247
3248poly kCreateZeroPoly(long exp[], long cabsind, poly* t_p, ring leadRing, ring tailRing)
3249{
3250
3251  poly zeroPoly = NULL;
3252
3253  number tmp1;
3254  poly tmp2, tmp3;
3255
3256  if (cabsind == -1)
3257  {
3258    cabsind = 0;
3259    for (int i = 1; i <= leadRing->N; i++)
3260    {
3261      cabsind += ind_fact_2(exp[i]);
3262    }
3263//    Print("cabsind: %d\n", cabsind);
3264  }
3265  if (cabsind < leadRing->ch)
3266  {
3267    zeroPoly = p_ISet(twoPow(leadRing->ch - cabsind), tailRing);
3268  }
3269  else
3270  {
3271    zeroPoly = p_ISet(1, tailRing);
3272  }
3273  for (int i = 1; i <= leadRing->N; i++)
3274  {
3275    for (long j = 1; j <= exp[i]; j++)
3276    {
3277      tmp1 = nInit(j);
3278      tmp2 = p_ISet(1, tailRing);
3279      p_SetExp(tmp2, i, 1, tailRing);
3280      p_Setm(tmp2, tailRing);
3281      if (nIsZero(tmp1))
3282      { // should nowbe obsolet, test ! TODO OLIVER
3283        zeroPoly = p_Mult_q(zeroPoly, tmp2, tailRing);
3284      }
3285      else
3286      {
3287        tmp3 = p_NSet(nCopy(tmp1), tailRing);
3288        zeroPoly = p_Mult_q(zeroPoly, p_Add_q(tmp3, tmp2, tailRing), tailRing);
3289      }
3290    }
3291  }
3292  tmp2 = p_NSet(nCopy(pGetCoeff(zeroPoly)), leadRing);
3293  for (int i = 1; i <= leadRing->N; i++)
3294  {
3295    pSetExp(tmp2, i, p_GetExp(zeroPoly, i, tailRing));
3296  }
3297  p_Setm(tmp2, leadRing);
3298  *t_p = zeroPoly;
3299  zeroPoly = pNext(zeroPoly);
3300  pNext(*t_p) = NULL;
3301  pNext(tmp2) = zeroPoly;
3302  return tmp2;
3303}
3304
3305// #define OLI_DEBUG
3306
3307/*
3308 * Generate the s-polynomial for the virtual set of zero-polynomials
3309 */
3310
3311void initenterzeropairsRing (poly p, int ecart, kStrategy strat, int atR)
3312{
3313  // Initialize
3314  long exp[50];            // The exponent of \hat{X} (basepoint)
3315  long cexp[50];           // The current exponent for iterating over all
3316  long ind[50];            // The power of 2 in the i-th component of exp
3317  long cind[50];           // analog for cexp
3318  long mult[50];           // How to multiply the elements of G
3319  long cabsind = 0;        // The abs. index of cexp, i.e. the sum of cind
3320  long habsind = 0;        // The abs. index of the coefficient of h
3321  long step[50];           // The last increases
3322  for (int i = 1; i <= currRing->N; i++)
3323  {
3324    exp[i] = p_GetExp(p, i, currRing);
3325    if (exp[i] & 1 != 0)
3326    {
3327      exp[i] = exp[i] - 1;
3328      mult[i] = 1;
3329    }
3330    cexp[i] = exp[i];
3331    ind[i] = ind_fact_2(exp[i]);
3332    cabsind += ind[i];
3333    cind[i] = ind[i];
3334    step[i] = 500000;
3335  }
3336  step[1] = 500000;
3337  habsind = ind2((long) p_GetCoeff(p, currRing));
3338  long bound = currRing->ch - habsind;
3339#ifdef OLI_DEBUG
3340  PrintS("-------------\npoly  :");
3341  wrp(p);
3342  Print("\nexp   : (%d, %d)\n", exp[1] + mult[1], exp[2] + mult[1]);
3343  Print("cexp  : (%d, %d)\n", cexp[1], cexp[2]);
3344  Print("cind  : (%d, %d)\n", cind[1], cind[2]);
3345  Print("bound : %d\n", bound);
3346  Print("cind  : %d\n", cabsind);
3347#endif
3348  if (cabsind == 0)
3349  {
3350    if (!(nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N)))
3351    {
3352      return;
3353    }
3354  }
3355  // Now the whole simplex
3356  do
3357  {
3358    // Build s-polynomial
3359    // 2**ind-def * mult * g - exp-def * h
3360    poly t_p;
3361    poly zeroPoly = kCreateZeroPoly(cexp, cabsind, &t_p, currRing, strat->tailRing);
3362#ifdef OLI_DEBUG
3363    Print("%d, (%d, %d), ind = (%d, %d)\n", cabsind, cexp[1], cexp[2], cind[1], cind[2]);
3364    Print("zPoly : ");
3365    wrp(zeroPoly);
3366    Print("\n");
3367#endif
3368    enterOneZeroPairRing(zeroPoly, t_p, p, ecart, strat, atR);
3369  }
3370  while ( nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N) );
3371}
3372
3373/*
3374 * Create the Groebner basis of the vanishing polynomials.
3375 */
3376
3377ideal createG0()
3378{
3379  // Initialize
3380  long exp[50];            // The exponent of \hat{X} (basepoint)
3381  long cexp[50];           // The current exponent for iterating over all
3382  long ind[50];            // The power of 2 in the i-th component of exp
3383  long cind[50];           // analog for cexp
3384  long mult[50];           // How to multiply the elements of G
3385  long cabsind = 0;        // The abs. index of cexp, i.e. the sum of cind
3386  long habsind = 0;        // The abs. index of the coefficient of h
3387  long step[50];           // The last increases
3388  for (int i = 1; i <= currRing->N; i++)
3389  {
3390    exp[i] = 0;
3391    cexp[i] = exp[i];
3392    ind[i] = 0;
3393    step[i] = 500000;
3394    cind[i] = ind[i];
3395  }
3396  long bound = currRing->ch;
3397  step[1] = 500000;
3398#ifdef OLI_DEBUG
3399  PrintS("-------------\npoly  :");
3400//  wrp(p);
3401  Print("\nexp   : (%d, %d)\n", exp[1] + mult[1], exp[2] + mult[1]);
3402  Print("cexp  : (%d, %d)\n", cexp[1], cexp[2]);
3403  Print("cind  : (%d, %d)\n", cind[1], cind[2]);
3404  Print("bound : %d\n", bound);
3405  Print("cind  : %d\n", cabsind);
3406#endif
3407  if (cabsind == 0)
3408  {
3409    if (!(nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N)))
3410    {
3411      return idInit(1, 1);
3412    }
3413  }
3414  ideal G0 = idInit(1, 1);
3415  // Now the whole simplex
3416  do
3417  {
3418    // Build s-polynomial
3419    // 2**ind-def * mult * g - exp-def * h
3420    poly t_p;
3421    poly zeroPoly = kCreateZeroPoly(cexp, cabsind, &t_p, currRing, currRing);
3422#ifdef OLI_DEBUG
3423    Print("%d, (%d, %d), ind = (%d, %d)\n", cabsind, cexp[1], cexp[2], cind[1], cind[2]);
3424    Print("zPoly : ");
3425    wrp(zeroPoly);
3426    Print("\n");
3427#endif
3428    // Add to ideal
3429    pEnlargeSet(&(G0->m), IDELEMS(G0), 1);
3430    IDELEMS(G0) += 1;
3431    G0->m[IDELEMS(G0) - 1] = zeroPoly;
3432  }
3433  while ( nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N) );
3434  idSkipZeroes(G0);
3435  return G0;
3436}
3437#endif
3438
3439#ifdef HAVE_RINGS
3440/*2
3441*(s[0],h),...,(s[k],h) will be put to the pairset L
3442*/
3443void initenterstrongPairs (poly h,int k,int ecart,int isFromQ,kStrategy strat, int atR = -1)
3444{
3445  const unsigned long iCompH = pGetComp(h);
3446  if (!nIsOne(pGetCoeff(h)))
3447  {
3448    int j;
3449
3450    for (j=0; j<=k; j++)
3451    {
3452      // Print("j:%d, Ll:%d\n",j,strat->Ll);
3453//      if (((unsigned long) pGetCoeff(h) % (unsigned long) pGetCoeff(strat->S[j]) != 0) &&
3454//         ((unsigned long) pGetCoeff(strat->S[j]) % (unsigned long) pGetCoeff(h) != 0))
3455      if (((iCompH == pGetComp(strat->S[j]))
3456      || (0 == pGetComp(strat->S[j])))
3457      && ((iCompH<=strat->syzComp)||(strat->syzComp==0)))
3458      {
3459        enterOneStrongPoly(j,h,ecart,isFromQ,strat, atR);
3460      }
3461    }
3462  }
3463/*
3464ring r=256,(x,y,z),dp;
3465ideal I=12xz-133y, 2xy-z;
3466*/
3467
3468}
3469
3470/*2
3471* Generates spoly(0, h) if applicable. Assumes ring in Z/2^n.
3472*/
3473void enterExtendedSpoly(poly h,kStrategy strat)
3474{
3475  if (nIsOne(pGetCoeff(h))) return;
3476  number gcd;
3477  bool go = false;
3478  if (n_DivBy((number) 0, pGetCoeff(h), currRing->cf))
3479  {
3480    gcd = nIntDiv((number) 0, pGetCoeff(h));
3481    go = true;
3482  }
3483  else
3484    gcd = nGcd((number) 0, pGetCoeff(h), strat->tailRing);
3485  if (go || !nIsOne(gcd))
3486  {
3487    poly p = h->next;
3488    if (!go)
3489    {
3490      number tmp = gcd;
3491      gcd = nIntDiv(0, gcd);
3492      nDelete(&tmp);
3493    }
3494    p_Test(p,strat->tailRing);
3495    p = pp_Mult_nn(p, gcd, strat->tailRing);
3496    nDelete(&gcd);
3497
3498    if (p != NULL)
3499    {
3500      if (TEST_OPT_PROT)
3501      {
3502        PrintS("Z");
3503      }
3504#ifdef KDEBUG
3505      if (TEST_OPT_DEBUG)
3506      {
3507        PrintS("--- create zero spoly: ");
3508        p_wrp(h,currRing,strat->tailRing);
3509        PrintS(" ---> ");
3510      }
3511#endif
3512      poly tmp = pInit();
3513      pSetCoeff0(tmp, pGetCoeff(p));
3514      for (int i = 1; i <= rVar(currRing); i++)
3515      {
3516        pSetExp(tmp, i, p_GetExp(p, i, strat->tailRing));
3517      }
3518      if (rRing_has_Comp(currRing) && rRing_has_Comp(strat->tailRing))
3519      {
3520        p_SetComp(tmp, p_GetComp(p, strat->tailRing), currRing);
3521      }
3522      p_Setm(tmp, currRing);
3523      p = p_LmFreeAndNext(p, strat->tailRing);
3524      pNext(tmp) = p;
3525      LObject h;
3526      h.Init();
3527      h.p = tmp;
3528      h.tailRing = strat->tailRing;
3529      int posx;
3530      if (h.p!=NULL)
3531      {
3532        if (TEST_OPT_INTSTRATEGY)
3533        {
3534          //pContent(h.p);
3535          h.pCleardenom(); // also does a pContent
3536        }
3537        else
3538        {
3539          h.pNorm();
3540        }
3541        strat->initEcart(&h);
3542        if (strat->Ll==-1)
3543          posx =0;
3544        else
3545          posx = strat->posInL(strat->L,strat->Ll,&h,strat);
3546        h.sev = pGetShortExpVector(h.p);
3547        if (strat->tailRing != currRing)
3548        {
3549          h.t_p = k_LmInit_currRing_2_tailRing(h.p, strat->tailRing);
3550        }
3551#ifdef KDEBUG
3552        if (TEST_OPT_DEBUG)
3553        {
3554          p_wrp(tmp,currRing,strat->tailRing);
3555          PrintLn();
3556        }
3557#endif
3558        enterL(&strat->L,&strat->Ll,&strat->Lmax,h,posx);
3559      }
3560    }
3561  }
3562  nDelete(&gcd);
3563}
3564
3565void clearSbatch (poly h,int k,int pos,kStrategy strat)
3566{
3567  int j = pos;
3568  if ( (!strat->fromT)
3569  && ((strat->syzComp==0)
3570    ||(pGetComp(h)<=strat->syzComp)
3571  ))
3572  {
3573    // Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
3574    unsigned long h_sev = pGetShortExpVector(h);
3575    loop
3576    {
3577      if (j > k) break;
3578      clearS(h,h_sev, &j,&k,strat);
3579      j++;
3580    }
3581    // Print("end clearS sl=%d\n",strat->sl);
3582  }
3583}
3584
3585/*2
3586* Generates a sufficient set of spolys (maybe just a finite generating
3587* set of the syzygys)
3588*/
3589void superenterpairs (poly h,int k,int ecart,int pos,kStrategy strat, int atR)
3590{
3591  #if ADIDEBUG
3592  PrintLn();
3593  PrintS("Enter superenterpairs");
3594  PrintLn();
3595  int iii = strat->Ll;
3596  #endif
3597  assume (rField_is_Ring(currRing));
3598  // enter also zero divisor * poly, if this is non zero and of smaller degree
3599  if (!(rField_is_Domain(currRing))) enterExtendedSpoly(h, strat);
3600   #if ADIDEBUG
3601  if(iii==strat->Ll)
3602  {
3603    PrintLn();
3604    PrintS("                enterExtendedSpoly has not changed the list L.");
3605    PrintLn();
3606  }
3607  else
3608  {
3609    PrintLn();
3610    PrintS("                enterExtendedSpoly changed the list L: ");
3611    PrintLn();
3612    for(iii=0;iii<=strat->Ll;iii++)
3613    {
3614      PrintLn();
3615      PrintS("                L[");printf("%d",iii);PrintS("]:");PrintLn();
3616      PrintS("                     ");p_Write(strat->L[iii].p1,strat->tailRing);
3617      PrintS("                     ");p_Write(strat->L[iii].p2,strat->tailRing);
3618      PrintS("                     ");p_Write(strat->L[iii].p,strat->tailRing);
3619    }
3620  }
3621  iii = strat->Ll;
3622  #endif
3623  initenterpairs(h, k, ecart, 0, strat, atR);
3624  #if ADIDEBUG
3625  if(iii==strat->Ll)
3626  {
3627    PrintLn();
3628    PrintS("                initenterpairs has not changed the list L.");
3629    PrintLn();
3630  }
3631  else
3632  {
3633    PrintLn();
3634    PrintS("                initenterpairs changed the list L: ");
3635    PrintLn();
3636    for(iii=0;iii<=strat->Ll;iii++)
3637    {
3638      PrintLn();
3639      PrintS("                L[");printf("%d",iii);PrintS("]:");PrintLn();
3640      PrintS("                     ");p_Write(strat->L[iii].p1,strat->tailRing);
3641      PrintS("                     ");p_Write(strat->L[iii].p2,strat->tailRing);
3642      PrintS("                     ");p_Write(strat->L[iii].p,strat->tailRing);
3643    }
3644  }
3645  iii = strat->Ll;
3646  #endif
3647  initenterstrongPairs(h, k, ecart, 0, strat, atR);
3648  #if ADIDEBUG
3649  if(iii==strat->Ll)
3650  {
3651    PrintLn();
3652    PrintS("                initenterstrongPairs has not changed the list L.");
3653    PrintLn();
3654  }
3655  else
3656  {
3657    PrintLn();
3658    PrintS("                initenterstrongPairs changed the list L: ");
3659    PrintLn();
3660    for(iii=0;iii<=strat->Ll;iii++)
3661    {
3662      PrintLn();
3663      PrintS("                L[");printf("%d",iii);PrintS("]:");PrintLn();
3664      PrintS("                     ");p_Write(strat->L[iii].p1,strat->tailRing);
3665      PrintS("                     ");p_Write(strat->L[iii].p2,strat->tailRing);
3666      PrintS("                     ");p_Write(strat->L[iii].p,strat->tailRing);
3667    }
3668  }
3669  PrintLn();
3670  PrintS("End of superenterpairs");
3671  PrintLn();
3672  #endif
3673  clearSbatch(h, k, pos, strat);
3674}
3675#endif
3676
3677/*2
3678*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
3679*superfluous elements in S will be deleted
3680*/
3681void enterpairs (poly h,int k,int ecart,int pos,kStrategy strat, int atR)
3682{
3683  int j=pos;
3684
3685#ifdef HAVE_RINGS
3686  assume (!rField_is_Ring(currRing));
3687#endif
3688
3689  initenterpairs(h,k,ecart,0,strat, atR);
3690  if ( (!strat->fromT)
3691  && ((strat->syzComp==0)
3692    ||(pGetComp(h)<=strat->syzComp)))
3693  {
3694    //Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
3695    unsigned long h_sev = pGetShortExpVector(h);
3696    loop
3697    {
3698      if (j > k) break;
3699      clearS(h,h_sev, &j,&k,strat);
3700      j++;
3701    }
3702    //Print("end clearS sl=%d\n",strat->sl);
3703  }
3704 // PrintS("end enterpairs\n");
3705}
3706
3707/*2
3708*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
3709*superfluous elements in S will be deleted
3710*this is a special variant of signature-based algorithms including the
3711*signatures for criteria checks
3712*/
3713void enterpairsSig (poly h,poly hSig,int hFrom,int k,int ecart,int pos,kStrategy strat, int atR)
3714{
3715int j=pos;
3716
3717#ifdef HAVE_RINGS
3718assume (!rField_is_Ring(currRing));
3719#endif
3720
3721initenterpairsSig(h,hSig,hFrom,k,ecart,0,strat, atR);
3722if ( (!strat->fromT)
3723&& ((strat->syzComp==0)
3724  ||(pGetComp(h)<=strat->syzComp)))
3725{
3726  //Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
3727  unsigned long h_sev = pGetShortExpVector(h);
3728  loop
3729  {
3730    if (j > k) break;
3731    clearS(h,h_sev, &j,&k,strat);
3732    j++;
3733  }
3734  //Print("end clearS sl=%d\n",strat->sl);
3735}
3736// PrintS("end enterpairs\n");
3737}
3738
3739/*2
3740*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
3741*superfluous elements in S will be deleted
3742*/
3743void enterpairsSpecial (poly h,int k,int ecart,int pos,kStrategy strat, int atR = -1)
3744{
3745  int j;
3746  const int iCompH = pGetComp(h);
3747
3748#ifdef HAVE_RINGS
3749  if (rField_is_Ring(currRing))
3750  {
3751    for (j=0; j<=k; j++)
3752    {
3753      const int iCompSj = pGetComp(strat->S[j]);
3754      if ((iCompH==iCompSj)
3755          //|| (0==iCompH) // can only happen,if iCompSj==0
3756          || (0==iCompSj))
3757      {
3758        enterOnePairRing(j,h,ecart,FALSE,strat, atR);
3759      }
3760    }
3761    kMergeBintoL(strat);
3762  }
3763  else
3764#endif
3765  for (j=0; j<=k; j++)
3766  {
3767    const int iCompSj = pGetComp(strat->S[j]);
3768    if ((iCompH==iCompSj)
3769        //|| (0==iCompH) // can only happen,if iCompSj==0
3770        || (0==iCompSj))
3771    {
3772      enterOnePairSpecial(j,h,ecart,strat, atR);
3773    }
3774  }
3775
3776  if (strat->noClearS) return;
3777
3778//   #ifdef HAVE_PLURAL
3779/*
3780  if (rIsPluralRing(currRing))
3781  {
3782    j=pos;
3783    loop
3784    {
3785      if (j > k) break;
3786
3787      if (pLmDivisibleBy(h, strat->S[j]))
3788      {
3789        deleteInS(j, strat);
3790        j--;
3791        k--;
3792      }
3793
3794      j++;
3795    }
3796  }
3797  else
3798*/
3799//   #endif // ??? Why was the following cancelation disabled for non-commutative rings?
3800  {
3801    j=pos;
3802    loop
3803    {
3804      unsigned long h_sev = pGetShortExpVector(h);
3805      if (j > k) break;
3806      clearS(h,h_sev,&j,&k,strat);
3807      j++;
3808    }
3809  }
3810}
3811
3812/*2
3813*reorders  s with respect to posInS,
3814*suc is the first changed index or zero
3815*/
3816
3817void reorderS (int* suc,kStrategy strat)
3818{
3819  int i,j,at,ecart, s2r;
3820  int fq=0;
3821  unsigned long sev;
3822  poly  p;
3823  int new_suc=strat->sl+1;
3824  i= *suc;
3825  if (i<0) i=0;
3826
3827  for (; i<=strat->sl; i++)
3828  {
3829    at = posInS(strat,i-1,strat->S[i],strat->ecartS[i]);
3830    if (at != i)
3831    {
3832      if (new_suc > at) new_suc = at;
3833      p = strat->S[i];
3834      ecart = strat->ecartS[i];
3835      sev = strat->sevS[i];
3836      s2r = strat->S_2_R[i];
3837      if (strat->fromQ!=NULL) fq=strat->fromQ[i];
3838      for (j=i; j>=at+1; j--)
3839      {
3840        strat->S[j] = strat->S[j-1];
3841        strat->ecartS[j] = strat->ecartS[j-1];
3842        strat->sevS[j] = strat->sevS[j-1];
3843        strat->S_2_R[j] = strat->S_2_R[j-1];
3844      }
3845      strat->S[at] = p;
3846      strat->ecartS[at] = ecart;
3847      strat->sevS[at] = sev;
3848      strat->S_2_R[at] = s2r;
3849      if (strat->fromQ!=NULL)
3850      {
3851        for (j=i; j>=at+1; j--)
3852        {
3853          strat->fromQ[j] = strat->fromQ[j-1];
3854        }
3855        strat->fromQ[at]=fq;
3856      }
3857    }
3858  }
3859  if (new_suc <= strat->sl) *suc=new_suc;
3860  else                      *suc=-1;
3861}
3862
3863
3864/*2
3865*looks up the position of p in set
3866*set[0] is the smallest with respect to the ordering-procedure deg/pComp
3867* Assumption: posInS only depends on the leading term
3868*             otherwise, bba has to be changed
3869*/
3870int posInS (const kStrategy strat, const int length,const poly p,
3871            const int ecart_p)
3872{
3873  if(length==-1) return 0;
3874  polyset set=strat->S;
3875  int i;
3876  int an = 0;
3877  int en = length;
3878  int cmp_int = currRing->OrdSgn;
3879  if ((currRing->MixedOrder)
3880#ifdef HAVE_PLURAL
3881  && (currRing->real_var_start==0)
3882#endif
3883#if 0
3884  || ((strat->ak>0) && ((currRing->order[0]==ringorder_c)||((currRing->order[0]==ringorder_C))))
3885#endif
3886  )
3887  {
3888    int o=p_Deg(p,currRing);
3889    int oo=p_Deg(set[length],currRing);
3890
3891    if ((oo<o)
3892    || ((o==oo) && (pLmCmp(set[length],p)!= cmp_int)))
3893      return length+1;
3894
3895    loop
3896    {
3897      if (an >= en-1)
3898      {
3899        if ((p_Deg(set[an],currRing)>=o) && (pLmCmp(set[an],p) == cmp_int))
3900        {
3901          return an;
3902        }
3903        return en;
3904      }
3905      i=(an+en) / 2;
3906      if ((p_Deg(set[i],currRing)>=o) && (pLmCmp(set[i],p) == cmp_int)) en=i;
3907      else                              an=i;
3908    }
3909  }
3910  else
3911  {
3912#ifdef HAVE_RINGS
3913    if (rField_is_Ring(currRing))
3914    {
3915      if (pLmCmp(set[length],p)== -cmp_int)
3916        return length+1;
3917      int cmp;
3918      loop
3919      {
3920        if (an >= en-1)
3921        {
3922          cmp = pLmCmp(set[an],p);
3923          if (cmp == cmp_int)  return an;
3924          if (cmp == -cmp_int) return en;
3925          if (n_DivBy(pGetCoeff(p), pGetCoeff(set[an]), currRing->cf)) return en;
3926          return an;
3927        }
3928        i = (an+en) / 2;
3929        cmp = pLmCmp(set[i],p);
3930        if (cmp == cmp_int)         en = i;
3931        else if (cmp == -cmp_int)   an = i;
3932        else
3933        {
3934          if (n_DivBy(pGetCoeff(p), pGetCoeff(set[i]), currRing->cf)) an = i;
3935          else en = i;
3936        }
3937      }
3938    }
3939    else
3940#endif
3941    if (pLmCmp(set[length],p)== -cmp_int)
3942      return length+1;
3943
3944    loop
3945    {
3946      if (an >= en-1)
3947      {
3948        if (pLmCmp(set[an],p) == cmp_int) return an;
3949        if (pLmCmp(set[an],p) == -cmp_int) return en;
3950        if ((cmp_int!=1)
3951        && ((strat->ecartS[an])>ecart_p))
3952          return an;
3953        return en;
3954      }
3955      i=(an+en) / 2;
3956      if (pLmCmp(set[i],p) == cmp_int) en=i;
3957      else if (pLmCmp(set[i],p) == -cmp_int) an=i;
3958      else
3959      {
3960        if ((cmp_int!=1)
3961        &&((strat->ecartS[i])<ecart_p))
3962          en=i;
3963        else
3964          an=i;
3965      }
3966    }
3967  }
3968}
3969
3970
3971/*2
3972* looks up the position of p in set
3973* the position is the last one
3974*/
3975int posInT0 (const TSet,const int length,LObject &)
3976{
3977  return (length+1);
3978}
3979
3980
3981/*2
3982* looks up the position of p in T
3983* set[0] is the smallest with respect to the ordering-procedure
3984* pComp
3985*/
3986int posInT1 (const TSet set,const int length,LObject &p)
3987{
3988  if (length==-1) return 0;
3989
3990  if (pLmCmp(set[length].p,p.p)!= currRing->OrdSgn) return length+1;
3991
3992  int i;
3993  int an = 0;
3994  int en= length;
3995
3996  loop
3997  {
3998    if (an >= en-1)
3999    {
4000      if (pLmCmp(set[an].p,p.p) == currRing->OrdSgn) return an;
4001      return en;
4002    }
4003    i=(an+en) / 2;
4004    if (pLmCmp(set[i].p,p.p) == currRing->OrdSgn) en=i;
4005    else                                 an=i;
4006  }
4007}
4008
4009/*2
4010* looks up the position of p in T
4011* set[0] is the smallest with respect to the ordering-procedure
4012* length
4013*/
4014int posInT2 (const TSet set,const int length,LObject &p)
4015{
4016  p.GetpLength();
4017  if (length==-1)
4018    return 0;
4019  if (set[length].length<p.length)
4020    return length+1;
4021
4022  int i;
4023  int an = 0;
4024  int en= length;
4025
4026  loop
4027  {
4028    if (an >= en-1)
4029    {
4030      if (set[an].length>p.length) return an;
4031      return en;
4032    }
4033    i=(an+en) / 2;
4034    if (set[i].length>p.length) en=i;
4035    else                        an=i;
4036  }
4037}
4038
4039/*2
4040* looks up the position of p in T
4041* set[0] is the smallest with respect to the ordering-procedure
4042* totaldegree,pComp
4043*/
4044int posInT11 (const TSet set,const int length,LObject &p)
4045/*{
4046 * int j=0;
4047 * int o;
4048 *
4049 * o = p.GetpFDeg();
4050 * loop
4051 * {
4052 *   if ((pFDeg(set[j].p) > o)
4053 *   || ((pFDeg(set[j].p) == o) && (pLmCmp(set[j].p,p.p) == currRing->OrdSgn)))
4054 *   {
4055 *     return j;
4056 *   }
4057 *   j++;
4058 *   if (j > length) return j;
4059 * }
4060 *}
4061 */
4062{
4063  if (length==-1) return 0;
4064
4065  int o = p.GetpFDeg();
4066  int op = set[length].GetpFDeg();
4067
4068  if ((op < o)
4069  || ((op == o) && (pLmCmp(set[length].p,p.p) != currRing->OrdSgn)))
4070    return length+1;
4071
4072  int i;
4073  int an = 0;
4074  int en= length;
4075
4076  loop
4077  {
4078    if (an >= en-1)
4079    {
4080      op= set[an].GetpFDeg();
4081      if ((op > o)
4082      || (( op == o) && (pLmCmp(set[an].p,p.p) == currRing->OrdSgn)))
4083        return an;
4084      return en;
4085    }
4086    i=(an+en) / 2;
4087    op = set[i].GetpFDeg();
4088    if (( op > o)
4089    || (( op == o) && (pLmCmp(set[i].p,p.p) == currRing->OrdSgn)))
4090      en=i;
4091    else
4092      an=i;
4093  }
4094}
4095
4096/*2 Pos for rings T: Here I am
4097* looks up the position of p in T
4098* set[0] is the smallest with respect to the ordering-procedure
4099* totaldegree,pComp
4100*/
4101int posInTrg0 (const TSet set,const int length,LObject &p)
4102{
4103  if (length==-1) return 0;
4104  int o = p.GetpFDeg();
4105  int op = set[length].GetpFDeg();
4106  int i;
4107  int an = 0;
4108  int en = length;
4109  int cmp_int = currRing->OrdSgn;
4110  if ((op < o) || (pLmCmp(set[length].p,p.p)== -cmp_int))
4111    return length+1;
4112  int cmp;
4113  loop
4114  {
4115    if (an >= en-1)
4116    {
4117      op = set[an].GetpFDeg();
4118      if (op > o) return an;
4119      if (op < 0) return en;
4120      cmp = pLmCmp(set[an].p,p.p);
4121      if (cmp == cmp_int)  return an;
4122      if (cmp == -cmp_int) return en;
4123      if (nGreater(pGetCoeff(p.p), pGetCoeff(set[an].p))) return en;
4124      return an;
4125    }
4126    i = (an + en) / 2;
4127    op = set[i].GetpFDeg();
4128    if (op > o)       en = i;
4129    else if (op < o)  an = i;
4130    else
4131    {
4132      cmp = pLmCmp(set[i].p,p.p);
4133      if (cmp == cmp_int)                                     en = i;
4134      else if (cmp == -cmp_int)                               an = i;
4135      else if (nGreater(pGetCoeff(p.p), pGetCoeff(set[i].p))) an = i;
4136      else                                                    en = i;
4137    }
4138  }
4139}
4140/*
4141  int o = p.GetpFDeg();
4142  int op = set[length].GetpFDeg();
4143
4144  if ((op < o)
4145  || ((op == o) && (pLmCmp(set[length].p,p.p) != currRing->OrdSgn)))
4146    return length+1;
4147
4148  int i;
4149  int an = 0;
4150  int en= length;
4151
4152  loop
4153  {
4154    if (an >= en-1)
4155    {
4156      op= set[an].GetpFDeg();
4157      if ((op > o)
4158      || (( op == o) && (pLmCmp(set[an].p,p.p) == currRing->OrdSgn)))
4159        return an;
4160      return en;
4161    }
4162    i=(an+en) / 2;
4163    op = set[i].GetpFDeg();
4164    if (( op > o)
4165    || (( op == o) && (pLmCmp(set[i].p,p.p) == currRing->OrdSgn)))
4166      en=i;
4167    else
4168      an=i;
4169  }
4170}
4171  */
4172/*2
4173* looks up the position of p in T
4174* set[0] is the smallest with respect to the ordering-procedure
4175* totaldegree,pComp
4176*/
4177int posInT110 (const TSet set,const int length,LObject &p)
4178{
4179  p.GetpLength();
4180  if (length==-1) return 0;
4181
4182  int o = p.GetpFDeg();
4183  int op = set[length].GetpFDeg();
4184
4185  if (( op < o)
4186  || (( op == o) && (set[length].length<p.length))
4187  || (( op == o) && (set[length].length == p.length)
4188     && (pLmCmp(set[length].p,p.p) != currRing->OrdSgn)))
4189    return length+1;
4190
4191  int i;
4192  int an = 0;
4193  int en= length;
4194  loop
4195  {
4196    if (an >= en-1)
4197    {
4198      op = set[an].GetpFDeg();
4199      if (( op > o)
4200      || (( op == o) && (set[an].length > p.length))
4201      || (( op == o) && (set[an].length == p.length)
4202         && (pLmCmp(set[an].p,p.p) == currRing->OrdSgn)))
4203        return an;
4204      return en;
4205    }
4206    i=(an+en) / 2;
4207    op = set[i].GetpFDeg();
4208    if (( op > o)
4209    || (( op == o) && (set[i].length > p.length))
4210    || (( op == o) && (set[i].length == p.length)
4211       && (pLmCmp(set[i].p,p.p) == currRing->OrdSgn)))
4212      en=i;
4213    else
4214      an=i;
4215  }
4216}
4217
4218/*2
4219* looks up the position of p in set
4220* set[0] is the smallest with respect to the ordering-procedure
4221* pFDeg
4222*/
4223int posInT13 (const TSet set,const int length,LObject &p)
4224{
4225  if (length==-1) return 0;
4226
4227  int o = p.GetpFDeg();
4228
4229  if (set[length].GetpFDeg() <= o)
4230    return length+1;
4231
4232  int i;
4233  int an = 0;
4234  int en= length;
4235  loop
4236  {
4237    if (an >= en-1)
4238    {
4239      if (set[an].GetpFDeg() > o)
4240        return an;
4241      return en;
4242    }
4243    i=(an+en) / 2;
4244    if (set[i].GetpFDeg() > o)
4245      en=i;
4246    else
4247      an=i;
4248  }
4249}
4250
4251// determines the position based on: 1.) Ecart 2.) pLength
4252int posInT_EcartpLength(const TSet set,const int length,LObject &p)
4253{
4254  int ol = p.GetpLength();
4255  if (length==-1) return 0;
4256
4257  int op=p.ecart;
4258
4259  int oo=set[length].ecart;
4260  if ((oo < op) || ((oo==op) && (set[length].length < ol)))
4261    return length+1;
4262
4263  int i;
4264  int an = 0;
4265  int en= length;
4266  loop
4267    {
4268      if (an >= en-1)
4269      {
4270        int oo=set[an].ecart;
4271        if((oo > op)
4272           || ((oo==op) && (set[an].pLength > ol)))
4273          return an;
4274        return en;
4275      }
4276      i=(an+en) / 2;
4277      int oo=set[i].ecart;
4278      if ((oo > op)
4279          || ((oo == op) && (set[i].pLength > ol)))
4280        en=i;
4281      else
4282        an=i;
4283    }
4284}
4285
4286/*2
4287* looks up the position of p in set
4288* set[0] is the smallest with respect to the ordering-procedure
4289* maximaldegree, pComp
4290*/
4291int posInT15 (const TSet set,const int length,LObject &p)
4292/*{
4293 *int j=0;
4294 * int o;
4295 *
4296 * o = p.GetpFDeg()+p.ecart;
4297 * loop
4298 * {
4299 *   if ((set[j].GetpFDeg()+set[j].ecart > o)
4300 *   || ((set[j].GetpFDeg()+set[j].ecart == o)
4301 *     && (pLmCmp(set[j].p,p.p) == currRing->OrdSgn)))
4302 *   {
4303 *     return j;
4304 *   }
4305 *   j++;
4306 *   if (j > length) return j;
4307 * }
4308 *}
4309 */
4310{
4311  if (length==-1) return 0;
4312
4313  int o = p.GetpFDeg() + p.ecart;
4314  int op = set[length].GetpFDeg()+set[length].ecart;
4315
4316  if ((op < o)
4317  || ((op == o)
4318     && (pLmCmp(set[length].p,p.p) != currRing->OrdSgn)))
4319    return length+1;
4320
4321  int i;
4322  int an = 0;
4323  int en= length;
4324  loop
4325  {
4326    if (an >= en-1)
4327    {
4328      op = set[an].GetpFDeg()+set[an].ecart;
4329      if (( op > o)
4330      || (( op  == o) && (pLmCmp(set[an].p,p.p) == currRing->OrdSgn)))
4331        return an;
4332      return en;
4333    }
4334    i=(an+en) / 2;
4335    op = set[i].GetpFDeg()+set[i].ecart;
4336    if (( op > o)
4337    || (( op == o) && (pLmCmp(set[i].p,p.p) == currRing->OrdSgn)))
4338      en=i;
4339    else
4340      an=i;
4341  }
4342}
4343
4344/*2
4345* looks up the position of p in set
4346* set[0] is the smallest with respect to the ordering-procedure
4347* pFDeg+ecart, ecart, pComp
4348*/
4349int posInT17 (const TSet set,const int length,LObject &p)
4350/*
4351*{
4352* int j=0;
4353* int  o;
4354*
4355*  o = p.GetpFDeg()+p.ecart;
4356*  loop
4357*  {
4358*    if ((pFDeg(set[j].p)+set[j].ecart > o)
4359*    || (((pFDeg(set[j].p)+set[j].ecart == o)
4360*      && (set[j].ecart < p.ecart)))
4361*    || ((pFDeg(set[j].p)+set[j].ecart == o)
4362*      && (set[j].ecart==p.ecart)
4363*      && (pLmCmp(set[j].p,p.p)==currRing->OrdSgn)))
4364*      return j;
4365*    j++;
4366*    if (j > length) return j;
4367*  }
4368* }
4369*/
4370{
4371  if (length==-1) return 0;
4372
4373  int o = p.GetpFDeg() + p.ecart;
4374  int op = set[length].GetpFDeg()+set[length].ecart;
4375
4376  if ((op < o)
4377  || (( op == o) && (set[length].ecart > p.ecart))
4378  || (( op == o) && (set[length].ecart==p.ecart)
4379     && (pLmCmp(set[length].p,p.p) != currRing->OrdSgn)))
4380    return length+1;
4381
4382  int i;
4383  int an = 0;
4384  int en= length;
4385  loop
4386  {
4387    if (an >= en-1)
4388    {
4389      op = set[an].GetpFDeg()+set[an].ecart;
4390      if (( op > o)
4391      || (( op == o) && (set[an].ecart < p.ecart))
4392      || (( op  == o) && (set[an].ecart==p.ecart)
4393         && (pLmCmp(set[an].p,p.p) == currRing->OrdSgn)))
4394        return an;
4395      return en;
4396    }
4397    i=(an+en) / 2;
4398    op = set[i].GetpFDeg()+set[i].ecart;
4399    if ((op > o)
4400    || (( op == o) && (set[i].ecart < p.ecart))
4401    || (( op == o) && (set[i].ecart == p.ecart)
4402       && (pLmCmp(set[i].p,p.p) == currRing->OrdSgn)))
4403      en=i;
4404    else
4405      an=i;
4406  }
4407}
4408/*2
4409* looks up the position of p in set
4410* set[0] is the smallest with respect to the ordering-procedure
4411* pGetComp, pFDeg+ecart, ecart, pComp
4412*/
4413int posInT17_c (const TSet set,const int length,LObject &p)
4414{
4415  if (length==-1) return 0;
4416
4417  int cc = (-1+2*currRing->order[0]==ringorder_c);
4418  /* cc==1 for (c,..), cc==-1 for (C,..) */
4419  int o = p.GetpFDeg() + p.ecart;
4420  unsigned long c = pGetComp(p.p)*cc;
4421
4422  if (pGetComp(set[length].p)*cc < c)
4423    return length+1;
4424  if (pGetComp(set[length].p)*cc == c)
4425  {
4426    int op = set[length].GetpFDeg()+set[length].ecart;
4427    if ((op < o)
4428    || ((op == o) && (set[length].ecart > p.ecart))
4429    || ((op == o) && (set[length].ecart==p.ecart)
4430       && (pLmCmp(set[length].p,p.p) != currRing->OrdSgn)))
4431      return length+1;
4432  }
4433
4434  int i;
4435  int an = 0;
4436  int en= length;
4437  loop
4438  {
4439    if (an >= en-1)
4440    {
4441      if (pGetComp(set[an].p)*cc < c)
4442        return en;
4443      if (pGetComp(set[an].p)*cc == c)
4444      {
4445        int op = set[an].GetpFDeg()+set[an].ecart;
4446        if ((op > o)
4447        || ((op == o) && (set[an].ecart < p.ecart))
4448        || ((op == o) && (set[an].ecart==p.ecart)
4449           && (pLmCmp(set[an].p,p.p) == currRing->OrdSgn)))
4450          return an;
4451      }
4452      return en;
4453    }
4454    i=(an+en) / 2;
4455    if (pGetComp(set[i].p)*cc > c)
4456      en=i;
4457    else if (pGetComp(set[i].p)*cc == c)
4458    {
4459      int op = set[i].GetpFDeg()+set[i].ecart;
4460      if ((op > o)
4461      || ((op == o) && (set[i].ecart < p.ecart))
4462      || ((op == o) && (set[i].ecart == p.ecart)
4463         && (pLmCmp(set[i].p,p.p) == currRing->OrdSgn)))
4464        en=i;
4465      else
4466        an=i;
4467    }
4468    else
4469      an=i;
4470  }
4471}
4472
4473/*2
4474* looks up the position of p in set
4475* set[0] is the smallest with respect to
4476* ecart, pFDeg, length
4477*/
4478int posInT19 (const TSet set,const int length,LObject &p)
4479{
4480  p.GetpLength();
4481  if (length==-1) return 0;
4482
4483  int o = p.ecart;
4484  int op=p.GetpFDeg();
4485
4486  if (set[length].ecart < o)
4487    return length+1;
4488  if (set[length].ecart == o)
4489  {
4490     int oo=set[length].GetpFDeg();
4491     if ((oo < op) || ((oo==op) && (set[length].length < p.length)))
4492       return length+1;
4493  }
4494
4495  int i;
4496  int an = 0;
4497  int en= length;
4498  loop
4499  {
4500    if (an >= en-1)
4501    {
4502      if (set[an].ecart > o)
4503        return an;
4504      if (set[an].ecart == o)
4505      {
4506         int oo=set[an].GetpFDeg();
4507         if((oo > op)
4508         || ((oo==op) && (set[an].length > p.length)))
4509           return an;
4510      }
4511      return en;
4512    }
4513    i=(an+en) / 2;
4514    if (set[i].ecart > o)
4515      en=i;
4516    else if (set[i].ecart == o)
4517    {
4518       int oo=set[i].GetpFDeg();
4519       if ((oo > op)
4520       || ((oo == op) && (set[i].length > p.length)))
4521         en=i;
4522       else
4523        an=i;
4524    }
4525    else
4526      an=i;
4527  }
4528}
4529
4530/*2
4531*looks up the position of polynomial p in set
4532*set[length] is the smallest element in set with respect
4533*to the ordering-procedure pComp
4534*/
4535int posInLSpecial (const LSet set, const int length,
4536                   LObject *p,const kStrategy)
4537{
4538  if (length<0) return 0;
4539
4540  int d=p->GetpFDeg();
4541  int op=set[length].GetpFDeg();
4542
4543  if ((op > d)
4544  || ((op == d) && (p->p1!=NULL)&&(set[length].p1==NULL))
4545  || (pLmCmp(set[length].p,p->p)== currRing->OrdSgn))
4546     return length+1;
4547
4548  int i;
4549  int an = 0;
4550  int en= length;
4551  loop
4552  {
4553    if (an >= en-1)
4554    {
4555      op=set[an].GetpFDeg();
4556      if ((op > d)
4557      || ((op == d) && (p->p1!=NULL) && (set[an].p1==NULL))
4558      || (pLmCmp(set[an].p,p->p)== currRing->OrdSgn))
4559         return en;
4560      return an;
4561    }
4562    i=(an+en) / 2;
4563    op=set[i].GetpFDeg();
4564    if ((op>d)
4565    || ((op==d) && (p->p1!=NULL) && (set[i].p1==NULL))
4566    || (pLmCmp(set[i].p,p->p) == currRing->OrdSgn))
4567      an=i;
4568    else
4569      en=i;
4570  }
4571}
4572
4573/*2
4574*looks up the position of polynomial p in set
4575*set[length] is the smallest element in set with respect
4576*to the ordering-procedure pComp
4577*/
4578int posInL0 (const LSet set, const int length,
4579             LObject* p,const kStrategy)
4580{
4581  if (length<0) return 0;
4582
4583  if (pLmCmp(set[length].p,p->p)== currRing->OrdSgn)
4584    return length+1;
4585
4586  int i;
4587  int an = 0;
4588  int en= length;
4589  loop
4590  {
4591    if (an >= en-1)
4592    {
4593      if (pLmCmp(set[an].p,p->p) == currRing->OrdSgn) return en;
4594      return an;
4595    }
4596    i=(an+en) / 2;
4597    if (pLmCmp(set[i].p,p->p) == currRing->OrdSgn) an=i;
4598    else                                 en=i;
4599    /*aend. fuer lazy == in !=- machen */
4600  }
4601}
4602
4603/*2
4604* looks up the position of polynomial p in set
4605* e is the ecart of p
4606* set[length] is the smallest element in set with respect
4607* to the signature order
4608*/
4609int posInLSig (const LSet set, const int length,
4610               LObject* p,const kStrategy /*strat*/)
4611{
4612if (length<0) return 0;
4613if (pLmCmp(set[length].sig,p->sig)== currRing->OrdSgn)
4614  return length+1;
4615
4616int i;
4617int an = 0;
4618int en= length;
4619loop
4620{
4621  if (an >= en-1)
4622  {
4623    if (pLmCmp(set[an].sig,p->sig) == currRing->OrdSgn) return en;
4624    return an;
4625  }
4626  i=(an+en) / 2;
4627  if (pLmCmp(set[i].sig,p->sig) == currRing->OrdSgn) an=i;
4628  else                                      en=i;
4629  /*aend. fuer lazy == in !=- machen */
4630}
4631}
4632
4633/*2
4634*
4635* is only used in F5C, must ensure that the interreduction process does add new
4636* critical pairs to strat->L only behind all other critical pairs which are
4637* still in strat->L!
4638*/
4639int posInLF5C (const LSet /*set*/, const int /*length*/,
4640               LObject* /*p*/,const kStrategy strat)
4641{
4642  return strat->Ll+1;
4643}
4644
4645/*2
4646* looks up the position of polynomial p in set
4647* e is the ecart of p
4648* set[length] is the smallest element in set with respect
4649* to the ordering-procedure totaldegree,pComp
4650*/
4651int posInL11 (const LSet set, const int length,
4652              LObject* p,const kStrategy)
4653/*{
4654 * int j=0;
4655 * int o;
4656 *
4657 * o = p->GetpFDeg();
4658 * loop
4659 * {
4660 *   if (j > length)            return j;
4661 *   if ((set[j].GetpFDeg() < o)) return j;
4662 *   if ((set[j].GetpFDeg() == o) && (pLmCmp(set[j].p,p->p) == -currRing->OrdSgn))
4663 *   {
4664 *     return j;
4665 *   }
4666 *   j++;
4667 * }
4668 *}
4669 */
4670{
4671  if (length<0) return 0;
4672
4673  int o = p->GetpFDeg();
4674  int op = set[length].GetpFDeg();
4675
4676  if ((op > o)
4677  || ((op == o) && (pLmCmp(set[length].p,p->p) != -currRing->OrdSgn)))
4678    return length+1;
4679  int i;
4680  int an = 0;
4681  int en= length;
4682  loop
4683  {
4684    if (an >= en-1)
4685    {
4686      op = set[an].GetpFDeg();
4687      if ((op > o)
4688      || ((op == o) && (pLmCmp(set[an].p,p->p) != -currRing->OrdSgn)))
4689        return en;
4690      return an;
4691    }
4692    i=(an+en) / 2;
4693    op = set[i].GetpFDeg();
4694    if ((op > o)
4695    || ((op == o) && (pLmCmp(set[i].p,p->p) != -currRing->OrdSgn)))
4696      an=i;
4697    else
4698      en=i;
4699  }
4700}
4701
4702/*2 Position for rings L: Here I am
4703* looks up the position of polynomial p in set
4704* e is the ecart of p
4705* set[length] is the smallest element in set with respect
4706* to the ordering-procedure totaldegree,pComp
4707*/
4708inline int getIndexRng(long coeff)
4709{
4710  if (coeff == 0) return -1;
4711  long tmp = coeff;
4712  int ind = 0;
4713  while (tmp % 2 == 0)
4714  {
4715    tmp = tmp / 2;
4716    ind++;
4717  }
4718  return ind;
4719}
4720
4721int posInLrg0 (const LSet set, const int length,
4722              LObject* p,const kStrategy)
4723/*          if (nGreater(pGetCoeff(p), pGetCoeff(set[an]))) return en;
4724        if (pLmCmp(set[i],p) == cmp_int)         en = i;
4725        else if (pLmCmp(set[i],p) == -cmp_int)   an = i;
4726        else
4727        {
4728          if (nGreater(pGetCoeff(p), pGetCoeff(set[i]))) an = i;
4729          else en = i;
4730        }*/
4731{
4732  if (length < 0) return 0;
4733
4734  int o = p->GetpFDeg();
4735  int op = set[length].GetpFDeg();
4736
4737  if ((op > o) || ((op == o) && (pLmCmp(set[length].p,p->p) != -currRing->OrdSgn)))
4738    return length + 1;
4739  int i;
4740  int an = 0;
4741  int en = length;
4742  loop
4743  {
4744    if (an >= en - 1)
4745    {
4746      op = set[an].GetpFDeg();
4747      if ((op > o) || ((op == o) && (pLmCmp(set[an].p,p->p) != -currRing->OrdSgn)))
4748        return en;
4749      return an;
4750    }
4751    i = (an+en) / 2;
4752    op = set[i].GetpFDeg();
4753    if ((op > o) || ((op == o) && (pLmCmp(set[i].p,p->p) != -currRing->OrdSgn)))
4754      an = i;
4755    else
4756      en = i;
4757  }
4758}
4759
4760/*{
4761  if (length < 0) return 0;
4762
4763  int o = p->GetpFDeg();
4764  int op = set[length].GetpFDeg();
4765
4766  int inde = getIndexRng((unsigned long) pGetCoeff(set[length].p));
4767  int indp = getIndexRng((unsigned long) pGetCoeff(p->p));
4768  int inda;
4769  int indi;
4770
4771  if ((inda > indp) || ((inda == inde) && ((op > o) || ((op == o) && (pLmCmp(set[length].p,p->p) != -currRing->OrdSgn)))))
4772    return length + 1;
4773  int i;
4774  int an = 0;
4775  inda = getIndexRng((unsigned long) pGetCoeff(set[an].p));
4776  int en = length;
4777  loop
4778  {
4779    if (an >= en-1)
4780    {
4781      op = set[an].GetpFDeg();
4782      if ((indp > inda) || ((indp == inda) && ((op > o) || ((op == o) && (pLmCmp(set[an].p,p->p) != -currRing->OrdSgn)))))
4783        return en;
4784      return an;
4785    }
4786    i = (an + en) / 2;
4787    indi = getIndexRng((unsigned long) pGetCoeff(set[i].p));
4788    op = set[i].GetpFDeg();
4789    if ((indi > indp) || ((indi == indp) && ((op > o) || ((op == o) && (pLmCmp(set[i].p,p->p) != -currRing->OrdSgn)))))
4790    // if ((op > o) || ((op == o) && (pLmCmp(set[i].p,p->p) != -currRing->OrdSgn)))
4791    {
4792      an = i;
4793      inda = getIndexRng((unsigned long) pGetCoeff(set[an].p));
4794    }
4795    else
4796      en = i;
4797  }
4798} */
4799
4800/*2
4801* looks up the position of polynomial p in set
4802* set[length] is the smallest element in set with respect
4803* to the ordering-procedure totaldegree,pLength0
4804*/
4805int posInL110 (const LSet set, const int length,
4806               LObject* p,const kStrategy)
4807{
4808  if (length<0) return 0;
4809
4810  int o = p->GetpFDeg();
4811  int op = set[length].GetpFDeg();
4812
4813  if ((op > o)
4814  || ((op == o) && (set[length].length >p->length))
4815  || ((op == o) && (set[length].length <= p->length)
4816     && (pLmCmp(set[length].p,p->p) != -currRing->OrdSgn)))
4817    return length+1;
4818  int i;
4819  int an = 0;
4820  int en= length;
4821  loop
4822  {
4823    if (an >= en-1)
4824    {
4825      op = set[an].GetpFDeg();
4826      if ((op > o)
4827      || ((op == o) && (set[an].length >p->length))
4828      || ((op == o) && (set[an].length <=p->length)
4829         && (pLmCmp(set[an].p,p->p) != -currRing->OrdSgn)))
4830        return en;
4831      return an;
4832    }
4833    i=(an+en) / 2;
4834    op = set[i].GetpFDeg();
4835    if ((op > o)
4836    || ((op == o) && (set[i].length > p->length))
4837    || ((op == o) && (set[i].length <= p->length)
4838       && (pLmCmp(set[i].p,p->p) != -currRing->OrdSgn)))
4839      an=i;
4840    else
4841      en=i;
4842  }
4843}
4844
4845/*2
4846* looks up the position of polynomial p in set
4847* e is the ecart of p
4848* set[length] is the smallest element in set with respect
4849* to the ordering-procedure totaldegree
4850*/
4851int posInL13 (const LSet set, const int length,
4852              LObject* p,const kStrategy)
4853{
4854  if (length<0) return 0;
4855
4856  int o = p->GetpFDeg();
4857
4858  if (set[length].GetpFDeg() > o)
4859    return length+1;
4860
4861  int i;
4862  int an = 0;
4863  int en= length;
4864  loop
4865  {
4866    if (an >= en-1)
4867    {
4868      if (set[an].GetpFDeg() >= o)
4869        return en;
4870      return an;
4871    }
4872    i=(an+en) / 2;
4873    if (set[i].GetpFDeg() >= o)
4874      an=i;
4875    else
4876      en=i;
4877  }
4878}
4879
4880/*2
4881* looks up the position of polynomial p in set
4882* e is the ecart of p
4883* set[length] is the smallest element in set with respect
4884* to the ordering-procedure maximaldegree,pComp
4885*/
4886int posInL15 (const LSet set, const int length,
4887              LObject* p,const kStrategy)
4888/*{
4889 * int j=0;
4890 * int o;
4891 *
4892 * o = p->ecart+p->GetpFDeg();
4893 * loop
4894 * {
4895 *   if (j > length)                       return j;
4896 *   if (set[j].GetpFDeg()+set[j].ecart < o) return j;
4897 *   if ((set[j].GetpFDeg()+set[j].ecart == o)
4898 *   && (pLmCmp(set[j].p,p->p) == -currRing->OrdSgn))
4899 *   {
4900 *     return j;
4901 *   }
4902 *   j++;
4903 * }
4904 *}
4905 */
4906{
4907  if (length<0) return 0;
4908
4909  int o = p->GetpFDeg() + p->ecart;
4910  int op = set[length].GetpFDeg() + set[length].ecart;
4911
4912  if ((op > o)
4913  || ((op == o) && (pLmCmp(set[length].p,p->p) != -currRing->OrdSgn)))
4914    return length+1;
4915  int i;
4916  int an = 0;
4917  int en= length;
4918  loop
4919  {
4920    if (an >= en-1)
4921    {
4922      op = set[an].GetpFDeg() + set[an].ecart;
4923      if ((op > o)
4924      || ((op == o) && (pLmCmp(set[an].p,p->p) != -currRing->OrdSgn)))
4925        return en;
4926      return an;
4927    }
4928    i=(an+en) / 2;
4929    op = set[i].GetpFDeg() + set[i].ecart;
4930    if ((op > o)
4931    || ((op == o) && (pLmCmp(set[i].p,p->p) != -currRing->OrdSgn)))
4932      an=i;
4933    else
4934      en=i;
4935  }
4936}
4937
4938/*2
4939* looks up the position of polynomial p in set
4940* e is the ecart of p
4941* set[length] is the smallest element in set with respect
4942* to the ordering-procedure totaldegree
4943*/
4944int posInL17 (const LSet set, const int length,
4945              LObject* p,const kStrategy)
4946{
4947  if (length<0) return 0;
4948
4949  int o = p->GetpFDeg() + p->ecart;
4950
4951  if ((set[length].GetpFDeg() + set[length].ecart > o)
4952  || ((set[length].GetpFDeg() + set[length].ecart == o)
4953     && (set[length].ecart > p->ecart))
4954  || ((set[length].GetpFDeg() + set[length].ecart == o)
4955     && (set[length].ecart == p->ecart)
4956     && (pLmCmp(set[length].p,p->p) != -currRing->OrdSgn)))
4957    return length+1;
4958  int i;
4959  int an = 0;
4960  int en= length;
4961  loop
4962  {
4963    if (an >= en-1)
4964    {
4965      if ((set[an].GetpFDeg() + set[an].ecart > o)
4966      || ((set[an].GetpFDeg() + set[an].ecart == o)
4967         && (set[an].ecart > p->ecart))
4968      || ((set[an].GetpFDeg() + set[an].ecart == o)
4969         && (set[an].ecart == p->ecart)
4970         && (pLmCmp(set[an].p,p->p) != -currRing->OrdSgn)))
4971        return en;
4972      return an;
4973    }
4974    i=(an+en) / 2;
4975    if ((set[i].GetpFDeg() + set[i].ecart > o)
4976    || ((set[i].GetpFDeg() + set[i].ecart == o)
4977       && (set[i].ecart > p->ecart))
4978    || ((set[i].GetpFDeg() +set[i].ecart == o)
4979       && (set[i].ecart == p->ecart)
4980       && (pLmCmp(set[i].p,p->p) != -currRing->OrdSgn)))
4981      an=i;
4982    else
4983      en=i;
4984  }
4985}
4986/*2
4987* looks up the position of polynomial p in set
4988* e is the ecart of p
4989* set[length] is the smallest element in set with respect
4990* to the ordering-procedure pComp
4991*/
4992int posInL17_c (const LSet set, const int length,
4993                LObject* p,const kStrategy)
4994{
4995  if (length<0) return 0;
4996
4997  int cc = (-1+2*currRing->order[0]==ringorder_c);
4998  /* cc==1 for (c,..), cc==-1 for (C,..) */
4999  unsigned long c = pGetComp(p->p)*cc;
5000  int o = p->GetpFDeg() + p->ecart;
5001
5002  if (pGetComp(set[length].p)*cc > c)
5003    return length+1;
5004  if (pGetComp(set[length].p)*cc == c)
5005  {
5006    if ((set[length].GetpFDeg() + set[length].ecart > o)
5007    || ((set[length].GetpFDeg() + set[length].ecart == o)
5008       && (set[length].ecart > p->ecart))
5009    || ((set[length].GetpFDeg() + set[length].ecart == o)
5010       && (set[length].ecart == p->ecart)
5011       && (pLmCmp(set[length].p,p->p) != -currRing->OrdSgn)))
5012      return length+1;
5013  }
5014  int i;
5015  int an = 0;
5016  int en= length;
5017  loop
5018  {
5019    if (an >= en-1)
5020    {
5021      if (pGetComp(set[an].p)*cc > c)
5022        return en;
5023      if (pGetComp(set[an].p)*cc == c)
5024      {
5025        if ((set[an].GetpFDeg() + set[an].ecart > o)
5026        || ((set[an].GetpFDeg() + set[an].ecart == o)
5027           && (set[an].ecart > p->ecart))
5028        || ((set[an].GetpFDeg() + set[an].ecart == o)
5029           && (set[an].ecart == p->ecart)
5030           && (pLmCmp(set[an].p,p->p) != -currRing->OrdSgn)))
5031          return en;
5032      }
5033      return an;
5034    }
5035    i=(an+en) / 2;
5036    if (pGetComp(set[i].p)*cc > c)
5037      an=i;
5038    else if (pGetComp(set[i].p)*cc == c)
5039    {
5040      if ((set[i].GetpFDeg() + set[i].ecart > o)
5041      || ((set[i].GetpFDeg() + set[i].ecart == o)
5042         && (set[i].ecart > p->ecart))
5043      || ((set[i].GetpFDeg() +set[i].ecart == o)
5044         && (set[i].ecart == p->ecart)
5045         && (pLmCmp(set[i].p,p->p) != -currRing->OrdSgn)))
5046        an=i;
5047      else
5048        en=i;
5049    }
5050    else
5051      en=i;
5052  }
5053}
5054
5055/*
5056 * SYZYGY CRITERION for signature-based standard basis algorithms
5057 */
5058BOOLEAN syzCriterion(poly sig, unsigned long not_sevSig, kStrategy strat)
5059{
5060//#if 1
5061#ifdef DEBUGF5
5062  Print("syzygy criterion checks:  ");
5063  pWrite(sig);
5064#endif
5065  for (int k=0; k<strat->syzl; k++)
5066  {
5067//#if 1
5068#ifdef DEBUGF5
5069    Print("checking with: %d --  ",k);
5070    pWrite(pHead(strat->syz[k]));
5071#endif
5072    if (p_LmShortDivisibleBy(strat->syz[k], strat->sevSyz[k], sig, not_sevSig, currRing))
5073    {
5074//#if 1
5075#ifdef DEBUGF5
5076      printf("DELETE!\n");
5077#endif
5078      return TRUE;
5079    }
5080  }
5081  return FALSE;
5082}
5083
5084/*
5085 * SYZYGY CRITERION for signature-based standard basis algorithms
5086 */
5087BOOLEAN syzCriterionInc(poly sig, unsigned long not_sevSig, kStrategy strat)
5088{
5089//#if 1
5090#ifdef DEBUGF5
5091  Print("syzygy criterion checks:  ");
5092  pWrite(sig);
5093#endif
5094  int comp = p_GetComp(sig, currRing);
5095  int min, max;
5096  if (comp<=1)
5097    return FALSE;
5098  else
5099  {
5100    min = strat->syzIdx[comp-2];
5101    //printf("SYZIDX %d/%d\n",strat->syzIdx[comp-2],comp-2);
5102    //printf("SYZIDX %d/%d\n",strat->syzIdx[comp-1],comp-1);
5103    //printf("SYZIDX %d/%d\n",strat->syzIdx[comp],comp);
5104    if (comp == strat->currIdx)
5105    {
5106      max = strat->syzl;
5107    }
5108    else
5109    {
5110      max = strat->syzIdx[comp-1];
5111    }
5112    for (int k=min; k<max; k++)
5113    {
5114#ifdef DEBUGF5
5115      printf("COMP %d/%d - MIN %d - MAX %d - SYZL %ld\n",comp,strat->currIdx,min,max,strat->syzl);
5116      Print("checking with: %d --  ",k);
5117      pWrite(pHead(strat->syz[k]));
5118#endif
5119      if (p_LmShortDivisibleBy(strat->syz[k], strat->sevSyz[k], sig, not_sevSig, currRing))
5120        return TRUE;
5121    }
5122    return FALSE;
5123  }
5124}
5125
5126/*
5127 * REWRITTEN CRITERION for signature-based standard basis algorithms
5128 */
5129BOOLEAN faugereRewCriterion(poly sig, unsigned long not_sevSig, kStrategy strat, int start=0)
5130{
5131  //printf("Faugere Rewritten Criterion\n");
5132//#if 1
5133#ifdef DEBUGF5
5134  printf("rewritten criterion checks:  ");
5135  pWrite(sig);
5136#endif
5137  //for(int k = start; k<strat->sl+1; k++)
5138  for(int k = strat->sl; k>start; k--)
5139  {
5140//#if 1
5141#ifdef DEBUGF5
5142    Print("checking with:  ");
5143    pWrite(strat->sig[k]);
5144    pWrite(pHead(strat->S[k]));
5145#endif
5146    if (p_LmShortDivisibleBy(strat->sig[k], strat->sevSig[k], sig, not_sevSig, currRing))
5147    //if (p_LmEqual(strat->sig[k], sig, currRing))
5148    {
5149//#if 1
5150#ifdef DEBUGF5
5151      printf("DELETE!\n");
5152#endif
5153      return TRUE;
5154    }
5155  }
5156#ifdef DEBUGF5
5157  Print("ALL ELEMENTS OF S\n----------------------------------------\n");
5158  for(int kk = 0; kk<strat->sl+1; kk++)
5159  {
5160    pWrite(pHead(strat->S[kk]));
5161  }
5162  Print("------------------------------\n");
5163#endif
5164  return FALSE;
5165}
5166
5167/*
5168 * REWRITTEN CRITERION for signature-based standard basis algorithms
5169 ***************************************************************************
5170 * TODO:This should become the version of Arri/Perry resp. Bjarke/Stillman *
5171 ***************************************************************************
5172 */
5173
5174// real implementation of arri's rewritten criterion, only called once in
5175// kstd2.cc, right before starting reduction
5176// IDEA:  Arri says that it is enough to consider 1 polynomial for each unique
5177//        signature appearing during the computations. Thus we first of all go
5178//        through strat->L and delete all other pairs of the same signature,
5179//        keeping only the one with least possible leading monomial. After this
5180//        we check if we really need to compute this critical pair at all: There
5181//        can be elements already in strat->S whose signatures divide the
5182//        signature of the critical pair in question and whose multiplied
5183//        leading monomials are smaller than the leading monomial of the
5184//        critical pair. In this situation we can discard the critical pair
5185//        completely.
5186BOOLEAN arriRewCriterion(poly /*sig*/, unsigned long /*not_sevSig*/, kStrategy strat, int /*start=0*/)
5187{
5188  //printf("Arri Rewritten Criterion\n");
5189  while (strat->Ll > 0 && pLmEqual(strat->L[strat->Ll].sig,strat->P.sig))
5190  {
5191    if (strat->P.GetLmCurrRing() == NULL)
5192    {
5193      deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
5194    }
5195    if (strat->L[strat->Ll].GetLmCurrRing() == NULL)
5196    {
5197      pDelete(&strat->P.sig);
5198      strat->P.Delete();
5199      strat->P = strat->L[strat->Ll];
5200      strat->Ll--;
5201    }
5202
5203    if ((strat->P.GetLmCurrRing() != NULL)
5204    && (strat->L[strat->Ll].GetLmCurrRing() != NULL))
5205    {
5206      if (pLmCmp(strat->P.GetLmCurrRing(),strat->L[strat->Ll].GetLmCurrRing()) == -1)
5207      {
5208        deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
5209      }
5210      else
5211      {
5212        pDelete(&strat->P.sig);
5213        strat->P = strat->L[strat->Ll];
5214        strat->Ll--;
5215      }
5216    }
5217  }
5218  poly p1 = pOne();
5219  poly p2 = pOne();
5220  for (int ii=strat->sl; ii>-1; ii--)
5221  {
5222    if (p_LmShortDivisibleBy(strat->sig[ii], strat->sevSig[ii], strat->P.sig, ~strat->P.sevSig, currRing))
5223    {
5224      p_ExpVectorSum(p1,strat->P.sig,strat->S[ii],currRing);
5225      p_ExpVectorSum(p2,strat->sig[ii],strat->P.p,currRing);
5226      if (!(pLmCmp(p1,p2) == 1))
5227      {
5228        pDelete(&strat->P.sig);
5229        pDelete(&p1);
5230        pDelete(&p2);
5231        return TRUE;
5232      }
5233    }
5234  }
5235  pDelete(&p1);
5236  pDelete(&p2);
5237  return FALSE;
5238}
5239
5240/***************************************************************
5241 *
5242 * Tail reductions
5243 *
5244 ***************************************************************/
5245TObject*
5246kFindDivisibleByInS(kStrategy strat, int pos, LObject* L, TObject *T,
5247                    long ecart)
5248{
5249  int j = 0;
5250  const unsigned long not_sev = ~L->sev;
5251  const unsigned long* sev = strat->sevS;
5252  poly p;
5253  ring r;
5254  L->GetLm(p, r);
5255
5256  assume(~not_sev == p_GetShortExpVector(p, r));
5257
5258  if (r == currRing)
5259  {
5260    loop
5261    {
5262      if (j > pos) return NULL;
5263#if defined(PDEBUG) || defined(PDIV_DEBUG)
5264      if (p_LmShortDivisibleBy(strat->S[j], sev[j], p, not_sev, r) &&
5265          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
5266        break;
5267#else
5268      if (!(sev[j] & not_sev) &&
5269          (ecart== LONG_MAX || ecart>= strat->ecartS[j]) &&
5270          p_LmDivisibleBy(strat->S[j], p, r))
5271        break;
5272
5273#endif
5274      j++;
5275    }
5276    // if called from NF, T objects do not exist:
5277    if (strat->tl < 0 || strat->S_2_R[j] == -1)
5278    {
5279      T->Set(strat->S[j], r, strat->tailRing);
5280      return T;
5281    }
5282    else
5283    {
5284/////      assume (j >= 0 && j <= strat->tl && strat->S_2_T(j) != NULL
5285/////      && strat->S_2_T(j)->p == strat->S[j]); // wrong?
5286//      assume (j >= 0 && j <= strat->sl && strat->S_2_T(j) != NULL && strat->S_2_T(j)->p == strat->S[j]);
5287      return strat->S_2_T(j);
5288    }
5289  }
5290  else
5291  {
5292    TObject* t;
5293    loop
5294    {
5295      if (j > pos) return NULL;
5296      assume(strat->S_2_R[j] != -1);
5297#if defined(PDEBUG) || defined(PDIV_DEBUG)
5298      t = strat->S_2_T(j);
5299      assume(t != NULL && t->t_p != NULL && t->tailRing == r);
5300      if (p_LmShortDivisibleBy(t->t_p, sev[j], p, not_sev, r) &&
5301          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
5302        return t;
5303#else
5304      if (! (sev[j] & not_sev) && (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
5305      {
5306        t = strat->S_2_T(j);
5307        assume(t != NULL && t->t_p != NULL && t->tailRing == r && t->p == strat->S[j]);
5308        if (p_LmDivisibleBy(t->t_p, p, r)) return t;
5309      }
5310#endif
5311      j++;
5312    }
5313  }
5314}
5315
5316poly redtail (LObject* L, int pos, kStrategy strat)
5317{
5318  poly h, hn;
5319  strat->redTailChange=FALSE;
5320
5321  poly p = L->p;
5322  if (strat->noTailReduction || pNext(p) == NULL)
5323    return p;
5324
5325  LObject Ln(strat->tailRing);
5326  TObject* With;
5327  // placeholder in case strat->tl < 0
5328  TObject  With_s(strat->tailRing);
5329  h = p;
5330  hn = pNext(h);
5331  long op = strat->tailRing->pFDeg(hn, strat->tailRing);
5332  long e;
5333  int l;
5334  BOOLEAN save_HE=strat->kHEdgeFound;
5335  strat->kHEdgeFound |=
5336    ((Kstd1_deg>0) && (op<=Kstd1_deg)) || TEST_OPT_INFREDTAIL;
5337
5338  while(hn != NULL)
5339  {
5340    op = strat->tailRing->pFDeg(hn, strat->tailRing);
5341    if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
5342    e = strat->tailRing->pLDeg(hn, &l, strat->tailRing) - op;
5343    loop
5344    {
5345      Ln.Set(hn, strat->tailRing);
5346      Ln.sev = p_GetShortExpVector(hn, strat->tailRing);
5347      if (strat->kHEdgeFound)
5348        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
5349      else
5350        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s, e);
5351      if (With == NULL) break;
5352      With->length=0;
5353      With->pLength=0;
5354      strat->redTailChange=TRUE;
5355      if (ksReducePolyTail(L, With, h, strat->kNoetherTail()))
5356      {
5357        // reducing the tail would violate the exp bound
5358        if (kStratChangeTailRing(strat, L))
5359        {
5360          strat->kHEdgeFound = save_HE;
5361          return redtail(L, pos, strat);
5362        }
5363        else
5364          return NULL;
5365      }
5366      hn = pNext(h);
5367      if (hn == NULL) goto all_done;
5368      op = strat->tailRing->pFDeg(hn, strat->tailRing);
5369      if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
5370      e = strat->tailRing->pLDeg(hn, &l, strat->tailRing) - op;
5371    }
5372    h = hn;
5373    hn = pNext(h);
5374  }
5375
5376  all_done:
5377  if (strat->redTailChange)
5378  {
5379    L->pLength = 0;
5380  }
5381  strat->kHEdgeFound = save_HE;
5382  return p;
5383}
5384
5385poly redtail (poly p, int pos, kStrategy strat)
5386{
5387  LObject L(p, currRing);
5388  return redtail(&L, pos, strat);
5389}
5390
5391poly redtailBba (LObject* L, int pos, kStrategy strat, BOOLEAN withT, BOOLEAN normalize)
5392{
5393#define REDTAIL_CANONICALIZE 100
5394  strat->redTailChange=FALSE;
5395  if (strat->noTailReduction) return L->GetLmCurrRing();
5396  poly h, p;
5397  p = h = L->GetLmTailRing();
5398  if ((h==NULL) || (pNext(h)==NULL))
5399    return L->GetLmCurrRing();
5400
5401  TObject* With;
5402  // placeholder in case strat->tl < 0
5403  TObject  With_s(strat->tailRing);
5404
5405  LObject Ln(pNext(h), strat->tailRing);
5406  Ln.pLength = L->GetpLength() - 1;
5407
5408  pNext(h) = NULL;
5409  if (L->p != NULL) pNext(L->p) = NULL;
5410  L->pLength = 1;
5411
5412  Ln.PrepareRed(strat->use_buckets);
5413
5414  int cnt=REDTAIL_CANONICALIZE;
5415  while(!Ln.IsNull())
5416  {
5417    loop
5418    {
5419      Ln.SetShortExpVector();
5420      if (withT)
5421      {
5422        int j;
5423        j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln);
5424        if (j < 0) break;
5425        With = &(strat->T[j]);
5426      }
5427      else
5428      {
5429        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
5430        if (With == NULL) break;
5431      }
5432      cnt--;
5433      if (cnt==0)
5434      {
5435        cnt=REDTAIL_CANONICALIZE;
5436        /*poly tmp=*/Ln.CanonicalizeP();
5437        if (normalize)
5438        {
5439          Ln.Normalize();
5440          //pNormalize(tmp);
5441          //if (TEST_OPT_PROT) { PrintS("n"); mflush(); }
5442        }
5443      }
5444      if (normalize && (!TEST_OPT_INTSTRATEGY) && (!nIsOne(pGetCoeff(With->p))))
5445      {
5446        With->pNorm();
5447      }
5448      strat->redTailChange=TRUE;
5449      if (ksReducePolyTail(L, With, &Ln))
5450      {
5451        // reducing the tail would violate the exp bound
5452        //  set a flag and hope for a retry (in bba)
5453        strat->completeReduce_retry=TRUE;
5454        if ((Ln.p != NULL) && (Ln.t_p != NULL)) Ln.p=NULL;
5455        do
5456        {
5457          pNext(h) = Ln.LmExtractAndIter();
5458          pIter(h);
5459          L->pLength++;
5460        } while (!Ln.IsNull());
5461        goto all_done;
5462      }
5463      if (Ln.IsNull()) goto all_done;
5464      if (! withT) With_s.Init(currRing);
5465    }
5466    pNext(h) = Ln.LmExtractAndIter();
5467    pIter(h);
5468    pNormalize(h);
5469    L->pLength++;
5470  }
5471
5472  all_done:
5473  Ln.Delete();
5474  if (L->p != NULL) pNext(L->p) = pNext(p);
5475
5476  if (strat->redTailChange)
5477  {
5478    L->length = 0;
5479  }
5480
5481  //if (TEST_OPT_PROT) { PrintS("N"); mflush(); }
5482  //L->Normalize(); // HANNES: should have a test
5483  assume(kTest_L(L));
5484  return L->GetLmCurrRing();
5485}
5486
5487#ifdef HAVE_RINGS
5488poly redtailBba_Z (LObject* L, int pos, kStrategy strat )
5489// normalize=FALSE, withT=FALSE, coeff=Z
5490{
5491  strat->redTailChange=FALSE;
5492  if (strat->noTailReduction) return L->GetLmCurrRing();
5493  poly h, p;
5494  p = h = L->GetLmTailRing();
5495  if ((h==NULL) || (pNext(h)==NULL))
5496    return L->GetLmCurrRing();
5497
5498  TObject* With;
5499  // placeholder in case strat->tl < 0
5500  TObject  With_s(strat->tailRing);
5501
5502  LObject Ln(pNext(h), strat->tailRing);
5503  Ln.pLength = L->GetpLength() - 1;
5504
5505  pNext(h) = NULL;
5506  if (L->p != NULL) pNext(L->p) = NULL;
5507  L->pLength = 1;
5508
5509  Ln.PrepareRed(strat->use_buckets);
5510
5511  int cnt=REDTAIL_CANONICALIZE;
5512  while(!Ln.IsNull())
5513  {
5514    loop
5515    {
5516      Ln.SetShortExpVector();
5517      With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
5518      if (With == NULL) break;
5519      cnt--;
5520      if (cnt==0)
5521      {
5522        cnt=REDTAIL_CANONICALIZE;
5523        /*poly tmp=*/Ln.CanonicalizeP();
5524      }
5525      // we are in Z, do not call pNorm
5526      strat->redTailChange=TRUE;
5527      // test divisibility of coefs:
5528      poly p_Ln=Ln.GetLmCurrRing();
5529      poly p_With=With->GetLmCurrRing();
5530      number z=n_IntMod(pGetCoeff(p_Ln),pGetCoeff(p_With), currRing->cf);
5531      if (!nIsZero(z))
5532      {
5533        // subtract z*Ln, add z.Ln to L
5534        poly m=pHead(p_Ln);
5535        pSetCoeff(m,z);
5536        poly mm=pHead(m);
5537        pNext(h) = m;
5538        pIter(h);
5539        L->pLength++;
5540        mm=pNeg(mm);
5541        if (Ln.bucket!=NULL)
5542        {
5543          int dummy=1;
5544          kBucket_Add_q(Ln.bucket,mm,&dummy);
5545        }
5546        else
5547        {
5548          if (Ln.p!=NULL) Ln.p=pAdd(Ln.p,mm);
5549          else if (Ln.t_p!=NULL)  Ln.t_p=p_Add_q(Ln.t_p,mm,strat->tailRing);
5550        }
5551      }
5552      else
5553        nDelete(&z);
5554
5555      if (ksReducePolyTail(L, With, &Ln))
5556      {
5557        // reducing the tail would violate the exp bound
5558        //  set a flag and hope for a retry (in bba)
5559        strat->completeReduce_retry=TRUE;
5560        if ((Ln.p != NULL) && (Ln.t_p != NULL)) Ln.p=NULL;
5561        do
5562        {
5563          pNext(h) = Ln.LmExtractAndIter();
5564          pIter(h);
5565          L->pLength++;
5566        } while (!Ln.IsNull());
5567        goto all_done;
5568      }
5569      if (Ln.IsNull()) goto all_done;
5570      With_s.Init(currRing);
5571    }
5572    pNext(h) = Ln.LmExtractAndIter();
5573    pIter(h);
5574    pNormalize(h);
5575    L->pLength++;
5576  }
5577
5578  all_done:
5579  Ln.Delete();
5580  if (L->p != NULL) pNext(L->p) = pNext(p);
5581
5582  if (strat->redTailChange)
5583  {
5584    L->length = 0;
5585  }
5586
5587  //if (TEST_OPT_PROT) { PrintS("N"); mflush(); }
5588  //L->Normalize(); // HANNES: should have a test
5589  assume(kTest_L(L));
5590  return L->GetLmCurrRing();
5591}
5592#endif
5593
5594/*2
5595*checks the change degree and write progress report
5596*/
5597void message (int i,int* reduc,int* olddeg,kStrategy strat, int red_result)
5598{
5599  if (i != *olddeg)
5600  {
5601    Print("%d",i);
5602    *olddeg = i;
5603  }
5604  if (TEST_OPT_OLDSTD)
5605  {
5606    if (strat->Ll != *reduc)
5607    {
5608      if (strat->Ll != *reduc-1)
5609        Print("(%d)",strat->Ll+1);
5610      else
5611        PrintS("-");
5612      *reduc = strat->Ll;
5613    }
5614    else
5615      PrintS(".");
5616    mflush();
5617  }
5618  else
5619  {
5620    if (red_result == 0)
5621      PrintS("-");
5622    else if (red_result < 0)
5623      PrintS(".");
5624    if ((red_result > 0) || ((strat->Ll % 100)==99))
5625    {
5626      if (strat->Ll != *reduc && strat->Ll > 0)
5627      {
5628        Print("(%d)",strat->Ll+1);
5629        *reduc = strat->Ll;
5630      }
5631    }
5632  }
5633}
5634
5635/*2
5636*statistics
5637*/
5638void messageStat (int hilbcount,kStrategy strat)
5639{
5640  //PrintS("\nUsage/Allocation of temporary storage:\n");
5641  //Print("%d/%d polynomials in standard base\n",srmax,IDELEMS(Shdl));
5642  //Print("%d/%d polynomials in set L (for lazy alg.)",lrmax+1,strat->Lmax);
5643  Print("product criterion:%d chain criterion:%d\n",strat->cp,strat->c3);
5644  if (hilbcount!=0) Print("hilbert series criterion:%d\n",hilbcount);
5645  /* in usual case strat->cv is 0, it gets changed only in shift routines */
5646  if (strat->cv!=0) Print("shift V criterion:%d\n",strat->cv);
5647  /*mflush();*/
5648}
5649
5650#ifdef KDEBUG
5651/*2
5652*debugging output: all internal sets, if changed
5653*for testing purpuse only/has to be changed for later use
5654*/
5655void messageSets (kStrategy strat)
5656{
5657  int i;
5658  if (strat->news)
5659  {
5660    PrintS("set S");
5661    for (i=0; i<=strat->sl; i++)
5662    {
5663      Print("\n  %d:",i);
5664      p_wrp(strat->S[i], currRing, strat->tailRing);
5665    }
5666    strat->news = FALSE;
5667  }
5668  if (strat->newt)
5669  {
5670    PrintS("\nset T");
5671    for (i=0; i<=strat->tl; i++)
5672    {
5673      Print("\n  %d:",i);
5674      strat->T[i].wrp();
5675      Print(" o:%ld e:%d l:%d",
5676        strat->T[i].pFDeg(),strat->T[i].ecart,strat->T[i].length);
5677    }
5678    strat->newt = FALSE;
5679  }
5680  PrintS("\nset L");
5681  for (i=strat->Ll; i>=0; i--)
5682  {
5683    Print("\n%d:",i);
5684    p_wrp(strat->L[i].p1, currRing, strat->tailRing);
5685    PrintS("  ");
5686    p_wrp(strat->L[i].p2, currRing, strat->tailRing);
5687    PrintS(" lcm: ");p_wrp(strat->L[i].lcm, currRing);
5688    PrintS("\n  p : ");
5689    strat->L[i].wrp();
5690    Print("  o:%ld e:%d l:%d",
5691          strat->L[i].pFDeg(),strat->L[i].ecart,strat->L[i].length);
5692  }
5693  PrintLn();
5694}
5695
5696#endif
5697
5698
5699/*2
5700*construct the set s from F
5701*/
5702void initS (ideal F, ideal Q, kStrategy strat)
5703{
5704  int   i,pos;
5705
5706  if (Q!=NULL) i=((IDELEMS(F)+IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
5707  else         i=((IDELEMS(F)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
5708  strat->ecartS=initec(i);
5709  strat->sevS=initsevS(i);
5710  strat->S_2_R=initS_2_R(i);
5711  strat->fromQ=NULL;
5712  strat->Shdl=idInit(i,F->rank);
5713  strat->S=strat->Shdl->m;
5714  /*- put polys into S -*/
5715  if (Q!=NULL)
5716  {
5717    strat->fromQ=initec(i);
5718    memset(strat->fromQ,0,i*sizeof(int));
5719    for (i=0; i<IDELEMS(Q); i++)
5720    {
5721      if (Q->m[i]!=NULL)
5722      {
5723        LObject h;
5724        h.p = pCopy(Q->m[i]);
5725        if (TEST_OPT_INTSTRATEGY)
5726        {
5727          //pContent(h.p);
5728          h.pCleardenom(); // also does a pContent
5729        }
5730        else
5731        {
5732          h.pNorm();
5733        }
5734        if (currRing->OrdSgn==-1)
5735        {
5736          deleteHC(&h, strat);
5737        }
5738        if (h.p!=NULL)
5739        {
5740          strat->initEcart(&h);
5741          if (strat->sl==-1)
5742            pos =0;
5743          else
5744          {
5745            pos = posInS(strat,strat->sl,h.p,h.ecart);
5746          }
5747          h.sev = pGetShortExpVector(h.p);
5748          strat->enterS(h,pos,strat,-1);
5749          strat->fromQ[pos]=1;
5750        }
5751      }
5752    }
5753  }
5754  for (i=0; i<IDELEMS(F); i++)
5755  {
5756    if (F->m[i]!=NULL)
5757    {
5758      LObject h;
5759      h.p = pCopy(F->m[i]);
5760      if (currRing->OrdSgn==-1)
5761      {
5762                    /*#ifdef HAVE_RINGS
5763                          if (rField_is_Ring(currRing))
5764                            {
5765                            h.pCleardenom();
5766                            }
5767                          else
5768                                #endif*/
5769        cancelunit(&h);  /*- tries to cancel a unit -*/
5770        deleteHC(&h, strat);
5771      }
5772      if (h.p!=NULL)
5773      // do not rely on the input being a SB!
5774      {
5775        if (TEST_OPT_INTSTRATEGY)
5776        {
5777          //pContent(h.p);
5778          h.pCleardenom(); // also does a pContent
5779        }
5780        else
5781        {
5782          h.pNorm();
5783        }
5784        strat->initEcart(&h);
5785        if (strat->sl==-1)
5786          pos =0;
5787        else
5788          pos = posInS(strat,strat->sl,h.p,h.ecart);
5789        h.sev = pGetShortExpVector(h.p);
5790        strat->enterS(h,pos,strat,-1);
5791      }
5792    }
5793  }
5794  /*- test, if a unit is in F -*/
5795  if ((strat->sl>=0)
5796#ifdef HAVE_RINGS
5797       && n_IsUnit(pGetCoeff(strat->S[0]),currRing->cf)
5798#endif
5799       && pIsConstant(strat->S[0]))
5800  {
5801    while (strat->sl>0) deleteInS(strat->sl,strat);
5802  }
5803}
5804
5805void initSL (ideal F, ideal Q,kStrategy strat)
5806{
5807  int   i,pos;
5808
5809  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
5810  else i=setmaxT;
5811  strat->ecartS=initec(i);
5812  strat->sevS=initsevS(i);
5813  strat->S_2_R=initS_2_R(i);
5814  strat->fromQ=NULL;
5815  strat->Shdl=idInit(i,F->rank);
5816  strat->S=strat->Shdl->m;
5817  /*- put polys into S -*/
5818  if (Q!=NULL)
5819  {
5820    strat->fromQ=initec(i);
5821    memset(strat->fromQ,0,i*sizeof(int));
5822    for (i=0; i<IDELEMS(Q); i++)
5823    {
5824      if (Q->m[i]!=NULL)
5825      {
5826        LObject h;
5827        h.p = pCopy(Q->m[i]);
5828        if (currRing->OrdSgn==-1)
5829        {
5830          deleteHC(&h,strat);
5831        }
5832        if (TEST_OPT_INTSTRATEGY)
5833        {
5834          //pContent(h.p);
5835          h.pCleardenom(); // also does a pContent
5836        }
5837        else
5838        {
5839          h.pNorm();
5840        }
5841        if (h.p!=NULL)
5842        {
5843          strat->initEcart(&h);
5844          if (strat->sl==-1)
5845            pos =0;
5846          else
5847          {
5848            pos = posInS(strat,strat->sl,h.p,h.ecart);
5849          }
5850          h.sev = pGetShortExpVector(h.p);
5851          strat->enterS(h,pos,strat,-1);
5852          strat->fromQ[pos]=1;
5853        }
5854      }
5855    }
5856  }
5857  for (i=0; i<IDELEMS(F); i++)
5858  {
5859    if (F->m[i]!=NULL)
5860    {
5861      LObject h;
5862      h.p = pCopy(F->m[i]);
5863      if (h.p!=NULL)
5864      {
5865        if (currRing->OrdSgn==-1)
5866        {
5867          cancelunit(&h);  /*- tries to cancel a unit -*/
5868          deleteHC(&h, strat);
5869        }
5870        if (h.p!=NULL)
5871        {
5872          if (TEST_OPT_INTSTRATEGY)
5873          {
5874            //pContent(h.p);
5875            h.pCleardenom(); // also does a pContent
5876          }
5877          else
5878          {
5879            h.pNorm();
5880          }
5881          strat->initEcart(&h);
5882          if (strat->Ll==-1)
5883            pos =0;
5884          else
5885            pos = strat->posInL(strat->L,strat->Ll,&h,strat);
5886          h.sev = pGetShortExpVector(h.p);
5887          enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
5888        }
5889      }
5890    }
5891  }
5892  /*- test, if a unit is in F -*/
5893
5894  if ((strat->Ll>=0)
5895#ifdef HAVE_RINGS
5896       && n_IsUnit(pGetCoeff(strat->L[strat->Ll].p), currRing->cf)
5897#endif
5898       && pIsConstant(strat->L[strat->Ll].p))
5899  {
5900    while (strat->Ll>0) deleteInL(strat->L,&strat->Ll,strat->Ll-1,strat);
5901  }
5902}
5903
5904void initSLSba (ideal F, ideal Q,kStrategy strat)
5905{
5906  int   i,pos;
5907  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
5908  else i=setmaxT;
5909  strat->ecartS =   initec(i);
5910  strat->fromS  =   initec(i);
5911  strat->sevS   =   initsevS(i);
5912  strat->sevSig =   initsevS(i);
5913  strat->S_2_R  =   initS_2_R(i);
5914  strat->fromQ  =   NULL;
5915  strat->Shdl   =   idInit(i,F->rank);
5916  strat->S      =   strat->Shdl->m;
5917  strat->sig    =   (poly *)omAlloc0(i*sizeof(poly));
5918  if (strat->sbaOrder != 1)
5919  {
5920    strat->syz    = (poly *)omAlloc0(i*sizeof(poly));
5921    strat->sevSyz = initsevS(i);
5922    strat->syzmax = i;
5923    strat->syzl   = 0;
5924  }
5925  /*- put polys into S -*/
5926  if (Q!=NULL)
5927  {
5928    strat->fromQ=initec(i);
5929    memset(strat->fromQ,0,i*sizeof(int));
5930    for (i=0; i<IDELEMS(Q); i++)
5931    {
5932      if (Q->m[i]!=NULL)
5933      {
5934        LObject h;
5935        h.p = pCopy(Q->m[i]);
5936        if (currRing->OrdSgn==-1)
5937        {
5938          deleteHC(&h,strat);
5939        }
5940        if (TEST_OPT_INTSTRATEGY)
5941        {
5942          //pContent(h.p);
5943          h.pCleardenom(); // also does a pContent
5944        }
5945        else
5946        {
5947          h.pNorm();
5948        }
5949        if (h.p!=NULL)
5950        {
5951          strat->initEcart(&h);
5952          if (strat->sl==-1)
5953            pos =0;
5954          else
5955          {
5956            pos = posInS(strat,strat->sl,h.p,h.ecart);
5957          }
5958          h.sev = pGetShortExpVector(h.p);
5959          strat->enterS(h,pos,strat,-1);
5960          strat->fromQ[pos]=1;
5961        }
5962      }
5963    }
5964  }
5965  for (i=0; i<IDELEMS(F); i++)
5966  {
5967    if (F->m[i]!=NULL)
5968    {
5969      LObject h;
5970      h.p = pCopy(F->m[i]);
5971      h.sig = pOne();
5972      //h.sig = pInit();
5973      //p_SetCoeff(h.sig,nInit(1),currRing);
5974      p_SetComp(h.sig,i+1,currRing);
5975      // if we are working with the Schreyer order we generate it
5976      // by multiplying the initial signatures with the leading monomial
5977      // of the corresponding initial polynomials generating the ideal
5978      // => we can keep the underlying monomial order and get a Schreyer
5979      //    order without any bigger overhead
5980      if (strat->sbaOrder == 0)
5981      {
5982        p_ExpVectorAdd (h.sig,F->m[i],currRing);
5983      }
5984      h.sevSig = pGetShortExpVector(h.sig);
5985#ifdef DEBUGF5
5986      pWrite(h.p);
5987      pWrite(h.sig);
5988#endif
5989      if (h.p!=NULL)
5990      {
5991        if (currRing->OrdSgn==-1)
5992        {
5993          cancelunit(&h);  /*- tries to cancel a unit -*/
5994          deleteHC(&h, strat);
5995        }
5996        if (h.p!=NULL)
5997        {
5998          if (TEST_OPT_INTSTRATEGY)
5999          {
6000            //pContent(h.p);
6001            h.pCleardenom(); // also does a pContent
6002          }
6003          else
6004          {
6005            h.pNorm();
6006          }
6007          strat->initEcart(&h);
6008          if (strat->Ll==-1)
6009            pos =0;
6010          else
6011            pos = strat->posInLSba(strat->L,strat->Ll,&h,strat);
6012          h.sev = pGetShortExpVector(h.p);
6013          enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
6014        }
6015      }
6016      /*
6017      if (strat->sbaOrder != 1)
6018      {
6019        for(j=0;j<i;j++)
6020        {
6021          strat->syz[ctr] = pCopy(F->m[j]);
6022          p_SetCompP(strat->syz[ctr],i+1,currRing);
6023          // add LM(F->m[i]) to the signature to get a Schreyer order
6024          // without changing the underlying polynomial ring at all
6025          p_ExpVectorAdd (strat->syz[ctr],F->m[i],currRing);
6026          // since p_Add_q() destroys all input
6027          // data we need to recreate help
6028          // each time
6029          poly help = pCopy(F->m[i]);
6030          p_SetCompP(help,j+1,currRing);
6031          pWrite(strat->syz[ctr]);
6032          pWrite(help);
6033          printf("%d\n",pLmCmp(strat->syz[ctr],help));
6034          strat->syz[ctr] = p_Add_q(strat->syz[ctr],help,currRing);
6035          printf("%d. SYZ  ",ctr);
6036          pWrite(strat->syz[ctr]);
6037          strat->sevSyz[ctr] = p_GetShortExpVector(strat->syz[ctr],currRing);
6038          ctr++;
6039        }
6040        strat->syzl = ps;
6041      }
6042      */
6043    }
6044  }
6045  /*- test, if a unit is in F -*/
6046
6047  if ((strat->Ll>=0)
6048#ifdef HAVE_RINGS
6049       && n_IsUnit(pGetCoeff(strat->L[strat->Ll].p), currRing->cf)
6050#endif
6051       && pIsConstant(strat->L[strat->Ll].p))
6052  {
6053    while (strat->Ll>0) deleteInL(strat->L,&strat->Ll,strat->Ll-1,strat);
6054  }
6055}
6056
6057void initSyzRules (kStrategy strat)
6058{
6059  if( strat->S[0] )
6060  {
6061    if( strat->S[1] )
6062    {
6063      omFreeSize(strat->syzIdx,(strat->syzidxmax)*sizeof(int));
6064      omFreeSize(strat->sevSyz,(strat->syzmax)*sizeof(unsigned long));
6065      omFreeSize(strat->syz,(strat->syzmax)*sizeof(poly));
6066    }
6067    int i, j, k, diff, comp, comp_old, ps=0, ctr=0;
6068    /************************************************************
6069     * computing the length of the syzygy array needed
6070     ***********************************************************/
6071    for(i=1; i<=strat->sl; i++)
6072    {
6073      if (pGetComp(strat->sig[i-1]) != pGetComp(strat->sig[i]))
6074      {
6075        ps += i;
6076      }
6077    }
6078    ps += strat->sl+1;
6079    //comp              = pGetComp (strat->P.sig);
6080    comp              = strat->currIdx;
6081    strat->syzIdx     = initec(comp);
6082    strat->sevSyz     = initsevS(ps);
6083    strat->syz        = (poly *)omAlloc(ps*sizeof(poly));
6084    strat->syzl       = strat->syzmax = ps;
6085    strat->syzidxmax  = comp;
6086#if defined(DEBUGF5) || defined(DEBUGF51)
6087    printf("------------- GENERATING SYZ RULES NEW ---------------\n");
6088#endif
6089    i = 1;
6090    j = 0;
6091    /************************************************************
6092     * generating the leading terms of the principal syzygies
6093     ***********************************************************/
6094    while (i <= strat->sl)
6095    {
6096      /**********************************************************
6097       * principal syzygies start with component index 2
6098       * the array syzIdx starts with index 0
6099       * => the rules for a signature with component comp start
6100       *    at strat->syz[strat->syzIdx[comp-2]] !
6101       *********************************************************/
6102      if (pGetComp(strat->sig[i-1]) != pGetComp(strat->sig[i]))
6103      {
6104        comp      = pGetComp(strat->sig[i]);
6105        comp_old  = pGetComp(strat->sig[i-1]);
6106        diff      = comp - comp_old - 1;
6107        // diff should be zero, but sometimes also the initial generating
6108        // elements of the input ideal reduce to zero. then there is an
6109        // index-gap between the signatures. for these inbetween signatures we
6110        // can safely set syzIdx[j] = 0 as no such element will be ever computed
6111        // in the following.
6112        // doing this, we keep the relation "j = comp - 2" alive, which makes
6113        // jumps way easier when checking criteria
6114        while (diff>0)
6115        {
6116          strat->syzIdx[j]  = 0;
6117          diff--;
6118          j++;
6119        }
6120        strat->syzIdx[j]  = ctr;
6121        j++;
6122        for (k = 0; k<i; k++)
6123        {
6124          poly p          = pOne();
6125          pLcm(strat->S[k],strat->S[i],p);
6126          strat->syz[ctr] = p;
6127          p_SetCompP (strat->syz[ctr], comp, currRing);
6128          poly q          = p_Copy(p, currRing);
6129          q               = p_Neg (q, currRing);
6130          p_SetCompP (q, p_GetComp(strat->sig[k], currRing), currRing);
6131          strat->syz[ctr] = p_Add_q (strat->syz[ctr], q, currRing);
6132#if defined(DEBUGF5) || defined(DEBUGF51)
6133          pWrite(strat->syz[ctr]);
6134#endif
6135          strat->sevSyz[ctr] = p_GetShortExpVector(strat->syz[ctr],currRing);
6136          ctr++;
6137        }
6138      }
6139      i++;
6140    }
6141    /**************************************************************
6142    * add syzygies for upcoming first element of new iteration step
6143    **************************************************************/
6144    comp      = strat->currIdx;
6145    comp_old  = pGetComp(strat->sig[i-1]);
6146    diff      = comp - comp_old - 1;
6147    // diff should be zero, but sometimes also the initial generating
6148    // elements of the input ideal reduce to zero. then there is an
6149    // index-gap between the signatures. for these inbetween signatures we
6150    // can safely set syzIdx[j] = 0 as no such element will be ever computed
6151    // in the following.
6152    // doing this, we keep the relation "j = comp - 2" alive, which makes
6153    // jumps way easier when checking criteria
6154    while (diff>0)
6155    {
6156      strat->syzIdx[j]  = 0;
6157      diff--;
6158      j++;
6159    }
6160    strat->syzIdx[j]  = ctr;
6161    for (k = 0; k<strat->sl+1; k++)
6162    {
6163      strat->syz[ctr] = p_Copy (pHead(strat->S[k]), currRing);
6164      p_SetCompP (strat->syz[ctr], comp, currRing);
6165      poly q          = p_Copy (pHead(strat->L[strat->Ll].p), currRing);
6166      q               = p_Neg (q, currRing);
6167      p_SetCompP (q, p_GetComp(strat->sig[k], currRing), currRing);
6168      strat->syz[ctr] = p_Add_q (strat->syz[ctr], q, currRing);
6169//#if 1
6170#if DEBUGF5 || DEBUGF51
6171      printf("..");
6172      pWrite(strat->syz[ctr]);
6173#endif
6174      strat->sevSyz[ctr] = p_GetShortExpVector(strat->syz[ctr],currRing);
6175      ctr++;
6176    }
6177//#if 1
6178#ifdef DEBUGF5
6179    Print("Principal syzygies:\n");
6180    Print("--------------------------------\n");
6181    for(i=0;i<=ps-1;i++)
6182    {
6183      pWrite(strat->syz[i]);
6184    }
6185    Print("--------------------------------\n");
6186#endif
6187
6188  }
6189}
6190
6191
6192
6193/*2
6194*construct the set s from F and {P}
6195*/
6196void initSSpecial (ideal F, ideal Q, ideal P,kStrategy strat)
6197{
6198  int   i,pos;
6199
6200  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
6201  else i=setmaxT;
6202  i=((i+IDELEMS(F)+IDELEMS(P)+15)/16)*16;
6203  strat->ecartS=initec(i);
6204  strat->sevS=initsevS(i);
6205  strat->S_2_R=initS_2_R(i);
6206  strat->fromQ=NULL;
6207  strat->Shdl=idInit(i,F->rank);
6208  strat->S=strat->Shdl->m;
6209
6210  /*- put polys into S -*/
6211  if (Q!=NULL)
6212  {
6213    strat->fromQ=initec(i);
6214    memset(strat->fromQ,0,i*sizeof(int));
6215    for (i=0; i<IDELEMS(Q); i++)
6216    {
6217      if (Q->m[i]!=NULL)
6218      {
6219        LObject h;
6220        h.p = pCopy(Q->m[i]);
6221        //if (TEST_OPT_INTSTRATEGY)
6222        //{
6223        //  //pContent(h.p);
6224        //  h.pCleardenom(); // also does a pContent
6225        //}
6226        //else
6227        //{
6228        //  h.pNorm();
6229        //}
6230        if (currRing->OrdSgn==-1)
6231        {
6232          deleteHC(&h,strat);
6233        }
6234        if (h.p!=NULL)
6235        {
6236          strat->initEcart(&h);
6237          if (strat->sl==-1)
6238            pos =0;
6239          else
6240          {
6241            pos = posInS(strat,strat->sl,h.p,h.ecart);
6242          }
6243          h.sev = pGetShortExpVector(h.p);
6244          strat->enterS(h,pos,strat, strat->tl+1);
6245          enterT(h, strat);
6246          strat->fromQ[pos]=1;
6247        }
6248      }
6249    }
6250  }
6251  /*- put polys into S -*/
6252  for (i=0; i<IDELEMS(F); i++)
6253  {
6254    if (F->m[i]!=NULL)
6255    {
6256      LObject h;
6257      h.p = pCopy(F->m[i]);
6258      if (currRing->OrdSgn==-1)
6259      {
6260        deleteHC(&h,strat);
6261      }
6262      else
6263      {
6264        h.p=redtailBba(h.p,strat->sl,strat);
6265      }
6266      if (h.p!=NULL)
6267      {
6268        strat->initEcart(&h);
6269        if (strat->sl==-1)
6270          pos =0;
6271        else
6272          pos = posInS(strat,strat->sl,h.p,h.ecart);
6273        h.sev = pGetShortExpVector(h.p);
6274        strat->enterS(h,pos,strat, strat->tl+1);
6275        enterT(h,strat);
6276      }
6277    }
6278  }
6279  for (i=0; i<IDELEMS(P); i++)
6280  {
6281    if (P->m[i]!=NULL)
6282    {
6283      LObject h;
6284      h.p=pCopy(P->m[i]);
6285      if (TEST_OPT_INTSTRATEGY)
6286      {
6287        h.pCleardenom();
6288      }
6289      else
6290      {
6291        h.pNorm();
6292      }
6293      if(strat->sl>=0)
6294      {
6295        if (currRing->OrdSgn==1)
6296        {
6297          h.p=redBba(h.p,strat->sl,strat);
6298          if (h.p!=NULL)
6299          {
6300            h.p=redtailBba(h.p,strat->sl,strat);
6301          }
6302        }
6303        else
6304        {
6305          h.p=redMora(h.p,strat->sl,strat);
6306        }
6307        if(h.p!=NULL)
6308        {
6309          strat->initEcart(&h);
6310          if (TEST_OPT_INTSTRATEGY)
6311          {
6312            h.pCleardenom();
6313          }
6314          else
6315          {
6316            h.is_normalized = 0;
6317            h.pNorm();
6318          }
6319          h.sev = pGetShortExpVector(h.p);
6320          h.SetpFDeg();
6321          pos = posInS(strat,strat->sl,h.p,h.ecart);
6322          enterpairsSpecial(h.p,strat->sl,h.ecart,pos,strat,strat->tl+1);
6323          strat->enterS(h,pos,strat, strat->tl+1);
6324          enterT(h,strat);
6325        }
6326      }
6327      else
6328      {
6329        h.sev = pGetShortExpVector(h.p);
6330        strat->initEcart(&h);
6331        strat->enterS(h,0,strat, strat->tl+1);
6332        enterT(h,strat);
6333      }
6334    }
6335  }
6336}
6337/*2
6338*construct the set s from F and {P}
6339*/
6340
6341void initSSpecialSba (ideal F, ideal Q, ideal P,kStrategy strat)
6342{
6343  int   i,pos;
6344
6345  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
6346  else i=setmaxT;
6347  i=((i+IDELEMS(F)+IDELEMS(P)+15)/16)*16;
6348  strat->fromS=initec(i);
6349  strat->sevS=initsevS(i);
6350  strat->sevSig=initsevS(i);
6351  strat->S_2_R=initS_2_R(i);
6352  strat->fromQ=NULL;
6353  strat->Shdl=idInit(i,F->rank);
6354  strat->S=strat->Shdl->m;
6355  strat->sig=(poly *)omAlloc0(i*sizeof(poly));
6356  /*- put polys into S -*/
6357  if (Q!=NULL)
6358  {
6359    strat->fromQ=initec(i);
6360    memset(strat->fromQ,0,i*sizeof(int));
6361    for (i=0; i<IDELEMS(Q); i++)
6362    {
6363      if (Q->m[i]!=NULL)
6364      {
6365        LObject h;
6366        h.p = pCopy(Q->m[i]);
6367        //if (TEST_OPT_INTSTRATEGY)
6368        //{
6369        //  //pContent(h.p);
6370        //  h.pCleardenom(); // also does a pContent
6371        //}
6372        //else
6373        //{
6374        //  h.pNorm();
6375        //}
6376        if (currRing->OrdSgn==-1)
6377        {
6378          deleteHC(&h,strat);
6379        }
6380        if (h.p!=NULL)
6381        {
6382          strat->initEcart(&h);
6383          if (strat->sl==-1)
6384            pos =0;
6385          else
6386          {
6387            pos = posInS(strat,strat->sl,h.p,h.ecart);
6388          }
6389          h.sev = pGetShortExpVector(h.p);
6390          strat->enterS(h,pos,strat, strat->tl+1);
6391          enterT(h, strat);
6392          strat->fromQ[pos]=1;
6393        }
6394      }
6395    }
6396  }
6397  /*- put polys into S -*/
6398  for (i=0; i<IDELEMS(F); i++)
6399  {
6400    if (F->m[i]!=NULL)
6401    {
6402      LObject h;
6403      h.p = pCopy(F->m[i]);
6404      if (currRing->OrdSgn==-1)
6405      {
6406        deleteHC(&h,strat);
6407      }
6408      else
6409      {
6410        h.p=redtailBba(h.p,strat->sl,strat);
6411      }
6412      if (h.p!=NULL)
6413      {
6414        strat->initEcart(&h);
6415        if (strat->sl==-1)
6416          pos =0;
6417        else
6418          pos = posInS(strat,strat->sl,h.p,h.ecart);
6419        h.sev = pGetShortExpVector(h.p);
6420        strat->enterS(h,pos,strat, strat->tl+1);
6421        enterT(h,strat);
6422      }
6423    }
6424  }
6425  for (i=0; i<IDELEMS(P); i++)
6426  {
6427    if (P->m[i]!=NULL)
6428    {
6429      LObject h;
6430      h.p=pCopy(P->m[i]);
6431      if (TEST_OPT_INTSTRATEGY)
6432      {
6433        h.pCleardenom();
6434      }
6435      else
6436      {
6437        h.pNorm();
6438      }
6439      if(strat->sl>=0)
6440      {
6441        if (currRing->OrdSgn==1)
6442        {
6443          h.p=redBba(h.p,strat->sl,strat);
6444          if (h.p!=NULL)
6445          {
6446            h.p=redtailBba(h.p,strat->sl,strat);
6447          }
6448        }
6449        else
6450        {
6451          h.p=redMora(h.p,strat->sl,strat);
6452        }
6453        if(h.p!=NULL)
6454        {
6455          strat->initEcart(&h);
6456          if (TEST_OPT_INTSTRATEGY)
6457          {
6458            h.pCleardenom();
6459          }
6460          else
6461          {
6462            h.is_normalized = 0;
6463            h.pNorm();
6464          }
6465          h.sev = pGetShortExpVector(h.p);
6466          h.SetpFDeg();
6467          pos = posInS(strat,strat->sl,h.p,h.ecart);
6468          enterpairsSpecial(h.p,strat->sl,h.ecart,pos,strat,strat->tl+1);
6469          strat->enterS(h,pos,strat, strat->tl+1);
6470          enterT(h,strat);
6471        }
6472      }
6473      else
6474      {
6475        h.sev = pGetShortExpVector(h.p);
6476        strat->initEcart(&h);
6477        strat->enterS(h,0,strat, strat->tl+1);
6478        enterT(h,strat);
6479      }
6480    }
6481  }
6482}
6483/*2
6484* reduces h using the set S
6485* procedure used in cancelunit1
6486*/
6487static poly redBba1 (poly h,int maxIndex,kStrategy strat)
6488{
6489  int j = 0;
6490  unsigned long not_sev = ~ pGetShortExpVector(h);
6491
6492  while (j <= maxIndex)
6493  {
6494    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j],h, not_sev))
6495       return ksOldSpolyRedNew(strat->S[j],h,strat->kNoetherTail());
6496    else j++;
6497  }
6498  return h;
6499}
6500
6501/*2
6502*tests if p.p=monomial*unit and cancels the unit
6503*/
6504void cancelunit1 (LObject* p,int *suc, int index,kStrategy strat )
6505{
6506  int k;
6507  poly r,h,h1,q;
6508
6509  if (!pIsVector((*p).p) && ((*p).ecart != 0))
6510  {
6511#ifdef HAVE_RINGS_LOC
6512    // Leading coef have to be a unit
6513    if ( !(nIsUnit(p_GetCoeff((*p).p, r))) ) return;
6514#endif
6515    k = 0;
6516    h1 = r = pCopy((*p).p);
6517    h =pNext(r);
6518    loop
6519    {
6520      if (h==NULL)
6521      {
6522        pDelete(&r);
6523        pDelete(&(pNext((*p).p)));
6524        (*p).ecart = 0;
6525        (*p).length = 1;
6526#ifdef HAVE_RINGS_LOC
6527        (*p).pLength = 1;  // Why wasn't this set already?
6528#endif
6529        (*suc)=0;
6530        return;
6531      }
6532      if (!pDivisibleBy(r,h))
6533      {
6534        q=redBba1(h,index ,strat);
6535        if (q != h)
6536        {
6537          k++;
6538          pDelete(&h);
6539          pNext(h1) = h = q;
6540        }
6541        else
6542        {
6543          pDelete(&r);
6544          return;
6545        }
6546      }
6547      else
6548      {
6549        h1 = h;
6550        pIter(h);
6551      }
6552      if (k > 10)
6553      {
6554        pDelete(&r);
6555        return;
6556      }
6557    }
6558  }
6559}
6560
6561#if 0
6562/*2
6563* reduces h using the elements from Q in the set S
6564* procedure used in updateS
6565* must not be used for elements of Q or elements of an ideal !
6566*/
6567static poly redQ (poly h, int j, kStrategy strat)
6568{
6569  int start;
6570  unsigned long not_sev = ~ pGetShortExpVector(h);
6571  while ((j <= strat->sl) && (pGetComp(strat->S[j])!=0)) j++;
6572  start=j;
6573  while (j<=strat->sl)
6574  {
6575    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev))
6576    {
6577      h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
6578      if (h==NULL) return NULL;
6579      j = start;
6580      not_sev = ~ pGetShortExpVector(h);
6581    }
6582    else j++;
6583  }
6584  return h;
6585}
6586#endif
6587
6588/*2
6589* reduces h using the set S
6590* procedure used in updateS
6591*/
6592static poly redBba (poly h,int maxIndex,kStrategy strat)
6593{
6594  int j = 0;
6595  unsigned long not_sev = ~ pGetShortExpVector(h);
6596
6597  while (j <= maxIndex)
6598  {
6599    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev))
6600    {
6601      h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
6602      if (h==NULL) return NULL;
6603      j = 0;
6604      not_sev = ~ pGetShortExpVector(h);    }
6605    else j++;
6606  }
6607  return h;
6608}
6609
6610/*2
6611* reduces h using the set S
6612*e is the ecart of h
6613*procedure used in updateS
6614*/
6615static poly redMora (poly h,int maxIndex,kStrategy strat)
6616{
6617  int  j=0;
6618  int  e,l;
6619  unsigned long not_sev = ~ pGetShortExpVector(h);
6620
6621  if (maxIndex >= 0)
6622  {
6623    e = currRing->pLDeg(h,&l,currRing)-p_FDeg(h,currRing);
6624    do
6625    {
6626      if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev)
6627      && ((e >= strat->ecartS[j]) || strat->kHEdgeFound))
6628      {
6629#ifdef KDEBUG
6630        if (TEST_OPT_DEBUG)
6631          {PrintS("reduce ");wrp(h);Print(" with S[%d] (",j);wrp(strat->S[j]);}
6632#endif
6633        h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
6634#ifdef KDEBUG
6635        if(TEST_OPT_DEBUG)
6636          {PrintS(")\nto "); wrp(h); PrintLn();}
6637#endif
6638        // pDelete(&h);
6639        if (h == NULL) return NULL;
6640        e = currRing->pLDeg(h,&l,currRing)-p_FDeg(h,currRing);
6641        j = 0;
6642        not_sev = ~ pGetShortExpVector(h);
6643      }
6644      else j++;
6645    }
6646    while (j <= maxIndex);
6647  }
6648  return h;
6649}
6650
6651/*2
6652*updates S:
6653*the result is a set of polynomials which are in
6654*normalform with respect to S
6655*/
6656void updateS(BOOLEAN toT,kStrategy strat)
6657{
6658  LObject h;
6659  int i, suc=0;
6660  poly redSi=NULL;
6661  BOOLEAN change,any_change;
6662//  Print("nach initS: updateS start mit sl=%d\n",(strat->sl));
6663//  for (i=0; i<=(strat->sl); i++)
6664//  {
6665//    Print("s%d:",i);
6666//    if (strat->fromQ!=NULL) Print("(Q:%d) ",strat->fromQ[i]);
6667//    pWrite(strat->S[i]);
6668//  }
6669//  Print("currRing->OrdSgn=%d\n", currRing->OrdSgn);
6670  any_change=FALSE;
6671  if (currRing->OrdSgn==1)
6672  {
6673    while (suc != -1)
6674    {
6675      i=suc+1;
6676      while (i<=strat->sl)
6677      {
6678        change=FALSE;
6679        if (((strat->fromQ==NULL) || (strat->fromQ[i]==0)) && (i>0))
6680        {
6681          redSi = pHead(strat->S[i]);
6682          strat->S[i] = redBba(strat->S[i],i-1,strat);
6683          //if ((strat->ak!=0)&&(strat->S[i]!=NULL))
6684          //  strat->S[i]=redQ(strat->S[i],i+1,strat); /*reduce S[i] mod Q*/
6685          if (pCmp(redSi,strat->S[i])!=0)
6686          {
6687            change=TRUE;
6688            any_change=TRUE;
6689            #ifdef KDEBUG
6690            if (TEST_OPT_DEBUG)
6691            {
6692              PrintS("reduce:");
6693              wrp(redSi);PrintS(" to ");p_wrp(strat->S[i], currRing, strat->tailRing);PrintLn();
6694            }
6695            #endif
6696            if (TEST_OPT_PROT)
6697            {
6698              if (strat->S[i]==NULL)
6699                PrintS("V");
6700              else
6701                PrintS("v");
6702              mflush();
6703            }
6704          }
6705          pLmDelete(&redSi);
6706          if (strat->S[i]==NULL)
6707          {
6708            deleteInS(i,strat);
6709            i--;
6710          }
6711          else if (change)
6712          {
6713            if (TEST_OPT_INTSTRATEGY)
6714            {
6715              if (TEST_OPT_CONTENTSB)
6716                {
6717                  number n;
6718                  p_Cleardenom_n(strat->S[i], currRing, n);// also does a pContent
6719                  if (!nIsOne(n))
6720                    {
6721                      denominator_list denom=(denominator_list)omAlloc(sizeof(denominator_list_s));
6722                      denom->n=nInvers(n);
6723                      denom->next=DENOMINATOR_LIST;
6724                      DENOMINATOR_LIST=denom;
6725                    }
6726                  nDelete(&n);
6727                }
6728              else
6729                {
6730                  //pContent(strat->S[i]);
6731                  strat->S[i]=p_Cleardenom(strat->S[i], currRing);// also does a pContent
6732                }
6733            }
6734            else
6735            {
6736              pNorm(strat->S[i]);
6737            }
6738            strat->sevS[i] = pGetShortExpVector(strat->S[i]);
6739          }
6740        }
6741        i++;
6742      }
6743      if (any_change) reorderS(&suc,strat);
6744      else break;
6745    }
6746    if (toT)
6747    {
6748      for (i=0; i<=strat->sl; i++)
6749      {
6750        if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
6751        {
6752          h.p = redtailBba(strat->S[i],i-1,strat);
6753          if (TEST_OPT_INTSTRATEGY)
6754          {
6755            h.pCleardenom();// also does a pContent
6756          }
6757        }
6758        else
6759        {
6760          h.p = strat->S[i];
6761        }
6762        strat->initEcart(&h);
6763        if (strat->honey)
6764        {
6765          strat->ecartS[i] = h.ecart;
6766        }
6767        if (strat->sevS[i] == 0) {strat->sevS[i] = pGetShortExpVector(h.p);}
6768        else assume(strat->sevS[i] == pGetShortExpVector(h.p));
6769        h.sev = strat->sevS[i];
6770        /*puts the elements of S also to T*/
6771        strat->initEcart(&h);
6772        enterT(h,strat);
6773        strat->S_2_R[i] = strat->tl;
6774      }
6775    }
6776  }
6777  else
6778  {
6779    while (suc != -1)
6780    {
6781      i=suc;
6782      while (i<=strat->sl)
6783      {
6784        change=FALSE;
6785        if (((strat->fromQ==NULL) || (strat->fromQ[i]==0)) && (i>0))
6786        {
6787          redSi=pHead((strat->S)[i]);
6788          (strat->S)[i] = redMora((strat->S)[i],i-1,strat);
6789          if ((strat->S)[i]==NULL)
6790          {
6791            deleteInS(i,strat);
6792            i--;
6793          }
6794          else if (pCmp((strat->S)[i],redSi)!=0)
6795          {
6796            any_change=TRUE;
6797            h.p = strat->S[i];
6798            strat->initEcart(&h);
6799            strat->ecartS[i] = h.ecart;
6800            if (TEST_OPT_INTSTRATEGY)
6801            {
6802              if (TEST_OPT_CONTENTSB)
6803                {
6804                  number n;
6805                  p_Cleardenom_n(strat->S[i], currRing, n);// also does a pContent
6806                  if (!nIsOne(n))
6807                    {
6808                      denominator_list denom=(denominator_list)omAlloc(sizeof(denominator_list_s));
6809                      denom->n=nInvers(n);
6810                      denom->next=DENOMINATOR_LIST;
6811                      DENOMINATOR_LIST=denom;
6812                    }
6813                  nDelete(&n);
6814                }
6815              else
6816                {
6817                  //pContent(strat->S[i]);
6818                  strat->S[i]=p_Cleardenom(strat->S[i], currRing);// also does a pContent
6819                }
6820            }
6821            else
6822            {
6823              pNorm(strat->S[i]); // == h.p
6824            }
6825            h.sev =  pGetShortExpVector(h.p);
6826            strat->sevS[i] = h.sev;
6827          }
6828          pLmDelete(&redSi);
6829          assume(kTest(strat));
6830        }
6831        i++;
6832      }
6833#ifdef KDEBUG
6834      assume(kTest(strat));
6835#endif
6836      if (any_change) reorderS(&suc,strat);
6837      else { suc=-1; break; }
6838      if (h.p!=NULL)
6839      {
6840        if (!strat->kHEdgeFound)
6841        {
6842          /*strat->kHEdgeFound =*/ HEckeTest(h.p,strat);
6843        }
6844        if (strat->kHEdgeFound)
6845          newHEdge(strat);
6846      }
6847    }
6848    for (i=0; i<=strat->sl; i++)
6849    {
6850      if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
6851      {
6852        strat->S[i] = h.p = redtail(strat->S[i],strat->sl,strat);
6853        strat->initEcart(&h);
6854        strat->ecartS[i] = h.ecart;
6855        h.sev = pGetShortExpVector(h.p);
6856        strat->sevS[i] = h.sev;
6857      }
6858      else
6859      {
6860        h.p = strat->S[i];
6861        h.ecart=strat->ecartS[i];
6862        h.sev = strat->sevS[i];
6863        h.length = h.pLength = pLength(h.p);
6864      }
6865      if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
6866        cancelunit1(&h,&suc,strat->sl,strat);
6867      h.SetpFDeg();
6868      /*puts the elements of S also to T*/
6869      enterT(h,strat);
6870      strat->S_2_R[i] = strat->tl;
6871    }
6872    if (suc!= -1) updateS(toT,strat);
6873  }
6874#ifdef KDEBUG
6875  assume(kTest(strat));
6876#endif
6877}
6878
6879
6880/*2
6881* -puts p to the standardbasis s at position at
6882* -saves the result in S
6883*/
6884void enterSBba (LObject p,int atS,kStrategy strat, int atR)
6885{
6886  strat->news = TRUE;
6887  /*- puts p to the standardbasis s at position at -*/
6888  if (strat->sl == IDELEMS(strat->Shdl)-1)
6889  {
6890    strat->sevS = (unsigned long*) omRealloc0Size(strat->sevS,
6891                                    IDELEMS(strat->Shdl)*sizeof(unsigned long),
6892                                    (IDELEMS(strat->Shdl)+setmaxTinc)
6893                                                  *sizeof(unsigned long));
6894    strat->ecartS = (intset)omReallocSize(strat->ecartS,
6895                                          IDELEMS(strat->Shdl)*sizeof(int),
6896                                          (IDELEMS(strat->Shdl)+setmaxTinc)
6897                                                  *sizeof(int));
6898    strat->S_2_R = (int*) omRealloc0Size(strat->S_2_R,
6899                                         IDELEMS(strat->Shdl)*sizeof(int),
6900                                         (IDELEMS(strat->Shdl)+setmaxTinc)
6901                                                  *sizeof(int));
6902    if (strat->lenS!=NULL)
6903      strat->lenS=(int*)omRealloc0Size(strat->lenS,
6904                                       IDELEMS(strat->Shdl)*sizeof(int),
6905                                       (IDELEMS(strat->Shdl)+setmaxTinc)
6906                                                 *sizeof(int));
6907    if (strat->lenSw!=NULL)
6908      strat->lenSw=(wlen_type*)omRealloc0Size(strat->lenSw,
6909                                       IDELEMS(strat->Shdl)*sizeof(wlen_type),
6910                                       (IDELEMS(strat->Shdl)+setmaxTinc)
6911                                                 *sizeof(wlen_type));
6912    if (strat->fromQ!=NULL)
6913    {
6914      strat->fromQ = (intset)omReallocSize(strat->fromQ,
6915                                    IDELEMS(strat->Shdl)*sizeof(int),
6916                                    (IDELEMS(strat->Shdl)+setmaxTinc)*sizeof(int));
6917    }
6918    pEnlargeSet(&strat->S,IDELEMS(strat->Shdl),setmaxTinc);
6919    IDELEMS(strat->Shdl)+=setmaxTinc;
6920    strat->Shdl->m=strat->S;
6921  }
6922  if (atS <= strat->sl)
6923  {
6924#ifdef ENTER_USE_MEMMOVE
6925// #if 0
6926    memmove(&(strat->S[atS+1]), &(strat->S[atS]),
6927            (strat->sl - atS + 1)*sizeof(poly));
6928    memmove(&(strat->ecartS[atS+1]), &(strat->ecartS[atS]),
6929            (strat->sl - atS + 1)*sizeof(int));
6930    memmove(&(strat->sevS[atS+1]), &(strat->sevS[atS]),
6931            (strat->sl - atS + 1)*sizeof(unsigned long));
6932    memmove(&(strat->S_2_R[atS+1]), &(strat->S_2_R[atS]),
6933            (strat->sl - atS + 1)*sizeof(int));
6934    if (strat->lenS!=NULL)
6935    memmove(&(strat->lenS[atS+1]), &(strat->lenS[atS]),
6936            (strat->sl - atS + 1)*sizeof(int));
6937    if (strat->lenSw!=NULL)
6938    memmove(&(strat->lenSw[atS+1]), &(strat->lenSw[atS]),
6939            (strat->sl - atS + 1)*sizeof(wlen_type));
6940#else
6941    for (i=strat->sl+1; i>=atS+1; i--)
6942    {
6943      strat->S[i] = strat->S[i-1];
6944      strat->ecartS[i] = strat->ecartS[i-1];
6945      strat->sevS[i] = strat->sevS[i-1];
6946      strat->S_2_R[i] = strat->S_2_R[i-1];
6947    }
6948    if (strat->lenS!=NULL)
6949    for (i=strat->sl+1; i>=atS+1; i--)
6950      strat->lenS[i] = strat->lenS[i-1];
6951    if (strat->lenSw!=NULL)
6952    for (i=strat->sl+1; i>=atS+1; i--)
6953      strat->lenSw[i] = strat->lenSw[i-1];
6954#endif
6955  }
6956  if (strat->fromQ!=NULL)
6957  {
6958#ifdef ENTER_USE_MEMMOVE
6959    memmove(&(strat->fromQ[atS+1]), &(strat->fromQ[atS]),
6960                  (strat->sl - atS + 1)*sizeof(int));
6961#else
6962    for (i=strat->sl+1; i>=atS+1; i--)
6963    {
6964      strat->fromQ[i] = strat->fromQ[i-1];
6965    }
6966#endif
6967    strat->fromQ[atS]=0;
6968  }
6969
6970  /*- save result -*/
6971  strat->S[atS] = p.p;
6972  if (strat->honey) strat->ecartS[atS] = p.ecart;
6973  if (p.sev == 0)
6974    p.sev = pGetShortExpVector(p.p);
6975  else
6976    assume(p.sev == pGetShortExpVector(p.p));
6977  strat->sevS[atS] = p.sev;
6978  strat->ecartS[atS] = p.ecart;
6979  strat->S_2_R[atS] = atR;
6980  strat->sl++;
6981}
6982
6983/*2
6984* -puts p to the standardbasis s at position at
6985* -saves the result in S
6986*/
6987void enterSSba (LObject p,int atS,kStrategy strat, int atR)
6988{
6989  strat->news = TRUE;
6990  /*- puts p to the standardbasis s at position at -*/
6991  if (strat->sl == IDELEMS(strat->Shdl)-1)
6992  {
6993    strat->sevS = (unsigned long*) omRealloc0Size(strat->sevS,
6994                                    IDELEMS(strat->Shdl)*sizeof(unsigned long),
6995                                    (IDELEMS(strat->Shdl)+setmaxTinc)
6996                                                  *sizeof(unsigned long));
6997    strat->sevSig = (unsigned long*) omRealloc0Size(strat->sevSig,
6998                                    IDELEMS(strat->Shdl)*sizeof(unsigned long),
6999                                    (IDELEMS(strat->Shdl)+setmaxTinc)
7000                                                  *sizeof(unsigned long));
7001    strat->ecartS = (intset)omReallocSize(strat->ecartS,
7002                                          IDELEMS(strat->Shdl)*sizeof(int),
7003                                          (IDELEMS(strat->Shdl)+setmaxTinc)
7004                                                  *sizeof(int));
7005    strat->fromS = (intset)omReallocSize(strat->fromS,
7006                                          IDELEMS(strat->Shdl)*sizeof(int),
7007                                          (IDELEMS(strat->Shdl)+setmaxTinc)
7008                                                  *sizeof(int));
7009    strat->S_2_R = (int*) omRealloc0Size(strat->S_2_R,
7010                                         IDELEMS(strat->Shdl)*sizeof(int),
7011                                         (IDELEMS(strat->Shdl)+setmaxTinc)
7012                                                  *sizeof(int));
7013    if (strat->lenS!=NULL)
7014      strat->lenS=(int*)omRealloc0Size(strat->lenS,
7015                                       IDELEMS(strat->Shdl)*sizeof(int),
7016                                       (IDELEMS(strat->Shdl)+setmaxTinc)
7017                                                 *sizeof(int));
7018    if (strat->lenSw!=NULL)
7019      strat->lenSw=(wlen_type*)omRealloc0Size(strat->lenSw,
7020                                       IDELEMS(strat->Shdl)*sizeof(wlen_type),
7021                                       (IDELEMS(strat->Shdl)+setmaxTinc)
7022                                                 *sizeof(wlen_type));
7023    if (strat->fromQ!=NULL)
7024    {
7025      strat->fromQ = (intset)omReallocSize(strat->fromQ,
7026                                    IDELEMS(strat->Shdl)*sizeof(int),
7027                                    (IDELEMS(strat->Shdl)+setmaxTinc)*sizeof(int));
7028    }
7029    pEnlargeSet(&strat->S,IDELEMS(strat->Shdl),setmaxTinc);
7030    pEnlargeSet(&strat->sig,IDELEMS(strat->Shdl),setmaxTinc);
7031    IDELEMS(strat->Shdl)+=setmaxTinc;
7032    strat->Shdl->m=strat->S;
7033  }
7034  // in a signature-based algorithm the following situation will never
7035  // appear due to the fact that the critical pairs are already sorted
7036  // by increasing signature.
7037  if (atS <= strat->sl)
7038  {
7039#ifdef ENTER_USE_MEMMOVE
7040// #if 0
7041    memmove(&(strat->S[atS+1]), &(strat->S[atS]),
7042            (strat->sl - atS + 1)*sizeof(poly));
7043    memmove(&(strat->ecartS[atS+1]), &(strat->ecartS[atS]),
7044            (strat->sl - atS + 1)*sizeof(int));
7045    memmove(&(strat->fromS[atS+1]), &(strat->fromS[atS]),
7046            (strat->sl - atS + 1)*sizeof(int));
7047    memmove(&(strat->sevS[atS+1]), &(strat->sevS[atS]),
7048            (strat->sl - atS + 1)*sizeof(unsigned long));
7049    memmove(&(strat->S_2_R[atS+1]), &(strat->S_2_R[atS]),
7050            (strat->sl - atS + 1)*sizeof(int));
7051    if (strat->lenS!=NULL)
7052    memmove(&(strat->lenS[atS+1]), &(strat->lenS[atS]),
7053            (strat->sl - atS + 1)*sizeof(int));
7054    if (strat->lenSw!=NULL)
7055    memmove(&(strat->lenSw[atS+1]), &(strat->lenSw[atS]),
7056            (strat->sl - atS + 1)*sizeof(wlen_type));
7057#else
7058    for (i=strat->sl+1; i>=atS+1; i--)
7059    {
7060      strat->S[i] = strat->S[i-1];
7061      strat->ecartS[i] = strat->ecartS[i-1];
7062      strat->fromS[i] = strat->fromS[i-1];
7063      strat->sevS[i] = strat->sevS[i-1];
7064      strat->S_2_R[i] = strat->S_2_R[i-1];
7065    }
7066    if (strat->lenS!=NULL)
7067    for (i=strat->sl+1; i>=atS+1; i--)
7068      strat->lenS[i] = strat->lenS[i-1];
7069    if (strat->lenSw!=NULL)
7070    for (i=strat->sl+1; i>=atS+1; i--)
7071      strat->lenSw[i] = strat->lenSw[i-1];
7072#endif
7073  }
7074  if (strat->fromQ!=NULL)
7075  {
7076#ifdef ENTER_USE_MEMMOVE
7077    memmove(&(strat->fromQ[atS+1]), &(strat->fromQ[atS]),
7078                  (strat->sl - atS + 1)*sizeof(int));
7079#else
7080    for (i=strat->sl+1; i>=atS+1; i--)
7081    {
7082      strat->fromQ[i] = strat->fromQ[i-1];
7083    }
7084#endif
7085    strat->fromQ[atS]=0;
7086  }
7087
7088  /*- save result -*/
7089  strat->S[atS] = p.p;
7090  strat->sig[atS] = p.sig; // TODO: get ths correct signature in here!
7091  if (strat->honey) strat->ecartS[atS] = p.ecart;
7092  if (p.sev == 0)
7093    p.sev = pGetShortExpVector(p.p);
7094  else
7095    assume(p.sev == pGetShortExpVector(p.p));
7096  strat->sevS[atS] = p.sev;
7097  // during the interreduction process of a signature-based algorithm we do not
7098  // compute the signature at this point, but when the whole interreduction
7099  // process finishes, i.e. f5c terminates!
7100  if (p.sig != NULL)
7101  {
7102    if (p.sevSig == 0)
7103      p.sevSig = pGetShortExpVector(p.sig);
7104    else
7105      assume(p.sevSig == pGetShortExpVector(p.sig));
7106    strat->sevSig[atS] = p.sevSig; // TODO: get the correct signature in here!
7107  }
7108  strat->ecartS[atS] = p.ecart;
7109  strat->fromS[atS] = p.from;
7110  strat->S_2_R[atS] = atR;
7111  strat->sl++;
7112#ifdef DEBUGF5
7113  int k;
7114  Print("--- LIST S: %d ---\n",strat->sl);
7115  for(k=0;k<=strat->sl;k++)
7116  {
7117    pWrite(strat->sig[k]);
7118  }
7119  Print("--- LIST S END ---\n");
7120#endif
7121}
7122
7123/*2
7124* puts p to the set T at position atT
7125*/
7126void enterT(LObject p, kStrategy strat, int atT)
7127{
7128  int i;
7129
7130  pp_Test(p.p, currRing, p.tailRing);
7131  assume(strat->tailRing == p.tailRing);
7132  // redMoraNF complains about this -- but, we don't really
7133  // neeed this so far
7134  assume(p.pLength == 0 || pLength(p.p) == p.pLength || rIsSyzIndexRing(currRing)); // modulo syzring
7135  assume(p.FDeg == p.pFDeg());
7136  assume(!p.is_normalized || nIsOne(pGetCoeff(p.p)));
7137
7138#ifdef KDEBUG
7139  // do not put an LObject twice into T:
7140  for(i=strat->tl;i>=0;i--)
7141  {
7142    if (p.p==strat->T[i].p)
7143    {
7144      printf("already in T at pos %d of %d, atT=%d\n",i,strat->tl,atT);
7145      return;
7146    }
7147  }
7148#endif
7149  strat->newt = TRUE;
7150  if (atT < 0)
7151    atT = strat->posInT(strat->T, strat->tl, p);
7152  if (strat->tl == strat->tmax-1)
7153    enlargeT(strat->T,strat->R,strat->sevT,strat->tmax,setmaxTinc);
7154  if (atT <= strat->tl)
7155  {
7156#ifdef ENTER_USE_MEMMOVE
7157    memmove(&(strat->T[atT+1]), &(strat->T[atT]),
7158            (strat->tl-atT+1)*sizeof(TObject));
7159    memmove(&(strat->sevT[atT+1]), &(strat->sevT[atT]),
7160            (strat->tl-atT+1)*sizeof(unsigned long));
7161#endif
7162    for (i=strat->tl+1; i>=atT+1; i--)
7163    {
7164#ifndef ENTER_USE_MEMMOVE
7165      strat->T[i] = strat->T[i-1];
7166      strat->sevT[i] = strat->sevT[i-1];
7167#endif
7168      strat->R[strat->T[i].i_r] = &(strat->T[i]);
7169    }
7170  }
7171
7172  if ((strat->tailBin != NULL) && (pNext(p.p) != NULL))
7173  {
7174    pNext(p.p)=p_ShallowCopyDelete(pNext(p.p),
7175                                   (strat->tailRing != NULL ?
7176                                    strat->tailRing : currRing),
7177                                   strat->tailBin);
7178    if (p.t_p != NULL) pNext(p.t_p) = pNext(p.p);
7179  }
7180  strat->T[atT] = (TObject) p;
7181
7182  if (strat->tailRing != currRing && pNext(p.p) != NULL)
7183    strat->T[atT].max = p_GetMaxExpP(pNext(p.p), strat->tailRing);
7184  else
7185    strat->T[atT].max = NULL;
7186
7187  strat->tl++;
7188  strat->R[strat->tl] = &(strat->T[atT]);
7189  strat->T[atT].i_r = strat->tl;
7190  assume(p.sev == 0 || pGetShortExpVector(p.p) == p.sev);
7191  strat->sevT[atT] = (p.sev == 0 ? pGetShortExpVector(p.p) : p.sev);
7192  assume(kTest_T(&(strat->T[atT])));
7193}
7194
7195/*2
7196* puts signature p.sig to the set syz
7197*/
7198void enterSyz(LObject p, kStrategy strat)
7199{
7200  int i = strat->syzl;
7201
7202  strat->newt = TRUE;
7203  if (strat->syzl == strat->syzmax)
7204  {
7205    pEnlargeSet(&strat->syz,strat->syzmax,setmaxTinc);
7206    strat->sevSyz = (unsigned long*) omRealloc0Size(strat->sevSyz,
7207                                    (strat->syzmax)*sizeof(unsigned long),
7208                                    ((strat->syzmax)+setmaxTinc)
7209                                                  *sizeof(unsigned long));
7210    strat->syzmax += setmaxTinc;
7211  }
7212  strat->syz[i] = p.sig;
7213  strat->sevSyz[i] = p.sevSig;
7214  strat->syzl++;
7215#ifdef DEBUGF5
7216  Print("last element in strat->syz: %d--%d  ",i+1,strat->syzmax);
7217  pWrite(strat->syz[i]);
7218#endif
7219  // recheck pairs in strat->L with new rule and delete correspondingly
7220  int cc = strat->Ll;
7221  while (cc>-1)
7222  {
7223    if (p_LmShortDivisibleBy( strat->syz[strat->syzl-1], strat->sevSyz[strat->syzl-1],
7224                              strat->L[cc].sig, ~strat->L[cc].sevSig, currRing))
7225    {
7226      deleteInL(strat->L,&strat->Ll,cc,strat);
7227    }
7228    cc--;
7229  }
7230
7231}
7232
7233
7234void initHilbCrit(ideal/*F*/, ideal /*Q*/, intvec **hilb,kStrategy strat)
7235{
7236
7237  //if the ordering is local, then hilb criterion
7238  //can be used also if tzhe ideal is not homogenous
7239  if((currRing->OrdSgn == -1) && (currRing->MixedOrder == 0 ))
7240  #ifdef HAVE_RINGS
7241  {
7242  if(rField_is_Ring(currRing))
7243          *hilb=NULL;
7244  else
7245           return;
7246  }
7247#endif
7248  if (strat->homog!=isHomog)
7249  {
7250    *hilb=NULL;
7251  }
7252}
7253
7254void initBuchMoraCrit(kStrategy strat)
7255{
7256  strat->enterOnePair=enterOnePairNormal;
7257  strat->chainCrit=chainCritNormal;
7258#ifdef HAVE_RINGS
7259  if (rField_is_Ring(currRing))
7260  {
7261    strat->enterOnePair=enterOnePairRing;
7262    strat->chainCrit=chainCritRing;
7263  }
7264#endif
7265#ifdef HAVE_RATGRING
7266  if (rIsRatGRing(currRing))
7267  {
7268     strat->chainCrit=chainCritPart;
7269     /* enterOnePairNormal get rational part in it */
7270  }
7271#endif
7272
7273  strat->sugarCrit =        TEST_OPT_SUGARCRIT;
7274  strat->Gebauer =          strat->homog || strat->sugarCrit;
7275  strat->honey =            !strat->homog || strat->sugarCrit || TEST_OPT_WEIGHTM;
7276  if (TEST_OPT_NOT_SUGAR) strat->honey = FALSE;
7277  strat->pairtest = NULL;
7278  /* alway use tailreduction, except:
7279  * - in local rings, - in lex order case, -in ring over extensions */
7280  strat->noTailReduction = !TEST_OPT_REDTAIL;
7281
7282#ifdef HAVE_PLURAL
7283  // and r is plural_ring
7284  //  hence this holds for r a rational_plural_ring
7285  if( rIsPluralRing(currRing) || (rIsSCA(currRing) && !strat->z2homog) )
7286  {    //or it has non-quasi-comm type... later
7287    strat->sugarCrit = FALSE;
7288    strat->Gebauer = FALSE;
7289    strat->honey = FALSE;
7290  }
7291#endif
7292
7293#ifdef HAVE_RINGS
7294  // Coefficient ring?
7295  if (rField_is_Ring(currRing))
7296  {
7297    strat->sugarCrit = FALSE;
7298    strat->Gebauer = FALSE ;
7299    strat->honey = FALSE;
7300  }
7301#endif
7302  #ifdef KDEBUG
7303  if (TEST_OPT_DEBUG)
7304  {
7305    if (strat->homog) PrintS("ideal/module is homogeneous\n");
7306    else              PrintS("ideal/module is not homogeneous\n");
7307  }
7308  #endif
7309}
7310
7311void initSbaCrit(kStrategy strat)
7312{
7313  //strat->enterOnePair=enterOnePairNormal;
7314  strat->enterOnePair = enterOnePairNormal;
7315  //strat->chainCrit=chainCritNormal;
7316  strat->chainCrit    = chainCritSig;
7317  /******************************************
7318   * rewCrit1 and rewCrit2 are already set in
7319   * kSba() in kstd1.cc
7320   *****************************************/
7321  //strat->rewCrit1     = faugereRewCriterion;
7322  if (strat->sbaOrder == 1)
7323  {
7324    strat->syzCrit  = syzCriterionInc;
7325  }
7326  else
7327  {
7328    strat->syzCrit  = syzCriterion;
7329  }
7330#ifdef HAVE_RINGS
7331  if (rField_is_Ring(currRing))
7332  {
7333    strat->enterOnePair=enterOnePairRing;
7334    strat->chainCrit=chainCritRing;
7335  }
7336#endif
7337#ifdef HAVE_RATGRING
7338  if (rIsRatGRing(currRing))
7339  {
7340     strat->chainCrit=chainCritPart;
7341     /* enterOnePairNormal get rational part in it */
7342  }
7343#endif
7344
7345  strat->sugarCrit =        TEST_OPT_SUGARCRIT;
7346  strat->Gebauer =          strat->homog || strat->sugarCrit;
7347  strat->honey =            !strat->homog || strat->sugarCrit || TEST_OPT_WEIGHTM;
7348  if (TEST_OPT_NOT_SUGAR) strat->honey = FALSE;
7349  strat->pairtest = NULL;
7350  /* alway use tailreduction, except:
7351  * - in local rings, - in lex order case, -in ring over extensions */
7352  strat->noTailReduction = !TEST_OPT_REDTAIL;
7353  //strat->noTailReduction = NULL;
7354
7355#ifdef HAVE_PLURAL
7356  // and r is plural_ring
7357  //  hence this holds for r a rational_plural_ring
7358  if( rIsPluralRing(currRing) || (rIsSCA(currRing) && !strat->z2homog) )
7359  {    //or it has non-quasi-comm type... later
7360    strat->sugarCrit = FALSE;
7361    strat->Gebauer = FALSE;
7362    strat->honey = FALSE;
7363  }
7364#endif
7365
7366#ifdef HAVE_RINGS
7367  // Coefficient ring?
7368  if (rField_is_Ring(currRing))
7369  {
7370    strat->sugarCrit = FALSE;
7371    strat->Gebauer = FALSE ;
7372    strat->honey = FALSE;
7373  }
7374#endif
7375  #ifdef KDEBUG
7376  if (TEST_OPT_DEBUG)
7377  {
7378    if (strat->homog) PrintS("ideal/module is homogeneous\n");
7379    else              PrintS("ideal/module is not homogeneous\n");
7380  }
7381  #endif
7382}
7383
7384BOOLEAN kPosInLDependsOnLength(int (*pos_in_l)
7385                               (const LSet set, const int length,
7386                                LObject* L,const kStrategy strat))
7387{
7388  if (pos_in_l == posInL110 ||
7389      pos_in_l == posInL10)
7390    return TRUE;
7391
7392  return FALSE;
7393}
7394
7395void initBuchMoraPos (kStrategy strat)
7396{
7397  if (currRing->OrdSgn==1)
7398  {
7399    if (strat->honey)
7400    {
7401      strat->posInL = posInL15;
7402      // ok -- here is the deal: from my experiments for Singular-2-0
7403      // I conclude that that posInT_EcartpLength is the best of
7404      // posInT15, posInT_EcartFDegpLength, posInT_FDegLength, posInT_pLength
7405      // see the table at the end of this file
7406      if (TEST_OPT_OLDSTD)
7407        strat->posInT = posInT15;
7408      else
7409        strat->posInT = posInT_EcartpLength;
7410    }
7411    else if (currRing->pLexOrder && !TEST_OPT_INTSTRATEGY)
7412    {
7413      strat->posInL = posInL11;
7414      strat->posInT = posInT11;
7415    }
7416    else if (TEST_OPT_INTSTRATEGY)
7417    {
7418      strat->posInL = posInL11;
7419      strat->posInT = posInT11;
7420    }
7421    else
7422    {
7423      strat->posInL = posInL0;
7424      strat->posInT = posInT0;
7425    }
7426    //if (strat->minim>0) strat->posInL =posInLSpecial;
7427    if (strat->homog)
7428    {
7429       strat->posInL = posInL110;
7430       strat->posInT = posInT110;
7431    }
7432  }
7433  else
7434  {
7435    if (strat->homog)
7436    {
7437      strat->posInL = posInL11;
7438      strat->posInT = posInT11;
7439    }
7440    else
7441    {
7442      if ((currRing->order[0]==ringorder_c)
7443      ||(currRing->order[0]==ringorder_C))
7444      {
7445        strat->posInL = posInL17_c;
7446        strat->posInT = posInT17_c;
7447      }
7448      else
7449      {
7450        strat->posInL = posInL17;
7451        strat->posInT = posInT17;
7452      }
7453    }
7454  }
7455  if (strat->minim>0) strat->posInL =posInLSpecial;
7456  // for further tests only
7457  if ((BTEST1(11)) || (BTEST1(12)))
7458    strat->posInL = posInL11;
7459  else if ((BTEST1(13)) || (BTEST1(14)))
7460    strat->posInL = posInL13;
7461  else if ((BTEST1(15)) || (BTEST1(16)))
7462    strat->posInL = posInL15;
7463  else if ((BTEST1(17)) || (BTEST1(18)))
7464    strat->posInL = posInL17;
7465  if (BTEST1(11))
7466    strat->posInT = posInT11;
7467  else if (BTEST1(13))
7468    strat->posInT = posInT13;
7469  else if (BTEST1(15))
7470    strat->posInT = posInT15;
7471  else if ((BTEST1(17)))
7472    strat->posInT = posInT17;
7473  else if ((BTEST1(19)))
7474    strat->posInT = posInT19;
7475  else if (BTEST1(12) || BTEST1(14) || BTEST1(16) || BTEST1(18))
7476    strat->posInT = posInT1;
7477#ifdef HAVE_RINGS
7478  if (rField_is_Ring(currRing))
7479  {
7480    strat->posInL = posInL11;
7481    strat->posInT = posInT11;
7482  }
7483#endif
7484  strat->posInLDependsOnLength = kPosInLDependsOnLength(strat->posInL);
7485}
7486
7487void initBuchMora (ideal F,ideal Q,kStrategy strat)
7488{
7489  strat->interpt = BTEST1(OPT_INTERRUPT);
7490  strat->kHEdge=NULL;
7491  if (currRing->OrdSgn==1) strat->kHEdgeFound=FALSE;
7492  /*- creating temp data structures------------------- -*/
7493  strat->cp = 0;
7494  strat->c3 = 0;
7495  strat->tail = pInit();
7496  /*- set s -*/
7497  strat->sl = -1;
7498  /*- set L -*/
7499  strat->Lmax = ((IDELEMS(F)+setmaxLinc-1)/setmaxLinc)*setmaxLinc;
7500  strat->Ll = -1;
7501  strat->L = initL(((IDELEMS(F)+setmaxLinc-1)/setmaxLinc)*setmaxLinc);
7502  /*- set B -*/
7503  strat->Bmax = setmaxL;
7504  strat->Bl = -1;
7505  strat->B = initL();
7506  /*- set T -*/
7507  strat->tl = -1;
7508  strat->tmax = setmaxT;
7509  strat->T = initT();
7510  strat->R = initR();
7511  strat->sevT = initsevT();
7512  /*- init local data struct.---------------------------------------- -*/
7513  strat->P.ecart=0;
7514  strat->P.length=0;
7515  if (currRing->OrdSgn==-1)
7516  {
7517    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
7518    if (strat->kNoether!=NULL) pSetComp(strat->kNoetherTail(), strat->ak);
7519  }
7520  if(TEST_OPT_SB_1)
7521  {
7522    int i;
7523    ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
7524    for (i=strat->newIdeal;i<IDELEMS(F);i++)
7525    {
7526      P->m[i-strat->newIdeal] = F->m[i];
7527      F->m[i] = NULL;
7528    }
7529    initSSpecial(F,Q,P,strat);
7530    for (i=strat->newIdeal;i<IDELEMS(F);i++)
7531    {
7532      F->m[i] = P->m[i-strat->newIdeal];
7533      P->m[i-strat->newIdeal] = NULL;
7534    }
7535    idDelete(&P);
7536  }
7537  else
7538  {
7539    /*Shdl=*/initSL(F, Q,strat); /*sets also S, ecartS, fromQ */
7540    // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
7541  }
7542  strat->fromT = FALSE;
7543  strat->noTailReduction = !TEST_OPT_REDTAIL;
7544  if (!TEST_OPT_SB_1)
7545  {
7546    updateS(TRUE,strat);
7547  }
7548  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
7549  strat->fromQ=NULL;
7550}
7551
7552void exitBuchMora (kStrategy strat)
7553{
7554  /*- release temp data -*/
7555  cleanT(strat);
7556  omFreeSize(strat->T,(strat->tmax)*sizeof(TObject));
7557  omFreeSize(strat->R,(strat->tmax)*sizeof(TObject*));
7558  omFreeSize(strat->sevT, (strat->tmax)*sizeof(unsigned long));
7559  omFreeSize(strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
7560  omFreeSize((ADDRESS)strat->sevS,IDELEMS(strat->Shdl)*sizeof(unsigned long));
7561  omFreeSize(strat->S_2_R,IDELEMS(strat->Shdl)*sizeof(int));
7562  /*- set L: should be empty -*/
7563  omFreeSize(strat->L,(strat->Lmax)*sizeof(LObject));
7564  /*- set B: should be empty -*/
7565  omFreeSize(strat->B,(strat->Bmax)*sizeof(LObject));
7566  pLmDelete(&strat->tail);
7567  strat->syzComp=0;
7568}
7569
7570void initSbaPos (kStrategy strat)
7571{
7572  if (currRing->OrdSgn==1)
7573  {
7574    if (strat->honey)
7575    {
7576      strat->posInL = posInL15;
7577      // ok -- here is the deal: from my experiments for Singular-2-0
7578      // I conclude that that posInT_EcartpLength is the best of
7579      // posInT15, posInT_EcartFDegpLength, posInT_FDegLength, posInT_pLength
7580      // see the table at the end of this file
7581      if (TEST_OPT_OLDSTD)
7582        strat->posInT = posInT15;
7583      else
7584        strat->posInT = posInT_EcartpLength;
7585    }
7586    else if (currRing->pLexOrder && !TEST_OPT_INTSTRATEGY)
7587    {
7588      strat->posInL = posInL11;
7589      strat->posInT = posInT11;
7590    }
7591    else if (TEST_OPT_INTSTRATEGY)
7592    {
7593      strat->posInL = posInL11;
7594      strat->posInT = posInT11;
7595    }
7596    else
7597    {
7598      strat->posInL = posInL0;
7599      strat->posInT = posInT0;
7600    }
7601    //if (strat->minim>0) strat->posInL =posInLSpecial;
7602    if (strat->homog)
7603    {
7604       strat->posInL = posInL110;
7605       strat->posInT = posInT110;
7606    }
7607  }
7608  else
7609  {
7610    if (strat->homog)
7611    {
7612      strat->posInL = posInL11;
7613      strat->posInT = posInT11;
7614    }
7615    else
7616    {
7617      if ((currRing->order[0]==ringorder_c)
7618      ||(currRing->order[0]==ringorder_C))
7619      {
7620        strat->posInL = posInL17_c;
7621        strat->posInT = posInT17_c;
7622      }
7623      else
7624      {
7625        strat->posInL = posInL17;
7626        strat->posInT = posInT17;
7627      }
7628    }
7629  }
7630  if (strat->minim>0) strat->posInL =posInLSpecial;
7631  // for further tests only
7632  if ((BTEST1(11)) || (BTEST1(12)))
7633    strat->posInL = posInL11;
7634  else if ((BTEST1(13)) || (BTEST1(14)))
7635    strat->posInL = posInL13;
7636  else if ((BTEST1(15)) || (BTEST1(16)))
7637    strat->posInL = posInL15;
7638  else if ((BTEST1(17)) || (BTEST1(18)))
7639    strat->posInL = posInL17;
7640  if (BTEST1(11))
7641    strat->posInT = posInT11;
7642  else if (BTEST1(13))
7643    strat->posInT = posInT13;
7644  else if (BTEST1(15))
7645    strat->posInT = posInT15;
7646  else if ((BTEST1(17)))
7647    strat->posInT = posInT17;
7648  else if ((BTEST1(19)))
7649    strat->posInT = posInT19;
7650  else if (BTEST1(12) || BTEST1(14) || BTEST1(16) || BTEST1(18))
7651    strat->posInT = posInT1;
7652#ifdef HAVE_RINGS
7653  if (rField_is_Ring(currRing))
7654  {
7655    strat->posInL = posInL11;
7656    strat->posInT = posInT11;
7657  }
7658#endif
7659  strat->posInLDependsOnLength = FALSE;
7660  strat->posInLSba  = posInLSig;
7661  //strat->posInL     = posInLSig;
7662  strat->posInL     = posInLF5C;
7663  //strat->posInT     = posInTSig;
7664}
7665
7666void initSbaBuchMora (ideal F,ideal Q,kStrategy strat)
7667{
7668  strat->interpt = BTEST1(OPT_INTERRUPT);
7669  strat->kHEdge=NULL;
7670  if (currRing->OrdSgn==1) strat->kHEdgeFound=FALSE;
7671  /*- creating temp data structures------------------- -*/
7672  strat->cp = 0;
7673  strat->c3 = 0;
7674  strat->tail = pInit();
7675  /*- set s -*/
7676  strat->sl = -1;
7677  /*- set ps -*/
7678  strat->syzl = -1;
7679  /*- set L -*/
7680  strat->Lmax = ((IDELEMS(F)+setmaxLinc-1)/setmaxLinc)*setmaxLinc;
7681  strat->Ll = -1;
7682  strat->L = initL(((IDELEMS(F)+setmaxLinc-1)/setmaxLinc)*setmaxLinc);
7683  /*- set B -*/
7684  strat->Bmax = setmaxL;
7685  strat->Bl = -1;
7686  strat->B = initL();
7687  /*- set T -*/
7688  strat->tl = -1;
7689  strat->tmax = setmaxT;
7690  strat->T = initT();
7691  strat->R = initR();
7692  strat->sevT = initsevT();
7693  /*- init local data struct.---------------------------------------- -*/
7694  strat->P.ecart=0;
7695  strat->P.length=0;
7696  if (currRing->OrdSgn==-1)
7697  {
7698    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
7699    if (strat->kNoether!=NULL) pSetComp(strat->kNoetherTail(), strat->ak);
7700  }
7701  if(TEST_OPT_SB_1)
7702  {
7703    int i;
7704    ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
7705    for (i=strat->newIdeal;i<IDELEMS(F);i++)
7706    {
7707      P->m[i-strat->newIdeal] = F->m[i];
7708      F->m[i] = NULL;
7709    }
7710    initSSpecialSba(F,Q,P,strat);
7711    for (i=strat->newIdeal;i<IDELEMS(F);i++)
7712    {
7713      F->m[i] = P->m[i-strat->newIdeal];
7714      P->m[i-strat->newIdeal] = NULL;
7715    }
7716    idDelete(&P);
7717  }
7718  else
7719  {
7720    /*Shdl=*/initSLSba(F, Q,strat); /*sets also S, ecartS, fromQ */
7721    // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
7722  }
7723  strat->fromT = FALSE;
7724  strat->noTailReduction = !TEST_OPT_REDTAIL;
7725  if (!TEST_OPT_SB_1)
7726  {
7727    updateS(TRUE,strat);
7728  }
7729  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
7730  strat->fromQ=NULL;
7731}
7732
7733void exitSba (kStrategy strat)
7734{
7735  /*- release temp data -*/
7736  cleanT(strat);
7737  omFreeSize(strat->T,(strat->tmax)*sizeof(TObject));
7738  omFreeSize(strat->R,(strat->tmax)*sizeof(TObject*));
7739  omFreeSize(strat->sevT, (strat->tmax)*sizeof(unsigned long));
7740  omFreeSize(strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
7741  omFreeSize(strat->fromS,IDELEMS(strat->Shdl)*sizeof(int));
7742  omFreeSize((ADDRESS)strat->sevS,IDELEMS(strat->Shdl)*sizeof(unsigned long));
7743  omFreeSize((ADDRESS)strat->sevSig,IDELEMS(strat->Shdl)*sizeof(unsigned long));
7744  omFreeSize((ADDRESS)strat->syz,(strat->syzmax)*sizeof(poly));
7745  omFreeSize((ADDRESS)strat->sevSyz,(strat->syzmax)*sizeof(unsigned long));
7746  if (strat->sbaOrder == 1)
7747  {
7748    omFreeSize(strat->syzIdx,(strat->syzidxmax)*sizeof(int));
7749  }
7750  omFreeSize(strat->S_2_R,IDELEMS(strat->Shdl)*sizeof(int));
7751  /*- set L: should be empty -*/
7752  omFreeSize(strat->L,(strat->Lmax)*sizeof(LObject));
7753  /*- set B: should be empty -*/
7754  omFreeSize(strat->B,(strat->Bmax)*sizeof(LObject));
7755  /*- set sig: no need for the signatures anymore -*/
7756  omFreeSize(strat->sig,IDELEMS(strat->Shdl)*sizeof(poly));
7757  pLmDelete(&strat->tail);
7758  strat->syzComp=0;
7759}
7760
7761/*2
7762* in the case of a standardbase of a module over a qring:
7763* replace polynomials in i by ak vectors,
7764* (the polynomial * unit vectors gen(1)..gen(ak)
7765* in every case (also for ideals:)
7766* deletes divisible vectors/polynomials
7767*/
7768void updateResult(ideal r,ideal Q, kStrategy strat)
7769{
7770  int l;
7771  if (strat->ak>0)
7772  {
7773    for (l=IDELEMS(r)-1;l>=0;l--)
7774    {
7775      if ((r->m[l]!=NULL) && (pGetComp(r->m[l])==0))
7776      {
7777        pDelete(&r->m[l]); // and set it to NULL
7778      }
7779    }
7780    int q;
7781    poly p;
7782    for (l=IDELEMS(r)-1;l>=0;l--)
7783    {
7784      if ((r->m[l]!=NULL)
7785      //&& (strat->syzComp>0)
7786      //&& (pGetComp(r->m[l])<=strat->syzComp)
7787      )
7788      {
7789        for(q=IDELEMS(Q)-1; q>=0;q--)
7790        {
7791          if ((Q->m[q]!=NULL)
7792          &&(pLmDivisibleBy(Q->m[q],r->m[l])))
7793          {
7794            if (TEST_OPT_REDSB)
7795            {
7796              p=r->m[l];
7797              r->m[l]=kNF(Q,NULL,p);
7798              pDelete(&p);
7799            }
7800            else
7801            {
7802              pDelete(&r->m[l]); // and set it to NULL
7803            }
7804            break;
7805          }
7806        }
7807      }
7808    }
7809  }
7810  else
7811  {
7812    int q;
7813    poly p;
7814    BOOLEAN reduction_found=FALSE;
7815    for (l=IDELEMS(r)-1;l>=0;l--)
7816    {
7817      if (r->m[l]!=NULL)
7818      {
7819        for(q=IDELEMS(Q)-1; q>=0;q--)
7820        {
7821          if ((Q->m[q]!=NULL)
7822          &&(pLmEqual(r->m[l],Q->m[q])))
7823          {
7824            if (TEST_OPT_REDSB)
7825            {
7826              p=r->m[l];
7827              r->m[l]=kNF(Q,NULL,p);
7828              pDelete(&p);
7829              reduction_found=TRUE;
7830            }
7831            else
7832            {
7833              pDelete(&r->m[l]); // and set it to NULL
7834            }
7835            break;
7836          }
7837        }
7838      }
7839    }
7840    if (/*TEST_OPT_REDSB &&*/ reduction_found)
7841    {
7842      for (l=IDELEMS(r)-1;l>=0;l--)
7843      {
7844        if (r->m[l]!=NULL)
7845        {
7846          for(q=IDELEMS(r)-1;q>=0;q--)
7847          {
7848            if ((l!=q)
7849            && (r->m[q]!=NULL)
7850            &&(pLmDivisibleBy(r->m[l],r->m[q])))
7851            {
7852              pDelete(&r->m[q]);
7853            }
7854          }
7855        }
7856      }
7857    }
7858  }
7859  idSkipZeroes(r);
7860}
7861
7862void completeReduce (kStrategy strat, BOOLEAN withT)
7863{
7864  int i;
7865  int low = (((currRing->OrdSgn==1) && (strat->ak==0)) ? 1 : 0);
7866  LObject L;
7867
7868#ifdef KDEBUG
7869  // need to set this: during tailreductions of T[i], T[i].max is out of
7870  // sync
7871  sloppy_max = TRUE;
7872#endif
7873
7874  strat->noTailReduction = FALSE;
7875  if (TEST_OPT_PROT)
7876  {
7877    PrintLn();
7878    if (timerv) writeTime("standard base computed:");
7879  }
7880  if (TEST_OPT_PROT)
7881  {
7882    Print("(S:%d)",strat->sl);mflush();
7883  }
7884  for (i=strat->sl; i>=low; i--)
7885  {
7886    int end_pos=strat->sl;
7887    if ((strat->fromQ!=NULL) && (strat->fromQ[i])) continue; // do not reduce Q_i
7888    if (strat->ak==0) end_pos=i-1;
7889    TObject* T_j = strat->s_2_t(i);
7890    if ((T_j != NULL)&&(T_j->p==strat->S[i]))
7891    {
7892      L = *T_j;
7893      #ifdef KDEBUG
7894      if (TEST_OPT_DEBUG)
7895      {
7896        Print("test S[%d]:",i);
7897        p_wrp(L.p,currRing,strat->tailRing);
7898        PrintLn();
7899      }
7900      #endif
7901      if (currRing->OrdSgn == 1)
7902        strat->S[i] = redtailBba(&L, end_pos, strat, withT);
7903      else
7904        strat->S[i] = redtail(&L, strat->sl, strat);
7905      #ifdef KDEBUG
7906      if (TEST_OPT_DEBUG)
7907      {
7908        Print("to (tailR) S[%d]:",i);
7909        p_wrp(strat->S[i],currRing,strat->tailRing);
7910        PrintLn();
7911      }
7912      #endif
7913
7914      if (strat->redTailChange && strat->tailRing != currRing)
7915      {
7916        if (T_j->max != NULL) p_LmFree(T_j->max, strat->tailRing);
7917        if (pNext(T_j->p) != NULL)
7918          T_j->max = p_GetMaxExpP(pNext(T_j->p), strat->tailRing);
7919        else
7920          T_j->max = NULL;
7921      }
7922      if (TEST_OPT_INTSTRATEGY)
7923        T_j->pCleardenom();
7924    }
7925    else
7926    {
7927      assume(currRing == strat->tailRing);
7928      #ifdef KDEBUG
7929      if (TEST_OPT_DEBUG)
7930      {
7931        Print("test S[%d]:",i);
7932        p_wrp(strat->S[i],currRing,strat->tailRing);
7933        PrintLn();
7934      }
7935      #endif
7936      if (currRing->OrdSgn == 1)
7937        strat->S[i] = redtailBba(strat->S[i], end_pos, strat, withT);
7938      else
7939        strat->S[i] = redtail(strat->S[i], strat->sl, strat);
7940      if (TEST_OPT_INTSTRATEGY)
7941      {
7942        if (TEST_OPT_CONTENTSB)
7943        {
7944          number n;
7945          p_Cleardenom_n(strat->S[i], currRing, n);// also does a pContent
7946          if (!nIsOne(n))
7947          {
7948            denominator_list denom=(denominator_list)omAlloc(sizeof(denominator_list_s));
7949            denom->n=nInvers(n);
7950            denom->next=DENOMINATOR_LIST;
7951            DENOMINATOR_LIST=denom;
7952          }
7953          nDelete(&n);
7954        }
7955        else
7956        {
7957          //pContent(strat->S[i]);
7958          strat->S[i]=p_Cleardenom(strat->S[i], currRing);// also does a pContent
7959        }
7960      }
7961      #ifdef KDEBUG
7962      if (TEST_OPT_DEBUG)
7963      {
7964        Print("to (-tailR) S[%d]:",i);
7965        p_wrp(strat->S[i],currRing,strat->tailRing);
7966        PrintLn();
7967      }
7968      #endif
7969    }
7970    if (TEST_OPT_PROT)
7971      PrintS("-");
7972  }
7973  if (TEST_OPT_PROT) PrintLn();
7974#ifdef KDEBUG
7975  sloppy_max = FALSE;
7976#endif
7977}
7978
7979
7980/*2
7981* computes the new strat->kHEdge and the new pNoether,
7982* returns TRUE, if pNoether has changed
7983*/
7984BOOLEAN newHEdge(kStrategy strat)
7985{
7986  int i,j;
7987  poly newNoether;
7988
7989#if 0
7990  if (currRing->weight_all_1)
7991    scComputeHC(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
7992  else
7993    scComputeHCw(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
7994#else
7995  scComputeHC(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
7996#endif
7997  if (strat->t_kHEdge != NULL) p_LmFree(strat->t_kHEdge, strat->tailRing);
7998  if (strat->tailRing != currRing)
7999    strat->t_kHEdge = k_LmInit_currRing_2_tailRing(strat->kHEdge, strat->tailRing);
8000  /* compare old and new noether*/
8001  newNoether = pLmInit(strat->kHEdge);
8002  j = p_FDeg(newNoether,currRing);
8003/*  #ifdef HAVE_RINGS
8004  if (!rField_is_Ring(currRing))
8005  #endif */
8006  for (i=1; i<=(currRing->N); i++)
8007  {
8008    if (pGetExp(newNoether, i) > 0) pDecrExp(newNoether,i);
8009  }
8010  pSetm(newNoether);
8011  if (j < strat->HCord) /*- statistics -*/
8012  {
8013    if (TEST_OPT_PROT)
8014    {
8015      Print("H(%d)",j);
8016      mflush();
8017    }
8018    strat->HCord=j;
8019    #ifdef KDEBUG
8020    if (TEST_OPT_DEBUG)
8021    {
8022      Print("H(%d):",j);
8023      wrp(strat->kHEdge);
8024      PrintLn();
8025    }
8026    #endif
8027  }
8028  if (pCmp(strat->kNoether,newNoether)!=1)
8029  {
8030    pDelete(&strat->kNoether);
8031    strat->kNoether=newNoether;
8032    if (strat->t_kNoether != NULL) p_LmFree(strat->t_kNoether, strat->tailRing);
8033    if (strat->tailRing != currRing)
8034      strat->t_kNoether = k_LmInit_currRing_2_tailRing(strat->kNoether, strat->tailRing);
8035
8036    return TRUE;
8037  }
8038  pLmFree(newNoether);
8039  return FALSE;
8040}
8041
8042/***************************************************************
8043 *
8044 * Routines related for ring changes during std computations
8045 *
8046 ***************************************************************/
8047BOOLEAN kCheckSpolyCreation(LObject *L, kStrategy strat, poly &m1, poly &m2)
8048{
8049  if (strat->overflow) return FALSE;
8050  assume(L->p1 != NULL && L->p2 != NULL);
8051  // shift changes: from 0 to -1
8052  assume(L->i_r1 >= -1 && L->i_r1 <= strat->tl);
8053  assume(L->i_r2 >= -1 && L->i_r2 <= strat->tl);
8054  assume(strat->tailRing != currRing);
8055
8056  if (! k_GetLeadTerms(L->p1, L->p2, currRing, m1, m2, strat->tailRing))
8057    return FALSE;
8058  // shift changes: extra case inserted
8059  if ((L->i_r1 == -1) || (L->i_r2 == -1) )
8060  {
8061    return TRUE;
8062  }
8063  poly p1_max = (strat->R[L->i_r1])->max;
8064  poly p2_max = (strat->R[L->i_r2])->max;
8065
8066  if (((p1_max != NULL) && !p_LmExpVectorAddIsOk(m1, p1_max, strat->tailRing)) ||
8067      ((p2_max != NULL) && !p_LmExpVectorAddIsOk(m2, p2_max, strat->tailRing)))
8068  {
8069    p_LmFree(m1, strat->tailRing);
8070    p_LmFree(m2, strat->tailRing);
8071    m1 = NULL;
8072    m2 = NULL;
8073    return FALSE;
8074  }
8075  return TRUE;
8076}
8077
8078#ifdef HAVE_RINGS
8079/***************************************************************
8080 *
8081 * Checks, if we can compute the gcd poly / strong pair
8082 * gcd-poly = m1 * R[atR] + m2 * S[atS]
8083 *
8084 ***************************************************************/
8085BOOLEAN kCheckStrongCreation(int atR, poly m1, int atS, poly m2, kStrategy strat)
8086{
8087  assume(strat->S_2_R[atS] >= -1 && strat->S_2_R[atS] <= strat->tl);
8088  //assume(strat->tailRing != currRing);
8089
8090  poly p1_max = (strat->R[atR])->max;
8091  poly p2_max = (strat->R[strat->S_2_R[atS]])->max;
8092
8093  if (((p1_max != NULL) && !p_LmExpVectorAddIsOk(m1, p1_max, strat->tailRing)) ||
8094      ((p2_max != NULL) && !p_LmExpVectorAddIsOk(m2, p2_max, strat->tailRing)))
8095  {
8096    return FALSE;
8097  }
8098  return TRUE;
8099}
8100#endif
8101
8102BOOLEAN kStratChangeTailRing(kStrategy strat, LObject *L, TObject* T, unsigned long expbound)
8103{
8104  assume((strat->tailRing == currRing) || (strat->tailRing->bitmask < currRing->bitmask));
8105  /* initial setup or extending */
8106
8107  if (expbound == 0) expbound = strat->tailRing->bitmask << 1;
8108  if (expbound >= currRing->bitmask) return FALSE;
8109  strat->overflow=FALSE;
8110  ring new_tailRing = rModifyRing(currRing,
8111  // Hmmm .. the condition pFDeg == p_Deg
8112  // might be too strong
8113#ifdef HAVE_RINGS
8114  (strat->homog && currRing->pFDeg == p_Deg && !(rField_is_Ring(currRing))), // TODO Oliver
8115#else
8116  (strat->homog && currRing->pFDeg == p_Deg), // omit_degree
8117#endif
8118  (strat->ak==0), // omit_comp if the input is an ideal
8119  expbound); // exp_limit
8120
8121  if (new_tailRing == currRing) return TRUE;
8122
8123  strat->pOrigFDeg_TailRing = new_tailRing->pFDeg;
8124  strat->pOrigLDeg_TailRing = new_tailRing->pLDeg;
8125
8126  if (currRing->pFDeg != currRing->pFDegOrig)
8127  {
8128    new_tailRing->pFDeg = currRing->pFDeg;
8129    new_tailRing->pLDeg = currRing->pLDeg;
8130  }
8131
8132  if (TEST_OPT_PROT)
8133    Print("[%lu:%d", (unsigned long) new_tailRing->bitmask, new_tailRing->ExpL_Size);
8134  assume(kTest_TS(strat));
8135  assume(new_tailRing != strat->tailRing);
8136  pShallowCopyDeleteProc p_shallow_copy_delete
8137    = pGetShallowCopyDeleteProc(strat->tailRing, new_tailRing);
8138
8139  omBin new_tailBin = omGetStickyBinOfBin(new_tailRing->PolyBin);
8140
8141  int i;
8142  for (i=0; i<=strat->tl; i++)
8143  {
8144    strat->T[i].ShallowCopyDelete(new_tailRing, new_tailBin,
8145                                  p_shallow_copy_delete);
8146  }
8147  for (i=0; i<=strat->Ll; i++)
8148  {
8149    assume(strat->L[i].p != NULL);
8150    if (pNext(strat->L[i].p) != strat->tail)
8151      strat->L[i].ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
8152  }
8153  if ((strat->P.t_p != NULL) ||
8154      ((strat->P.p != NULL) && pNext(strat->P.p) != strat->tail))
8155    strat->P.ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
8156
8157  if ((L != NULL) && (L->tailRing != new_tailRing))
8158  {
8159    if (L->i_r < 0)
8160      L->ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
8161    else
8162    {
8163      assume(L->i_r <= strat->tl);
8164      TObject* t_l = strat->R[L->i_r];
8165      assume(t_l != NULL);
8166      L->tailRing = new_tailRing;
8167      L->p = t_l->p;
8168      L->t_p = t_l->t_p;
8169      L->max = t_l->max;
8170    }
8171  }
8172
8173  if ((T != NULL) && (T->tailRing != new_tailRing && T->i_r < 0))
8174    T->ShallowCopyDelete(new_tailRing, new_tailBin, p_shallow_copy_delete);
8175
8176  omMergeStickyBinIntoBin(strat->tailBin, strat->tailRing->PolyBin);
8177  if (strat->tailRing != currRing)
8178    rKillModifiedRing(strat->tailRing);
8179
8180  strat->tailRing = new_tailRing;
8181  strat->tailBin = new_tailBin;
8182  strat->p_shallow_copy_delete
8183    = pGetShallowCopyDeleteProc(currRing, new_tailRing);
8184
8185  if (strat->kHEdge != NULL)
8186  {
8187    if (strat->t_kHEdge != NULL)
8188      p_LmFree(strat->t_kHEdge, strat->tailRing);
8189    strat->t_kHEdge=k_LmInit_currRing_2_tailRing(strat->kHEdge, new_tailRing);
8190  }
8191
8192  if (strat->kNoether != NULL)
8193  {
8194    if (strat->t_kNoether != NULL)
8195      p_LmFree(strat->t_kNoether, strat->tailRing);
8196    strat->t_kNoether=k_LmInit_currRing_2_tailRing(strat->kNoether,
8197                                                   new_tailRing);
8198  }
8199  assume(kTest_TS(strat));
8200  if (TEST_OPT_PROT)
8201    PrintS("]");
8202  return TRUE;
8203}
8204
8205void kStratInitChangeTailRing(kStrategy strat)
8206{
8207  unsigned long l = 0;
8208  int i;
8209  long e;
8210
8211  assume(strat->tailRing == currRing);
8212
8213  for (i=0; i<= strat->Ll; i++)
8214  {
8215    l = p_GetMaxExpL(strat->L[i].p, currRing, l);
8216  }
8217  for (i=0; i<=strat->tl; i++)
8218  {
8219    // Hmm ... this we could do in one Step
8220    l = p_GetMaxExpL(strat->T[i].p, currRing, l);
8221  }
8222  if (rField_is_Ring(currRing))
8223  {
8224    l *= 2;
8225  }
8226  e = p_GetMaxExp(l, currRing);
8227  if (e <= 1) e = 2;
8228
8229  kStratChangeTailRing(strat, NULL, NULL, e);
8230}
8231
8232ring sbaRing (kStrategy strat, const ring r, BOOLEAN /*complete*/, int /*sgn*/)
8233{
8234  int n = rBlocks(r); // Including trailing zero!
8235  // if sbaOrder == 1 => use (C,monomial order from r)
8236  if (strat->sbaOrder == 1)
8237  {
8238    if (r->order[0] == ringorder_C || r->order[0] == ringorder_c)
8239    {
8240      return r;
8241    }
8242    ring res = rCopy0(r, FALSE, TRUE);
8243    for (int i=1; i<n-1; i++)
8244    {
8245      res->order[i] = res->order[i-1];
8246      res->block0[i] = res->block0[i-1];
8247      res->block1[i] = res->block1[i-1];
8248      res->wvhdl[i] = res->wvhdl[i-1];
8249    }
8250
8251    // new 1st block
8252    res->order[0]   = ringorder_C; // Prefix
8253    res->block0[0]  = 1;
8254    res->block1[0]  = res->N;
8255    //res->wvhdl[j]   = NULL;
8256    // res->order [j] = 0; // The End!
8257    rComplete(res, 1);
8258#ifdef HAVE_PLURAL
8259    if (rIsPluralRing(r))
8260    {
8261      if ( nc_rComplete(r, res, false) ) // no qideal!
8262      {
8263#ifndef NDEBUG
8264        WarnS("error in nc_rComplete");
8265#endif
8266        // cleanup?
8267
8268        //      rDelete(res);
8269        //      return r;
8270
8271        // just go on..
8272      }
8273    }
8274#endif
8275    strat->tailRing = res;
8276    return (res);
8277  }
8278
8279  // not sbaOrder == 1 => use Schreyer order
8280  // this is done by a trick when initializing the signatures
8281  // in initSLSba():
8282  // Instead of using the signature 1e_i for F->m[i], we start
8283  // with the signature LM(F->m[i])e_i for F->m[i]. Doing this we get a
8284  // Schreyer order w.r.t. the underlying monomial order.
8285  // => we do not need to change the underlying polynomial ring at all!
8286
8287  // UPDATE/NOTE/TODO: use induced Schreyer ordering 'IS'!!!!????
8288
8289  /*
8290  else
8291  {
8292    ring res = rCopy0(r, FALSE, FALSE);
8293    // Create 2 more blocks for prefix/suffix:
8294    res->order=(int *)omAlloc0((n+2)*sizeof(int)); // 0  ..  n+1
8295    res->block0=(int *)omAlloc0((n+2)*sizeof(int));
8296    res->block1=(int *)omAlloc0((n+2)*sizeof(int));
8297    int ** wvhdl =(int **)omAlloc0((n+2)*sizeof(int**));
8298
8299    // Encapsulate all existing blocks between induced Schreyer ordering markers: prefix and suffix!
8300    // Note that prefix and suffix have the same ringorder marker and only differ in block[] parameters!
8301
8302    // new 1st block
8303    int j = 0;
8304    res->order[j] = ringorder_IS; // Prefix
8305    res->block0[j] = res->block1[j] = 0;
8306    // wvhdl[j] = NULL;
8307    j++;
8308
8309    for(int i = 0; (i < n) && (r->order[i] != 0); i++, j++) // i = [0 .. n-1] <- non-zero old blocks
8310    {
8311      res->order [j] = r->order [i];
8312      res->block0[j] = r->block0[i];
8313      res->block1[j] = r->block1[i];
8314
8315      if (r->wvhdl[i] != NULL)
8316      {
8317        wvhdl[j] = (int*) omMemDup(r->wvhdl[i]);
8318      } // else wvhdl[j] = NULL;
8319    }
8320
8321    // new last block
8322    res->order [j] = ringorder_IS; // Suffix
8323    res->block0[j] = res->block1[j] = sgn; // Sign of v[o]: 1 for C, -1 for c
8324    // wvhdl[j] = NULL;
8325    j++;
8326
8327    // res->order [j] = 0; // The End!
8328    res->wvhdl = wvhdl;
8329
8330    // j == the last zero block now!
8331    assume(j == (n+1));
8332    assume(res->order[0]==ringorder_IS);
8333    assume(res->order[j-1]==ringorder_IS);
8334    assume(res->order[j]==0);
8335
8336    if (complete)
8337    {
8338      rComplete(res, 1);
8339
8340#ifdef HAVE_PLURAL
8341      if (rIsPluralRing(r))
8342      {
8343        if ( nc_rComplete(r, res, false) ) // no qideal!
8344        {
8345        }
8346      }
8347      assume(rIsPluralRing(r) == rIsPluralRing(res));
8348#endif
8349
8350
8351#ifdef HAVE_PLURAL
8352      ring old_ring = r;
8353
8354#endif
8355
8356      if (r->qideal!=NULL)
8357      {
8358        res->qideal= idrCopyR_NoSort(r->qideal, r, res);
8359
8360        assume(idRankFreeModule(res->qideal, res) == 0);
8361
8362#ifdef HAVE_PLURAL
8363        if( rIsPluralRing(res) )
8364          if( nc_SetupQuotient(res, r, true) )
8365          {
8366            //          WarnS("error in nc_SetupQuotient"); // cleanup?      rDelete(res);       return r;  // just go on...?
8367          }
8368
8369#endif
8370        assume(idRankFreeModule(res->qideal, res) == 0);
8371      }
8372
8373#ifdef HAVE_PLURAL
8374      assume((res->qideal==NULL) == (old_ring->qideal==NULL));
8375      assume(rIsPluralRing(res) == rIsPluralRing(old_ring));
8376      assume(rIsSCA(res) == rIsSCA(old_ring));
8377      assume(ncRingType(res) == ncRingType(old_ring));
8378#endif
8379    }
8380    strat->tailRing = res;
8381    return res;
8382  }
8383  */
8384
8385  assume(FALSE);
8386  return(NULL);
8387}
8388
8389skStrategy::skStrategy()
8390{
8391  memset(this, 0, sizeof(skStrategy));
8392#ifndef NDEBUG
8393  strat_nr++;
8394  nr=strat_nr;
8395  if (strat_fac_debug) Print("s(%d) created\n",nr);
8396#endif
8397  tailRing = currRing;
8398  P.tailRing = currRing;
8399  tl = -1;
8400  sl = -1;
8401#ifdef HAVE_LM_BIN
8402  lmBin = omGetStickyBinOfBin(currRing->PolyBin);
8403#endif
8404#ifdef HAVE_TAIL_BIN
8405  tailBin = omGetStickyBinOfBin(currRing->PolyBin);
8406#endif
8407  pOrigFDeg = currRing->pFDeg;
8408  pOrigLDeg = currRing->pLDeg;
8409}
8410
8411
8412skStrategy::~skStrategy()
8413{
8414  if (lmBin != NULL)
8415    omMergeStickyBinIntoBin(lmBin, currRing->PolyBin);
8416  if (tailBin != NULL)
8417    omMergeStickyBinIntoBin(tailBin,
8418                            (tailRing != NULL ? tailRing->PolyBin:
8419                             currRing->PolyBin));
8420  if (t_kHEdge != NULL)
8421    p_LmFree(t_kHEdge, tailRing);
8422  if (t_kNoether != NULL)
8423    p_LmFree(t_kNoether, tailRing);
8424
8425  if (currRing != tailRing)
8426    rKillModifiedRing(tailRing);
8427  pRestoreDegProcs(currRing,pOrigFDeg, pOrigLDeg);
8428}
8429
8430#if 0
8431Timings for the different possibilities of posInT:
8432            T15           EDL         DL          EL            L         1-2-3
8433Gonnet      43.26       42.30       38.34       41.98       38.40      100.04
8434Hairer_2_1   1.11        1.15        1.04        1.22        1.08        4.7
8435Twomat3      1.62        1.69        1.70        1.65        1.54       11.32
8436ahml         4.48        4.03        4.03        4.38        4.96       26.50
8437c7          15.02       13.98       15.16       13.24       17.31       47.89
8438c8         505.09      407.46      852.76      413.21      499.19        n/a
8439f855        12.65        9.27       14.97        8.78       14.23       33.12
8440gametwo6    11.47       11.35       14.57       11.20       12.02       35.07
8441gerhard_3    2.73        2.83        2.93        2.64        3.12        6.24
8442ilias13     22.89       22.46       24.62       20.60       23.34       53.86
8443noon8       40.68       37.02       37.99       36.82       35.59      877.16
8444rcyclic_19  48.22       42.29       43.99       45.35       51.51      204.29
8445rkat9       82.37       79.46       77.20       77.63       82.54      267.92
8446schwarz_11  16.46       16.81       16.76       16.81       16.72       35.56
8447test016     16.39       14.17       14.40       13.50       14.26       34.07
8448test017     34.70       36.01       33.16       35.48       32.75       71.45
8449test042     10.76       10.99       10.27       11.57       10.45       23.04
8450test058      6.78        6.75        6.51        6.95        6.22        9.47
8451test066     10.71       10.94       10.76       10.61       10.56       19.06
8452test073     10.75       11.11       10.17       10.79        8.63       58.10
8453test086     12.23       11.81       12.88       12.24       13.37       66.68
8454test103      5.05        4.80        5.47        4.64        4.89       11.90
8455test154     12.96       11.64       13.51       12.46       14.61       36.35
8456test162     65.27       64.01       67.35       59.79       67.54      196.46
8457test164      7.50        6.50        7.68        6.70        7.96       17.13
8458virasoro     3.39        3.50        3.35        3.47        3.70        7.66
8459#endif
8460
8461
8462//#ifdef HAVE_MORE_POS_IN_T
8463#if 1
8464// determines the position based on: 1.) Ecart 2.) FDeg 3.) pLength
8465int posInT_EcartFDegpLength(const TSet set,const int length,LObject &p)
8466{
8467
8468  if (length==-1) return 0;
8469
8470  int o = p.ecart;
8471  int op=p.GetpFDeg();
8472  int ol = p.GetpLength();
8473
8474  if (set[length].ecart < o)
8475    return length+1;
8476  if (set[length].ecart == o)
8477  {
8478     int oo=set[length].GetpFDeg();
8479     if ((oo < op) || ((oo==op) && (set[length].length < ol)))
8480       return length+1;
8481  }
8482
8483  int i;
8484  int an = 0;
8485  int en= length;
8486  loop
8487  {
8488    if (an >= en-1)
8489    {
8490      if (set[an].ecart > o)
8491        return an;
8492      if (set[an].ecart == o)
8493      {
8494         int oo=set[an].GetpFDeg();
8495         if((oo > op)
8496         || ((oo==op) && (set[an].pLength > ol)))
8497           return an;
8498      }
8499      return en;
8500    }
8501    i=(an+en) / 2;
8502    if (set[i].ecart > o)
8503      en=i;
8504    else if (set[i].ecart == o)
8505    {
8506       int oo=set[i].GetpFDeg();
8507       if ((oo > op)
8508       || ((oo == op) && (set[i].pLength > ol)))
8509         en=i;
8510       else
8511        an=i;
8512    }
8513    else
8514      an=i;
8515  }
8516}
8517
8518// determines the position based on: 1.) FDeg 2.) pLength
8519int posInT_FDegpLength(const TSet set,const int length,LObject &p)
8520{
8521
8522  if (length==-1) return 0;
8523
8524  int op=p.GetpFDeg();
8525  int ol = p.GetpLength();
8526
8527  int oo=set[length].GetpFDeg();
8528  if ((oo < op) || ((oo==op) && (set[length].length < ol)))
8529    return length+1;
8530
8531  int i;
8532  int an = 0;
8533  int en= length;
8534  loop
8535    {
8536      if (an >= en-1)
8537      {
8538        int oo=set[an].GetpFDeg();
8539        if((oo > op)
8540           || ((oo==op) && (set[an].pLength > ol)))
8541          return an;
8542        return en;
8543      }
8544      i=(an+en) / 2;
8545      int oo=set[i].GetpFDeg();
8546      if ((oo > op)
8547          || ((oo == op) && (set[i].pLength > ol)))
8548        en=i;
8549      else
8550        an=i;
8551    }
8552}
8553
8554
8555// determines the position based on: 1.) pLength
8556int posInT_pLength(const TSet set,const int length,LObject &p)
8557{
8558  int ol = p.GetpLength();
8559  if (length==-1)
8560    return 0;
8561  if (set[length].length<p.length)
8562    return length+1;
8563
8564  int i;
8565  int an = 0;
8566  int en= length;
8567
8568  loop
8569  {
8570    if (an >= en-1)
8571    {
8572      if (set[an].pLength>ol) return an;
8573      return en;
8574    }
8575    i=(an+en) / 2;
8576    if (set[i].pLength>ol) en=i;
8577    else                        an=i;
8578  }
8579}
8580#endif
8581
8582// kstd1.cc:
8583int redFirst (LObject* h,kStrategy strat);
8584int redEcart (LObject* h,kStrategy strat);
8585void enterSMora (LObject p,int atS,kStrategy strat, int atR=-1);
8586void enterSMoraNF (LObject p,int atS,kStrategy strat, int atR=-1);
8587// ../Singular/misc.cc:
8588extern char *  showOption();
8589
8590void kDebugPrint(kStrategy strat)
8591{
8592  PrintS("red: ");
8593    if (strat->red==redFirst) PrintS("redFirst\n");
8594    else if (strat->red==redHoney) PrintS("redHoney\n");
8595    else if (strat->red==redEcart) PrintS("redEcart\n");
8596    else if (strat->red==redHomog) PrintS("redHomog\n");
8597    else  Print("%p\n",(void*)strat->red);
8598  PrintS("posInT: ");
8599    if (strat->posInT==posInT0) PrintS("posInT0\n");
8600    else if (strat->posInT==posInT0) PrintS("posInT0\n");
8601    else if (strat->posInT==posInT1) PrintS("posInT1\n");
8602    else if (strat->posInT==posInT11) PrintS("posInT11\n");
8603    else if (strat->posInT==posInT110) PrintS("posInT110\n");
8604    else if (strat->posInT==posInT13) PrintS("posInT13\n");
8605    else if (strat->posInT==posInT15) PrintS("posInT15\n");
8606    else if (strat->posInT==posInT17) PrintS("posInT17\n");
8607    else if (strat->posInT==posInT17_c) PrintS("posInT17_c\n");
8608    else if (strat->posInT==posInT19) PrintS("posInT19\n");
8609    else if (strat->posInT==posInT2) PrintS("posInT2\n");
8610#ifdef HAVE_MORE_POS_IN_T
8611    else if (strat->posInT==posInT_EcartFDegpLength) PrintS("posInT_EcartFDegpLength\n");
8612    else if (strat->posInT==posInT_FDegpLength) PrintS("posInT_FDegpLength\n");
8613    else if (strat->posInT==posInT_pLength) PrintS("posInT_pLength\n");
8614#endif
8615    else if (strat->posInT==posInT_EcartpLength) PrintS("posInT_EcartpLength\n");
8616    else if (strat->posInT==posInTrg0) PrintS("posInTrg0\n");
8617    else  Print("%p\n",(void*)strat->posInT);
8618  PrintS("posInL: ");
8619    if (strat->posInL==posInL0) PrintS("posInL0\n");
8620    else if (strat->posInL==posInL10) PrintS("posInL10\n");
8621    else if (strat->posInL==posInL11) PrintS("posInL11\n");
8622    else if (strat->posInL==posInL110) PrintS("posInL110\n");
8623    else if (strat->posInL==posInL13) PrintS("posInL13\n");
8624    else if (strat->posInL==posInL15) PrintS("posInL15\n");
8625    else if (strat->posInL==posInL17) PrintS("posInL17\n");
8626    else if (strat->posInL==posInL17_c) PrintS("posInL17_c\n");
8627    else if (strat->posInL==posInLSpecial) PrintS("posInLSpecial\n");
8628    else if (strat->posInL==posInLrg0) PrintS("posInLrg0\n");
8629    else  Print("%p\n",(void*)strat->posInL);
8630  PrintS("enterS: ");
8631    if (strat->enterS==enterSBba) PrintS("enterSBba\n");
8632    else if (strat->enterS==enterSMora) PrintS("enterSMora\n");
8633    else if (strat->enterS==enterSMoraNF) PrintS("enterSMoraNF\n");
8634    else  Print("%p\n",(void*)strat->enterS);
8635  PrintS("initEcart: ");
8636    if (strat->initEcart==initEcartBBA) PrintS("initEcartBBA\n");
8637    else if (strat->initEcart==initEcartNormal) PrintS("initEcartNormal\n");
8638    else  Print("%p\n",(void*)strat->initEcart);
8639  PrintS("initEcartPair: ");
8640    if (strat->initEcartPair==initEcartPairBba) PrintS("initEcartPairBba\n");
8641    else if (strat->initEcartPair==initEcartPairMora) PrintS("initEcartPairMora\n");
8642    else  Print("%p\n",(void*)strat->initEcartPair);
8643  Print("homog=%d, LazyDegree=%d, LazyPass=%d, ak=%d,\n",
8644         strat->homog, strat->LazyDegree,strat->LazyPass, strat->ak);
8645  Print("honey=%d, sugarCrit=%d, Gebauer=%d, noTailReduction=%d, use_buckets=%d\n",
8646         strat->honey,strat->sugarCrit,strat->Gebauer,strat->noTailReduction,strat->use_buckets);
8647  Print("posInLDependsOnLength=%d\n",
8648         strat->posInLDependsOnLength);
8649  PrintS(showOption());PrintLn();
8650  PrintS("LDeg: ");
8651    if (currRing->pLDeg==pLDeg0) PrintS("pLDeg0");
8652    else if (currRing->pLDeg==pLDeg0c) PrintS("pLDeg0c");
8653    else if (currRing->pLDeg==pLDegb) PrintS("pLDegb");
8654    else if (currRing->pLDeg==pLDeg1) PrintS("pLDeg1");
8655    else if (currRing->pLDeg==pLDeg1c) PrintS("pLDeg1c");
8656    else if (currRing->pLDeg==pLDeg1_Deg) PrintS("pLDeg1_Deg");
8657    else if (currRing->pLDeg==pLDeg1c_Deg) PrintS("pLDeg1c_Deg");
8658    else if (currRing->pLDeg==pLDeg1_Totaldegree) PrintS("pLDeg1_Totaldegree");
8659    else if (currRing->pLDeg==pLDeg1c_Totaldegree) PrintS("pLDeg1c_Totaldegree");
8660    else if (currRing->pLDeg==pLDeg1_WFirstTotalDegree) PrintS("pLDeg1_WFirstTotalDegree");
8661    else if (currRing->pLDeg==pLDeg1c_WFirstTotalDegree) PrintS("pLDeg1c_WFirstTotalDegree");
8662    else if (currRing->pLDeg==maxdegreeWecart) PrintS("maxdegreeWecart");
8663    else Print("? (%lx)", (long)currRing->pLDeg);
8664    PrintS(" / ");
8665    if (strat->tailRing->pLDeg==pLDeg0) PrintS("pLDeg0");
8666    else if (strat->tailRing->pLDeg==pLDeg0c) PrintS("pLDeg0c");
8667    else if (strat->tailRing->pLDeg==pLDegb) PrintS("pLDegb");
8668    else if (strat->tailRing->pLDeg==pLDeg1) PrintS("pLDeg1");
8669    else if (strat->tailRing->pLDeg==pLDeg1c) PrintS("pLDeg1c");
8670    else if (strat->tailRing->pLDeg==pLDeg1_Deg) PrintS("pLDeg1_Deg");
8671    else if (strat->tailRing->pLDeg==pLDeg1c_Deg) PrintS("pLDeg1c_Deg");
8672    else if (strat->tailRing->pLDeg==pLDeg1_Totaldegree) PrintS("pLDeg1_Totaldegree");
8673    else if (strat->tailRing->pLDeg==pLDeg1c_Totaldegree) PrintS("pLDeg1c_Totaldegree");
8674    else if (strat->tailRing->pLDeg==pLDeg1_WFirstTotalDegree) PrintS("pLDeg1_WFirstTotalDegree");
8675    else if (strat->tailRing->pLDeg==pLDeg1c_WFirstTotalDegree) PrintS("pLDeg1c_WFirstTotalDegree");
8676    else if (strat->tailRing->pLDeg==maxdegreeWecart) PrintS("maxdegreeWecart");
8677    else Print("? (%lx)", (long)strat->tailRing->pLDeg);
8678    PrintLn();
8679  PrintS("currRing->pFDeg: ");
8680    if (currRing->pFDeg==p_Totaldegree) PrintS("p_Totaldegree");
8681    else if (currRing->pFDeg==p_WFirstTotalDegree) PrintS("pWFirstTotalDegree");
8682    else if (currRing->pFDeg==p_Deg) PrintS("p_Deg");
8683    else if (currRing->pFDeg==kHomModDeg) PrintS("kHomModDeg");
8684    else if (currRing->pFDeg==totaldegreeWecart) PrintS("totaldegreeWecart");
8685    else if (currRing->pFDeg==p_WTotaldegree) PrintS("p_WTotaldegree");
8686    else Print("? (%lx)", (long)currRing->pFDeg);
8687    PrintLn();
8688    Print(" syzring:%d, syzComp(strat):%d limit:%d\n",rIsSyzIndexRing(currRing),strat->syzComp,rGetCurrSyzLimit(currRing));
8689    if(TEST_OPT_DEGBOUND)
8690      Print(" degBound: %d\n", Kstd1_deg);
8691
8692    if( ecartWeights != NULL )
8693    {
8694       PrintS("ecartWeights: ");
8695       for (int i = rVar(currRing); i > 0; i--)
8696         Print("%hd ", ecartWeights[i]);
8697       PrintLn();
8698       assume( TEST_OPT_WEIGHTM );
8699    }
8700
8701#ifndef NDEBUG
8702    rDebugPrint(currRing);
8703#endif
8704}
8705
8706
8707#ifdef HAVE_SHIFTBBA
8708poly pMove2CurrTail(poly p, kStrategy strat)
8709{
8710  /* assume: p is completely in currRing */
8711  /* produces an object with LM in curring
8712     and TAIL in tailring */
8713  if (pNext(p)!=NULL)
8714  {
8715    pNext(p) = prMoveR(pNext(p), /* src */ currRing, /* dest */ strat->tailRing);
8716  }
8717  return(p);
8718}
8719#endif
8720
8721#ifdef HAVE_SHIFTBBA
8722poly pMoveCurrTail2poly(poly p, kStrategy strat)
8723{
8724  /* assume: p has  LM in curring and TAIL in tailring */
8725  /* convert it to complete currRing */
8726
8727  /* check that LM is in currRing */
8728  assume(p_LmCheckIsFromRing(p, currRing));
8729
8730  if (pNext(p)!=NULL)
8731  {
8732    pNext(p) = prMoveR(pNext(p), /* src */ strat->tailRing, /* dest */currRing);
8733  }
8734  return(p);
8735}
8736#endif
8737
8738#ifdef HAVE_SHIFTBBA
8739poly pCopyL2p(LObject H, kStrategy strat)
8740{
8741    /* restores a poly in currRing from LObject */
8742    LObject h = H;
8743    h.Copy();
8744    poly p;
8745    if (h.p == NULL)
8746    {
8747      if (h.t_p != NULL)
8748      {
8749         p = prMoveR(h.t_p, /* source ring: */ strat->tailRing, /* dest. ring: */ currRing);
8750        return(p);
8751      }
8752      else
8753      {
8754        /* h.tp == NULL -> the object is NULL */
8755        return(NULL);
8756      }
8757    }
8758    /* we're here if h.p != NULL */
8759    if (h.t_p == NULL)
8760    {
8761       /* then h.p is the whole poly in currRing */
8762       p = h.p;
8763      return(p);
8764    }
8765    /* we're here if h.p != NULL and h.t_p != NULL */
8766    // clean h.p, get poly from t_p
8767     pNext(h.p)=NULL;
8768     pDelete(&h.p);
8769     p = prMoveR(h.t_p, /* source ring: */ strat->tailRing,
8770                         /* dest. ring: */ currRing);
8771     // no need to clean h: we re-used the polys
8772    return(p);
8773}
8774#endif
8775
8776//LObject pCopyp2L(poly p, kStrategy strat)
8777//{
8778    /* creates LObject from the poly in currRing */
8779  /* actually put p into L.p and make L.t_p=NULL : does not work */
8780
8781//}
8782
8783// poly pCopyL2p(LObject H, kStrategy strat)
8784// {
8785//   /* restores a poly in currRing from LObject */
8786//   LObject h = H;
8787//   h.Copy();
8788//   poly p;
8789//   if (h.p == NULL)
8790//   {
8791//     if (h.t_p != NULL)
8792//     {
8793//       p = p_ShallowCopyDelete(h.t_p, (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
8794//       return(p);
8795//     }
8796//     else
8797//     {
8798//       /* h.tp == NULL -> the object is NULL */
8799//       return(NULL);
8800//     }
8801//   }
8802//   /* we're here if h.p != NULL */
8803
8804//   if (h.t_p == NULL)
8805//   {
8806//     /* then h.p is the whole poly in tailRing */
8807//     if (strat->tailBin != NULL && (pNext(h.p) != NULL))
8808//     {
8809//       p = p_ShallowCopyDelete(h.p, (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
8810//     }
8811//     return(p);
8812//   }
8813//   /* we're here if h.p != NULL and h.t_p != NULL */
8814//   p = pCopy(pHead(h.p)); // in currRing
8815//   if (strat->tailBin != NULL && (pNext(h.p) != NULL))
8816//   {
8817//     //    pNext(p) = p_ShallowCopyDelete(pNext(h.t_p), (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
8818//     poly pp = p_Copy(pNext(h.p), strat->tailRing);
8819//     //    poly p3 = p_Copy(pNext(h.p), currRing); // error
8820//       // p_ShallowCopyDelete(pNext(h.p), currRing, strat->tailBin); // the same as pp
8821//     poly p5 = p_ShallowCopyDelete(pNext(h.p), strat->tailRing, strat->tailBin);
8822//     pNext(p) = p_ShallowCopyDelete(h.t_p, strat->tailRing, strat->tailBin);
8823//     poly p4 = p_Copy(h.t_p, strat->tailRing);
8824//     //    if (p.t_p != NULL) pNext(p.t_p) = pNext(p.p);
8825//   }
8826//   //  pTest(p);
8827//   return(p);
8828// }
8829
8830#ifdef HAVE_SHIFTBBA
8831/* including the self pairs */
8832void updateSShift(kStrategy strat,int uptodeg,int lV)
8833{
8834  /* to use after updateS(toT=FALSE,strat) */
8835  /* fills T with shifted elt's of S */
8836  int i;
8837  LObject h;
8838  int atT = -1; // or figure out smth better
8839  strat->tl = -1; // init
8840  for (i=0; i<=strat->sl; i++)
8841  {
8842    memset(&h,0,sizeof(h));
8843    h.p =  strat->S[i]; // lm in currRing, tail in TR
8844    strat->initEcart(&h);
8845    h.sev = strat->sevS[i];
8846    h.t_p = NULL;
8847    h.GetTP(); // creates correct t_p
8848    /*puts the elements of S with their shifts to T*/
8849    //    int atT, int uptodeg, int lV)
8850    strat->S_2_R[i] = strat->tl + 1; // the el't with shift 0 will be inserted first
8851    // need a small check for above; we insert >=1 elements
8852    // insert this check into kTest_TS ?
8853    enterTShift(h,strat,atT,uptodeg,lV);
8854  }
8855  /* what about setting strat->tl? */
8856}
8857#endif
8858
8859#ifdef HAVE_SHIFTBBA
8860void initBuchMoraShift (ideal F,ideal Q,kStrategy strat)
8861{
8862  strat->interpt = BTEST1(OPT_INTERRUPT);
8863  strat->kHEdge=NULL;
8864  if (currRing->OrdSgn==1) strat->kHEdgeFound=FALSE;
8865  /*- creating temp data structures------------------- -*/
8866  strat->cp = 0;
8867  strat->c3 = 0;
8868  strat->cv = 0;
8869  strat->tail = pInit();
8870  /*- set s -*/
8871  strat->sl = -1;
8872  /*- set L -*/
8873  strat->Lmax = setmaxL;
8874  strat->Ll = -1;
8875  strat->L = initL();
8876  /*- set B -*/
8877  strat->Bmax = setmaxL;
8878  strat->Bl = -1;
8879  strat->B = initL();
8880  /*- set T -*/
8881  strat->tl = -1;
8882  strat->tmax = setmaxT;
8883  strat->T = initT();
8884  strat->R = initR();
8885  strat->sevT = initsevT();
8886  /*- init local data struct.---------------------------------------- -*/
8887  strat->P.ecart=0;
8888  strat->P.length=0;
8889  if (currRing->OrdSgn==-1)
8890  {
8891    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
8892    if (strat->kNoether!=NULL) pSetComp(strat->kNoetherTail(), strat->ak);
8893  }
8894  if(TEST_OPT_SB_1)
8895  {
8896    int i;
8897    ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
8898    for (i=strat->newIdeal;i<IDELEMS(F);i++)
8899    {
8900      P->m[i-strat->newIdeal] = F->m[i];
8901      F->m[i] = NULL;
8902    }
8903    initSSpecial(F,Q,P,strat);
8904    for (i=strat->newIdeal;i<IDELEMS(F);i++)
8905    {
8906      F->m[i] = P->m[i-strat->newIdeal];
8907      P->m[i-strat->newIdeal] = NULL;
8908    }
8909    idDelete(&P);
8910  }
8911  else
8912  {
8913    /*Shdl=*/initSL(F, Q,strat); /*sets also S, ecartS, fromQ */
8914    // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
8915  }
8916  strat->fromT = FALSE;
8917  strat->noTailReduction = !TEST_OPT_REDTAIL;
8918  if (!TEST_OPT_SB_1)
8919  {
8920    /* the only change: we do not fill the set T*/
8921    updateS(FALSE,strat);
8922  }
8923  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
8924  strat->fromQ=NULL;
8925  /* more changes: fill the set T with all the shifts of elts of S*/
8926  /* is done by other procedure */
8927}
8928#endif
8929
8930#ifdef HAVE_SHIFTBBA
8931/*1
8932* put the pairs (sh \dot s[i],p)  into the set B, ecart=ecart(p)
8933*/
8934void enterOnePairManyShifts (int i, poly p, int ecart, int isFromQ, kStrategy strat, int /*atR*/, int uptodeg, int lV)
8935{
8936  /* p comes from strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
8937
8938  assume(p_LmCheckIsFromRing(p,currRing));
8939  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
8940
8941  /* cycles through all shifts of s[i] until uptodeg - lastVblock(s[i]) */
8942  /* that is create the pairs (f, s \dot g)  */
8943
8944  poly qq = strat->S[i]; //  lm in currRing, tail in tailRing
8945
8946  //  poly q = pCopy(pHead(strat->S[i])); // lm in currRing
8947  //  pNext(q) = prCopyR(pNext(strat->S[i]),strat->tailRing,currRing); // zero shift
8948
8949 /* determine how many elements we have to insert for a given s[i] */
8950  /* x(0)y(1)z(2) : lastVblock-1=2, to add until lastVblock=uptodeg-1 */
8951  /* hence, a total number of elt's to add is: */
8952  /*  int toInsert = 1 + (uptodeg-1) - (pLastVblock(p.p, lV) -1);  */
8953  int toInsert =  itoInsert(qq, uptodeg,  lV, strat->tailRing);
8954
8955#ifdef KDEBUG
8956    if (TEST_OPT_DEBUG)
8957    {
8958      //      Print("entered ManyShifts: with toInsert=%d",toInsert); PrintLn();
8959    }
8960#endif
8961
8962  assume(i<=strat->sl); // from OnePair
8963  if (strat->interred_flag) return; // ?
8964
8965  /* these vars hold for all shifts of s[i] */
8966  int ecartq = 0; //Hans says it's ok; we're in the homog case, no ecart
8967
8968  int qfromQ;
8969  if (strat->fromQ != NULL)
8970  {
8971    qfromQ = strat->fromQ[i];
8972  }
8973  else
8974  {
8975    qfromQ = -1;
8976  }
8977
8978  int j;
8979
8980  poly q/*, s*/;
8981
8982  // for the 0th shift: insert the orig. pair
8983  enterOnePairShift(qq, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, 0, i, uptodeg, lV);
8984
8985  for (j=1; j<= toInsert; j++)
8986  {
8987    //    q = pLPshift(strat->S[i],j,uptodeg,lV);
8988    q = p_LPshiftT(qq, j, uptodeg, lV, strat, currRing);
8989    //    q = p_mLPshift(qq,j,uptodeg,lV,currRing); // lm in currRing, shift this monomial
8990    //    s = p_LPshift(pNext(qq), j, uptodeg, lV, strat->tailRing); // from tailRing
8991    //    pNext(q) = s; // in tailRing
8992    /* here we need to call enterOnePair with two polys ... */
8993
8994#ifdef KDEBUG
8995    if (TEST_OPT_DEBUG)
8996    {
8997      //      PrintS("ManyShifts: calling enterOnePairShift(q,p)");      PrintLn();
8998    }
8999#endif
9000    enterOnePairShift(q, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, j, i, uptodeg, lV);
9001  }
9002}
9003#endif
9004
9005#ifdef HAVE_SHIFTBBA
9006/*1
9007* put the pairs (sh \dot qq,p)  into the set B, ecart=ecart(p)
9008* despite the name, not only self shifts
9009*/
9010void enterOnePairSelfShifts (poly qq, poly p, int ecart, int isFromQ, kStrategy strat, int /*atR*/, int uptodeg, int lV)
9011{
9012
9013  /* format: p,qq are in LObject form: lm in CR, tail in TR */
9014  /* for true self pairs qq ==p  */
9015  /* we test both qq and p */
9016  assume(p_LmCheckIsFromRing(qq,currRing));
9017  assume(p_CheckIsFromRing(pNext(qq),strat->tailRing));
9018  assume(p_LmCheckIsFromRing(p,currRing));
9019  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
9020
9021  /* since this proc is applied twice for (h, s*g) and (g,s*h), init j with 1 only */
9022
9023  //  int j = 0;
9024  int j = 1;
9025
9026  /* for such self pairs start with 1, not with 0 */
9027  if (qq == p) j=1;
9028
9029  /* should cycle through all shifts of q until uptodeg - lastVblock(q) */
9030  /* that is create the pairs (f, s \dot g)  */
9031
9032  int toInsert =  itoInsert(qq, uptodeg,  lV, strat->tailRing);
9033
9034#ifdef KDEBUG
9035    if (TEST_OPT_DEBUG)
9036    {
9037      //      Print("entered SelfShifts: with toInsert=%d",toInsert); PrintLn();
9038    }
9039#endif
9040
9041  poly q;
9042
9043  if (strat->interred_flag) return; // ?
9044
9045  /* these vars hold for all shifts of s[i] */
9046  int ecartq = 0; //Hans says it's ok; we're in the homog case, no ecart
9047  int qfromQ = 0; // strat->fromQ[i];
9048
9049  for (; j<= toInsert; j++)
9050  {
9051    //    q = pLPshift(strat->S[i],j,uptodeg,lV);
9052    /* we increase shifts by one; must delete q there*/
9053    //    q = qq; q = pMoveCurrTail2poly(q,strat);
9054    //    q = pLPshift(q,j,uptodeg,lV); //,currRing);
9055    q = p_LPshiftT(qq, j, uptodeg, lV, strat, currRing);
9056    //    q = p_mLPshift(qq,j,uptodeg,lV,currRing); // lm in currRing, shift this monomial
9057    //    s = p_LPshift(pNext(qq), j, uptodeg, lV, strat->tailRing); // from tailRing
9058    //    pNext(q) = s; // in tailRing
9059    /* here we need to call enterOnePair with two polys ... */
9060#ifdef KDEBUG
9061    if (TEST_OPT_DEBUG)
9062    {
9063      //      PrintS("SelfShifts: calling enterOnePairShift(q,p)");      PrintLn();
9064    }
9065#endif
9066    enterOnePairShift(q, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, j, -1, uptodeg, lV);
9067  }
9068}
9069#endif
9070
9071#ifdef HAVE_SHIFTBBA
9072/*2
9073* put the pair (q,p)  into the set B, ecart=ecart(p), q is the shift of some s[i]
9074*/
9075void enterOnePairShift (poly q, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int ecartq, int qisFromQ, int shiftcount, int ifromS, int /*uptodeg*/, int lV)
9076{
9077
9078  /* Format: q and p are like strat->P.p, so lm in CR, tail in TR */
9079
9080  /* check this Formats: */
9081  assume(p_LmCheckIsFromRing(q,currRing));
9082  assume(p_CheckIsFromRing(pNext(q),strat->tailRing));
9083  assume(p_LmCheckIsFromRing(p,currRing));
9084  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
9085
9086#ifdef KDEBUG
9087    if (TEST_OPT_DEBUG)
9088    {
9089//       PrintS("enterOnePairShift(q,p) invoked with q = ");
9090//       wrp(q); //      wrp(pHead(q));
9091//       PrintS(", p = ");
9092//       wrp(p); //wrp(pHead(p));
9093//       PrintLn();
9094    }
9095#endif
9096
9097  /* poly q stays for s[i], ecartq = ecart(q), qisFromQ = applies to q */
9098
9099  int qfromQ = qisFromQ;
9100
9101  /* need additionally: int up_to_degree, poly V0 with the variables in (0)  or just the number lV = the length of the first block */
9102
9103  if (strat->interred_flag) return;
9104
9105  int      l,j,compare;
9106  LObject  Lp;
9107  Lp.i_r = -1;
9108
9109#ifdef KDEBUG
9110  Lp.ecart=0; Lp.length=0;
9111#endif
9112  /*- computes the lcm(s[i],p) -*/
9113  Lp.lcm = pInit();
9114
9115  pLcm(p,q, Lp.lcm); // q is what was strat->S[i], so a poly in LM/TR presentation
9116  pSetm(Lp.lcm);
9117
9118  /* apply the V criterion */
9119  if (!isInV(Lp.lcm, lV))
9120  {
9121#ifdef KDEBUG
9122    if (TEST_OPT_DEBUG)
9123    {
9124      PrintS("V crit applied to q = ");
9125      wrp(q); //      wrp(pHead(q));
9126      PrintS(", p = ");
9127      wrp(p); //wrp(pHead(p));
9128      PrintLn();
9129    }
9130#endif
9131    pLmFree(Lp.lcm);
9132    Lp.lcm=NULL;
9133    /* + counter for applying the V criterion */
9134    strat->cv++;
9135    return;
9136  }
9137
9138  if (strat->sugarCrit && ALLOW_PROD_CRIT(strat))
9139  {
9140    if((!((ecartq>0)&&(ecart>0)))
9141    && pHasNotCF(p,q))
9142    {
9143    /*
9144    *the product criterion has applied for (s,p),
9145    *i.e. lcm(s,p)=product of the leading terms of s and p.
9146    *Suppose (s,r) is in L and the leading term
9147    *of p divides lcm(s,r)
9148    *(==> the leading term of p divides the leading term of r)
9149    *but the leading term of s does not divide the leading term of r
9150    *(notice that this condition is automatically satisfied if r is still
9151    *in S), then (s,r) can be cancelled.
9152    *This should be done here because the
9153    *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
9154    *
9155    *Moreover, skipping (s,r) holds also for the noncommutative case.
9156    */
9157      strat->cp++;
9158      pLmFree(Lp.lcm);
9159      Lp.lcm=NULL;
9160      return;
9161    }
9162    else
9163      Lp.ecart = si_max(ecart,ecartq);
9164    if (strat->fromT && (ecartq>ecart))
9165    {
9166      pLmFree(Lp.lcm);
9167      Lp.lcm=NULL;
9168      return;
9169      /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
9170    }
9171    /*
9172    *the set B collects the pairs of type (S[j],p)
9173    *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
9174    *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
9175    *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
9176    */
9177    {
9178      j = strat->Bl;
9179      loop
9180      {
9181        if (j < 0)  break;
9182        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
9183        if ((compare==1)
9184        &&(sugarDivisibleBy(strat->B[j].ecart,Lp.ecart)))
9185        {
9186          strat->c3++;
9187          if ((strat->fromQ==NULL) || (isFromQ==0) || (qfromQ==0))
9188          {
9189            pLmFree(Lp.lcm);
9190            return;
9191          }
9192          break;
9193        }
9194        else
9195        if ((compare ==-1)
9196        && sugarDivisibleBy(Lp.ecart,strat->B[j].ecart))
9197        {
9198          deleteInL(strat->B,&strat->Bl,j,strat);
9199          strat->c3++;
9200        }
9201        j--;
9202      }
9203    }
9204  }
9205  else /*sugarcrit*/
9206  {
9207    if (ALLOW_PROD_CRIT(strat))
9208    {
9209      // if currRing->nc_type!=quasi (or skew)
9210      // TODO: enable productCrit for super commutative algebras...
9211      if(/*(strat->ak==0) && productCrit(p,strat->S[i])*/
9212      pHasNotCF(p,q))
9213      {
9214      /*
9215      *the product criterion has applied for (s,p),
9216      *i.e. lcm(s,p)=product of the leading terms of s and p.
9217      *Suppose (s,r) is in L and the leading term
9218      *of p devides lcm(s,r)
9219      *(==> the leading term of p devides the leading term of r)
9220      *but the leading term of s does not devide the leading term of r
9221      *(notice that tis condition is automatically satisfied if r is still
9222      *in S), then (s,r) can be canceled.
9223      *This should be done here because the
9224      *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
9225      */
9226          strat->cp++;
9227          pLmFree(Lp.lcm);
9228          Lp.lcm=NULL;
9229          return;
9230      }
9231      if (strat->fromT && (ecartq>ecart))
9232      {
9233        pLmFree(Lp.lcm);
9234        Lp.lcm=NULL;
9235        return;
9236        /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
9237      }
9238      /*
9239      *the set B collects the pairs of type (S[j],p)
9240      *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
9241      *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
9242      *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
9243      */
9244      for(j = strat->Bl;j>=0;j--)
9245      {
9246        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
9247        if (compare==1)
9248        {
9249          strat->c3++;
9250          if ((strat->fromQ==NULL) || (isFromQ==0) || (qfromQ==0))
9251          {
9252            pLmFree(Lp.lcm);
9253            return;
9254          }
9255          break;
9256        }
9257        else
9258        if (compare ==-1)
9259        {
9260          deleteInL(strat->B,&strat->Bl,j,strat);
9261          strat->c3++;
9262        }
9263      }
9264    }
9265  }
9266  /*
9267  *the pair (S[i],p) enters B if the spoly != 0
9268  */
9269  /*-  compute the short s-polynomial -*/
9270  if (strat->fromT && !TEST_OPT_INTSTRATEGY)
9271    pNorm(p);
9272  if ((q==NULL) || (p==NULL))
9273    return;
9274  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (qfromQ!=0))
9275    Lp.p=NULL;
9276  else
9277  {
9278//     if ( rIsPluralRing(currRing) )
9279//     {
9280//       if(pHasNotCF(p, q))
9281//       {
9282//         if(ncRingType(currRing) == nc_lie)
9283//         {
9284//             // generalized prod-crit for lie-type
9285//             strat->cp++;
9286//             Lp.p = nc_p_Bracket_qq(pCopy(p),q, currRing);
9287//         }
9288//         else
9289//         if( ALLOW_PROD_CRIT(strat) )
9290//         {
9291//             // product criterion for homogeneous case in SCA
9292//             strat->cp++;
9293//             Lp.p = NULL;
9294//         }
9295//         else
9296//           Lp.p = nc_CreateSpoly(q,p,currRing); // ?
9297//       }
9298//       else  Lp.p = nc_CreateSpoly(q,p,currRing);
9299//     }
9300//     else
9301//     {
9302
9303    /* ksCreateShortSpoly needs two Lobject-kind presentations */
9304    /* p is already in this form, so convert q */
9305    //    q = pMove2CurrTail(q, strat);
9306    Lp.p = ksCreateShortSpoly(q, p, strat->tailRing);
9307      //  }
9308  }
9309  if (Lp.p == NULL)
9310  {
9311    /*- the case that the s-poly is 0 -*/
9312    /* TEMPORARILY DISABLED FOR SHIFTS because there is no i*/
9313//      if (strat->pairtest==NULL) initPairtest(strat);
9314//      strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
9315//      strat->pairtest[strat->sl+1] = TRUE;
9316    /* END _ TEMPORARILY DISABLED FOR SHIFTS */
9317    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
9318    /*
9319    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
9320    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
9321    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
9322    *term of p devides the lcm(s,r)
9323    *(this canceling should be done here because
9324    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
9325    *the first case is handeled in chainCrit
9326    */
9327    if (Lp.lcm!=NULL) pLmFree(Lp.lcm);
9328  }
9329  else
9330  {
9331    /*- the pair (S[i],p) enters B -*/
9332    /* both of them should have their LM in currRing and TAIL in tailring */
9333    Lp.p1 = q;  // already in the needed form
9334    Lp.p2 = p; // already in the needed form
9335
9336    if ( !rIsPluralRing(currRing) )
9337      pNext(Lp.p) = strat->tail;
9338
9339    /* TEMPORARILY DISABLED FOR SHIFTS because there's no i*/
9340    /* at the beginning we DO NOT set atR = -1 ANYMORE*/
9341    if ( (atR >= 0) && (shiftcount==0) && (ifromS >=0) )
9342    {
9343      Lp.i_r1 = kFindInT(Lp.p1,strat); //strat->S_2_R[ifromS];
9344      Lp.i_r2 = atR;
9345    }
9346    else
9347    {
9348      /* END _ TEMPORARILY DISABLED FOR SHIFTS */
9349      Lp.i_r1 = -1;
9350      Lp.i_r2 = -1;
9351     }
9352    strat->initEcartPair(&Lp,q,p,ecartq,ecart);
9353
9354    if (TEST_OPT_INTSTRATEGY)
9355    {
9356      if (!rIsPluralRing(currRing))
9357        nDelete(&(Lp.p->coef));
9358    }
9359
9360    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
9361    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
9362  }
9363}
9364#endif
9365
9366#ifdef HAVE_SHIFTBBA
9367/*2
9368*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
9369*superfluous elements in S will be deleted
9370*/
9371void enterpairsShift (poly h,int k,int ecart,int pos,kStrategy strat, int atR,int uptodeg, int lV)
9372{
9373  /* h is strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
9374  /* Q: what is exactly the strat->fromT ? A: a local case trick; don't need it yet*/
9375  int j=pos;
9376
9377#ifdef HAVE_RINGS
9378  assume (!rField_is_Ring(currRing));
9379#endif
9380  initenterpairsShift(h,k,ecart,0,strat, atR,uptodeg,lV);
9381  if ( (!strat->fromT)
9382  && ((strat->syzComp==0)
9383    ||(pGetComp(h)<=strat->syzComp)))
9384  {
9385    //Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
9386    unsigned long h_sev = pGetShortExpVector(h);
9387    loop
9388    {
9389      if (j > k) break;
9390      clearS(h,h_sev, &j,&k,strat);
9391      j++;
9392    }
9393    //Print("end clearS sl=%d\n",strat->sl);
9394  }
9395 // PrintS("end enterpairs\n");
9396}
9397#endif
9398
9399#ifdef HAVE_SHIFTBBA
9400/*3
9401*(s[0], s \dot h),...,(s[k],s \dot h) will be put to the pairset L
9402* also the pairs (h, s\dot s[0]), ..., (h, s\dot s[k]) enter L
9403* additionally we put the pairs (h, s \sdot h) for s>=1 to L
9404*/
9405void initenterpairsShift (poly h,int k,int ecart,int isFromQ, kStrategy strat, int atR, int uptodeg, int lV)
9406{
9407  /* h comes from strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
9408  //  atR = -1;
9409  if ((strat->syzComp==0)
9410  || (pGetComp(h)<=strat->syzComp))
9411  {
9412    int j;
9413    BOOLEAN new_pair=FALSE;
9414
9415    if (pGetComp(h)==0)
9416    {
9417      /* for Q!=NULL: build pairs (f,q),(f1,f2), but not (q1,q2)*/
9418      if ((isFromQ)&&(strat->fromQ!=NULL))
9419      {
9420        for (j=0; j<=k; j++)
9421        {
9422          if (!strat->fromQ[j])
9423          {
9424            new_pair=TRUE;
9425            enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR,uptodeg,lV);
9426            // other side pairs:
9427            enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
9428          //Print("j:%d, Ll:%d\n",j,strat->Ll);
9429          }
9430        }
9431      }
9432      else
9433      {
9434        new_pair=TRUE;
9435        for (j=0; j<=k; j++)
9436        {
9437          enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR,uptodeg,lV);
9438          // other side pairs
9439          enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
9440        }
9441        /* HERE we put (h, s*h) pairs */
9442       /* enterOnePairSelfShifts (poly qq, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int uptodeg, int lV); */
9443       enterOnePairSelfShifts (h, h, ecart, isFromQ, strat, atR, uptodeg, lV);
9444      }
9445    }
9446    else
9447    {
9448      for (j=0; j<=k; j++)
9449      {
9450        if ((pGetComp(h)==pGetComp(strat->S[j]))
9451        || (pGetComp(strat->S[j])==0))
9452        {
9453          new_pair=TRUE;
9454          enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR, uptodeg, lV);
9455          // other side pairs
9456          enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
9457        //Print("j:%d, Ll:%d\n",j,strat->Ll);
9458        }
9459      }
9460      /* HERE we put (h, s*h) pairs */
9461      enterOnePairSelfShifts (h, h, ecart, isFromQ, strat, atR, uptodeg, lV);
9462    }
9463
9464    if (new_pair)
9465    {
9466      strat->chainCrit(h,ecart,strat);
9467    }
9468
9469  }
9470}
9471#endif
9472
9473#ifdef HAVE_SHIFTBBA
9474/*2
9475* puts p to the set T, starting with the at position atT
9476* and inserts all admissible shifts of p
9477*/
9478void enterTShift(LObject p, kStrategy strat, int atT, int uptodeg, int lV)
9479{
9480  /* determine how many elements we have to insert */
9481  /* x(0)y(1)z(2) : lastVblock-1=2, to add until lastVblock=uptodeg-1 */
9482  /* hence, a total number of elt's to add is: */
9483  /*  int toInsert = 1 + (uptodeg-1) - (pLastVblock(p.p, lV) -1);  */
9484
9485  int toInsert =  itoInsert(p.p, uptodeg,  lV, strat->tailRing);
9486
9487#ifdef PDEBUG
9488  //  Print("enterTShift uses toInsert: %d", toInsert);  PrintLn();
9489#endif
9490  int i;
9491
9492  if (atT < 0)
9493    atT = strat->posInT(strat->T, strat->tl, p);
9494
9495  /* can call enterT in a sequence, e.g. */
9496
9497  /* shift0 = it's our model for further shifts */
9498  enterT(p,strat,atT);
9499  LObject qq;
9500  for (i=1; i<=toInsert; i++) // toIns - 1?
9501  {
9502    qq      = p; //qq.Copy();
9503    qq.p    = NULL;
9504    qq.max  = NULL;
9505    qq.t_p = p_LPshift(p_Copy(p.t_p,strat->tailRing), i, uptodeg, lV, strat->tailRing); // direct shift
9506    qq.GetP();
9507    // update q.sev
9508    qq.sev = pGetShortExpVector(qq.p);
9509    /* enter it into T, first el't is with the shift 0 */
9510    // compute the position for qq
9511    atT = strat->posInT(strat->T, strat->tl, qq);
9512    enterT(qq,strat,atT);
9513  }
9514/* Q: what to do with this one in the orig enterT ? */
9515/*  strat->R[strat->tl] = &(strat->T[atT]); */
9516/* Solution: it is done by enterT each time separately */
9517}
9518#endif
9519
9520#ifdef HAVE_SHIFTBBA
9521poly redtailBbaShift (LObject* L, int pos, kStrategy strat, BOOLEAN withT, BOOLEAN normalize)
9522{
9523  /* for the shift case need to run it with withT = TRUE */
9524  strat->redTailChange=FALSE;
9525  if (strat->noTailReduction) return L->GetLmCurrRing();
9526  poly h, p;
9527  p = h = L->GetLmTailRing();
9528  if ((h==NULL) || (pNext(h)==NULL))
9529    return L->GetLmCurrRing();
9530
9531  TObject* With;
9532  // placeholder in case strat->tl < 0
9533  TObject  With_s(strat->tailRing);
9534
9535  LObject Ln(pNext(h), strat->tailRing);
9536  Ln.pLength = L->GetpLength() - 1;
9537
9538  pNext(h) = NULL;
9539  if (L->p != NULL) pNext(L->p) = NULL;
9540  L->pLength = 1;
9541
9542  Ln.PrepareRed(strat->use_buckets);
9543
9544  while(!Ln.IsNull())
9545  {
9546    loop
9547    {
9548      Ln.SetShortExpVector();
9549      if (withT)
9550      {
9551        int j;
9552        j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln);
9553        if (j < 0) break;
9554        With = &(strat->T[j]);
9555      }
9556      else
9557      {
9558        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
9559        if (With == NULL) break;
9560      }
9561      if (normalize && (!TEST_OPT_INTSTRATEGY) && (!nIsOne(pGetCoeff(With->p))))
9562      {
9563        With->pNorm();
9564        //if (TEST_OPT_PROT) { PrintS("n"); mflush(); }
9565      }
9566      strat->redTailChange=TRUE;
9567      if (ksReducePolyTail(L, With, &Ln))
9568      {
9569        // reducing the tail would violate the exp bound
9570        //  set a flag and hope for a retry (in bba)
9571        strat->completeReduce_retry=TRUE;
9572        if ((Ln.p != NULL) && (Ln.t_p != NULL)) Ln.p=NULL;
9573        do
9574        {
9575          pNext(h) = Ln.LmExtractAndIter();
9576          pIter(h);
9577          L->pLength++;
9578        } while (!Ln.IsNull());
9579        goto all_done;
9580      }
9581      if (Ln.IsNull()) goto all_done;
9582      if (! withT) With_s.Init(currRing);
9583    }
9584    pNext(h) = Ln.LmExtractAndIter();
9585    pIter(h);
9586    L->pLength++;
9587  }
9588
9589  all_done:
9590  Ln.Delete();
9591  if (L->p != NULL) pNext(L->p) = pNext(p);
9592
9593  if (strat->redTailChange)
9594  {
9595    L->length = 0;
9596  }
9597  L->Normalize(); // HANNES: should have a test
9598  assume(kTest_L(L));
9599  return L->GetLmCurrRing();
9600}
9601#endif
Note: See TracBrowser for help on using the repository browser.