source: git/kernel/kutil.cc @ c656700

spielwiese
Last change on this file since c656700 was c656700, checked in by Oleksandr Motsak <motsak@…>, 13 years ago
FIX: degBound support for SCA (std/syz/res) From: Oleksandr Motsak <motsak@mathematik.uni-kl.de> git-svn-id: file:///usr/local/Singular/svn/trunk@14152 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 193.2 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id$ */
5/*
6* ABSTRACT: kernel: utils for kStd
7*/
8
9// #define PDEBUG 2
10// #define PDIV_DEBUG
11#define KUTIL_CC
12#include <stdlib.h>
13#include <string.h>
14#include <kernel/mod2.h>
15
16#ifndef NDEBUG
17# define MYTEST 0
18#else /* ifndef NDEBUG */
19# define MYTEST 0
20#endif /* ifndef NDEBUG */
21
22
23#include <omalloc/mylimits.h>
24#include <kernel/options.h>
25#include <kernel/gring.h>
26#include <kernel/sca.h>
27#ifdef KDEBUG
28#undef KDEBUG
29#define KDEBUG 2
30#endif
31
32#ifdef HAVE_RINGS
33#include <kernel/ideals.h>
34#endif
35
36// define if enterL, enterT should use memmove instead of doing it manually
37// on topgun, this is slightly faster (see monodromy_l.tst, homog_gonnet.sing)
38#ifndef SunOS_4
39#define ENTER_USE_MEMMOVE
40#endif
41
42// define, if the my_memmove inlines should be used instead of
43// system memmove -- it does not seem to pay off, though
44// #define ENTER_USE_MYMEMMOVE
45
46#include <kernel/kutil.h>
47#include <kernel/kbuckets.h>
48#include <kernel/febase.h>
49#include <omalloc/omalloc.h>
50#include <kernel/numbers.h>
51#include <kernel/polys.h>
52#include <kernel/ring.h>
53#include <kernel/ideals.h>
54#include <kernel/timer.h>
55//#include "cntrlc.h"
56#include <kernel/stairc.h>
57#include <kernel/kstd1.h>
58#include <kernel/pShallowCopyDelete.h>
59
60/* shiftgb stuff */
61#include <kernel/shiftgb.h>
62#include <kernel/prCopy.h>
63
64#ifdef HAVE_RATGRING
65#include <kernel/ratgring.h>
66#endif
67
68#ifdef KDEBUG
69#undef KDEBUG
70#define KDEBUG 2
71#endif
72
73denominator_list DENOMINATOR_LIST=NULL;
74
75
76#ifdef ENTER_USE_MYMEMMOVE
77inline void _my_memmove_d_gt_s(unsigned long* d, unsigned long* s, long l)
78{
79  register unsigned long* _dl = (unsigned long*) d;
80  register unsigned long* _sl = (unsigned long*) s;
81  register long _i = l - 1;
82
83  do
84  {
85    _dl[_i] = _sl[_i];
86    _i--;
87  }
88  while (_i >= 0);
89}
90
91inline void _my_memmove_d_lt_s(unsigned long* d, unsigned long* s, long l)
92{
93  register long _ll = l;
94  register unsigned long* _dl = (unsigned long*) d;
95  register unsigned long* _sl = (unsigned long*) s;
96  register long _i = 0;
97
98  do
99  {
100    _dl[_i] = _sl[_i];
101    _i++;
102  }
103  while (_i < _ll);
104}
105
106inline void _my_memmove(void* d, void* s, long l)
107{
108  unsigned long _d = (unsigned long) d;
109  unsigned long _s = (unsigned long) s;
110  unsigned long _l = ((l) + SIZEOF_LONG - 1) >> LOG_SIZEOF_LONG;
111
112  if (_d > _s) _my_memmove_d_gt_s(_d, _s, _l);
113  else _my_memmove_d_lt_s(_d, _s, _l);
114}
115
116#undef memmove
117#define memmove(d,s,l) _my_memmove(d, s, l)
118#endif
119
120static poly redMora (poly h,int maxIndex,kStrategy strat);
121static poly redBba (poly h,int maxIndex,kStrategy strat);
122
123#ifdef HAVE_RINGS
124#define pDivComp_EQUAL 2
125#define pDivComp_LESS 1
126#define pDivComp_GREATER -1
127#define pDivComp_INCOMP 0
128/* Checks the relation of LM(p) and LM(q)
129     LM(p) = LM(q) => return pDivComp_EQUAL
130     LM(p) | LM(q) => return pDivComp_LESS
131     LM(q) | LM(p) => return pDivComp_GREATER
132     else return pDivComp_INCOMP */
133static inline int pDivCompRing(poly p, poly q)
134{
135  if (pGetComp(p) == pGetComp(q))
136  {
137    BOOLEAN a=FALSE, b=FALSE;
138    int i;
139    unsigned long la, lb;
140    unsigned long divmask = currRing->divmask;
141    for (i=0; i<currRing->VarL_Size; i++)
142    {
143      la = p->exp[currRing->VarL_Offset[i]];
144      lb = q->exp[currRing->VarL_Offset[i]];
145      if (la != lb)
146      {
147        if (la < lb)
148        {
149          if (b) return pDivComp_INCOMP;
150          if (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask))
151            return pDivComp_INCOMP;
152          a = TRUE;
153        }
154        else
155        {
156          if (a) return pDivComp_INCOMP;
157          if (((la & divmask) ^ (lb & divmask)) != ((la - lb) & divmask))
158            return pDivComp_INCOMP;
159          b = TRUE;
160        }
161      }
162    }
163    if (a) return pDivComp_LESS;
164    if (b) return pDivComp_GREATER;
165    if (!a & !b) return pDivComp_EQUAL;
166  }
167  return pDivComp_INCOMP;
168}
169#endif
170
171static inline int pDivComp(poly p, poly q)
172{
173  if (pGetComp(p) == pGetComp(q))
174  {
175#ifdef HAVE_RATGRING
176    if (rIsRatGRing(currRing))
177    {
178      if (_p_LmDivisibleByPart(p,currRing,
179                           q,currRing,
180                           currRing->real_var_start, currRing->real_var_end))
181        return 0;
182      return pLmCmp(q,p); // ONLY FOR GLOBAL ORDER!
183    }
184#endif
185    BOOLEAN a=FALSE, b=FALSE;
186    int i;
187    unsigned long la, lb;
188    unsigned long divmask = currRing->divmask;
189    for (i=0; i<currRing->VarL_Size; i++)
190    {
191      la = p->exp[currRing->VarL_Offset[i]];
192      lb = q->exp[currRing->VarL_Offset[i]];
193      if (la != lb)
194      {
195        if (la < lb)
196        {
197          if (b) return 0;
198          if (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask))
199            return 0;
200          a = TRUE;
201        }
202        else
203        {
204          if (a) return 0;
205          if (((la & divmask) ^ (lb & divmask)) != ((la - lb) & divmask))
206            return 0;
207          b = TRUE;
208        }
209      }
210    }
211    if (a) { /*assume(pLmCmp(q,p)==1);*/ return 1; }
212    if (b) { /*assume(pLmCmp(q,p)==-1);*/return -1; }
213    /*assume(pLmCmp(q,p)==0);*/
214  }
215  return 0;
216}
217
218
219int     HCord;
220int     Kstd1_deg;
221int     Kstd1_mu=32000;
222
223/*2
224*deletes higher monomial of p, re-compute ecart and length
225*works only for orderings with ecart =pFDeg(end)-pFDeg(start)
226*/
227void deleteHC(LObject *L, kStrategy strat, BOOLEAN fromNext)
228{
229  if (strat->kHEdgeFound)
230  {
231    kTest_L(L);
232    poly p1;
233    poly p = L->GetLmTailRing();
234    int l = 1;
235    kBucket_pt bucket = NULL;
236    if (L->bucket != NULL)
237    {
238      kBucketClear(L->bucket, &pNext(p), &L->pLength);
239      L->pLength++;
240      bucket = L->bucket;
241      L->bucket = NULL;
242      L->last = NULL;
243    }
244
245    if (!fromNext && p_Cmp(p,strat->kNoetherTail(), L->tailRing) == -1)
246    {
247      L->Delete();
248      L->Clear();
249      L->ecart = -1;
250      if (bucket != NULL) kBucketDestroy(&bucket);
251      return;
252    }
253    p1 = p;
254    while (pNext(p1)!=NULL)
255    {
256      if (p_LmCmp(pNext(p1), strat->kNoetherTail(), L->tailRing) == -1)
257      {
258        L->last = p1;
259        p_Delete(&pNext(p1), L->tailRing);
260        if (p1 == p)
261        {
262          if (L->t_p != NULL)
263          {
264            assume(L->p != NULL && p == L->t_p);
265            pNext(L->p) = NULL;
266          }
267          L->max  = NULL;
268        }
269        else if (fromNext)
270          L->max  = p_GetMaxExpP(pNext(L->p), L->tailRing ); // p1;
271        //if (L->pLength != 0)
272        L->pLength = l;
273        // Hmmm when called from updateT, then only
274        // reset ecart when cut
275        if (fromNext)
276          L->ecart = L->pLDeg() - L->GetpFDeg();
277        break;
278      }
279      l++;
280      pIter(p1);
281    }
282    if (! fromNext)
283    {
284      L->SetpFDeg();
285      L->ecart = L->pLDeg(strat->LDegLast) - L->GetpFDeg();
286    }
287    if (bucket != NULL)
288    {
289      if (L->pLength > 1)
290      {
291        kBucketInit(bucket, pNext(p), L->pLength - 1);
292        pNext(p) = NULL;
293        if (L->t_p != NULL) pNext(L->t_p) = NULL;
294        L->pLength = 0;
295        L->bucket = bucket;
296        L->last = NULL;
297      }
298      else
299        kBucketDestroy(&bucket);
300    }
301    kTest_L(L);
302  }
303}
304
305void deleteHC(poly* p, int* e, int* l,kStrategy strat)
306{
307  LObject L(*p, currRing, strat->tailRing);
308
309  deleteHC(&L, strat);
310  *p = L.p;
311  *e = L.ecart;
312  *l = L.length;
313  if (L.t_p != NULL) p_LmFree(L.t_p, strat->tailRing);
314}
315
316/*2
317*tests if p.p=monomial*unit and cancels the unit
318*/
319void cancelunit (LObject* L,BOOLEAN inNF)
320{
321  int  i;
322  poly h;
323
324  if(rHasGlobalOrdering_currRing()) return;
325  if(TEST_OPT_CANCELUNIT) return;
326
327  ring r = L->tailRing;
328  poly p = L->GetLmTailRing();
329
330#ifdef HAVE_RINGS_LOC
331  // Leading coef have to be a unit
332  if ( !(nIsUnit(p_GetCoeff(p, r))) ) return;
333#endif
334
335  if(p_GetComp(p, r) != 0 && !p_OneComp(p, r)) return;
336
337//    for(i=r->N;i>0;i--)
338//    {
339//      if ((p_GetExp(p,i,r)>0) && (rIsPolyVar(i, r)==TRUE)) return;
340//    }
341  h = pNext(p);
342  loop
343  {
344    if (h==NULL)
345    {
346      p_Delete(&pNext(p), r);
347      if (!inNF)
348      {
349        number eins=nInit(1);
350        if (L->p != NULL)  pSetCoeff(L->p,eins);
351        else if (L->t_p != NULL) nDelete(&pGetCoeff(L->t_p));
352        if (L->t_p != NULL) pSetCoeff0(L->t_p,eins);
353      }
354      L->ecart = 0;
355      L->length = 1;
356      //if (L->pLength > 0)
357      L->pLength = 1;
358      if (L->last != NULL) L->last = p;
359      L->max = NULL;
360
361      if (L->t_p != NULL && pNext(L->t_p) != NULL)
362        pNext(L->t_p) = NULL;
363      if (L->p != NULL && pNext(L->p) != NULL)
364        pNext(L->p) = NULL;
365      return;
366    }
367    i = 0;
368    loop
369    {
370      i++;
371      if (p_GetExp(p,i,r) > p_GetExp(h,i,r)) return ; // does not divide
372      if (i == r->N) break; // does divide, try next monom
373    }
374    pIter(h);
375  }
376}
377
378/*2
379*pp is the new element in s
380*returns TRUE (in strat->kHEdgeFound) if
381*-HEcke is allowed
382*-we are in the last componente of the vector
383*-on all axis are monomials (all elements in NotUsedAxis are FALSE)
384*returns FALSE for pLexOrderings,
385*assumes in module case an ordering of type c* !!
386* HEckeTest is only called with strat->kHEdgeFound==FALSE !
387*/
388void HEckeTest (poly pp,kStrategy strat)
389{
390  int   j,k,p;
391
392  strat->kHEdgeFound=FALSE;
393  if (pLexOrder || currRing->MixedOrder)
394  {
395    return;
396  }
397  if (strat->ak > 1)           /*we are in the module case*/
398  {
399    return; // until ....
400    //if (!pVectorOut)     /*pVectorOut <=> order = c,* */
401    //  return FALSE;
402    //if (pGetComp(pp) < strat->ak) /* ak is the number of the last component */
403    //  return FALSE;
404  }
405  k = 0;
406  p=pIsPurePower(pp);
407  if (p!=0) strat->NotUsedAxis[p] = FALSE;
408  /*- the leading term of pp is a power of the p-th variable -*/
409  for (j=pVariables;j>0; j--)
410  {
411    if (strat->NotUsedAxis[j])
412    {
413      return;
414    }
415  }
416  strat->kHEdgeFound=TRUE;
417}
418
419/*2
420*utilities for TSet, LSet
421*/
422inline static intset initec (const int maxnr)
423{
424  return (intset)omAlloc(maxnr*sizeof(int));
425}
426
427inline static unsigned long* initsevS (const int maxnr)
428{
429  return (unsigned long*)omAlloc0(maxnr*sizeof(unsigned long));
430}
431inline static int* initS_2_R (const int maxnr)
432{
433  return (int*)omAlloc0(maxnr*sizeof(int));
434}
435
436static inline void enlargeT (TSet &T, TObject** &R, unsigned long* &sevT,
437                             int &length, const int incr)
438{
439  assume(T!=NULL);
440  assume(sevT!=NULL);
441  assume(R!=NULL);
442  assume((length+incr) > 0);
443
444  int i;
445  T = (TSet)omRealloc0Size(T, length*sizeof(TObject),
446                           (length+incr)*sizeof(TObject));
447
448  sevT = (unsigned long*) omReallocSize(sevT, length*sizeof(long*),
449                           (length+incr)*sizeof(long*));
450
451  R = (TObject**)omRealloc0Size(R,length*sizeof(TObject*),
452                                (length+incr)*sizeof(TObject*));
453  for (i=length-1;i>=0;i--) R[T[i].i_r] = &(T[i]);
454  length += incr;
455}
456
457void cleanT (kStrategy strat)
458{
459  int i,j;
460  poly  p;
461  assume(currRing == strat->tailRing || strat->tailRing != NULL);
462
463  pShallowCopyDeleteProc p_shallow_copy_delete =
464    (strat->tailRing != currRing ?
465     pGetShallowCopyDeleteProc(strat->tailRing, currRing) :
466     NULL);
467
468  for (j=0; j<=strat->tl; j++)
469  {
470    p = strat->T[j].p;
471    strat->T[j].p=NULL;
472    if (strat->T[j].max != NULL)
473    {
474      p_LmFree(strat->T[j].max, strat->tailRing);
475    }
476    i = -1;
477    loop
478    {
479      i++;
480      if (i>strat->sl)
481      {
482        if (strat->T[j].t_p != NULL)
483        {
484          p_Delete(&(strat->T[j].t_p), strat->tailRing);
485          p_LmFree(p, currRing);
486        }
487        else
488          pDelete(&p);
489        break;
490      }
491      if (p == strat->S[i])
492      {
493        if (strat->T[j].t_p != NULL)
494        {
495          assume(p_shallow_copy_delete != NULL);
496          pNext(p) = p_shallow_copy_delete(pNext(p),strat->tailRing,currRing,
497                                           currRing->PolyBin);
498          p_LmFree(strat->T[j].t_p, strat->tailRing);
499        }
500        break;
501      }
502    }
503  }
504  strat->tl=-1;
505}
506
507//LSet initL ()
508//{
509//  int i;
510//  LSet l = (LSet)omAlloc(setmaxL*sizeof(LObject));
511//  return l;
512//}
513
514static inline void enlargeL (LSet* L,int* length,const int incr)
515{
516  assume((*L)!=NULL);
517  assume((length+incr)>0);
518
519  *L = (LSet)omReallocSize((*L),(*length)*sizeof(LObject),
520                                   ((*length)+incr)*sizeof(LObject));
521  (*length) += incr;
522}
523
524void initPairtest(kStrategy strat)
525{
526  strat->pairtest = (BOOLEAN *)omAlloc0((strat->sl+2)*sizeof(BOOLEAN));
527}
528
529/*2
530*test whether (p1,p2) or (p2,p1) is in L up position length
531*it returns TRUE if yes and the position k
532*/
533BOOLEAN isInPairsetL(int length,poly p1,poly p2,int*  k,kStrategy strat)
534{
535  LObject *p=&(strat->L[length]);
536
537  *k = length;
538  loop
539  {
540    if ((*k) < 0) return FALSE;
541    if (((p1 == (*p).p1) && (p2 == (*p).p2))
542    ||  ((p1 == (*p).p2) && (p2 == (*p).p1)))
543      return TRUE;
544    (*k)--;
545    p--;
546  }
547}
548
549/*2
550*in B all pairs have the same element p on the right
551*it tests whether (q,p) is in B and returns TRUE if yes
552*and the position k
553*/
554BOOLEAN isInPairsetB(poly q,int*  k,kStrategy strat)
555{
556  LObject *p=&(strat->B[strat->Bl]);
557
558  *k = strat->Bl;
559  loop
560  {
561    if ((*k) < 0) return FALSE;
562    if (q == (*p).p1)
563      return TRUE;
564    (*k)--;
565    p--;
566  }
567}
568
569int kFindInT(poly p, TSet T, int tlength)
570{
571  int i;
572
573  for (i=0; i<=tlength; i++)
574  {
575    if (T[i].p == p) return i;
576  }
577  return -1;
578}
579
580int kFindInT(poly p, kStrategy strat)
581{
582  int i;
583  do
584  {
585    i = kFindInT(p, strat->T, strat->tl);
586    if (i >= 0) return i;
587    strat = strat->next;
588  }
589  while (strat != NULL);
590  return -1;
591}
592
593#ifdef KDEBUG
594
595void sTObject::wrp()
596{
597  if (t_p != NULL) p_wrp(t_p, tailRing);
598  else if (p != NULL) p_wrp(p, currRing, tailRing);
599  else ::wrp(NULL);
600}
601
602#define kFalseReturn(x) do { if (!x) return FALSE;} while (0)
603
604// check that Lm's of a poly from T are "equal"
605static const char* kTest_LmEqual(poly p, poly t_p, ring tailRing)
606{
607  int i;
608  for (i=1; i<=tailRing->N; i++)
609  {
610    if (p_GetExp(p, i, currRing) != p_GetExp(t_p, i, tailRing))
611      return "Lm[i] different";
612  }
613  if (p_GetComp(p, currRing) != p_GetComp(t_p, tailRing))
614    return "Lm[0] different";
615  if (pNext(p) != pNext(t_p))
616    return "Lm.next different";
617  if (pGetCoeff(p) != pGetCoeff(t_p))
618    return "Lm.coeff different";
619  return NULL;
620}
621
622static BOOLEAN sloppy_max = FALSE;
623BOOLEAN kTest_T(TObject * T, ring strat_tailRing, int i, char TN)
624{
625  ring tailRing = T->tailRing;
626  if (strat_tailRing == NULL) strat_tailRing = tailRing;
627  r_assume(strat_tailRing == tailRing);
628
629  poly p = T->p;
630  ring r = currRing;
631
632  if (T->p == NULL && T->t_p == NULL && i >= 0)
633    return dReportError("%c[%d].poly is NULL", TN, i);
634
635  if (T->tailRing != currRing)
636  {
637    if (T->t_p == NULL && i > 0)
638      return dReportError("%c[%d].t_p is NULL", TN, i);
639    pFalseReturn(p_Test(T->t_p, T->tailRing));
640    if (T->p != NULL) pFalseReturn(p_LmTest(T->p, currRing));
641    if (T->p != NULL && T->t_p != NULL)
642    {
643      const char* msg = kTest_LmEqual(T->p, T->t_p, T->tailRing);
644      if (msg != NULL)
645        return dReportError("%c[%d] %s", TN, i, msg);
646      r = T->tailRing;
647      p = T->t_p;
648    }
649    if (T->p == NULL)
650    {
651      p = T->t_p;
652      r = T->tailRing;
653    }
654    if (T->t_p != NULL && i >= 0 && TN == 'T')
655    {
656      if (pNext(T->t_p) == NULL)
657      {
658        if (T->max != NULL)
659          return dReportError("%c[%d].max is not NULL as it should be", TN, i);
660      }
661      else
662      {
663        if (T->max == NULL)
664          return dReportError("%c[%d].max is NULL", TN, i);
665        if (pNext(T->max) != NULL)
666          return dReportError("pNext(%c[%d].max) != NULL", TN, i);
667
668        pFalseReturn(p_CheckPolyRing(T->max, tailRing));
669        omCheckBinAddrSize(T->max, (tailRing->PolyBin->sizeW)*SIZEOF_LONG);
670#if KDEBUG > 0
671        if (! sloppy_max)
672        {
673          poly test_max = p_GetMaxExpP(pNext(T->t_p), tailRing);
674          p_Setm(T->max, tailRing);
675          p_Setm(test_max, tailRing);
676          BOOLEAN equal = p_ExpVectorEqual(T->max, test_max, tailRing);
677          if (! equal)
678            return dReportError("%c[%d].max out of sync", TN, i);
679          p_LmFree(test_max, tailRing);
680        }
681#endif
682      }
683    }
684  }
685  else
686  {
687    if (T->max != NULL)
688      return dReportError("%c[%d].max != NULL but tailRing == currRing",TN,i);
689    if (T->t_p != NULL)
690      return dReportError("%c[%d].t_p != NULL but tailRing == currRing",TN,i);
691    if (T->p == NULL && i > 0)
692      return dReportError("%c[%d].p is NULL", TN, i);
693    pFalseReturn(p_Test(T->p, currRing));
694  }
695
696  if (i >= 0 && T->pLength != 0
697  && ! rIsSyzIndexRing(currRing) && T->pLength != pLength(p))
698  {
699    int l=T->pLength;
700    T->pLength=pLength(p);
701    return dReportError("%c[%d] pLength error: has %d, specified to have %d",
702                        TN, i , pLength(p), l);
703  }
704
705  // check FDeg,  for elements in L and T
706  if (i >= 0 && (TN == 'T' || TN == 'L'))
707  {
708    // FDeg has ir element from T of L set
709    if (T->FDeg  != T->pFDeg())
710    {
711      int d=T->FDeg;
712      T->FDeg=T->pFDeg();
713      return dReportError("%c[%d] FDeg error: has %d, specified to have %d",
714                          TN, i , T->pFDeg(), d);
715    }
716  }
717
718  // check is_normalized for elements in T
719  if (i >= 0 && TN == 'T')
720  {
721    if (T->is_normalized && ! nIsOne(pGetCoeff(p)))
722      return dReportError("T[%d] is_normalized error", i);
723
724  }
725  return TRUE;
726}
727
728BOOLEAN kTest_L(LObject *L, ring strat_tailRing,
729                BOOLEAN testp, int lpos, TSet T, int tlength)
730{
731  if (testp)
732  {
733    poly pn = NULL;
734    if (L->bucket != NULL)
735    {
736      kFalseReturn(kbTest(L->bucket));
737      r_assume(L->bucket->bucket_ring == L->tailRing);
738      if (L->p != NULL && pNext(L->p) != NULL)
739      {
740        pn = pNext(L->p);
741        pNext(L->p) = NULL;
742      }
743    }
744    kFalseReturn(kTest_T(L, strat_tailRing, lpos, 'L'));
745    if (pn != NULL)
746      pNext(L->p) = pn;
747
748    ring r;
749    poly p;
750    L->GetLm(p, r);
751    if (L->sev != 0 && p_GetShortExpVector(p, r) != L->sev)
752    {
753      return dReportError("L[%d] wrong sev: has %o, specified to have %o",
754                          lpos, p_GetShortExpVector(p, r), L->sev);
755    }
756    if (lpos > 0 && L->last != NULL && pLast(p) != L->last)
757    {
758      return dReportError("L[%d] last wrong: has %p specified to have %p",
759                          lpos, pLast(p), L->last);
760    }
761  }
762  if (L->p1 == NULL)
763  {
764    // L->p2 either NULL or "normal" poly
765    pFalseReturn(pp_Test(L->p2, currRing, L->tailRing));
766  }
767  else if (tlength > 0 && T != NULL && (lpos >=0))
768  {
769    // now p1 and p2 must be != NULL and must be contained in T
770    int i;
771    i = kFindInT(L->p1, T, tlength);
772    if (i < 0)
773      return dReportError("L[%d].p1 not in T",lpos);
774    i = kFindInT(L->p2, T, tlength);
775    if (i < 0)
776      return dReportError("L[%d].p2 not in T",lpos);
777  }
778  return TRUE;
779}
780
781BOOLEAN kTest (kStrategy strat)
782{
783  int i;
784
785  // test P
786  kFalseReturn(kTest_L(&(strat->P), strat->tailRing,
787                       (strat->P.p != NULL && pNext(strat->P.p)!=strat->tail),
788                       -1, strat->T, strat->tl));
789
790  // test T
791  if (strat->T != NULL)
792  {
793    for (i=0; i<=strat->tl; i++)
794    {
795      kFalseReturn(kTest_T(&(strat->T[i]), strat->tailRing, i, 'T'));
796      if (strat->sevT[i] != pGetShortExpVector(strat->T[i].p))
797        return dReportError("strat->sevT[%d] out of sync", i);
798    }
799  }
800
801  // test L
802  if (strat->L != NULL)
803  {
804    for (i=0; i<=strat->Ll; i++)
805    {
806      kFalseReturn(kTest_L(&(strat->L[i]), strat->tailRing,
807                           strat->L[i].Next() != strat->tail, i,
808                           strat->T, strat->tl));
809      // may be unused
810      //if (strat->use_buckets && strat->L[i].Next() != strat->tail &&
811      //    strat->L[i].Next() != NULL && strat->L[i].p1 != NULL)
812      //{
813      //  assume(strat->L[i].bucket != NULL);
814      //}
815    }
816  }
817
818  // test S
819  if (strat->S != NULL)
820    kFalseReturn(kTest_S(strat));
821
822  return TRUE;
823}
824
825BOOLEAN kTest_S(kStrategy strat)
826{
827  int i;
828  BOOLEAN ret = TRUE;
829  for (i=0; i<=strat->sl; i++)
830  {
831    if (strat->S[i] != NULL &&
832        strat->sevS[i] != pGetShortExpVector(strat->S[i]))
833    {
834      return dReportError("S[%d] wrong sev: has %o, specified to have %o",
835                          i , pGetShortExpVector(strat->S[i]), strat->sevS[i]);
836    }
837  }
838  return ret;
839}
840
841
842
843BOOLEAN kTest_TS(kStrategy strat)
844{
845  int i, j;
846  BOOLEAN ret = TRUE;
847  kFalseReturn(kTest(strat));
848
849  // test strat->R, strat->T[i].i_r
850  for (i=0; i<=strat->tl; i++)
851  {
852    if (strat->T[i].i_r < 0 || strat->T[i].i_r > strat->tl)
853      return dReportError("strat->T[%d].i_r == %d out of bounds", i,
854                          strat->T[i].i_r);
855    if (strat->R[strat->T[i].i_r] != &(strat->T[i]))
856      return dReportError("T[%d].i_r with R out of sync", i);
857  }
858  // test containment of S inT
859  if (strat->S != NULL)
860  {
861    for (i=0; i<=strat->sl; i++)
862    {
863      j = kFindInT(strat->S[i], strat->T, strat->tl);
864      if (j < 0)
865        return dReportError("S[%d] not in T", i);
866      if (strat->S_2_R[i] != strat->T[j].i_r)
867        return dReportError("S_2_R[%d]=%d != T[%d].i_r=%d\n",
868                            i, strat->S_2_R[i], j, strat->T[j].i_r);
869    }
870  }
871  // test strat->L[i].i_r1
872  for (i=0; i<=strat->Ll; i++)
873  {
874    if (strat->L[i].p1 != NULL && strat->L[i].p2)
875    {
876      if (strat->L[i].i_r1 < 0 ||
877          strat->L[i].i_r1 > strat->tl ||
878          strat->L[i].T_1(strat)->p != strat->L[i].p1)
879        return dReportError("L[%d].i_r1 out of sync", i);
880      if (strat->L[i].i_r2 < 0 ||
881          strat->L[i].i_r2 > strat->tl ||
882          strat->L[i].T_2(strat)->p != strat->L[i].p2);
883    }
884    else
885    {
886      if (strat->L[i].i_r1 != -1)
887        return dReportError("L[%d].i_r1 out of sync", i);
888      if (strat->L[i].i_r2 != -1)
889        return dReportError("L[%d].i_r2 out of sync", i);
890    }
891    if (strat->L[i].i_r != -1)
892      return dReportError("L[%d].i_r out of sync", i);
893  }
894  return TRUE;
895}
896
897#endif // KDEBUG
898
899/*2
900*cancels the i-th polynomial in the standardbase s
901*/
902void deleteInS (int i,kStrategy strat)
903{
904#ifdef ENTER_USE_MEMMOVE
905  memmove(&(strat->S[i]), &(strat->S[i+1]), (strat->sl - i)*sizeof(poly));
906  memmove(&(strat->ecartS[i]),&(strat->ecartS[i+1]),(strat->sl - i)*sizeof(int));
907  memmove(&(strat->sevS[i]),&(strat->sevS[i+1]),(strat->sl - i)*sizeof(long));
908  memmove(&(strat->S_2_R[i]),&(strat->S_2_R[i+1]),(strat->sl - i)*sizeof(int));
909#else
910  int j;
911  for (j=i; j<strat->sl; j++)
912  {
913    strat->S[j] = strat->S[j+1];
914    strat->ecartS[j] = strat->ecartS[j+1];
915    strat->sevS[j] = strat->sevS[j+1];
916    strat->S_2_R[j] = strat->S_2_R[j+1];
917  }
918#endif
919  if (strat->lenS!=NULL)
920  {
921#ifdef ENTER_USE_MEMMOVE
922    memmove(&(strat->lenS[i]),&(strat->lenS[i+1]),(strat->sl - i)*sizeof(int));
923#else
924    for (j=i; j<strat->sl; j++) strat->lenS[j] = strat->lenS[j+1];
925#endif
926  }
927  if (strat->lenSw!=NULL)
928  {
929#ifdef ENTER_USE_MEMMOVE
930    memmove(&(strat->lenSw[i]),&(strat->lenSw[i+1]),(strat->sl - i)*sizeof(wlen_type));
931#else
932    for (j=i; j<strat->sl; j++) strat->lenSw[j] = strat->lenSw[j+1];
933#endif
934  }
935  if (strat->fromQ!=NULL)
936  {
937#ifdef ENTER_USE_MEMMOVE
938    memmove(&(strat->fromQ[i]),&(strat->fromQ[i+1]),(strat->sl - i)*sizeof(int));
939#else
940    for (j=i; j<strat->sl; j++)
941    {
942      strat->fromQ[j] = strat->fromQ[j+1];
943    }
944#endif
945  }
946  strat->S[strat->sl] = NULL;
947  strat->sl--;
948}
949
950/*2
951*cancels the j-th polynomial in the set
952*/
953void deleteInL (LSet set, int *length, int j,kStrategy strat)
954{
955  if (set[j].lcm!=NULL)
956  {
957#ifdef HAVE_RINGS
958    if (pGetCoeff(set[j].lcm) != NULL)
959      pLmDelete(set[j].lcm);
960    else
961#endif
962      pLmFree(set[j].lcm);
963  }
964  if (set[j].p!=NULL)
965  {
966    if (pNext(set[j].p) == strat->tail)
967    {
968#ifdef HAVE_RINGS
969      if (pGetCoeff(set[j].p) != NULL)
970        pLmDelete(set[j].p);
971      else
972#endif
973        pLmFree(set[j].p);
974      /*- tail belongs to several int spolys -*/
975    }
976    else
977    {
978      // search p in T, if it is there, do not delete it
979      if (pOrdSgn != -1 || kFindInT(set[j].p, strat) < 0)
980      {
981        // assure that for global orderings kFindInT fails
982        assume(pOrdSgn == -1 || kFindInT(set[j].p, strat) < 0);
983        set[j].Delete();
984      }
985    }
986  }
987  if (*length > 0 && j < *length)
988  {
989#ifdef ENTER_USE_MEMMOVE
990    memmove(&(set[j]), &(set[j+1]), (*length - j)*sizeof(LObject));
991#else
992    int i;
993    for (i=j; i < (*length); i++)
994      set[i] = set[i+1];
995#endif
996  }
997#ifdef KDEBUG
998  memset(&(set[*length]),0,sizeof(LObject));
999#endif
1000  (*length)--;
1001}
1002
1003/*2
1004*enters p at position at in L
1005*/
1006void enterL (LSet *set,int *length, int *LSetmax, LObject p,int at)
1007{
1008#ifdef PDEBUG
1009  /*  zaehler++; */
1010#endif /*PDEBUG*/
1011  int i;
1012  // this should be corrected
1013  assume(p.FDeg == p.pFDeg());
1014
1015  if ((*length)>=0)
1016  {
1017    if ((*length) == (*LSetmax)-1) enlargeL(set,LSetmax,setmaxLinc);
1018    if (at <= (*length))
1019#ifdef ENTER_USE_MEMMOVE
1020      memmove(&((*set)[at+1]), &((*set)[at]), ((*length)-at+1)*sizeof(LObject));
1021#else
1022    for (i=(*length)+1; i>=at+1; i--) (*set)[i] = (*set)[i-1];
1023#endif
1024  }
1025  else at = 0;
1026  (*set)[at] = p;
1027  (*length)++;
1028}
1029
1030/*2
1031* computes the normal ecart;
1032* used in mora case and if pLexOrder & sugar in bba case
1033*/
1034void initEcartNormal (LObject* h)
1035{
1036  h->FDeg = h->pFDeg();
1037  h->ecart = h->pLDeg() - h->FDeg;
1038  // h->length is set by h->pLDeg
1039  h->length=h->pLength=pLength(h->p);
1040}
1041
1042void initEcartBBA (LObject* h)
1043{
1044  h->FDeg = h->pFDeg();
1045  (*h).ecart = 0;
1046  h->length=h->pLength=pLength(h->p);
1047}
1048
1049void initEcartPairBba (LObject* Lp,poly f,poly g,int ecartF,int ecartG)
1050{
1051  Lp->FDeg = Lp->pFDeg();
1052  (*Lp).ecart = 0;
1053  (*Lp).length = 0;
1054}
1055
1056void initEcartPairMora (LObject* Lp,poly f,poly g,int ecartF,int ecartG)
1057{
1058  Lp->FDeg = Lp->pFDeg();
1059  (*Lp).ecart = si_max(ecartF,ecartG);
1060  (*Lp).ecart = (*Lp).ecart- (Lp->FDeg -pFDeg((*Lp).lcm,currRing));
1061  (*Lp).length = 0;
1062}
1063
1064/*2
1065*if ecart1<=ecart2 it returns TRUE
1066*/
1067static inline BOOLEAN sugarDivisibleBy(int ecart1, int ecart2)
1068{
1069  return (ecart1 <= ecart2);
1070}
1071
1072#ifdef HAVE_RINGS
1073/*2
1074* put the pair (s[i],p)  into the set B, ecart=ecart(p) (ring case)
1075*/
1076void enterOnePairRing (int i,poly p,int ecart, int isFromQ,kStrategy strat, int atR = -1)
1077{
1078  assume(i<=strat->sl);
1079  int      l,j,compare,compareCoeff;
1080  LObject  Lp;
1081
1082  if (strat->interred_flag) return;
1083#ifdef KDEBUG
1084  Lp.ecart=0; Lp.length=0;
1085#endif
1086  /*- computes the lcm(s[i],p) -*/
1087  Lp.lcm = pInit();
1088  pSetCoeff0(Lp.lcm, nLcm(pGetCoeff(p), pGetCoeff(strat->S[i]), currRing));
1089  // Lp.lcm == 0
1090  if (nIsZero(pGetCoeff(Lp.lcm)))
1091  {
1092#ifdef KDEBUG
1093      if (TEST_OPT_DEBUG)
1094      {
1095        PrintS("--- Lp.lcm == 0\n");
1096        PrintS("p:");
1097        wrp(p);
1098        Print("  strat->S[%d]:", i);
1099        wrp(strat->S[i]);
1100        PrintLn();
1101      }
1102#endif
1103      strat->cp++;
1104      pLmDelete(Lp.lcm);
1105      return;
1106  }
1107  // basic product criterion
1108  pLcm(p,strat->S[i],Lp.lcm);
1109  pSetm(Lp.lcm);
1110  assume(!strat->sugarCrit);
1111  if (pHasNotCF(p,strat->S[i]) && nIsUnit(pGetCoeff(p)) && nIsUnit(pGetCoeff(strat->S[i])))
1112  {
1113#ifdef KDEBUG
1114      if (TEST_OPT_DEBUG)
1115      {
1116        PrintS("--- product criterion func enterOnePairRing type 1\n");
1117        PrintS("p:");
1118        wrp(p);
1119        Print("  strat->S[%d]:", i);
1120        wrp(strat->S[i]);
1121        PrintLn();
1122      }
1123#endif
1124      strat->cp++;
1125      pLmDelete(Lp.lcm);
1126      return;
1127  }
1128  assume(!strat->fromT);
1129  /*
1130  *the set B collects the pairs of type (S[j],p)
1131  *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p) != lcm(r,p)
1132  *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
1133  *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
1134  */
1135  for(j = strat->Bl;j>=0;j--)
1136  {
1137    compare=pDivCompRing(strat->B[j].lcm,Lp.lcm);
1138    compareCoeff = nDivComp(pGetCoeff(strat->B[j].lcm), pGetCoeff(Lp.lcm));
1139    if (compareCoeff == pDivComp_EQUAL || compare == compareCoeff)
1140    {
1141      if (compare == 1)
1142      {
1143        strat->c3++;
1144#ifdef KDEBUG
1145        if (TEST_OPT_DEBUG)
1146        {
1147          PrintS("--- chain criterion type 1\n");
1148          PrintS("strat->B[j]:");
1149          wrp(strat->B[j].lcm);
1150          PrintS("  Lp.lcm:");
1151          wrp(Lp.lcm);
1152          PrintLn();
1153        }
1154#endif
1155        if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1156        {
1157          pLmDelete(Lp.lcm);
1158          return;
1159        }
1160        break;
1161      }
1162      else
1163      if (compare == -1)
1164      {
1165#ifdef KDEBUG
1166        if (TEST_OPT_DEBUG)
1167        {
1168          PrintS("--- chain criterion type 2\n");
1169          Print("strat->B[%d].lcm:",j);
1170          wrp(strat->B[j].lcm);
1171          PrintS("  Lp.lcm:");
1172          wrp(Lp.lcm);
1173          PrintLn();
1174        }
1175#endif
1176        deleteInL(strat->B,&strat->Bl,j,strat);
1177        strat->c3++;
1178      }
1179    }
1180    if ((compare == pDivComp_EQUAL) && (compareCoeff != 2))
1181    {
1182      if (compareCoeff == pDivComp_LESS)
1183      {
1184#ifdef KDEBUG
1185        if (TEST_OPT_DEBUG)
1186        {
1187          PrintS("--- chain criterion type 3\n");
1188          Print("strat->B[%d].lcm:", j);
1189          wrp(strat->B[j].lcm);
1190          PrintS("  Lp.lcm:");
1191          wrp(Lp.lcm);
1192          PrintLn();
1193        }
1194#endif
1195        strat->c3++;
1196        if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1197        {
1198          pLmDelete(Lp.lcm);
1199          return;
1200        }
1201        break;
1202      }
1203      else
1204      // Add hint for same LM and LC (later) (TODO Oliver)
1205      // if (compareCoeff == pDivComp_GREATER)
1206      {
1207#ifdef KDEBUG
1208        if (TEST_OPT_DEBUG)
1209        {
1210          PrintS("--- chain criterion type 4\n");
1211          Print("strat->B[%d].lcm:", j);
1212          wrp(strat->B[j].lcm);
1213          PrintS("  Lp.lcm:");
1214          wrp(Lp.lcm);
1215          PrintLn();
1216        }
1217#endif
1218        deleteInL(strat->B,&strat->Bl,j,strat);
1219        strat->c3++;
1220      }
1221    }
1222  }
1223  /*
1224  *the pair (S[i],p) enters B if the spoly != 0
1225  */
1226  /*-  compute the short s-polynomial -*/
1227  if ((strat->S[i]==NULL) || (p==NULL)) {
1228#ifdef KDEBUG
1229    if (TEST_OPT_DEBUG)
1230    {
1231      PrintS("--- spoly = NULL\n");
1232    }
1233#endif
1234    pLmDelete(Lp.lcm);
1235    return;
1236  }
1237  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (strat->fromQ[i]!=0))
1238  {
1239    // Is from a previous computed GB, therefore we know that spoly will
1240    // reduce to zero. Oliver.
1241    WarnS("Could we come here? 8738947389");
1242    Lp.p=NULL;
1243  }
1244  else
1245  {
1246    Lp.p = ksCreateShortSpoly(strat->S[i], p, strat->tailRing);
1247  }
1248  if (Lp.p == NULL)
1249  {
1250#ifdef KDEBUG
1251    if (TEST_OPT_DEBUG)
1252    {
1253      PrintS("--- spoly = NULL\n");
1254    }
1255#endif
1256    /*- the case that the s-poly is 0 -*/
1257    if (strat->pairtest==NULL) initPairtest(strat);
1258    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
1259    strat->pairtest[strat->sl+1] = TRUE;
1260    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
1261    /*
1262    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
1263    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
1264    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
1265    *term of p devides the lcm(s,r)
1266    *(this canceling should be done here because
1267    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
1268    *the first case is handeled in chainCrit
1269    */
1270    pLmDelete(Lp.lcm);
1271  }
1272  else
1273  {
1274    /*- the pair (S[i],p) enters B -*/
1275    Lp.p1 = strat->S[i];
1276    Lp.p2 = p;
1277
1278    pNext(Lp.p) = strat->tail;
1279
1280    if (atR >= 0)
1281    {
1282      Lp.i_r2 = atR;
1283      Lp.i_r1 = strat->S_2_R[i];
1284    }
1285    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
1286    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
1287    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
1288  }
1289}
1290
1291
1292/*2
1293* put the  lcm(s[i],p)  into the set B
1294*/
1295
1296BOOLEAN enterOneStrongPoly (int i,poly p,int ecart, int isFromQ,kStrategy strat, int atR = -1)
1297{
1298  number d, s, t;
1299  assume(i<=strat->sl);
1300  assume(atR >= 0);
1301  poly m1, m2, gcd;
1302
1303  d = nExtGcd(pGetCoeff(p), pGetCoeff(strat->S[i]), &s, &t);
1304
1305  if (nIsZero(s) || nIsZero(t))  // evtl. durch divBy tests ersetzen
1306  {
1307    nDelete(&d);
1308    nDelete(&s);
1309    nDelete(&t);
1310    return FALSE;
1311  }
1312
1313  k_GetStrongLeadTerms(p, strat->S[i], currRing, m1, m2, gcd, strat->tailRing);
1314  //p_Test(m1,strat->tailRing);
1315  //p_Test(m2,strat->tailRing);
1316  while (! kCheckStrongCreation(atR, m1, i, m2, strat) )
1317  {
1318    memset(&(strat->P), 0, sizeof(strat->P));
1319    kStratChangeTailRing(strat);
1320    strat->P = *(strat->R[atR]);
1321    p_LmFree(m1, strat->tailRing);
1322    p_LmFree(m2, strat->tailRing);
1323    p_LmFree(gcd, currRing);
1324    k_GetStrongLeadTerms(p, strat->S[i], currRing, m1, m2, gcd, strat->tailRing);
1325  }
1326  pSetCoeff0(m1, s);
1327  pSetCoeff0(m2, t);
1328  pSetCoeff0(gcd, d);
1329  p_Test(m1,strat->tailRing);
1330  p_Test(m2,strat->tailRing);
1331
1332#ifdef KDEBUG
1333  if (TEST_OPT_DEBUG)
1334  {
1335    // Print("t = %d; s = %d; d = %d\n", nInt(t), nInt(s), nInt(d));
1336    PrintS("m1 = ");
1337    p_wrp(m1, strat->tailRing);
1338    PrintS(" ; m2 = ");
1339    p_wrp(m2, strat->tailRing);
1340    PrintS(" ; gcd = ");
1341    wrp(gcd);
1342    PrintS("\n--- create strong gcd poly: ");
1343    Print("\n p: ", i);
1344    wrp(p);
1345    Print("\n strat->S[%d]: ", i);
1346    wrp(strat->S[i]);
1347    PrintS(" ---> ");
1348  }
1349#endif
1350
1351  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);
1352  p_LmDelete(m1, strat->tailRing);
1353  p_LmDelete(m2, strat->tailRing);
1354
1355#ifdef KDEBUG
1356  if (TEST_OPT_DEBUG)
1357  {
1358    wrp(gcd);
1359    PrintLn();
1360  }
1361#endif
1362
1363  LObject h;
1364  h.p = gcd;
1365  h.tailRing = strat->tailRing;
1366  int posx;
1367  h.pCleardenom();
1368  strat->initEcart(&h);
1369  if (strat->Ll==-1)
1370    posx =0;
1371  else
1372    posx = strat->posInL(strat->L,strat->Ll,&h,strat);
1373  h.sev = pGetShortExpVector(h.p);
1374  if (currRing!=strat->tailRing)
1375    h.t_p = k_LmInit_currRing_2_tailRing(h.p, strat->tailRing);
1376  enterL(&strat->L,&strat->Ll,&strat->Lmax,h,posx);
1377  return TRUE;
1378}
1379#endif
1380
1381/*2
1382* put the pair (s[i],p)  into the set B, ecart=ecart(p)
1383*/
1384
1385void enterOnePairNormal (int i,poly p,int ecart, int isFromQ,kStrategy strat, int atR = -1)
1386{
1387  assume(i<=strat->sl);
1388  if (strat->interred_flag) return;
1389
1390  int      l,j,compare;
1391  LObject  Lp;
1392  Lp.i_r = -1;
1393
1394#ifdef KDEBUG
1395  Lp.ecart=0; Lp.length=0;
1396#endif
1397  /*- computes the lcm(s[i],p) -*/
1398  Lp.lcm = pInit();
1399
1400#ifndef HAVE_RATGRING
1401  pLcm(p,strat->S[i],Lp.lcm);
1402#elif defined(HAVE_RATGRING)
1403  //  if (rIsRatGRing(currRing))
1404  pLcmRat(p,strat->S[i],Lp.lcm, currRing->real_var_start); // int rat_shift
1405#endif
1406  pSetm(Lp.lcm);
1407
1408
1409  if (strat->sugarCrit && ALLOW_PROD_CRIT(strat))
1410  {
1411    if((!((strat->ecartS[i]>0)&&(ecart>0)))
1412    && pHasNotCF(p,strat->S[i]))
1413    {
1414    /*
1415    *the product criterion has applied for (s,p),
1416    *i.e. lcm(s,p)=product of the leading terms of s and p.
1417    *Suppose (s,r) is in L and the leading term
1418    *of p divides lcm(s,r)
1419    *(==> the leading term of p divides the leading term of r)
1420    *but the leading term of s does not divide the leading term of r
1421    *(notice that tis condition is automatically satisfied if r is still
1422    *in S), then (s,r) can be cancelled.
1423    *This should be done here because the
1424    *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
1425    *
1426    *Moreover, skipping (s,r) holds also for the noncommutative case.
1427    */
1428      strat->cp++;
1429      pLmFree(Lp.lcm);
1430      Lp.lcm=NULL;
1431      return;
1432    }
1433    else
1434      Lp.ecart = si_max(ecart,strat->ecartS[i]);
1435    if (strat->fromT && (strat->ecartS[i]>ecart))
1436    {
1437      pLmFree(Lp.lcm);
1438      Lp.lcm=NULL;
1439      return;
1440      /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
1441    }
1442    /*
1443    *the set B collects the pairs of type (S[j],p)
1444    *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
1445    *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
1446    *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
1447    */
1448    {
1449      j = strat->Bl;
1450      loop
1451      {
1452        if (j < 0)  break;
1453        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
1454        if ((compare==1)
1455        &&(sugarDivisibleBy(strat->B[j].ecart,Lp.ecart)))
1456        {
1457          strat->c3++;
1458          if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1459          {
1460            pLmFree(Lp.lcm);
1461            return;
1462          }
1463          break;
1464        }
1465        else
1466        if ((compare ==-1)
1467        && sugarDivisibleBy(Lp.ecart,strat->B[j].ecart))
1468        {
1469          deleteInL(strat->B,&strat->Bl,j,strat);
1470          strat->c3++;
1471        }
1472        j--;
1473      }
1474    }
1475  }
1476  else /*sugarcrit*/
1477  {
1478    if (ALLOW_PROD_CRIT(strat))
1479    {
1480      // if currRing->nc_type!=quasi (or skew)
1481      // TODO: enable productCrit for super commutative algebras...
1482      if(/*(strat->ak==0) && productCrit(p,strat->S[i])*/
1483      pHasNotCF(p,strat->S[i]))
1484      {
1485      /*
1486      *the product criterion has applied for (s,p),
1487      *i.e. lcm(s,p)=product of the leading terms of s and p.
1488      *Suppose (s,r) is in L and the leading term
1489      *of p devides lcm(s,r)
1490      *(==> the leading term of p devides the leading term of r)
1491      *but the leading term of s does not devide the leading term of r
1492      *(notice that tis condition is automatically satisfied if r is still
1493      *in S), then (s,r) can be canceled.
1494      *This should be done here because the
1495      *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
1496      */
1497          strat->cp++;
1498          pLmFree(Lp.lcm);
1499          Lp.lcm=NULL;
1500          return;
1501      }
1502      if (strat->fromT && (strat->ecartS[i]>ecart))
1503      {
1504        pLmFree(Lp.lcm);
1505        Lp.lcm=NULL;
1506        return;
1507        /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
1508      }
1509      /*
1510      *the set B collects the pairs of type (S[j],p)
1511      *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
1512      *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
1513      *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
1514      */
1515      for(j = strat->Bl;j>=0;j--)
1516      {
1517        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
1518        if (compare==1)
1519        {
1520          strat->c3++;
1521          if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1522          {
1523            pLmFree(Lp.lcm);
1524            return;
1525          }
1526          break;
1527        }
1528        else
1529        if (compare ==-1)
1530        {
1531          deleteInL(strat->B,&strat->Bl,j,strat);
1532          strat->c3++;
1533        }
1534      }
1535    }
1536  }
1537  /*
1538  *the pair (S[i],p) enters B if the spoly != 0
1539  */
1540  /*-  compute the short s-polynomial -*/
1541  if (strat->fromT && !TEST_OPT_INTSTRATEGY)
1542    pNorm(p);
1543
1544  if ((strat->S[i]==NULL) || (p==NULL))
1545    return;
1546
1547  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (strat->fromQ[i]!=0))
1548    Lp.p=NULL;
1549  else
1550  {
1551    #ifdef HAVE_PLURAL
1552    if ( rIsPluralRing(currRing) )
1553    {
1554      if(pHasNotCF(p, strat->S[i]))
1555      {
1556         if(ncRingType(currRing) == nc_lie)
1557         {
1558             // generalized prod-crit for lie-type
1559             strat->cp++;
1560             Lp.p = nc_p_Bracket_qq(pCopy(p),strat->S[i]);
1561         }
1562         else
1563        if( ALLOW_PROD_CRIT(strat) )
1564        {
1565            // product criterion for homogeneous case in SCA
1566            strat->cp++;
1567            Lp.p = NULL;
1568        }
1569        else
1570        {
1571          Lp.p = // nc_CreateSpoly(strat->S[i],p,currRing);
1572                nc_CreateShortSpoly(strat->S[i], p, currRing);
1573
1574          assume(pNext(Lp.p)==NULL); // TODO: this may be violated whenever ext.prod.crit. for Lie alg. is used
1575          pNext(Lp.p) = strat->tail; // !!!
1576        }
1577      }
1578      else
1579      {
1580        Lp.p = // nc_CreateSpoly(strat->S[i],p,currRing);
1581              nc_CreateShortSpoly(strat->S[i], p, currRing);
1582
1583        assume(pNext(Lp.p)==NULL); // TODO: this may be violated whenever ext.prod.crit. for Lie alg. is used
1584        pNext(Lp.p) = strat->tail; // !!!
1585
1586      }
1587
1588
1589#if MYTEST
1590      if (TEST_OPT_DEBUG)
1591      {
1592        PrintS("enterOnePairNormal::\n strat->S[i]: "); pWrite(strat->S[i]);
1593        PrintS("p: "); pWrite(p);
1594        PrintS("SPoly: "); pWrite(Lp.p);
1595      }
1596#endif
1597
1598    }
1599    else
1600    #endif
1601    {
1602      assume(!rIsPluralRing(currRing));
1603      Lp.p = ksCreateShortSpoly(strat->S[i], p, strat->tailRing);
1604#if MYTEST
1605      if (TEST_OPT_DEBUG)
1606      {
1607        PrintS("enterOnePairNormal::\n strat->S[i]: "); pWrite(strat->S[i]);
1608        PrintS("p: "); pWrite(p);
1609        PrintS("commutative SPoly: "); pWrite(Lp.p);
1610      }
1611#endif
1612
1613      }
1614  }
1615  if (Lp.p == NULL)
1616  {
1617    /*- the case that the s-poly is 0 -*/
1618    if (strat->pairtest==NULL) initPairtest(strat);
1619    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
1620    strat->pairtest[strat->sl+1] = TRUE;
1621    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
1622    /*
1623    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
1624    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
1625    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
1626    *term of p devides the lcm(s,r)
1627    *(this canceling should be done here because
1628    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
1629    *the first case is handeled in chainCrit
1630    */
1631    if (Lp.lcm!=NULL) pLmFree(Lp.lcm);
1632  }
1633  else
1634  {
1635    /*- the pair (S[i],p) enters B -*/
1636    Lp.p1 = strat->S[i];
1637    Lp.p2 = p;
1638
1639    if (
1640        (!rIsPluralRing(currRing))
1641//      ||  (rIsPluralRing(currRing) && (ncRingType(currRing) != nc_lie))
1642       )
1643    {
1644      assume(pNext(Lp.p)==NULL); // TODO: this may be violated whenever ext.prod.crit. for Lie alg. is used
1645      pNext(Lp.p) = strat->tail; // !!!
1646    }
1647
1648    if (atR >= 0)
1649    {
1650      Lp.i_r1 = strat->S_2_R[i];
1651      Lp.i_r2 = atR;
1652    }
1653    else
1654    {
1655      Lp.i_r1 = -1;
1656      Lp.i_r2 = -1;
1657    }
1658    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
1659
1660    if (TEST_OPT_INTSTRATEGY)
1661    {
1662      if (!rIsPluralRing(currRing))
1663        nDelete(&(Lp.p->coef));
1664    }
1665
1666    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
1667    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
1668  }
1669}
1670
1671/*2
1672* put the pair (s[i],p) into the set L, ecart=ecart(p)
1673* in the case that s forms a SB of (s)
1674*/
1675void enterOnePairSpecial (int i,poly p,int ecart,kStrategy strat, int atR = -1)
1676{
1677  //PrintS("try ");wrp(strat->S[i]);PrintS(" and ");wrp(p);PrintLn();
1678  if(pHasNotCF(p,strat->S[i]))
1679  {
1680    //PrintS("prod-crit\n");
1681    if(ALLOW_PROD_CRIT(strat))
1682    {
1683      //PrintS("prod-crit\n");
1684      strat->cp++;
1685      return;
1686    }
1687  }
1688
1689  int      l,j,compare;
1690  LObject  Lp;
1691  Lp.i_r = -1;
1692
1693  Lp.lcm = pInit();
1694  pLcm(p,strat->S[i],Lp.lcm);
1695  pSetm(Lp.lcm);
1696  for(j = strat->Ll;j>=0;j--)
1697  {
1698    compare=pDivComp(strat->L[j].lcm,Lp.lcm);
1699    if ((compare==1) || (pLmEqual(strat->L[j].lcm,Lp.lcm)))
1700    {
1701      //PrintS("c3-crit\n");
1702      strat->c3++;
1703      pLmFree(Lp.lcm);
1704      return;
1705    }
1706    else if (compare ==-1)
1707    {
1708      //Print("c3-crit with L[%d]\n",j);
1709      deleteInL(strat->L,&strat->Ll,j,strat);
1710      strat->c3++;
1711    }
1712  }
1713  /*-  compute the short s-polynomial -*/
1714
1715  #ifdef HAVE_PLURAL
1716  if (rIsPluralRing(currRing))
1717  {
1718    Lp.p = nc_CreateShortSpoly(strat->S[i],p); // ??? strat->tailRing?
1719  }
1720  else
1721  #endif
1722    Lp.p = ksCreateShortSpoly(strat->S[i],p,strat->tailRing);
1723
1724  if (Lp.p == NULL)
1725  {
1726     //PrintS("short spoly==NULL\n");
1727     pLmFree(Lp.lcm);
1728  }
1729  else
1730  {
1731    /*- the pair (S[i],p) enters L -*/
1732    Lp.p1 = strat->S[i];
1733    Lp.p2 = p;
1734    if (atR >= 0)
1735    {
1736      Lp.i_r1 = strat->S_2_R[i];
1737      Lp.i_r2 = atR;
1738    }
1739    else
1740    {
1741      Lp.i_r1 = -1;
1742      Lp.i_r2 = -1;
1743    }
1744    assume(pNext(Lp.p) == NULL);
1745    pNext(Lp.p) = strat->tail;
1746    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
1747    if (TEST_OPT_INTSTRATEGY)
1748    {
1749      nDelete(&(Lp.p->coef));
1750    }
1751    l = strat->posInL(strat->L,strat->Ll,&Lp,strat);
1752    //Print("-> L[%d]\n",l);
1753    enterL(&strat->L,&strat->Ll,&strat->Lmax,Lp,l);
1754  }
1755}
1756
1757/*2
1758* merge set B into L
1759*/
1760void kMergeBintoL(kStrategy strat)
1761{
1762  int j=strat->Ll+strat->Bl+1;
1763  if (j>strat->Lmax)
1764  {
1765    j=((j+setmaxLinc-1)/setmaxLinc)*setmaxLinc;
1766    strat->L = (LSet)omReallocSize(strat->L,strat->Lmax*sizeof(LObject),
1767                                 j*sizeof(LObject));
1768    strat->Lmax=j;
1769  }
1770  j = strat->Ll;
1771  int i;
1772  for (i=strat->Bl; i>=0; i--)
1773  {
1774    j = strat->posInL(strat->L,j,&(strat->B[i]),strat);
1775    enterL(&strat->L,&strat->Ll,&strat->Lmax,strat->B[i],j);
1776  }
1777  strat->Bl = -1;
1778}
1779/*2
1780*the pairset B of pairs of type (s[i],p) is complete now. It will be updated
1781*using the chain-criterion in B and L and enters B to L
1782*/
1783void chainCritNormal (poly p,int ecart,kStrategy strat)
1784{
1785  int i,j,l;
1786
1787  /*
1788  *pairtest[i] is TRUE if spoly(S[i],p) == 0.
1789  *In this case all elements in B such
1790  *that their lcm is divisible by the leading term of S[i] can be canceled
1791  */
1792  if (strat->pairtest!=NULL)
1793  {
1794    {
1795      /*- i.e. there is an i with pairtest[i]==TRUE -*/
1796      for (j=0; j<=strat->sl; j++)
1797      {
1798        if (strat->pairtest[j])
1799        {
1800          for (i=strat->Bl; i>=0; i--)
1801          {
1802            if (pDivisibleBy(strat->S[j],strat->B[i].lcm))
1803            {
1804              deleteInL(strat->B,&strat->Bl,i,strat);
1805              strat->c3++;
1806            }
1807          }
1808        }
1809      }
1810    }
1811    omFreeSize(strat->pairtest,(strat->sl+2)*sizeof(BOOLEAN));
1812    strat->pairtest=NULL;
1813  }
1814  if (strat->Gebauer || strat->fromT)
1815  {
1816    if (strat->sugarCrit)
1817    {
1818    /*
1819    *suppose L[j] == (s,r) and p/lcm(s,r)
1820    *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
1821    *and in case the sugar is o.k. then L[j] can be canceled
1822    */
1823      for (j=strat->Ll; j>=0; j--)
1824      {
1825        if (sugarDivisibleBy(ecart,strat->L[j].ecart)
1826        && ((pNext(strat->L[j].p) == strat->tail) || (pOrdSgn==1))
1827        && pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1828        {
1829          if (strat->L[j].p == strat->tail)
1830          {
1831              deleteInL(strat->L,&strat->Ll,j,strat);
1832              strat->c3++;
1833          }
1834        }
1835      }
1836      /*
1837      *this is GEBAUER-MOELLER:
1838      *in B all elements with the same lcm except the "best"
1839      *(i.e. the last one in B with this property) will be canceled
1840      */
1841      j = strat->Bl;
1842      loop /*cannot be changed into a for !!! */
1843      {
1844        if (j <= 0) break;
1845        i = j-1;
1846        loop
1847        {
1848          if (i <  0) break;
1849          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
1850          {
1851            strat->c3++;
1852            if (sugarDivisibleBy(strat->B[j].ecart,strat->B[i].ecart))
1853            {
1854              deleteInL(strat->B,&strat->Bl,i,strat);
1855              j--;
1856            }
1857            else
1858            {
1859              deleteInL(strat->B,&strat->Bl,j,strat);
1860              break;
1861            }
1862          }
1863          i--;
1864        }
1865        j--;
1866      }
1867    }
1868    else /*sugarCrit*/
1869    {
1870      /*
1871      *suppose L[j] == (s,r) and p/lcm(s,r)
1872      *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
1873      *and in case the sugar is o.k. then L[j] can be canceled
1874      */
1875      for (j=strat->Ll; j>=0; j--)
1876      {
1877        if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1878        {
1879          if ((pNext(strat->L[j].p) == strat->tail)||(pOrdSgn==1))
1880          {
1881            deleteInL(strat->L,&strat->Ll,j,strat);
1882            strat->c3++;
1883          }
1884        }
1885      }
1886      /*
1887      *this is GEBAUER-MOELLER:
1888      *in B all elements with the same lcm except the "best"
1889      *(i.e. the last one in B with this property) will be canceled
1890      */
1891      j = strat->Bl;
1892      loop   /*cannot be changed into a for !!! */
1893      {
1894        if (j <= 0) break;
1895        for(i=j-1; i>=0; i--)
1896        {
1897          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
1898          {
1899            strat->c3++;
1900            deleteInL(strat->B,&strat->Bl,i,strat);
1901            j--;
1902          }
1903        }
1904        j--;
1905      }
1906    }
1907    /*
1908    *the elements of B enter L
1909    */
1910    kMergeBintoL(strat);
1911  }
1912  else
1913  {
1914    for (j=strat->Ll; j>=0; j--)
1915    {
1916      if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1917      {
1918        if ((pNext(strat->L[j].p) == strat->tail)||(pOrdSgn==1))
1919        {
1920          deleteInL(strat->L,&strat->Ll,j,strat);
1921          strat->c3++;
1922        }
1923      }
1924    }
1925    /*
1926    *this is our MODIFICATION of GEBAUER-MOELLER:
1927    *First the elements of B enter L,
1928    *then we fix a lcm and the "best" element in L
1929    *(i.e the last in L with this lcm and of type (s,p))
1930    *and cancel all the other elements of type (r,p) with this lcm
1931    *except the case the element (s,r) has also the same lcm
1932    *and is on the worst position with respect to (s,p) and (r,p)
1933    */
1934    /*
1935    *B enters to L/their order with respect to B is permutated for elements
1936    *B[i].p with the same leading term
1937    */
1938    kMergeBintoL(strat);
1939    j = strat->Ll;
1940    loop  /*cannot be changed into a for !!! */
1941    {
1942      if (j <= 0)
1943      {
1944        /*now L[0] cannot be canceled any more and the tail can be removed*/
1945        if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
1946        break;
1947      }
1948      if (strat->L[j].p2 == p)
1949      {
1950        i = j-1;
1951        loop
1952        {
1953          if (i < 0)  break;
1954          if ((strat->L[i].p2 == p) && pLmEqual(strat->L[j].lcm,strat->L[i].lcm))
1955          {
1956            /*L[i] could be canceled but we search for a better one to cancel*/
1957            strat->c3++;
1958            if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
1959            && (pNext(strat->L[l].p) == strat->tail)
1960            && (!pLmEqual(strat->L[i].p,strat->L[l].p))
1961            && pDivisibleBy(p,strat->L[l].lcm))
1962            {
1963              /*
1964              *"NOT equal(...)" because in case of "equal" the element L[l]
1965              *is "older" and has to be from theoretical point of view behind
1966              *L[i], but we do not want to reorder L
1967              */
1968              strat->L[i].p2 = strat->tail;
1969              /*
1970              *L[l] will be canceled, we cannot cancel L[i] later on,
1971              *so we mark it with "tail"
1972              */
1973              deleteInL(strat->L,&strat->Ll,l,strat);
1974              i--;
1975            }
1976            else
1977            {
1978              deleteInL(strat->L,&strat->Ll,i,strat);
1979            }
1980            j--;
1981          }
1982          i--;
1983        }
1984      }
1985      else if (strat->L[j].p2 == strat->tail)
1986      {
1987        /*now L[j] cannot be canceled any more and the tail can be removed*/
1988        strat->L[j].p2 = p;
1989      }
1990      j--;
1991    }
1992  }
1993}
1994#ifdef HAVE_RATGRING
1995void chainCritPart (poly p,int ecart,kStrategy strat)
1996{
1997  int i,j,l;
1998
1999  /*
2000  *pairtest[i] is TRUE if spoly(S[i],p) == 0.
2001  *In this case all elements in B such
2002  *that their lcm is divisible by the leading term of S[i] can be canceled
2003  */
2004  if (strat->pairtest!=NULL)
2005  {
2006    {
2007      /*- i.e. there is an i with pairtest[i]==TRUE -*/
2008      for (j=0; j<=strat->sl; j++)
2009      {
2010        if (strat->pairtest[j])
2011        {
2012          for (i=strat->Bl; i>=0; i--)
2013          {
2014            if (_p_LmDivisibleByPart(strat->S[j],currRing,
2015               strat->B[i].lcm,currRing,
2016               currRing->real_var_start,currRing->real_var_end))
2017            {
2018              if(TEST_OPT_DEBUG)
2019              {
2020                 Print("chain-crit-part: S[%d]=",j);
2021                 p_wrp(strat->S[j],currRing);
2022                 Print(" divide B[%d].lcm=",i);
2023                 p_wrp(strat->B[i].lcm,currRing);
2024                 PrintLn();
2025              }
2026              deleteInL(strat->B,&strat->Bl,i,strat);
2027              strat->c3++;
2028            }
2029          }
2030        }
2031      }
2032    }
2033    omFreeSize(strat->pairtest,(strat->sl+2)*sizeof(BOOLEAN));
2034    strat->pairtest=NULL;
2035  }
2036  if (strat->Gebauer || strat->fromT)
2037  {
2038    if (strat->sugarCrit)
2039    {
2040    /*
2041    *suppose L[j] == (s,r) and p/lcm(s,r)
2042    *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
2043    *and in case the sugar is o.k. then L[j] can be canceled
2044    */
2045      for (j=strat->Ll; j>=0; j--)
2046      {
2047        if (sugarDivisibleBy(ecart,strat->L[j].ecart)
2048        && ((pNext(strat->L[j].p) == strat->tail) || (pOrdSgn==1))
2049        && pCompareChainPart(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
2050        {
2051          if (strat->L[j].p == strat->tail)
2052          {
2053              if(TEST_OPT_DEBUG)
2054              {
2055                 PrintS("chain-crit-part: pCompareChainPart p=");
2056                 p_wrp(p,currRing);
2057                 Print(" delete L[%d]",j);
2058                 p_wrp(strat->L[j].lcm,currRing);
2059                 PrintLn();
2060              }
2061              deleteInL(strat->L,&strat->Ll,j,strat);
2062              strat->c3++;
2063          }
2064        }
2065      }
2066      /*
2067      *this is GEBAUER-MOELLER:
2068      *in B all elements with the same lcm except the "best"
2069      *(i.e. the last one in B with this property) will be canceled
2070      */
2071      j = strat->Bl;
2072      loop /*cannot be changed into a for !!! */
2073      {
2074        if (j <= 0) break;
2075        i = j-1;
2076        loop
2077        {
2078          if (i <  0) break;
2079          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
2080          {
2081            strat->c3++;
2082            if (sugarDivisibleBy(strat->B[j].ecart,strat->B[i].ecart))
2083            {
2084              if(TEST_OPT_DEBUG)
2085              {
2086                 Print("chain-crit-part: sugar B[%d].lcm=",j);
2087                 p_wrp(strat->B[j].lcm,currRing);
2088                 Print(" delete B[%d]",i);
2089                 p_wrp(strat->B[i].lcm,currRing);
2090                 PrintLn();
2091              }
2092              deleteInL(strat->B,&strat->Bl,i,strat);
2093              j--;
2094            }
2095            else
2096            {
2097              if(TEST_OPT_DEBUG)
2098              {
2099                 Print("chain-crit-part: sugar B[%d].lcm=",i);
2100                 p_wrp(strat->B[i].lcm,currRing);
2101                 Print(" delete B[%d]",j);
2102                 p_wrp(strat->B[j].lcm,currRing);
2103                 PrintLn();
2104              }
2105              deleteInL(strat->B,&strat->Bl,j,strat);
2106              break;
2107            }
2108          }
2109          i--;
2110        }
2111        j--;
2112      }
2113    }
2114    else /*sugarCrit*/
2115    {
2116      /*
2117      *suppose L[j] == (s,r) and p/lcm(s,r)
2118      *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
2119      *and in case the sugar is o.k. then L[j] can be canceled
2120      */
2121      for (j=strat->Ll; j>=0; j--)
2122      {
2123        if (pCompareChainPart(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
2124        {
2125          if ((pNext(strat->L[j].p) == strat->tail)||(pOrdSgn==1))
2126          {
2127              if(TEST_OPT_DEBUG)
2128              {
2129                 PrintS("chain-crit-part: sugar:pCompareChainPart p=");
2130                 p_wrp(p,currRing);
2131                 Print(" delete L[%d]",j);
2132                 p_wrp(strat->L[j].lcm,currRing);
2133                 PrintLn();
2134              }
2135            deleteInL(strat->L,&strat->Ll,j,strat);
2136            strat->c3++;
2137          }
2138        }
2139      }
2140      /*
2141      *this is GEBAUER-MOELLER:
2142      *in B all elements with the same lcm except the "best"
2143      *(i.e. the last one in B with this property) will be canceled
2144      */
2145      j = strat->Bl;
2146      loop   /*cannot be changed into a for !!! */
2147      {
2148        if (j <= 0) break;
2149        for(i=j-1; i>=0; i--)
2150        {
2151          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
2152          {
2153              if(TEST_OPT_DEBUG)
2154              {
2155                 Print("chain-crit-part: equal lcm B[%d].lcm=",j);
2156                 p_wrp(strat->B[j].lcm,currRing);
2157                 Print(" delete B[%d]\n",i);
2158              }
2159            strat->c3++;
2160            deleteInL(strat->B,&strat->Bl,i,strat);
2161            j--;
2162          }
2163        }
2164        j--;
2165      }
2166    }
2167    /*
2168    *the elements of B enter L
2169    */
2170    kMergeBintoL(strat);
2171  }
2172  else
2173  {
2174    for (j=strat->Ll; j>=0; j--)
2175    {
2176      if (pCompareChainPart(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
2177      {
2178        if ((pNext(strat->L[j].p) == strat->tail)||(pOrdSgn==1))
2179        {
2180              if(TEST_OPT_DEBUG)
2181              {
2182                 PrintS("chain-crit-part: pCompareChainPart p=");
2183                 p_wrp(p,currRing);
2184                 Print(" delete L[%d]",j);
2185                 p_wrp(strat->L[j].lcm,currRing);
2186                 PrintLn();
2187              }
2188          deleteInL(strat->L,&strat->Ll,j,strat);
2189          strat->c3++;
2190        }
2191      }
2192    }
2193    /*
2194    *this is our MODIFICATION of GEBAUER-MOELLER:
2195    *First the elements of B enter L,
2196    *then we fix a lcm and the "best" element in L
2197    *(i.e the last in L with this lcm and of type (s,p))
2198    *and cancel all the other elements of type (r,p) with this lcm
2199    *except the case the element (s,r) has also the same lcm
2200    *and is on the worst position with respect to (s,p) and (r,p)
2201    */
2202    /*
2203    *B enters to L/their order with respect to B is permutated for elements
2204    *B[i].p with the same leading term
2205    */
2206    kMergeBintoL(strat);
2207    j = strat->Ll;
2208    loop  /*cannot be changed into a for !!! */
2209    {
2210      if (j <= 0)
2211      {
2212        /*now L[0] cannot be canceled any more and the tail can be removed*/
2213        if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
2214        break;
2215      }
2216      if (strat->L[j].p2 == p)
2217      {
2218        i = j-1;
2219        loop
2220        {
2221          if (i < 0)  break;
2222          if ((strat->L[i].p2 == p) && pLmEqual(strat->L[j].lcm,strat->L[i].lcm))
2223          {
2224            /*L[i] could be canceled but we search for a better one to cancel*/
2225            strat->c3++;
2226            if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
2227            && (pNext(strat->L[l].p) == strat->tail)
2228            && (!pLmEqual(strat->L[i].p,strat->L[l].p))
2229            && _p_LmDivisibleByPart(p,currRing,
2230                           strat->L[l].lcm,currRing,
2231                           currRing->real_var_start, currRing->real_var_end))
2232
2233            {
2234              /*
2235              *"NOT equal(...)" because in case of "equal" the element L[l]
2236              *is "older" and has to be from theoretical point of view behind
2237              *L[i], but we do not want to reorder L
2238              */
2239              strat->L[i].p2 = strat->tail;
2240              /*
2241              *L[l] will be canceled, we cannot cancel L[i] later on,
2242              *so we mark it with "tail"
2243              */
2244              if(TEST_OPT_DEBUG)
2245              {
2246                 PrintS("chain-crit-part: divisible_by p=");
2247                 p_wrp(p,currRing);
2248                 Print(" delete L[%d]",l);
2249                 p_wrp(strat->L[l].lcm,currRing);
2250                 PrintLn();
2251              }
2252              deleteInL(strat->L,&strat->Ll,l,strat);
2253              i--;
2254            }
2255            else
2256            {
2257              if(TEST_OPT_DEBUG)
2258              {
2259                 PrintS("chain-crit-part: divisible_by(2) p=");
2260                 p_wrp(p,currRing);
2261                 Print(" delete L[%d]",i);
2262                 p_wrp(strat->L[i].lcm,currRing);
2263                 PrintLn();
2264              }
2265              deleteInL(strat->L,&strat->Ll,i,strat);
2266            }
2267            j--;
2268          }
2269          i--;
2270        }
2271      }
2272      else if (strat->L[j].p2 == strat->tail)
2273      {
2274        /*now L[j] cannot be canceled any more and the tail can be removed*/
2275        strat->L[j].p2 = p;
2276      }
2277      j--;
2278    }
2279  }
2280}
2281#endif
2282
2283/*2
2284*(s[0],h),...,(s[k],h) will be put to the pairset L
2285*/
2286void initenterpairs (poly h,int k,int ecart,int isFromQ,kStrategy strat, int atR = -1)
2287{
2288
2289  if ((strat->syzComp==0)
2290  || (pGetComp(h)<=strat->syzComp))
2291  {
2292    int j;
2293    BOOLEAN new_pair=FALSE;
2294
2295    if (pGetComp(h)==0)
2296    {
2297      /* for Q!=NULL: build pairs (f,q),(f1,f2), but not (q1,q2)*/
2298      if ((isFromQ)&&(strat->fromQ!=NULL))
2299      {
2300        for (j=0; j<=k; j++)
2301        {
2302          if (!strat->fromQ[j])
2303          {
2304            new_pair=TRUE;
2305            strat->enterOnePair(j,h,ecart,isFromQ,strat, atR);
2306          //Print("j:%d, Ll:%d\n",j,strat->Ll);
2307          }
2308        }
2309      }
2310      else
2311      {
2312        new_pair=TRUE;
2313        for (j=0; j<=k; j++)
2314        {
2315          strat->enterOnePair(j,h,ecart,isFromQ,strat, atR);
2316          //Print("j:%d, Ll:%d\n",j,strat->Ll);
2317        }
2318      }
2319    }
2320    else
2321    {
2322      for (j=0; j<=k; j++)
2323      {
2324        if ((pGetComp(h)==pGetComp(strat->S[j]))
2325        || (pGetComp(strat->S[j])==0))
2326        {
2327          new_pair=TRUE;
2328          strat->enterOnePair(j,h,ecart,isFromQ,strat, atR);
2329        //Print("j:%d, Ll:%d\n",j,strat->Ll);
2330        }
2331      }
2332    }
2333
2334    if (new_pair)
2335    {
2336#ifdef HAVE_RATGRING
2337      if (currRing->real_var_start>0)
2338        chainCritPart(h,ecart,strat);
2339      else
2340#endif
2341      strat->chainCrit(h,ecart,strat);
2342    }
2343  }
2344}
2345
2346#ifdef HAVE_RINGS
2347/*2
2348*the pairset B of pairs of type (s[i],p) is complete now. It will be updated
2349*using the chain-criterion in B and L and enters B to L
2350*/
2351void chainCritRing (poly p,int ecart,kStrategy strat)
2352{
2353  int i,j,l;
2354  /*
2355  *pairtest[i] is TRUE if spoly(S[i],p) == 0.
2356  *In this case all elements in B such
2357  *that their lcm is divisible by the leading term of S[i] can be canceled
2358  */
2359  if (strat->pairtest!=NULL)
2360  {
2361    {
2362      /*- i.e. there is an i with pairtest[i]==TRUE -*/
2363      for (j=0; j<=strat->sl; j++)
2364      {
2365        if (strat->pairtest[j])
2366        {
2367          for (i=strat->Bl; i>=0; i--)
2368          {
2369            if (pDivisibleBy(strat->S[j],strat->B[i].lcm))
2370            {
2371#ifdef KDEBUG
2372              if (TEST_OPT_DEBUG)
2373              {
2374                PrintS("--- chain criterion func chainCritRing type 1\n");
2375                PrintS("strat->S[j]:");
2376                wrp(strat->S[j]);
2377                PrintS("  strat->B[i].lcm:");
2378                wrp(strat->B[i].lcm);
2379                PrintLn();
2380              }
2381#endif
2382              deleteInL(strat->B,&strat->Bl,i,strat);
2383              strat->c3++;
2384            }
2385          }
2386        }
2387      }
2388    }
2389    omFreeSize(strat->pairtest,(strat->sl+2)*sizeof(BOOLEAN));
2390    strat->pairtest=NULL;
2391  }
2392  assume(!(strat->Gebauer || strat->fromT));
2393  for (j=strat->Ll; j>=0; j--)
2394  {
2395    if (strat->L[j].lcm != NULL && nDivBy(pGetCoeff(strat->L[j].lcm), pGetCoeff(p)))
2396    {
2397      if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
2398      {
2399        if ((pNext(strat->L[j].p) == strat->tail) || (pOrdSgn==1))
2400        {
2401          deleteInL(strat->L,&strat->Ll,j,strat);
2402          strat->c3++;
2403#ifdef KDEBUG
2404              if (TEST_OPT_DEBUG)
2405              {
2406                PrintS("--- chain criterion func chainCritRing type 2\n");
2407                PrintS("strat->L[j].p:");
2408                wrp(strat->L[j].p);
2409                PrintS("  p:");
2410                wrp(p);
2411                PrintLn();
2412              }
2413#endif
2414        }
2415      }
2416    }
2417  }
2418  /*
2419  *this is our MODIFICATION of GEBAUER-MOELLER:
2420  *First the elements of B enter L,
2421  *then we fix a lcm and the "best" element in L
2422  *(i.e the last in L with this lcm and of type (s,p))
2423  *and cancel all the other elements of type (r,p) with this lcm
2424  *except the case the element (s,r) has also the same lcm
2425  *and is on the worst position with respect to (s,p) and (r,p)
2426  */
2427  /*
2428  *B enters to L/their order with respect to B is permutated for elements
2429  *B[i].p with the same leading term
2430  */
2431  kMergeBintoL(strat);
2432  j = strat->Ll;
2433  loop  /*cannot be changed into a for !!! */
2434  {
2435    if (j <= 0)
2436    {
2437      /*now L[0] cannot be canceled any more and the tail can be removed*/
2438      if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
2439      break;
2440    }
2441    if (strat->L[j].p2 == p) // Was the element added from B?
2442    {
2443      i = j-1;
2444      loop
2445      {
2446        if (i < 0)  break;
2447        // Element is from B and has the same lcm as L[j]
2448        if ((strat->L[i].p2 == p) && nDivBy(pGetCoeff(strat->L[j].lcm), pGetCoeff(strat->L[i].lcm))
2449             && pLmEqual(strat->L[j].lcm,strat->L[i].lcm))
2450        {
2451          /*L[i] could be canceled but we search for a better one to cancel*/
2452          strat->c3++;
2453#ifdef KDEBUG
2454          if (TEST_OPT_DEBUG)
2455          {
2456            PrintS("--- chain criterion func chainCritRing type 3\n");
2457            PrintS("strat->L[j].lcm:");
2458            wrp(strat->L[j].lcm);
2459            PrintS("  strat->L[i].lcm:");
2460            wrp(strat->L[i].lcm);
2461            PrintLn();
2462          }
2463#endif
2464          if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
2465          && (pNext(strat->L[l].p) == strat->tail)
2466          && (!pLmEqual(strat->L[i].p,strat->L[l].p))
2467          && pDivisibleBy(p,strat->L[l].lcm))
2468          {
2469            /*
2470            *"NOT equal(...)" because in case of "equal" the element L[l]
2471            *is "older" and has to be from theoretical point of view behind
2472            *L[i], but we do not want to reorder L
2473            */
2474            strat->L[i].p2 = strat->tail;
2475            /*
2476            *L[l] will be canceled, we cannot cancel L[i] later on,
2477            *so we mark it with "tail"
2478            */
2479            deleteInL(strat->L,&strat->Ll,l,strat);
2480            i--;
2481          }
2482          else
2483          {
2484            deleteInL(strat->L,&strat->Ll,i,strat);
2485          }
2486          j--;
2487        }
2488        i--;
2489      }
2490    }
2491    else if (strat->L[j].p2 == strat->tail)
2492    {
2493      /*now L[j] cannot be canceled any more and the tail can be removed*/
2494      strat->L[j].p2 = p;
2495    }
2496    j--;
2497  }
2498}
2499#endif
2500
2501#ifdef HAVE_RINGS
2502long ind2(long arg)
2503{
2504  long ind = 0;
2505  if (arg <= 0) return 0;
2506  while (arg%2 == 0)
2507  {
2508    arg = arg / 2;
2509    ind++;
2510  }
2511  return ind;
2512}
2513
2514long ind_fact_2(long arg)
2515{
2516  long ind = 0;
2517  if (arg <= 0) return 0;
2518  if (arg%2 == 1) { arg--; }
2519  while (arg > 0)
2520  {
2521    ind += ind2(arg);
2522    arg = arg - 2;
2523  }
2524  return ind;
2525}
2526#endif
2527
2528#ifdef HAVE_VANIDEAL
2529long twoPow(long arg)
2530{
2531  return 1L << arg;
2532}
2533
2534/*2
2535* put the pair (p, f) in B and f in T
2536*/
2537void enterOneZeroPairRing (poly f, poly t_p, poly p, int ecart, kStrategy strat, int atR = -1)
2538{
2539  int      l,j,compare,compareCoeff;
2540  LObject  Lp;
2541
2542  if (strat->interred_flag) return;
2543#ifdef KDEBUG
2544  Lp.ecart=0; Lp.length=0;
2545#endif
2546  /*- computes the lcm(s[i],p) -*/
2547  Lp.lcm = pInit();
2548
2549  pLcm(p,f,Lp.lcm);
2550  pSetm(Lp.lcm);
2551  pSetCoeff(Lp.lcm, nLcm(pGetCoeff(p), pGetCoeff(f), currRing));
2552  assume(!strat->sugarCrit);
2553  assume(!strat->fromT);
2554  /*
2555  *the set B collects the pairs of type (S[j],p)
2556  *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p) != lcm(r,p)
2557  *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
2558  *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
2559  */
2560  for(j = strat->Bl;j>=0;j--)
2561  {
2562    compare=pDivCompRing(strat->B[j].lcm,Lp.lcm);
2563    compareCoeff = nDivComp(pGetCoeff(strat->B[j].lcm), pGetCoeff(Lp.lcm));
2564    if (compareCoeff == 0 || compare == compareCoeff)
2565    {
2566      if (compare == 1)
2567      {
2568        strat->c3++;
2569        pLmDelete(Lp.lcm);
2570        return;
2571      }
2572      else
2573      if (compare == -1)
2574      {
2575        deleteInL(strat->B,&strat->Bl,j,strat);
2576        strat->c3++;
2577      }
2578    }
2579    if (compare == pDivComp_EQUAL)
2580    {
2581      // Add hint for same LM and direction of LC (later) (TODO Oliver)
2582      if (compareCoeff == 1)
2583      {
2584        strat->c3++;
2585        pLmDelete(Lp.lcm);
2586        return;
2587      }
2588      else
2589      if (compareCoeff == -1)
2590      {
2591        deleteInL(strat->B,&strat->Bl,j,strat);
2592        strat->c3++;
2593      }
2594    }
2595  }
2596  /*
2597  *the pair (S[i],p) enters B if the spoly != 0
2598  */
2599  /*-  compute the short s-polynomial -*/
2600  if ((f==NULL) || (p==NULL)) return;
2601  pNorm(p);
2602  {
2603    Lp.p = ksCreateShortSpoly(f, p, strat->tailRing);
2604  }
2605  if (Lp.p == NULL) //deactivated, as we are adding pairs with zeropoly and not from S
2606  {
2607    /*- the case that the s-poly is 0 -*/
2608//    if (strat->pairtest==NULL) initPairtest(strat);
2609//    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
2610//    strat->pairtest[strat->sl+1] = TRUE;
2611    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
2612    /*
2613    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
2614    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
2615    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
2616    *term of p devides the lcm(s,r)
2617    *(this canceling should be done here because
2618    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
2619    *the first case is handeled in chainCrit
2620    */
2621    if (Lp.lcm!=NULL) pLmDelete(Lp.lcm);
2622  }
2623  else
2624  {
2625    /*- the pair (S[i],p) enters B -*/
2626    Lp.p1 = f;
2627    Lp.p2 = p;
2628
2629    pNext(Lp.p) = strat->tail;
2630
2631    LObject tmp_h(f, currRing, strat->tailRing);
2632    tmp_h.SetShortExpVector();
2633    strat->initEcart(&tmp_h);
2634    tmp_h.sev = pGetShortExpVector(tmp_h.p);
2635    tmp_h.t_p = t_p;
2636
2637    enterT(tmp_h, strat, strat->tl + 1);
2638
2639    if (atR >= 0)
2640    {
2641      Lp.i_r2 = atR;
2642      Lp.i_r1 = strat->tl;
2643    }
2644
2645    strat->initEcartPair(&Lp,f,p,0/*strat->ecartS[i]*/,ecart);     // Attention: TODO: break ecart
2646    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
2647    enterL(&strat->B, &strat->Bl, &strat->Bmax, Lp, l);
2648  }
2649}
2650
2651/* Helper for kCreateZeroPoly
2652 * enumerating the exponents
2653ring r = 2^2, (a, b, c), lp; ideal G0 = system("createG0"); ideal G = interred(G0); ncols(G0); ncols(G);
2654 */
2655
2656int nextZeroSimplexExponent (long exp[], long ind[], long cexp[], long cind[], long* cabsind, long step[], long bound, long N)
2657/* gives the next exponent from the set H_1 */
2658{
2659  long add = ind2(cexp[1] + 2);
2660  if ((*cabsind < bound) && (*cabsind - step[1] + add < bound))
2661  {
2662    cexp[1] += 2;
2663    cind[1] += add;
2664    *cabsind += add;
2665  }
2666  else
2667  {
2668    // cabsind >= habsind
2669    if (N == 1) return 0;
2670    int i = 1;
2671    while (exp[i] == cexp[i] && i <= N) i++;
2672    cexp[i] = exp[i];
2673    *cabsind -= cind[i];
2674    cind[i] = ind[i];
2675    step[i] = 500000;
2676    *cabsind += cind[i];
2677    // Print("in: %d\n", *cabsind);
2678    i += 1;
2679    if (i > N) return 0;
2680    do
2681    {
2682      step[1] = 500000;
2683      for (int j = i + 1; j <= N; j++)
2684      {
2685        if (step[1] > step[j]) step[1] = step[j];
2686      }
2687      add = ind2(cexp[i] + 2);
2688      if (*cabsind - step[1] + add >= bound)
2689      {
2690        cexp[i] = exp[i];
2691        *cabsind -= cind[i];
2692        cind[i] = ind[i];
2693        *cabsind += cind[i];
2694        step[i] = 500000;
2695        i += 1;
2696        if (i > N) return 0;
2697      }
2698      else step[1] = -1;
2699    } while (step[1] != -1);
2700    step[1] = 500000;
2701    cexp[i] += 2;
2702    cind[i] += add;
2703    *cabsind += add;
2704    if (add < step[i]) step[i] = add;
2705    for (i = 2; i <= N; i++)
2706    {
2707      if (step[1] > step[i]) step[1] = step[i];
2708    }
2709  }
2710  return 1;
2711}
2712
2713/*
2714 * Creates the zero Polynomial on position exp
2715 * long exp[] : exponent of leading term
2716 * cabsind    : total 2-ind of exp (if -1 will be computed)
2717 * poly* t_p  : will hold the LT in tailRing
2718 * leadRing   : ring for the LT
2719 * tailRing   : ring for the tail
2720 */
2721
2722poly kCreateZeroPoly(long exp[], long cabsind, poly* t_p, ring leadRing, ring tailRing)
2723{
2724
2725  poly zeroPoly = NULL;
2726
2727  number tmp1;
2728  poly tmp2, tmp3;
2729
2730  if (cabsind == -1)
2731  {
2732    cabsind = 0;
2733    for (int i = 1; i <= leadRing->N; i++)
2734    {
2735      cabsind += ind_fact_2(exp[i]);
2736    }
2737//    Print("cabsind: %d\n", cabsind);
2738  }
2739  if (cabsind < leadRing->ch)
2740  {
2741    zeroPoly = p_ISet(twoPow(leadRing->ch - cabsind), tailRing);
2742  }
2743  else
2744  {
2745    zeroPoly = p_ISet(1, tailRing);
2746  }
2747  for (int i = 1; i <= leadRing->N; i++)
2748  {
2749    for (long j = 1; j <= exp[i]; j++)
2750    {
2751      tmp1 = nInit(j);
2752      tmp2 = p_ISet(1, tailRing);
2753      p_SetExp(tmp2, i, 1, tailRing);
2754      p_Setm(tmp2, tailRing);
2755      if (nIsZero(tmp1))
2756      { // should nowbe obsolet, test ! TODO OLIVER
2757        zeroPoly = p_Mult_q(zeroPoly, tmp2, tailRing);
2758      }
2759      else
2760      {
2761        tmp3 = p_NSet(nCopy(tmp1), tailRing);
2762        zeroPoly = p_Mult_q(zeroPoly, p_Add_q(tmp3, tmp2, tailRing), tailRing);
2763      }
2764    }
2765  }
2766  tmp2 = p_NSet(nCopy(pGetCoeff(zeroPoly)), leadRing);
2767  for (int i = 1; i <= leadRing->N; i++)
2768  {
2769    pSetExp(tmp2, i, p_GetExp(zeroPoly, i, tailRing));
2770  }
2771  p_Setm(tmp2, leadRing);
2772  *t_p = zeroPoly;
2773  zeroPoly = pNext(zeroPoly);
2774  pNext(*t_p) = NULL;
2775  pNext(tmp2) = zeroPoly;
2776  return tmp2;
2777}
2778
2779// #define OLI_DEBUG
2780
2781/*
2782 * Generate the s-polynomial for the virtual set of zero-polynomials
2783 */
2784
2785void initenterzeropairsRing (poly p, int ecart, kStrategy strat, int atR)
2786{
2787  // Initialize
2788  long exp[50];            // The exponent of \hat{X} (basepoint)
2789  long cexp[50];           // The current exponent for iterating over all
2790  long ind[50];            // The power of 2 in the i-th component of exp
2791  long cind[50];           // analog for cexp
2792  long mult[50];           // How to multiply the elements of G
2793  long cabsind = 0;        // The abs. index of cexp, i.e. the sum of cind
2794  long habsind = 0;        // The abs. index of the coefficient of h
2795  long step[50];           // The last increases
2796  for (int i = 1; i <= currRing->N; i++)
2797  {
2798    exp[i] = p_GetExp(p, i, currRing);
2799    if (exp[i] & 1 != 0)
2800    {
2801      exp[i] = exp[i] - 1;
2802      mult[i] = 1;
2803    }
2804    cexp[i] = exp[i];
2805    ind[i] = ind_fact_2(exp[i]);
2806    cabsind += ind[i];
2807    cind[i] = ind[i];
2808    step[i] = 500000;
2809  }
2810  step[1] = 500000;
2811  habsind = ind2((long) p_GetCoeff(p, currRing));
2812  long bound = currRing->ch - habsind;
2813#ifdef OLI_DEBUG
2814  PrintS("-------------\npoly  :");
2815  wrp(p);
2816  Print("\nexp   : (%d, %d)\n", exp[1] + mult[1], exp[2] + mult[1]);
2817  Print("cexp  : (%d, %d)\n", cexp[1], cexp[2]);
2818  Print("cind  : (%d, %d)\n", cind[1], cind[2]);
2819  Print("bound : %d\n", bound);
2820  Print("cind  : %d\n", cabsind);
2821#endif
2822  if (cabsind == 0)
2823  {
2824    if (!(nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N)))
2825    {
2826      return;
2827    }
2828  }
2829  // Now the whole simplex
2830  do
2831  {
2832    // Build s-polynomial
2833    // 2**ind-def * mult * g - exp-def * h
2834    poly t_p;
2835    poly zeroPoly = kCreateZeroPoly(cexp, cabsind, &t_p, currRing, strat->tailRing);
2836#ifdef OLI_DEBUG
2837    Print("%d, (%d, %d), ind = (%d, %d)\n", cabsind, cexp[1], cexp[2], cind[1], cind[2]);
2838    Print("zPoly : ");
2839    wrp(zeroPoly);
2840    Print("\n");
2841#endif
2842    enterOneZeroPairRing(zeroPoly, t_p, p, ecart, strat, atR);
2843  }
2844  while ( nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N) );
2845}
2846
2847/*
2848 * Create the Groebner basis of the vanishing polynomials.
2849 */
2850
2851ideal createG0()
2852{
2853  // Initialize
2854  long exp[50];            // The exponent of \hat{X} (basepoint)
2855  long cexp[50];           // The current exponent for iterating over all
2856  long ind[50];            // The power of 2 in the i-th component of exp
2857  long cind[50];           // analog for cexp
2858  long mult[50];           // How to multiply the elements of G
2859  long cabsind = 0;        // The abs. index of cexp, i.e. the sum of cind
2860  long habsind = 0;        // The abs. index of the coefficient of h
2861  long step[50];           // The last increases
2862  for (int i = 1; i <= currRing->N; i++)
2863  {
2864    exp[i] = 0;
2865    cexp[i] = exp[i];
2866    ind[i] = 0;
2867    step[i] = 500000;
2868    cind[i] = ind[i];
2869  }
2870  long bound = currRing->ch;
2871  step[1] = 500000;
2872#ifdef OLI_DEBUG
2873  PrintS("-------------\npoly  :");
2874//  wrp(p);
2875  Print("\nexp   : (%d, %d)\n", exp[1] + mult[1], exp[2] + mult[1]);
2876  Print("cexp  : (%d, %d)\n", cexp[1], cexp[2]);
2877  Print("cind  : (%d, %d)\n", cind[1], cind[2]);
2878  Print("bound : %d\n", bound);
2879  Print("cind  : %d\n", cabsind);
2880#endif
2881  if (cabsind == 0)
2882  {
2883    if (!(nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N)))
2884    {
2885      return idInit(1, 1);
2886    }
2887  }
2888  ideal G0 = idInit(1, 1);
2889  // Now the whole simplex
2890  do
2891  {
2892    // Build s-polynomial
2893    // 2**ind-def * mult * g - exp-def * h
2894    poly t_p;
2895    poly zeroPoly = kCreateZeroPoly(cexp, cabsind, &t_p, currRing, currRing);
2896#ifdef OLI_DEBUG
2897    Print("%d, (%d, %d), ind = (%d, %d)\n", cabsind, cexp[1], cexp[2], cind[1], cind[2]);
2898    Print("zPoly : ");
2899    wrp(zeroPoly);
2900    Print("\n");
2901#endif
2902    // Add to ideal
2903    pEnlargeSet(&(G0->m), IDELEMS(G0), 1);
2904    IDELEMS(G0) += 1;
2905    G0->m[IDELEMS(G0) - 1] = zeroPoly;
2906  }
2907  while ( nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N) );
2908  idSkipZeroes(G0);
2909  return G0;
2910}
2911#endif
2912
2913#ifdef HAVE_RINGS
2914/*2
2915*(s[0],h),...,(s[k],h) will be put to the pairset L
2916*/
2917void initenterstrongPairs (poly h,int k,int ecart,int isFromQ,kStrategy strat, int atR = -1)
2918{
2919  const int iCompH = pGetComp(h);
2920  if (!nIsOne(pGetCoeff(h)))
2921  {
2922    int j;
2923    BOOLEAN new_pair=FALSE;
2924
2925    for (j=0; j<=k; j++)
2926    {
2927      // Print("j:%d, Ll:%d\n",j,strat->Ll);
2928//      if (((unsigned long) pGetCoeff(h) % (unsigned long) pGetCoeff(strat->S[j]) != 0) &&
2929//         ((unsigned long) pGetCoeff(strat->S[j]) % (unsigned long) pGetCoeff(h) != 0))
2930      if ( iCompH == pGetComp(strat->S[j]) )
2931      {
2932        {
2933          if (enterOneStrongPoly(j,h,ecart,isFromQ,strat, atR))
2934            new_pair=TRUE;
2935        }
2936      }
2937    }
2938  }
2939/*
2940ring r=256,(x,y,z),dp;
2941ideal I=12xz-133y, 2xy-z;
2942*/
2943
2944}
2945
2946/*2
2947* Generates spoly(0, h) if applicable. Assumes ring in Z/2^n.
2948*/
2949void enterExtendedSpoly(poly h,kStrategy strat)
2950{
2951  if (nIsOne(pGetCoeff(h))) return;
2952  number gcd;
2953  bool go = false;
2954  if (nDivBy((number) 0, pGetCoeff(h)))
2955  {
2956    gcd = nIntDiv((number) 0, pGetCoeff(h));
2957    go = true;
2958  }
2959  else
2960    gcd = nGcd((number) 0, pGetCoeff(h), strat->tailRing);
2961  if (go || !nIsOne(gcd))
2962  {
2963    poly p = h->next;
2964    if (!go)
2965    {
2966      number tmp = gcd;
2967      gcd = nIntDiv(0, gcd);
2968      nDelete(&tmp);
2969    }
2970    p_Test(p,strat->tailRing);
2971    p = pp_Mult_nn(p, gcd, strat->tailRing);
2972    nDelete(&gcd);
2973
2974    if (p != NULL)
2975    {
2976      if (TEST_OPT_PROT)
2977      {
2978        PrintS("Z");
2979      }
2980#ifdef KDEBUG
2981      if (TEST_OPT_DEBUG)
2982      {
2983        PrintS("--- create zero spoly: ");
2984        p_wrp(h,currRing,strat->tailRing);
2985        PrintS(" ---> ");
2986      }
2987#endif
2988      poly tmp = pInit();
2989      pSetCoeff0(tmp, pGetCoeff(p));
2990      for (int i = 1; i <= rVar(currRing); i++)
2991      {
2992        pSetExp(tmp, i, p_GetExp(p, i, strat->tailRing));
2993      }
2994      if (rRing_has_Comp(currRing) && rRing_has_Comp(strat->tailRing))
2995      {
2996        p_SetComp(tmp, p_GetComp(p, strat->tailRing), currRing);
2997      }
2998      p_Setm(tmp, currRing);
2999      p = p_LmFreeAndNext(p, strat->tailRing);
3000      pNext(tmp) = p;
3001      LObject h;
3002      h.Init();
3003      h.p = tmp;
3004      h.tailRing = strat->tailRing;
3005      int posx;
3006      if (h.p!=NULL)
3007      {
3008        if (TEST_OPT_INTSTRATEGY)
3009        {
3010          //pContent(h.p);
3011          h.pCleardenom(); // also does a pContent
3012        }
3013        else
3014        {
3015          h.pNorm();
3016        }
3017        strat->initEcart(&h);
3018        if (strat->Ll==-1)
3019          posx =0;
3020        else
3021          posx = strat->posInL(strat->L,strat->Ll,&h,strat);
3022        h.sev = pGetShortExpVector(h.p);
3023        if (strat->tailRing != currRing)
3024        {
3025          h.t_p = k_LmInit_currRing_2_tailRing(h.p, strat->tailRing);
3026        }
3027#ifdef KDEBUG
3028        if (TEST_OPT_DEBUG)
3029        {
3030          p_wrp(tmp,currRing,strat->tailRing);
3031          PrintLn();
3032        }
3033#endif
3034        enterL(&strat->L,&strat->Ll,&strat->Lmax,h,posx);
3035      }
3036    }
3037  }
3038  nDelete(&gcd);
3039}
3040
3041void clearSbatch (poly h,int k,int pos,kStrategy strat)
3042{
3043  int j = pos;
3044  if ( (!strat->fromT)
3045  && (1//(strat->syzComp==0)
3046    //||(pGetComp(h)<=strat->syzComp)))
3047  ))
3048  {
3049    // Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
3050    unsigned long h_sev = pGetShortExpVector(h);
3051    loop
3052    {
3053      if (j > k) break;
3054      clearS(h,h_sev, &j,&k,strat);
3055      j++;
3056    }
3057    // Print("end clearS sl=%d\n",strat->sl);
3058  }
3059}
3060
3061/*2
3062* Generates a sufficient set of spolys (maybe just a finite generating
3063* set of the syzygys)
3064*/
3065void superenterpairs (poly h,int k,int ecart,int pos,kStrategy strat, int atR)
3066{
3067    assume (rField_is_Ring(currRing));
3068    // enter also zero divisor * poly, if this is non zero and of smaller degree
3069    if (!(rField_is_Domain(currRing))) enterExtendedSpoly(h, strat);
3070    initenterpairs(h, k, ecart, 0, strat, atR);
3071    initenterstrongPairs(h, k, ecart, 0, strat, atR);
3072    clearSbatch(h, k, pos, strat);
3073}
3074#endif
3075
3076/*2
3077*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
3078*superfluous elements in S will be deleted
3079*/
3080void enterpairs (poly h,int k,int ecart,int pos,kStrategy strat, int atR)
3081{
3082  int j=pos;
3083
3084#ifdef HAVE_RINGS
3085  assume (!rField_is_Ring(currRing));
3086#endif
3087
3088  initenterpairs(h,k,ecart,0,strat, atR);
3089  if ( (!strat->fromT)
3090  && ((strat->syzComp==0)
3091    ||(pGetComp(h)<=strat->syzComp)))
3092  {
3093    //Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
3094    unsigned long h_sev = pGetShortExpVector(h);
3095    loop
3096    {
3097      if (j > k) break;
3098      clearS(h,h_sev, &j,&k,strat);
3099      j++;
3100    }
3101    //Print("end clearS sl=%d\n",strat->sl);
3102  }
3103 // PrintS("end enterpairs\n");
3104}
3105
3106/*2
3107*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
3108*superfluous elements in S will be deleted
3109*/
3110void enterpairsSpecial (poly h,int k,int ecart,int pos,kStrategy strat, int atR = -1)
3111{
3112  int j;
3113  const int iCompH = pGetComp(h);
3114
3115  for (j=0; j<=k; j++)
3116  {
3117    const int iCompSj = pGetComp(strat->S[j]);
3118    if ((iCompH==iCompSj)
3119        || (0==iCompH) // TODO: what about this case???
3120        || (0==iCompSj))
3121    {
3122      enterOnePairSpecial(j,h,ecart,strat, atR);
3123    }
3124  }
3125
3126  if (strat->noClearS) return;
3127
3128//   #ifdef HAVE_PLURAL
3129/*
3130  if (rIsPluralRing(currRing))
3131  {
3132    j=pos;
3133    loop
3134    {
3135      if (j > k) break;
3136
3137      if (pLmDivisibleBy(h, strat->S[j]))
3138      {
3139        deleteInS(j, strat);
3140        j--;
3141        k--;
3142      }
3143
3144      j++;
3145    }
3146  }
3147  else
3148*/
3149//   #endif // ??? Why was the following cancelation disabled for non-commutative rings?
3150  {
3151    j=pos;
3152    loop
3153    {
3154      unsigned long h_sev = pGetShortExpVector(h);
3155      if (j > k) break;
3156      clearS(h,h_sev,&j,&k,strat);
3157      j++;
3158    }
3159  }
3160}
3161
3162/*2
3163*reorders  s with respect to posInS,
3164*suc is the first changed index or zero
3165*/
3166
3167void reorderS (int* suc,kStrategy strat)
3168{
3169  int i,j,at,ecart, s2r;
3170  int fq=0;
3171  unsigned long sev;
3172  poly  p;
3173  int new_suc=strat->sl+1;
3174  i= *suc;
3175  if (i<0) i=0;
3176
3177  for (; i<=strat->sl; i++)
3178  {
3179    at = posInS(strat,i-1,strat->S[i],strat->ecartS[i]);
3180    if (at != i)
3181    {
3182      if (new_suc > at) new_suc = at;
3183      p = strat->S[i];
3184      ecart = strat->ecartS[i];
3185      sev = strat->sevS[i];
3186      s2r = strat->S_2_R[i];
3187      if (strat->fromQ!=NULL) fq=strat->fromQ[i];
3188      for (j=i; j>=at+1; j--)
3189      {
3190        strat->S[j] = strat->S[j-1];
3191        strat->ecartS[j] = strat->ecartS[j-1];
3192        strat->sevS[j] = strat->sevS[j-1];
3193        strat->S_2_R[j] = strat->S_2_R[j-1];
3194      }
3195      strat->S[at] = p;
3196      strat->ecartS[at] = ecart;
3197      strat->sevS[at] = sev;
3198      strat->S_2_R[at] = s2r;
3199      if (strat->fromQ!=NULL)
3200      {
3201        for (j=i; j>=at+1; j--)
3202        {
3203          strat->fromQ[j] = strat->fromQ[j-1];
3204        }
3205        strat->fromQ[at]=fq;
3206      }
3207    }
3208  }
3209  if (new_suc <= strat->sl) *suc=new_suc;
3210  else                      *suc=-1;
3211}
3212
3213
3214/*2
3215*looks up the position of p in set
3216*set[0] is the smallest with respect to the ordering-procedure deg/pComp
3217* Assumption: posInS only depends on the leading term
3218*             otherwise, bba has to be changed
3219*/
3220int posInS (const kStrategy strat, const int length,const poly p,
3221            const int ecart_p)
3222{
3223  if(length==-1) return 0;
3224  polyset set=strat->S;
3225  int i;
3226  int an = 0;
3227  int en = length;
3228  int cmp_int = pOrdSgn;
3229  int pc=pGetComp(p);
3230  if ((currRing->MixedOrder)
3231#ifdef HAVE_PLURAL
3232  && (currRing->real_var_start==0)
3233#endif
3234#if 0
3235  || ((strat->ak>0) && ((currRing->order[0]==ringorder_c)||((currRing->order[0]==ringorder_C))))
3236#endif
3237  )
3238  {
3239    int o=pDeg(p);
3240    int oo=pDeg(set[length]);
3241
3242    if ((oo<o)
3243    || ((o==oo) && (pLmCmp(set[length],p)!= cmp_int)))
3244      return length+1;
3245
3246    loop
3247    {
3248      if (an >= en-1)
3249      {
3250        if ((pDeg(set[an])>=o) && (pLmCmp(set[an],p) == cmp_int))
3251        {
3252          return an;
3253        }
3254        return en;
3255      }
3256      i=(an+en) / 2;
3257      if ((pDeg(set[i])>=o) && (pLmCmp(set[i],p) == cmp_int)) en=i;
3258      else                              an=i;
3259    }
3260  }
3261  else
3262  {
3263#ifdef HAVE_RINGS
3264    if (rField_is_Ring(currRing))
3265    {
3266      if (pLmCmp(set[length],p)== -cmp_int)
3267        return length+1;
3268      int cmp;
3269      loop
3270      {
3271        if (an >= en-1)
3272        {
3273          cmp = pLmCmp(set[an],p);
3274          if (cmp == cmp_int)  return an;
3275          if (cmp == -cmp_int) return en;
3276          if (nDivBy(pGetCoeff(p), pGetCoeff(set[an]))) return en;
3277          return an;
3278        }
3279        i = (an+en) / 2;
3280        cmp = pLmCmp(set[i],p);
3281        if (cmp == cmp_int)         en = i;
3282        else if (cmp == -cmp_int)   an = i;
3283        else
3284        {
3285          if (nDivBy(pGetCoeff(p), pGetCoeff(set[i]))) an = i;
3286          else en = i;
3287        }
3288      }
3289    }
3290    else
3291#endif
3292    if (pLmCmp(set[length],p)== -cmp_int)
3293      return length+1;
3294
3295    loop
3296    {
3297      if (an >= en-1)
3298      {
3299        if (pLmCmp(set[an],p) == cmp_int) return an;
3300        if (pLmCmp(set[an],p) == -cmp_int) return en;
3301        if ((cmp_int!=1)
3302        && ((strat->ecartS[an])>ecart_p))
3303          return an;
3304        return en;
3305      }
3306      i=(an+en) / 2;
3307      if (pLmCmp(set[i],p) == cmp_int) en=i;
3308      else if (pLmCmp(set[i],p) == -cmp_int) an=i;
3309      else
3310      {
3311        if ((cmp_int!=1)
3312        &&((strat->ecartS[i])<ecart_p))
3313          en=i;
3314        else
3315          an=i;
3316      }
3317    }
3318  }
3319}
3320
3321
3322/*2
3323* looks up the position of p in set
3324* the position is the last one
3325*/
3326int posInT0 (const TSet set,const int length,LObject &p)
3327{
3328  return (length+1);
3329}
3330
3331
3332/*2
3333* looks up the position of p in T
3334* set[0] is the smallest with respect to the ordering-procedure
3335* pComp
3336*/
3337int posInT1 (const TSet set,const int length,LObject &p)
3338{
3339  if (length==-1) return 0;
3340
3341  if (pLmCmp(set[length].p,p.p)!= pOrdSgn) return length+1;
3342
3343  int i;
3344  int an = 0;
3345  int en= length;
3346
3347  loop
3348  {
3349    if (an >= en-1)
3350    {
3351      if (pLmCmp(set[an].p,p.p) == pOrdSgn) return an;
3352      return en;
3353    }
3354    i=(an+en) / 2;
3355    if (pLmCmp(set[i].p,p.p) == pOrdSgn) en=i;
3356    else                                 an=i;
3357  }
3358}
3359
3360/*2
3361* looks up the position of p in T
3362* set[0] is the smallest with respect to the ordering-procedure
3363* length
3364*/
3365int posInT2 (const TSet set,const int length,LObject &p)
3366{
3367  p.GetpLength();
3368  if (length==-1)
3369    return 0;
3370  if (set[length].length<p.length)
3371    return length+1;
3372
3373  int i;
3374  int an = 0;
3375  int en= length;
3376
3377  loop
3378  {
3379    if (an >= en-1)
3380    {
3381      if (set[an].length>p.length) return an;
3382      return en;
3383    }
3384    i=(an+en) / 2;
3385    if (set[i].length>p.length) en=i;
3386    else                        an=i;
3387  }
3388}
3389
3390/*2
3391* looks up the position of p in T
3392* set[0] is the smallest with respect to the ordering-procedure
3393* totaldegree,pComp
3394*/
3395int posInT11 (const TSet set,const int length,LObject &p)
3396/*{
3397 * int j=0;
3398 * int o;
3399 *
3400 * o = p.GetpFDeg();
3401 * loop
3402 * {
3403 *   if ((pFDeg(set[j].p) > o)
3404 *   || ((pFDeg(set[j].p) == o) && (pLmCmp(set[j].p,p.p) == pOrdSgn)))
3405 *   {
3406 *     return j;
3407 *   }
3408 *   j++;
3409 *   if (j > length) return j;
3410 * }
3411 *}
3412 */
3413{
3414  if (length==-1) return 0;
3415
3416  int o = p.GetpFDeg();
3417  int op = set[length].GetpFDeg();
3418
3419  if ((op < o)
3420  || ((op == o) && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
3421    return length+1;
3422
3423  int i;
3424  int an = 0;
3425  int en= length;
3426
3427  loop
3428  {
3429    if (an >= en-1)
3430    {
3431      op= set[an].GetpFDeg();
3432      if ((op > o)
3433      || (( op == o) && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
3434        return an;
3435      return en;
3436    }
3437    i=(an+en) / 2;
3438    op = set[i].GetpFDeg();
3439    if (( op > o)
3440    || (( op == o) && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
3441      en=i;
3442    else
3443      an=i;
3444  }
3445}
3446
3447/*2 Pos for rings T: Here I am
3448* looks up the position of p in T
3449* set[0] is the smallest with respect to the ordering-procedure
3450* totaldegree,pComp
3451*/
3452int posInTrg0 (const TSet set,const int length,LObject &p)
3453{
3454  if (length==-1) return 0;
3455  int o = p.GetpFDeg();
3456  int op = set[length].GetpFDeg();
3457  int i;
3458  int an = 0;
3459  int en = length;
3460  int cmp_int = pOrdSgn;
3461  if ((op < o) || (pLmCmp(set[length].p,p.p)== -cmp_int))
3462    return length+1;
3463  int cmp;
3464  loop
3465  {
3466    if (an >= en-1)
3467    {
3468      op = set[an].GetpFDeg();
3469      if (op > o) return an;
3470      if (op < 0) return en;
3471      cmp = pLmCmp(set[an].p,p.p);
3472      if (cmp == cmp_int)  return an;
3473      if (cmp == -cmp_int) return en;
3474      if (nGreater(pGetCoeff(p.p), pGetCoeff(set[an].p))) return en;
3475      return an;
3476    }
3477    i = (an + en) / 2;
3478    op = set[i].GetpFDeg();
3479    if (op > o)       en = i;
3480    else if (op < o)  an = i;
3481    else
3482    {
3483      cmp = pLmCmp(set[i].p,p.p);
3484      if (cmp == cmp_int)                                     en = i;
3485      else if (cmp == -cmp_int)                               an = i;
3486      else if (nGreater(pGetCoeff(p.p), pGetCoeff(set[i].p))) an = i;
3487      else                                                    en = i;
3488    }
3489  }
3490}
3491/*
3492  int o = p.GetpFDeg();
3493  int op = set[length].GetpFDeg();
3494
3495  if ((op < o)
3496  || ((op == o) && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
3497    return length+1;
3498
3499  int i;
3500  int an = 0;
3501  int en= length;
3502
3503  loop
3504  {
3505    if (an >= en-1)
3506    {
3507      op= set[an].GetpFDeg();
3508      if ((op > o)
3509      || (( op == o) && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
3510        return an;
3511      return en;
3512    }
3513    i=(an+en) / 2;
3514    op = set[i].GetpFDeg();
3515    if (( op > o)
3516    || (( op == o) && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
3517      en=i;
3518    else
3519      an=i;
3520  }
3521}
3522  */
3523/*2
3524* looks up the position of p in T
3525* set[0] is the smallest with respect to the ordering-procedure
3526* totaldegree,pComp
3527*/
3528int posInT110 (const TSet set,const int length,LObject &p)
3529{
3530  p.GetpLength();
3531  if (length==-1) return 0;
3532
3533  int o = p.GetpFDeg();
3534  int op = set[length].GetpFDeg();
3535
3536  if (( op < o)
3537  || (( op == o) && (set[length].length<p.length))
3538  || (( op == o) && (set[length].length == p.length)
3539     && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
3540    return length+1;
3541
3542  int i;
3543  int an = 0;
3544  int en= length;
3545  loop
3546  {
3547    if (an >= en-1)
3548    {
3549      op = set[an].GetpFDeg();
3550      if (( op > o)
3551      || (( op == o) && (set[an].length > p.length))
3552      || (( op == o) && (set[an].length == p.length)
3553         && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
3554        return an;
3555      return en;
3556    }
3557    i=(an+en) / 2;
3558    op = set[i].GetpFDeg();
3559    if (( op > o)
3560    || (( op == o) && (set[i].length > p.length))
3561    || (( op == o) && (set[i].length == p.length)
3562       && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
3563      en=i;
3564    else
3565      an=i;
3566  }
3567}
3568
3569/*2
3570* looks up the position of p in set
3571* set[0] is the smallest with respect to the ordering-procedure
3572* pFDeg
3573*/
3574int posInT13 (const TSet set,const int length,LObject &p)
3575{
3576  if (length==-1) return 0;
3577
3578  int o = p.GetpFDeg();
3579
3580  if (set[length].GetpFDeg() <= o)
3581    return length+1;
3582
3583  int i;
3584  int an = 0;
3585  int en= length;
3586  loop
3587  {
3588    if (an >= en-1)
3589    {
3590      if (set[an].GetpFDeg() > o)
3591        return an;
3592      return en;
3593    }
3594    i=(an+en) / 2;
3595    if (set[i].GetpFDeg() > o)
3596      en=i;
3597    else
3598      an=i;
3599  }
3600}
3601
3602// determines the position based on: 1.) Ecart 2.) pLength
3603int posInT_EcartpLength(const TSet set,const int length,LObject &p)
3604{
3605  int ol = p.GetpLength();
3606  if (length==-1) return 0;
3607
3608  int op=p.ecart;
3609
3610  int oo=set[length].ecart;
3611  if ((oo < op) || ((oo==op) && (set[length].length < ol)))
3612    return length+1;
3613
3614  int i;
3615  int an = 0;
3616  int en= length;
3617  loop
3618    {
3619      if (an >= en-1)
3620      {
3621        int oo=set[an].ecart;
3622        if((oo > op)
3623           || ((oo==op) && (set[an].pLength > ol)))
3624          return an;
3625        return en;
3626      }
3627      i=(an+en) / 2;
3628      int oo=set[i].ecart;
3629      if ((oo > op)
3630          || ((oo == op) && (set[i].pLength > ol)))
3631        en=i;
3632      else
3633        an=i;
3634    }
3635}
3636
3637/*2
3638* looks up the position of p in set
3639* set[0] is the smallest with respect to the ordering-procedure
3640* maximaldegree, pComp
3641*/
3642int posInT15 (const TSet set,const int length,LObject &p)
3643/*{
3644 *int j=0;
3645 * int o;
3646 *
3647 * o = p.GetpFDeg()+p.ecart;
3648 * loop
3649 * {
3650 *   if ((set[j].GetpFDeg()+set[j].ecart > o)
3651 *   || ((set[j].GetpFDeg()+set[j].ecart == o)
3652 *     && (pLmCmp(set[j].p,p.p) == pOrdSgn)))
3653 *   {
3654 *     return j;
3655 *   }
3656 *   j++;
3657 *   if (j > length) return j;
3658 * }
3659 *}
3660 */
3661{
3662  if (length==-1) return 0;
3663
3664  int o = p.GetpFDeg() + p.ecart;
3665  int op = set[length].GetpFDeg()+set[length].ecart;
3666
3667  if ((op < o)
3668  || ((op == o)
3669     && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
3670    return length+1;
3671
3672  int i;
3673  int an = 0;
3674  int en= length;
3675  loop
3676  {
3677    if (an >= en-1)
3678    {
3679      op = set[an].GetpFDeg()+set[an].ecart;
3680      if (( op > o)
3681      || (( op  == o) && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
3682        return an;
3683      return en;
3684    }
3685    i=(an+en) / 2;
3686    op = set[i].GetpFDeg()+set[i].ecart;
3687    if (( op > o)
3688    || (( op == o) && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
3689      en=i;
3690    else
3691      an=i;
3692  }
3693}
3694
3695/*2
3696* looks up the position of p in set
3697* set[0] is the smallest with respect to the ordering-procedure
3698* pFDeg+ecart, ecart, pComp
3699*/
3700int posInT17 (const TSet set,const int length,LObject &p)
3701/*
3702*{
3703* int j=0;
3704* int  o;
3705*
3706*  o = p.GetpFDeg()+p.ecart;
3707*  loop
3708*  {
3709*    if ((pFDeg(set[j].p)+set[j].ecart > o)
3710*    || (((pFDeg(set[j].p)+set[j].ecart == o)
3711*      && (set[j].ecart < p.ecart)))
3712*    || ((pFDeg(set[j].p)+set[j].ecart == o)
3713*      && (set[j].ecart==p.ecart)
3714*      && (pLmCmp(set[j].p,p.p)==pOrdSgn)))
3715*      return j;
3716*    j++;
3717*    if (j > length) return j;
3718*  }
3719* }
3720*/
3721{
3722  if (length==-1) return 0;
3723
3724  int o = p.GetpFDeg() + p.ecart;
3725  int op = set[length].GetpFDeg()+set[length].ecart;
3726
3727  if ((op < o)
3728  || (( op == o) && (set[length].ecart > p.ecart))
3729  || (( op == o) && (set[length].ecart==p.ecart)
3730     && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
3731    return length+1;
3732
3733  int i;
3734  int an = 0;
3735  int en= length;
3736  loop
3737  {
3738    if (an >= en-1)
3739    {
3740      op = set[an].GetpFDeg()+set[an].ecart;
3741      if (( op > o)
3742      || (( op == o) && (set[an].ecart < p.ecart))
3743      || (( op  == o) && (set[an].ecart==p.ecart)
3744         && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
3745        return an;
3746      return en;
3747    }
3748    i=(an+en) / 2;
3749    op = set[i].GetpFDeg()+set[i].ecart;
3750    if ((op > o)
3751    || (( op == o) && (set[i].ecart < p.ecart))
3752    || (( op == o) && (set[i].ecart == p.ecart)
3753       && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
3754      en=i;
3755    else
3756      an=i;
3757  }
3758}
3759/*2
3760* looks up the position of p in set
3761* set[0] is the smallest with respect to the ordering-procedure
3762* pGetComp, pFDeg+ecart, ecart, pComp
3763*/
3764int posInT17_c (const TSet set,const int length,LObject &p)
3765{
3766  if (length==-1) return 0;
3767
3768  int cc = (-1+2*currRing->order[0]==ringorder_c);
3769  /* cc==1 for (c,..), cc==-1 for (C,..) */
3770  int o = p.GetpFDeg() + p.ecart;
3771  int c = pGetComp(p.p)*cc;
3772
3773  if (pGetComp(set[length].p)*cc < c)
3774    return length+1;
3775  if (pGetComp(set[length].p)*cc == c)
3776  {
3777    int op = set[length].GetpFDeg()+set[length].ecart;
3778    if ((op < o)
3779    || ((op == o) && (set[length].ecart > p.ecart))
3780    || ((op == o) && (set[length].ecart==p.ecart)
3781       && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
3782      return length+1;
3783  }
3784
3785  int i;
3786  int an = 0;
3787  int en= length;
3788  loop
3789  {
3790    if (an >= en-1)
3791    {
3792      if (pGetComp(set[an].p)*cc < c)
3793        return en;
3794      if (pGetComp(set[an].p)*cc == c)
3795      {
3796        int op = set[an].GetpFDeg()+set[an].ecart;
3797        if ((op > o)
3798        || ((op == o) && (set[an].ecart < p.ecart))
3799        || ((op == o) && (set[an].ecart==p.ecart)
3800           && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
3801          return an;
3802      }
3803      return en;
3804    }
3805    i=(an+en) / 2;
3806    if (pGetComp(set[i].p)*cc > c)
3807      en=i;
3808    else if (pGetComp(set[i].p)*cc == c)
3809    {
3810      int op = set[i].GetpFDeg()+set[i].ecart;
3811      if ((op > o)
3812      || ((op == o) && (set[i].ecart < p.ecart))
3813      || ((op == o) && (set[i].ecart == p.ecart)
3814         && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
3815        en=i;
3816      else
3817        an=i;
3818    }
3819    else
3820      an=i;
3821  }
3822}
3823
3824/*2
3825* looks up the position of p in set
3826* set[0] is the smallest with respect to
3827* ecart, pFDeg, length
3828*/
3829int posInT19 (const TSet set,const int length,LObject &p)
3830{
3831  p.GetpLength();
3832  if (length==-1) return 0;
3833
3834  int o = p.ecart;
3835  int op=p.GetpFDeg();
3836
3837  if (set[length].ecart < o)
3838    return length+1;
3839  if (set[length].ecart == o)
3840  {
3841     int oo=set[length].GetpFDeg();
3842     if ((oo < op) || ((oo==op) && (set[length].length < p.length)))
3843       return length+1;
3844  }
3845
3846  int i;
3847  int an = 0;
3848  int en= length;
3849  loop
3850  {
3851    if (an >= en-1)
3852    {
3853      if (set[an].ecart > o)
3854        return an;
3855      if (set[an].ecart == o)
3856      {
3857         int oo=set[an].GetpFDeg();
3858         if((oo > op)
3859         || ((oo==op) && (set[an].length > p.length)))
3860           return an;
3861      }
3862      return en;
3863    }
3864    i=(an+en) / 2;
3865    if (set[i].ecart > o)
3866      en=i;
3867    else if (set[i].ecart == o)
3868    {
3869       int oo=set[i].GetpFDeg();
3870       if ((oo > op)
3871       || ((oo == op) && (set[i].length > p.length)))
3872         en=i;
3873       else
3874        an=i;
3875    }
3876    else
3877      an=i;
3878  }
3879}
3880
3881/*2
3882*looks up the position of polynomial p in set
3883*set[length] is the smallest element in set with respect
3884*to the ordering-procedure pComp
3885*/
3886int posInLSpecial (const LSet set, const int length,
3887                   LObject *p,const kStrategy strat)
3888{
3889  if (length<0) return 0;
3890
3891  int d=p->GetpFDeg();
3892  int op=set[length].GetpFDeg();
3893
3894  if ((op > d)
3895  || ((op == d) && (p->p1!=NULL)&&(set[length].p1==NULL))
3896  || (pLmCmp(set[length].p,p->p)== pOrdSgn))
3897     return length+1;
3898
3899  int i;
3900  int an = 0;
3901  int en= length;
3902  loop
3903  {
3904    if (an >= en-1)
3905    {
3906      op=set[an].GetpFDeg();
3907      if ((op > d)
3908      || ((op == d) && (p->p1!=NULL) && (set[an].p1==NULL))
3909      || (pLmCmp(set[an].p,p->p)== pOrdSgn))
3910         return en;
3911      return an;
3912    }
3913    i=(an+en) / 2;
3914    op=set[i].GetpFDeg();
3915    if ((op>d)
3916    || ((op==d) && (p->p1!=NULL) && (set[i].p1==NULL))
3917    || (pLmCmp(set[i].p,p->p) == pOrdSgn))
3918      an=i;
3919    else
3920      en=i;
3921  }
3922}
3923
3924/*2
3925*looks up the position of polynomial p in set
3926*set[length] is the smallest element in set with respect
3927*to the ordering-procedure pComp
3928*/
3929int posInL0 (const LSet set, const int length,
3930             LObject* p,const kStrategy strat)
3931{
3932  if (length<0) return 0;
3933
3934  if (pLmCmp(set[length].p,p->p)== pOrdSgn)
3935    return length+1;
3936
3937  int i;
3938  int an = 0;
3939  int en= length;
3940  loop
3941  {
3942    if (an >= en-1)
3943    {
3944      if (pLmCmp(set[an].p,p->p) == pOrdSgn) return en;
3945      return an;
3946    }
3947    i=(an+en) / 2;
3948    if (pLmCmp(set[i].p,p->p) == pOrdSgn) an=i;
3949    else                                 en=i;
3950    /*aend. fuer lazy == in !=- machen */
3951  }
3952}
3953
3954/*2
3955* looks up the position of polynomial p in set
3956* e is the ecart of p
3957* set[length] is the smallest element in set with respect
3958* to the ordering-procedure totaldegree,pComp
3959*/
3960int posInL11 (const LSet set, const int length,
3961              LObject* p,const kStrategy strat)
3962/*{
3963 * int j=0;
3964 * int o;
3965 *
3966 * o = p->GetpFDeg();
3967 * loop
3968 * {
3969 *   if (j > length)            return j;
3970 *   if ((set[j].GetpFDeg() < o)) return j;
3971 *   if ((set[j].GetpFDeg() == o) && (pLmCmp(set[j].p,p->p) == -pOrdSgn))
3972 *   {
3973 *     return j;
3974 *   }
3975 *   j++;
3976 * }
3977 *}
3978 */
3979{
3980  if (length<0) return 0;
3981
3982  int o = p->GetpFDeg();
3983  int op = set[length].GetpFDeg();
3984
3985  if ((op > o)
3986  || ((op == o) && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
3987    return length+1;
3988  int i;
3989  int an = 0;
3990  int en= length;
3991  loop
3992  {
3993    if (an >= en-1)
3994    {
3995      op = set[an].GetpFDeg();
3996      if ((op > o)
3997      || ((op == o) && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
3998        return en;
3999      return an;
4000    }
4001    i=(an+en) / 2;
4002    op = set[i].GetpFDeg();
4003    if ((op > o)
4004    || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
4005      an=i;
4006    else
4007      en=i;
4008  }
4009}
4010
4011/*2 Position for rings L: Here I am
4012* looks up the position of polynomial p in set
4013* e is the ecart of p
4014* set[length] is the smallest element in set with respect
4015* to the ordering-procedure totaldegree,pComp
4016*/
4017inline int getIndexRng(long coeff)
4018{
4019  if (coeff == 0) return -1;
4020  long tmp = coeff;
4021  int ind = 0;
4022  while (tmp % 2 == 0)
4023  {
4024    tmp = tmp / 2;
4025    ind++;
4026  }
4027  return ind;
4028}
4029
4030int posInLrg0 (const LSet set, const int length,
4031              LObject* p,const kStrategy strat)
4032/*          if (nGreater(pGetCoeff(p), pGetCoeff(set[an]))) return en;
4033        if (pLmCmp(set[i],p) == cmp_int)         en = i;
4034        else if (pLmCmp(set[i],p) == -cmp_int)   an = i;
4035        else
4036        {
4037          if (nGreater(pGetCoeff(p), pGetCoeff(set[i]))) an = i;
4038          else en = i;
4039        }*/
4040{
4041  if (length < 0) return 0;
4042
4043  int o = p->GetpFDeg();
4044  int op = set[length].GetpFDeg();
4045
4046  if ((op > o) || ((op == o) && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
4047    return length + 1;
4048  int i;
4049  int an = 0;
4050  int en = length;
4051  loop
4052  {
4053    if (an >= en - 1)
4054    {
4055      op = set[an].GetpFDeg();
4056      if ((op > o) || ((op == o) && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
4057        return en;
4058      return an;
4059    }
4060    i = (an+en) / 2;
4061    op = set[i].GetpFDeg();
4062    if ((op > o) || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
4063      an = i;
4064    else
4065      en = i;
4066  }
4067}
4068
4069/*{
4070  if (length < 0) return 0;
4071
4072  int o = p->GetpFDeg();
4073  int op = set[length].GetpFDeg();
4074
4075  int inde = getIndexRng((unsigned long) pGetCoeff(set[length].p));
4076  int indp = getIndexRng((unsigned long) pGetCoeff(p->p));
4077  int inda;
4078  int indi;
4079
4080  if ((inda > indp) || ((inda == inde) && ((op > o) || ((op == o) && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))))
4081    return length + 1;
4082  int i;
4083  int an = 0;
4084  inda = getIndexRng((unsigned long) pGetCoeff(set[an].p));
4085  int en = length;
4086  loop
4087  {
4088    if (an >= en-1)
4089    {
4090      op = set[an].GetpFDeg();
4091      if ((indp > inda) || ((indp == inda) && ((op > o) || ((op == o) && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))))
4092        return en;
4093      return an;
4094    }
4095    i = (an + en) / 2;
4096    indi = getIndexRng((unsigned long) pGetCoeff(set[i].p));
4097    op = set[i].GetpFDeg();
4098    if ((indi > indp) || ((indi == indp) && ((op > o) || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))))
4099    // if ((op > o) || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
4100    {
4101      an = i;
4102      inda = getIndexRng((unsigned long) pGetCoeff(set[an].p));
4103    }
4104    else
4105      en = i;
4106  }
4107} */
4108
4109/*2
4110* looks up the position of polynomial p in set
4111* set[length] is the smallest element in set with respect
4112* to the ordering-procedure totaldegree,pLength0
4113*/
4114int posInL110 (const LSet set, const int length,
4115               LObject* p,const kStrategy strat)
4116{
4117  if (length<0) return 0;
4118
4119  int o = p->GetpFDeg();
4120  int op = set[length].GetpFDeg();
4121
4122  if ((op > o)
4123  || ((op == o) && (set[length].length >p->length))
4124  || ((op == o) && (set[length].length <= p->length)
4125     && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
4126    return length+1;
4127  int i;
4128  int an = 0;
4129  int en= length;
4130  loop
4131  {
4132    if (an >= en-1)
4133    {
4134      op = set[an].GetpFDeg();
4135      if ((op > o)
4136      || ((op == o) && (set[an].length >p->length))
4137      || ((op == o) && (set[an].length <=p->length)
4138         && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
4139        return en;
4140      return an;
4141    }
4142    i=(an+en) / 2;
4143    op = set[i].GetpFDeg();
4144    if ((op > o)
4145    || ((op == o) && (set[i].length > p->length))
4146    || ((op == o) && (set[i].length <= p->length)
4147       && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
4148      an=i;
4149    else
4150      en=i;
4151  }
4152}
4153
4154/*2
4155* looks up the position of polynomial p in set
4156* e is the ecart of p
4157* set[length] is the smallest element in set with respect
4158* to the ordering-procedure totaldegree
4159*/
4160int posInL13 (const LSet set, const int length,
4161              LObject* p,const kStrategy strat)
4162{
4163  if (length<0) return 0;
4164
4165  int o = p->GetpFDeg();
4166
4167  if (set[length].GetpFDeg() > o)
4168    return length+1;
4169
4170  int i;
4171  int an = 0;
4172  int en= length;
4173  loop
4174  {
4175    if (an >= en-1)
4176    {
4177      if (set[an].GetpFDeg() >= o)
4178        return en;
4179      return an;
4180    }
4181    i=(an+en) / 2;
4182    if (set[i].GetpFDeg() >= o)
4183      an=i;
4184    else
4185      en=i;
4186  }
4187}
4188
4189/*2
4190* looks up the position of polynomial p in set
4191* e is the ecart of p
4192* set[length] is the smallest element in set with respect
4193* to the ordering-procedure maximaldegree,pComp
4194*/
4195int posInL15 (const LSet set, const int length,
4196              LObject* p,const kStrategy strat)
4197/*{
4198 * int j=0;
4199 * int o;
4200 *
4201 * o = p->ecart+p->GetpFDeg();
4202 * loop
4203 * {
4204 *   if (j > length)                       return j;
4205 *   if (set[j].GetpFDeg()+set[j].ecart < o) return j;
4206 *   if ((set[j].GetpFDeg()+set[j].ecart == o)
4207 *   && (pLmCmp(set[j].p,p->p) == -pOrdSgn))
4208 *   {
4209 *     return j;
4210 *   }
4211 *   j++;
4212 * }
4213 *}
4214 */
4215{
4216  if (length<0) return 0;
4217
4218  int o = p->GetpFDeg() + p->ecart;
4219  int op = set[length].GetpFDeg() + set[length].ecart;
4220
4221  if ((op > o)
4222  || ((op == o) && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
4223    return length+1;
4224  int i;
4225  int an = 0;
4226  int en= length;
4227  loop
4228  {
4229    if (an >= en-1)
4230    {
4231      op = set[an].GetpFDeg() + set[an].ecart;
4232      if ((op > o)
4233      || ((op == o) && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
4234        return en;
4235      return an;
4236    }
4237    i=(an+en) / 2;
4238    op = set[i].GetpFDeg() + set[i].ecart;
4239    if ((op > o)
4240    || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
4241      an=i;
4242    else
4243      en=i;
4244  }
4245}
4246
4247/*2
4248* looks up the position of polynomial p in set
4249* e is the ecart of p
4250* set[length] is the smallest element in set with respect
4251* to the ordering-procedure totaldegree
4252*/
4253int posInL17 (const LSet set, const int length,
4254              LObject* p,const kStrategy strat)
4255{
4256  if (length<0) return 0;
4257
4258  int o = p->GetpFDeg() + p->ecart;
4259
4260  if ((set[length].GetpFDeg() + set[length].ecart > o)
4261  || ((set[length].GetpFDeg() + set[length].ecart == o)
4262     && (set[length].ecart > p->ecart))
4263  || ((set[length].GetpFDeg() + set[length].ecart == o)
4264     && (set[length].ecart == p->ecart)
4265     && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
4266    return length+1;
4267  int i;
4268  int an = 0;
4269  int en= length;
4270  loop
4271  {
4272    if (an >= en-1)
4273    {
4274      if ((set[an].GetpFDeg() + set[an].ecart > o)
4275      || ((set[an].GetpFDeg() + set[an].ecart == o)
4276         && (set[an].ecart > p->ecart))
4277      || ((set[an].GetpFDeg() + set[an].ecart == o)
4278         && (set[an].ecart == p->ecart)
4279         && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
4280        return en;
4281      return an;
4282    }
4283    i=(an+en) / 2;
4284    if ((set[i].GetpFDeg() + set[i].ecart > o)
4285    || ((set[i].GetpFDeg() + set[i].ecart == o)
4286       && (set[i].ecart > p->ecart))
4287    || ((set[i].GetpFDeg() +set[i].ecart == o)
4288       && (set[i].ecart == p->ecart)
4289       && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
4290      an=i;
4291    else
4292      en=i;
4293  }
4294}
4295/*2
4296* looks up the position of polynomial p in set
4297* e is the ecart of p
4298* set[length] is the smallest element in set with respect
4299* to the ordering-procedure pComp
4300*/
4301int posInL17_c (const LSet set, const int length,
4302                LObject* p,const kStrategy strat)
4303{
4304  if (length<0) return 0;
4305
4306  int cc = (-1+2*currRing->order[0]==ringorder_c);
4307  /* cc==1 for (c,..), cc==-1 for (C,..) */
4308  int c = pGetComp(p->p)*cc;
4309  int o = p->GetpFDeg() + p->ecart;
4310
4311  if (pGetComp(set[length].p)*cc > c)
4312    return length+1;
4313  if (pGetComp(set[length].p)*cc == c)
4314  {
4315    if ((set[length].GetpFDeg() + set[length].ecart > o)
4316    || ((set[length].GetpFDeg() + set[length].ecart == o)
4317       && (set[length].ecart > p->ecart))
4318    || ((set[length].GetpFDeg() + set[length].ecart == o)
4319       && (set[length].ecart == p->ecart)
4320       && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
4321      return length+1;
4322  }
4323  int i;
4324  int an = 0;
4325  int en= length;
4326  loop
4327  {
4328    if (an >= en-1)
4329    {
4330      if (pGetComp(set[an].p)*cc > c)
4331        return en;
4332      if (pGetComp(set[an].p)*cc == c)
4333      {
4334        if ((set[an].GetpFDeg() + set[an].ecart > o)
4335        || ((set[an].GetpFDeg() + set[an].ecart == o)
4336           && (set[an].ecart > p->ecart))
4337        || ((set[an].GetpFDeg() + set[an].ecart == o)
4338           && (set[an].ecart == p->ecart)
4339           && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
4340          return en;
4341      }
4342      return an;
4343    }
4344    i=(an+en) / 2;
4345    if (pGetComp(set[i].p)*cc > c)
4346      an=i;
4347    else if (pGetComp(set[i].p)*cc == c)
4348    {
4349      if ((set[i].GetpFDeg() + set[i].ecart > o)
4350      || ((set[i].GetpFDeg() + set[i].ecart == o)
4351         && (set[i].ecart > p->ecart))
4352      || ((set[i].GetpFDeg() +set[i].ecart == o)
4353         && (set[i].ecart == p->ecart)
4354         && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
4355        an=i;
4356      else
4357        en=i;
4358    }
4359    else
4360      en=i;
4361  }
4362}
4363
4364/***************************************************************
4365 *
4366 * Tail reductions
4367 *
4368 ***************************************************************/
4369TObject*
4370kFindDivisibleByInS(kStrategy strat, int pos, LObject* L, TObject *T,
4371                    long ecart)
4372{
4373  int j = 0;
4374  const unsigned long not_sev = ~L->sev;
4375  const unsigned long* sev = strat->sevS;
4376  poly p;
4377  ring r;
4378  L->GetLm(p, r);
4379
4380  assume(~not_sev == p_GetShortExpVector(p, r));
4381
4382  if (r == currRing)
4383  {
4384    loop
4385    {
4386      if (j > pos) return NULL;
4387#if defined(PDEBUG) || defined(PDIV_DEBUG)
4388      if (p_LmShortDivisibleBy(strat->S[j], sev[j], p, not_sev, r) &&
4389          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
4390        break;
4391#else
4392      if (!(sev[j] & not_sev) &&
4393          (ecart== LONG_MAX || ecart>= strat->ecartS[j]) &&
4394          p_LmDivisibleBy(strat->S[j], p, r))
4395        break;
4396
4397#endif
4398      j++;
4399    }
4400    // if called from NF, T objects do not exist:
4401    if (strat->tl < 0 || strat->S_2_R[j] == -1)
4402    {
4403      T->Set(strat->S[j], r, strat->tailRing);
4404      return T;
4405    }
4406    else
4407    {
4408/////      assume (j >= 0 && j <= strat->tl && strat->S_2_T(j) != NULL
4409/////      && strat->S_2_T(j)->p == strat->S[j]); // wrong?
4410//      assume (j >= 0 && j <= strat->sl && strat->S_2_T(j) != NULL && strat->S_2_T(j)->p == strat->S[j]);
4411      return strat->S_2_T(j);
4412    }
4413  }
4414  else
4415  {
4416    TObject* t;
4417    loop
4418    {
4419      if (j > pos) return NULL;
4420      assume(strat->S_2_R[j] != -1);
4421#if defined(PDEBUG) || defined(PDIV_DEBUG)
4422      t = strat->S_2_T(j);
4423      assume(t != NULL && t->t_p != NULL && t->tailRing == r);
4424      if (p_LmShortDivisibleBy(t->t_p, sev[j], p, not_sev, r) &&
4425          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
4426        return t;
4427#else
4428      if (! (sev[j] & not_sev) && (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
4429      {
4430        t = strat->S_2_T(j);
4431        assume(t != NULL && t->t_p != NULL && t->tailRing == r && t->p == strat->S[j]);
4432        if (p_LmDivisibleBy(t->t_p, p, r)) return t;
4433      }
4434#endif
4435      j++;
4436    }
4437  }
4438}
4439
4440poly redtail (LObject* L, int pos, kStrategy strat)
4441{
4442  poly h, hn;
4443  int j;
4444  unsigned long not_sev;
4445  strat->redTailChange=FALSE;
4446
4447  poly p = L->p;
4448  if (strat->noTailReduction || pNext(p) == NULL)
4449    return p;
4450
4451  LObject Ln(strat->tailRing);
4452  TObject* With;
4453  // placeholder in case strat->tl < 0
4454  TObject  With_s(strat->tailRing);
4455  h = p;
4456  hn = pNext(h);
4457  long op = strat->tailRing->pFDeg(hn, strat->tailRing);
4458  long e;
4459  int l;
4460  BOOLEAN save_HE=strat->kHEdgeFound;
4461  strat->kHEdgeFound |=
4462    ((Kstd1_deg>0) && (op<=Kstd1_deg)) || TEST_OPT_INFREDTAIL;
4463
4464  while(hn != NULL)
4465  {
4466    op = strat->tailRing->pFDeg(hn, strat->tailRing);
4467    if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
4468    e = strat->tailRing->pLDeg(hn, &l, strat->tailRing) - op;
4469    loop
4470    {
4471      Ln.Set(hn, strat->tailRing);
4472      Ln.sev = p_GetShortExpVector(hn, strat->tailRing);
4473      if (strat->kHEdgeFound)
4474        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
4475      else
4476        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s, e);
4477      if (With == NULL) break;
4478      With->length=0;
4479      With->pLength=0;
4480      strat->redTailChange=TRUE;
4481      if (ksReducePolyTail(L, With, h, strat->kNoetherTail()))
4482      {
4483        // reducing the tail would violate the exp bound
4484        if (kStratChangeTailRing(strat, L))
4485        {
4486          strat->kHEdgeFound = save_HE;
4487          return redtail(L, pos, strat);
4488        }
4489        else
4490          return NULL;
4491      }
4492      hn = pNext(h);
4493      if (hn == NULL) goto all_done;
4494      op = strat->tailRing->pFDeg(hn, strat->tailRing);
4495      if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
4496      e = strat->tailRing->pLDeg(hn, &l, strat->tailRing) - op;
4497    }
4498    h = hn;
4499    hn = pNext(h);
4500  }
4501
4502  all_done:
4503  if (strat->redTailChange)
4504  {
4505    L->last = NULL;
4506    L->pLength = 0;
4507  }
4508  strat->kHEdgeFound = save_HE;
4509  return p;
4510}
4511
4512poly redtail (poly p, int pos, kStrategy strat)
4513{
4514  LObject L(p, currRing);
4515  return redtail(&L, pos, strat);
4516}
4517
4518poly redtailBba (LObject* L, int pos, kStrategy strat, BOOLEAN withT, BOOLEAN normalize)
4519{
4520#define REDTAIL_CANONICALIZE 100
4521  strat->redTailChange=FALSE;
4522  if (strat->noTailReduction) return L->GetLmCurrRing();
4523  poly h, p;
4524  p = h = L->GetLmTailRing();
4525  if ((h==NULL) || (pNext(h)==NULL))
4526    return L->GetLmCurrRing();
4527
4528  TObject* With;
4529  // placeholder in case strat->tl < 0
4530  TObject  With_s(strat->tailRing);
4531
4532  LObject Ln(pNext(h), strat->tailRing);
4533  Ln.pLength = L->GetpLength() - 1;
4534
4535  pNext(h) = NULL;
4536  if (L->p != NULL) pNext(L->p) = NULL;
4537  L->pLength = 1;
4538
4539  Ln.PrepareRed(strat->use_buckets);
4540
4541  int cnt=REDTAIL_CANONICALIZE;
4542  while(!Ln.IsNull())
4543  {
4544    loop
4545    {
4546      Ln.SetShortExpVector();
4547      if (withT)
4548      {
4549        int j;
4550        j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln);
4551        if (j < 0) break;
4552        With = &(strat->T[j]);
4553      }
4554      else
4555      {
4556        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
4557        if (With == NULL) break;
4558      }
4559      cnt--;
4560      if (cnt==0)
4561      {
4562        cnt=REDTAIL_CANONICALIZE;
4563        poly tmp=Ln.CanonicalizeP();
4564        if (normalize)
4565        {
4566          Ln.Normalize();
4567          //pNormalize(tmp);
4568          //if (TEST_OPT_PROT) { PrintS("n"); mflush(); }
4569        }
4570      }
4571      if (normalize && (!TEST_OPT_INTSTRATEGY) && (!nIsOne(pGetCoeff(With->p))))
4572      {
4573        With->pNorm();
4574      }
4575      strat->redTailChange=TRUE;
4576      if (ksReducePolyTail(L, With, &Ln))
4577      {
4578        // reducing the tail would violate the exp bound
4579        //  set a flag and hope for a retry (in bba)
4580        strat->completeReduce_retry=TRUE;
4581        if ((Ln.p != NULL) && (Ln.t_p != NULL)) Ln.p=NULL;
4582        do
4583        {
4584          pNext(h) = Ln.LmExtractAndIter();
4585          pIter(h);
4586          L->pLength++;
4587        } while (!Ln.IsNull());
4588        goto all_done;
4589      }
4590      if (Ln.IsNull()) goto all_done;
4591      if (! withT) With_s.Init(currRing);
4592    }
4593    pNext(h) = Ln.LmExtractAndIter();
4594    pIter(h);
4595    pNormalize(h);
4596    L->pLength++;
4597  }
4598
4599  all_done:
4600  Ln.Delete();
4601  if (L->p != NULL) pNext(L->p) = pNext(p);
4602
4603  if (strat->redTailChange)
4604  {
4605    L->last = NULL;
4606    L->length = 0;
4607  }
4608
4609  //if (TEST_OPT_PROT) { PrintS("N"); mflush(); }
4610  //L->Normalize(); // HANNES: should have a test
4611  kTest_L(L);
4612  return L->GetLmCurrRing();
4613}
4614
4615#ifdef HAVE_RINGS
4616poly redtailBba_Z (LObject* L, int pos, kStrategy strat )
4617// normalize=FALSE, withT=FALSE, coeff=Z
4618{
4619  strat->redTailChange=FALSE;
4620  if (strat->noTailReduction) return L->GetLmCurrRing();
4621  poly h, p;
4622  p = h = L->GetLmTailRing();
4623  if ((h==NULL) || (pNext(h)==NULL))
4624    return L->GetLmCurrRing();
4625
4626  TObject* With;
4627  // placeholder in case strat->tl < 0
4628  TObject  With_s(strat->tailRing);
4629
4630  LObject Ln(pNext(h), strat->tailRing);
4631  Ln.pLength = L->GetpLength() - 1;
4632
4633  pNext(h) = NULL;
4634  if (L->p != NULL) pNext(L->p) = NULL;
4635  L->pLength = 1;
4636
4637  Ln.PrepareRed(strat->use_buckets);
4638
4639  int cnt=REDTAIL_CANONICALIZE;
4640  while(!Ln.IsNull())
4641  {
4642    loop
4643    {
4644      Ln.SetShortExpVector();
4645      With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
4646      if (With == NULL) break;
4647      cnt--;
4648      if (cnt==0)
4649      {
4650        cnt=REDTAIL_CANONICALIZE;
4651        poly tmp=Ln.CanonicalizeP();
4652      }
4653      // we are in Z, do not Ccall pNorm
4654      strat->redTailChange=TRUE;
4655      // test divisibility of coefs:
4656      poly p_Ln=Ln.GetLmCurrRing();
4657      poly p_With=With->GetLmCurrRing();
4658      number z=nIntMod(pGetCoeff(p_Ln),pGetCoeff(p_With));
4659      if (!nIsZero(z))
4660      {
4661        // subtract z*Ln, add z.Ln to L
4662        poly m=pHead(p_Ln);
4663        pSetCoeff(m,z);
4664        poly mm=pHead(m);
4665        pNext(h) = m;
4666        pIter(h);
4667        L->pLength++;
4668        mm=pNeg(mm);
4669        if (Ln.bucket!=NULL)
4670        {
4671          int dummy=1;
4672          kBucket_Add_q(Ln.bucket,mm,&dummy);
4673        }
4674        else
4675        {
4676          if (Ln.p!=NULL) Ln.p=pAdd(Ln.p,mm);
4677          else if (Ln.t_p!=NULL)  Ln.t_p=p_Add_q(Ln.t_p,mm,strat->tailRing);
4678        }
4679      }
4680      else
4681        nDelete(&z);
4682
4683      if (ksReducePolyTail(L, With, &Ln))
4684      {
4685        // reducing the tail would violate the exp bound
4686        //  set a flag and hope for a retry (in bba)
4687        strat->completeReduce_retry=TRUE;
4688        if ((Ln.p != NULL) && (Ln.t_p != NULL)) Ln.p=NULL;
4689        do
4690        {
4691          pNext(h) = Ln.LmExtractAndIter();
4692          pIter(h);
4693          L->pLength++;
4694        } while (!Ln.IsNull());
4695        goto all_done;
4696      }
4697      if (Ln.IsNull()) goto all_done;
4698      With_s.Init(currRing);
4699    }
4700    pNext(h) = Ln.LmExtractAndIter();
4701    pIter(h);
4702    pNormalize(h);
4703    L->pLength++;
4704  }
4705
4706  all_done:
4707  Ln.Delete();
4708  if (L->p != NULL) pNext(L->p) = pNext(p);
4709
4710  if (strat->redTailChange)
4711  {
4712    L->last = NULL;
4713    L->length = 0;
4714  }
4715
4716  //if (TEST_OPT_PROT) { PrintS("N"); mflush(); }
4717  //L->Normalize(); // HANNES: should have a test
4718  kTest_L(L);
4719  return L->GetLmCurrRing();
4720}
4721#endif
4722
4723/*2
4724*checks the change degree and write progress report
4725*/
4726void message (int i,int* reduc,int* olddeg,kStrategy strat, int red_result)
4727{
4728  if (i != *olddeg)
4729  {
4730    Print("%d",i);
4731    *olddeg = i;
4732  }
4733  if (TEST_OPT_OLDSTD)
4734  {
4735    if (strat->Ll != *reduc)
4736    {
4737      if (strat->Ll != *reduc-1)
4738        Print("(%d)",strat->Ll+1);
4739      else
4740        PrintS("-");
4741      *reduc = strat->Ll;
4742    }
4743    else
4744      PrintS(".");
4745    mflush();
4746  }
4747  else
4748  {
4749    if (red_result == 0)
4750      PrintS("-");
4751    else if (red_result < 0)
4752      PrintS(".");
4753    if ((red_result > 0) || ((strat->Ll % 100)==99))
4754    {
4755      if (strat->Ll != *reduc && strat->Ll > 0)
4756      {
4757        Print("(%d)",strat->Ll+1);
4758        *reduc = strat->Ll;
4759      }
4760    }
4761  }
4762}
4763
4764/*2
4765*statistics
4766*/
4767void messageStat (int srmax,int lrmax,int hilbcount,kStrategy strat)
4768{
4769  //PrintS("\nUsage/Allocation of temporary storage:\n");
4770  //Print("%d/%d polynomials in standard base\n",srmax,IDELEMS(Shdl));
4771  //Print("%d/%d polynomials in set L (for lazy alg.)",lrmax+1,strat->Lmax);
4772  Print("product criterion:%d chain criterion:%d\n",strat->cp,strat->c3);
4773  if (hilbcount!=0) Print("hilbert series criterion:%d\n",hilbcount);
4774  /* in usual case strat->cv is 0, it gets changed only in shift routines */
4775  if (strat->cv!=0) Print("shift V criterion:%d\n",strat->cv);
4776  /*mflush();*/
4777}
4778
4779#ifdef KDEBUG
4780/*2
4781*debugging output: all internal sets, if changed
4782*for testing purpuse only/has to be changed for later use
4783*/
4784void messageSets (kStrategy strat)
4785{
4786  int i;
4787  if (strat->news)
4788  {
4789    PrintS("set S");
4790    for (i=0; i<=strat->sl; i++)
4791    {
4792      Print("\n  %d:",i);
4793      p_wrp(strat->S[i], currRing, strat->tailRing);
4794    }
4795    strat->news = FALSE;
4796  }
4797  if (strat->newt)
4798  {
4799    PrintS("\nset T");
4800    for (i=0; i<=strat->tl; i++)
4801    {
4802      Print("\n  %d:",i);
4803      strat->T[i].wrp();
4804      Print(" o:%ld e:%d l:%d",
4805        strat->T[i].pFDeg(),strat->T[i].ecart,strat->T[i].length);
4806    }
4807    strat->newt = FALSE;
4808  }
4809  PrintS("\nset L");
4810  for (i=strat->Ll; i>=0; i--)
4811  {
4812    Print("\n%d:",i);
4813    p_wrp(strat->L[i].p1, currRing, strat->tailRing);
4814    PrintS("  ");
4815    p_wrp(strat->L[i].p2, currRing, strat->tailRing);
4816    PrintS(" lcm: ");p_wrp(strat->L[i].lcm, currRing);
4817    PrintS("\n  p : ");
4818    strat->L[i].wrp();
4819    Print("  o:%ld e:%d l:%d",
4820          strat->L[i].pFDeg(),strat->L[i].ecart,strat->L[i].length);
4821  }
4822  PrintLn();
4823}
4824
4825#endif
4826
4827
4828/*2
4829*construct the set s from F
4830*/
4831void initS (ideal F, ideal Q, kStrategy strat)
4832{
4833  int   i,pos;
4834
4835  if (Q!=NULL) i=((IDELEMS(F)+IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
4836  else         i=((IDELEMS(F)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
4837  strat->ecartS=initec(i);
4838  strat->sevS=initsevS(i);
4839  strat->S_2_R=initS_2_R(i);
4840  strat->fromQ=NULL;
4841  strat->Shdl=idInit(i,F->rank);
4842  strat->S=strat->Shdl->m;
4843  /*- put polys into S -*/
4844  if (Q!=NULL)
4845  {
4846    strat->fromQ=initec(i);
4847    memset(strat->fromQ,0,i*sizeof(int));
4848    for (i=0; i<IDELEMS(Q); i++)
4849    {
4850      if (Q->m[i]!=NULL)
4851      {
4852        LObject h;
4853        h.p = pCopy(Q->m[i]);
4854        if (TEST_OPT_INTSTRATEGY)
4855        {
4856          //pContent(h.p);
4857          h.pCleardenom(); // also does a pContent
4858        }
4859        else
4860        {
4861          h.pNorm();
4862        }
4863        if (pOrdSgn==-1)
4864        {
4865          deleteHC(&h, strat);
4866        }
4867        if (h.p!=NULL)
4868        {
4869          strat->initEcart(&h);
4870          if (strat->sl==-1)
4871            pos =0;
4872          else
4873          {
4874            pos = posInS(strat,strat->sl,h.p,h.ecart);
4875          }
4876          h.sev = pGetShortExpVector(h.p);
4877          strat->enterS(h,pos,strat,-1);
4878          strat->fromQ[pos]=1;
4879        }
4880      }
4881    }
4882  }
4883  for (i=0; i<IDELEMS(F); i++)
4884  {
4885    if (F->m[i]!=NULL)
4886    {
4887      LObject h;
4888      h.p = pCopy(F->m[i]);
4889      if (pOrdSgn==-1)
4890      {
4891        cancelunit(&h);  /*- tries to cancel a unit -*/
4892        deleteHC(&h, strat);
4893      }
4894      if (h.p!=NULL)
4895      // do not rely on the input being a SB!
4896      {
4897        if (TEST_OPT_INTSTRATEGY)
4898        {
4899          //pContent(h.p);
4900          h.pCleardenom(); // also does a pContent
4901        }
4902        else
4903        {
4904          h.pNorm();
4905        }
4906        strat->initEcart(&h);
4907        if (strat->sl==-1)
4908          pos =0;
4909        else
4910          pos = posInS(strat,strat->sl,h.p,h.ecart);
4911        h.sev = pGetShortExpVector(h.p);
4912        strat->enterS(h,pos,strat,-1);
4913      }
4914    }
4915  }
4916  /*- test, if a unit is in F -*/
4917  if ((strat->sl>=0)
4918#ifdef HAVE_RINGS
4919       && nIsUnit(pGetCoeff(strat->S[0]))
4920#endif
4921       && pIsConstant(strat->S[0]))
4922  {
4923    while (strat->sl>0) deleteInS(strat->sl,strat);
4924  }
4925}
4926
4927void initSL (ideal F, ideal Q,kStrategy strat)
4928{
4929  int   i,pos;
4930
4931  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
4932  else i=setmaxT;
4933  strat->ecartS=initec(i);
4934  strat->sevS=initsevS(i);
4935  strat->S_2_R=initS_2_R(i);
4936  strat->fromQ=NULL;
4937  strat->Shdl=idInit(i,F->rank);
4938  strat->S=strat->Shdl->m;
4939  /*- put polys into S -*/
4940  if (Q!=NULL)
4941  {
4942    strat->fromQ=initec(i);
4943    memset(strat->fromQ,0,i*sizeof(int));
4944    for (i=0; i<IDELEMS(Q); i++)
4945    {
4946      if (Q->m[i]!=NULL)
4947      {
4948        LObject h;
4949        h.p = pCopy(Q->m[i]);
4950        if (pOrdSgn==-1)
4951        {
4952          deleteHC(&h,strat);
4953        }
4954        if (TEST_OPT_INTSTRATEGY)
4955        {
4956          //pContent(h.p);
4957          h.pCleardenom(); // also does a pContent
4958        }
4959        else
4960        {
4961          h.pNorm();
4962        }
4963        if (h.p!=NULL)
4964        {
4965          strat->initEcart(&h);
4966          if (strat->sl==-1)
4967            pos =0;
4968          else
4969          {
4970            pos = posInS(strat,strat->sl,h.p,h.ecart);
4971          }
4972          h.sev = pGetShortExpVector(h.p);
4973          strat->enterS(h,pos,strat,-1);
4974          strat->fromQ[pos]=1;
4975        }
4976      }
4977    }
4978  }
4979  for (i=0; i<IDELEMS(F); i++)
4980  {
4981    if (F->m[i]!=NULL)
4982    {
4983      LObject h;
4984      h.p = pCopy(F->m[i]);
4985      if (h.p!=NULL)
4986      {
4987        if (pOrdSgn==-1)
4988        {
4989          cancelunit(&h);  /*- tries to cancel a unit -*/
4990          deleteHC(&h, strat);
4991        }
4992        if (h.p!=NULL)
4993        {
4994          if (TEST_OPT_INTSTRATEGY)
4995          {
4996            //pContent(h.p);
4997            h.pCleardenom(); // also does a pContent
4998          }
4999          else
5000          {
5001            h.pNorm();
5002          }
5003          strat->initEcart(&h);
5004          if (strat->Ll==-1)
5005            pos =0;
5006          else
5007            pos = strat->posInL(strat->L,strat->Ll,&h,strat);
5008          h.sev = pGetShortExpVector(h.p);
5009          enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
5010        }
5011      }
5012    }
5013  }
5014  /*- test, if a unit is in F -*/
5015
5016  if ((strat->Ll>=0)
5017#ifdef HAVE_RINGS
5018       && nIsUnit(pGetCoeff(strat->L[strat->Ll].p))
5019#endif
5020       && pIsConstant(strat->L[strat->Ll].p))
5021  {
5022    while (strat->Ll>0) deleteInL(strat->L,&strat->Ll,strat->Ll-1,strat);
5023  }
5024}
5025
5026
5027/*2
5028*construct the set s from F and {P}
5029*/
5030void initSSpecial (ideal F, ideal Q, ideal P,kStrategy strat)
5031{
5032  int   i,pos;
5033
5034  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
5035  else i=setmaxT;
5036  i=((i+IDELEMS(F)+IDELEMS(P)+15)/16)*16;
5037  strat->ecartS=initec(i);
5038  strat->sevS=initsevS(i);
5039  strat->S_2_R=initS_2_R(i);
5040  strat->fromQ=NULL;
5041  strat->Shdl=idInit(i,F->rank);
5042  strat->S=strat->Shdl->m;
5043
5044  /*- put polys into S -*/
5045  if (Q!=NULL)
5046  {
5047    strat->fromQ=initec(i);
5048    memset(strat->fromQ,0,i*sizeof(int));
5049    for (i=0; i<IDELEMS(Q); i++)
5050    {
5051      if (Q->m[i]!=NULL)
5052      {
5053        LObject h;
5054        h.p = pCopy(Q->m[i]);
5055        //if (TEST_OPT_INTSTRATEGY)
5056        //{
5057        //  //pContent(h.p);
5058        //  h.pCleardenom(); // also does a pContent
5059        //}
5060        //else
5061        //{
5062        //  h.pNorm();
5063        //}
5064        if (pOrdSgn==-1)
5065        {
5066          deleteHC(&h,strat);
5067        }
5068        if (h.p!=NULL)
5069        {
5070          strat->initEcart(&h);
5071          if (strat->sl==-1)
5072            pos =0;
5073          else
5074          {
5075            pos = posInS(strat,strat->sl,h.p,h.ecart);
5076          }
5077          h.sev = pGetShortExpVector(h.p);
5078          strat->enterS(h,pos,strat, strat->tl+1);
5079          enterT(h, strat);
5080          strat->fromQ[pos]=1;
5081        }
5082      }
5083    }
5084  }
5085  /*- put polys into S -*/
5086  for (i=0; i<IDELEMS(F); i++)
5087  {
5088    if (F->m[i]!=NULL)
5089    {
5090      LObject h;
5091      h.p = pCopy(F->m[i]);
5092      if (pOrdSgn==-1)
5093      {
5094        deleteHC(&h,strat);
5095      }
5096      else
5097      {
5098        h.p=redtailBba(h.p,strat->sl,strat);
5099      }
5100      if (h.p!=NULL)
5101      {
5102        strat->initEcart(&h);
5103        if (strat->sl==-1)
5104          pos =0;
5105        else
5106          pos = posInS(strat,strat->sl,h.p,h.ecart);
5107        h.sev = pGetShortExpVector(h.p);
5108        strat->enterS(h,pos,strat, strat->tl+1);
5109        enterT(h,strat);
5110      }
5111    }
5112  }
5113  for (i=0; i<IDELEMS(P); i++)
5114  {
5115    if (P->m[i]!=NULL)
5116    {
5117      LObject h;
5118      h.p=pCopy(P->m[i]);
5119      if (TEST_OPT_INTSTRATEGY)
5120      {
5121        h.pCleardenom();
5122      }
5123      else
5124      {
5125        h.pNorm();
5126      }
5127      if(strat->sl>=0)
5128      {
5129        if (pOrdSgn==1)
5130        {
5131          h.p=redBba(h.p,strat->sl,strat);
5132          if (h.p!=NULL)
5133          {
5134            h.p=redtailBba(h.p,strat->sl,strat);
5135          }
5136        }
5137        else
5138        {
5139          h.p=redMora(h.p,strat->sl,strat);
5140        }
5141        if(h.p!=NULL)
5142        {
5143          strat->initEcart(&h);
5144          if (TEST_OPT_INTSTRATEGY)
5145          {
5146            h.pCleardenom();
5147          }
5148          else
5149          {
5150            h.is_normalized = 0;
5151            h.pNorm();
5152          }
5153          h.sev = pGetShortExpVector(h.p);
5154          h.SetpFDeg();
5155          pos = posInS(strat,strat->sl,h.p,h.ecart);
5156          enterpairsSpecial(h.p,strat->sl,h.ecart,pos,strat,strat->tl+1);
5157          strat->enterS(h,pos,strat, strat->tl+1);
5158          enterT(h,strat);
5159        }
5160      }
5161      else
5162      {
5163        h.sev = pGetShortExpVector(h.p);
5164        strat->initEcart(&h);
5165        strat->enterS(h,0,strat, strat->tl+1);
5166        enterT(h,strat);
5167      }
5168    }
5169  }
5170}
5171/*2
5172* reduces h using the set S
5173* procedure used in cancelunit1
5174*/
5175static poly redBba1 (poly h,int maxIndex,kStrategy strat)
5176{
5177  int j = 0;
5178  unsigned long not_sev = ~ pGetShortExpVector(h);
5179
5180  while (j <= maxIndex)
5181  {
5182    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j],h, not_sev))
5183       return ksOldSpolyRedNew(strat->S[j],h,strat->kNoetherTail());
5184    else j++;
5185  }
5186  return h;
5187}
5188
5189/*2
5190*tests if p.p=monomial*unit and cancels the unit
5191*/
5192void cancelunit1 (LObject* p,int *suc, int index,kStrategy strat )
5193{
5194  int k;
5195  poly r,h,h1,q;
5196
5197  if (!pIsVector((*p).p) && ((*p).ecart != 0))
5198  {
5199#ifdef HAVE_RINGS_LOC
5200    // Leading coef have to be a unit
5201    if ( !(nIsUnit(p_GetCoeff((*p).p, r))) ) return;
5202#endif
5203    k = 0;
5204    h1 = r = pCopy((*p).p);
5205    h =pNext(r);
5206    loop
5207    {
5208      if (h==NULL)
5209      {
5210        pDelete(&r);
5211        pDelete(&(pNext((*p).p)));
5212        (*p).ecart = 0;
5213        (*p).length = 1;
5214#ifdef HAVE_RINGS_LOC
5215        (*p).pLength = 1;  // Why wasn't this set already?
5216#endif
5217        (*suc)=0;
5218        return;
5219      }
5220      if (!pDivisibleBy(r,h))
5221      {
5222        q=redBba1(h,index ,strat);
5223        if (q != h)
5224        {
5225          k++;
5226          pDelete(&h);
5227          pNext(h1) = h = q;
5228        }
5229        else
5230        {
5231          pDelete(&r);
5232          return;
5233        }
5234      }
5235      else
5236      {
5237        h1 = h;
5238        pIter(h);
5239      }
5240      if (k > 10)
5241      {
5242        pDelete(&r);
5243        return;
5244      }
5245    }
5246  }
5247}
5248
5249#if 0
5250/*2
5251* reduces h using the elements from Q in the set S
5252* procedure used in updateS
5253* must not be used for elements of Q or elements of an ideal !
5254*/
5255static poly redQ (poly h, int j, kStrategy strat)
5256{
5257  int start;
5258  unsigned long not_sev = ~ pGetShortExpVector(h);
5259  while ((j <= strat->sl) && (pGetComp(strat->S[j])!=0)) j++;
5260  start=j;
5261  while (j<=strat->sl)
5262  {
5263    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev))
5264    {
5265      h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
5266      if (h==NULL) return NULL;
5267      j = start;
5268      not_sev = ~ pGetShortExpVector(h);
5269    }
5270    else j++;
5271  }
5272  return h;
5273}
5274#endif
5275
5276/*2
5277* reduces h using the set S
5278* procedure used in updateS
5279*/
5280static poly redBba (poly h,int maxIndex,kStrategy strat)
5281{
5282  int j = 0;
5283  unsigned long not_sev = ~ pGetShortExpVector(h);
5284
5285  while (j <= maxIndex)
5286  {
5287    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev))
5288    {
5289      h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
5290      if (h==NULL) return NULL;
5291      j = 0;
5292      not_sev = ~ pGetShortExpVector(h);    }
5293    else j++;
5294  }
5295  return h;
5296}
5297
5298/*2
5299* reduces h using the set S
5300*e is the ecart of h
5301*procedure used in updateS
5302*/
5303static poly redMora (poly h,int maxIndex,kStrategy strat)
5304{
5305  int  j=0;
5306  int  e,l;
5307  unsigned long not_sev = ~ pGetShortExpVector(h);
5308
5309  if (maxIndex >= 0)
5310  {
5311    e = pLDeg(h,&l,currRing)-pFDeg(h,currRing);
5312    do
5313    {
5314      if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev)
5315      && ((e >= strat->ecartS[j]) || strat->kHEdgeFound))
5316      {
5317#ifdef KDEBUG
5318        if (TEST_OPT_DEBUG)
5319          {PrintS("reduce ");wrp(h);Print(" with S[%d] (",j);wrp(strat->S[j]);}
5320#endif
5321        h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
5322#ifdef KDEBUG
5323        if(TEST_OPT_DEBUG)
5324          {PrintS(")\nto "); wrp(h); PrintLn();}
5325#endif
5326        // pDelete(&h);
5327        if (h == NULL) return NULL;
5328        e = pLDeg(h,&l,currRing)-pFDeg(h,currRing);
5329        j = 0;
5330        not_sev = ~ pGetShortExpVector(h);
5331      }
5332      else j++;
5333    }
5334    while (j <= maxIndex);
5335  }
5336  return h;
5337}
5338
5339/*2
5340*updates S:
5341*the result is a set of polynomials which are in
5342*normalform with respect to S
5343*/
5344void updateS(BOOLEAN toT,kStrategy strat)
5345{
5346  LObject h;
5347  int i, suc=0;
5348  poly redSi=NULL;
5349  BOOLEAN change,any_change;
5350//  Print("nach initS: updateS start mit sl=%d\n",(strat->sl));
5351//  for (i=0; i<=(strat->sl); i++)
5352//  {
5353//    Print("s%d:",i);
5354//    if (strat->fromQ!=NULL) Print("(Q:%d) ",strat->fromQ[i]);
5355//    pWrite(strat->S[i]);
5356//  }
5357//  Print("pOrdSgn=%d\n", pOrdSgn);
5358  any_change=FALSE;
5359  if (pOrdSgn==1)
5360  {
5361    while (suc != -1)
5362    {
5363      i=suc+1;
5364      while (i<=strat->sl)
5365      {
5366        change=FALSE;
5367        if (((strat->fromQ==NULL) || (strat->fromQ[i]==0)) && (i>0))
5368        {
5369          redSi = pHead(strat->S[i]);
5370          strat->S[i] = redBba(strat->S[i],i-1,strat);
5371          //if ((strat->ak!=0)&&(strat->S[i]!=NULL))
5372          //  strat->S[i]=redQ(strat->S[i],i+1,strat); /*reduce S[i] mod Q*/
5373          if (pCmp(redSi,strat->S[i])!=0)
5374          {
5375            change=TRUE;
5376            any_change=TRUE;
5377            #ifdef KDEBUG
5378            if (TEST_OPT_DEBUG)
5379            {
5380              PrintS("reduce:");
5381              wrp(redSi);PrintS(" to ");p_wrp(strat->S[i], currRing, strat->tailRing);PrintLn();
5382            }
5383            #endif
5384            if (TEST_OPT_PROT)
5385            {
5386              if (strat->S[i]==NULL)
5387                PrintS("V");
5388              else
5389                PrintS("v");
5390              mflush();
5391            }
5392          }
5393          pLmDelete(&redSi);
5394          if (strat->S[i]==NULL)
5395          {
5396            deleteInS(i,strat);
5397            i--;
5398          }
5399          else if (change)
5400          {
5401            if (TEST_OPT_INTSTRATEGY)
5402            {
5403              if (TEST_OPT_CONTENTSB)
5404                {
5405                  number n;
5406                  p_Cleardenom_n(strat->S[i], currRing, n);// also does a pContent
5407                  if (!nIsOne(n))
5408                    {
5409                      denominator_list denom=(denominator_list)omAlloc(sizeof(denominator_list_s));
5410                      denom->n=nInvers(n);
5411                      denom->next=DENOMINATOR_LIST;
5412                      DENOMINATOR_LIST=denom;
5413                    }
5414                  nDelete(&n);
5415                }
5416              else
5417                {
5418                  //pContent(strat->S[i]);
5419                  strat->S[i]=p_Cleardenom(strat->S[i], currRing);// also does a pContent
5420                }
5421            }
5422            else
5423            {
5424              pNorm(strat->S[i]);
5425            }
5426            strat->sevS[i] = pGetShortExpVector(strat->S[i]);
5427          }
5428        }
5429        i++;
5430      }
5431      if (any_change) reorderS(&suc,strat);
5432      else break;
5433    }
5434    if (toT)
5435    {
5436      for (i=0; i<=strat->sl; i++)
5437      {
5438        if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
5439        {
5440          h.p = redtailBba(strat->S[i],i-1,strat);
5441          if (TEST_OPT_INTSTRATEGY)
5442          {
5443            h.pCleardenom();// also does a pContent
5444          }
5445        }
5446        else
5447        {
5448          h.p = strat->S[i];
5449        }
5450        strat->initEcart(&h);
5451        if (strat->honey)
5452        {
5453          strat->ecartS[i] = h.ecart;
5454        }
5455        if (strat->sevS[i] == 0) {strat->sevS[i] = pGetShortExpVector(h.p);}
5456        else assume(strat->sevS[i] == pGetShortExpVector(h.p));
5457        h.sev = strat->sevS[i];
5458        /*puts the elements of S also to T*/
5459        strat->initEcart(&h);
5460        enterT(h,strat);
5461        strat->S_2_R[i] = strat->tl;
5462      }
5463    }
5464  }
5465  else
5466  {
5467    while (suc != -1)
5468    {
5469      i=suc;
5470      while (i<=strat->sl)
5471      {
5472        change=FALSE;
5473        if (((strat->fromQ==NULL) || (strat->fromQ[i]==0)) && (i>0))
5474        {
5475          redSi=pHead((strat->S)[i]);
5476          (strat->S)[i] = redMora((strat->S)[i],i-1,strat);
5477          if ((strat->S)[i]==NULL)
5478          {
5479            deleteInS(i,strat);
5480            i--;
5481          }
5482          else if (pCmp((strat->S)[i],redSi)!=0)
5483          {
5484            any_change=TRUE;
5485            h.p = strat->S[i];
5486            strat->initEcart(&h);
5487            strat->ecartS[i] = h.ecart;
5488            if (TEST_OPT_INTSTRATEGY)
5489            {
5490              if (TEST_OPT_CONTENTSB)
5491                {
5492                  number n;
5493                  p_Cleardenom_n(strat->S[i], currRing, n);// also does a pContent
5494                  if (!nIsOne(n))
5495                    {
5496                      denominator_list denom=(denominator_list)omAlloc(sizeof(denominator_list_s));
5497                      denom->n=nInvers(n);
5498                      denom->next=DENOMINATOR_LIST;
5499                      DENOMINATOR_LIST=denom;
5500                    }
5501                  nDelete(&n);
5502                }
5503              else
5504                {
5505                  //pContent(strat->S[i]);
5506                  strat->S[i]=p_Cleardenom(strat->S[i], currRing);// also does a pContent
5507                }
5508            }
5509            else
5510            {
5511              pNorm(strat->S[i]); // == h.p
5512            }
5513            h.sev =  pGetShortExpVector(h.p);
5514            strat->sevS[i] = h.sev;
5515          }
5516          pLmDelete(&redSi);
5517          kTest(strat);
5518        }
5519        i++;
5520      }
5521#ifdef KDEBUG
5522      kTest(strat);
5523#endif
5524      if (any_change) reorderS(&suc,strat);
5525      else { suc=-1; break; }
5526      if (h.p!=NULL)
5527      {
5528        if (!strat->kHEdgeFound)
5529        {
5530          /*strat->kHEdgeFound =*/ HEckeTest(h.p,strat);
5531        }
5532        if (strat->kHEdgeFound)
5533          newHEdge(strat->S,strat);
5534      }
5535    }
5536    for (i=0; i<=strat->sl; i++)
5537    {
5538      if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
5539      {
5540        strat->S[i] = h.p = redtail(strat->S[i],strat->sl,strat);
5541        strat->initEcart(&h);
5542        strat->ecartS[i] = h.ecart;
5543        h.sev = pGetShortExpVector(h.p);
5544        strat->sevS[i] = h.sev;
5545      }
5546      else
5547      {
5548        h.p = strat->S[i];
5549        h.ecart=strat->ecartS[i];
5550        h.sev = strat->sevS[i];
5551        h.length = h.pLength = pLength(h.p);
5552      }
5553      if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
5554        cancelunit1(&h,&suc,strat->sl,strat);
5555      h.SetpFDeg();
5556      /*puts the elements of S also to T*/
5557      enterT(h,strat);
5558      strat->S_2_R[i] = strat->tl;
5559    }
5560    if (suc!= -1) updateS(toT,strat);
5561  }
5562#ifdef KDEBUG
5563  kTest(strat);
5564#endif
5565}
5566
5567
5568/*2
5569* -puts p to the standardbasis s at position at
5570* -saves the result in S
5571*/
5572void enterSBba (LObject p,int atS,kStrategy strat, int atR)
5573{
5574  int i;
5575  strat->news = TRUE;
5576  /*- puts p to the standardbasis s at position at -*/
5577  if (strat->sl == IDELEMS(strat->Shdl)-1)
5578  {
5579    strat->sevS = (unsigned long*) omRealloc0Size(strat->sevS,
5580                                    IDELEMS(strat->Shdl)*sizeof(unsigned long),
5581                                    (IDELEMS(strat->Shdl)+setmaxTinc)
5582                                                  *sizeof(unsigned long));
5583    strat->ecartS = (intset)omReallocSize(strat->ecartS,
5584                                          IDELEMS(strat->Shdl)*sizeof(int),
5585                                          (IDELEMS(strat->Shdl)+setmaxTinc)
5586                                                  *sizeof(int));
5587    strat->S_2_R = (int*) omRealloc0Size(strat->S_2_R,
5588                                         IDELEMS(strat->Shdl)*sizeof(int),
5589                                         (IDELEMS(strat->Shdl)+setmaxTinc)
5590                                                  *sizeof(int));
5591    if (strat->lenS!=NULL)
5592      strat->lenS=(int*)omRealloc0Size(strat->lenS,
5593                                       IDELEMS(strat->Shdl)*sizeof(int),
5594                                       (IDELEMS(strat->Shdl)+setmaxTinc)
5595                                                 *sizeof(int));
5596    if (strat->lenSw!=NULL)
5597      strat->lenSw=(wlen_type*)omRealloc0Size(strat->lenSw,
5598                                       IDELEMS(strat->Shdl)*sizeof(wlen_type),
5599                                       (IDELEMS(strat->Shdl)+setmaxTinc)
5600                                                 *sizeof(wlen_type));
5601    if (strat->fromQ!=NULL)
5602    {
5603      strat->fromQ = (intset)omReallocSize(strat->fromQ,
5604                                    IDELEMS(strat->Shdl)*sizeof(int),
5605                                    (IDELEMS(strat->Shdl)+setmaxTinc)*sizeof(int));
5606    }
5607    pEnlargeSet(&strat->S,IDELEMS(strat->Shdl),setmaxTinc);
5608    IDELEMS(strat->Shdl)+=setmaxTinc;
5609    strat->Shdl->m=strat->S;
5610  }
5611  if (atS <= strat->sl)
5612  {
5613#ifdef ENTER_USE_MEMMOVE
5614// #if 0
5615    memmove(&(strat->S[atS+1]), &(strat->S[atS]),
5616            (strat->sl - atS + 1)*sizeof(poly));
5617    memmove(&(strat->ecartS[atS+1]), &(strat->ecartS[atS]),
5618            (strat->sl - atS + 1)*sizeof(int));
5619    memmove(&(strat->sevS[atS+1]), &(strat->sevS[atS]),
5620            (strat->sl - atS + 1)*sizeof(unsigned long));
5621    memmove(&(strat->S_2_R[atS+1]), &(strat->S_2_R[atS]),
5622            (strat->sl - atS + 1)*sizeof(int));
5623    if (strat->lenS!=NULL)
5624    memmove(&(strat->lenS[atS+1]), &(strat->lenS[atS]),
5625            (strat->sl - atS + 1)*sizeof(int));
5626    if (strat->lenSw!=NULL)
5627    memmove(&(strat->lenSw[atS+1]), &(strat->lenSw[atS]),
5628            (strat->sl - atS + 1)*sizeof(wlen_type));
5629#else
5630    for (i=strat->sl+1; i>=atS+1; i--)
5631    {
5632      strat->S[i] = strat->S[i-1];
5633      strat->ecartS[i] = strat->ecartS[i-1];
5634      strat->sevS[i] = strat->sevS[i-1];
5635      strat->S_2_R[i] = strat->S_2_R[i-1];
5636    }
5637    if (strat->lenS!=NULL)
5638    for (i=strat->sl+1; i>=atS+1; i--)
5639      strat->lenS[i] = strat->lenS[i-1];
5640    if (strat->lenSw!=NULL)
5641    for (i=strat->sl+1; i>=atS+1; i--)
5642      strat->lenSw[i] = strat->lenSw[i-1];
5643#endif
5644  }
5645  if (strat->fromQ!=NULL)
5646  {
5647#ifdef ENTER_USE_MEMMOVE
5648    memmove(&(strat->fromQ[atS+1]), &(strat->fromQ[atS]),
5649                  (strat->sl - atS + 1)*sizeof(int));
5650#else
5651    for (i=strat->sl+1; i>=atS+1; i--)
5652    {
5653      strat->fromQ[i] = strat->fromQ[i-1];
5654    }
5655#endif
5656    strat->fromQ[atS]=0;
5657  }
5658
5659  /*- save result -*/
5660  strat->S[atS] = p.p;
5661  if (strat->honey) strat->ecartS[atS] = p.ecart;
5662  if (p.sev == 0)
5663    p.sev = pGetShortExpVector(p.p);
5664  else
5665    assume(p.sev == pGetShortExpVector(p.p));
5666  strat->sevS[atS] = p.sev;
5667  strat->ecartS[atS] = p.ecart;
5668  strat->S_2_R[atS] = atR;
5669  strat->sl++;
5670}
5671
5672/*2
5673* puts p to the set T at position atT
5674*/
5675void enterT(LObject p, kStrategy strat, int atT)
5676{
5677  int i;
5678
5679  pp_Test(p.p, currRing, p.tailRing);
5680  assume(strat->tailRing == p.tailRing);
5681  // redMoraNF complains about this -- but, we don't really
5682  // neeed this so far
5683  assume(p.pLength == 0 || pLength(p.p) == p.pLength || rIsSyzIndexRing(currRing)); // modulo syzring
5684  assume(p.FDeg == p.pFDeg());
5685  assume(!p.is_normalized || nIsOne(pGetCoeff(p.p)));
5686
5687#ifdef KDEBUG
5688  // do not put an LObject twice into T:
5689  for(i=strat->tl;i>=0;i--)
5690  {
5691    if (p.p==strat->T[i].p)
5692    {
5693      printf("already in T at pos %d of %d, atT=%d\n",i,strat->tl,atT);
5694      return;
5695    }
5696  }
5697#endif
5698  strat->newt = TRUE;
5699  if (atT < 0)
5700    atT = strat->posInT(strat->T, strat->tl, p);
5701  if (strat->tl == strat->tmax-1)
5702    enlargeT(strat->T,strat->R,strat->sevT,strat->tmax,setmaxTinc);
5703  if (atT <= strat->tl)
5704  {
5705#ifdef ENTER_USE_MEMMOVE
5706    memmove(&(strat->T[atT+1]), &(strat->T[atT]),
5707            (strat->tl-atT+1)*sizeof(TObject));
5708    memmove(&(strat->sevT[atT+1]), &(strat->sevT[atT]),
5709            (strat->tl-atT+1)*sizeof(unsigned long));
5710#endif
5711    for (i=strat->tl+1; i>=atT+1; i--)
5712    {
5713#ifndef ENTER_USE_MEMMOVE
5714      strat->T[i] = strat->T[i-1];
5715      strat->sevT[i] = strat->sevT[i-1];
5716#endif
5717      strat->R[strat->T[i].i_r] = &(strat->T[i]);
5718    }
5719  }
5720
5721  if (strat->tailBin != NULL && (pNext(p.p) != NULL))
5722  {
5723    pNext(p.p)=p_ShallowCopyDelete(pNext(p.p),
5724                                   (strat->tailRing != NULL ?
5725                                    strat->tailRing : currRing),
5726                                   strat->tailBin);
5727    if (p.t_p != NULL) pNext(p.t_p) = pNext(p.p);
5728  }
5729  strat->T[atT] = (TObject) p;
5730
5731  if (strat->tailRing != currRing && pNext(p.p) != NULL)
5732    strat->T[atT].max = p_GetMaxExpP(pNext(p.p), strat->tailRing);
5733  else
5734    strat->T[atT].max = NULL;
5735
5736  strat->tl++;
5737  strat->R[strat->tl] = &(strat->T[atT]);
5738  strat->T[atT].i_r = strat->tl;
5739  assume(p.sev == 0 || pGetShortExpVector(p.p) == p.sev);
5740  strat->sevT[atT] = (p.sev == 0 ? pGetShortExpVector(p.p) : p.sev);
5741  kTest_T(&(strat->T[atT]));
5742}
5743
5744void initHilbCrit(ideal F, ideal Q, intvec **hilb,kStrategy strat)
5745{
5746  if (strat->homog!=isHomog)
5747  {
5748    *hilb=NULL;
5749  }
5750}
5751
5752void initBuchMoraCrit(kStrategy strat)
5753{
5754  strat->enterOnePair=enterOnePairNormal;
5755  strat->chainCrit=chainCritNormal;
5756#ifdef HAVE_RINGS
5757  if (rField_is_Ring(currRing))
5758  {
5759    strat->enterOnePair=enterOnePairRing;
5760    strat->chainCrit=chainCritRing;
5761  }
5762#endif
5763#ifdef HAVE_RATGRING
5764  if (rIsRatGRing(currRing))
5765  {
5766     strat->chainCrit=chainCritPart;
5767     /* enterOnePairNormal get rational part in it */
5768  }
5769#endif
5770
5771  strat->sugarCrit =        TEST_OPT_SUGARCRIT;
5772  strat->Gebauer =          strat->homog || strat->sugarCrit;
5773  strat->honey =            !strat->homog || strat->sugarCrit || TEST_OPT_WEIGHTM;
5774  if (TEST_OPT_NOT_SUGAR) strat->honey = FALSE;
5775  strat->pairtest = NULL;
5776  /* alway use tailreduction, except:
5777  * - in local rings, - in lex order case, -in ring over extensions */
5778  strat->noTailReduction = !TEST_OPT_REDTAIL;
5779
5780#ifdef HAVE_PLURAL
5781  // and r is plural_ring
5782  //  hence this holds for r a rational_plural_ring
5783  if( rIsPluralRing(currRing) || (rIsSCA(currRing) && !strat->z2homog) )
5784  {    //or it has non-quasi-comm type... later
5785    strat->sugarCrit = FALSE;
5786    strat->Gebauer = FALSE;
5787    strat->honey = FALSE;
5788  }
5789#endif
5790
5791#ifdef HAVE_RINGS
5792  // Coefficient ring?
5793  if (rField_is_Ring(currRing))
5794  {
5795    strat->sugarCrit = FALSE;
5796    strat->Gebauer = FALSE ;
5797    strat->honey = FALSE;
5798  }
5799#endif
5800  #ifdef KDEBUG
5801  if (TEST_OPT_DEBUG)
5802  {
5803    if (strat->homog) PrintS("ideal/module is homogeneous\n");
5804    else              PrintS("ideal/module is not homogeneous\n");
5805  }
5806  #endif
5807}
5808
5809BOOLEAN kPosInLDependsOnLength(int (*pos_in_l)
5810                               (const LSet set, const int length,
5811                                LObject* L,const kStrategy strat))
5812{
5813  if (pos_in_l == posInL110 ||
5814      pos_in_l == posInL10)
5815    return TRUE;
5816
5817  return FALSE;
5818}
5819
5820void initBuchMoraPos (kStrategy strat)
5821{
5822  if (pOrdSgn==1)
5823  {
5824    if (strat->honey)
5825    {
5826      strat->posInL = posInL15;
5827      // ok -- here is the deal: from my experiments for Singular-2-0
5828      // I conclude that that posInT_EcartpLength is the best of
5829      // posInT15, posInT_EcartFDegpLength, posInT_FDegLength, posInT_pLength
5830      // see the table at the end of this file
5831      if (TEST_OPT_OLDSTD)
5832        strat->posInT = posInT15;
5833      else
5834        strat->posInT = posInT_EcartpLength;
5835    }
5836    else if (pLexOrder && !TEST_OPT_INTSTRATEGY)
5837    {
5838      strat->posInL = posInL11;
5839      strat->posInT = posInT11;
5840    }
5841    else if (TEST_OPT_INTSTRATEGY)
5842    {
5843      strat->posInL = posInL11;
5844      strat->posInT = posInT11;
5845    }
5846    else
5847    {
5848      strat->posInL = posInL0;
5849      strat->posInT = posInT0;
5850    }
5851    //if (strat->minim>0) strat->posInL =posInLSpecial;
5852    if (strat->homog)
5853    {
5854       strat->posInL = posInL110;
5855       strat->posInT = posInT110;
5856    }
5857  }
5858  else
5859  {
5860    if (strat->homog)
5861    {
5862      strat->posInL = posInL11;
5863      strat->posInT = posInT11;
5864    }
5865    else
5866    {
5867      if ((currRing->order[0]==ringorder_c)
5868      ||(currRing->order[0]==ringorder_C))
5869      {
5870        strat->posInL = posInL17_c;
5871        strat->posInT = posInT17_c;
5872      }
5873      else
5874      {
5875        strat->posInL = posInL17;
5876        strat->posInT = posInT17;
5877      }
5878    }
5879  }
5880  if (strat->minim>0) strat->posInL =posInLSpecial;
5881  // for further tests only
5882  if ((BTEST1(11)) || (BTEST1(12)))
5883    strat->posInL = posInL11;
5884  else if ((BTEST1(13)) || (BTEST1(14)))
5885    strat->posInL = posInL13;
5886  else if ((BTEST1(15)) || (BTEST1(16)))
5887    strat->posInL = posInL15;
5888  else if ((BTEST1(17)) || (BTEST1(18)))
5889    strat->posInL = posInL17;
5890  if (BTEST1(11))
5891    strat->posInT = posInT11;
5892  else if (BTEST1(13))
5893    strat->posInT = posInT13;
5894  else if (BTEST1(15))
5895    strat->posInT = posInT15;
5896  else if ((BTEST1(17)))
5897    strat->posInT = posInT17;
5898  else if ((BTEST1(19)))
5899    strat->posInT = posInT19;
5900  else if (BTEST1(12) || BTEST1(14) || BTEST1(16) || BTEST1(18))
5901    strat->posInT = posInT1;
5902#ifdef HAVE_RINGS
5903  if (rField_is_Ring(currRing))
5904  {
5905    strat->posInL = posInL11;
5906    strat->posInT = posInT11;
5907  }
5908#endif
5909  strat->posInLDependsOnLength = kPosInLDependsOnLength(strat->posInL);
5910}
5911
5912void initBuchMora (ideal F,ideal Q,kStrategy strat)
5913{
5914  strat->interpt = BTEST1(OPT_INTERRUPT);
5915  strat->kHEdge=NULL;
5916  if (pOrdSgn==1) strat->kHEdgeFound=FALSE;
5917  /*- creating temp data structures------------------- -*/
5918  strat->cp = 0;
5919  strat->c3 = 0;
5920  strat->tail = pInit();
5921  /*- set s -*/
5922  strat->sl = -1;
5923  /*- set L -*/
5924  strat->Lmax = ((IDELEMS(F)+setmaxLinc-1)/setmaxLinc)*setmaxLinc;
5925  strat->Ll = -1;
5926  strat->L = initL(((IDELEMS(F)+setmaxLinc-1)/setmaxLinc)*setmaxLinc);
5927  /*- set B -*/
5928  strat->Bmax = setmaxL;
5929  strat->Bl = -1;
5930  strat->B = initL();
5931  /*- set T -*/
5932  strat->tl = -1;
5933  strat->tmax = setmaxT;
5934  strat->T = initT();
5935  strat->R = initR();
5936  strat->sevT = initsevT();
5937  /*- init local data struct.---------------------------------------- -*/
5938  strat->P.ecart=0;
5939  strat->P.length=0;
5940  if (pOrdSgn==-1)
5941  {
5942    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
5943    if (strat->kNoether!=NULL) pSetComp(strat->kNoetherTail(), strat->ak);
5944  }
5945  if(TEST_OPT_SB_1)
5946  {
5947    int i;
5948    ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
5949    for (i=strat->newIdeal;i<IDELEMS(F);i++)
5950    {
5951      P->m[i-strat->newIdeal] = F->m[i];
5952      F->m[i] = NULL;
5953    }
5954    initSSpecial(F,Q,P,strat);
5955    for (i=strat->newIdeal;i<IDELEMS(F);i++)
5956    {
5957      F->m[i] = P->m[i-strat->newIdeal];
5958      P->m[i-strat->newIdeal] = NULL;
5959    }
5960    idDelete(&P);
5961  }
5962  else
5963  {
5964    /*Shdl=*/initSL(F, Q,strat); /*sets also S, ecartS, fromQ */
5965    // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
5966  }
5967  strat->kIdeal = NULL;
5968  strat->fromT = FALSE;
5969  strat->noTailReduction = !TEST_OPT_REDTAIL;
5970  if (!TEST_OPT_SB_1)
5971  {
5972    updateS(TRUE,strat);
5973  }
5974  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
5975  strat->fromQ=NULL;
5976}
5977
5978void exitBuchMora (kStrategy strat)
5979{
5980  /*- release temp data -*/
5981  cleanT(strat);
5982  omFreeSize(strat->T,(strat->tmax)*sizeof(TObject));
5983  omFreeSize(strat->R,(strat->tmax)*sizeof(TObject*));
5984  omFreeSize(strat->sevT, (strat->tmax)*sizeof(unsigned long));
5985  omFreeSize(strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
5986  omFreeSize(strat->sevS,IDELEMS(strat->Shdl)*sizeof(int));
5987  omFreeSize(strat->S_2_R,IDELEMS(strat->Shdl)*sizeof(int));
5988  /*- set L: should be empty -*/
5989  omFreeSize(strat->L,(strat->Lmax)*sizeof(LObject));
5990  /*- set B: should be empty -*/
5991  omFreeSize(strat->B,(strat->Bmax)*sizeof(LObject));
5992  pLmDelete(&strat->tail);
5993  strat->syzComp=0;
5994  if (strat->kIdeal!=NULL)
5995  {
5996    omFreeBin(strat->kIdeal, sleftv_bin);
5997    strat->kIdeal=NULL;
5998  }
5999}
6000
6001/*2
6002* in the case of a standardbase of a module over a qring:
6003* replace polynomials in i by ak vectors,
6004* (the polynomial * unit vectors gen(1)..gen(ak)
6005* in every case (also for ideals:)
6006* deletes divisible vectors/polynomials
6007*/
6008void updateResult(ideal r,ideal Q, kStrategy strat)
6009{
6010  int l;
6011  if (strat->ak>0)
6012  {
6013    for (l=IDELEMS(r)-1;l>=0;l--)
6014    {
6015      if ((r->m[l]!=NULL) && (pGetComp(r->m[l])==0))
6016      {
6017        pDelete(&r->m[l]); // and set it to NULL
6018      }
6019    }
6020    int q;
6021    poly p;
6022    for (l=IDELEMS(r)-1;l>=0;l--)
6023    {
6024      if ((r->m[l]!=NULL)
6025      //&& (strat->syzComp>0)
6026      //&& (pGetComp(r->m[l])<=strat->syzComp)
6027      )
6028      {
6029        for(q=IDELEMS(Q)-1; q>=0;q--)
6030        {
6031          if ((Q->m[q]!=NULL)
6032          &&(pLmDivisibleBy(Q->m[q],r->m[l])))
6033          {
6034            if (TEST_OPT_REDSB)
6035            {
6036              p=r->m[l];
6037              r->m[l]=kNF(Q,NULL,p);
6038              pDelete(&p);
6039            }
6040            else
6041            {
6042              pDelete(&r->m[l]); // and set it to NULL
6043            }
6044            break;
6045          }
6046        }
6047      }
6048    }
6049  }
6050  else
6051  {
6052    int q;
6053    poly p;
6054    BOOLEAN reduction_found=FALSE;
6055    for (l=IDELEMS(r)-1;l>=0;l--)
6056    {
6057      if (r->m[l]!=NULL)
6058      {
6059        for(q=IDELEMS(Q)-1; q>=0;q--)
6060        {
6061          if ((Q->m[q]!=NULL)
6062          &&(pLmEqual(r->m[l],Q->m[q])))
6063          {
6064            if (TEST_OPT_REDSB)
6065            {
6066              p=r->m[l];
6067              r->m[l]=kNF(Q,NULL,p);
6068              pDelete(&p);
6069              reduction_found=TRUE;
6070            }
6071            else
6072            {
6073              pDelete(&r->m[l]); // and set it to NULL
6074            }
6075            break;
6076          }
6077        }
6078      }
6079    }
6080    if (/*TEST_OPT_REDSB &&*/ reduction_found)
6081    {
6082      for (l=IDELEMS(r)-1;l>=0;l--)
6083      {
6084        if (r->m[l]!=NULL)
6085        {
6086          for(q=IDELEMS(r)-1;q>=0;q--)
6087          {
6088            if ((l!=q)
6089            && (r->m[q]!=NULL)
6090            &&(pLmDivisibleBy(r->m[l],r->m[q])))
6091            {
6092              pDelete(&r->m[q]);
6093            }
6094          }
6095        }
6096      }
6097    }
6098  }
6099  idSkipZeroes(r);
6100}
6101
6102void completeReduce (kStrategy strat, BOOLEAN withT)
6103{
6104  int i;
6105  int low = (((pOrdSgn==1) && (strat->ak==0)) ? 1 : 0);
6106  LObject L;
6107
6108#ifdef KDEBUG
6109  // need to set this: during tailreductions of T[i], T[i].max is out of
6110  // sync
6111  sloppy_max = TRUE;
6112#endif
6113
6114  strat->noTailReduction = FALSE;
6115  if (TEST_OPT_PROT)
6116  {
6117    PrintLn();
6118    if (timerv) writeTime("standard base computed:");
6119  }
6120  if (TEST_OPT_PROT)
6121  {
6122    Print("(S:%d)",strat->sl);mflush();
6123  }
6124  for (i=strat->sl; i>=low; i--)
6125  {
6126    int end_pos=strat->sl;
6127    if ((strat->fromQ!=NULL) && (strat->fromQ[i])) continue; // do not reduce Q_i
6128    if (strat->ak==0) end_pos=i-1;
6129    TObject* T_j = strat->s_2_t(i);
6130    if (T_j != NULL)
6131    {
6132      L = *T_j;
6133      poly p;
6134      if (pOrdSgn == 1)
6135        strat->S[i] = redtailBba(&L, end_pos, strat, withT);
6136      else
6137        strat->S[i] = redtail(&L, strat->sl, strat);
6138
6139      if (strat->redTailChange && strat->tailRing != currRing)
6140      {
6141        if (T_j->max != NULL) p_LmFree(T_j->max, strat->tailRing);
6142        if (pNext(T_j->p) != NULL)
6143          T_j->max = p_GetMaxExpP(pNext(T_j->p), strat->tailRing);
6144        else
6145          T_j->max = NULL;
6146      }
6147      if (TEST_OPT_INTSTRATEGY)
6148        T_j->pCleardenom();
6149    }
6150    else
6151    {
6152      assume(currRing == strat->tailRing);
6153      if (pOrdSgn == 1)
6154        strat->S[i] = redtailBba(strat->S[i], end_pos, strat, withT);
6155      else
6156        strat->S[i] = redtail(strat->S[i], strat->sl, strat);
6157      if (TEST_OPT_INTSTRATEGY)
6158        {
6159          if (TEST_OPT_CONTENTSB)
6160            {
6161              number n;
6162              p_Cleardenom_n(strat->S[i], currRing, n);// also does a pContent
6163              if (!nIsOne(n))
6164                {
6165                  denominator_list denom=(denominator_list)omAlloc(sizeof(denominator_list_s));
6166                  denom->n=nInvers(n);
6167                  denom->next=DENOMINATOR_LIST;
6168                  DENOMINATOR_LIST=denom;
6169                }
6170              nDelete(&n);
6171            }
6172          else
6173            {
6174              //pContent(strat->S[i]);
6175              strat->S[i]=p_Cleardenom(strat->S[i], currRing);// also does a pContent
6176            }
6177        }
6178    }
6179    if (TEST_OPT_PROT)
6180      PrintS("-");
6181  }
6182  if (TEST_OPT_PROT) PrintLn();
6183#ifdef KDEBUG
6184  sloppy_max = FALSE;
6185#endif
6186}
6187
6188
6189/*2
6190* computes the new strat->kHEdge and the new pNoether,
6191* returns TRUE, if pNoether has changed
6192*/
6193BOOLEAN newHEdge(polyset S, kStrategy strat)
6194{
6195  int i,j;
6196  poly newNoether;
6197
6198#if 0
6199  if (currRing->weight_all_1)
6200    scComputeHC(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
6201  else
6202    scComputeHCw(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
6203#else
6204  scComputeHC(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
6205#endif
6206  if (strat->t_kHEdge != NULL) p_LmFree(strat->t_kHEdge, strat->tailRing);
6207  if (strat->tailRing != currRing)
6208    strat->t_kHEdge = k_LmInit_currRing_2_tailRing(strat->kHEdge, strat->tailRing);
6209  /* compare old and new noether*/
6210  newNoether = pLmInit(strat->kHEdge);
6211  j = pFDeg(newNoether,currRing);
6212  for (i=1; i<=pVariables; i++)
6213  {
6214    if (pGetExp(newNoether, i) > 0) pDecrExp(newNoether,i);
6215  }
6216  pSetm(newNoether);
6217  if (j < strat->HCord) /*- statistics -*/
6218  {
6219    if (TEST_OPT_PROT)
6220    {
6221      Print("H(%d)",j);
6222      mflush();
6223    }
6224    strat->HCord=j;
6225    #ifdef KDEBUG
6226    if (TEST_OPT_DEBUG)
6227    {
6228      Print("H(%d):",j);
6229      wrp(strat->kHEdge);
6230      PrintLn();
6231    }
6232    #endif
6233  }
6234  if (pCmp(strat->kNoether,newNoether)!=1)
6235  {
6236    pDelete(&strat->kNoether);
6237    strat->kNoether=newNoether;
6238    if (strat->t_kNoether != NULL) p_LmFree(strat->t_kNoether, strat->tailRing);
6239    if (strat->tailRing != currRing)
6240      strat->t_kNoether = k_LmInit_currRing_2_tailRing(strat->kNoether, strat->tailRing);
6241
6242    return TRUE;
6243  }
6244  pLmFree(newNoether);
6245  return FALSE;
6246}
6247
6248/***************************************************************
6249 *
6250 * Routines related for ring changes during std computations
6251 *
6252 ***************************************************************/
6253BOOLEAN kCheckSpolyCreation(LObject *L, kStrategy strat, poly &m1, poly &m2)
6254{
6255  if (strat->overflow) return FALSE;
6256  assume(L->p1 != NULL && L->p2 != NULL);
6257  // shift changes: from 0 to -1
6258  assume(L->i_r1 >= -1 && L->i_r1 <= strat->tl);
6259  assume(L->i_r2 >= -1 && L->i_r2 <= strat->tl);
6260  assume(strat->tailRing != currRing);
6261
6262  if (! k_GetLeadTerms(L->p1, L->p2, currRing, m1, m2, strat->tailRing))
6263    return FALSE;
6264  // shift changes: extra case inserted
6265  if ((L->i_r1 == -1) || (L->i_r2 == -1) )
6266  {
6267    return TRUE;
6268  }
6269  poly p1_max = (strat->R[L->i_r1])->max;
6270  poly p2_max = (strat->R[L->i_r2])->max;
6271
6272  if ((p1_max != NULL && !p_LmExpVectorAddIsOk(m1, p1_max, strat->tailRing)) ||
6273      (p2_max != NULL && !p_LmExpVectorAddIsOk(m2, p2_max, strat->tailRing)))
6274  {
6275    p_LmFree(m1, strat->tailRing);
6276    p_LmFree(m2, strat->tailRing);
6277    m1 = NULL;
6278    m2 = NULL;
6279    return FALSE;
6280  }
6281  return TRUE;
6282}
6283
6284#ifdef HAVE_RINGS
6285/***************************************************************
6286 *
6287 * Checks, if we can compute the gcd poly / strong pair
6288 * gcd-poly = m1 * R[atR] + m2 * S[atS]
6289 *
6290 ***************************************************************/
6291BOOLEAN kCheckStrongCreation(int atR, poly m1, int atS, poly m2, kStrategy strat)
6292{
6293  assume(strat->S_2_R[atS] >= -1 && strat->S_2_R[atS] <= strat->tl);
6294  //assume(strat->tailRing != currRing);
6295
6296  poly p1_max = (strat->R[atR])->max;
6297  poly p2_max = (strat->R[strat->S_2_R[atS]])->max;
6298
6299  if ((p1_max != NULL && !p_LmExpVectorAddIsOk(m1, p1_max, strat->tailRing)) ||
6300      (p2_max != NULL && !p_LmExpVectorAddIsOk(m2, p2_max, strat->tailRing)))
6301  {
6302    return FALSE;
6303  }
6304  return TRUE;
6305}
6306#endif
6307
6308BOOLEAN kStratChangeTailRing(kStrategy strat, LObject *L, TObject* T, unsigned long expbound)
6309{
6310  assume((strat->tailRing == currRing) || (strat->tailRing->bitmask < currRing->bitmask));
6311  /* initial setup or extending */
6312
6313  if (expbound == 0) expbound = strat->tailRing->bitmask << 1;
6314  if (expbound >= currRing->bitmask) return FALSE;
6315  strat->overflow=FALSE;
6316  ring new_tailRing = rModifyRing(currRing,
6317                                  // Hmmm .. the condition pFDeg == pDeg
6318                                  // might be too strong
6319#ifdef HAVE_RINGS
6320                                  (strat->homog && pFDeg == pDeg && !(rField_is_Ring(currRing))), // TODO Oliver
6321#else
6322                                  (strat->homog && pFDeg == pDeg), // omit_degree
6323#endif
6324                                  (strat->ak==0), // omit_comp if the input is an ideal
6325                                  expbound); // exp_limit
6326
6327  if (new_tailRing == currRing) return TRUE;
6328
6329  strat->pOrigFDeg_TailRing = new_tailRing->pFDeg;
6330  strat->pOrigLDeg_TailRing = new_tailRing->pLDeg;
6331
6332  if (currRing->pFDeg != currRing->pFDegOrig)
6333  {
6334    new_tailRing->pFDeg = currRing->pFDeg;
6335    new_tailRing->pLDeg = currRing->pLDeg;
6336  }
6337
6338  if (TEST_OPT_PROT)
6339    Print("[%lu:%d", (unsigned long) new_tailRing->bitmask, new_tailRing->ExpL_Size);
6340  kTest_TS(strat);
6341  assume(new_tailRing != strat->tailRing);
6342  pShallowCopyDeleteProc p_shallow_copy_delete
6343    = pGetShallowCopyDeleteProc(strat->tailRing, new_tailRing);
6344
6345  omBin new_tailBin = omGetStickyBinOfBin(new_tailRing->PolyBin);
6346
6347  int i;
6348  for (i=0; i<=strat->tl; i++)
6349  {
6350    strat->T[i].ShallowCopyDelete(new_tailRing, new_tailBin,
6351                                  p_shallow_copy_delete);
6352  }
6353  for (i=0; i<=strat->Ll; i++)
6354  {
6355    assume(strat->L[i].p != NULL);
6356    if (pNext(strat->L[i].p) != strat->tail)
6357      strat->L[i].ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
6358  }
6359  if (strat->P.t_p != NULL ||
6360      (strat->P.p != NULL && pNext(strat->P.p) != strat->tail))
6361    strat->P.ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
6362
6363  if (L != NULL && L->tailRing != new_tailRing)
6364  {
6365    if (L->i_r < 0)
6366      L->ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
6367    else
6368    {
6369      assume(L->i_r <= strat->tl);
6370      TObject* t_l = strat->R[L->i_r];
6371      assume(t_l != NULL);
6372      L->tailRing = new_tailRing;
6373      L->p = t_l->p;
6374      L->t_p = t_l->t_p;
6375      L->max = t_l->max;
6376    }
6377  }
6378
6379  if (T != NULL && T->tailRing != new_tailRing && T->i_r < 0)
6380    T->ShallowCopyDelete(new_tailRing, new_tailBin, p_shallow_copy_delete);
6381
6382  omMergeStickyBinIntoBin(strat->tailBin, strat->tailRing->PolyBin);
6383  if (strat->tailRing != currRing)
6384    rKillModifiedRing(strat->tailRing);
6385
6386  strat->tailRing = new_tailRing;
6387  strat->tailBin = new_tailBin;
6388  strat->p_shallow_copy_delete
6389    = pGetShallowCopyDeleteProc(currRing, new_tailRing);
6390
6391  if (strat->kHEdge != NULL)
6392  {
6393    if (strat->t_kHEdge != NULL)
6394      p_LmFree(strat->t_kHEdge, strat->tailRing);
6395    strat->t_kHEdge=k_LmInit_currRing_2_tailRing(strat->kHEdge, new_tailRing);
6396  }
6397
6398  if (strat->kNoether != NULL)
6399  {
6400    if (strat->t_kNoether != NULL)
6401      p_LmFree(strat->t_kNoether, strat->tailRing);
6402    strat->t_kNoether=k_LmInit_currRing_2_tailRing(strat->kNoether,
6403                                                   new_tailRing);
6404  }
6405  kTest_TS(strat);
6406  if (TEST_OPT_PROT)
6407    PrintS("]");
6408  return TRUE;
6409}
6410
6411void kStratInitChangeTailRing(kStrategy strat)
6412{
6413  unsigned long l = 0;
6414  int i;
6415  long e;
6416
6417  assume(strat->tailRing == currRing);
6418
6419  for (i=0; i<= strat->Ll; i++)
6420  {
6421    l = p_GetMaxExpL(strat->L[i].p, currRing, l);
6422  }
6423  for (i=0; i<=strat->tl; i++)
6424  {
6425    // Hmm ... this we could do in one Step
6426    l = p_GetMaxExpL(strat->T[i].p, currRing, l);
6427  }
6428  if (rField_is_Ring(currRing))
6429  {
6430    l *= 2;
6431  }
6432  e = p_GetMaxExp(l, currRing);
6433  if (e <= 1) e = 2;
6434
6435  kStratChangeTailRing(strat, NULL, NULL, e);
6436}
6437
6438skStrategy::skStrategy()
6439{
6440  memset(this, 0, sizeof(skStrategy));
6441#ifndef NDEBUG
6442  strat_nr++;
6443  nr=strat_nr;
6444  if (strat_fac_debug) Print("s(%d) created\n",nr);
6445#endif
6446  tailRing = currRing;
6447  P.tailRing = currRing;
6448  tl = -1;
6449  sl = -1;
6450#ifdef HAVE_LM_BIN
6451  lmBin = omGetStickyBinOfBin(currRing->PolyBin);
6452#endif
6453#ifdef HAVE_TAIL_BIN
6454  tailBin = omGetStickyBinOfBin(currRing->PolyBin);
6455#endif
6456  pOrigFDeg = pFDeg;
6457  pOrigLDeg = pLDeg;
6458}
6459
6460
6461skStrategy::~skStrategy()
6462{
6463  if (lmBin != NULL)
6464    omMergeStickyBinIntoBin(lmBin, currRing->PolyBin);
6465  if (tailBin != NULL)
6466    omMergeStickyBinIntoBin(tailBin,
6467                            (tailRing != NULL ? tailRing->PolyBin:
6468                             currRing->PolyBin));
6469  if (t_kHEdge != NULL)
6470    p_LmFree(t_kHEdge, tailRing);
6471  if (t_kNoether != NULL)
6472    p_LmFree(t_kNoether, tailRing);
6473
6474  if (currRing != tailRing)
6475    rKillModifiedRing(tailRing);
6476  pRestoreDegProcs(pOrigFDeg, pOrigLDeg);
6477}
6478
6479#if 0
6480Timings for the different possibilities of posInT:
6481            T15           EDL         DL          EL            L         1-2-3
6482Gonnet      43.26       42.30       38.34       41.98       38.40      100.04
6483Hairer_2_1   1.11        1.15        1.04        1.22        1.08        4.7
6484Twomat3      1.62        1.69        1.70        1.65        1.54       11.32
6485ahml         4.48        4.03        4.03        4.38        4.96       26.50
6486c7          15.02       13.98       15.16       13.24       17.31       47.89
6487c8         505.09      407.46      852.76      413.21      499.19        n/a
6488f855        12.65        9.27       14.97        8.78       14.23       33.12
6489gametwo6    11.47       11.35       14.57       11.20       12.02       35.07
6490gerhard_3    2.73        2.83        2.93        2.64        3.12        6.24
6491ilias13     22.89       22.46       24.62       20.60       23.34       53.86
6492noon8       40.68       37.02       37.99       36.82       35.59      877.16
6493rcyclic_19  48.22       42.29       43.99       45.35       51.51      204.29
6494rkat9       82.37       79.46       77.20       77.63       82.54      267.92
6495schwarz_11  16.46       16.81       16.76       16.81       16.72       35.56
6496test016     16.39       14.17       14.40       13.50       14.26       34.07
6497test017     34.70       36.01       33.16       35.48       32.75       71.45
6498test042     10.76       10.99       10.27       11.57       10.45       23.04
6499test058      6.78        6.75        6.51        6.95        6.22        9.47
6500test066     10.71       10.94       10.76       10.61       10.56       19.06
6501test073     10.75       11.11       10.17       10.79        8.63       58.10
6502test086     12.23       11.81       12.88       12.24       13.37       66.68
6503test103      5.05        4.80        5.47        4.64        4.89       11.90
6504test154     12.96       11.64       13.51       12.46       14.61       36.35
6505test162     65.27       64.01       67.35       59.79       67.54      196.46
6506test164      7.50        6.50        7.68        6.70        7.96       17.13
6507virasoro     3.39        3.50        3.35        3.47        3.70        7.66
6508#endif
6509
6510
6511//#ifdef HAVE_MORE_POS_IN_T
6512#if 1
6513// determines the position based on: 1.) Ecart 2.) FDeg 3.) pLength
6514int posInT_EcartFDegpLength(const TSet set,const int length,LObject &p)
6515{
6516
6517  if (length==-1) return 0;
6518
6519  int o = p.ecart;
6520  int op=p.GetpFDeg();
6521  int ol = p.GetpLength();
6522
6523  if (set[length].ecart < o)
6524    return length+1;
6525  if (set[length].ecart == o)
6526  {
6527     int oo=set[length].GetpFDeg();
6528     if ((oo < op) || ((oo==op) && (set[length].length < ol)))
6529       return length+1;
6530  }
6531
6532  int i;
6533  int an = 0;
6534  int en= length;
6535  loop
6536  {
6537    if (an >= en-1)
6538    {
6539      if (set[an].ecart > o)
6540        return an;
6541      if (set[an].ecart == o)
6542      {
6543         int oo=set[an].GetpFDeg();
6544         if((oo > op)
6545         || ((oo==op) && (set[an].pLength > ol)))
6546           return an;
6547      }
6548      return en;
6549    }
6550    i=(an+en) / 2;
6551    if (set[i].ecart > o)
6552      en=i;
6553    else if (set[i].ecart == o)
6554    {
6555       int oo=set[i].GetpFDeg();
6556       if ((oo > op)
6557       || ((oo == op) && (set[i].pLength > ol)))
6558         en=i;
6559       else
6560        an=i;
6561    }
6562    else
6563      an=i;
6564  }
6565}
6566
6567// determines the position based on: 1.) FDeg 2.) pLength
6568int posInT_FDegpLength(const TSet set,const int length,LObject &p)
6569{
6570
6571  if (length==-1) return 0;
6572
6573  int op=p.GetpFDeg();
6574  int ol = p.GetpLength();
6575
6576  int oo=set[length].GetpFDeg();
6577  if ((oo < op) || ((oo==op) && (set[length].length < ol)))
6578    return length+1;
6579
6580  int i;
6581  int an = 0;
6582  int en= length;
6583  loop
6584    {
6585      if (an >= en-1)
6586      {
6587        int oo=set[an].GetpFDeg();
6588        if((oo > op)
6589           || ((oo==op) && (set[an].pLength > ol)))
6590          return an;
6591        return en;
6592      }
6593      i=(an+en) / 2;
6594      int oo=set[i].GetpFDeg();
6595      if ((oo > op)
6596          || ((oo == op) && (set[i].pLength > ol)))
6597        en=i;
6598      else
6599        an=i;
6600    }
6601}
6602
6603
6604// determines the position based on: 1.) pLength
6605int posInT_pLength(const TSet set,const int length,LObject &p)
6606{
6607  int ol = p.GetpLength();
6608  if (length==-1)
6609    return 0;
6610  if (set[length].length<p.length)
6611    return length+1;
6612
6613  int i;
6614  int an = 0;
6615  int en= length;
6616
6617  loop
6618  {
6619    if (an >= en-1)
6620    {
6621      if (set[an].pLength>ol) return an;
6622      return en;
6623    }
6624    i=(an+en) / 2;
6625    if (set[i].pLength>ol) en=i;
6626    else                        an=i;
6627  }
6628}
6629#endif
6630
6631// kstd1.cc:
6632int redFirst (LObject* h,kStrategy strat);
6633int redEcart (LObject* h,kStrategy strat);
6634void enterSMora (LObject p,int atS,kStrategy strat, int atR=-1);
6635void enterSMoraNF (LObject p,int atS,kStrategy strat, int atR=-1);
6636// ../Singular/misc.cc:
6637char *  showOption();
6638
6639void kDebugPrint(kStrategy strat)
6640{
6641  PrintS("red: ");
6642    if (strat->red==redFirst) PrintS("redFirst\n");
6643    else if (strat->red==redHoney) PrintS("redHoney\n");
6644    else if (strat->red==redEcart) PrintS("redEcart\n");
6645    else if (strat->red==redHomog) PrintS("redHomog\n");
6646    else  Print("%p\n",(void*)strat->red);
6647  PrintS("posInT: ");
6648    if (strat->posInT==posInT0) PrintS("posInT0\n");
6649    else if (strat->posInT==posInT0) PrintS("posInT0\n");
6650    else if (strat->posInT==posInT1) PrintS("posInT1\n");
6651    else if (strat->posInT==posInT11) PrintS("posInT11\n");
6652    else if (strat->posInT==posInT110) PrintS("posInT110\n");
6653    else if (strat->posInT==posInT13) PrintS("posInT13\n");
6654    else if (strat->posInT==posInT15) PrintS("posInT15\n");
6655    else if (strat->posInT==posInT17) PrintS("posInT17\n");
6656    else if (strat->posInT==posInT17_c) PrintS("posInT17_c\n");
6657    else if (strat->posInT==posInT19) PrintS("posInT19\n");
6658    else if (strat->posInT==posInT2) PrintS("posInT2\n");
6659#ifdef HAVE_MORE_POS_IN_T
6660    else if (strat->posInT==posInT_EcartFDegpLength) PrintS("posInT_EcartFDegpLength\n");
6661    else if (strat->posInT==posInT_FDegpLength) PrintS("posInT_FDegpLength\n");
6662    else if (strat->posInT==posInT_pLength) PrintS("posInT_pLength\n");
6663#endif
6664    else if (strat->posInT==posInT_EcartpLength) PrintS("posInT_EcartpLength\n");
6665    else if (strat->posInT==posInTrg0) PrintS("posInTrg0\n");
6666    else  Print("%p\n",(void*)strat->posInT);
6667  PrintS("posInL: ");
6668    if (strat->posInL==posInL0) PrintS("posInL0\n");
6669    else if (strat->posInL==posInL10) PrintS("posInL10\n");
6670    else if (strat->posInL==posInL11) PrintS("posInL11\n");
6671    else if (strat->posInL==posInL110) PrintS("posInL110\n");
6672    else if (strat->posInL==posInL13) PrintS("posInL13\n");
6673    else if (strat->posInL==posInL15) PrintS("posInL15\n");
6674    else if (strat->posInL==posInL17) PrintS("posInL17\n");
6675    else if (strat->posInL==posInL17_c) PrintS("posInL17_c\n");
6676    else if (strat->posInL==posInLSpecial) PrintS("posInLSpecial\n");
6677    else if (strat->posInL==posInLrg0) PrintS("posInLrg0\n");
6678    else  Print("%p\n",(void*)strat->posInL);
6679  PrintS("enterS: ");
6680    if (strat->enterS==enterSBba) PrintS("enterSBba\n");
6681    else if (strat->enterS==enterSMora) PrintS("enterSMora\n");
6682    else if (strat->enterS==enterSMoraNF) PrintS("enterSMoraNF\n");
6683    else  Print("%p\n",(void*)strat->enterS);
6684  PrintS("initEcart: ");
6685    if (strat->initEcart==initEcartBBA) PrintS("initEcartBBA\n");
6686    else if (strat->initEcart==initEcartNormal) PrintS("initEcartNormal\n");
6687    else  Print("%p\n",(void*)strat->initEcart);
6688  PrintS("initEcartPair: ");
6689    if (strat->initEcartPair==initEcartPairBba) PrintS("initEcartPairBba\n");
6690    else if (strat->initEcartPair==initEcartPairMora) PrintS("initEcartPairMora\n");
6691    else  Print("%p\n",(void*)strat->initEcartPair);
6692  Print("homog=%d, LazyDegree=%d, LazyPass=%d, ak=%d,\n",
6693         strat->homog, strat->LazyDegree,strat->LazyPass, strat->ak);
6694  Print("honey=%d, sugarCrit=%d, Gebauer=%d, noTailReduction=%d\n",
6695         strat->honey,strat->sugarCrit,strat->Gebauer,strat->noTailReduction,strat->use_buckets);
6696  Print("posInLDependsOnLength=%d, use_buckets=%d\n",
6697         strat->posInLDependsOnLength,strat->use_buckets);
6698  PrintS(showOption());PrintLn();
6699  PrintS("LDeg: ");
6700    if (currRing->pLDeg==pLDeg0) PrintS("pLDeg0");
6701    else if (currRing->pLDeg==pLDeg0c) PrintS("pLDeg0c");
6702    else if (currRing->pLDeg==pLDegb) PrintS("pLDegb");
6703    else if (currRing->pLDeg==pLDeg1) PrintS("pLDeg1");
6704    else if (currRing->pLDeg==pLDeg1c) PrintS("pLDeg1c");
6705    else if (currRing->pLDeg==pLDeg1_Deg) PrintS("pLDeg1_Deg");
6706    else if (currRing->pLDeg==pLDeg1c_Deg) PrintS("pLDeg1c_Deg");
6707    else if (currRing->pLDeg==pLDeg1_Totaldegree) PrintS("pLDeg1_Totaldegree");
6708    else if (currRing->pLDeg==pLDeg1c_Totaldegree) PrintS("pLDeg1c_Totaldegree");
6709    else if (currRing->pLDeg==pLDeg1_WFirstTotalDegree) PrintS("pLDeg1_WFirstTotalDegree");
6710    else if (currRing->pLDeg==pLDeg1c_WFirstTotalDegree) PrintS("pLDeg1c_WFirstTotalDegree");
6711    else Print("? (%lx)", (long)currRing->pLDeg);
6712    PrintS(" / ");
6713    if (strat->tailRing->pLDeg==pLDeg0) PrintS("pLDeg0");
6714    else if (strat->tailRing->pLDeg==pLDeg0c) PrintS("pLDeg0c");
6715    else if (strat->tailRing->pLDeg==pLDegb) PrintS("pLDegb");
6716    else if (strat->tailRing->pLDeg==pLDeg1) PrintS("pLDeg1");
6717    else if (strat->tailRing->pLDeg==pLDeg1c) PrintS("pLDeg1c");
6718    else if (strat->tailRing->pLDeg==pLDeg1_Deg) PrintS("pLDeg1_Deg");
6719    else if (strat->tailRing->pLDeg==pLDeg1c_Deg) PrintS("pLDeg1c_Deg");
6720    else if (strat->tailRing->pLDeg==pLDeg1_Totaldegree) PrintS("pLDeg1_Totaldegree");
6721    else if (strat->tailRing->pLDeg==pLDeg1c_Totaldegree) PrintS("pLDeg1c_Totaldegree");
6722    else if (strat->tailRing->pLDeg==pLDeg1_WFirstTotalDegree) PrintS("pLDeg1_WFirstTotalDegree");
6723    else if (strat->tailRing->pLDeg==pLDeg1c_WFirstTotalDegree) PrintS("pLDeg1c_WFirstTotalDegree");
6724    else Print("? (%lx)", (long)strat->tailRing->pLDeg);
6725    Print(" syzring:%d, syzComp(strat):%d syzComb(ring)\n",rIsSyzIndexRing(currRing),strat->syzComp,rGetCurrSyzLimit());
6726    if(TEST_OPT_DEGBOUND)
6727      Print(" degBound: %d\n", Kstd1_deg);
6728
6729}
6730
6731
6732#ifdef HAVE_SHIFTBBA
6733poly pMove2CurrTail(poly p, kStrategy strat)
6734{
6735  /* assume: p is completely in currRing */
6736  /* produces an object with LM in curring
6737     and TAIL in tailring */
6738  if (pNext(p)!=NULL)
6739  {
6740    pNext(p) = prMoveR(pNext(p), /* src */ currRing, /* dest */ strat->tailRing);
6741  }
6742  return(p);
6743}
6744#endif
6745
6746#ifdef HAVE_SHIFTBBA
6747poly pMoveCurrTail2poly(poly p, kStrategy strat)
6748{
6749  /* assume: p has  LM in curring and TAIL in tailring */
6750  /* convert it to complete currRing */
6751
6752  /* check that LM is in currRing */
6753  assume(p_LmCheckIsFromRing(p, currRing));
6754
6755  if (pNext(p)!=NULL)
6756  {
6757    pNext(p) = prMoveR(pNext(p), /* src */ strat->tailRing, /* dest */currRing);
6758  }
6759  return(p);
6760}
6761#endif
6762
6763#ifdef HAVE_SHIFTBBA
6764poly pCopyL2p(LObject H, kStrategy strat)
6765{
6766    /* restores a poly in currRing from LObject */
6767    LObject h = H;
6768    h.Copy();
6769    poly p;
6770    if (h.p == NULL)
6771    {
6772      if (h.t_p != NULL)
6773      {
6774         p = prMoveR(h.t_p, /* source ring: */ strat->tailRing, /* dest. ring: */ currRing);
6775        return(p);
6776      }
6777      else
6778      {
6779        /* h.tp == NULL -> the object is NULL */
6780        return(NULL);
6781      }
6782    }
6783    /* we're here if h.p != NULL */
6784    if (h.t_p == NULL)
6785    {
6786       /* then h.p is the whole poly in currRing */
6787       p = h.p;
6788      return(p);
6789    }
6790    /* we're here if h.p != NULL and h.t_p != NULL */
6791    // clean h.p, get poly from t_p
6792     pNext(h.p)=NULL;
6793     pDelete(&h.p);
6794     p = prMoveR(h.t_p, /* source ring: */ strat->tailRing,
6795                         /* dest. ring: */ currRing);
6796     // no need to clean h: we re-used the polys
6797    return(p);
6798}
6799#endif
6800
6801//LObject pCopyp2L(poly p, kStrategy strat)
6802//{
6803    /* creates LObject from the poly in currRing */
6804  /* actually put p into L.p and make L.t_p=NULL : does not work */
6805
6806//}
6807
6808// poly pCopyL2p(LObject H, kStrategy strat)
6809// {
6810//   /* restores a poly in currRing from LObject */
6811//   LObject h = H;
6812//   h.Copy();
6813//   poly p;
6814//   if (h.p == NULL)
6815//   {
6816//     if (h.t_p != NULL)
6817//     {
6818//       p = p_ShallowCopyDelete(h.t_p, (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
6819//       return(p);
6820//     }
6821//     else
6822//     {
6823//       /* h.tp == NULL -> the object is NULL */
6824//       return(NULL);
6825//     }
6826//   }
6827//   /* we're here if h.p != NULL */
6828
6829//   if (h.t_p == NULL)
6830//   {
6831//     /* then h.p is the whole poly in tailRing */
6832//     if (strat->tailBin != NULL && (pNext(h.p) != NULL))
6833//     {
6834//       p = p_ShallowCopyDelete(h.p, (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
6835//     }
6836//     return(p);
6837//   }
6838//   /* we're here if h.p != NULL and h.t_p != NULL */
6839//   p = pCopy(pHead(h.p)); // in currRing
6840//   if (strat->tailBin != NULL && (pNext(h.p) != NULL))
6841//   {
6842//     //    pNext(p) = p_ShallowCopyDelete(pNext(h.t_p), (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
6843//     poly pp = p_Copy(pNext(h.p), strat->tailRing);
6844//     //    poly p3 = p_Copy(pNext(h.p), currRing); // error
6845//       // p_ShallowCopyDelete(pNext(h.p), currRing, strat->tailBin); // the same as pp
6846//     poly p5 = p_ShallowCopyDelete(pNext(h.p), strat->tailRing, strat->tailBin);
6847//     pNext(p) = p_ShallowCopyDelete(h.t_p, strat->tailRing, strat->tailBin);
6848//     poly p4 = p_Copy(h.t_p, strat->tailRing);
6849//     //    if (p.t_p != NULL) pNext(p.t_p) = pNext(p.p);
6850//   }
6851//   //  pTest(p);
6852//   return(p);
6853// }
6854
6855#ifdef HAVE_SHIFTBBA
6856/* including the self pairs */
6857void updateSShift(kStrategy strat,int uptodeg,int lV)
6858{
6859  /* to use after updateS(toT=FALSE,strat) */
6860  /* fills T with shifted elt's of S */
6861  int i;
6862  LObject h;
6863  int atT = -1; // or figure out smth better
6864  strat->tl = -1; // init
6865  for (i=0; i<=strat->sl; i++)
6866  {
6867    memset(&h,0,sizeof(h));
6868    h.p =  strat->S[i]; // lm in currRing, tail in TR
6869    strat->initEcart(&h);
6870    h.sev = strat->sevS[i];
6871    h.t_p = NULL;
6872    h.GetTP(); // creates correct t_p
6873    /*puts the elements of S with their shifts to T*/
6874    //    int atT, int uptodeg, int lV)
6875    strat->S_2_R[i] = strat->tl + 1; // the el't with shift 0 will be inserted first
6876    // need a small check for above; we insert >=1 elements
6877    // insert this check into kTest_TS ?
6878    enterTShift(h,strat,atT,uptodeg,lV);
6879  }
6880  /* what about setting strat->tl? */
6881}
6882#endif
6883
6884#ifdef HAVE_SHIFTBBA
6885void initBuchMoraShift (ideal F,ideal Q,kStrategy strat)
6886{
6887  strat->interpt = BTEST1(OPT_INTERRUPT);
6888  strat->kHEdge=NULL;
6889  if (pOrdSgn==1) strat->kHEdgeFound=FALSE;
6890  /*- creating temp data structures------------------- -*/
6891  strat->cp = 0;
6892  strat->c3 = 0;
6893  strat->cv = 0;
6894  strat->tail = pInit();
6895  /*- set s -*/
6896  strat->sl = -1;
6897  /*- set L -*/
6898  strat->Lmax = setmaxL;
6899  strat->Ll = -1;
6900  strat->L = initL();
6901  /*- set B -*/
6902  strat->Bmax = setmaxL;
6903  strat->Bl = -1;
6904  strat->B = initL();
6905  /*- set T -*/
6906  strat->tl = -1;
6907  strat->tmax = setmaxT;
6908  strat->T = initT();
6909  strat->R = initR();
6910  strat->sevT = initsevT();
6911  /*- init local data struct.---------------------------------------- -*/
6912  strat->P.ecart=0;
6913  strat->P.length=0;
6914  if (pOrdSgn==-1)
6915  {
6916    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
6917    if (strat->kNoether!=NULL) pSetComp(strat->kNoetherTail(), strat->ak);
6918  }
6919  if(TEST_OPT_SB_1)
6920  {
6921    int i;
6922    ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
6923    for (i=strat->newIdeal;i<IDELEMS(F);i++)
6924    {
6925      P->m[i-strat->newIdeal] = F->m[i];
6926      F->m[i] = NULL;
6927    }
6928    initSSpecial(F,Q,P,strat);
6929    for (i=strat->newIdeal;i<IDELEMS(F);i++)
6930    {
6931      F->m[i] = P->m[i-strat->newIdeal];
6932      P->m[i-strat->newIdeal] = NULL;
6933    }
6934    idDelete(&P);
6935  }
6936  else
6937  {
6938    /*Shdl=*/initSL(F, Q,strat); /*sets also S, ecartS, fromQ */
6939    // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
6940  }
6941  strat->kIdeal = NULL;
6942  strat->fromT = FALSE;
6943  strat->noTailReduction = !TEST_OPT_REDTAIL;
6944  if (!TEST_OPT_SB_1)
6945  {
6946    /* the only change: we do not fill the set T*/
6947    updateS(FALSE,strat);
6948  }
6949  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
6950  strat->fromQ=NULL;
6951  /* more changes: fill the set T with all the shifts of elts of S*/
6952  /* is done by other procedure */
6953}
6954#endif
6955
6956#ifdef HAVE_SHIFTBBA
6957/*1
6958* put the pairs (sh \dot s[i],p)  into the set B, ecart=ecart(p)
6959*/
6960void enterOnePairManyShifts (int i, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int uptodeg, int lV)
6961{
6962  /* p comes from strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
6963
6964  assume(p_LmCheckIsFromRing(p,currRing));
6965  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
6966
6967  /* cycles through all shifts of s[i] until uptodeg - lastVblock(s[i]) */
6968  /* that is create the pairs (f, s \dot g)  */
6969
6970  poly qq = strat->S[i]; //  lm in currRing, tail in tailRing
6971
6972  //  poly q = pCopy(pHead(strat->S[i])); // lm in currRing
6973  //  pNext(q) = prCopyR(pNext(strat->S[i]),strat->tailRing,currRing); // zero shift
6974
6975 /* determine how many elements we have to insert for a given s[i] */
6976  /* x(0)y(1)z(2) : lastVblock-1=2, to add until lastVblock=uptodeg-1 */
6977  /* hence, a total number of elt's to add is: */
6978  /*  int toInsert = 1 + (uptodeg-1) - (pLastVblock(p.p, lV) -1);  */
6979  int toInsert =  itoInsert(qq, uptodeg,  lV, strat->tailRing);
6980
6981#ifdef KDEBUG
6982    if (TEST_OPT_DEBUG)
6983    {
6984      //      Print("entered ManyShifts: with toInsert=%d",toInsert); PrintLn();
6985    }
6986#endif
6987
6988  assume(i<=strat->sl); // from OnePair
6989  if (strat->interred_flag) return; // ?
6990
6991  /* these vars hold for all shifts of s[i] */
6992  int ecartq = 0; //Hans says it's ok; we're in the homog case, no ecart
6993
6994  int qfromQ;
6995  if (strat->fromQ != NULL)
6996  {
6997    qfromQ = strat->fromQ[i];
6998  }
6999  else
7000  {
7001    qfromQ = -1;
7002  }
7003
7004  int j;
7005
7006  poly q, s;
7007
7008  // for the 0th shift: insert the orig. pair
7009  enterOnePairShift(qq, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, 0, i, uptodeg, lV);
7010
7011  for (j=1; j<= toInsert; j++)
7012  {
7013    //    q = pLPshift(strat->S[i],j,uptodeg,lV);
7014    q = p_LPshiftT(qq, j, uptodeg, lV, strat, currRing);
7015    //    q = p_mLPshift(qq,j,uptodeg,lV,currRing); // lm in currRing, shift this monomial
7016    //    s = p_LPshift(pNext(qq), j, uptodeg, lV, strat->tailRing); // from tailRing
7017    //    pNext(q) = s; // in tailRing
7018    /* here we need to call enterOnePair with two polys ... */
7019
7020#ifdef KDEBUG
7021    if (TEST_OPT_DEBUG)
7022    {
7023      //      PrintS("ManyShifts: calling enterOnePairShift(q,p)");      PrintLn();
7024    }
7025#endif
7026    enterOnePairShift(q, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, j, i, uptodeg, lV);
7027  }
7028}
7029#endif
7030
7031#ifdef HAVE_SHIFTBBA
7032/*1
7033* put the pairs (sh \dot qq,p)  into the set B, ecart=ecart(p)
7034* despite the name, not only self shifts
7035*/
7036void enterOnePairSelfShifts (poly qq, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int uptodeg, int lV)
7037{
7038
7039  /* format: p,qq are in LObject form: lm in CR, tail in TR */
7040  /* for true self pairs qq ==p  */
7041  /* we test both qq and p */
7042  assume(p_LmCheckIsFromRing(qq,currRing));
7043  assume(p_CheckIsFromRing(pNext(qq),strat->tailRing));
7044  assume(p_LmCheckIsFromRing(p,currRing));
7045  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
7046
7047  /* since this proc is applied twice for (h, s*g) and (g,s*h), init j with 1 only */
7048
7049  //  int j = 0;
7050  int j = 1;
7051
7052  /* for such self pairs start with 1, not with 0 */
7053  if (qq == p) j=1;
7054
7055  /* should cycle through all shifts of q until uptodeg - lastVblock(q) */
7056  /* that is create the pairs (f, s \dot g)  */
7057
7058  int toInsert =  itoInsert(qq, uptodeg,  lV, strat->tailRing);
7059
7060#ifdef KDEBUG
7061    if (TEST_OPT_DEBUG)
7062    {
7063      //      Print("entered SelfShifts: with toInsert=%d",toInsert); PrintLn();
7064    }
7065#endif
7066
7067  poly q, s;
7068
7069  if (strat->interred_flag) return; // ?
7070
7071  /* these vars hold for all shifts of s[i] */
7072  int ecartq = 0; //Hans says it's ok; we're in the homog case, no ecart
7073  int qfromQ = 0; // strat->fromQ[i];
7074
7075  for (; j<= toInsert; j++)
7076  {
7077    //    q = pLPshift(strat->S[i],j,uptodeg,lV);
7078    /* we increase shifts by one; must delete q there*/
7079    //    q = qq; q = pMoveCurrTail2poly(q,strat);
7080    //    q = pLPshift(q,j,uptodeg,lV); //,currRing);
7081    q = p_LPshiftT(qq, j, uptodeg, lV, strat, currRing);
7082    //    q = p_mLPshift(qq,j,uptodeg,lV,currRing); // lm in currRing, shift this monomial
7083    //    s = p_LPshift(pNext(qq), j, uptodeg, lV, strat->tailRing); // from tailRing
7084    //    pNext(q) = s; // in tailRing
7085    /* here we need to call enterOnePair with two polys ... */
7086#ifdef KDEBUG
7087    if (TEST_OPT_DEBUG)
7088    {
7089      //      PrintS("SelfShifts: calling enterOnePairShift(q,p)");      PrintLn();
7090    }
7091#endif
7092    enterOnePairShift(q, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, j, -1, uptodeg, lV);
7093  }
7094}
7095#endif
7096
7097#ifdef HAVE_SHIFTBBA
7098/*2
7099* put the pair (q,p)  into the set B, ecart=ecart(p), q is the shift of some s[i]
7100*/
7101void 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)
7102{
7103
7104  /* Format: q and p are like strat->P.p, so lm in CR, tail in TR */
7105
7106  /* check this Formats: */
7107  assume(p_LmCheckIsFromRing(q,currRing));
7108  assume(p_CheckIsFromRing(pNext(q),strat->tailRing));
7109  assume(p_LmCheckIsFromRing(p,currRing));
7110  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
7111
7112#ifdef KDEBUG
7113    if (TEST_OPT_DEBUG)
7114    {
7115//       PrintS("enterOnePairShift(q,p) invoked with q = ");
7116//       wrp(q); //      wrp(pHead(q));
7117//       PrintS(", p = ");
7118//       wrp(p); //wrp(pHead(p));
7119//       PrintLn();
7120    }
7121#endif
7122
7123  /* poly q stays for s[i], ecartq = ecart(q), qisFromQ = applies to q */
7124
7125  int qfromQ = qisFromQ;
7126
7127  /* need additionally: int up_to_degree, poly V0 with the variables in (0)  or just the number lV = the length of the first block */
7128
7129  if (strat->interred_flag) return;
7130
7131  int      l,j,compare;
7132  LObject  Lp;
7133  Lp.i_r = -1;
7134
7135#ifdef KDEBUG
7136  Lp.ecart=0; Lp.length=0;
7137#endif
7138  /*- computes the lcm(s[i],p) -*/
7139  Lp.lcm = pInit();
7140
7141  pLcm(p,q, Lp.lcm); // q is what was strat->S[i], so a poly in LM/TR presentation
7142  pSetm(Lp.lcm);
7143
7144  /* apply the V criterion */
7145  if (!isInV(Lp.lcm, lV))
7146  {
7147#ifdef KDEBUG
7148    if (TEST_OPT_DEBUG)
7149    {
7150      PrintS("V crit applied to q = ");
7151      wrp(q); //      wrp(pHead(q));
7152      PrintS(", p = ");
7153      wrp(p); //wrp(pHead(p));
7154      PrintLn();
7155    }
7156#endif
7157    pLmFree(Lp.lcm);
7158    Lp.lcm=NULL;
7159    /* + counter for applying the V criterion */
7160    strat->cv++;
7161    return;
7162  }
7163
7164  if (strat->sugarCrit && ALLOW_PROD_CRIT(strat))
7165  {
7166    if((!((ecartq>0)&&(ecart>0)))
7167    && pHasNotCF(p,q))
7168    {
7169    /*
7170    *the product criterion has applied for (s,p),
7171    *i.e. lcm(s,p)=product of the leading terms of s and p.
7172    *Suppose (s,r) is in L and the leading term
7173    *of p divides lcm(s,r)
7174    *(==> the leading term of p divides the leading term of r)
7175    *but the leading term of s does not divide the leading term of r
7176    *(notice that this condition is automatically satisfied if r is still
7177    *in S), then (s,r) can be cancelled.
7178    *This should be done here because the
7179    *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
7180    *
7181    *Moreover, skipping (s,r) holds also for the noncommutative case.
7182    */
7183      strat->cp++;
7184      pLmFree(Lp.lcm);
7185      Lp.lcm=NULL;
7186      return;
7187    }
7188    else
7189      Lp.ecart = si_max(ecart,ecartq);
7190    if (strat->fromT && (ecartq>ecart))
7191    {
7192      pLmFree(Lp.lcm);
7193      Lp.lcm=NULL;
7194      return;
7195      /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
7196    }
7197    /*
7198    *the set B collects the pairs of type (S[j],p)
7199    *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
7200    *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
7201    *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
7202    */
7203    {
7204      j = strat->Bl;
7205      loop
7206      {
7207        if (j < 0)  break;
7208        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
7209        if ((compare==1)
7210        &&(sugarDivisibleBy(strat->B[j].ecart,Lp.ecart)))
7211        {
7212          strat->c3++;
7213          if ((strat->fromQ==NULL) || (isFromQ==0) || (qfromQ==0))
7214          {
7215            pLmFree(Lp.lcm);
7216            return;
7217          }
7218          break;
7219        }
7220        else
7221        if ((compare ==-1)
7222        && sugarDivisibleBy(Lp.ecart,strat->B[j].ecart))
7223        {
7224          deleteInL(strat->B,&strat->Bl,j,strat);
7225          strat->c3++;
7226        }
7227        j--;
7228      }
7229    }
7230  }
7231  else /*sugarcrit*/
7232  {
7233    if (ALLOW_PROD_CRIT(strat))
7234    {
7235      // if currRing->nc_type!=quasi (or skew)
7236      // TODO: enable productCrit for super commutative algebras...
7237      if(/*(strat->ak==0) && productCrit(p,strat->S[i])*/
7238      pHasNotCF(p,q))
7239      {
7240      /*
7241      *the product criterion has applied for (s,p),
7242      *i.e. lcm(s,p)=product of the leading terms of s and p.
7243      *Suppose (s,r) is in L and the leading term
7244      *of p devides lcm(s,r)
7245      *(==> the leading term of p devides the leading term of r)
7246      *but the leading term of s does not devide the leading term of r
7247      *(notice that tis condition is automatically satisfied if r is still
7248      *in S), then (s,r) can be canceled.
7249      *This should be done here because the
7250      *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
7251      */
7252          strat->cp++;
7253          pLmFree(Lp.lcm);
7254          Lp.lcm=NULL;
7255          return;
7256      }
7257      if (strat->fromT && (ecartq>ecart))
7258      {
7259        pLmFree(Lp.lcm);
7260        Lp.lcm=NULL;
7261        return;
7262        /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
7263      }
7264      /*
7265      *the set B collects the pairs of type (S[j],p)
7266      *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
7267      *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
7268      *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
7269      */
7270      for(j = strat->Bl;j>=0;j--)
7271      {
7272        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
7273        if (compare==1)
7274        {
7275          strat->c3++;
7276          if ((strat->fromQ==NULL) || (isFromQ==0) || (qfromQ==0))
7277          {
7278            pLmFree(Lp.lcm);
7279            return;
7280          }
7281          break;
7282        }
7283        else
7284        if (compare ==-1)
7285        {
7286          deleteInL(strat->B,&strat->Bl,j,strat);
7287          strat->c3++;
7288        }
7289      }
7290    }
7291  }
7292  /*
7293  *the pair (S[i],p) enters B if the spoly != 0
7294  */
7295  /*-  compute the short s-polynomial -*/
7296  if (strat->fromT && !TEST_OPT_INTSTRATEGY)
7297    pNorm(p);
7298  if ((q==NULL) || (p==NULL))
7299    return;
7300  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (qfromQ!=0))
7301    Lp.p=NULL;
7302  else
7303  {
7304//     if ( rIsPluralRing(currRing) )
7305//     {
7306//       if(pHasNotCF(p, q))
7307//       {
7308//         if(ncRingType(currRing) == nc_lie)
7309//         {
7310//             // generalized prod-crit for lie-type
7311//             strat->cp++;
7312//             Lp.p = nc_p_Bracket_qq(pCopy(p),q);
7313//         }
7314//         else
7315//         if( ALLOW_PROD_CRIT(strat) )
7316//         {
7317//             // product criterion for homogeneous case in SCA
7318//             strat->cp++;
7319//             Lp.p = NULL;
7320//         }
7321//         else
7322//           Lp.p = nc_CreateSpoly(q,p,currRing); // ?
7323//       }
7324//       else  Lp.p = nc_CreateSpoly(q,p,currRing);
7325//     }
7326//     else
7327//     {
7328
7329    /* ksCreateShortSpoly needs two Lobject-kind presentations */
7330    /* p is already in this form, so convert q */
7331    //    q = pMove2CurrTail(q, strat);
7332    Lp.p = ksCreateShortSpoly(q, p, strat->tailRing);
7333      //  }
7334  }
7335  if (Lp.p == NULL)
7336  {
7337    /*- the case that the s-poly is 0 -*/
7338    /* TEMPORARILY DISABLED FOR SHIFTS because there is no i*/
7339//      if (strat->pairtest==NULL) initPairtest(strat);
7340//      strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
7341//      strat->pairtest[strat->sl+1] = TRUE;
7342    /* END _ TEMPORARILY DISABLED FOR SHIFTS */
7343    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
7344    /*
7345    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
7346    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
7347    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
7348    *term of p devides the lcm(s,r)
7349    *(this canceling should be done here because
7350    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
7351    *the first case is handeled in chainCrit
7352    */
7353    if (Lp.lcm!=NULL) pLmFree(Lp.lcm);
7354  }
7355  else
7356  {
7357    /*- the pair (S[i],p) enters B -*/
7358    /* both of them should have their LM in currRing and TAIL in tailring */
7359    Lp.p1 = q;  // already in the needed form
7360    Lp.p2 = p; // already in the needed form
7361
7362    if ( !rIsPluralRing(currRing) )
7363      pNext(Lp.p) = strat->tail;
7364
7365    /* TEMPORARILY DISABLED FOR SHIFTS because there's no i*/
7366    /* at the beginning we DO NOT set atR = -1 ANYMORE*/
7367    if ( (atR >= 0) && (shiftcount==0) && (ifromS >=0) )
7368    {
7369      Lp.i_r1 = kFindInT(Lp.p1,strat); //strat->S_2_R[ifromS];
7370      Lp.i_r2 = atR;
7371    }
7372    else
7373    {
7374      /* END _ TEMPORARILY DISABLED FOR SHIFTS */
7375      Lp.i_r1 = -1;
7376      Lp.i_r2 = -1;
7377     }
7378    strat->initEcartPair(&Lp,q,p,ecartq,ecart);
7379
7380    if (TEST_OPT_INTSTRATEGY)
7381    {
7382      if (!rIsPluralRing(currRing))
7383        nDelete(&(Lp.p->coef));
7384    }
7385
7386    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
7387    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
7388  }
7389}
7390#endif
7391
7392#ifdef HAVE_SHIFTBBA
7393/*2
7394*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
7395*superfluous elements in S will be deleted
7396*/
7397void enterpairsShift (poly h,int k,int ecart,int pos,kStrategy strat, int atR,int uptodeg, int lV)
7398{
7399  /* h is strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
7400  /* Q: what is exactly the strat->fromT ? A: a local case trick; don't need it yet*/
7401  int j=pos;
7402
7403#ifdef HAVE_RINGS
7404  assume (!rField_is_Ring(currRing));
7405#endif
7406  initenterpairsShift(h,k,ecart,0,strat, atR,uptodeg,lV);
7407  if ( (!strat->fromT)
7408  && ((strat->syzComp==0)
7409    ||(pGetComp(h)<=strat->syzComp)))
7410  {
7411    //Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
7412    unsigned long h_sev = pGetShortExpVector(h);
7413    loop
7414    {
7415      if (j > k) break;
7416      clearS(h,h_sev, &j,&k,strat);
7417      j++;
7418    }
7419    //Print("end clearS sl=%d\n",strat->sl);
7420  }
7421 // PrintS("end enterpairs\n");
7422}
7423#endif
7424
7425#ifdef HAVE_SHIFTBBA
7426/*3
7427*(s[0], s \dot h),...,(s[k],s \dot h) will be put to the pairset L
7428* also the pairs (h, s\dot s[0]), ..., (h, s\dot s[k]) enter L
7429* additionally we put the pairs (h, s \sdot h) for s>=1 to L
7430*/
7431void initenterpairsShift (poly h,int k,int ecart,int isFromQ, kStrategy strat, int atR, int uptodeg, int lV)
7432{
7433  /* h comes from strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
7434  //  atR = -1;
7435  if ((strat->syzComp==0)
7436  || (pGetComp(h)<=strat->syzComp))
7437  {
7438    int j;
7439    BOOLEAN new_pair=FALSE;
7440
7441    if (pGetComp(h)==0)
7442    {
7443      /* for Q!=NULL: build pairs (f,q),(f1,f2), but not (q1,q2)*/
7444      if ((isFromQ)&&(strat->fromQ!=NULL))
7445      {
7446        for (j=0; j<=k; j++)
7447        {
7448          if (!strat->fromQ[j])
7449          {
7450            new_pair=TRUE;
7451            enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR,uptodeg,lV);
7452            // other side pairs:
7453            enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
7454          //Print("j:%d, Ll:%d\n",j,strat->Ll);
7455          }
7456        }
7457      }
7458      else
7459      {
7460        new_pair=TRUE;
7461        for (j=0; j<=k; j++)
7462        {
7463          enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR,uptodeg,lV);
7464          // other side pairs
7465          enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
7466        }
7467        /* HERE we put (h, s*h) pairs */
7468       /* enterOnePairSelfShifts (poly qq, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int uptodeg, int lV); */
7469       enterOnePairSelfShifts (h, h, ecart, isFromQ, strat, atR, uptodeg, lV);
7470      }
7471    }
7472    else
7473    {
7474      for (j=0; j<=k; j++)
7475      {
7476        if ((pGetComp(h)==pGetComp(strat->S[j]))
7477        || (pGetComp(strat->S[j])==0))
7478        {
7479          new_pair=TRUE;
7480          enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR, uptodeg, lV);
7481          // other side pairs
7482          enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
7483        //Print("j:%d, Ll:%d\n",j,strat->Ll);
7484        }
7485      }
7486      /* HERE we put (h, s*h) pairs */
7487      enterOnePairSelfShifts (h, h, ecart, isFromQ, strat, atR, uptodeg, lV);
7488    }
7489
7490    if (new_pair)
7491    {
7492      strat->chainCrit(h,ecart,strat);
7493    }
7494
7495  }
7496}
7497#endif
7498
7499#ifdef HAVE_SHIFTBBA
7500/*2
7501* puts p to the set T, starting with the at position atT
7502* and inserts all admissible shifts of p
7503*/
7504void enterTShift(LObject p, kStrategy strat, int atT, int uptodeg, int lV)
7505{
7506  /* determine how many elements we have to insert */
7507  /* x(0)y(1)z(2) : lastVblock-1=2, to add until lastVblock=uptodeg-1 */
7508  /* hence, a total number of elt's to add is: */
7509  /*  int toInsert = 1 + (uptodeg-1) - (pLastVblock(p.p, lV) -1);  */
7510
7511  int toInsert =  itoInsert(p.p, uptodeg,  lV, strat->tailRing);
7512
7513#ifdef PDEBUG
7514  //  Print("enterTShift uses toInsert: %d", toInsert);  PrintLn();
7515#endif
7516  int i;
7517
7518  if (atT < 0)
7519    atT = strat->posInT(strat->T, strat->tl, p);
7520
7521  /* can call enterT in a sequence, e.g. */
7522
7523  /* shift0 = it's our model for further shifts */
7524  enterT(p,strat,atT);
7525  LObject qq;
7526  for (i=1; i<=toInsert; i++) // toIns - 1?
7527  {
7528    qq      = p; //qq.Copy();
7529    qq.p    = NULL;
7530    qq.max  = NULL;
7531    qq.t_p = p_LPshift(p_Copy(p.t_p,strat->tailRing), i, uptodeg, lV, strat->tailRing); // direct shift
7532    qq.GetP();
7533    // update q.sev
7534    qq.sev = pGetShortExpVector(qq.p);
7535    /* enter it into T, first el't is with the shift 0 */
7536    // compute the position for qq
7537    atT = strat->posInT(strat->T, strat->tl, qq);
7538    enterT(qq,strat,atT);
7539  }
7540/* Q: what to do with this one in the orig enterT ? */
7541/*  strat->R[strat->tl] = &(strat->T[atT]); */
7542/* Solution: it is done by enterT each time separately */
7543}
7544#endif
7545
7546#ifdef HAVE_SHIFTBBA
7547poly redtailBbaShift (LObject* L, int pos, kStrategy strat, BOOLEAN withT, BOOLEAN normalize)
7548{
7549  /* for the shift case need to run it with withT = TRUE */
7550  strat->redTailChange=FALSE;
7551  if (strat->noTailReduction) return L->GetLmCurrRing();
7552  poly h, p;
7553  p = h = L->GetLmTailRing();
7554  if ((h==NULL) || (pNext(h)==NULL))
7555    return L->GetLmCurrRing();
7556
7557  TObject* With;
7558  // placeholder in case strat->tl < 0
7559  TObject  With_s(strat->tailRing);
7560
7561  LObject Ln(pNext(h), strat->tailRing);
7562  Ln.pLength = L->GetpLength() - 1;
7563
7564  pNext(h) = NULL;
7565  if (L->p != NULL) pNext(L->p) = NULL;
7566  L->pLength = 1;
7567
7568  Ln.PrepareRed(strat->use_buckets);
7569
7570  while(!Ln.IsNull())
7571  {
7572    loop
7573    {
7574      Ln.SetShortExpVector();
7575      if (withT)
7576      {
7577        int j;
7578        j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln);
7579        if (j < 0) break;
7580        With = &(strat->T[j]);
7581      }
7582      else
7583      {
7584        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
7585        if (With == NULL) break;
7586      }
7587      if (normalize && (!TEST_OPT_INTSTRATEGY) && (!nIsOne(pGetCoeff(With->p))))
7588      {
7589        With->pNorm();
7590        //if (TEST_OPT_PROT) { PrintS("n"); mflush(); }
7591      }
7592      strat->redTailChange=TRUE;
7593      if (ksReducePolyTail(L, With, &Ln))
7594      {
7595        // reducing the tail would violate the exp bound
7596        //  set a flag and hope for a retry (in bba)
7597        strat->completeReduce_retry=TRUE;
7598        if ((Ln.p != NULL) && (Ln.t_p != NULL)) Ln.p=NULL;
7599        do
7600        {
7601          pNext(h) = Ln.LmExtractAndIter();
7602          pIter(h);
7603          L->pLength++;
7604        } while (!Ln.IsNull());
7605        goto all_done;
7606      }
7607      if (Ln.IsNull()) goto all_done;
7608      if (! withT) With_s.Init(currRing);
7609    }
7610    pNext(h) = Ln.LmExtractAndIter();
7611    pIter(h);
7612    L->pLength++;
7613  }
7614
7615  all_done:
7616  Ln.Delete();
7617  if (L->p != NULL) pNext(L->p) = pNext(p);
7618
7619  if (strat->redTailChange)
7620  {
7621    L->last = NULL;
7622    L->length = 0;
7623  }
7624  L->Normalize(); // HANNES: should have a test
7625  kTest_L(L);
7626  return L->GetLmCurrRing();
7627}
7628#endif
Note: See TracBrowser for help on using the repository browser.