source: git/kernel/kutil.cc @ a7b37d

spielwiese
Last change on this file since a7b37d was a7b37d, checked in by Christian Eder, 10 years ago
1. some more memory leaks fixed 2. preparation for buchber product criterion check
  • Property mode set to 100644
File size: 250.5 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    // deletes the short spoly
5192#ifdef HAVE_RINGS
5193    if (rField_is_Ring(currRing))
5194      pLmDelete(strat->L[strat->Ll].p);
5195    else
5196#endif
5197      pLmFree(strat->L[strat->Ll].p);
5198
5199    // TODO: needs some masking
5200    // TODO: masking needs to vanish once the signature
5201    //       sutff is completely implemented
5202    strat->L[strat->Ll].p = NULL;
5203    poly m1 = NULL, m2 = NULL;
5204
5205    // check that spoly creation is ok
5206    while (strat->tailRing != currRing &&
5207          !kCheckSpolyCreation(&(strat->L[strat->Ll]), strat, m1, m2))
5208    {
5209      assume(m1 == NULL && m2 == NULL);
5210      // if not, change to a ring where exponents are at least
5211      // large enough
5212      if (!kStratChangeTailRing(strat))
5213      {
5214        WerrorS("OVERFLOW...");
5215        break;
5216      }
5217    }
5218    // create the real one
5219    ksCreateSpoly(&(strat->L[strat->Ll]), NULL, strat->use_buckets,
5220                  strat->tailRing, m1, m2, strat->R);
5221    if (strat->P.GetLmCurrRing() == NULL)
5222    {
5223      deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
5224    }
5225    if (strat->L[strat->Ll].GetLmCurrRing() == NULL)
5226    {
5227      pDelete(&strat->P.sig);
5228      strat->P.Delete();
5229      strat->P = strat->L[strat->Ll];
5230      strat->Ll--;
5231    }
5232
5233    if ((strat->P.GetLmCurrRing() != NULL)
5234    && (strat->L[strat->Ll].GetLmCurrRing() != NULL))
5235    {
5236      if (pLmCmp(strat->P.GetLmCurrRing(),strat->L[strat->Ll].GetLmCurrRing()) == -1)
5237      {
5238        deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
5239      }
5240      else
5241      {
5242        pDelete(&strat->P.sig);
5243        strat->P.Delete();
5244        strat->P = strat->L[strat->Ll];
5245        strat->Ll--;
5246      }
5247    }
5248  }
5249  for (int ii=strat->sl; ii>-1; ii--)
5250  {
5251    if (p_LmShortDivisibleBy(strat->sig[ii], strat->sevSig[ii], strat->P.sig, ~strat->P.sevSig, currRing))
5252    {
5253      if (!(pLmCmp(ppMult_mm(strat->P.sig,pHead(strat->S[ii])),ppMult_mm(strat->sig[ii],strat->P.GetLmCurrRing())) == 1))
5254      {
5255        strat->P.Delete();
5256        return TRUE;
5257      }
5258    }
5259  }
5260  return FALSE;
5261}
5262
5263/***************************************************************
5264 *
5265 * Tail reductions
5266 *
5267 ***************************************************************/
5268TObject*
5269kFindDivisibleByInS(kStrategy strat, int pos, LObject* L, TObject *T,
5270                    long ecart)
5271{
5272  int j = 0;
5273  const unsigned long not_sev = ~L->sev;
5274  const unsigned long* sev = strat->sevS;
5275  poly p;
5276  ring r;
5277  L->GetLm(p, r);
5278
5279  assume(~not_sev == p_GetShortExpVector(p, r));
5280
5281  if (r == currRing)
5282  {
5283    loop
5284    {
5285      if (j > pos) return NULL;
5286#if defined(PDEBUG) || defined(PDIV_DEBUG)
5287      if (p_LmShortDivisibleBy(strat->S[j], sev[j], p, not_sev, r) &&
5288          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
5289        break;
5290#else
5291      if (!(sev[j] & not_sev) &&
5292          (ecart== LONG_MAX || ecart>= strat->ecartS[j]) &&
5293          p_LmDivisibleBy(strat->S[j], p, r))
5294        break;
5295
5296#endif
5297      j++;
5298    }
5299    // if called from NF, T objects do not exist:
5300    if (strat->tl < 0 || strat->S_2_R[j] == -1)
5301    {
5302      T->Set(strat->S[j], r, strat->tailRing);
5303      return T;
5304    }
5305    else
5306    {
5307/////      assume (j >= 0 && j <= strat->tl && strat->S_2_T(j) != NULL
5308/////      && strat->S_2_T(j)->p == strat->S[j]); // wrong?
5309//      assume (j >= 0 && j <= strat->sl && strat->S_2_T(j) != NULL && strat->S_2_T(j)->p == strat->S[j]);
5310      return strat->S_2_T(j);
5311    }
5312  }
5313  else
5314  {
5315    TObject* t;
5316    loop
5317    {
5318      if (j > pos) return NULL;
5319      assume(strat->S_2_R[j] != -1);
5320#if defined(PDEBUG) || defined(PDIV_DEBUG)
5321      t = strat->S_2_T(j);
5322      assume(t != NULL && t->t_p != NULL && t->tailRing == r);
5323      if (p_LmShortDivisibleBy(t->t_p, sev[j], p, not_sev, r) &&
5324          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
5325        return t;
5326#else
5327      if (! (sev[j] & not_sev) && (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
5328      {
5329        t = strat->S_2_T(j);
5330        assume(t != NULL && t->t_p != NULL && t->tailRing == r && t->p == strat->S[j]);
5331        if (p_LmDivisibleBy(t->t_p, p, r)) return t;
5332      }
5333#endif
5334      j++;
5335    }
5336  }
5337}
5338
5339poly redtail (LObject* L, int pos, kStrategy strat)
5340{
5341  poly h, hn;
5342  strat->redTailChange=FALSE;
5343
5344  poly p = L->p;
5345  if (strat->noTailReduction || pNext(p) == NULL)
5346    return p;
5347
5348  LObject Ln(strat->tailRing);
5349  TObject* With;
5350  // placeholder in case strat->tl < 0
5351  TObject  With_s(strat->tailRing);
5352  h = p;
5353  hn = pNext(h);
5354  long op = strat->tailRing->pFDeg(hn, strat->tailRing);
5355  long e;
5356  int l;
5357  BOOLEAN save_HE=strat->kHEdgeFound;
5358  strat->kHEdgeFound |=
5359    ((Kstd1_deg>0) && (op<=Kstd1_deg)) || TEST_OPT_INFREDTAIL;
5360
5361  while(hn != NULL)
5362  {
5363    op = strat->tailRing->pFDeg(hn, strat->tailRing);
5364    if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
5365    e = strat->tailRing->pLDeg(hn, &l, strat->tailRing) - op;
5366    loop
5367    {
5368      Ln.Set(hn, strat->tailRing);
5369      Ln.sev = p_GetShortExpVector(hn, strat->tailRing);
5370      if (strat->kHEdgeFound)
5371        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
5372      else
5373        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s, e);
5374      if (With == NULL) break;
5375      With->length=0;
5376      With->pLength=0;
5377      strat->redTailChange=TRUE;
5378      if (ksReducePolyTail(L, With, h, strat->kNoetherTail()))
5379      {
5380        // reducing the tail would violate the exp bound
5381        if (kStratChangeTailRing(strat, L))
5382        {
5383          strat->kHEdgeFound = save_HE;
5384          return redtail(L, pos, strat);
5385        }
5386        else
5387          return NULL;
5388      }
5389      hn = pNext(h);
5390      if (hn == NULL) goto all_done;
5391      op = strat->tailRing->pFDeg(hn, strat->tailRing);
5392      if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
5393      e = strat->tailRing->pLDeg(hn, &l, strat->tailRing) - op;
5394    }
5395    h = hn;
5396    hn = pNext(h);
5397  }
5398
5399  all_done:
5400  if (strat->redTailChange)
5401  {
5402    L->pLength = 0;
5403  }
5404  strat->kHEdgeFound = save_HE;
5405  return p;
5406}
5407
5408poly redtail (poly p, int pos, kStrategy strat)
5409{
5410  LObject L(p, currRing);
5411  return redtail(&L, pos, strat);
5412}
5413
5414poly redtailBba (LObject* L, int pos, kStrategy strat, BOOLEAN withT, BOOLEAN normalize)
5415{
5416#define REDTAIL_CANONICALIZE 100
5417  strat->redTailChange=FALSE;
5418  if (strat->noTailReduction) return L->GetLmCurrRing();
5419  poly h, p;
5420  p = h = L->GetLmTailRing();
5421  if ((h==NULL) || (pNext(h)==NULL))
5422    return L->GetLmCurrRing();
5423
5424  TObject* With;
5425  // placeholder in case strat->tl < 0
5426  TObject  With_s(strat->tailRing);
5427
5428  LObject Ln(pNext(h), strat->tailRing);
5429  Ln.pLength = L->GetpLength() - 1;
5430
5431  pNext(h) = NULL;
5432  if (L->p != NULL) pNext(L->p) = NULL;
5433  L->pLength = 1;
5434
5435  Ln.PrepareRed(strat->use_buckets);
5436
5437  int cnt=REDTAIL_CANONICALIZE;
5438  while(!Ln.IsNull())
5439  {
5440    loop
5441    {
5442      Ln.SetShortExpVector();
5443      if (withT)
5444      {
5445        int j;
5446        j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln);
5447        if (j < 0) break;
5448        With = &(strat->T[j]);
5449      }
5450      else
5451      {
5452        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
5453        if (With == NULL) break;
5454      }
5455      cnt--;
5456      if (cnt==0)
5457      {
5458        cnt=REDTAIL_CANONICALIZE;
5459        /*poly tmp=*/Ln.CanonicalizeP();
5460        if (normalize)
5461        {
5462          Ln.Normalize();
5463          //pNormalize(tmp);
5464          //if (TEST_OPT_PROT) { PrintS("n"); mflush(); }
5465        }
5466      }
5467      if (normalize && (!TEST_OPT_INTSTRATEGY) && (!nIsOne(pGetCoeff(With->p))))
5468      {
5469        With->pNorm();
5470      }
5471      strat->redTailChange=TRUE;
5472      if (ksReducePolyTail(L, With, &Ln))
5473      {
5474        // reducing the tail would violate the exp bound
5475        //  set a flag and hope for a retry (in bba)
5476        strat->completeReduce_retry=TRUE;
5477        if ((Ln.p != NULL) && (Ln.t_p != NULL)) Ln.p=NULL;
5478        do
5479        {
5480          pNext(h) = Ln.LmExtractAndIter();
5481          pIter(h);
5482          L->pLength++;
5483        } while (!Ln.IsNull());
5484        goto all_done;
5485      }
5486      if (Ln.IsNull()) goto all_done;
5487      if (! withT) With_s.Init(currRing);
5488    }
5489    pNext(h) = Ln.LmExtractAndIter();
5490    pIter(h);
5491    pNormalize(h);
5492    L->pLength++;
5493  }
5494
5495  all_done:
5496  Ln.Delete();
5497  if (L->p != NULL) pNext(L->p) = pNext(p);
5498
5499  if (strat->redTailChange)
5500  {
5501    L->length = 0;
5502  }
5503
5504  //if (TEST_OPT_PROT) { PrintS("N"); mflush(); }
5505  //L->Normalize(); // HANNES: should have a test
5506  assume(kTest_L(L));
5507  return L->GetLmCurrRing();
5508}
5509
5510#ifdef HAVE_RINGS
5511poly redtailBba_Z (LObject* L, int pos, kStrategy strat )
5512// normalize=FALSE, withT=FALSE, coeff=Z
5513{
5514  strat->redTailChange=FALSE;
5515  if (strat->noTailReduction) return L->GetLmCurrRing();
5516  poly h, p;
5517  p = h = L->GetLmTailRing();
5518  if ((h==NULL) || (pNext(h)==NULL))
5519    return L->GetLmCurrRing();
5520
5521  TObject* With;
5522  // placeholder in case strat->tl < 0
5523  TObject  With_s(strat->tailRing);
5524
5525  LObject Ln(pNext(h), strat->tailRing);
5526  Ln.pLength = L->GetpLength() - 1;
5527
5528  pNext(h) = NULL;
5529  if (L->p != NULL) pNext(L->p) = NULL;
5530  L->pLength = 1;
5531
5532  Ln.PrepareRed(strat->use_buckets);
5533
5534  int cnt=REDTAIL_CANONICALIZE;
5535  while(!Ln.IsNull())
5536  {
5537    loop
5538    {
5539      Ln.SetShortExpVector();
5540      With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
5541      if (With == NULL) break;
5542      cnt--;
5543      if (cnt==0)
5544      {
5545        cnt=REDTAIL_CANONICALIZE;
5546        /*poly tmp=*/Ln.CanonicalizeP();
5547      }
5548      // we are in Z, do not call pNorm
5549      strat->redTailChange=TRUE;
5550      // test divisibility of coefs:
5551      poly p_Ln=Ln.GetLmCurrRing();
5552      poly p_With=With->GetLmCurrRing();
5553      number z=n_IntMod(pGetCoeff(p_Ln),pGetCoeff(p_With), currRing->cf);
5554      if (!nIsZero(z))
5555      {
5556        // subtract z*Ln, add z.Ln to L
5557        poly m=pHead(p_Ln);
5558        pSetCoeff(m,z);
5559        poly mm=pHead(m);
5560        pNext(h) = m;
5561        pIter(h);
5562        L->pLength++;
5563        mm=pNeg(mm);
5564        if (Ln.bucket!=NULL)
5565        {
5566          int dummy=1;
5567          kBucket_Add_q(Ln.bucket,mm,&dummy);
5568        }
5569        else
5570        {
5571          if (Ln.p!=NULL) Ln.p=pAdd(Ln.p,mm);
5572          else if (Ln.t_p!=NULL)  Ln.t_p=p_Add_q(Ln.t_p,mm,strat->tailRing);
5573        }
5574      }
5575      else
5576        nDelete(&z);
5577
5578      if (ksReducePolyTail(L, With, &Ln))
5579      {
5580        // reducing the tail would violate the exp bound
5581        //  set a flag and hope for a retry (in bba)
5582        strat->completeReduce_retry=TRUE;
5583        if ((Ln.p != NULL) && (Ln.t_p != NULL)) Ln.p=NULL;
5584        do
5585        {
5586          pNext(h) = Ln.LmExtractAndIter();
5587          pIter(h);
5588          L->pLength++;
5589        } while (!Ln.IsNull());
5590        goto all_done;
5591      }
5592      if (Ln.IsNull()) goto all_done;
5593      With_s.Init(currRing);
5594    }
5595    pNext(h) = Ln.LmExtractAndIter();
5596    pIter(h);
5597    pNormalize(h);
5598    L->pLength++;
5599  }
5600
5601  all_done:
5602  Ln.Delete();
5603  if (L->p != NULL) pNext(L->p) = pNext(p);
5604
5605  if (strat->redTailChange)
5606  {
5607    L->length = 0;
5608  }
5609
5610  //if (TEST_OPT_PROT) { PrintS("N"); mflush(); }
5611  //L->Normalize(); // HANNES: should have a test
5612  assume(kTest_L(L));
5613  return L->GetLmCurrRing();
5614}
5615#endif
5616
5617/*2
5618*checks the change degree and write progress report
5619*/
5620void message (int i,int* reduc,int* olddeg,kStrategy strat, int red_result)
5621{
5622  if (i != *olddeg)
5623  {
5624    Print("%d",i);
5625    *olddeg = i;
5626  }
5627  if (TEST_OPT_OLDSTD)
5628  {
5629    if (strat->Ll != *reduc)
5630    {
5631      if (strat->Ll != *reduc-1)
5632        Print("(%d)",strat->Ll+1);
5633      else
5634        PrintS("-");
5635      *reduc = strat->Ll;
5636    }
5637    else
5638      PrintS(".");
5639    mflush();
5640  }
5641  else
5642  {
5643    if (red_result == 0)
5644      PrintS("-");
5645    else if (red_result < 0)
5646      PrintS(".");
5647    if ((red_result > 0) || ((strat->Ll % 100)==99))
5648    {
5649      if (strat->Ll != *reduc && strat->Ll > 0)
5650      {
5651        Print("(%d)",strat->Ll+1);
5652        *reduc = strat->Ll;
5653      }
5654    }
5655  }
5656}
5657
5658/*2
5659*statistics
5660*/
5661void messageStat (int hilbcount,kStrategy strat)
5662{
5663  //PrintS("\nUsage/Allocation of temporary storage:\n");
5664  //Print("%d/%d polynomials in standard base\n",srmax,IDELEMS(Shdl));
5665  //Print("%d/%d polynomials in set L (for lazy alg.)",lrmax+1,strat->Lmax);
5666  Print("product criterion:%d chain criterion:%d\n",strat->cp,strat->c3);
5667  if (hilbcount!=0) Print("hilbert series criterion:%d\n",hilbcount);
5668  /* in usual case strat->cv is 0, it gets changed only in shift routines */
5669  if (strat->cv!=0) Print("shift V criterion:%d\n",strat->cv);
5670  /*mflush();*/
5671}
5672
5673#ifdef KDEBUG
5674/*2
5675*debugging output: all internal sets, if changed
5676*for testing purpuse only/has to be changed for later use
5677*/
5678void messageSets (kStrategy strat)
5679{
5680  int i;
5681  if (strat->news)
5682  {
5683    PrintS("set S");
5684    for (i=0; i<=strat->sl; i++)
5685    {
5686      Print("\n  %d:",i);
5687      p_wrp(strat->S[i], currRing, strat->tailRing);
5688    }
5689    strat->news = FALSE;
5690  }
5691  if (strat->newt)
5692  {
5693    PrintS("\nset T");
5694    for (i=0; i<=strat->tl; i++)
5695    {
5696      Print("\n  %d:",i);
5697      strat->T[i].wrp();
5698      Print(" o:%ld e:%d l:%d",
5699        strat->T[i].pFDeg(),strat->T[i].ecart,strat->T[i].length);
5700    }
5701    strat->newt = FALSE;
5702  }
5703  PrintS("\nset L");
5704  for (i=strat->Ll; i>=0; i--)
5705  {
5706    Print("\n%d:",i);
5707    p_wrp(strat->L[i].p1, currRing, strat->tailRing);
5708    PrintS("  ");
5709    p_wrp(strat->L[i].p2, currRing, strat->tailRing);
5710    PrintS(" lcm: ");p_wrp(strat->L[i].lcm, currRing);
5711    PrintS("\n  p : ");
5712    strat->L[i].wrp();
5713    Print("  o:%ld e:%d l:%d",
5714          strat->L[i].pFDeg(),strat->L[i].ecart,strat->L[i].length);
5715  }
5716  PrintLn();
5717}
5718
5719#endif
5720
5721
5722/*2
5723*construct the set s from F
5724*/
5725void initS (ideal F, ideal Q, kStrategy strat)
5726{
5727  int   i,pos;
5728
5729  if (Q!=NULL) i=((IDELEMS(F)+IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
5730  else         i=((IDELEMS(F)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
5731  strat->ecartS=initec(i);
5732  strat->sevS=initsevS(i);
5733  strat->S_2_R=initS_2_R(i);
5734  strat->fromQ=NULL;
5735  strat->Shdl=idInit(i,F->rank);
5736  strat->S=strat->Shdl->m;
5737  /*- put polys into S -*/
5738  if (Q!=NULL)
5739  {
5740    strat->fromQ=initec(i);
5741    memset(strat->fromQ,0,i*sizeof(int));
5742    for (i=0; i<IDELEMS(Q); i++)
5743    {
5744      if (Q->m[i]!=NULL)
5745      {
5746        LObject h;
5747        h.p = pCopy(Q->m[i]);
5748        if (TEST_OPT_INTSTRATEGY)
5749        {
5750          //pContent(h.p);
5751          h.pCleardenom(); // also does a pContent
5752        }
5753        else
5754        {
5755          h.pNorm();
5756        }
5757        if (currRing->OrdSgn==-1)
5758        {
5759          deleteHC(&h, strat);
5760        }
5761        if (h.p!=NULL)
5762        {
5763          strat->initEcart(&h);
5764          if (strat->sl==-1)
5765            pos =0;
5766          else
5767          {
5768            pos = posInS(strat,strat->sl,h.p,h.ecart);
5769          }
5770          h.sev = pGetShortExpVector(h.p);
5771          strat->enterS(h,pos,strat,-1);
5772          strat->fromQ[pos]=1;
5773        }
5774      }
5775    }
5776  }
5777  for (i=0; i<IDELEMS(F); i++)
5778  {
5779    if (F->m[i]!=NULL)
5780    {
5781      LObject h;
5782      h.p = pCopy(F->m[i]);
5783      if (currRing->OrdSgn==-1)
5784      {
5785                    /*#ifdef HAVE_RINGS
5786                          if (rField_is_Ring(currRing))
5787                            {
5788                            h.pCleardenom();
5789                            }
5790                          else
5791                                #endif*/
5792        cancelunit(&h);  /*- tries to cancel a unit -*/
5793        deleteHC(&h, strat);
5794      }
5795      if (h.p!=NULL)
5796      // do not rely on the input being a SB!
5797      {
5798        if (TEST_OPT_INTSTRATEGY)
5799        {
5800          //pContent(h.p);
5801          h.pCleardenom(); // also does a pContent
5802        }
5803        else
5804        {
5805          h.pNorm();
5806        }
5807        strat->initEcart(&h);
5808        if (strat->sl==-1)
5809          pos =0;
5810        else
5811          pos = posInS(strat,strat->sl,h.p,h.ecart);
5812        h.sev = pGetShortExpVector(h.p);
5813        strat->enterS(h,pos,strat,-1);
5814      }
5815    }
5816  }
5817  /*- test, if a unit is in F -*/
5818  if ((strat->sl>=0)
5819#ifdef HAVE_RINGS
5820       && n_IsUnit(pGetCoeff(strat->S[0]),currRing->cf)
5821#endif
5822       && pIsConstant(strat->S[0]))
5823  {
5824    while (strat->sl>0) deleteInS(strat->sl,strat);
5825  }
5826}
5827
5828void initSL (ideal F, ideal Q,kStrategy strat)
5829{
5830  int   i,pos;
5831
5832  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
5833  else i=setmaxT;
5834  strat->ecartS=initec(i);
5835  strat->sevS=initsevS(i);
5836  strat->S_2_R=initS_2_R(i);
5837  strat->fromQ=NULL;
5838  strat->Shdl=idInit(i,F->rank);
5839  strat->S=strat->Shdl->m;
5840  /*- put polys into S -*/
5841  if (Q!=NULL)
5842  {
5843    strat->fromQ=initec(i);
5844    memset(strat->fromQ,0,i*sizeof(int));
5845    for (i=0; i<IDELEMS(Q); i++)
5846    {
5847      if (Q->m[i]!=NULL)
5848      {
5849        LObject h;
5850        h.p = pCopy(Q->m[i]);
5851        if (currRing->OrdSgn==-1)
5852        {
5853          deleteHC(&h,strat);
5854        }
5855        if (TEST_OPT_INTSTRATEGY)
5856        {
5857          //pContent(h.p);
5858          h.pCleardenom(); // also does a pContent
5859        }
5860        else
5861        {
5862          h.pNorm();
5863        }
5864        if (h.p!=NULL)
5865        {
5866          strat->initEcart(&h);
5867          if (strat->sl==-1)
5868            pos =0;
5869          else
5870          {
5871            pos = posInS(strat,strat->sl,h.p,h.ecart);
5872          }
5873          h.sev = pGetShortExpVector(h.p);
5874          strat->enterS(h,pos,strat,-1);
5875          strat->fromQ[pos]=1;
5876        }
5877      }
5878    }
5879  }
5880  for (i=0; i<IDELEMS(F); i++)
5881  {
5882    if (F->m[i]!=NULL)
5883    {
5884      LObject h;
5885      h.p = pCopy(F->m[i]);
5886      if (h.p!=NULL)
5887      {
5888        if (currRing->OrdSgn==-1)
5889        {
5890          cancelunit(&h);  /*- tries to cancel a unit -*/
5891          deleteHC(&h, strat);
5892        }
5893        if (h.p!=NULL)
5894        {
5895          if (TEST_OPT_INTSTRATEGY)
5896          {
5897            //pContent(h.p);
5898            h.pCleardenom(); // also does a pContent
5899          }
5900          else
5901          {
5902            h.pNorm();
5903          }
5904          strat->initEcart(&h);
5905          if (strat->Ll==-1)
5906            pos =0;
5907          else
5908            pos = strat->posInL(strat->L,strat->Ll,&h,strat);
5909          h.sev = pGetShortExpVector(h.p);
5910          enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
5911        }
5912      }
5913    }
5914  }
5915  /*- test, if a unit is in F -*/
5916
5917  if ((strat->Ll>=0)
5918#ifdef HAVE_RINGS
5919       && n_IsUnit(pGetCoeff(strat->L[strat->Ll].p), currRing->cf)
5920#endif
5921       && pIsConstant(strat->L[strat->Ll].p))
5922  {
5923    while (strat->Ll>0) deleteInL(strat->L,&strat->Ll,strat->Ll-1,strat);
5924  }
5925}
5926
5927void initSLSba (ideal F, ideal Q,kStrategy strat)
5928{
5929  int   i,pos;
5930  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
5931  else i=setmaxT;
5932  strat->ecartS =   initec(i);
5933  strat->fromS  =   initec(i);
5934  strat->sevS   =   initsevS(i);
5935  strat->sevSig =   initsevS(i);
5936  strat->S_2_R  =   initS_2_R(i);
5937  strat->fromQ  =   NULL;
5938  strat->Shdl   =   idInit(i,F->rank);
5939  strat->S      =   strat->Shdl->m;
5940  strat->sig    =   (poly *)omAlloc0(i*sizeof(poly));
5941  if (strat->sbaOrder != 1)
5942  {
5943    strat->syz    = (poly *)omAlloc0(i*sizeof(poly));
5944    strat->sevSyz = initsevS(i);
5945    strat->syzmax = i;
5946    strat->syzl   = 0;
5947  }
5948  /*- put polys into S -*/
5949  if (Q!=NULL)
5950  {
5951    strat->fromQ=initec(i);
5952    memset(strat->fromQ,0,i*sizeof(int));
5953    for (i=0; i<IDELEMS(Q); i++)
5954    {
5955      if (Q->m[i]!=NULL)
5956      {
5957        LObject h;
5958        h.p = pCopy(Q->m[i]);
5959        if (currRing->OrdSgn==-1)
5960        {
5961          deleteHC(&h,strat);
5962        }
5963        if (TEST_OPT_INTSTRATEGY)
5964        {
5965          //pContent(h.p);
5966          h.pCleardenom(); // also does a pContent
5967        }
5968        else
5969        {
5970          h.pNorm();
5971        }
5972        if (h.p!=NULL)
5973        {
5974          strat->initEcart(&h);
5975          if (strat->sl==-1)
5976            pos =0;
5977          else
5978          {
5979            pos = posInS(strat,strat->sl,h.p,h.ecart);
5980          }
5981          h.sev = pGetShortExpVector(h.p);
5982          strat->enterS(h,pos,strat,-1);
5983          strat->fromQ[pos]=1;
5984        }
5985      }
5986    }
5987  }
5988  for (i=0; i<IDELEMS(F); i++)
5989  {
5990    if (F->m[i]!=NULL)
5991    {
5992      LObject h;
5993      h.p = pCopy(F->m[i]);
5994      h.sig = pOne();
5995      //h.sig = pInit();
5996      //p_SetCoeff(h.sig,nInit(1),currRing);
5997      p_SetComp(h.sig,i+1,currRing);
5998      // if we are working with the Schreyer order we generate it
5999      // by multiplying the initial signatures with the leading monomial
6000      // of the corresponding initial polynomials generating the ideal
6001      // => we can keep the underlying monomial order and get a Schreyer
6002      //    order without any bigger overhead
6003      if (strat->sbaOrder == 0)
6004      {
6005        p_ExpVectorAdd (h.sig,F->m[i],currRing);
6006      }
6007      h.sevSig = pGetShortExpVector(h.sig);
6008#ifdef DEBUGF5
6009      pWrite(h.p);
6010      pWrite(h.sig);
6011#endif
6012      if (h.p!=NULL)
6013      {
6014        if (currRing->OrdSgn==-1)
6015        {
6016          cancelunit(&h);  /*- tries to cancel a unit -*/
6017          deleteHC(&h, strat);
6018        }
6019        if (h.p!=NULL)
6020        {
6021          if (TEST_OPT_INTSTRATEGY)
6022          {
6023            //pContent(h.p);
6024            h.pCleardenom(); // also does a pContent
6025          }
6026          else
6027          {
6028            h.pNorm();
6029          }
6030          strat->initEcart(&h);
6031          if (strat->Ll==-1)
6032            pos =0;
6033          else
6034            pos = strat->posInLSba(strat->L,strat->Ll,&h,strat);
6035          h.sev = pGetShortExpVector(h.p);
6036          enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
6037        }
6038      }
6039      /*
6040      if (strat->sbaOrder != 1)
6041      {
6042        for(j=0;j<i;j++)
6043        {
6044          strat->syz[ctr] = pCopy(F->m[j]);
6045          p_SetCompP(strat->syz[ctr],i+1,currRing);
6046          // add LM(F->m[i]) to the signature to get a Schreyer order
6047          // without changing the underlying polynomial ring at all
6048          p_ExpVectorAdd (strat->syz[ctr],F->m[i],currRing);
6049          // since p_Add_q() destroys all input
6050          // data we need to recreate help
6051          // each time
6052          poly help = pCopy(F->m[i]);
6053          p_SetCompP(help,j+1,currRing);
6054          pWrite(strat->syz[ctr]);
6055          pWrite(help);
6056          printf("%d\n",pLmCmp(strat->syz[ctr],help));
6057          strat->syz[ctr] = p_Add_q(strat->syz[ctr],help,currRing);
6058          printf("%d. SYZ  ",ctr);
6059          pWrite(strat->syz[ctr]);
6060          strat->sevSyz[ctr] = p_GetShortExpVector(strat->syz[ctr],currRing);
6061          ctr++;
6062        }
6063        strat->syzl = ps;
6064      }
6065      */
6066    }
6067  }
6068  /*- test, if a unit is in F -*/
6069
6070  if ((strat->Ll>=0)
6071#ifdef HAVE_RINGS
6072       && n_IsUnit(pGetCoeff(strat->L[strat->Ll].p), currRing->cf)
6073#endif
6074       && pIsConstant(strat->L[strat->Ll].p))
6075  {
6076    while (strat->Ll>0) deleteInL(strat->L,&strat->Ll,strat->Ll-1,strat);
6077  }
6078}
6079
6080void initSyzRules (kStrategy strat)
6081{
6082  if( strat->S[0] )
6083  {
6084    if( strat->S[1] )
6085    {
6086      omFreeSize(strat->syzIdx,(strat->syzidxmax)*sizeof(int));
6087      omFreeSize(strat->sevSyz,(strat->syzmax)*sizeof(unsigned long));
6088      omFreeSize(strat->syz,(strat->syzmax)*sizeof(poly));
6089    }
6090    int i, j, k, diff, comp, comp_old, ps=0, ctr=0;
6091    /************************************************************
6092     * computing the length of the syzygy array needed
6093     ***********************************************************/
6094    for(i=1; i<=strat->sl; i++)
6095    {
6096      if (pGetComp(strat->sig[i-1]) != pGetComp(strat->sig[i]))
6097      {
6098        ps += i;
6099      }
6100    }
6101    ps += strat->sl+1;
6102    //comp              = pGetComp (strat->P.sig);
6103    comp              = strat->currIdx;
6104    strat->syzIdx     = initec(comp);
6105    strat->sevSyz     = initsevS(ps);
6106    strat->syz        = (poly *)omAlloc(ps*sizeof(poly));
6107    strat->syzl       = strat->syzmax = ps;
6108    strat->syzidxmax  = comp;
6109#if defined(DEBUGF5) || defined(DEBUGF51)
6110    printf("------------- GENERATING SYZ RULES NEW ---------------\n");
6111#endif
6112    i = 1;
6113    j = 0;
6114    /************************************************************
6115     * generating the leading terms of the principal syzygies
6116     ***********************************************************/
6117    while (i <= strat->sl)
6118    {
6119      /**********************************************************
6120       * principal syzygies start with component index 2
6121       * the array syzIdx starts with index 0
6122       * => the rules for a signature with component comp start
6123       *    at strat->syz[strat->syzIdx[comp-2]] !
6124       *********************************************************/
6125      if (pGetComp(strat->sig[i-1]) != pGetComp(strat->sig[i]))
6126      {
6127        comp      = pGetComp(strat->sig[i]);
6128        comp_old  = pGetComp(strat->sig[i-1]);
6129        diff      = comp - comp_old - 1;
6130        // diff should be zero, but sometimes also the initial generating
6131        // elements of the input ideal reduce to zero. then there is an
6132        // index-gap between the signatures. for these inbetween signatures we
6133        // can safely set syzIdx[j] = 0 as no such element will be ever computed
6134        // in the following.
6135        // doing this, we keep the relation "j = comp - 2" alive, which makes
6136        // jumps way easier when checking criteria
6137        while (diff>0)
6138        {
6139          strat->syzIdx[j]  = 0;
6140          diff--;
6141          j++;
6142        }
6143        strat->syzIdx[j]  = ctr;
6144        j++;
6145        for (k = 0; k<i; k++)
6146        {
6147          poly p          = pOne();
6148          pLcm(strat->S[k],strat->S[i],p);
6149          strat->syz[ctr] = p;
6150          p_SetCompP (strat->syz[ctr], comp, currRing);
6151          poly q          = p_Copy(p, currRing);
6152          q               = p_Neg (q, currRing);
6153          p_SetCompP (q, p_GetComp(strat->sig[k], currRing), currRing);
6154          strat->syz[ctr] = p_Add_q (strat->syz[ctr], q, currRing);
6155#if defined(DEBUGF5) || defined(DEBUGF51)
6156          pWrite(strat->syz[ctr]);
6157#endif
6158          strat->sevSyz[ctr] = p_GetShortExpVector(strat->syz[ctr],currRing);
6159          ctr++;
6160        }
6161      }
6162      i++;
6163    }
6164    /**************************************************************
6165    * add syzygies for upcoming first element of new iteration step
6166    **************************************************************/
6167    comp      = strat->currIdx;
6168    comp_old  = pGetComp(strat->sig[i-1]);
6169    diff      = comp - comp_old - 1;
6170    // diff should be zero, but sometimes also the initial generating
6171    // elements of the input ideal reduce to zero. then there is an
6172    // index-gap between the signatures. for these inbetween signatures we
6173    // can safely set syzIdx[j] = 0 as no such element will be ever computed
6174    // in the following.
6175    // doing this, we keep the relation "j = comp - 2" alive, which makes
6176    // jumps way easier when checking criteria
6177    while (diff>0)
6178    {
6179      strat->syzIdx[j]  = 0;
6180      diff--;
6181      j++;
6182    }
6183    strat->syzIdx[j]  = ctr;
6184    for (k = 0; k<strat->sl+1; k++)
6185    {
6186      strat->syz[ctr] = p_Copy (pHead(strat->S[k]), currRing);
6187      p_SetCompP (strat->syz[ctr], comp, currRing);
6188      poly q          = p_Copy (pHead(strat->L[strat->Ll].p), currRing);
6189      q               = p_Neg (q, currRing);
6190      p_SetCompP (q, p_GetComp(strat->sig[k], currRing), currRing);
6191      strat->syz[ctr] = p_Add_q (strat->syz[ctr], q, currRing);
6192//#if 1
6193#if DEBUGF5 || DEBUGF51
6194      printf("..");
6195      pWrite(strat->syz[ctr]);
6196#endif
6197      strat->sevSyz[ctr] = p_GetShortExpVector(strat->syz[ctr],currRing);
6198      ctr++;
6199    }
6200//#if 1
6201#ifdef DEBUGF5
6202    Print("Principal syzygies:\n");
6203    Print("--------------------------------\n");
6204    for(i=0;i<=ps-1;i++)
6205    {
6206      pWrite(strat->syz[i]);
6207    }
6208    Print("--------------------------------\n");
6209#endif
6210
6211  }
6212}
6213
6214
6215
6216/*2
6217*construct the set s from F and {P}
6218*/
6219void initSSpecial (ideal F, ideal Q, ideal P,kStrategy strat)
6220{
6221  int   i,pos;
6222
6223  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
6224  else i=setmaxT;
6225  i=((i+IDELEMS(F)+IDELEMS(P)+15)/16)*16;
6226  strat->ecartS=initec(i);
6227  strat->sevS=initsevS(i);
6228  strat->S_2_R=initS_2_R(i);
6229  strat->fromQ=NULL;
6230  strat->Shdl=idInit(i,F->rank);
6231  strat->S=strat->Shdl->m;
6232
6233  /*- put polys into S -*/
6234  if (Q!=NULL)
6235  {
6236    strat->fromQ=initec(i);
6237    memset(strat->fromQ,0,i*sizeof(int));
6238    for (i=0; i<IDELEMS(Q); i++)
6239    {
6240      if (Q->m[i]!=NULL)
6241      {
6242        LObject h;
6243        h.p = pCopy(Q->m[i]);
6244        //if (TEST_OPT_INTSTRATEGY)
6245        //{
6246        //  //pContent(h.p);
6247        //  h.pCleardenom(); // also does a pContent
6248        //}
6249        //else
6250        //{
6251        //  h.pNorm();
6252        //}
6253        if (currRing->OrdSgn==-1)
6254        {
6255          deleteHC(&h,strat);
6256        }
6257        if (h.p!=NULL)
6258        {
6259          strat->initEcart(&h);
6260          if (strat->sl==-1)
6261            pos =0;
6262          else
6263          {
6264            pos = posInS(strat,strat->sl,h.p,h.ecart);
6265          }
6266          h.sev = pGetShortExpVector(h.p);
6267          strat->enterS(h,pos,strat, strat->tl+1);
6268          enterT(h, strat);
6269          strat->fromQ[pos]=1;
6270        }
6271      }
6272    }
6273  }
6274  /*- put polys into S -*/
6275  for (i=0; i<IDELEMS(F); i++)
6276  {
6277    if (F->m[i]!=NULL)
6278    {
6279      LObject h;
6280      h.p = pCopy(F->m[i]);
6281      if (currRing->OrdSgn==-1)
6282      {
6283        deleteHC(&h,strat);
6284      }
6285      else
6286      {
6287        h.p=redtailBba(h.p,strat->sl,strat);
6288      }
6289      if (h.p!=NULL)
6290      {
6291        strat->initEcart(&h);
6292        if (strat->sl==-1)
6293          pos =0;
6294        else
6295          pos = posInS(strat,strat->sl,h.p,h.ecart);
6296        h.sev = pGetShortExpVector(h.p);
6297        strat->enterS(h,pos,strat, strat->tl+1);
6298        enterT(h,strat);
6299      }
6300    }
6301  }
6302  for (i=0; i<IDELEMS(P); i++)
6303  {
6304    if (P->m[i]!=NULL)
6305    {
6306      LObject h;
6307      h.p=pCopy(P->m[i]);
6308      if (TEST_OPT_INTSTRATEGY)
6309      {
6310        h.pCleardenom();
6311      }
6312      else
6313      {
6314        h.pNorm();
6315      }
6316      if(strat->sl>=0)
6317      {
6318        if (currRing->OrdSgn==1)
6319        {
6320          h.p=redBba(h.p,strat->sl,strat);
6321          if (h.p!=NULL)
6322          {
6323            h.p=redtailBba(h.p,strat->sl,strat);
6324          }
6325        }
6326        else
6327        {
6328          h.p=redMora(h.p,strat->sl,strat);
6329        }
6330        if(h.p!=NULL)
6331        {
6332          strat->initEcart(&h);
6333          if (TEST_OPT_INTSTRATEGY)
6334          {
6335            h.pCleardenom();
6336          }
6337          else
6338          {
6339            h.is_normalized = 0;
6340            h.pNorm();
6341          }
6342          h.sev = pGetShortExpVector(h.p);
6343          h.SetpFDeg();
6344          pos = posInS(strat,strat->sl,h.p,h.ecart);
6345          enterpairsSpecial(h.p,strat->sl,h.ecart,pos,strat,strat->tl+1);
6346          strat->enterS(h,pos,strat, strat->tl+1);
6347          enterT(h,strat);
6348        }
6349      }
6350      else
6351      {
6352        h.sev = pGetShortExpVector(h.p);
6353        strat->initEcart(&h);
6354        strat->enterS(h,0,strat, strat->tl+1);
6355        enterT(h,strat);
6356      }
6357    }
6358  }
6359}
6360/*2
6361*construct the set s from F and {P}
6362*/
6363
6364void initSSpecialSba (ideal F, ideal Q, ideal P,kStrategy strat)
6365{
6366  int   i,pos;
6367
6368  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
6369  else i=setmaxT;
6370  i=((i+IDELEMS(F)+IDELEMS(P)+15)/16)*16;
6371  strat->fromS=initec(i);
6372  strat->sevS=initsevS(i);
6373  strat->sevSig=initsevS(i);
6374  strat->S_2_R=initS_2_R(i);
6375  strat->fromQ=NULL;
6376  strat->Shdl=idInit(i,F->rank);
6377  strat->S=strat->Shdl->m;
6378  strat->sig=(poly *)omAlloc0(i*sizeof(poly));
6379  /*- put polys into S -*/
6380  if (Q!=NULL)
6381  {
6382    strat->fromQ=initec(i);
6383    memset(strat->fromQ,0,i*sizeof(int));
6384    for (i=0; i<IDELEMS(Q); i++)
6385    {
6386      if (Q->m[i]!=NULL)
6387      {
6388        LObject h;
6389        h.p = pCopy(Q->m[i]);
6390        //if (TEST_OPT_INTSTRATEGY)
6391        //{
6392        //  //pContent(h.p);
6393        //  h.pCleardenom(); // also does a pContent
6394        //}
6395        //else
6396        //{
6397        //  h.pNorm();
6398        //}
6399        if (currRing->OrdSgn==-1)
6400        {
6401          deleteHC(&h,strat);
6402        }
6403        if (h.p!=NULL)
6404        {
6405          strat->initEcart(&h);
6406          if (strat->sl==-1)
6407            pos =0;
6408          else
6409          {
6410            pos = posInS(strat,strat->sl,h.p,h.ecart);
6411          }
6412          h.sev = pGetShortExpVector(h.p);
6413          strat->enterS(h,pos,strat, strat->tl+1);
6414          enterT(h, strat);
6415          strat->fromQ[pos]=1;
6416        }
6417      }
6418    }
6419  }
6420  /*- put polys into S -*/
6421  for (i=0; i<IDELEMS(F); i++)
6422  {
6423    if (F->m[i]!=NULL)
6424    {
6425      LObject h;
6426      h.p = pCopy(F->m[i]);
6427      if (currRing->OrdSgn==-1)
6428      {
6429        deleteHC(&h,strat);
6430      }
6431      else
6432      {
6433        h.p=redtailBba(h.p,strat->sl,strat);
6434      }
6435      if (h.p!=NULL)
6436      {
6437        strat->initEcart(&h);
6438        if (strat->sl==-1)
6439          pos =0;
6440        else
6441          pos = posInS(strat,strat->sl,h.p,h.ecart);
6442        h.sev = pGetShortExpVector(h.p);
6443        strat->enterS(h,pos,strat, strat->tl+1);
6444        enterT(h,strat);
6445      }
6446    }
6447  }
6448  for (i=0; i<IDELEMS(P); i++)
6449  {
6450    if (P->m[i]!=NULL)
6451    {
6452      LObject h;
6453      h.p=pCopy(P->m[i]);
6454      if (TEST_OPT_INTSTRATEGY)
6455      {
6456        h.pCleardenom();
6457      }
6458      else
6459      {
6460        h.pNorm();
6461      }
6462      if(strat->sl>=0)
6463      {
6464        if (currRing->OrdSgn==1)
6465        {
6466          h.p=redBba(h.p,strat->sl,strat);
6467          if (h.p!=NULL)
6468          {
6469            h.p=redtailBba(h.p,strat->sl,strat);
6470          }
6471        }
6472        else
6473        {
6474          h.p=redMora(h.p,strat->sl,strat);
6475        }
6476        if(h.p!=NULL)
6477        {
6478          strat->initEcart(&h);
6479          if (TEST_OPT_INTSTRATEGY)
6480          {
6481            h.pCleardenom();
6482          }
6483          else
6484          {
6485            h.is_normalized = 0;
6486            h.pNorm();
6487          }
6488          h.sev = pGetShortExpVector(h.p);
6489          h.SetpFDeg();
6490          pos = posInS(strat,strat->sl,h.p,h.ecart);
6491          enterpairsSpecial(h.p,strat->sl,h.ecart,pos,strat,strat->tl+1);
6492          strat->enterS(h,pos,strat, strat->tl+1);
6493          enterT(h,strat);
6494        }
6495      }
6496      else
6497      {
6498        h.sev = pGetShortExpVector(h.p);
6499        strat->initEcart(&h);
6500        strat->enterS(h,0,strat, strat->tl+1);
6501        enterT(h,strat);
6502      }
6503    }
6504  }
6505}
6506/*2
6507* reduces h using the set S
6508* procedure used in cancelunit1
6509*/
6510static poly redBba1 (poly h,int maxIndex,kStrategy strat)
6511{
6512  int j = 0;
6513  unsigned long not_sev = ~ pGetShortExpVector(h);
6514
6515  while (j <= maxIndex)
6516  {
6517    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j],h, not_sev))
6518       return ksOldSpolyRedNew(strat->S[j],h,strat->kNoetherTail());
6519    else j++;
6520  }
6521  return h;
6522}
6523
6524/*2
6525*tests if p.p=monomial*unit and cancels the unit
6526*/
6527void cancelunit1 (LObject* p,int *suc, int index,kStrategy strat )
6528{
6529  int k;
6530  poly r,h,h1,q;
6531
6532  if (!pIsVector((*p).p) && ((*p).ecart != 0))
6533  {
6534#ifdef HAVE_RINGS_LOC
6535    // Leading coef have to be a unit
6536    if ( !(nIsUnit(p_GetCoeff((*p).p, r))) ) return;
6537#endif
6538    k = 0;
6539    h1 = r = pCopy((*p).p);
6540    h =pNext(r);
6541    loop
6542    {
6543      if (h==NULL)
6544      {
6545        pDelete(&r);
6546        pDelete(&(pNext((*p).p)));
6547        (*p).ecart = 0;
6548        (*p).length = 1;
6549#ifdef HAVE_RINGS_LOC
6550        (*p).pLength = 1;  // Why wasn't this set already?
6551#endif
6552        (*suc)=0;
6553        return;
6554      }
6555      if (!pDivisibleBy(r,h))
6556      {
6557        q=redBba1(h,index ,strat);
6558        if (q != h)
6559        {
6560          k++;
6561          pDelete(&h);
6562          pNext(h1) = h = q;
6563        }
6564        else
6565        {
6566          pDelete(&r);
6567          return;
6568        }
6569      }
6570      else
6571      {
6572        h1 = h;
6573        pIter(h);
6574      }
6575      if (k > 10)
6576      {
6577        pDelete(&r);
6578        return;
6579      }
6580    }
6581  }
6582}
6583
6584#if 0
6585/*2
6586* reduces h using the elements from Q in the set S
6587* procedure used in updateS
6588* must not be used for elements of Q or elements of an ideal !
6589*/
6590static poly redQ (poly h, int j, kStrategy strat)
6591{
6592  int start;
6593  unsigned long not_sev = ~ pGetShortExpVector(h);
6594  while ((j <= strat->sl) && (pGetComp(strat->S[j])!=0)) j++;
6595  start=j;
6596  while (j<=strat->sl)
6597  {
6598    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev))
6599    {
6600      h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
6601      if (h==NULL) return NULL;
6602      j = start;
6603      not_sev = ~ pGetShortExpVector(h);
6604    }
6605    else j++;
6606  }
6607  return h;
6608}
6609#endif
6610
6611/*2
6612* reduces h using the set S
6613* procedure used in updateS
6614*/
6615static poly redBba (poly h,int maxIndex,kStrategy strat)
6616{
6617  int j = 0;
6618  unsigned long not_sev = ~ pGetShortExpVector(h);
6619
6620  while (j <= maxIndex)
6621  {
6622    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev))
6623    {
6624      h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
6625      if (h==NULL) return NULL;
6626      j = 0;
6627      not_sev = ~ pGetShortExpVector(h);    }
6628    else j++;
6629  }
6630  return h;
6631}
6632
6633/*2
6634* reduces h using the set S
6635*e is the ecart of h
6636*procedure used in updateS
6637*/
6638static poly redMora (poly h,int maxIndex,kStrategy strat)
6639{
6640  int  j=0;
6641  int  e,l;
6642  unsigned long not_sev = ~ pGetShortExpVector(h);
6643
6644  if (maxIndex >= 0)
6645  {
6646    e = currRing->pLDeg(h,&l,currRing)-p_FDeg(h,currRing);
6647    do
6648    {
6649      if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev)
6650      && ((e >= strat->ecartS[j]) || strat->kHEdgeFound))
6651      {
6652#ifdef KDEBUG
6653        if (TEST_OPT_DEBUG)
6654          {PrintS("reduce ");wrp(h);Print(" with S[%d] (",j);wrp(strat->S[j]);}
6655#endif
6656        h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
6657#ifdef KDEBUG
6658        if(TEST_OPT_DEBUG)
6659          {PrintS(")\nto "); wrp(h); PrintLn();}
6660#endif
6661        // pDelete(&h);
6662        if (h == NULL) return NULL;
6663        e = currRing->pLDeg(h,&l,currRing)-p_FDeg(h,currRing);
6664        j = 0;
6665        not_sev = ~ pGetShortExpVector(h);
6666      }
6667      else j++;
6668    }
6669    while (j <= maxIndex);
6670  }
6671  return h;
6672}
6673
6674/*2
6675*updates S:
6676*the result is a set of polynomials which are in
6677*normalform with respect to S
6678*/
6679void updateS(BOOLEAN toT,kStrategy strat)
6680{
6681  LObject h;
6682  int i, suc=0;
6683  poly redSi=NULL;
6684  BOOLEAN change,any_change;
6685//  Print("nach initS: updateS start mit sl=%d\n",(strat->sl));
6686//  for (i=0; i<=(strat->sl); i++)
6687//  {
6688//    Print("s%d:",i);
6689//    if (strat->fromQ!=NULL) Print("(Q:%d) ",strat->fromQ[i]);
6690//    pWrite(strat->S[i]);
6691//  }
6692//  Print("currRing->OrdSgn=%d\n", currRing->OrdSgn);
6693  any_change=FALSE;
6694  if (currRing->OrdSgn==1)
6695  {
6696    while (suc != -1)
6697    {
6698      i=suc+1;
6699      while (i<=strat->sl)
6700      {
6701        change=FALSE;
6702        if (((strat->fromQ==NULL) || (strat->fromQ[i]==0)) && (i>0))
6703        {
6704          redSi = pHead(strat->S[i]);
6705          strat->S[i] = redBba(strat->S[i],i-1,strat);
6706          //if ((strat->ak!=0)&&(strat->S[i]!=NULL))
6707          //  strat->S[i]=redQ(strat->S[i],i+1,strat); /*reduce S[i] mod Q*/
6708          if (pCmp(redSi,strat->S[i])!=0)
6709          {
6710            change=TRUE;
6711            any_change=TRUE;
6712            #ifdef KDEBUG
6713            if (TEST_OPT_DEBUG)
6714            {
6715              PrintS("reduce:");
6716              wrp(redSi);PrintS(" to ");p_wrp(strat->S[i], currRing, strat->tailRing);PrintLn();
6717            }
6718            #endif
6719            if (TEST_OPT_PROT)
6720            {
6721              if (strat->S[i]==NULL)
6722                PrintS("V");
6723              else
6724                PrintS("v");
6725              mflush();
6726            }
6727          }
6728          pLmDelete(&redSi);
6729          if (strat->S[i]==NULL)
6730          {
6731            deleteInS(i,strat);
6732            i--;
6733          }
6734          else if (change)
6735          {
6736            if (TEST_OPT_INTSTRATEGY)
6737            {
6738              if (TEST_OPT_CONTENTSB)
6739                {
6740                  number n;
6741                  p_Cleardenom_n(strat->S[i], currRing, n);// also does a pContent
6742                  if (!nIsOne(n))
6743                    {
6744                      denominator_list denom=(denominator_list)omAlloc(sizeof(denominator_list_s));
6745                      denom->n=nInvers(n);
6746                      denom->next=DENOMINATOR_LIST;
6747                      DENOMINATOR_LIST=denom;
6748                    }
6749                  nDelete(&n);
6750                }
6751              else
6752                {
6753                  //pContent(strat->S[i]);
6754                  strat->S[i]=p_Cleardenom(strat->S[i], currRing);// also does a pContent
6755                }
6756            }
6757            else
6758            {
6759              pNorm(strat->S[i]);
6760            }
6761            strat->sevS[i] = pGetShortExpVector(strat->S[i]);
6762          }
6763        }
6764        i++;
6765      }
6766      if (any_change) reorderS(&suc,strat);
6767      else break;
6768    }
6769    if (toT)
6770    {
6771      for (i=0; i<=strat->sl; i++)
6772      {
6773        if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
6774        {
6775          h.p = redtailBba(strat->S[i],i-1,strat);
6776          if (TEST_OPT_INTSTRATEGY)
6777          {
6778            h.pCleardenom();// also does a pContent
6779          }
6780        }
6781        else
6782        {
6783          h.p = strat->S[i];
6784        }
6785        strat->initEcart(&h);
6786        if (strat->honey)
6787        {
6788          strat->ecartS[i] = h.ecart;
6789        }
6790        if (strat->sevS[i] == 0) {strat->sevS[i] = pGetShortExpVector(h.p);}
6791        else assume(strat->sevS[i] == pGetShortExpVector(h.p));
6792        h.sev = strat->sevS[i];
6793        /*puts the elements of S also to T*/
6794        strat->initEcart(&h);
6795        enterT(h,strat);
6796        strat->S_2_R[i] = strat->tl;
6797      }
6798    }
6799  }
6800  else
6801  {
6802    while (suc != -1)
6803    {
6804      i=suc;
6805      while (i<=strat->sl)
6806      {
6807        change=FALSE;
6808        if (((strat->fromQ==NULL) || (strat->fromQ[i]==0)) && (i>0))
6809        {
6810          redSi=pHead((strat->S)[i]);
6811          (strat->S)[i] = redMora((strat->S)[i],i-1,strat);
6812          if ((strat->S)[i]==NULL)
6813          {
6814            deleteInS(i,strat);
6815            i--;
6816          }
6817          else if (pCmp((strat->S)[i],redSi)!=0)
6818          {
6819            any_change=TRUE;
6820            h.p = strat->S[i];
6821            strat->initEcart(&h);
6822            strat->ecartS[i] = h.ecart;
6823            if (TEST_OPT_INTSTRATEGY)
6824            {
6825              if (TEST_OPT_CONTENTSB)
6826                {
6827                  number n;
6828                  p_Cleardenom_n(strat->S[i], currRing, n);// also does a pContent
6829                  if (!nIsOne(n))
6830                    {
6831                      denominator_list denom=(denominator_list)omAlloc(sizeof(denominator_list_s));
6832                      denom->n=nInvers(n);
6833                      denom->next=DENOMINATOR_LIST;
6834                      DENOMINATOR_LIST=denom;
6835                    }
6836                  nDelete(&n);
6837                }
6838              else
6839                {
6840                  //pContent(strat->S[i]);
6841                  strat->S[i]=p_Cleardenom(strat->S[i], currRing);// also does a pContent
6842                }
6843            }
6844            else
6845            {
6846              pNorm(strat->S[i]); // == h.p
6847            }
6848            h.sev =  pGetShortExpVector(h.p);
6849            strat->sevS[i] = h.sev;
6850          }
6851          pLmDelete(&redSi);
6852          assume(kTest(strat));
6853        }
6854        i++;
6855      }
6856#ifdef KDEBUG
6857      assume(kTest(strat));
6858#endif
6859      if (any_change) reorderS(&suc,strat);
6860      else { suc=-1; break; }
6861      if (h.p!=NULL)
6862      {
6863        if (!strat->kHEdgeFound)
6864        {
6865          /*strat->kHEdgeFound =*/ HEckeTest(h.p,strat);
6866        }
6867        if (strat->kHEdgeFound)
6868          newHEdge(strat);
6869      }
6870    }
6871    for (i=0; i<=strat->sl; i++)
6872    {
6873      if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
6874      {
6875        strat->S[i] = h.p = redtail(strat->S[i],strat->sl,strat);
6876        strat->initEcart(&h);
6877        strat->ecartS[i] = h.ecart;
6878        h.sev = pGetShortExpVector(h.p);
6879        strat->sevS[i] = h.sev;
6880      }
6881      else
6882      {
6883        h.p = strat->S[i];
6884        h.ecart=strat->ecartS[i];
6885        h.sev = strat->sevS[i];
6886        h.length = h.pLength = pLength(h.p);
6887      }
6888      if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
6889        cancelunit1(&h,&suc,strat->sl,strat);
6890      h.SetpFDeg();
6891      /*puts the elements of S also to T*/
6892      enterT(h,strat);
6893      strat->S_2_R[i] = strat->tl;
6894    }
6895    if (suc!= -1) updateS(toT,strat);
6896  }
6897#ifdef KDEBUG
6898  assume(kTest(strat));
6899#endif
6900}
6901
6902
6903/*2
6904* -puts p to the standardbasis s at position at
6905* -saves the result in S
6906*/
6907void enterSBba (LObject p,int atS,kStrategy strat, int atR)
6908{
6909  strat->news = TRUE;
6910  /*- puts p to the standardbasis s at position at -*/
6911  if (strat->sl == IDELEMS(strat->Shdl)-1)
6912  {
6913    strat->sevS = (unsigned long*) omRealloc0Size(strat->sevS,
6914                                    IDELEMS(strat->Shdl)*sizeof(unsigned long),
6915                                    (IDELEMS(strat->Shdl)+setmaxTinc)
6916                                                  *sizeof(unsigned long));
6917    strat->ecartS = (intset)omReallocSize(strat->ecartS,
6918                                          IDELEMS(strat->Shdl)*sizeof(int),
6919                                          (IDELEMS(strat->Shdl)+setmaxTinc)
6920                                                  *sizeof(int));
6921    strat->S_2_R = (int*) omRealloc0Size(strat->S_2_R,
6922                                         IDELEMS(strat->Shdl)*sizeof(int),
6923                                         (IDELEMS(strat->Shdl)+setmaxTinc)
6924                                                  *sizeof(int));
6925    if (strat->lenS!=NULL)
6926      strat->lenS=(int*)omRealloc0Size(strat->lenS,
6927                                       IDELEMS(strat->Shdl)*sizeof(int),
6928                                       (IDELEMS(strat->Shdl)+setmaxTinc)
6929                                                 *sizeof(int));
6930    if (strat->lenSw!=NULL)
6931      strat->lenSw=(wlen_type*)omRealloc0Size(strat->lenSw,
6932                                       IDELEMS(strat->Shdl)*sizeof(wlen_type),
6933                                       (IDELEMS(strat->Shdl)+setmaxTinc)
6934                                                 *sizeof(wlen_type));
6935    if (strat->fromQ!=NULL)
6936    {
6937      strat->fromQ = (intset)omReallocSize(strat->fromQ,
6938                                    IDELEMS(strat->Shdl)*sizeof(int),
6939                                    (IDELEMS(strat->Shdl)+setmaxTinc)*sizeof(int));
6940    }
6941    pEnlargeSet(&strat->S,IDELEMS(strat->Shdl),setmaxTinc);
6942    IDELEMS(strat->Shdl)+=setmaxTinc;
6943    strat->Shdl->m=strat->S;
6944  }
6945  if (atS <= strat->sl)
6946  {
6947#ifdef ENTER_USE_MEMMOVE
6948// #if 0
6949    memmove(&(strat->S[atS+1]), &(strat->S[atS]),
6950            (strat->sl - atS + 1)*sizeof(poly));
6951    memmove(&(strat->ecartS[atS+1]), &(strat->ecartS[atS]),
6952            (strat->sl - atS + 1)*sizeof(int));
6953    memmove(&(strat->sevS[atS+1]), &(strat->sevS[atS]),
6954            (strat->sl - atS + 1)*sizeof(unsigned long));
6955    memmove(&(strat->S_2_R[atS+1]), &(strat->S_2_R[atS]),
6956            (strat->sl - atS + 1)*sizeof(int));
6957    if (strat->lenS!=NULL)
6958    memmove(&(strat->lenS[atS+1]), &(strat->lenS[atS]),
6959            (strat->sl - atS + 1)*sizeof(int));
6960    if (strat->lenSw!=NULL)
6961    memmove(&(strat->lenSw[atS+1]), &(strat->lenSw[atS]),
6962            (strat->sl - atS + 1)*sizeof(wlen_type));
6963#else
6964    for (i=strat->sl+1; i>=atS+1; i--)
6965    {
6966      strat->S[i] = strat->S[i-1];
6967      strat->ecartS[i] = strat->ecartS[i-1];
6968      strat->sevS[i] = strat->sevS[i-1];
6969      strat->S_2_R[i] = strat->S_2_R[i-1];
6970    }
6971    if (strat->lenS!=NULL)
6972    for (i=strat->sl+1; i>=atS+1; i--)
6973      strat->lenS[i] = strat->lenS[i-1];
6974    if (strat->lenSw!=NULL)
6975    for (i=strat->sl+1; i>=atS+1; i--)
6976      strat->lenSw[i] = strat->lenSw[i-1];
6977#endif
6978  }
6979  if (strat->fromQ!=NULL)
6980  {
6981#ifdef ENTER_USE_MEMMOVE
6982    memmove(&(strat->fromQ[atS+1]), &(strat->fromQ[atS]),
6983                  (strat->sl - atS + 1)*sizeof(int));
6984#else
6985    for (i=strat->sl+1; i>=atS+1; i--)
6986    {
6987      strat->fromQ[i] = strat->fromQ[i-1];
6988    }
6989#endif
6990    strat->fromQ[atS]=0;
6991  }
6992
6993  /*- save result -*/
6994  strat->S[atS] = p.p;
6995  if (strat->honey) strat->ecartS[atS] = p.ecart;
6996  if (p.sev == 0)
6997    p.sev = pGetShortExpVector(p.p);
6998  else
6999    assume(p.sev == pGetShortExpVector(p.p));
7000  strat->sevS[atS] = p.sev;
7001  strat->ecartS[atS] = p.ecart;
7002  strat->S_2_R[atS] = atR;
7003  strat->sl++;
7004}
7005
7006/*2
7007* -puts p to the standardbasis s at position at
7008* -saves the result in S
7009*/
7010void enterSSba (LObject p,int atS,kStrategy strat, int atR)
7011{
7012  strat->news = TRUE;
7013  /*- puts p to the standardbasis s at position at -*/
7014  if (strat->sl == IDELEMS(strat->Shdl)-1)
7015  {
7016    strat->sevS = (unsigned long*) omRealloc0Size(strat->sevS,
7017                                    IDELEMS(strat->Shdl)*sizeof(unsigned long),
7018                                    (IDELEMS(strat->Shdl)+setmaxTinc)
7019                                                  *sizeof(unsigned long));
7020    strat->sevSig = (unsigned long*) omRealloc0Size(strat->sevSig,
7021                                    IDELEMS(strat->Shdl)*sizeof(unsigned long),
7022                                    (IDELEMS(strat->Shdl)+setmaxTinc)
7023                                                  *sizeof(unsigned long));
7024    strat->ecartS = (intset)omReallocSize(strat->ecartS,
7025                                          IDELEMS(strat->Shdl)*sizeof(int),
7026                                          (IDELEMS(strat->Shdl)+setmaxTinc)
7027                                                  *sizeof(int));
7028    strat->fromS = (intset)omReallocSize(strat->fromS,
7029                                          IDELEMS(strat->Shdl)*sizeof(int),
7030                                          (IDELEMS(strat->Shdl)+setmaxTinc)
7031                                                  *sizeof(int));
7032    strat->S_2_R = (int*) omRealloc0Size(strat->S_2_R,
7033                                         IDELEMS(strat->Shdl)*sizeof(int),
7034                                         (IDELEMS(strat->Shdl)+setmaxTinc)
7035                                                  *sizeof(int));
7036    if (strat->lenS!=NULL)
7037      strat->lenS=(int*)omRealloc0Size(strat->lenS,
7038                                       IDELEMS(strat->Shdl)*sizeof(int),
7039                                       (IDELEMS(strat->Shdl)+setmaxTinc)
7040                                                 *sizeof(int));
7041    if (strat->lenSw!=NULL)
7042      strat->lenSw=(wlen_type*)omRealloc0Size(strat->lenSw,
7043                                       IDELEMS(strat->Shdl)*sizeof(wlen_type),
7044                                       (IDELEMS(strat->Shdl)+setmaxTinc)
7045                                                 *sizeof(wlen_type));
7046    if (strat->fromQ!=NULL)
7047    {
7048      strat->fromQ = (intset)omReallocSize(strat->fromQ,
7049                                    IDELEMS(strat->Shdl)*sizeof(int),
7050                                    (IDELEMS(strat->Shdl)+setmaxTinc)*sizeof(int));
7051    }
7052    pEnlargeSet(&strat->S,IDELEMS(strat->Shdl),setmaxTinc);
7053    pEnlargeSet(&strat->sig,IDELEMS(strat->Shdl),setmaxTinc);
7054    IDELEMS(strat->Shdl)+=setmaxTinc;
7055    strat->Shdl->m=strat->S;
7056  }
7057  // in a signature-based algorithm the following situation will never
7058  // appear due to the fact that the critical pairs are already sorted
7059  // by increasing signature.
7060  if (atS <= strat->sl)
7061  {
7062#ifdef ENTER_USE_MEMMOVE
7063// #if 0
7064    memmove(&(strat->S[atS+1]), &(strat->S[atS]),
7065            (strat->sl - atS + 1)*sizeof(poly));
7066    memmove(&(strat->ecartS[atS+1]), &(strat->ecartS[atS]),
7067            (strat->sl - atS + 1)*sizeof(int));
7068    memmove(&(strat->fromS[atS+1]), &(strat->fromS[atS]),
7069            (strat->sl - atS + 1)*sizeof(int));
7070    memmove(&(strat->sevS[atS+1]), &(strat->sevS[atS]),
7071            (strat->sl - atS + 1)*sizeof(unsigned long));
7072    memmove(&(strat->S_2_R[atS+1]), &(strat->S_2_R[atS]),
7073            (strat->sl - atS + 1)*sizeof(int));
7074    if (strat->lenS!=NULL)
7075    memmove(&(strat->lenS[atS+1]), &(strat->lenS[atS]),
7076            (strat->sl - atS + 1)*sizeof(int));
7077    if (strat->lenSw!=NULL)
7078    memmove(&(strat->lenSw[atS+1]), &(strat->lenSw[atS]),
7079            (strat->sl - atS + 1)*sizeof(wlen_type));
7080#else
7081    for (i=strat->sl+1; i>=atS+1; i--)
7082    {
7083      strat->S[i] = strat->S[i-1];
7084      strat->ecartS[i] = strat->ecartS[i-1];
7085      strat->fromS[i] = strat->fromS[i-1];
7086      strat->sevS[i] = strat->sevS[i-1];
7087      strat->S_2_R[i] = strat->S_2_R[i-1];
7088    }
7089    if (strat->lenS!=NULL)
7090    for (i=strat->sl+1; i>=atS+1; i--)
7091      strat->lenS[i] = strat->lenS[i-1];
7092    if (strat->lenSw!=NULL)
7093    for (i=strat->sl+1; i>=atS+1; i--)
7094      strat->lenSw[i] = strat->lenSw[i-1];
7095#endif
7096  }
7097  if (strat->fromQ!=NULL)
7098  {
7099#ifdef ENTER_USE_MEMMOVE
7100    memmove(&(strat->fromQ[atS+1]), &(strat->fromQ[atS]),
7101                  (strat->sl - atS + 1)*sizeof(int));
7102#else
7103    for (i=strat->sl+1; i>=atS+1; i--)
7104    {
7105      strat->fromQ[i] = strat->fromQ[i-1];
7106    }
7107#endif
7108    strat->fromQ[atS]=0;
7109  }
7110
7111  /*- save result -*/
7112  strat->S[atS] = p.p;
7113  strat->sig[atS] = p.sig; // TODO: get ths correct signature in here!
7114  if (strat->honey) strat->ecartS[atS] = p.ecart;
7115  if (p.sev == 0)
7116    p.sev = pGetShortExpVector(p.p);
7117  else
7118    assume(p.sev == pGetShortExpVector(p.p));
7119  strat->sevS[atS] = p.sev;
7120  // during the interreduction process of a signature-based algorithm we do not
7121  // compute the signature at this point, but when the whole interreduction
7122  // process finishes, i.e. f5c terminates!
7123  if (p.sig != NULL)
7124  {
7125    if (p.sevSig == 0)
7126      p.sevSig = pGetShortExpVector(p.sig);
7127    else
7128      assume(p.sevSig == pGetShortExpVector(p.sig));
7129    strat->sevSig[atS] = p.sevSig; // TODO: get the correct signature in here!
7130  }
7131  strat->ecartS[atS] = p.ecart;
7132  strat->fromS[atS] = p.from;
7133  strat->S_2_R[atS] = atR;
7134  strat->sl++;
7135#ifdef DEBUGF5
7136  int k;
7137  Print("--- LIST S: %d ---\n",strat->sl);
7138  for(k=0;k<=strat->sl;k++)
7139  {
7140    pWrite(strat->sig[k]);
7141  }
7142  Print("--- LIST S END ---\n");
7143#endif
7144}
7145
7146/*2
7147* puts p to the set T at position atT
7148*/
7149void enterT(LObject p, kStrategy strat, int atT)
7150{
7151  int i;
7152
7153  pp_Test(p.p, currRing, p.tailRing);
7154  assume(strat->tailRing == p.tailRing);
7155  // redMoraNF complains about this -- but, we don't really
7156  // neeed this so far
7157  assume(p.pLength == 0 || pLength(p.p) == p.pLength || rIsSyzIndexRing(currRing)); // modulo syzring
7158  assume(p.FDeg == p.pFDeg());
7159  assume(!p.is_normalized || nIsOne(pGetCoeff(p.p)));
7160
7161#ifdef KDEBUG
7162  // do not put an LObject twice into T:
7163  for(i=strat->tl;i>=0;i--)
7164  {
7165    if (p.p==strat->T[i].p)
7166    {
7167      printf("already in T at pos %d of %d, atT=%d\n",i,strat->tl,atT);
7168      return;
7169    }
7170  }
7171#endif
7172  strat->newt = TRUE;
7173  if (atT < 0)
7174    atT = strat->posInT(strat->T, strat->tl, p);
7175  if (strat->tl == strat->tmax-1)
7176    enlargeT(strat->T,strat->R,strat->sevT,strat->tmax,setmaxTinc);
7177  if (atT <= strat->tl)
7178  {
7179#ifdef ENTER_USE_MEMMOVE
7180    memmove(&(strat->T[atT+1]), &(strat->T[atT]),
7181            (strat->tl-atT+1)*sizeof(TObject));
7182    memmove(&(strat->sevT[atT+1]), &(strat->sevT[atT]),
7183            (strat->tl-atT+1)*sizeof(unsigned long));
7184#endif
7185    for (i=strat->tl+1; i>=atT+1; i--)
7186    {
7187#ifndef ENTER_USE_MEMMOVE
7188      strat->T[i] = strat->T[i-1];
7189      strat->sevT[i] = strat->sevT[i-1];
7190#endif
7191      strat->R[strat->T[i].i_r] = &(strat->T[i]);
7192    }
7193  }
7194
7195  if ((strat->tailBin != NULL) && (pNext(p.p) != NULL))
7196  {
7197    pNext(p.p)=p_ShallowCopyDelete(pNext(p.p),
7198                                   (strat->tailRing != NULL ?
7199                                    strat->tailRing : currRing),
7200                                   strat->tailBin);
7201    if (p.t_p != NULL) pNext(p.t_p) = pNext(p.p);
7202  }
7203  strat->T[atT] = (TObject) p;
7204
7205  if (strat->tailRing != currRing && pNext(p.p) != NULL)
7206    strat->T[atT].max = p_GetMaxExpP(pNext(p.p), strat->tailRing);
7207  else
7208    strat->T[atT].max = NULL;
7209
7210  strat->tl++;
7211  strat->R[strat->tl] = &(strat->T[atT]);
7212  strat->T[atT].i_r = strat->tl;
7213  assume(p.sev == 0 || pGetShortExpVector(p.p) == p.sev);
7214  strat->sevT[atT] = (p.sev == 0 ? pGetShortExpVector(p.p) : p.sev);
7215  assume(kTest_T(&(strat->T[atT])));
7216}
7217
7218/*2
7219* puts signature p.sig to the set syz
7220*/
7221void enterSyz(LObject p, kStrategy strat)
7222{
7223  int i = strat->syzl;
7224
7225  strat->newt = TRUE;
7226  if (strat->syzl == strat->syzmax)
7227  {
7228    pEnlargeSet(&strat->syz,strat->syzmax,setmaxTinc);
7229    strat->sevSyz = (unsigned long*) omRealloc0Size(strat->sevSyz,
7230                                    (strat->syzmax)*sizeof(unsigned long),
7231                                    ((strat->syzmax)+setmaxTinc)
7232                                                  *sizeof(unsigned long));
7233    strat->syzmax += setmaxTinc;
7234  }
7235  strat->syz[i] = p.sig;
7236  strat->sevSyz[i] = p.sevSig;
7237  strat->syzl++;
7238#ifdef DEBUGF5
7239  Print("last element in strat->syz: %d--%d  ",i+1,strat->syzmax);
7240  pWrite(strat->syz[i]);
7241#endif
7242  // recheck pairs in strat->L with new rule and delete correspondingly
7243  int cc = strat->Ll;
7244  while (cc>-1)
7245  {
7246    if (p_LmShortDivisibleBy( strat->syz[strat->syzl-1], strat->sevSyz[strat->syzl-1],
7247                              strat->L[cc].sig, ~strat->L[cc].sevSig, currRing))
7248    {
7249      deleteInL(strat->L,&strat->Ll,cc,strat);
7250    }
7251    cc--;
7252  }
7253
7254}
7255
7256
7257void initHilbCrit(ideal/*F*/, ideal /*Q*/, intvec **hilb,kStrategy strat)
7258{
7259
7260  //if the ordering is local, then hilb criterion
7261  //can be used also if tzhe ideal is not homogenous
7262  if((currRing->OrdSgn == -1) && (currRing->MixedOrder == 0 ))
7263  #ifdef HAVE_RINGS
7264  {
7265  if(rField_is_Ring(currRing))
7266          *hilb=NULL;
7267  else
7268           return;
7269  }
7270#endif
7271  if (strat->homog!=isHomog)
7272  {
7273    *hilb=NULL;
7274  }
7275}
7276
7277void initBuchMoraCrit(kStrategy strat)
7278{
7279  strat->enterOnePair=enterOnePairNormal;
7280  strat->chainCrit=chainCritNormal;
7281#ifdef HAVE_RINGS
7282  if (rField_is_Ring(currRing))
7283  {
7284    strat->enterOnePair=enterOnePairRing;
7285    strat->chainCrit=chainCritRing;
7286  }
7287#endif
7288#ifdef HAVE_RATGRING
7289  if (rIsRatGRing(currRing))
7290  {
7291     strat->chainCrit=chainCritPart;
7292     /* enterOnePairNormal get rational part in it */
7293  }
7294#endif
7295
7296  strat->sugarCrit =        TEST_OPT_SUGARCRIT;
7297  strat->Gebauer =          strat->homog || strat->sugarCrit;
7298  strat->honey =            !strat->homog || strat->sugarCrit || TEST_OPT_WEIGHTM;
7299  if (TEST_OPT_NOT_SUGAR) strat->honey = FALSE;
7300  strat->pairtest = NULL;
7301  /* alway use tailreduction, except:
7302  * - in local rings, - in lex order case, -in ring over extensions */
7303  strat->noTailReduction = !TEST_OPT_REDTAIL;
7304
7305#ifdef HAVE_PLURAL
7306  // and r is plural_ring
7307  //  hence this holds for r a rational_plural_ring
7308  if( rIsPluralRing(currRing) || (rIsSCA(currRing) && !strat->z2homog) )
7309  {    //or it has non-quasi-comm type... later
7310    strat->sugarCrit = FALSE;
7311    strat->Gebauer = FALSE;
7312    strat->honey = FALSE;
7313  }
7314#endif
7315
7316#ifdef HAVE_RINGS
7317  // Coefficient ring?
7318  if (rField_is_Ring(currRing))
7319  {
7320    strat->sugarCrit = FALSE;
7321    strat->Gebauer = FALSE ;
7322    strat->honey = FALSE;
7323  }
7324#endif
7325  #ifdef KDEBUG
7326  if (TEST_OPT_DEBUG)
7327  {
7328    if (strat->homog) PrintS("ideal/module is homogeneous\n");
7329    else              PrintS("ideal/module is not homogeneous\n");
7330  }
7331  #endif
7332}
7333
7334void initSbaCrit(kStrategy strat)
7335{
7336  //strat->enterOnePair=enterOnePairNormal;
7337  strat->enterOnePair = enterOnePairNormal;
7338  //strat->chainCrit=chainCritNormal;
7339  strat->chainCrit    = chainCritSig;
7340  /******************************************
7341   * rewCrit1 and rewCrit2 are already set in
7342   * kSba() in kstd1.cc
7343   *****************************************/
7344  //strat->rewCrit1     = faugereRewCriterion;
7345  if (strat->sbaOrder == 1)
7346  {
7347    strat->syzCrit  = syzCriterionInc;
7348  }
7349  else
7350  {
7351    strat->syzCrit  = syzCriterion;
7352  }
7353#ifdef HAVE_RINGS
7354  if (rField_is_Ring(currRing))
7355  {
7356    strat->enterOnePair=enterOnePairRing;
7357    strat->chainCrit=chainCritRing;
7358  }
7359#endif
7360#ifdef HAVE_RATGRING
7361  if (rIsRatGRing(currRing))
7362  {
7363     strat->chainCrit=chainCritPart;
7364     /* enterOnePairNormal get rational part in it */
7365  }
7366#endif
7367
7368  strat->sugarCrit =        TEST_OPT_SUGARCRIT;
7369  strat->Gebauer =          strat->homog || strat->sugarCrit;
7370  strat->honey =            !strat->homog || strat->sugarCrit || TEST_OPT_WEIGHTM;
7371  if (TEST_OPT_NOT_SUGAR) strat->honey = FALSE;
7372  strat->pairtest = NULL;
7373  /* alway use tailreduction, except:
7374  * - in local rings, - in lex order case, -in ring over extensions */
7375  strat->noTailReduction = !TEST_OPT_REDTAIL;
7376  //strat->noTailReduction = NULL;
7377
7378#ifdef HAVE_PLURAL
7379  // and r is plural_ring
7380  //  hence this holds for r a rational_plural_ring
7381  if( rIsPluralRing(currRing) || (rIsSCA(currRing) && !strat->z2homog) )
7382  {    //or it has non-quasi-comm type... later
7383    strat->sugarCrit = FALSE;
7384    strat->Gebauer = FALSE;
7385    strat->honey = FALSE;
7386  }
7387#endif
7388
7389#ifdef HAVE_RINGS
7390  // Coefficient ring?
7391  if (rField_is_Ring(currRing))
7392  {
7393    strat->sugarCrit = FALSE;
7394    strat->Gebauer = FALSE ;
7395    strat->honey = FALSE;
7396  }
7397#endif
7398  #ifdef KDEBUG
7399  if (TEST_OPT_DEBUG)
7400  {
7401    if (strat->homog) PrintS("ideal/module is homogeneous\n");
7402    else              PrintS("ideal/module is not homogeneous\n");
7403  }
7404  #endif
7405}
7406
7407BOOLEAN kPosInLDependsOnLength(int (*pos_in_l)
7408                               (const LSet set, const int length,
7409                                LObject* L,const kStrategy strat))
7410{
7411  if (pos_in_l == posInL110 ||
7412      pos_in_l == posInL10)
7413    return TRUE;
7414
7415  return FALSE;
7416}
7417
7418void initBuchMoraPos (kStrategy strat)
7419{
7420  if (currRing->OrdSgn==1)
7421  {
7422    if (strat->honey)
7423    {
7424      strat->posInL = posInL15;
7425      // ok -- here is the deal: from my experiments for Singular-2-0
7426      // I conclude that that posInT_EcartpLength is the best of
7427      // posInT15, posInT_EcartFDegpLength, posInT_FDegLength, posInT_pLength
7428      // see the table at the end of this file
7429      if (TEST_OPT_OLDSTD)
7430        strat->posInT = posInT15;
7431      else
7432        strat->posInT = posInT_EcartpLength;
7433    }
7434    else if (currRing->pLexOrder && !TEST_OPT_INTSTRATEGY)
7435    {
7436      strat->posInL = posInL11;
7437      strat->posInT = posInT11;
7438    }
7439    else if (TEST_OPT_INTSTRATEGY)
7440    {
7441      strat->posInL = posInL11;
7442      strat->posInT = posInT11;
7443    }
7444    else
7445    {
7446      strat->posInL = posInL0;
7447      strat->posInT = posInT0;
7448    }
7449    //if (strat->minim>0) strat->posInL =posInLSpecial;
7450    if (strat->homog)
7451    {
7452       strat->posInL = posInL110;
7453       strat->posInT = posInT110;
7454    }
7455  }
7456  else
7457  {
7458    if (strat->homog)
7459    {
7460      strat->posInL = posInL11;
7461      strat->posInT = posInT11;
7462    }
7463    else
7464    {
7465      if ((currRing->order[0]==ringorder_c)
7466      ||(currRing->order[0]==ringorder_C))
7467      {
7468        strat->posInL = posInL17_c;
7469        strat->posInT = posInT17_c;
7470      }
7471      else
7472      {
7473        strat->posInL = posInL17;
7474        strat->posInT = posInT17;
7475      }
7476    }
7477  }
7478  if (strat->minim>0) strat->posInL =posInLSpecial;
7479  // for further tests only
7480  if ((BTEST1(11)) || (BTEST1(12)))
7481    strat->posInL = posInL11;
7482  else if ((BTEST1(13)) || (BTEST1(14)))
7483    strat->posInL = posInL13;
7484  else if ((BTEST1(15)) || (BTEST1(16)))
7485    strat->posInL = posInL15;
7486  else if ((BTEST1(17)) || (BTEST1(18)))
7487    strat->posInL = posInL17;
7488  if (BTEST1(11))
7489    strat->posInT = posInT11;
7490  else if (BTEST1(13))
7491    strat->posInT = posInT13;
7492  else if (BTEST1(15))
7493    strat->posInT = posInT15;
7494  else if ((BTEST1(17)))
7495    strat->posInT = posInT17;
7496  else if ((BTEST1(19)))
7497    strat->posInT = posInT19;
7498  else if (BTEST1(12) || BTEST1(14) || BTEST1(16) || BTEST1(18))
7499    strat->posInT = posInT1;
7500#ifdef HAVE_RINGS
7501  if (rField_is_Ring(currRing))
7502  {
7503    strat->posInL = posInL11;
7504    strat->posInT = posInT11;
7505  }
7506#endif
7507  strat->posInLDependsOnLength = kPosInLDependsOnLength(strat->posInL);
7508}
7509
7510void initBuchMora (ideal F,ideal Q,kStrategy strat)
7511{
7512  strat->interpt = BTEST1(OPT_INTERRUPT);
7513  strat->kHEdge=NULL;
7514  if (currRing->OrdSgn==1) strat->kHEdgeFound=FALSE;
7515  /*- creating temp data structures------------------- -*/
7516  strat->cp = 0;
7517  strat->c3 = 0;
7518  strat->tail = pInit();
7519  /*- set s -*/
7520  strat->sl = -1;
7521  /*- set L -*/
7522  strat->Lmax = ((IDELEMS(F)+setmaxLinc-1)/setmaxLinc)*setmaxLinc;
7523  strat->Ll = -1;
7524  strat->L = initL(((IDELEMS(F)+setmaxLinc-1)/setmaxLinc)*setmaxLinc);
7525  /*- set B -*/
7526  strat->Bmax = setmaxL;
7527  strat->Bl = -1;
7528  strat->B = initL();
7529  /*- set T -*/
7530  strat->tl = -1;
7531  strat->tmax = setmaxT;
7532  strat->T = initT();
7533  strat->R = initR();
7534  strat->sevT = initsevT();
7535  /*- init local data struct.---------------------------------------- -*/
7536  strat->P.ecart=0;
7537  strat->P.length=0;
7538  if (currRing->OrdSgn==-1)
7539  {
7540    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
7541    if (strat->kNoether!=NULL) pSetComp(strat->kNoetherTail(), strat->ak);
7542  }
7543  if(TEST_OPT_SB_1)
7544  {
7545    int i;
7546    ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
7547    for (i=strat->newIdeal;i<IDELEMS(F);i++)
7548    {
7549      P->m[i-strat->newIdeal] = F->m[i];
7550      F->m[i] = NULL;
7551    }
7552    initSSpecial(F,Q,P,strat);
7553    for (i=strat->newIdeal;i<IDELEMS(F);i++)
7554    {
7555      F->m[i] = P->m[i-strat->newIdeal];
7556      P->m[i-strat->newIdeal] = NULL;
7557    }
7558    idDelete(&P);
7559  }
7560  else
7561  {
7562    /*Shdl=*/initSL(F, Q,strat); /*sets also S, ecartS, fromQ */
7563    // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
7564  }
7565  strat->fromT = FALSE;
7566  strat->noTailReduction = !TEST_OPT_REDTAIL;
7567  if (!TEST_OPT_SB_1)
7568  {
7569    updateS(TRUE,strat);
7570  }
7571  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
7572  strat->fromQ=NULL;
7573}
7574
7575void exitBuchMora (kStrategy strat)
7576{
7577  /*- release temp data -*/
7578  cleanT(strat);
7579  omFreeSize(strat->T,(strat->tmax)*sizeof(TObject));
7580  omFreeSize(strat->R,(strat->tmax)*sizeof(TObject*));
7581  omFreeSize(strat->sevT, (strat->tmax)*sizeof(unsigned long));
7582  omFreeSize(strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
7583  omFreeSize((ADDRESS)strat->sevS,IDELEMS(strat->Shdl)*sizeof(unsigned long));
7584  omFreeSize(strat->S_2_R,IDELEMS(strat->Shdl)*sizeof(int));
7585  /*- set L: should be empty -*/
7586  omFreeSize(strat->L,(strat->Lmax)*sizeof(LObject));
7587  /*- set B: should be empty -*/
7588  omFreeSize(strat->B,(strat->Bmax)*sizeof(LObject));
7589  pLmDelete(&strat->tail);
7590  strat->syzComp=0;
7591}
7592
7593void initSbaPos (kStrategy strat)
7594{
7595  if (currRing->OrdSgn==1)
7596  {
7597    if (strat->honey)
7598    {
7599      strat->posInL = posInL15;
7600      // ok -- here is the deal: from my experiments for Singular-2-0
7601      // I conclude that that posInT_EcartpLength is the best of
7602      // posInT15, posInT_EcartFDegpLength, posInT_FDegLength, posInT_pLength
7603      // see the table at the end of this file
7604      if (TEST_OPT_OLDSTD)
7605        strat->posInT = posInT15;
7606      else
7607        strat->posInT = posInT_EcartpLength;
7608    }
7609    else if (currRing->pLexOrder && !TEST_OPT_INTSTRATEGY)
7610    {
7611      strat->posInL = posInL11;
7612      strat->posInT = posInT11;
7613    }
7614    else if (TEST_OPT_INTSTRATEGY)
7615    {
7616      strat->posInL = posInL11;
7617      strat->posInT = posInT11;
7618    }
7619    else
7620    {
7621      strat->posInL = posInL0;
7622      strat->posInT = posInT0;
7623    }
7624    //if (strat->minim>0) strat->posInL =posInLSpecial;
7625    if (strat->homog)
7626    {
7627       strat->posInL = posInL110;
7628       strat->posInT = posInT110;
7629    }
7630  }
7631  else
7632  {
7633    if (strat->homog)
7634    {
7635      strat->posInL = posInL11;
7636      strat->posInT = posInT11;
7637    }
7638    else
7639    {
7640      if ((currRing->order[0]==ringorder_c)
7641      ||(currRing->order[0]==ringorder_C))
7642      {
7643        strat->posInL = posInL17_c;
7644        strat->posInT = posInT17_c;
7645      }
7646      else
7647      {
7648        strat->posInL = posInL17;
7649        strat->posInT = posInT17;
7650      }
7651    }
7652  }
7653  if (strat->minim>0) strat->posInL =posInLSpecial;
7654  // for further tests only
7655  if ((BTEST1(11)) || (BTEST1(12)))
7656    strat->posInL = posInL11;
7657  else if ((BTEST1(13)) || (BTEST1(14)))
7658    strat->posInL = posInL13;
7659  else if ((BTEST1(15)) || (BTEST1(16)))
7660    strat->posInL = posInL15;
7661  else if ((BTEST1(17)) || (BTEST1(18)))
7662    strat->posInL = posInL17;
7663  if (BTEST1(11))
7664    strat->posInT = posInT11;
7665  else if (BTEST1(13))
7666    strat->posInT = posInT13;
7667  else if (BTEST1(15))
7668    strat->posInT = posInT15;
7669  else if ((BTEST1(17)))
7670    strat->posInT = posInT17;
7671  else if ((BTEST1(19)))
7672    strat->posInT = posInT19;
7673  else if (BTEST1(12) || BTEST1(14) || BTEST1(16) || BTEST1(18))
7674    strat->posInT = posInT1;
7675#ifdef HAVE_RINGS
7676  if (rField_is_Ring(currRing))
7677  {
7678    strat->posInL = posInL11;
7679    strat->posInT = posInT11;
7680  }
7681#endif
7682  strat->posInLDependsOnLength = FALSE;
7683  strat->posInLSba  = posInLSig;
7684  //strat->posInL     = posInLSig;
7685  strat->posInL     = posInLF5C;
7686  //strat->posInT     = posInTSig;
7687}
7688
7689void initSbaBuchMora (ideal F,ideal Q,kStrategy strat)
7690{
7691  strat->interpt = BTEST1(OPT_INTERRUPT);
7692  strat->kHEdge=NULL;
7693  if (currRing->OrdSgn==1) strat->kHEdgeFound=FALSE;
7694  /*- creating temp data structures------------------- -*/
7695  strat->cp = 0;
7696  strat->c3 = 0;
7697  strat->tail = pInit();
7698  /*- set s -*/
7699  strat->sl = -1;
7700  /*- set ps -*/
7701  strat->syzl = -1;
7702  /*- set L -*/
7703  strat->Lmax = ((IDELEMS(F)+setmaxLinc-1)/setmaxLinc)*setmaxLinc;
7704  strat->Ll = -1;
7705  strat->L = initL(((IDELEMS(F)+setmaxLinc-1)/setmaxLinc)*setmaxLinc);
7706  /*- set B -*/
7707  strat->Bmax = setmaxL;
7708  strat->Bl = -1;
7709  strat->B = initL();
7710  /*- set T -*/
7711  strat->tl = -1;
7712  strat->tmax = setmaxT;
7713  strat->T = initT();
7714  strat->R = initR();
7715  strat->sevT = initsevT();
7716  /*- init local data struct.---------------------------------------- -*/
7717  strat->P.ecart=0;
7718  strat->P.length=0;
7719  if (currRing->OrdSgn==-1)
7720  {
7721    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
7722    if (strat->kNoether!=NULL) pSetComp(strat->kNoetherTail(), strat->ak);
7723  }
7724  if(TEST_OPT_SB_1)
7725  {
7726    int i;
7727    ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
7728    for (i=strat->newIdeal;i<IDELEMS(F);i++)
7729    {
7730      P->m[i-strat->newIdeal] = F->m[i];
7731      F->m[i] = NULL;
7732    }
7733    initSSpecialSba(F,Q,P,strat);
7734    for (i=strat->newIdeal;i<IDELEMS(F);i++)
7735    {
7736      F->m[i] = P->m[i-strat->newIdeal];
7737      P->m[i-strat->newIdeal] = NULL;
7738    }
7739    idDelete(&P);
7740  }
7741  else
7742  {
7743    /*Shdl=*/initSLSba(F, Q,strat); /*sets also S, ecartS, fromQ */
7744    // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
7745  }
7746  strat->fromT = FALSE;
7747  strat->noTailReduction = !TEST_OPT_REDTAIL;
7748  if (!TEST_OPT_SB_1)
7749  {
7750    updateS(TRUE,strat);
7751  }
7752  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
7753  strat->fromQ=NULL;
7754}
7755
7756void exitSba (kStrategy strat)
7757{
7758  /*- release temp data -*/
7759  cleanT(strat);
7760  omFreeSize(strat->T,(strat->tmax)*sizeof(TObject));
7761  omFreeSize(strat->R,(strat->tmax)*sizeof(TObject*));
7762  omFreeSize(strat->sevT, (strat->tmax)*sizeof(unsigned long));
7763  omFreeSize(strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
7764  omFreeSize(strat->fromS,IDELEMS(strat->Shdl)*sizeof(int));
7765  omFreeSize((ADDRESS)strat->sevS,IDELEMS(strat->Shdl)*sizeof(unsigned long));
7766  omFreeSize((ADDRESS)strat->sevSig,IDELEMS(strat->Shdl)*sizeof(unsigned long));
7767  omFreeSize((ADDRESS)strat->syz,(strat->syzmax)*sizeof(poly));
7768  omFreeSize((ADDRESS)strat->sevSyz,(strat->syzmax)*sizeof(unsigned long));
7769  if (strat->sbaOrder == 1)
7770  {
7771    omFreeSize(strat->syzIdx,(strat->syzidxmax)*sizeof(int));
7772  }
7773  omFreeSize(strat->S_2_R,IDELEMS(strat->Shdl)*sizeof(int));
7774  /*- set L: should be empty -*/
7775  omFreeSize(strat->L,(strat->Lmax)*sizeof(LObject));
7776  /*- set B: should be empty -*/
7777  omFreeSize(strat->B,(strat->Bmax)*sizeof(LObject));
7778  /*- set sig: no need for the signatures anymore -*/
7779  omFreeSize(strat->sig,IDELEMS(strat->Shdl)*sizeof(poly));
7780  pLmDelete(&strat->tail);
7781  strat->syzComp=0;
7782}
7783
7784/*2
7785* in the case of a standardbase of a module over a qring:
7786* replace polynomials in i by ak vectors,
7787* (the polynomial * unit vectors gen(1)..gen(ak)
7788* in every case (also for ideals:)
7789* deletes divisible vectors/polynomials
7790*/
7791void updateResult(ideal r,ideal Q, kStrategy strat)
7792{
7793  int l;
7794  if (strat->ak>0)
7795  {
7796    for (l=IDELEMS(r)-1;l>=0;l--)
7797    {
7798      if ((r->m[l]!=NULL) && (pGetComp(r->m[l])==0))
7799      {
7800        pDelete(&r->m[l]); // and set it to NULL
7801      }
7802    }
7803    int q;
7804    poly p;
7805    for (l=IDELEMS(r)-1;l>=0;l--)
7806    {
7807      if ((r->m[l]!=NULL)
7808      //&& (strat->syzComp>0)
7809      //&& (pGetComp(r->m[l])<=strat->syzComp)
7810      )
7811      {
7812        for(q=IDELEMS(Q)-1; q>=0;q--)
7813        {
7814          if ((Q->m[q]!=NULL)
7815          &&(pLmDivisibleBy(Q->m[q],r->m[l])))
7816          {
7817            if (TEST_OPT_REDSB)
7818            {
7819              p=r->m[l];
7820              r->m[l]=kNF(Q,NULL,p);
7821              pDelete(&p);
7822            }
7823            else
7824            {
7825              pDelete(&r->m[l]); // and set it to NULL
7826            }
7827            break;
7828          }
7829        }
7830      }
7831    }
7832  }
7833  else
7834  {
7835    int q;
7836    poly p;
7837    BOOLEAN reduction_found=FALSE;
7838    for (l=IDELEMS(r)-1;l>=0;l--)
7839    {
7840      if (r->m[l]!=NULL)
7841      {
7842        for(q=IDELEMS(Q)-1; q>=0;q--)
7843        {
7844          if ((Q->m[q]!=NULL)
7845          &&(pLmEqual(r->m[l],Q->m[q])))
7846          {
7847            if (TEST_OPT_REDSB)
7848            {
7849              p=r->m[l];
7850              r->m[l]=kNF(Q,NULL,p);
7851              pDelete(&p);
7852              reduction_found=TRUE;
7853            }
7854            else
7855            {
7856              pDelete(&r->m[l]); // and set it to NULL
7857            }
7858            break;
7859          }
7860        }
7861      }
7862    }
7863    if (/*TEST_OPT_REDSB &&*/ reduction_found)
7864    {
7865      for (l=IDELEMS(r)-1;l>=0;l--)
7866      {
7867        if (r->m[l]!=NULL)
7868        {
7869          for(q=IDELEMS(r)-1;q>=0;q--)
7870          {
7871            if ((l!=q)
7872            && (r->m[q]!=NULL)
7873            &&(pLmDivisibleBy(r->m[l],r->m[q])))
7874            {
7875              pDelete(&r->m[q]);
7876            }
7877          }
7878        }
7879      }
7880    }
7881  }
7882  idSkipZeroes(r);
7883}
7884
7885void completeReduce (kStrategy strat, BOOLEAN withT)
7886{
7887  int i;
7888  int low = (((currRing->OrdSgn==1) && (strat->ak==0)) ? 1 : 0);
7889  LObject L;
7890
7891#ifdef KDEBUG
7892  // need to set this: during tailreductions of T[i], T[i].max is out of
7893  // sync
7894  sloppy_max = TRUE;
7895#endif
7896
7897  strat->noTailReduction = FALSE;
7898  if (TEST_OPT_PROT)
7899  {
7900    PrintLn();
7901    if (timerv) writeTime("standard base computed:");
7902  }
7903  if (TEST_OPT_PROT)
7904  {
7905    Print("(S:%d)",strat->sl);mflush();
7906  }
7907  for (i=strat->sl; i>=low; i--)
7908  {
7909    int end_pos=strat->sl;
7910    if ((strat->fromQ!=NULL) && (strat->fromQ[i])) continue; // do not reduce Q_i
7911    if (strat->ak==0) end_pos=i-1;
7912    TObject* T_j = strat->s_2_t(i);
7913    if ((T_j != NULL)&&(T_j->p==strat->S[i]))
7914    {
7915      L = *T_j;
7916      #ifdef KDEBUG
7917      if (TEST_OPT_DEBUG)
7918      {
7919        Print("test S[%d]:",i);
7920        p_wrp(L.p,currRing,strat->tailRing);
7921        PrintLn();
7922      }
7923      #endif
7924      if (currRing->OrdSgn == 1)
7925        strat->S[i] = redtailBba(&L, end_pos, strat, withT);
7926      else
7927        strat->S[i] = redtail(&L, strat->sl, strat);
7928      #ifdef KDEBUG
7929      if (TEST_OPT_DEBUG)
7930      {
7931        Print("to (tailR) S[%d]:",i);
7932        p_wrp(strat->S[i],currRing,strat->tailRing);
7933        PrintLn();
7934      }
7935      #endif
7936
7937      if (strat->redTailChange && strat->tailRing != currRing)
7938      {
7939        if (T_j->max != NULL) p_LmFree(T_j->max, strat->tailRing);
7940        if (pNext(T_j->p) != NULL)
7941          T_j->max = p_GetMaxExpP(pNext(T_j->p), strat->tailRing);
7942        else
7943          T_j->max = NULL;
7944      }
7945      if (TEST_OPT_INTSTRATEGY)
7946        T_j->pCleardenom();
7947    }
7948    else
7949    {
7950      assume(currRing == strat->tailRing);
7951      #ifdef KDEBUG
7952      if (TEST_OPT_DEBUG)
7953      {
7954        Print("test S[%d]:",i);
7955        p_wrp(strat->S[i],currRing,strat->tailRing);
7956        PrintLn();
7957      }
7958      #endif
7959      if (currRing->OrdSgn == 1)
7960        strat->S[i] = redtailBba(strat->S[i], end_pos, strat, withT);
7961      else
7962        strat->S[i] = redtail(strat->S[i], strat->sl, strat);
7963      if (TEST_OPT_INTSTRATEGY)
7964      {
7965        if (TEST_OPT_CONTENTSB)
7966        {
7967          number n;
7968          p_Cleardenom_n(strat->S[i], currRing, n);// also does a pContent
7969          if (!nIsOne(n))
7970          {
7971            denominator_list denom=(denominator_list)omAlloc(sizeof(denominator_list_s));
7972            denom->n=nInvers(n);
7973            denom->next=DENOMINATOR_LIST;
7974            DENOMINATOR_LIST=denom;
7975          }
7976          nDelete(&n);
7977        }
7978        else
7979        {
7980          //pContent(strat->S[i]);
7981          strat->S[i]=p_Cleardenom(strat->S[i], currRing);// also does a pContent
7982        }
7983      }
7984      #ifdef KDEBUG
7985      if (TEST_OPT_DEBUG)
7986      {
7987        Print("to (-tailR) S[%d]:",i);
7988        p_wrp(strat->S[i],currRing,strat->tailRing);
7989        PrintLn();
7990      }
7991      #endif
7992    }
7993    if (TEST_OPT_PROT)
7994      PrintS("-");
7995  }
7996  if (TEST_OPT_PROT) PrintLn();
7997#ifdef KDEBUG
7998  sloppy_max = FALSE;
7999#endif
8000}
8001
8002
8003/*2
8004* computes the new strat->kHEdge and the new pNoether,
8005* returns TRUE, if pNoether has changed
8006*/
8007BOOLEAN newHEdge(kStrategy strat)
8008{
8009  int i,j;
8010  poly newNoether;
8011
8012#if 0
8013  if (currRing->weight_all_1)
8014    scComputeHC(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
8015  else
8016    scComputeHCw(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
8017#else
8018  scComputeHC(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
8019#endif
8020  if (strat->t_kHEdge != NULL) p_LmFree(strat->t_kHEdge, strat->tailRing);
8021  if (strat->tailRing != currRing)
8022    strat->t_kHEdge = k_LmInit_currRing_2_tailRing(strat->kHEdge, strat->tailRing);
8023  /* compare old and new noether*/
8024  newNoether = pLmInit(strat->kHEdge);
8025  j = p_FDeg(newNoether,currRing);
8026/*  #ifdef HAVE_RINGS
8027  if (!rField_is_Ring(currRing))
8028  #endif */
8029  for (i=1; i<=(currRing->N); i++)
8030  {
8031    if (pGetExp(newNoether, i) > 0) pDecrExp(newNoether,i);
8032  }
8033  pSetm(newNoether);
8034  if (j < strat->HCord) /*- statistics -*/
8035  {
8036    if (TEST_OPT_PROT)
8037    {
8038      Print("H(%d)",j);
8039      mflush();
8040    }
8041    strat->HCord=j;
8042    #ifdef KDEBUG
8043    if (TEST_OPT_DEBUG)
8044    {
8045      Print("H(%d):",j);
8046      wrp(strat->kHEdge);
8047      PrintLn();
8048    }
8049    #endif
8050  }
8051  if (pCmp(strat->kNoether,newNoether)!=1)
8052  {
8053    pDelete(&strat->kNoether);
8054    strat->kNoether=newNoether;
8055    if (strat->t_kNoether != NULL) p_LmFree(strat->t_kNoether, strat->tailRing);
8056    if (strat->tailRing != currRing)
8057      strat->t_kNoether = k_LmInit_currRing_2_tailRing(strat->kNoether, strat->tailRing);
8058
8059    return TRUE;
8060  }
8061  pLmFree(newNoether);
8062  return FALSE;
8063}
8064
8065/***************************************************************
8066 *
8067 * Routines related for ring changes during std computations
8068 *
8069 ***************************************************************/
8070BOOLEAN kCheckSpolyCreation(LObject *L, kStrategy strat, poly &m1, poly &m2)
8071{
8072  if (strat->overflow) return FALSE;
8073  assume(L->p1 != NULL && L->p2 != NULL);
8074  // shift changes: from 0 to -1
8075  assume(L->i_r1 >= -1 && L->i_r1 <= strat->tl);
8076  assume(L->i_r2 >= -1 && L->i_r2 <= strat->tl);
8077  assume(strat->tailRing != currRing);
8078
8079  if (! k_GetLeadTerms(L->p1, L->p2, currRing, m1, m2, strat->tailRing))
8080    return FALSE;
8081  // shift changes: extra case inserted
8082  if ((L->i_r1 == -1) || (L->i_r2 == -1) )
8083  {
8084    return TRUE;
8085  }
8086  poly p1_max = (strat->R[L->i_r1])->max;
8087  poly p2_max = (strat->R[L->i_r2])->max;
8088
8089  if (((p1_max != NULL) && !p_LmExpVectorAddIsOk(m1, p1_max, strat->tailRing)) ||
8090      ((p2_max != NULL) && !p_LmExpVectorAddIsOk(m2, p2_max, strat->tailRing)))
8091  {
8092    p_LmFree(m1, strat->tailRing);
8093    p_LmFree(m2, strat->tailRing);
8094    m1 = NULL;
8095    m2 = NULL;
8096    return FALSE;
8097  }
8098  return TRUE;
8099}
8100
8101#ifdef HAVE_RINGS
8102/***************************************************************
8103 *
8104 * Checks, if we can compute the gcd poly / strong pair
8105 * gcd-poly = m1 * R[atR] + m2 * S[atS]
8106 *
8107 ***************************************************************/
8108BOOLEAN kCheckStrongCreation(int atR, poly m1, int atS, poly m2, kStrategy strat)
8109{
8110  assume(strat->S_2_R[atS] >= -1 && strat->S_2_R[atS] <= strat->tl);
8111  //assume(strat->tailRing != currRing);
8112
8113  poly p1_max = (strat->R[atR])->max;
8114  poly p2_max = (strat->R[strat->S_2_R[atS]])->max;
8115
8116  if (((p1_max != NULL) && !p_LmExpVectorAddIsOk(m1, p1_max, strat->tailRing)) ||
8117      ((p2_max != NULL) && !p_LmExpVectorAddIsOk(m2, p2_max, strat->tailRing)))
8118  {
8119    return FALSE;
8120  }
8121  return TRUE;
8122}
8123#endif
8124
8125BOOLEAN kStratChangeTailRing(kStrategy strat, LObject *L, TObject* T, unsigned long expbound)
8126{
8127  assume((strat->tailRing == currRing) || (strat->tailRing->bitmask < currRing->bitmask));
8128  /* initial setup or extending */
8129
8130  if (expbound == 0) expbound = strat->tailRing->bitmask << 1;
8131  if (expbound >= currRing->bitmask) return FALSE;
8132  strat->overflow=FALSE;
8133  ring new_tailRing = rModifyRing(currRing,
8134  // Hmmm .. the condition pFDeg == p_Deg
8135  // might be too strong
8136#ifdef HAVE_RINGS
8137  (strat->homog && currRing->pFDeg == p_Deg && !(rField_is_Ring(currRing))), // TODO Oliver
8138#else
8139  (strat->homog && currRing->pFDeg == p_Deg), // omit_degree
8140#endif
8141  (strat->ak==0), // omit_comp if the input is an ideal
8142  expbound); // exp_limit
8143
8144  if (new_tailRing == currRing) return TRUE;
8145
8146  strat->pOrigFDeg_TailRing = new_tailRing->pFDeg;
8147  strat->pOrigLDeg_TailRing = new_tailRing->pLDeg;
8148
8149  if (currRing->pFDeg != currRing->pFDegOrig)
8150  {
8151    new_tailRing->pFDeg = currRing->pFDeg;
8152    new_tailRing->pLDeg = currRing->pLDeg;
8153  }
8154
8155  if (TEST_OPT_PROT)
8156    Print("[%lu:%d", (unsigned long) new_tailRing->bitmask, new_tailRing->ExpL_Size);
8157  assume(kTest_TS(strat));
8158  assume(new_tailRing != strat->tailRing);
8159  pShallowCopyDeleteProc p_shallow_copy_delete
8160    = pGetShallowCopyDeleteProc(strat->tailRing, new_tailRing);
8161
8162  omBin new_tailBin = omGetStickyBinOfBin(new_tailRing->PolyBin);
8163
8164  int i;
8165  for (i=0; i<=strat->tl; i++)
8166  {
8167    strat->T[i].ShallowCopyDelete(new_tailRing, new_tailBin,
8168                                  p_shallow_copy_delete);
8169  }
8170  for (i=0; i<=strat->Ll; i++)
8171  {
8172    assume(strat->L[i].p != NULL);
8173    if (pNext(strat->L[i].p) != strat->tail)
8174      strat->L[i].ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
8175  }
8176  if ((strat->P.t_p != NULL) ||
8177      ((strat->P.p != NULL) && pNext(strat->P.p) != strat->tail))
8178    strat->P.ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
8179
8180  if ((L != NULL) && (L->tailRing != new_tailRing))
8181  {
8182    if (L->i_r < 0)
8183      L->ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
8184    else
8185    {
8186      assume(L->i_r <= strat->tl);
8187      TObject* t_l = strat->R[L->i_r];
8188      assume(t_l != NULL);
8189      L->tailRing = new_tailRing;
8190      L->p = t_l->p;
8191      L->t_p = t_l->t_p;
8192      L->max = t_l->max;
8193    }
8194  }
8195
8196  if ((T != NULL) && (T->tailRing != new_tailRing && T->i_r < 0))
8197    T->ShallowCopyDelete(new_tailRing, new_tailBin, p_shallow_copy_delete);
8198
8199  omMergeStickyBinIntoBin(strat->tailBin, strat->tailRing->PolyBin);
8200  if (strat->tailRing != currRing)
8201    rKillModifiedRing(strat->tailRing);
8202
8203  strat->tailRing = new_tailRing;
8204  strat->tailBin = new_tailBin;
8205  strat->p_shallow_copy_delete
8206    = pGetShallowCopyDeleteProc(currRing, new_tailRing);
8207
8208  if (strat->kHEdge != NULL)
8209  {
8210    if (strat->t_kHEdge != NULL)
8211      p_LmFree(strat->t_kHEdge, strat->tailRing);
8212    strat->t_kHEdge=k_LmInit_currRing_2_tailRing(strat->kHEdge, new_tailRing);
8213  }
8214
8215  if (strat->kNoether != NULL)
8216  {
8217    if (strat->t_kNoether != NULL)
8218      p_LmFree(strat->t_kNoether, strat->tailRing);
8219    strat->t_kNoether=k_LmInit_currRing_2_tailRing(strat->kNoether,
8220                                                   new_tailRing);
8221  }
8222  assume(kTest_TS(strat));
8223  if (TEST_OPT_PROT)
8224    PrintS("]");
8225  return TRUE;
8226}
8227
8228void kStratInitChangeTailRing(kStrategy strat)
8229{
8230  unsigned long l = 0;
8231  int i;
8232  long e;
8233
8234  assume(strat->tailRing == currRing);
8235
8236  for (i=0; i<= strat->Ll; i++)
8237  {
8238    l = p_GetMaxExpL(strat->L[i].p, currRing, l);
8239  }
8240  for (i=0; i<=strat->tl; i++)
8241  {
8242    // Hmm ... this we could do in one Step
8243    l = p_GetMaxExpL(strat->T[i].p, currRing, l);
8244  }
8245  if (rField_is_Ring(currRing))
8246  {
8247    l *= 2;
8248  }
8249  e = p_GetMaxExp(l, currRing);
8250  if (e <= 1) e = 2;
8251
8252  kStratChangeTailRing(strat, NULL, NULL, e);
8253}
8254
8255ring sbaRing (kStrategy strat, const ring r, BOOLEAN /*complete*/, int /*sgn*/)
8256{
8257  int n = rBlocks(r); // Including trailing zero!
8258  // if sbaOrder == 1 => use (C,monomial order from r)
8259  if (strat->sbaOrder == 1)
8260  {
8261    if (r->order[0] == ringorder_C || r->order[0] == ringorder_c)
8262    {
8263      return r;
8264    }
8265    ring res = rCopy0(r, FALSE, TRUE);
8266    for (int i=1; i<n-1; i++)
8267    {
8268      res->order[i] = res->order[i-1];
8269      res->block0[i] = res->block0[i-1];
8270      res->block1[i] = res->block1[i-1];
8271      res->wvhdl[i] = res->wvhdl[i-1];
8272    }
8273
8274    // new 1st block
8275    res->order[0]   = ringorder_C; // Prefix
8276    res->block0[0]  = 1;
8277    res->block1[0]  = res->N;
8278    //res->wvhdl[j]   = NULL;
8279    // res->order [j] = 0; // The End!
8280    rComplete(res, 1);
8281#ifdef HAVE_PLURAL
8282    if (rIsPluralRing(r))
8283    {
8284      if ( nc_rComplete(r, res, false) ) // no qideal!
8285      {
8286#ifndef NDEBUG
8287        WarnS("error in nc_rComplete");
8288#endif
8289        // cleanup?
8290
8291        //      rDelete(res);
8292        //      return r;
8293
8294        // just go on..
8295      }
8296    }
8297#endif
8298    strat->tailRing = res;
8299    return (res);
8300  }
8301
8302  // not sbaOrder == 1 => use Schreyer order
8303  // this is done by a trick when initializing the signatures
8304  // in initSLSba():
8305  // Instead of using the signature 1e_i for F->m[i], we start
8306  // with the signature LM(F->m[i])e_i for F->m[i]. Doing this we get a
8307  // Schreyer order w.r.t. the underlying monomial order.
8308  // => we do not need to change the underlying polynomial ring at all!
8309
8310  // UPDATE/NOTE/TODO: use induced Schreyer ordering 'IS'!!!!????
8311
8312  /*
8313  else
8314  {
8315    ring res = rCopy0(r, FALSE, FALSE);
8316    // Create 2 more blocks for prefix/suffix:
8317    res->order=(int *)omAlloc0((n+2)*sizeof(int)); // 0  ..  n+1
8318    res->block0=(int *)omAlloc0((n+2)*sizeof(int));
8319    res->block1=(int *)omAlloc0((n+2)*sizeof(int));
8320    int ** wvhdl =(int **)omAlloc0((n+2)*sizeof(int**));
8321
8322    // Encapsulate all existing blocks between induced Schreyer ordering markers: prefix and suffix!
8323    // Note that prefix and suffix have the same ringorder marker and only differ in block[] parameters!
8324
8325    // new 1st block
8326    int j = 0;
8327    res->order[j] = ringorder_IS; // Prefix
8328    res->block0[j] = res->block1[j] = 0;
8329    // wvhdl[j] = NULL;
8330    j++;
8331
8332    for(int i = 0; (i < n) && (r->order[i] != 0); i++, j++) // i = [0 .. n-1] <- non-zero old blocks
8333    {
8334      res->order [j] = r->order [i];
8335      res->block0[j] = r->block0[i];
8336      res->block1[j] = r->block1[i];
8337
8338      if (r->wvhdl[i] != NULL)
8339      {
8340        wvhdl[j] = (int*) omMemDup(r->wvhdl[i]);
8341      } // else wvhdl[j] = NULL;
8342    }
8343
8344    // new last block
8345    res->order [j] = ringorder_IS; // Suffix
8346    res->block0[j] = res->block1[j] = sgn; // Sign of v[o]: 1 for C, -1 for c
8347    // wvhdl[j] = NULL;
8348    j++;
8349
8350    // res->order [j] = 0; // The End!
8351    res->wvhdl = wvhdl;
8352
8353    // j == the last zero block now!
8354    assume(j == (n+1));
8355    assume(res->order[0]==ringorder_IS);
8356    assume(res->order[j-1]==ringorder_IS);
8357    assume(res->order[j]==0);
8358
8359    if (complete)
8360    {
8361      rComplete(res, 1);
8362
8363#ifdef HAVE_PLURAL
8364      if (rIsPluralRing(r))
8365      {
8366        if ( nc_rComplete(r, res, false) ) // no qideal!
8367        {
8368        }
8369      }
8370      assume(rIsPluralRing(r) == rIsPluralRing(res));
8371#endif
8372
8373
8374#ifdef HAVE_PLURAL
8375      ring old_ring = r;
8376
8377#endif
8378
8379      if (r->qideal!=NULL)
8380      {
8381        res->qideal= idrCopyR_NoSort(r->qideal, r, res);
8382
8383        assume(idRankFreeModule(res->qideal, res) == 0);
8384
8385#ifdef HAVE_PLURAL
8386        if( rIsPluralRing(res) )
8387          if( nc_SetupQuotient(res, r, true) )
8388          {
8389            //          WarnS("error in nc_SetupQuotient"); // cleanup?      rDelete(res);       return r;  // just go on...?
8390          }
8391
8392#endif
8393        assume(idRankFreeModule(res->qideal, res) == 0);
8394      }
8395
8396#ifdef HAVE_PLURAL
8397      assume((res->qideal==NULL) == (old_ring->qideal==NULL));
8398      assume(rIsPluralRing(res) == rIsPluralRing(old_ring));
8399      assume(rIsSCA(res) == rIsSCA(old_ring));
8400      assume(ncRingType(res) == ncRingType(old_ring));
8401#endif
8402    }
8403    strat->tailRing = res;
8404    return res;
8405  }
8406  */
8407
8408  assume(FALSE);
8409  return(NULL);
8410}
8411
8412skStrategy::skStrategy()
8413{
8414  memset(this, 0, sizeof(skStrategy));
8415#ifndef NDEBUG
8416  strat_nr++;
8417  nr=strat_nr;
8418  if (strat_fac_debug) Print("s(%d) created\n",nr);
8419#endif
8420  tailRing = currRing;
8421  P.tailRing = currRing;
8422  tl = -1;
8423  sl = -1;
8424#ifdef HAVE_LM_BIN
8425  lmBin = omGetStickyBinOfBin(currRing->PolyBin);
8426#endif
8427#ifdef HAVE_TAIL_BIN
8428  tailBin = omGetStickyBinOfBin(currRing->PolyBin);
8429#endif
8430  pOrigFDeg = currRing->pFDeg;
8431  pOrigLDeg = currRing->pLDeg;
8432}
8433
8434
8435skStrategy::~skStrategy()
8436{
8437  if (lmBin != NULL)
8438    omMergeStickyBinIntoBin(lmBin, currRing->PolyBin);
8439  if (tailBin != NULL)
8440    omMergeStickyBinIntoBin(tailBin,
8441                            (tailRing != NULL ? tailRing->PolyBin:
8442                             currRing->PolyBin));
8443  if (t_kHEdge != NULL)
8444    p_LmFree(t_kHEdge, tailRing);
8445  if (t_kNoether != NULL)
8446    p_LmFree(t_kNoether, tailRing);
8447
8448  if (currRing != tailRing)
8449    rKillModifiedRing(tailRing);
8450  pRestoreDegProcs(currRing,pOrigFDeg, pOrigLDeg);
8451}
8452
8453#if 0
8454Timings for the different possibilities of posInT:
8455            T15           EDL         DL          EL            L         1-2-3
8456Gonnet      43.26       42.30       38.34       41.98       38.40      100.04
8457Hairer_2_1   1.11        1.15        1.04        1.22        1.08        4.7
8458Twomat3      1.62        1.69        1.70        1.65        1.54       11.32
8459ahml         4.48        4.03        4.03        4.38        4.96       26.50
8460c7          15.02       13.98       15.16       13.24       17.31       47.89
8461c8         505.09      407.46      852.76      413.21      499.19        n/a
8462f855        12.65        9.27       14.97        8.78       14.23       33.12
8463gametwo6    11.47       11.35       14.57       11.20       12.02       35.07
8464gerhard_3    2.73        2.83        2.93        2.64        3.12        6.24
8465ilias13     22.89       22.46       24.62       20.60       23.34       53.86
8466noon8       40.68       37.02       37.99       36.82       35.59      877.16
8467rcyclic_19  48.22       42.29       43.99       45.35       51.51      204.29
8468rkat9       82.37       79.46       77.20       77.63       82.54      267.92
8469schwarz_11  16.46       16.81       16.76       16.81       16.72       35.56
8470test016     16.39       14.17       14.40       13.50       14.26       34.07
8471test017     34.70       36.01       33.16       35.48       32.75       71.45
8472test042     10.76       10.99       10.27       11.57       10.45       23.04
8473test058      6.78        6.75        6.51        6.95        6.22        9.47
8474test066     10.71       10.94       10.76       10.61       10.56       19.06
8475test073     10.75       11.11       10.17       10.79        8.63       58.10
8476test086     12.23       11.81       12.88       12.24       13.37       66.68
8477test103      5.05        4.80        5.47        4.64        4.89       11.90
8478test154     12.96       11.64       13.51       12.46       14.61       36.35
8479test162     65.27       64.01       67.35       59.79       67.54      196.46
8480test164      7.50        6.50        7.68        6.70        7.96       17.13
8481virasoro     3.39        3.50        3.35        3.47        3.70        7.66
8482#endif
8483
8484
8485//#ifdef HAVE_MORE_POS_IN_T
8486#if 1
8487// determines the position based on: 1.) Ecart 2.) FDeg 3.) pLength
8488int posInT_EcartFDegpLength(const TSet set,const int length,LObject &p)
8489{
8490
8491  if (length==-1) return 0;
8492
8493  int o = p.ecart;
8494  int op=p.GetpFDeg();
8495  int ol = p.GetpLength();
8496
8497  if (set[length].ecart < o)
8498    return length+1;
8499  if (set[length].ecart == o)
8500  {
8501     int oo=set[length].GetpFDeg();
8502     if ((oo < op) || ((oo==op) && (set[length].length < ol)))
8503       return length+1;
8504  }
8505
8506  int i;
8507  int an = 0;
8508  int en= length;
8509  loop
8510  {
8511    if (an >= en-1)
8512    {
8513      if (set[an].ecart > o)
8514        return an;
8515      if (set[an].ecart == o)
8516      {
8517         int oo=set[an].GetpFDeg();
8518         if((oo > op)
8519         || ((oo==op) && (set[an].pLength > ol)))
8520           return an;
8521      }
8522      return en;
8523    }
8524    i=(an+en) / 2;
8525    if (set[i].ecart > o)
8526      en=i;
8527    else if (set[i].ecart == o)
8528    {
8529       int oo=set[i].GetpFDeg();
8530       if ((oo > op)
8531       || ((oo == op) && (set[i].pLength > ol)))
8532         en=i;
8533       else
8534        an=i;
8535    }
8536    else
8537      an=i;
8538  }
8539}
8540
8541// determines the position based on: 1.) FDeg 2.) pLength
8542int posInT_FDegpLength(const TSet set,const int length,LObject &p)
8543{
8544
8545  if (length==-1) return 0;
8546
8547  int op=p.GetpFDeg();
8548  int ol = p.GetpLength();
8549
8550  int oo=set[length].GetpFDeg();
8551  if ((oo < op) || ((oo==op) && (set[length].length < ol)))
8552    return length+1;
8553
8554  int i;
8555  int an = 0;
8556  int en= length;
8557  loop
8558    {
8559      if (an >= en-1)
8560      {
8561        int oo=set[an].GetpFDeg();
8562        if((oo > op)
8563           || ((oo==op) && (set[an].pLength > ol)))
8564          return an;
8565        return en;
8566      }
8567      i=(an+en) / 2;
8568      int oo=set[i].GetpFDeg();
8569      if ((oo > op)
8570          || ((oo == op) && (set[i].pLength > ol)))
8571        en=i;
8572      else
8573        an=i;
8574    }
8575}
8576
8577
8578// determines the position based on: 1.) pLength
8579int posInT_pLength(const TSet set,const int length,LObject &p)
8580{
8581  int ol = p.GetpLength();
8582  if (length==-1)
8583    return 0;
8584  if (set[length].length<p.length)
8585    return length+1;
8586
8587  int i;
8588  int an = 0;
8589  int en= length;
8590
8591  loop
8592  {
8593    if (an >= en-1)
8594    {
8595      if (set[an].pLength>ol) return an;
8596      return en;
8597    }
8598    i=(an+en) / 2;
8599    if (set[i].pLength>ol) en=i;
8600    else                        an=i;
8601  }
8602}
8603#endif
8604
8605// kstd1.cc:
8606int redFirst (LObject* h,kStrategy strat);
8607int redEcart (LObject* h,kStrategy strat);
8608void enterSMora (LObject p,int atS,kStrategy strat, int atR=-1);
8609void enterSMoraNF (LObject p,int atS,kStrategy strat, int atR=-1);
8610// ../Singular/misc.cc:
8611extern char *  showOption();
8612
8613void kDebugPrint(kStrategy strat)
8614{
8615  PrintS("red: ");
8616    if (strat->red==redFirst) PrintS("redFirst\n");
8617    else if (strat->red==redHoney) PrintS("redHoney\n");
8618    else if (strat->red==redEcart) PrintS("redEcart\n");
8619    else if (strat->red==redHomog) PrintS("redHomog\n");
8620    else  Print("%p\n",(void*)strat->red);
8621  PrintS("posInT: ");
8622    if (strat->posInT==posInT0) PrintS("posInT0\n");
8623    else if (strat->posInT==posInT0) PrintS("posInT0\n");
8624    else if (strat->posInT==posInT1) PrintS("posInT1\n");
8625    else if (strat->posInT==posInT11) PrintS("posInT11\n");
8626    else if (strat->posInT==posInT110) PrintS("posInT110\n");
8627    else if (strat->posInT==posInT13) PrintS("posInT13\n");
8628    else if (strat->posInT==posInT15) PrintS("posInT15\n");
8629    else if (strat->posInT==posInT17) PrintS("posInT17\n");
8630    else if (strat->posInT==posInT17_c) PrintS("posInT17_c\n");
8631    else if (strat->posInT==posInT19) PrintS("posInT19\n");
8632    else if (strat->posInT==posInT2) PrintS("posInT2\n");
8633#ifdef HAVE_MORE_POS_IN_T
8634    else if (strat->posInT==posInT_EcartFDegpLength) PrintS("posInT_EcartFDegpLength\n");
8635    else if (strat->posInT==posInT_FDegpLength) PrintS("posInT_FDegpLength\n");
8636    else if (strat->posInT==posInT_pLength) PrintS("posInT_pLength\n");
8637#endif
8638    else if (strat->posInT==posInT_EcartpLength) PrintS("posInT_EcartpLength\n");
8639    else if (strat->posInT==posInTrg0) PrintS("posInTrg0\n");
8640    else  Print("%p\n",(void*)strat->posInT);
8641  PrintS("posInL: ");
8642    if (strat->posInL==posInL0) PrintS("posInL0\n");
8643    else if (strat->posInL==posInL10) PrintS("posInL10\n");
8644    else if (strat->posInL==posInL11) PrintS("posInL11\n");
8645    else if (strat->posInL==posInL110) PrintS("posInL110\n");
8646    else if (strat->posInL==posInL13) PrintS("posInL13\n");
8647    else if (strat->posInL==posInL15) PrintS("posInL15\n");
8648    else if (strat->posInL==posInL17) PrintS("posInL17\n");
8649    else if (strat->posInL==posInL17_c) PrintS("posInL17_c\n");
8650    else if (strat->posInL==posInLSpecial) PrintS("posInLSpecial\n");
8651    else if (strat->posInL==posInLrg0) PrintS("posInLrg0\n");
8652    else  Print("%p\n",(void*)strat->posInL);
8653  PrintS("enterS: ");
8654    if (strat->enterS==enterSBba) PrintS("enterSBba\n");
8655    else if (strat->enterS==enterSMora) PrintS("enterSMora\n");
8656    else if (strat->enterS==enterSMoraNF) PrintS("enterSMoraNF\n");
8657    else  Print("%p\n",(void*)strat->enterS);
8658  PrintS("initEcart: ");
8659    if (strat->initEcart==initEcartBBA) PrintS("initEcartBBA\n");
8660    else if (strat->initEcart==initEcartNormal) PrintS("initEcartNormal\n");
8661    else  Print("%p\n",(void*)strat->initEcart);
8662  PrintS("initEcartPair: ");
8663    if (strat->initEcartPair==initEcartPairBba) PrintS("initEcartPairBba\n");
8664    else if (strat->initEcartPair==initEcartPairMora) PrintS("initEcartPairMora\n");
8665    else  Print("%p\n",(void*)strat->initEcartPair);
8666  Print("homog=%d, LazyDegree=%d, LazyPass=%d, ak=%d,\n",
8667         strat->homog, strat->LazyDegree,strat->LazyPass, strat->ak);
8668  Print("honey=%d, sugarCrit=%d, Gebauer=%d, noTailReduction=%d, use_buckets=%d\n",
8669         strat->honey,strat->sugarCrit,strat->Gebauer,strat->noTailReduction,strat->use_buckets);
8670  Print("posInLDependsOnLength=%d\n",
8671         strat->posInLDependsOnLength);
8672  PrintS(showOption());PrintLn();
8673  PrintS("LDeg: ");
8674    if (currRing->pLDeg==pLDeg0) PrintS("pLDeg0");
8675    else if (currRing->pLDeg==pLDeg0c) PrintS("pLDeg0c");
8676    else if (currRing->pLDeg==pLDegb) PrintS("pLDegb");
8677    else if (currRing->pLDeg==pLDeg1) PrintS("pLDeg1");
8678    else if (currRing->pLDeg==pLDeg1c) PrintS("pLDeg1c");
8679    else if (currRing->pLDeg==pLDeg1_Deg) PrintS("pLDeg1_Deg");
8680    else if (currRing->pLDeg==pLDeg1c_Deg) PrintS("pLDeg1c_Deg");
8681    else if (currRing->pLDeg==pLDeg1_Totaldegree) PrintS("pLDeg1_Totaldegree");
8682    else if (currRing->pLDeg==pLDeg1c_Totaldegree) PrintS("pLDeg1c_Totaldegree");
8683    else if (currRing->pLDeg==pLDeg1_WFirstTotalDegree) PrintS("pLDeg1_WFirstTotalDegree");
8684    else if (currRing->pLDeg==pLDeg1c_WFirstTotalDegree) PrintS("pLDeg1c_WFirstTotalDegree");
8685    else if (currRing->pLDeg==maxdegreeWecart) PrintS("maxdegreeWecart");
8686    else Print("? (%lx)", (long)currRing->pLDeg);
8687    PrintS(" / ");
8688    if (strat->tailRing->pLDeg==pLDeg0) PrintS("pLDeg0");
8689    else if (strat->tailRing->pLDeg==pLDeg0c) PrintS("pLDeg0c");
8690    else if (strat->tailRing->pLDeg==pLDegb) PrintS("pLDegb");
8691    else if (strat->tailRing->pLDeg==pLDeg1) PrintS("pLDeg1");
8692    else if (strat->tailRing->pLDeg==pLDeg1c) PrintS("pLDeg1c");
8693    else if (strat->tailRing->pLDeg==pLDeg1_Deg) PrintS("pLDeg1_Deg");
8694    else if (strat->tailRing->pLDeg==pLDeg1c_Deg) PrintS("pLDeg1c_Deg");
8695    else if (strat->tailRing->pLDeg==pLDeg1_Totaldegree) PrintS("pLDeg1_Totaldegree");
8696    else if (strat->tailRing->pLDeg==pLDeg1c_Totaldegree) PrintS("pLDeg1c_Totaldegree");
8697    else if (strat->tailRing->pLDeg==pLDeg1_WFirstTotalDegree) PrintS("pLDeg1_WFirstTotalDegree");
8698    else if (strat->tailRing->pLDeg==pLDeg1c_WFirstTotalDegree) PrintS("pLDeg1c_WFirstTotalDegree");
8699    else if (strat->tailRing->pLDeg==maxdegreeWecart) PrintS("maxdegreeWecart");
8700    else Print("? (%lx)", (long)strat->tailRing->pLDeg);
8701    PrintLn();
8702  PrintS("currRing->pFDeg: ");
8703    if (currRing->pFDeg==p_Totaldegree) PrintS("p_Totaldegree");
8704    else if (currRing->pFDeg==p_WFirstTotalDegree) PrintS("pWFirstTotalDegree");
8705    else if (currRing->pFDeg==p_Deg) PrintS("p_Deg");
8706    else if (currRing->pFDeg==kHomModDeg) PrintS("kHomModDeg");
8707    else if (currRing->pFDeg==totaldegreeWecart) PrintS("totaldegreeWecart");
8708    else if (currRing->pFDeg==p_WTotaldegree) PrintS("p_WTotaldegree");
8709    else Print("? (%lx)", (long)currRing->pFDeg);
8710    PrintLn();
8711    Print(" syzring:%d, syzComp(strat):%d limit:%d\n",rIsSyzIndexRing(currRing),strat->syzComp,rGetCurrSyzLimit(currRing));
8712    if(TEST_OPT_DEGBOUND)
8713      Print(" degBound: %d\n", Kstd1_deg);
8714
8715    if( ecartWeights != NULL )
8716    {
8717       PrintS("ecartWeights: ");
8718       for (int i = rVar(currRing); i > 0; i--)
8719         Print("%hd ", ecartWeights[i]);
8720       PrintLn();
8721       assume( TEST_OPT_WEIGHTM );
8722    }
8723
8724#ifndef NDEBUG
8725    rDebugPrint(currRing);
8726#endif
8727}
8728
8729
8730#ifdef HAVE_SHIFTBBA
8731poly pMove2CurrTail(poly p, kStrategy strat)
8732{
8733  /* assume: p is completely in currRing */
8734  /* produces an object with LM in curring
8735     and TAIL in tailring */
8736  if (pNext(p)!=NULL)
8737  {
8738    pNext(p) = prMoveR(pNext(p), /* src */ currRing, /* dest */ strat->tailRing);
8739  }
8740  return(p);
8741}
8742#endif
8743
8744#ifdef HAVE_SHIFTBBA
8745poly pMoveCurrTail2poly(poly p, kStrategy strat)
8746{
8747  /* assume: p has  LM in curring and TAIL in tailring */
8748  /* convert it to complete currRing */
8749
8750  /* check that LM is in currRing */
8751  assume(p_LmCheckIsFromRing(p, currRing));
8752
8753  if (pNext(p)!=NULL)
8754  {
8755    pNext(p) = prMoveR(pNext(p), /* src */ strat->tailRing, /* dest */currRing);
8756  }
8757  return(p);
8758}
8759#endif
8760
8761#ifdef HAVE_SHIFTBBA
8762poly pCopyL2p(LObject H, kStrategy strat)
8763{
8764    /* restores a poly in currRing from LObject */
8765    LObject h = H;
8766    h.Copy();
8767    poly p;
8768    if (h.p == NULL)
8769    {
8770      if (h.t_p != NULL)
8771      {
8772         p = prMoveR(h.t_p, /* source ring: */ strat->tailRing, /* dest. ring: */ currRing);
8773        return(p);
8774      }
8775      else
8776      {
8777        /* h.tp == NULL -> the object is NULL */
8778        return(NULL);
8779      }
8780    }
8781    /* we're here if h.p != NULL */
8782    if (h.t_p == NULL)
8783    {
8784       /* then h.p is the whole poly in currRing */
8785       p = h.p;
8786      return(p);
8787    }
8788    /* we're here if h.p != NULL and h.t_p != NULL */
8789    // clean h.p, get poly from t_p
8790     pNext(h.p)=NULL;
8791     pDelete(&h.p);
8792     p = prMoveR(h.t_p, /* source ring: */ strat->tailRing,
8793                         /* dest. ring: */ currRing);
8794     // no need to clean h: we re-used the polys
8795    return(p);
8796}
8797#endif
8798
8799//LObject pCopyp2L(poly p, kStrategy strat)
8800//{
8801    /* creates LObject from the poly in currRing */
8802  /* actually put p into L.p and make L.t_p=NULL : does not work */
8803
8804//}
8805
8806// poly pCopyL2p(LObject H, kStrategy strat)
8807// {
8808//   /* restores a poly in currRing from LObject */
8809//   LObject h = H;
8810//   h.Copy();
8811//   poly p;
8812//   if (h.p == NULL)
8813//   {
8814//     if (h.t_p != NULL)
8815//     {
8816//       p = p_ShallowCopyDelete(h.t_p, (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
8817//       return(p);
8818//     }
8819//     else
8820//     {
8821//       /* h.tp == NULL -> the object is NULL */
8822//       return(NULL);
8823//     }
8824//   }
8825//   /* we're here if h.p != NULL */
8826
8827//   if (h.t_p == NULL)
8828//   {
8829//     /* then h.p is the whole poly in tailRing */
8830//     if (strat->tailBin != NULL && (pNext(h.p) != NULL))
8831//     {
8832//       p = p_ShallowCopyDelete(h.p, (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
8833//     }
8834//     return(p);
8835//   }
8836//   /* we're here if h.p != NULL and h.t_p != NULL */
8837//   p = pCopy(pHead(h.p)); // in currRing
8838//   if (strat->tailBin != NULL && (pNext(h.p) != NULL))
8839//   {
8840//     //    pNext(p) = p_ShallowCopyDelete(pNext(h.t_p), (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
8841//     poly pp = p_Copy(pNext(h.p), strat->tailRing);
8842//     //    poly p3 = p_Copy(pNext(h.p), currRing); // error
8843//       // p_ShallowCopyDelete(pNext(h.p), currRing, strat->tailBin); // the same as pp
8844//     poly p5 = p_ShallowCopyDelete(pNext(h.p), strat->tailRing, strat->tailBin);
8845//     pNext(p) = p_ShallowCopyDelete(h.t_p, strat->tailRing, strat->tailBin);
8846//     poly p4 = p_Copy(h.t_p, strat->tailRing);
8847//     //    if (p.t_p != NULL) pNext(p.t_p) = pNext(p.p);
8848//   }
8849//   //  pTest(p);
8850//   return(p);
8851// }
8852
8853#ifdef HAVE_SHIFTBBA
8854/* including the self pairs */
8855void updateSShift(kStrategy strat,int uptodeg,int lV)
8856{
8857  /* to use after updateS(toT=FALSE,strat) */
8858  /* fills T with shifted elt's of S */
8859  int i;
8860  LObject h;
8861  int atT = -1; // or figure out smth better
8862  strat->tl = -1; // init
8863  for (i=0; i<=strat->sl; i++)
8864  {
8865    memset(&h,0,sizeof(h));
8866    h.p =  strat->S[i]; // lm in currRing, tail in TR
8867    strat->initEcart(&h);
8868    h.sev = strat->sevS[i];
8869    h.t_p = NULL;
8870    h.GetTP(); // creates correct t_p
8871    /*puts the elements of S with their shifts to T*/
8872    //    int atT, int uptodeg, int lV)
8873    strat->S_2_R[i] = strat->tl + 1; // the el't with shift 0 will be inserted first
8874    // need a small check for above; we insert >=1 elements
8875    // insert this check into kTest_TS ?
8876    enterTShift(h,strat,atT,uptodeg,lV);
8877  }
8878  /* what about setting strat->tl? */
8879}
8880#endif
8881
8882#ifdef HAVE_SHIFTBBA
8883void initBuchMoraShift (ideal F,ideal Q,kStrategy strat)
8884{
8885  strat->interpt = BTEST1(OPT_INTERRUPT);
8886  strat->kHEdge=NULL;
8887  if (currRing->OrdSgn==1) strat->kHEdgeFound=FALSE;
8888  /*- creating temp data structures------------------- -*/
8889  strat->cp = 0;
8890  strat->c3 = 0;
8891  strat->cv = 0;
8892  strat->tail = pInit();
8893  /*- set s -*/
8894  strat->sl = -1;
8895  /*- set L -*/
8896  strat->Lmax = setmaxL;
8897  strat->Ll = -1;
8898  strat->L = initL();
8899  /*- set B -*/
8900  strat->Bmax = setmaxL;
8901  strat->Bl = -1;
8902  strat->B = initL();
8903  /*- set T -*/
8904  strat->tl = -1;
8905  strat->tmax = setmaxT;
8906  strat->T = initT();
8907  strat->R = initR();
8908  strat->sevT = initsevT();
8909  /*- init local data struct.---------------------------------------- -*/
8910  strat->P.ecart=0;
8911  strat->P.length=0;
8912  if (currRing->OrdSgn==-1)
8913  {
8914    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
8915    if (strat->kNoether!=NULL) pSetComp(strat->kNoetherTail(), strat->ak);
8916  }
8917  if(TEST_OPT_SB_1)
8918  {
8919    int i;
8920    ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
8921    for (i=strat->newIdeal;i<IDELEMS(F);i++)
8922    {
8923      P->m[i-strat->newIdeal] = F->m[i];
8924      F->m[i] = NULL;
8925    }
8926    initSSpecial(F,Q,P,strat);
8927    for (i=strat->newIdeal;i<IDELEMS(F);i++)
8928    {
8929      F->m[i] = P->m[i-strat->newIdeal];
8930      P->m[i-strat->newIdeal] = NULL;
8931    }
8932    idDelete(&P);
8933  }
8934  else
8935  {
8936    /*Shdl=*/initSL(F, Q,strat); /*sets also S, ecartS, fromQ */
8937    // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
8938  }
8939  strat->fromT = FALSE;
8940  strat->noTailReduction = !TEST_OPT_REDTAIL;
8941  if (!TEST_OPT_SB_1)
8942  {
8943    /* the only change: we do not fill the set T*/
8944    updateS(FALSE,strat);
8945  }
8946  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
8947  strat->fromQ=NULL;
8948  /* more changes: fill the set T with all the shifts of elts of S*/
8949  /* is done by other procedure */
8950}
8951#endif
8952
8953#ifdef HAVE_SHIFTBBA
8954/*1
8955* put the pairs (sh \dot s[i],p)  into the set B, ecart=ecart(p)
8956*/
8957void enterOnePairManyShifts (int i, poly p, int ecart, int isFromQ, kStrategy strat, int /*atR*/, int uptodeg, int lV)
8958{
8959  /* p comes from strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
8960
8961  assume(p_LmCheckIsFromRing(p,currRing));
8962  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
8963
8964  /* cycles through all shifts of s[i] until uptodeg - lastVblock(s[i]) */
8965  /* that is create the pairs (f, s \dot g)  */
8966
8967  poly qq = strat->S[i]; //  lm in currRing, tail in tailRing
8968
8969  //  poly q = pCopy(pHead(strat->S[i])); // lm in currRing
8970  //  pNext(q) = prCopyR(pNext(strat->S[i]),strat->tailRing,currRing); // zero shift
8971
8972 /* determine how many elements we have to insert for a given s[i] */
8973  /* x(0)y(1)z(2) : lastVblock-1=2, to add until lastVblock=uptodeg-1 */
8974  /* hence, a total number of elt's to add is: */
8975  /*  int toInsert = 1 + (uptodeg-1) - (pLastVblock(p.p, lV) -1);  */
8976  int toInsert =  itoInsert(qq, uptodeg,  lV, strat->tailRing);
8977
8978#ifdef KDEBUG
8979    if (TEST_OPT_DEBUG)
8980    {
8981      //      Print("entered ManyShifts: with toInsert=%d",toInsert); PrintLn();
8982    }
8983#endif
8984
8985  assume(i<=strat->sl); // from OnePair
8986  if (strat->interred_flag) return; // ?
8987
8988  /* these vars hold for all shifts of s[i] */
8989  int ecartq = 0; //Hans says it's ok; we're in the homog case, no ecart
8990
8991  int qfromQ;
8992  if (strat->fromQ != NULL)
8993  {
8994    qfromQ = strat->fromQ[i];
8995  }
8996  else
8997  {
8998    qfromQ = -1;
8999  }
9000
9001  int j;
9002
9003  poly q/*, s*/;
9004
9005  // for the 0th shift: insert the orig. pair
9006  enterOnePairShift(qq, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, 0, i, uptodeg, lV);
9007
9008  for (j=1; j<= toInsert; j++)
9009  {
9010    //    q = pLPshift(strat->S[i],j,uptodeg,lV);
9011    q = p_LPshiftT(qq, j, uptodeg, lV, strat, currRing);
9012    //    q = p_mLPshift(qq,j,uptodeg,lV,currRing); // lm in currRing, shift this monomial
9013    //    s = p_LPshift(pNext(qq), j, uptodeg, lV, strat->tailRing); // from tailRing
9014    //    pNext(q) = s; // in tailRing
9015    /* here we need to call enterOnePair with two polys ... */
9016
9017#ifdef KDEBUG
9018    if (TEST_OPT_DEBUG)
9019    {
9020      //      PrintS("ManyShifts: calling enterOnePairShift(q,p)");      PrintLn();
9021    }
9022#endif
9023    enterOnePairShift(q, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, j, i, uptodeg, lV);
9024  }
9025}
9026#endif
9027
9028#ifdef HAVE_SHIFTBBA
9029/*1
9030* put the pairs (sh \dot qq,p)  into the set B, ecart=ecart(p)
9031* despite the name, not only self shifts
9032*/
9033void enterOnePairSelfShifts (poly qq, poly p, int ecart, int isFromQ, kStrategy strat, int /*atR*/, int uptodeg, int lV)
9034{
9035
9036  /* format: p,qq are in LObject form: lm in CR, tail in TR */
9037  /* for true self pairs qq ==p  */
9038  /* we test both qq and p */
9039  assume(p_LmCheckIsFromRing(qq,currRing));
9040  assume(p_CheckIsFromRing(pNext(qq),strat->tailRing));
9041  assume(p_LmCheckIsFromRing(p,currRing));
9042  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
9043
9044  /* since this proc is applied twice for (h, s*g) and (g,s*h), init j with 1 only */
9045
9046  //  int j = 0;
9047  int j = 1;
9048
9049  /* for such self pairs start with 1, not with 0 */
9050  if (qq == p) j=1;
9051
9052  /* should cycle through all shifts of q until uptodeg - lastVblock(q) */
9053  /* that is create the pairs (f, s \dot g)  */
9054
9055  int toInsert =  itoInsert(qq, uptodeg,  lV, strat->tailRing);
9056
9057#ifdef KDEBUG
9058    if (TEST_OPT_DEBUG)
9059    {
9060      //      Print("entered SelfShifts: with toInsert=%d",toInsert); PrintLn();
9061    }
9062#endif
9063
9064  poly q;
9065
9066  if (strat->interred_flag) return; // ?
9067
9068  /* these vars hold for all shifts of s[i] */
9069  int ecartq = 0; //Hans says it's ok; we're in the homog case, no ecart
9070  int qfromQ = 0; // strat->fromQ[i];
9071
9072  for (; j<= toInsert; j++)
9073  {
9074    //    q = pLPshift(strat->S[i],j,uptodeg,lV);
9075    /* we increase shifts by one; must delete q there*/
9076    //    q = qq; q = pMoveCurrTail2poly(q,strat);
9077    //    q = pLPshift(q,j,uptodeg,lV); //,currRing);
9078    q = p_LPshiftT(qq, j, uptodeg, lV, strat, currRing);
9079    //    q = p_mLPshift(qq,j,uptodeg,lV,currRing); // lm in currRing, shift this monomial
9080    //    s = p_LPshift(pNext(qq), j, uptodeg, lV, strat->tailRing); // from tailRing
9081    //    pNext(q) = s; // in tailRing
9082    /* here we need to call enterOnePair with two polys ... */
9083#ifdef KDEBUG
9084    if (TEST_OPT_DEBUG)
9085    {
9086      //      PrintS("SelfShifts: calling enterOnePairShift(q,p)");      PrintLn();
9087    }
9088#endif
9089    enterOnePairShift(q, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, j, -1, uptodeg, lV);
9090  }
9091}
9092#endif
9093
9094#ifdef HAVE_SHIFTBBA
9095/*2
9096* put the pair (q,p)  into the set B, ecart=ecart(p), q is the shift of some s[i]
9097*/
9098void 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)
9099{
9100
9101  /* Format: q and p are like strat->P.p, so lm in CR, tail in TR */
9102
9103  /* check this Formats: */
9104  assume(p_LmCheckIsFromRing(q,currRing));
9105  assume(p_CheckIsFromRing(pNext(q),strat->tailRing));
9106  assume(p_LmCheckIsFromRing(p,currRing));
9107  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
9108
9109#ifdef KDEBUG
9110    if (TEST_OPT_DEBUG)
9111    {
9112//       PrintS("enterOnePairShift(q,p) invoked with q = ");
9113//       wrp(q); //      wrp(pHead(q));
9114//       PrintS(", p = ");
9115//       wrp(p); //wrp(pHead(p));
9116//       PrintLn();
9117    }
9118#endif
9119
9120  /* poly q stays for s[i], ecartq = ecart(q), qisFromQ = applies to q */
9121
9122  int qfromQ = qisFromQ;
9123
9124  /* need additionally: int up_to_degree, poly V0 with the variables in (0)  or just the number lV = the length of the first block */
9125
9126  if (strat->interred_flag) return;
9127
9128  int      l,j,compare;
9129  LObject  Lp;
9130  Lp.i_r = -1;
9131
9132#ifdef KDEBUG
9133  Lp.ecart=0; Lp.length=0;
9134#endif
9135  /*- computes the lcm(s[i],p) -*/
9136  Lp.lcm = pInit();
9137
9138  pLcm(p,q, Lp.lcm); // q is what was strat->S[i], so a poly in LM/TR presentation
9139  pSetm(Lp.lcm);
9140
9141  /* apply the V criterion */
9142  if (!isInV(Lp.lcm, lV))
9143  {
9144#ifdef KDEBUG
9145    if (TEST_OPT_DEBUG)
9146    {
9147      PrintS("V crit applied to q = ");
9148      wrp(q); //      wrp(pHead(q));
9149      PrintS(", p = ");
9150      wrp(p); //wrp(pHead(p));
9151      PrintLn();
9152    }
9153#endif
9154    pLmFree(Lp.lcm);
9155    Lp.lcm=NULL;
9156    /* + counter for applying the V criterion */
9157    strat->cv++;
9158    return;
9159  }
9160
9161  if (strat->sugarCrit && ALLOW_PROD_CRIT(strat))
9162  {
9163    if((!((ecartq>0)&&(ecart>0)))
9164    && pHasNotCF(p,q))
9165    {
9166    /*
9167    *the product criterion has applied for (s,p),
9168    *i.e. lcm(s,p)=product of the leading terms of s and p.
9169    *Suppose (s,r) is in L and the leading term
9170    *of p divides lcm(s,r)
9171    *(==> the leading term of p divides the leading term of r)
9172    *but the leading term of s does not divide the leading term of r
9173    *(notice that this condition is automatically satisfied if r is still
9174    *in S), then (s,r) can be cancelled.
9175    *This should be done here because the
9176    *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
9177    *
9178    *Moreover, skipping (s,r) holds also for the noncommutative case.
9179    */
9180      strat->cp++;
9181      pLmFree(Lp.lcm);
9182      Lp.lcm=NULL;
9183      return;
9184    }
9185    else
9186      Lp.ecart = si_max(ecart,ecartq);
9187    if (strat->fromT && (ecartq>ecart))
9188    {
9189      pLmFree(Lp.lcm);
9190      Lp.lcm=NULL;
9191      return;
9192      /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
9193    }
9194    /*
9195    *the set B collects the pairs of type (S[j],p)
9196    *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
9197    *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
9198    *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
9199    */
9200    {
9201      j = strat->Bl;
9202      loop
9203      {
9204        if (j < 0)  break;
9205        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
9206        if ((compare==1)
9207        &&(sugarDivisibleBy(strat->B[j].ecart,Lp.ecart)))
9208        {
9209          strat->c3++;
9210          if ((strat->fromQ==NULL) || (isFromQ==0) || (qfromQ==0))
9211          {
9212            pLmFree(Lp.lcm);
9213            return;
9214          }
9215          break;
9216        }
9217        else
9218        if ((compare ==-1)
9219        && sugarDivisibleBy(Lp.ecart,strat->B[j].ecart))
9220        {
9221          deleteInL(strat->B,&strat->Bl,j,strat);
9222          strat->c3++;
9223        }
9224        j--;
9225      }
9226    }
9227  }
9228  else /*sugarcrit*/
9229  {
9230    if (ALLOW_PROD_CRIT(strat))
9231    {
9232      // if currRing->nc_type!=quasi (or skew)
9233      // TODO: enable productCrit for super commutative algebras...
9234      if(/*(strat->ak==0) && productCrit(p,strat->S[i])*/
9235      pHasNotCF(p,q))
9236      {
9237      /*
9238      *the product criterion has applied for (s,p),
9239      *i.e. lcm(s,p)=product of the leading terms of s and p.
9240      *Suppose (s,r) is in L and the leading term
9241      *of p devides lcm(s,r)
9242      *(==> the leading term of p devides the leading term of r)
9243      *but the leading term of s does not devide the leading term of r
9244      *(notice that tis condition is automatically satisfied if r is still
9245      *in S), then (s,r) can be canceled.
9246      *This should be done here because the
9247      *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
9248      */
9249          strat->cp++;
9250          pLmFree(Lp.lcm);
9251          Lp.lcm=NULL;
9252          return;
9253      }
9254      if (strat->fromT && (ecartq>ecart))
9255      {
9256        pLmFree(Lp.lcm);
9257        Lp.lcm=NULL;
9258        return;
9259        /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
9260      }
9261      /*
9262      *the set B collects the pairs of type (S[j],p)
9263      *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
9264      *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
9265      *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
9266      */
9267      for(j = strat->Bl;j>=0;j--)
9268      {
9269        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
9270        if (compare==1)
9271        {
9272          strat->c3++;
9273          if ((strat->fromQ==NULL) || (isFromQ==0) || (qfromQ==0))
9274          {
9275            pLmFree(Lp.lcm);
9276            return;
9277          }
9278          break;
9279        }
9280        else
9281        if (compare ==-1)
9282        {
9283          deleteInL(strat->B,&strat->Bl,j,strat);
9284          strat->c3++;
9285        }
9286      }
9287    }
9288  }
9289  /*
9290  *the pair (S[i],p) enters B if the spoly != 0
9291  */
9292  /*-  compute the short s-polynomial -*/
9293  if (strat->fromT && !TEST_OPT_INTSTRATEGY)
9294    pNorm(p);
9295  if ((q==NULL) || (p==NULL))
9296    return;
9297  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (qfromQ!=0))
9298    Lp.p=NULL;
9299  else
9300  {
9301//     if ( rIsPluralRing(currRing) )
9302//     {
9303//       if(pHasNotCF(p, q))
9304//       {
9305//         if(ncRingType(currRing) == nc_lie)
9306//         {
9307//             // generalized prod-crit for lie-type
9308//             strat->cp++;
9309//             Lp.p = nc_p_Bracket_qq(pCopy(p),q, currRing);
9310//         }
9311//         else
9312//         if( ALLOW_PROD_CRIT(strat) )
9313//         {
9314//             // product criterion for homogeneous case in SCA
9315//             strat->cp++;
9316//             Lp.p = NULL;
9317//         }
9318//         else
9319//           Lp.p = nc_CreateSpoly(q,p,currRing); // ?
9320//       }
9321//       else  Lp.p = nc_CreateSpoly(q,p,currRing);
9322//     }
9323//     else
9324//     {
9325
9326    /* ksCreateShortSpoly needs two Lobject-kind presentations */
9327    /* p is already in this form, so convert q */
9328    //    q = pMove2CurrTail(q, strat);
9329    Lp.p = ksCreateShortSpoly(q, p, strat->tailRing);
9330      //  }
9331  }
9332  if (Lp.p == NULL)
9333  {
9334    /*- the case that the s-poly is 0 -*/
9335    /* TEMPORARILY DISABLED FOR SHIFTS because there is no i*/
9336//      if (strat->pairtest==NULL) initPairtest(strat);
9337//      strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
9338//      strat->pairtest[strat->sl+1] = TRUE;
9339    /* END _ TEMPORARILY DISABLED FOR SHIFTS */
9340    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
9341    /*
9342    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
9343    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
9344    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
9345    *term of p devides the lcm(s,r)
9346    *(this canceling should be done here because
9347    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
9348    *the first case is handeled in chainCrit
9349    */
9350    if (Lp.lcm!=NULL) pLmFree(Lp.lcm);
9351  }
9352  else
9353  {
9354    /*- the pair (S[i],p) enters B -*/
9355    /* both of them should have their LM in currRing and TAIL in tailring */
9356    Lp.p1 = q;  // already in the needed form
9357    Lp.p2 = p; // already in the needed form
9358
9359    if ( !rIsPluralRing(currRing) )
9360      pNext(Lp.p) = strat->tail;
9361
9362    /* TEMPORARILY DISABLED FOR SHIFTS because there's no i*/
9363    /* at the beginning we DO NOT set atR = -1 ANYMORE*/
9364    if ( (atR >= 0) && (shiftcount==0) && (ifromS >=0) )
9365    {
9366      Lp.i_r1 = kFindInT(Lp.p1,strat); //strat->S_2_R[ifromS];
9367      Lp.i_r2 = atR;
9368    }
9369    else
9370    {
9371      /* END _ TEMPORARILY DISABLED FOR SHIFTS */
9372      Lp.i_r1 = -1;
9373      Lp.i_r2 = -1;
9374     }
9375    strat->initEcartPair(&Lp,q,p,ecartq,ecart);
9376
9377    if (TEST_OPT_INTSTRATEGY)
9378    {
9379      if (!rIsPluralRing(currRing))
9380        nDelete(&(Lp.p->coef));
9381    }
9382
9383    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
9384    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
9385  }
9386}
9387#endif
9388
9389#ifdef HAVE_SHIFTBBA
9390/*2
9391*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
9392*superfluous elements in S will be deleted
9393*/
9394void enterpairsShift (poly h,int k,int ecart,int pos,kStrategy strat, int atR,int uptodeg, int lV)
9395{
9396  /* h is strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
9397  /* Q: what is exactly the strat->fromT ? A: a local case trick; don't need it yet*/
9398  int j=pos;
9399
9400#ifdef HAVE_RINGS
9401  assume (!rField_is_Ring(currRing));
9402#endif
9403  initenterpairsShift(h,k,ecart,0,strat, atR,uptodeg,lV);
9404  if ( (!strat->fromT)
9405  && ((strat->syzComp==0)
9406    ||(pGetComp(h)<=strat->syzComp)))
9407  {
9408    //Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
9409    unsigned long h_sev = pGetShortExpVector(h);
9410    loop
9411    {
9412      if (j > k) break;
9413      clearS(h,h_sev, &j,&k,strat);
9414      j++;
9415    }
9416    //Print("end clearS sl=%d\n",strat->sl);
9417  }
9418 // PrintS("end enterpairs\n");
9419}
9420#endif
9421
9422#ifdef HAVE_SHIFTBBA
9423/*3
9424*(s[0], s \dot h),...,(s[k],s \dot h) will be put to the pairset L
9425* also the pairs (h, s\dot s[0]), ..., (h, s\dot s[k]) enter L
9426* additionally we put the pairs (h, s \sdot h) for s>=1 to L
9427*/
9428void initenterpairsShift (poly h,int k,int ecart,int isFromQ, kStrategy strat, int atR, int uptodeg, int lV)
9429{
9430  /* h comes from strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
9431  //  atR = -1;
9432  if ((strat->syzComp==0)
9433  || (pGetComp(h)<=strat->syzComp))
9434  {
9435    int j;
9436    BOOLEAN new_pair=FALSE;
9437
9438    if (pGetComp(h)==0)
9439    {
9440      /* for Q!=NULL: build pairs (f,q),(f1,f2), but not (q1,q2)*/
9441      if ((isFromQ)&&(strat->fromQ!=NULL))
9442      {
9443        for (j=0; j<=k; j++)
9444        {
9445          if (!strat->fromQ[j])
9446          {
9447            new_pair=TRUE;
9448            enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR,uptodeg,lV);
9449            // other side pairs:
9450            enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
9451          //Print("j:%d, Ll:%d\n",j,strat->Ll);
9452          }
9453        }
9454      }
9455      else
9456      {
9457        new_pair=TRUE;
9458        for (j=0; j<=k; j++)
9459        {
9460          enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR,uptodeg,lV);
9461          // other side pairs
9462          enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
9463        }
9464        /* HERE we put (h, s*h) pairs */
9465       /* enterOnePairSelfShifts (poly qq, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int uptodeg, int lV); */
9466       enterOnePairSelfShifts (h, h, ecart, isFromQ, strat, atR, uptodeg, lV);
9467      }
9468    }
9469    else
9470    {
9471      for (j=0; j<=k; j++)
9472      {
9473        if ((pGetComp(h)==pGetComp(strat->S[j]))
9474        || (pGetComp(strat->S[j])==0))
9475        {
9476          new_pair=TRUE;
9477          enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR, uptodeg, lV);
9478          // other side pairs
9479          enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
9480        //Print("j:%d, Ll:%d\n",j,strat->Ll);
9481        }
9482      }
9483      /* HERE we put (h, s*h) pairs */
9484      enterOnePairSelfShifts (h, h, ecart, isFromQ, strat, atR, uptodeg, lV);
9485    }
9486
9487    if (new_pair)
9488    {
9489      strat->chainCrit(h,ecart,strat);
9490    }
9491
9492  }
9493}
9494#endif
9495
9496#ifdef HAVE_SHIFTBBA
9497/*2
9498* puts p to the set T, starting with the at position atT
9499* and inserts all admissible shifts of p
9500*/
9501void enterTShift(LObject p, kStrategy strat, int atT, int uptodeg, int lV)
9502{
9503  /* determine how many elements we have to insert */
9504  /* x(0)y(1)z(2) : lastVblock-1=2, to add until lastVblock=uptodeg-1 */
9505  /* hence, a total number of elt's to add is: */
9506  /*  int toInsert = 1 + (uptodeg-1) - (pLastVblock(p.p, lV) -1);  */
9507
9508  int toInsert =  itoInsert(p.p, uptodeg,  lV, strat->tailRing);
9509
9510#ifdef PDEBUG
9511  //  Print("enterTShift uses toInsert: %d", toInsert);  PrintLn();
9512#endif
9513  int i;
9514
9515  if (atT < 0)
9516    atT = strat->posInT(strat->T, strat->tl, p);
9517
9518  /* can call enterT in a sequence, e.g. */
9519
9520  /* shift0 = it's our model for further shifts */
9521  enterT(p,strat,atT);
9522  LObject qq;
9523  for (i=1; i<=toInsert; i++) // toIns - 1?
9524  {
9525    qq      = p; //qq.Copy();
9526    qq.p    = NULL;
9527    qq.max  = NULL;
9528    qq.t_p = p_LPshift(p_Copy(p.t_p,strat->tailRing), i, uptodeg, lV, strat->tailRing); // direct shift
9529    qq.GetP();
9530    // update q.sev
9531    qq.sev = pGetShortExpVector(qq.p);
9532    /* enter it into T, first el't is with the shift 0 */
9533    // compute the position for qq
9534    atT = strat->posInT(strat->T, strat->tl, qq);
9535    enterT(qq,strat,atT);
9536  }
9537/* Q: what to do with this one in the orig enterT ? */
9538/*  strat->R[strat->tl] = &(strat->T[atT]); */
9539/* Solution: it is done by enterT each time separately */
9540}
9541#endif
9542
9543#ifdef HAVE_SHIFTBBA
9544poly redtailBbaShift (LObject* L, int pos, kStrategy strat, BOOLEAN withT, BOOLEAN normalize)
9545{
9546  /* for the shift case need to run it with withT = TRUE */
9547  strat->redTailChange=FALSE;
9548  if (strat->noTailReduction) return L->GetLmCurrRing();
9549  poly h, p;
9550  p = h = L->GetLmTailRing();
9551  if ((h==NULL) || (pNext(h)==NULL))
9552    return L->GetLmCurrRing();
9553
9554  TObject* With;
9555  // placeholder in case strat->tl < 0
9556  TObject  With_s(strat->tailRing);
9557
9558  LObject Ln(pNext(h), strat->tailRing);
9559  Ln.pLength = L->GetpLength() - 1;
9560
9561  pNext(h) = NULL;
9562  if (L->p != NULL) pNext(L->p) = NULL;
9563  L->pLength = 1;
9564
9565  Ln.PrepareRed(strat->use_buckets);
9566
9567  while(!Ln.IsNull())
9568  {
9569    loop
9570    {
9571      Ln.SetShortExpVector();
9572      if (withT)
9573      {
9574        int j;
9575        j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln);
9576        if (j < 0) break;
9577        With = &(strat->T[j]);
9578      }
9579      else
9580      {
9581        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
9582        if (With == NULL) break;
9583      }
9584      if (normalize && (!TEST_OPT_INTSTRATEGY) && (!nIsOne(pGetCoeff(With->p))))
9585      {
9586        With->pNorm();
9587        //if (TEST_OPT_PROT) { PrintS("n"); mflush(); }
9588      }
9589      strat->redTailChange=TRUE;
9590      if (ksReducePolyTail(L, With, &Ln))
9591      {
9592        // reducing the tail would violate the exp bound
9593        //  set a flag and hope for a retry (in bba)
9594        strat->completeReduce_retry=TRUE;
9595        if ((Ln.p != NULL) && (Ln.t_p != NULL)) Ln.p=NULL;
9596        do
9597        {
9598          pNext(h) = Ln.LmExtractAndIter();
9599          pIter(h);
9600          L->pLength++;
9601        } while (!Ln.IsNull());
9602        goto all_done;
9603      }
9604      if (Ln.IsNull()) goto all_done;
9605      if (! withT) With_s.Init(currRing);
9606    }
9607    pNext(h) = Ln.LmExtractAndIter();
9608    pIter(h);
9609    L->pLength++;
9610  }
9611
9612  all_done:
9613  Ln.Delete();
9614  if (L->p != NULL) pNext(L->p) = pNext(p);
9615
9616  if (strat->redTailChange)
9617  {
9618    L->length = 0;
9619  }
9620  L->Normalize(); // HANNES: should have a test
9621  assume(kTest_L(L));
9622  return L->GetLmCurrRing();
9623}
9624#endif
Note: See TracBrowser for help on using the repository browser.