source: git/kernel/kutil.cc @ 06662e

spielwiese
Last change on this file since 06662e was ce2454, checked in by Hans Schoenemann <hannes@…>, 14 years ago
pDeleteLm ->pLmDelete git-svn-id: file:///usr/local/Singular/svn/trunk@12892 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 191.8 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 "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 <mylimits.h>
24#include "options.h"
25#include "gring.h"
26#include "sca.h"
27#ifdef KDEBUG
28#undef KDEBUG
29#define KDEBUG 2
30#endif
31
32#ifdef HAVE_RINGS
33#include "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 "kutil.h"
47#include "kbuckets.h"
48#include "febase.h"
49#include "omalloc.h"
50#include "numbers.h"
51#include "polys.h"
52#include "ring.h"
53#include "ideals.h"
54#include "timer.h"
55//#include "cntrlc.h"
56#include "stairc.h"
57#include "kstd1.h"
58#include "pShallowCopyDelete.h"
59
60/* shiftgb stuff */
61#include "shiftgb.h"
62#include "prCopy.h"
63
64#ifdef HAVE_RATGRING
65#include "ratgring.h"
66#endif
67
68#ifdef KDEBUG
69#undef KDEBUG
70#define KDEBUG 2
71#endif
72
73
74#ifdef ENTER_USE_MYMEMMOVE
75inline void _my_memmove_d_gt_s(unsigned long* d, unsigned long* s, long l)
76{
77  register unsigned long* _dl = (unsigned long*) d;
78  register unsigned long* _sl = (unsigned long*) s;
79  register long _i = l - 1;
80
81  do
82  {
83    _dl[_i] = _sl[_i];
84    _i--;
85  }
86  while (_i >= 0);
87}
88
89inline void _my_memmove_d_lt_s(unsigned long* d, unsigned long* s, long l)
90{
91  register long _ll = l;
92  register unsigned long* _dl = (unsigned long*) d;
93  register unsigned long* _sl = (unsigned long*) s;
94  register long _i = 0;
95
96  do
97  {
98    _dl[_i] = _sl[_i];
99    _i++;
100  }
101  while (_i < _ll);
102}
103
104inline void _my_memmove(void* d, void* s, long l)
105{
106  unsigned long _d = (unsigned long) d;
107  unsigned long _s = (unsigned long) s;
108  unsigned long _l = ((l) + SIZEOF_LONG - 1) >> LOG_SIZEOF_LONG;
109
110  if (_d > _s) _my_memmove_d_gt_s(_d, _s, _l);
111  else _my_memmove_d_lt_s(_d, _s, _l);
112}
113
114#undef memmove
115#define memmove(d,s,l) _my_memmove(d, s, l)
116#endif
117
118static poly redMora (poly h,int maxIndex,kStrategy strat);
119static poly redBba (poly h,int maxIndex,kStrategy strat);
120
121#ifdef HAVE_RINGS
122#define pDivComp_EQUAL 2
123#define pDivComp_LESS 1
124#define pDivComp_GREATER -1
125#define pDivComp_INCOMP 0
126/* Checks the relation of LM(p) and LM(q)
127     LM(p) = LM(q) => return pDivComp_EQUAL
128     LM(p) | LM(q) => return pDivComp_LESS
129     LM(q) | LM(p) => return pDivComp_GREATER
130     else return pDivComp_INCOMP */
131static inline int pDivCompRing(poly p, poly q)
132{
133  if (pGetComp(p) == pGetComp(q))
134  {
135    BOOLEAN a=FALSE, b=FALSE;
136    int i;
137    unsigned long la, lb;
138    unsigned long divmask = currRing->divmask;
139    for (i=0; i<currRing->VarL_Size; i++)
140    {
141      la = p->exp[currRing->VarL_Offset[i]];
142      lb = q->exp[currRing->VarL_Offset[i]];
143      if (la != lb)
144      {
145        if (la < lb)
146        {
147          if (b) return pDivComp_INCOMP;
148          if (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask))
149            return pDivComp_INCOMP;
150          a = TRUE;
151        }
152        else
153        {
154          if (a) return pDivComp_INCOMP;
155          if (((la & divmask) ^ (lb & divmask)) != ((la - lb) & divmask))
156            return pDivComp_INCOMP;
157          b = TRUE;
158        }
159      }
160    }
161    if (a) return pDivComp_LESS;
162    if (b) return pDivComp_GREATER;
163    if (!a & !b) return pDivComp_EQUAL;
164  }
165  return 0;
166}
167#endif
168
169static inline int pDivComp(poly p, poly q)
170{
171  if (pGetComp(p) == pGetComp(q))
172  {
173#ifdef HAVE_RATGRING
174    if (rIsRatGRing(currRing))
175    {
176      if (_p_LmDivisibleByPart(p,currRing,
177                           q,currRing,
178                           currRing->real_var_start, currRing->real_var_end))
179        return 0;
180      return pLmCmp(q,p); // ONLY FOR GLOBAL ORDER!
181    }
182#endif
183    BOOLEAN a=FALSE, b=FALSE;
184    int i;
185    unsigned long la, lb;
186    unsigned long divmask = currRing->divmask;
187    for (i=0; i<currRing->VarL_Size; i++)
188    {
189      la = p->exp[currRing->VarL_Offset[i]];
190      lb = q->exp[currRing->VarL_Offset[i]];
191      if (la != lb)
192      {
193        if (la < lb)
194        {
195          if (b) return 0;
196          if (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask))
197            return 0;
198          a = TRUE;
199        }
200        else
201        {
202          if (a) return 0;
203          if (((la & divmask) ^ (lb & divmask)) != ((la - lb) & divmask))
204            return 0;
205          b = TRUE;
206        }
207      }
208    }
209    if (a) { /*assume(pLmCmp(q,p)==1);*/ return 1; }
210    if (b) { /*assume(pLmCmp(q,p)==-1);*/return -1; }
211    /*assume(pLmCmp(q,p)==0);*/
212  }
213  return 0;
214}
215
216
217int     HCord;
218int     Kstd1_deg;
219int     mu=32000;
220
221/*2
222*deletes higher monomial of p, re-compute ecart and length
223*works only for orderings with ecart =pFDeg(end)-pFDeg(start)
224*/
225void deleteHC(LObject *L, kStrategy strat, BOOLEAN fromNext)
226{
227  if (strat->kHEdgeFound)
228  {
229    kTest_L(L);
230    poly p1;
231    poly p = L->GetLmTailRing();
232    int l = 1;
233    kBucket_pt bucket = NULL;
234    if (L->bucket != NULL)
235    {
236      kBucketClear(L->bucket, &pNext(p), &L->pLength);
237      L->pLength++;
238      bucket = L->bucket;
239      L->bucket = NULL;
240      L->last = NULL;
241    }
242
243    if (!fromNext && p_Cmp(p,strat->kNoetherTail(), L->tailRing) == -1)
244    {
245      L->Delete();
246      L->Clear();
247      L->ecart = -1;
248      if (bucket != NULL) kBucketDestroy(&bucket);
249      return;
250    }
251    p1 = p;
252    while (pNext(p1)!=NULL)
253    {
254      if (p_LmCmp(pNext(p1), strat->kNoetherTail(), L->tailRing) == -1)
255      {
256        L->last = p1;
257        p_Delete(&pNext(p1), L->tailRing);
258        if (p1 == p)
259        {
260          if (L->t_p != NULL)
261          {
262            assume(L->p != NULL && p == L->t_p);
263            pNext(L->p) = NULL;
264          }
265          L->max  = NULL;
266        }
267        else if (fromNext)
268          L->max  = p_GetMaxExpP(pNext(L->p), L->tailRing ); // p1;
269        //if (L->pLength != 0)
270        L->pLength = l;
271        // Hmmm when called from updateT, then only
272        // reset ecart when cut
273        if (fromNext)
274          L->ecart = L->pLDeg() - L->GetpFDeg();
275        break;
276      }
277      l++;
278      pIter(p1);
279    }
280    if (! fromNext)
281    {
282      L->SetpFDeg();
283      L->ecart = L->pLDeg(strat->LDegLast) - L->GetpFDeg();
284    }
285    if (bucket != NULL)
286    {
287      if (L->pLength > 1)
288      {
289        kBucketInit(bucket, pNext(p), L->pLength - 1);
290        pNext(p) = NULL;
291        if (L->t_p != NULL) pNext(L->t_p) = NULL;
292        L->pLength = 0;
293        L->bucket = bucket;
294        L->last = NULL;
295      }
296      else
297        kBucketDestroy(&bucket);
298    }
299    kTest_L(L);
300  }
301}
302
303void deleteHC(poly* p, int* e, int* l,kStrategy strat)
304{
305  LObject L(*p, currRing, strat->tailRing);
306
307  deleteHC(&L, strat);
308  *p = L.p;
309  *e = L.ecart;
310  *l = L.length;
311  if (L.t_p != NULL) p_LmFree(L.t_p, strat->tailRing);
312}
313
314/*2
315*tests if p.p=monomial*unit and cancels the unit
316*/
317void cancelunit (LObject* L,BOOLEAN inNF)
318{
319  int  i;
320  poly h;
321
322  if(rHasGlobalOrdering_currRing()) return;
323  if(TEST_OPT_CANCELUNIT) return;
324
325  ring r = L->tailRing;
326  poly p = L->GetLmTailRing();
327
328#ifdef HAVE_RINGS_LOC
329  // Leading coef have to be a unit
330  if ( !(nIsUnit(p_GetCoeff(p, r))) ) return;
331#endif
332
333  if(p_GetComp(p, r) != 0 && !p_OneComp(p, r)) return;
334
335  if (L->ecart != 0)
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
360        if (L->t_p != NULL && pNext(L->t_p) != NULL)
361          pNext(L->t_p) = NULL;
362        if (L->p != NULL && pNext(L->p) != NULL)
363          pNext(L->p) = NULL;
364        return;
365      }
366      i = 0;
367      loop
368      {
369        i++;
370        if (p_GetExp(p,i,r) > p_GetExp(h,i,r)) return ; // does not divide
371        if (i == r->N) break; // does divide, try next monom
372      }
373      pIter(h);
374    }
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 == 0 || 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[k]) )
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=pWTotaldegree(p);
3240    int oo=pWTotaldegree(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 ((pWTotaldegree(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 ((pWTotaldegree(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 = 0;
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 (K_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              //pContent(strat->S[i]);
5404              strat->S[i]=p_Cleardenom(strat->S[i], currRing);// also does a pContent
5405            }
5406            else
5407            {
5408              pNorm(strat->S[i]);
5409            }
5410            strat->sevS[i] = pGetShortExpVector(strat->S[i]);
5411          }
5412        }
5413        i++;
5414      }
5415      if (any_change) reorderS(&suc,strat);
5416      else break;
5417    }
5418    if (toT)
5419    {
5420      for (i=0; i<=strat->sl; i++)
5421      {
5422        if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
5423        {
5424          h.p = redtailBba(strat->S[i],i-1,strat);
5425          if (TEST_OPT_INTSTRATEGY)
5426          {
5427            h.pCleardenom();// also does a pContent
5428          }
5429        }
5430        else
5431        {
5432          h.p = strat->S[i];
5433        }
5434        strat->initEcart(&h);
5435        if (strat->honey)
5436        {
5437          strat->ecartS[i] = h.ecart;
5438        }
5439        if (strat->sevS[i] == 0) {strat->sevS[i] = pGetShortExpVector(h.p);}
5440        else assume(strat->sevS[i] == pGetShortExpVector(h.p));
5441        h.sev = strat->sevS[i];
5442        /*puts the elements of S also to T*/
5443        enterT(h,strat);
5444        strat->S_2_R[i] = strat->tl;
5445      }
5446    }
5447  }
5448  else
5449  {
5450    while (suc != -1)
5451    {
5452      i=suc;
5453      while (i<=strat->sl)
5454      {
5455        change=FALSE;
5456        if (((strat->fromQ==NULL) || (strat->fromQ[i]==0)) && (i>0))
5457        {
5458          redSi=pHead((strat->S)[i]);
5459          (strat->S)[i] = redMora((strat->S)[i],i-1,strat);
5460          if ((strat->S)[i]==NULL)
5461          {
5462            deleteInS(i,strat);
5463            i--;
5464          }
5465          else if (pCmp((strat->S)[i],redSi)!=0)
5466          {
5467            any_change=TRUE;
5468            h.p = strat->S[i];
5469            strat->initEcart(&h);
5470            strat->ecartS[i] = h.ecart;
5471            if (TEST_OPT_INTSTRATEGY)
5472            {
5473              strat->S[i]=p_Cleardenom(strat->S[i], currRing);// also does a pContent
5474            }
5475            else
5476            {
5477              pNorm(strat->S[i]); // == h.p
5478            }
5479            h.sev =  pGetShortExpVector(h.p);
5480            strat->sevS[i] = h.sev;
5481          }
5482          pLmDelete(&redSi);
5483          kTest(strat);
5484        }
5485        i++;
5486      }
5487#ifdef KDEBUG
5488      kTest(strat);
5489#endif
5490      if (any_change) reorderS(&suc,strat);
5491      else { suc=-1; break; }
5492      if (h.p!=NULL)
5493      {
5494        if (!strat->kHEdgeFound)
5495        {
5496          /*strat->kHEdgeFound =*/ HEckeTest(h.p,strat);
5497        }
5498        if (strat->kHEdgeFound)
5499          newHEdge(strat->S,strat);
5500      }
5501    }
5502    for (i=0; i<=strat->sl; i++)
5503    {
5504      if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
5505      {
5506        strat->S[i] = h.p = redtail(strat->S[i],strat->sl,strat);
5507        strat->initEcart(&h);
5508        strat->ecartS[i] = h.ecart;
5509        h.sev = pGetShortExpVector(h.p);
5510        strat->sevS[i] = h.sev;
5511      }
5512      else
5513      {
5514        h.p = strat->S[i];
5515        h.ecart=strat->ecartS[i];
5516        h.sev = strat->sevS[i];
5517        h.length = h.pLength = pLength(h.p);
5518      }
5519      if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
5520        cancelunit1(&h,&suc,strat->sl,strat);
5521      h.SetpFDeg();
5522      /*puts the elements of S also to T*/
5523      enterT(h,strat);
5524      strat->S_2_R[i] = strat->tl;
5525    }
5526    if (suc!= -1) updateS(toT,strat);
5527  }
5528#ifdef KDEBUG
5529  kTest(strat);
5530#endif
5531}
5532
5533
5534/*2
5535* -puts p to the standardbasis s at position at
5536* -saves the result in S
5537*/
5538void enterSBba (LObject p,int atS,kStrategy strat, int atR)
5539{
5540  int i;
5541  strat->news = TRUE;
5542  /*- puts p to the standardbasis s at position at -*/
5543  if (strat->sl == IDELEMS(strat->Shdl)-1)
5544  {
5545    strat->sevS = (unsigned long*) omRealloc0Size(strat->sevS,
5546                                    IDELEMS(strat->Shdl)*sizeof(unsigned long),
5547                                    (IDELEMS(strat->Shdl)+setmaxTinc)
5548                                                  *sizeof(unsigned long));
5549    strat->ecartS = (intset)omReallocSize(strat->ecartS,
5550                                          IDELEMS(strat->Shdl)*sizeof(int),
5551                                          (IDELEMS(strat->Shdl)+setmaxTinc)
5552                                                  *sizeof(int));
5553    strat->S_2_R = (int*) omRealloc0Size(strat->S_2_R,
5554                                         IDELEMS(strat->Shdl)*sizeof(int),
5555                                         (IDELEMS(strat->Shdl)+setmaxTinc)
5556                                                  *sizeof(int));
5557    if (strat->lenS!=NULL)
5558      strat->lenS=(int*)omRealloc0Size(strat->lenS,
5559                                       IDELEMS(strat->Shdl)*sizeof(int),
5560                                       (IDELEMS(strat->Shdl)+setmaxTinc)
5561                                                 *sizeof(int));
5562    if (strat->lenSw!=NULL)
5563      strat->lenSw=(wlen_type*)omRealloc0Size(strat->lenSw,
5564                                       IDELEMS(strat->Shdl)*sizeof(wlen_type),
5565                                       (IDELEMS(strat->Shdl)+setmaxTinc)
5566                                                 *sizeof(wlen_type));
5567    if (strat->fromQ!=NULL)
5568    {
5569      strat->fromQ = (intset)omReallocSize(strat->fromQ,
5570                                    IDELEMS(strat->Shdl)*sizeof(int),
5571                                    (IDELEMS(strat->Shdl)+setmaxTinc)*sizeof(int));
5572    }
5573    pEnlargeSet(&strat->S,IDELEMS(strat->Shdl),setmaxTinc);
5574    IDELEMS(strat->Shdl)+=setmaxTinc;
5575    strat->Shdl->m=strat->S;
5576  }
5577  if (atS <= strat->sl)
5578  {
5579#ifdef ENTER_USE_MEMMOVE
5580// #if 0
5581    memmove(&(strat->S[atS+1]), &(strat->S[atS]),
5582            (strat->sl - atS + 1)*sizeof(poly));
5583    memmove(&(strat->ecartS[atS+1]), &(strat->ecartS[atS]),
5584            (strat->sl - atS + 1)*sizeof(int));
5585    memmove(&(strat->sevS[atS+1]), &(strat->sevS[atS]),
5586            (strat->sl - atS + 1)*sizeof(unsigned long));
5587    memmove(&(strat->S_2_R[atS+1]), &(strat->S_2_R[atS]),
5588            (strat->sl - atS + 1)*sizeof(int));
5589    if (strat->lenS!=NULL)
5590    memmove(&(strat->lenS[atS+1]), &(strat->lenS[atS]),
5591            (strat->sl - atS + 1)*sizeof(int));
5592    if (strat->lenSw!=NULL)
5593    memmove(&(strat->lenSw[atS+1]), &(strat->lenSw[atS]),
5594            (strat->sl - atS + 1)*sizeof(wlen_type));
5595#else
5596    for (i=strat->sl+1; i>=atS+1; i--)
5597    {
5598      strat->S[i] = strat->S[i-1];
5599      strat->ecartS[i] = strat->ecartS[i-1];
5600      strat->sevS[i] = strat->sevS[i-1];
5601      strat->S_2_R[i] = strat->S_2_R[i-1];
5602    }
5603    if (strat->lenS!=NULL)
5604    for (i=strat->sl+1; i>=atS+1; i--)
5605      strat->lenS[i] = strat->lenS[i-1];
5606    if (strat->lenSw!=NULL)
5607    for (i=strat->sl+1; i>=atS+1; i--)
5608      strat->lenSw[i] = strat->lenSw[i-1];
5609#endif
5610  }
5611  if (strat->fromQ!=NULL)
5612  {
5613#ifdef ENTER_USE_MEMMOVE
5614    memmove(&(strat->fromQ[atS+1]), &(strat->fromQ[atS]),
5615                  (strat->sl - atS + 1)*sizeof(int));
5616#else
5617    for (i=strat->sl+1; i>=atS+1; i--)
5618    {
5619      strat->fromQ[i] = strat->fromQ[i-1];
5620    }
5621#endif
5622    strat->fromQ[atS]=0;
5623  }
5624
5625  /*- save result -*/
5626  strat->S[atS] = p.p;
5627  if (strat->honey) strat->ecartS[atS] = p.ecart;
5628  if (p.sev == 0)
5629    p.sev = pGetShortExpVector(p.p);
5630  else
5631    assume(p.sev == pGetShortExpVector(p.p));
5632  strat->sevS[atS] = p.sev;
5633  strat->ecartS[atS] = p.ecart;
5634  strat->S_2_R[atS] = atR;
5635  strat->sl++;
5636}
5637
5638/*2
5639* puts p to the set T at position atT
5640*/
5641void enterT(LObject p, kStrategy strat, int atT)
5642{
5643  int i;
5644
5645  pp_Test(p.p, currRing, p.tailRing);
5646  assume(strat->tailRing == p.tailRing);
5647  // redMoraNF complains about this -- but, we don't really
5648  // neeed this so far
5649  assume(p.pLength == 0 || pLength(p.p) == p.pLength || rIsSyzIndexRing(currRing)); // modulo syzring
5650  assume(p.FDeg == p.pFDeg());
5651  assume(!p.is_normalized || nIsOne(pGetCoeff(p.p)));
5652
5653#ifdef KDEBUG
5654  // do not put an LObject twice into T:
5655  for(i=strat->tl;i>=0;i--)
5656  {
5657    if (p.p==strat->T[i].p)
5658    {
5659      printf("already in T at pos %d of %d, atT=%d\n",i,strat->tl,atT);
5660      return;
5661    }
5662  }
5663#endif
5664  strat->newt = TRUE;
5665  if (atT < 0)
5666    atT = strat->posInT(strat->T, strat->tl, p);
5667  if (strat->tl == strat->tmax-1)
5668    enlargeT(strat->T,strat->R,strat->sevT,strat->tmax,setmaxTinc);
5669  if (atT <= strat->tl)
5670  {
5671#ifdef ENTER_USE_MEMMOVE
5672    memmove(&(strat->T[atT+1]), &(strat->T[atT]),
5673            (strat->tl-atT+1)*sizeof(TObject));
5674    memmove(&(strat->sevT[atT+1]), &(strat->sevT[atT]),
5675            (strat->tl-atT+1)*sizeof(unsigned long));
5676#endif
5677    for (i=strat->tl+1; i>=atT+1; i--)
5678    {
5679#ifndef ENTER_USE_MEMMOVE
5680      strat->T[i] = strat->T[i-1];
5681      strat->sevT[i] = strat->sevT[i-1];
5682#endif
5683      strat->R[strat->T[i].i_r] = &(strat->T[i]);
5684    }
5685  }
5686
5687  if (strat->tailBin != NULL && (pNext(p.p) != NULL))
5688  {
5689    pNext(p.p)=p_ShallowCopyDelete(pNext(p.p),
5690                                   (strat->tailRing != NULL ?
5691                                    strat->tailRing : currRing),
5692                                   strat->tailBin);
5693    if (p.t_p != NULL) pNext(p.t_p) = pNext(p.p);
5694  }
5695  strat->T[atT] = (TObject) p;
5696
5697  if (strat->tailRing != currRing && pNext(p.p) != NULL)
5698    strat->T[atT].max = p_GetMaxExpP(pNext(p.p), strat->tailRing);
5699  else
5700    strat->T[atT].max = NULL;
5701
5702  strat->tl++;
5703  strat->R[strat->tl] = &(strat->T[atT]);
5704  strat->T[atT].i_r = strat->tl;
5705  assume(p.sev == 0 || pGetShortExpVector(p.p) == p.sev);
5706  strat->sevT[atT] = (p.sev == 0 ? pGetShortExpVector(p.p) : p.sev);
5707  kTest_T(&(strat->T[atT]));
5708}
5709
5710void initHilbCrit(ideal F, ideal Q, intvec **hilb,kStrategy strat)
5711{
5712  if (strat->homog!=isHomog)
5713  {
5714    *hilb=NULL;
5715  }
5716}
5717
5718void initBuchMoraCrit(kStrategy strat)
5719{
5720  strat->enterOnePair=enterOnePairNormal;
5721  strat->chainCrit=chainCritNormal;
5722#ifdef HAVE_RINGS
5723  if (rField_is_Ring(currRing))
5724  {
5725    strat->enterOnePair=enterOnePairRing;
5726    strat->chainCrit=chainCritRing;
5727  }
5728#endif
5729#ifdef HAVE_RATGRING
5730  if (rIsRatGRing(currRing))
5731  {
5732     strat->chainCrit=chainCritPart;
5733     /* enterOnePairNormal get rational part in it */
5734  }
5735#endif
5736
5737  strat->sugarCrit =        TEST_OPT_SUGARCRIT;
5738  strat->Gebauer =          strat->homog || strat->sugarCrit;
5739  strat->honey =            !strat->homog || strat->sugarCrit || TEST_OPT_WEIGHTM;
5740  if (TEST_OPT_NOT_SUGAR) strat->honey = FALSE;
5741  strat->pairtest = NULL;
5742  /* alway use tailreduction, except:
5743  * - in local rings, - in lex order case, -in ring over extensions */
5744  strat->noTailReduction = !TEST_OPT_REDTAIL;
5745
5746#ifdef HAVE_PLURAL
5747  // and r is plural_ring
5748  //  hence this holds for r a rational_plural_ring
5749  if( rIsPluralRing(currRing) || (rIsSCA(currRing) && !strat->z2homog) )
5750  {    //or it has non-quasi-comm type... later
5751    strat->sugarCrit = FALSE;
5752    strat->Gebauer = FALSE;
5753    strat->honey = FALSE;
5754  }
5755#endif
5756
5757#ifdef HAVE_RINGS
5758  // Coefficient ring?
5759  if (rField_is_Ring(currRing))
5760  {
5761    strat->sugarCrit = FALSE;
5762    strat->Gebauer = FALSE ;
5763    strat->honey = FALSE;
5764  }
5765#endif
5766  #ifdef KDEBUG
5767  if (TEST_OPT_DEBUG)
5768  {
5769    if (strat->homog) PrintS("ideal/module is homogeneous\n");
5770    else              PrintS("ideal/module is not homogeneous\n");
5771  }
5772  #endif
5773}
5774
5775BOOLEAN kPosInLDependsOnLength(int (*pos_in_l)
5776                               (const LSet set, const int length,
5777                                LObject* L,const kStrategy strat))
5778{
5779  if (pos_in_l == posInL110 ||
5780      pos_in_l == posInL10)
5781    return TRUE;
5782
5783  return FALSE;
5784}
5785
5786void initBuchMoraPos (kStrategy strat)
5787{
5788  if (pOrdSgn==1)
5789  {
5790    if (strat->honey)
5791    {
5792      strat->posInL = posInL15;
5793      // ok -- here is the deal: from my experiments for Singular-2-0
5794      // I conclude that that posInT_EcartpLength is the best of
5795      // posInT15, posInT_EcartFDegpLength, posInT_FDegLength, posInT_pLength
5796      // see the table at the end of this file
5797      if (K_TEST_OPT_OLDSTD)
5798        strat->posInT = posInT15;
5799      else
5800        strat->posInT = posInT_EcartpLength;
5801    }
5802    else if (pLexOrder && !TEST_OPT_INTSTRATEGY)
5803    {
5804      strat->posInL = posInL11;
5805      strat->posInT = posInT11;
5806    }
5807    else if (TEST_OPT_INTSTRATEGY)
5808    {
5809      strat->posInL = posInL11;
5810      strat->posInT = posInT11;
5811    }
5812    else
5813    {
5814      strat->posInL = posInL0;
5815      strat->posInT = posInT0;
5816    }
5817    //if (strat->minim>0) strat->posInL =posInLSpecial;
5818    if (strat->homog)
5819    {
5820       strat->posInL = posInL110;
5821       strat->posInT = posInT110;
5822    }
5823  }
5824  else
5825  {
5826    if (strat->homog)
5827    {
5828      strat->posInL = posInL11;
5829      strat->posInT = posInT11;
5830    }
5831    else
5832    {
5833      if ((currRing->order[0]==ringorder_c)
5834      ||(currRing->order[0]==ringorder_C))
5835      {
5836        strat->posInL = posInL17_c;
5837        strat->posInT = posInT17_c;
5838      }
5839      else
5840      {
5841        strat->posInL = posInL17;
5842        strat->posInT = posInT17;
5843      }
5844    }
5845  }
5846  if (strat->minim>0) strat->posInL =posInLSpecial;
5847  // for further tests only
5848  if ((BTEST1(11)) || (BTEST1(12)))
5849    strat->posInL = posInL11;
5850  else if ((BTEST1(13)) || (BTEST1(14)))
5851    strat->posInL = posInL13;
5852  else if ((BTEST1(15)) || (BTEST1(16)))
5853    strat->posInL = posInL15;
5854  else if ((BTEST1(17)) || (BTEST1(18)))
5855    strat->posInL = posInL17;
5856  if (BTEST1(11))
5857    strat->posInT = posInT11;
5858  else if (BTEST1(13))
5859    strat->posInT = posInT13;
5860  else if (BTEST1(15))
5861    strat->posInT = posInT15;
5862  else if ((BTEST1(17)))
5863    strat->posInT = posInT17;
5864  else if ((BTEST1(19)))
5865    strat->posInT = posInT19;
5866  else if (BTEST1(12) || BTEST1(14) || BTEST1(16) || BTEST1(18))
5867    strat->posInT = posInT1;
5868#ifdef HAVE_RINGS
5869  if (rField_is_Ring(currRing))
5870  {
5871    strat->posInL = posInL11;
5872    strat->posInT = posInT11;
5873  }
5874#endif
5875  strat->posInLDependsOnLength = kPosInLDependsOnLength(strat->posInL);
5876}
5877
5878void initBuchMora (ideal F,ideal Q,kStrategy strat)
5879{
5880  strat->interpt = BTEST1(OPT_INTERRUPT);
5881  strat->kHEdge=NULL;
5882  if (pOrdSgn==1) strat->kHEdgeFound=FALSE;
5883  /*- creating temp data structures------------------- -*/
5884  strat->cp = 0;
5885  strat->c3 = 0;
5886  strat->tail = pInit();
5887  /*- set s -*/
5888  strat->sl = -1;
5889  /*- set L -*/
5890  strat->Lmax = ((IDELEMS(F)+setmaxLinc-1)/setmaxLinc)*setmaxLinc;
5891  strat->Ll = -1;
5892  strat->L = initL(((IDELEMS(F)+setmaxLinc-1)/setmaxLinc)*setmaxLinc);
5893  /*- set B -*/
5894  strat->Bmax = setmaxL;
5895  strat->Bl = -1;
5896  strat->B = initL();
5897  /*- set T -*/
5898  strat->tl = -1;
5899  strat->tmax = setmaxT;
5900  strat->T = initT();
5901  strat->R = initR();
5902  strat->sevT = initsevT();
5903  /*- init local data struct.---------------------------------------- -*/
5904  strat->P.ecart=0;
5905  strat->P.length=0;
5906  if (pOrdSgn==-1)
5907  {
5908    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
5909    if (strat->kNoether!=NULL) pSetComp(strat->kNoetherTail(), strat->ak);
5910  }
5911  if(TEST_OPT_SB_1)
5912  {
5913    int i;
5914    ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
5915    for (i=strat->newIdeal;i<IDELEMS(F);i++)
5916    {
5917      P->m[i-strat->newIdeal] = F->m[i];
5918      F->m[i] = NULL;
5919    }
5920    initSSpecial(F,Q,P,strat);
5921    for (i=strat->newIdeal;i<IDELEMS(F);i++)
5922    {
5923      F->m[i] = P->m[i-strat->newIdeal];
5924      P->m[i-strat->newIdeal] = NULL;
5925    }
5926    idDelete(&P);
5927  }
5928  else
5929  {
5930    /*Shdl=*/initSL(F, Q,strat); /*sets also S, ecartS, fromQ */
5931    // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
5932  }
5933  strat->kIdeal = NULL;
5934  strat->fromT = FALSE;
5935  strat->noTailReduction = !TEST_OPT_REDTAIL;
5936  if (!TEST_OPT_SB_1)
5937  {
5938    updateS(TRUE,strat);
5939  }
5940  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
5941  strat->fromQ=NULL;
5942}
5943
5944void exitBuchMora (kStrategy strat)
5945{
5946  /*- release temp data -*/
5947  cleanT(strat);
5948  omFreeSize(strat->T,(strat->tmax)*sizeof(TObject));
5949  omFreeSize(strat->R,(strat->tmax)*sizeof(TObject*));
5950  omFreeSize(strat->sevT, (strat->tmax)*sizeof(unsigned long));
5951  omFreeSize(strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
5952  omFreeSize(strat->sevS,IDELEMS(strat->Shdl)*sizeof(int));
5953  omFreeSize(strat->S_2_R,IDELEMS(strat->Shdl)*sizeof(int));
5954  /*- set L: should be empty -*/
5955  omFreeSize(strat->L,(strat->Lmax)*sizeof(LObject));
5956  /*- set B: should be empty -*/
5957  omFreeSize(strat->B,(strat->Bmax)*sizeof(LObject));
5958  pLmDelete(&strat->tail);
5959  strat->syzComp=0;
5960  if (strat->kIdeal!=NULL)
5961  {
5962    omFreeBin(strat->kIdeal, sleftv_bin);
5963    strat->kIdeal=NULL;
5964  }
5965}
5966
5967/*2
5968* in the case of a standardbase of a module over a qring:
5969* replace polynomials in i by ak vectors,
5970* (the polynomial * unit vectors gen(1)..gen(ak)
5971* in every case (also for ideals:)
5972* deletes divisible vectors/polynomials
5973*/
5974void updateResult(ideal r,ideal Q, kStrategy strat)
5975{
5976  int l;
5977  if (strat->ak>0)
5978  {
5979    for (l=IDELEMS(r)-1;l>=0;l--)
5980    {
5981      if ((r->m[l]!=NULL) && (pGetComp(r->m[l])==0))
5982      {
5983        pDelete(&r->m[l]); // and set it to NULL
5984      }
5985    }
5986    int q;
5987    poly p;
5988    for (l=IDELEMS(r)-1;l>=0;l--)
5989    {
5990      if ((r->m[l]!=NULL)
5991      //&& (strat->syzComp>0)
5992      //&& (pGetComp(r->m[l])<=strat->syzComp)
5993      )
5994      {
5995        for(q=IDELEMS(Q)-1; q>=0;q--)
5996        {
5997          if ((Q->m[q]!=NULL)
5998          &&(pLmDivisibleBy(Q->m[q],r->m[l])))
5999          {
6000            if (TEST_OPT_REDSB)
6001            {
6002              p=r->m[l];
6003              r->m[l]=kNF(Q,NULL,p);
6004              pDelete(&p);
6005            }
6006            else
6007            {
6008              pDelete(&r->m[l]); // and set it to NULL
6009            }
6010            break;
6011          }
6012        }
6013      }
6014    }
6015  }
6016  else
6017  {
6018    int q;
6019    poly p;
6020    BOOLEAN reduction_found=FALSE;
6021    for (l=IDELEMS(r)-1;l>=0;l--)
6022    {
6023      if (r->m[l]!=NULL)
6024      {
6025        for(q=IDELEMS(Q)-1; q>=0;q--)
6026        {
6027          if ((Q->m[q]!=NULL)
6028          &&(pLmEqual(r->m[l],Q->m[q])))
6029          {
6030            if (TEST_OPT_REDSB)
6031            {
6032              p=r->m[l];
6033              r->m[l]=kNF(Q,NULL,p);
6034              pDelete(&p);
6035              reduction_found=TRUE;
6036            }
6037            else
6038            {
6039              pDelete(&r->m[l]); // and set it to NULL
6040            }
6041            break;
6042          }
6043        }
6044      }
6045    }
6046    if (/*TEST_OPT_REDSB &&*/ reduction_found)
6047    {
6048      for (l=IDELEMS(r)-1;l>=0;l--)
6049      {
6050        if (r->m[l]!=NULL)
6051        {
6052          for(q=IDELEMS(r)-1;q>=0;q--)
6053          {
6054            if ((l!=q)
6055            && (r->m[q]!=NULL)
6056            &&(pLmDivisibleBy(r->m[l],r->m[q])))
6057            {
6058              pDelete(&r->m[q]);
6059            }
6060          }
6061        }
6062      }
6063    }
6064  }
6065  idSkipZeroes(r);
6066}
6067
6068void completeReduce (kStrategy strat, BOOLEAN withT)
6069{
6070  int i;
6071  int low = (((pOrdSgn==1) && (strat->ak==0)) ? 1 : 0);
6072  LObject L;
6073
6074#ifdef KDEBUG
6075  // need to set this: during tailreductions of T[i], T[i].max is out of
6076  // sync
6077  sloppy_max = TRUE;
6078#endif
6079
6080  strat->noTailReduction = FALSE;
6081  if (TEST_OPT_PROT)
6082  {
6083    PrintLn();
6084    if (timerv) writeTime("standard base computed:");
6085  }
6086  if (TEST_OPT_PROT)
6087  {
6088    Print("(S:%d)",strat->sl);mflush();
6089  }
6090  for (i=strat->sl; i>=low; i--)
6091  {
6092    int end_pos=strat->sl;
6093    if ((strat->fromQ!=NULL) && (strat->fromQ[i])) continue; // do not reduce Q_i
6094    if (strat->ak==0) end_pos=i-1;
6095    TObject* T_j = strat->s_2_t(i);
6096    if (T_j != NULL)
6097    {
6098      L = *T_j;
6099      poly p;
6100      if (pOrdSgn == 1)
6101        strat->S[i] = redtailBba(&L, end_pos, strat, withT);
6102      else
6103        strat->S[i] = redtail(&L, strat->sl, strat);
6104
6105      if (strat->redTailChange && strat->tailRing != currRing)
6106      {
6107        if (T_j->max != NULL) p_LmFree(T_j->max, strat->tailRing);
6108        if (pNext(T_j->p) != NULL)
6109          T_j->max = p_GetMaxExpP(pNext(T_j->p), strat->tailRing);
6110        else
6111          T_j->max = NULL;
6112      }
6113      if (TEST_OPT_INTSTRATEGY)
6114        T_j->pCleardenom();
6115    }
6116    else
6117    {
6118      assume(currRing == strat->tailRing);
6119      if (pOrdSgn == 1)
6120        strat->S[i] = redtailBba(strat->S[i], end_pos, strat, withT);
6121      else
6122        strat->S[i] = redtail(strat->S[i], strat->sl, strat);
6123      if (TEST_OPT_INTSTRATEGY)
6124        strat->S[i]=p_Cleardenom(strat->S[i], currRing);
6125    }
6126    if (TEST_OPT_PROT)
6127      PrintS("-");
6128  }
6129  if (TEST_OPT_PROT) PrintLn();
6130#ifdef KDEBUG
6131  sloppy_max = FALSE;
6132#endif
6133}
6134
6135
6136/*2
6137* computes the new strat->kHEdge and the new pNoether,
6138* returns TRUE, if pNoether has changed
6139*/
6140BOOLEAN newHEdge(polyset S, kStrategy strat)
6141{
6142  int i,j;
6143  poly newNoether;
6144
6145#if 0
6146  if (currRing->weight_all_1)
6147    scComputeHC(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
6148  else
6149    scComputeHCw(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
6150#else
6151  scComputeHC(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
6152#endif
6153  if (strat->t_kHEdge != NULL) p_LmFree(strat->t_kHEdge, strat->tailRing);
6154  if (strat->tailRing != currRing)
6155    strat->t_kHEdge = k_LmInit_currRing_2_tailRing(strat->kHEdge, strat->tailRing);
6156  /* compare old and new noether*/
6157  newNoether = pLmInit(strat->kHEdge);
6158  j = pFDeg(newNoether,currRing);
6159  for (i=1; i<=pVariables; i++)
6160  {
6161    if (pGetExp(newNoether, i) > 0) pDecrExp(newNoether,i);
6162  }
6163  pSetm(newNoether);
6164  if (j < strat->HCord) /*- statistics -*/
6165  {
6166    if (TEST_OPT_PROT)
6167    {
6168      Print("H(%d)",j);
6169      mflush();
6170    }
6171    strat->HCord=j;
6172    #ifdef KDEBUG
6173    if (TEST_OPT_DEBUG)
6174    {
6175      Print("H(%d):",j);
6176      wrp(strat->kHEdge);
6177      PrintLn();
6178    }
6179    #endif
6180  }
6181  if (pCmp(strat->kNoether,newNoether)!=1)
6182  {
6183    pDelete(&strat->kNoether);
6184    strat->kNoether=newNoether;
6185    if (strat->t_kNoether != NULL) p_LmFree(strat->t_kNoether, strat->tailRing);
6186    if (strat->tailRing != currRing)
6187      strat->t_kNoether = k_LmInit_currRing_2_tailRing(strat->kNoether, strat->tailRing);
6188
6189    return TRUE;
6190  }
6191  pLmFree(newNoether);
6192  return FALSE;
6193}
6194
6195/***************************************************************
6196 *
6197 * Routines related for ring changes during std computations
6198 *
6199 ***************************************************************/
6200BOOLEAN kCheckSpolyCreation(LObject *L, kStrategy strat, poly &m1, poly &m2)
6201{
6202  if (strat->overflow) return FALSE;
6203  assume(L->p1 != NULL && L->p2 != NULL);
6204  // shift changes: from 0 to -1
6205  assume(L->i_r1 >= -1 && L->i_r1 <= strat->tl);
6206  assume(L->i_r2 >= -1 && L->i_r2 <= strat->tl);
6207  assume(strat->tailRing != currRing);
6208
6209  if (! k_GetLeadTerms(L->p1, L->p2, currRing, m1, m2, strat->tailRing))
6210    return FALSE;
6211  // shift changes: extra case inserted
6212  if ((L->i_r1 == -1) || (L->i_r2 == -1) )
6213  {
6214    return TRUE;
6215  }
6216  poly p1_max = (strat->R[L->i_r1])->max;
6217  poly p2_max = (strat->R[L->i_r2])->max;
6218
6219  if ((p1_max != NULL && !p_LmExpVectorAddIsOk(m1, p1_max, strat->tailRing)) ||
6220      (p2_max != NULL && !p_LmExpVectorAddIsOk(m2, p2_max, strat->tailRing)))
6221  {
6222    p_LmFree(m1, strat->tailRing);
6223    p_LmFree(m2, strat->tailRing);
6224    m1 = NULL;
6225    m2 = NULL;
6226    return FALSE;
6227  }
6228  return TRUE;
6229}
6230
6231#ifdef HAVE_RINGS
6232/***************************************************************
6233 *
6234 * Checks, if we can compute the gcd poly / strong pair
6235 * gcd-poly = m1 * R[atR] + m2 * S[atS]
6236 *
6237 ***************************************************************/
6238BOOLEAN kCheckStrongCreation(int atR, poly m1, int atS, poly m2, kStrategy strat)
6239{
6240  assume(strat->S_2_R[atS] >= -1 && strat->S_2_R[atS] <= strat->tl);
6241  //assume(strat->tailRing != currRing);
6242
6243  poly p1_max = (strat->R[atR])->max;
6244  poly p2_max = (strat->R[strat->S_2_R[atS]])->max;
6245
6246  if ((p1_max != NULL && !p_LmExpVectorAddIsOk(m1, p1_max, strat->tailRing)) ||
6247      (p2_max != NULL && !p_LmExpVectorAddIsOk(m2, p2_max, strat->tailRing)))
6248  {
6249    return FALSE;
6250  }
6251  return TRUE;
6252}
6253#endif
6254
6255BOOLEAN kStratChangeTailRing(kStrategy strat, LObject *L, TObject* T, unsigned long expbound)
6256{
6257  assume((strat->tailRing == currRing) || (strat->tailRing->bitmask < currRing->bitmask));
6258  /* initial setup or extending */
6259
6260  if (expbound == 0) expbound = strat->tailRing->bitmask << 1;
6261  if (expbound >= currRing->bitmask) return FALSE;
6262  strat->overflow=FALSE;
6263  ring new_tailRing = rModifyRing(currRing,
6264                                  // Hmmm .. the condition pFDeg == pDeg
6265                                  // might be too strong
6266#ifdef HAVE_RINGS
6267                                  (strat->homog && pFDeg == pDeg && !(rField_is_Ring(currRing))), // TODO Oliver
6268#else
6269                                  (strat->homog && pFDeg == pDeg), // omit_degree
6270#endif
6271                                  (strat->ak==0), // omit_comp if the input is an ideal
6272                                  expbound); // exp_limit
6273
6274  if (new_tailRing == currRing) return TRUE;
6275
6276  strat->pOrigFDeg_TailRing = new_tailRing->pFDeg;
6277  strat->pOrigLDeg_TailRing = new_tailRing->pLDeg;
6278
6279  if (currRing->pFDeg != currRing->pFDegOrig)
6280  {
6281    new_tailRing->pFDeg = currRing->pFDeg;
6282    new_tailRing->pLDeg = currRing->pLDeg;
6283  }
6284
6285  if (TEST_OPT_PROT)
6286    Print("[%lu:%d", (unsigned long) new_tailRing->bitmask, new_tailRing->ExpL_Size);
6287  kTest_TS(strat);
6288  assume(new_tailRing != strat->tailRing);
6289  pShallowCopyDeleteProc p_shallow_copy_delete
6290    = pGetShallowCopyDeleteProc(strat->tailRing, new_tailRing);
6291
6292  omBin new_tailBin = omGetStickyBinOfBin(new_tailRing->PolyBin);
6293
6294  int i;
6295  for (i=0; i<=strat->tl; i++)
6296  {
6297    strat->T[i].ShallowCopyDelete(new_tailRing, new_tailBin,
6298                                  p_shallow_copy_delete);
6299  }
6300  for (i=0; i<=strat->Ll; i++)
6301  {
6302    assume(strat->L[i].p != NULL);
6303    if (pNext(strat->L[i].p) != strat->tail)
6304      strat->L[i].ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
6305  }
6306  if (strat->P.t_p != NULL ||
6307      (strat->P.p != NULL && pNext(strat->P.p) != strat->tail))
6308    strat->P.ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
6309
6310  if (L != NULL && L->tailRing != new_tailRing)
6311  {
6312    if (L->i_r < 0)
6313      L->ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
6314    else
6315    {
6316      assume(L->i_r <= strat->tl);
6317      TObject* t_l = strat->R[L->i_r];
6318      assume(t_l != NULL);
6319      L->tailRing = new_tailRing;
6320      L->p = t_l->p;
6321      L->t_p = t_l->t_p;
6322      L->max = t_l->max;
6323    }
6324  }
6325
6326  if (T != NULL && T->tailRing != new_tailRing && T->i_r < 0)
6327    T->ShallowCopyDelete(new_tailRing, new_tailBin, p_shallow_copy_delete);
6328
6329  omMergeStickyBinIntoBin(strat->tailBin, strat->tailRing->PolyBin);
6330  if (strat->tailRing != currRing)
6331    rKillModifiedRing(strat->tailRing);
6332
6333  strat->tailRing = new_tailRing;
6334  strat->tailBin = new_tailBin;
6335  strat->p_shallow_copy_delete
6336    = pGetShallowCopyDeleteProc(currRing, new_tailRing);
6337
6338  if (strat->kHEdge != NULL)
6339  {
6340    if (strat->t_kHEdge != NULL)
6341      p_LmFree(strat->t_kHEdge, strat->tailRing);
6342    strat->t_kHEdge=k_LmInit_currRing_2_tailRing(strat->kHEdge, new_tailRing);
6343  }
6344
6345  if (strat->kNoether != NULL)
6346  {
6347    if (strat->t_kNoether != NULL)
6348      p_LmFree(strat->t_kNoether, strat->tailRing);
6349    strat->t_kNoether=k_LmInit_currRing_2_tailRing(strat->kNoether,
6350                                                   new_tailRing);
6351  }
6352  kTest_TS(strat);
6353  if (TEST_OPT_PROT)
6354    PrintS("]");
6355  return TRUE;
6356}
6357
6358void kStratInitChangeTailRing(kStrategy strat)
6359{
6360  unsigned long l = 0;
6361  int i;
6362  long e;
6363
6364  assume(strat->tailRing == currRing);
6365
6366  for (i=0; i<= strat->Ll; i++)
6367  {
6368    l = p_GetMaxExpL(strat->L[i].p, currRing, l);
6369  }
6370  for (i=0; i<=strat->tl; i++)
6371  {
6372    // Hmm ... this we could do in one Step
6373    l = p_GetMaxExpL(strat->T[i].p, currRing, l);
6374  }
6375  if (rField_is_Ring(currRing))
6376  {
6377    l *= 2;
6378  }
6379  e = p_GetMaxExp(l, currRing);
6380  if (e <= 1) e = 2;
6381
6382  kStratChangeTailRing(strat, NULL, NULL, e);
6383}
6384
6385skStrategy::skStrategy()
6386{
6387  memset(this, 0, sizeof(skStrategy));
6388#ifndef NDEBUG
6389  strat_nr++;
6390  nr=strat_nr;
6391  if (strat_fac_debug) Print("s(%d) created\n",nr);
6392#endif
6393  tailRing = currRing;
6394  P.tailRing = currRing;
6395  tl = -1;
6396  sl = -1;
6397#ifdef HAVE_LM_BIN
6398  lmBin = omGetStickyBinOfBin(currRing->PolyBin);
6399#endif
6400#ifdef HAVE_TAIL_BIN
6401  tailBin = omGetStickyBinOfBin(currRing->PolyBin);
6402#endif
6403  pOrigFDeg = pFDeg;
6404  pOrigLDeg = pLDeg;
6405}
6406
6407
6408skStrategy::~skStrategy()
6409{
6410  if (lmBin != NULL)
6411    omMergeStickyBinIntoBin(lmBin, currRing->PolyBin);
6412  if (tailBin != NULL)
6413    omMergeStickyBinIntoBin(tailBin,
6414                            (tailRing != NULL ? tailRing->PolyBin:
6415                             currRing->PolyBin));
6416  if (t_kHEdge != NULL)
6417    p_LmFree(t_kHEdge, tailRing);
6418  if (t_kNoether != NULL)
6419    p_LmFree(t_kNoether, tailRing);
6420
6421  if (currRing != tailRing)
6422    rKillModifiedRing(tailRing);
6423  pRestoreDegProcs(pOrigFDeg, pOrigLDeg);
6424}
6425
6426#if 0
6427Timings for the different possibilities of posInT:
6428            T15           EDL         DL          EL            L         1-2-3
6429Gonnet      43.26       42.30       38.34       41.98       38.40      100.04
6430Hairer_2_1   1.11        1.15        1.04        1.22        1.08        4.7
6431Twomat3      1.62        1.69        1.70        1.65        1.54       11.32
6432ahml         4.48        4.03        4.03        4.38        4.96       26.50
6433c7          15.02       13.98       15.16       13.24       17.31       47.89
6434c8         505.09      407.46      852.76      413.21      499.19        n/a
6435f855        12.65        9.27       14.97        8.78       14.23       33.12
6436gametwo6    11.47       11.35       14.57       11.20       12.02       35.07
6437gerhard_3    2.73        2.83        2.93        2.64        3.12        6.24
6438ilias13     22.89       22.46       24.62       20.60       23.34       53.86
6439noon8       40.68       37.02       37.99       36.82       35.59      877.16
6440rcyclic_19  48.22       42.29       43.99       45.35       51.51      204.29
6441rkat9       82.37       79.46       77.20       77.63       82.54      267.92
6442schwarz_11  16.46       16.81       16.76       16.81       16.72       35.56
6443test016     16.39       14.17       14.40       13.50       14.26       34.07
6444test017     34.70       36.01       33.16       35.48       32.75       71.45
6445test042     10.76       10.99       10.27       11.57       10.45       23.04
6446test058      6.78        6.75        6.51        6.95        6.22        9.47
6447test066     10.71       10.94       10.76       10.61       10.56       19.06
6448test073     10.75       11.11       10.17       10.79        8.63       58.10
6449test086     12.23       11.81       12.88       12.24       13.37       66.68
6450test103      5.05        4.80        5.47        4.64        4.89       11.90
6451test154     12.96       11.64       13.51       12.46       14.61       36.35
6452test162     65.27       64.01       67.35       59.79       67.54      196.46
6453test164      7.50        6.50        7.68        6.70        7.96       17.13
6454virasoro     3.39        3.50        3.35        3.47        3.70        7.66
6455#endif
6456
6457
6458//#ifdef HAVE_MORE_POS_IN_T
6459#if 1
6460// determines the position based on: 1.) Ecart 2.) FDeg 3.) pLength
6461int posInT_EcartFDegpLength(const TSet set,const int length,LObject &p)
6462{
6463
6464  if (length==-1) return 0;
6465
6466  int o = p.ecart;
6467  int op=p.GetpFDeg();
6468  int ol = p.GetpLength();
6469
6470  if (set[length].ecart < o)
6471    return length+1;
6472  if (set[length].ecart == o)
6473  {
6474     int oo=set[length].GetpFDeg();
6475     if ((oo < op) || ((oo==op) && (set[length].length < ol)))
6476       return length+1;
6477  }
6478
6479  int i;
6480  int an = 0;
6481  int en= length;
6482  loop
6483  {
6484    if (an >= en-1)
6485    {
6486      if (set[an].ecart > o)
6487        return an;
6488      if (set[an].ecart == o)
6489      {
6490         int oo=set[an].GetpFDeg();
6491         if((oo > op)
6492         || ((oo==op) && (set[an].pLength > ol)))
6493           return an;
6494      }
6495      return en;
6496    }
6497    i=(an+en) / 2;
6498    if (set[i].ecart > o)
6499      en=i;
6500    else if (set[i].ecart == o)
6501    {
6502       int oo=set[i].GetpFDeg();
6503       if ((oo > op)
6504       || ((oo == op) && (set[i].pLength > ol)))
6505         en=i;
6506       else
6507        an=i;
6508    }
6509    else
6510      an=i;
6511  }
6512}
6513
6514// determines the position based on: 1.) FDeg 2.) pLength
6515int posInT_FDegpLength(const TSet set,const int length,LObject &p)
6516{
6517
6518  if (length==-1) return 0;
6519
6520  int op=p.GetpFDeg();
6521  int ol = p.GetpLength();
6522
6523  int oo=set[length].GetpFDeg();
6524  if ((oo < op) || ((oo==op) && (set[length].length < ol)))
6525    return length+1;
6526
6527  int i;
6528  int an = 0;
6529  int en= length;
6530  loop
6531    {
6532      if (an >= en-1)
6533      {
6534        int oo=set[an].GetpFDeg();
6535        if((oo > op)
6536           || ((oo==op) && (set[an].pLength > ol)))
6537          return an;
6538        return en;
6539      }
6540      i=(an+en) / 2;
6541      int oo=set[i].GetpFDeg();
6542      if ((oo > op)
6543          || ((oo == op) && (set[i].pLength > ol)))
6544        en=i;
6545      else
6546        an=i;
6547    }
6548}
6549
6550
6551// determines the position based on: 1.) pLength
6552int posInT_pLength(const TSet set,const int length,LObject &p)
6553{
6554  int ol = p.GetpLength();
6555  if (length==-1)
6556    return 0;
6557  if (set[length].length<p.length)
6558    return length+1;
6559
6560  int i;
6561  int an = 0;
6562  int en= length;
6563
6564  loop
6565  {
6566    if (an >= en-1)
6567    {
6568      if (set[an].pLength>ol) return an;
6569      return en;
6570    }
6571    i=(an+en) / 2;
6572    if (set[i].pLength>ol) en=i;
6573    else                        an=i;
6574  }
6575}
6576#endif
6577
6578// kstd1.cc:
6579int redFirst (LObject* h,kStrategy strat);
6580int redEcart (LObject* h,kStrategy strat);
6581void enterSMora (LObject p,int atS,kStrategy strat, int atR=-1);
6582void enterSMoraNF (LObject p,int atS,kStrategy strat, int atR=-1);
6583// ../Singular/misc.cc:
6584char *  showOption();
6585
6586void kDebugPrint(kStrategy strat)
6587{
6588  PrintS("red: ");
6589    if (strat->red==redFirst) PrintS("redFirst\n");
6590    else if (strat->red==redHoney) PrintS("redHoney\n");
6591    else if (strat->red==redEcart) PrintS("redEcart\n");
6592    else if (strat->red==redHomog) PrintS("redHomog\n");
6593    else  Print("%p\n",(void*)strat->red);
6594  PrintS("posInT: ");
6595    if (strat->posInT==posInT0) PrintS("posInT0\n");
6596    else if (strat->posInT==posInT0) PrintS("posInT0\n");
6597    else if (strat->posInT==posInT1) PrintS("posInT1\n");
6598    else if (strat->posInT==posInT11) PrintS("posInT11\n");
6599    else if (strat->posInT==posInT110) PrintS("posInT110\n");
6600    else if (strat->posInT==posInT13) PrintS("posInT13\n");
6601    else if (strat->posInT==posInT15) PrintS("posInT15\n");
6602    else if (strat->posInT==posInT17) PrintS("posInT17\n");
6603    else if (strat->posInT==posInT17_c) PrintS("posInT17_c\n");
6604    else if (strat->posInT==posInT19) PrintS("posInT19\n");
6605    else if (strat->posInT==posInT2) PrintS("posInT2\n");
6606#ifdef HAVE_MORE_POS_IN_T
6607    else if (strat->posInT==posInT_EcartFDegpLength) PrintS("posInT_EcartFDegpLength\n");
6608    else if (strat->posInT==posInT_FDegpLength) PrintS("posInT_FDegpLength\n");
6609    else if (strat->posInT==posInT_pLength) PrintS("posInT_pLength\n");
6610#endif
6611    else if (strat->posInT==posInT_EcartpLength) PrintS("posInT_EcartpLength\n");
6612    else if (strat->posInT==posInTrg0) PrintS("posInTrg0\n");
6613    else  Print("%p\n",(void*)strat->posInT);
6614  PrintS("posInL: ");
6615    if (strat->posInL==posInL0) PrintS("posInL0\n");
6616    else if (strat->posInL==posInL10) PrintS("posInL10\n");
6617    else if (strat->posInL==posInL11) PrintS("posInL11\n");
6618    else if (strat->posInL==posInL110) PrintS("posInL110\n");
6619    else if (strat->posInL==posInL13) PrintS("posInL13\n");
6620    else if (strat->posInL==posInL15) PrintS("posInL15\n");
6621    else if (strat->posInL==posInL17) PrintS("posInL17\n");
6622    else if (strat->posInL==posInL17_c) PrintS("posInL17_c\n");
6623    else if (strat->posInL==posInLSpecial) PrintS("posInLSpecial\n");
6624    else if (strat->posInL==posInLrg0) PrintS("posInLrg0\n");
6625    else  Print("%p\n",(void*)strat->posInL);
6626  PrintS("enterS: ");
6627    if (strat->enterS==enterSBba) PrintS("enterSBba\n");
6628    else if (strat->enterS==enterSMora) PrintS("enterSMora\n");
6629    else if (strat->enterS==enterSMoraNF) PrintS("enterSMoraNF\n");
6630    else  Print("%p\n",(void*)strat->enterS);
6631  PrintS("initEcart: ");
6632    if (strat->initEcart==initEcartBBA) PrintS("initEcartBBA\n");
6633    else if (strat->initEcart==initEcartNormal) PrintS("initEcartNormal\n");
6634    else  Print("%p\n",(void*)strat->initEcart);
6635  PrintS("initEcartPair: ");
6636    if (strat->initEcartPair==initEcartPairBba) PrintS("initEcartPairBba\n");
6637    else if (strat->initEcartPair==initEcartPairMora) PrintS("initEcartPairMora\n");
6638    else  Print("%p\n",(void*)strat->initEcartPair);
6639  Print("homog=%d, LazyDegree=%d, LazyPass=%d, ak=%d,\n",
6640         strat->homog, strat->LazyDegree,strat->LazyPass, strat->ak);
6641  Print("honey=%d, sugarCrit=%d, Gebauer=%d, noTailReduction=%d\n",
6642         strat->honey,strat->sugarCrit,strat->Gebauer,strat->noTailReduction,strat->use_buckets);
6643  Print("posInLDependsOnLength=%d, use_buckets=%d\n",
6644         strat->posInLDependsOnLength,strat->use_buckets);
6645  PrintS(showOption());PrintLn();
6646  PrintS("LDeg: ");
6647    if (currRing->pLDeg==pLDeg0) PrintS("pLDeg0");
6648    else if (currRing->pLDeg==pLDeg0c) PrintS("pLDeg0c");
6649    else if (currRing->pLDeg==pLDegb) PrintS("pLDegb");
6650    else if (currRing->pLDeg==pLDeg1) PrintS("pLDeg1");
6651    else if (currRing->pLDeg==pLDeg1c) PrintS("pLDeg1c");
6652    else if (currRing->pLDeg==pLDeg1_Deg) PrintS("pLDeg1_Deg");
6653    else if (currRing->pLDeg==pLDeg1c_Deg) PrintS("pLDeg1c_Deg");
6654    else if (currRing->pLDeg==pLDeg1_Totaldegree) PrintS("pLDeg1_Totaldegree");
6655    else if (currRing->pLDeg==pLDeg1c_Totaldegree) PrintS("pLDeg1c_Totaldegree");
6656    else if (currRing->pLDeg==pLDeg1_WFirstTotalDegree) PrintS("pLDeg1_WFirstTotalDegree");
6657    else if (currRing->pLDeg==pLDeg1c_WFirstTotalDegree) PrintS("pLDeg1c_WFirstTotalDegree");
6658    else Print("? (%lx)", (long)currRing->pLDeg);
6659    PrintS(" / ");
6660    if (strat->tailRing->pLDeg==pLDeg0) PrintS("pLDeg0");
6661    else if (strat->tailRing->pLDeg==pLDeg0c) PrintS("pLDeg0c");
6662    else if (strat->tailRing->pLDeg==pLDegb) PrintS("pLDegb");
6663    else if (strat->tailRing->pLDeg==pLDeg1) PrintS("pLDeg1");
6664    else if (strat->tailRing->pLDeg==pLDeg1c) PrintS("pLDeg1c");
6665    else if (strat->tailRing->pLDeg==pLDeg1_Deg) PrintS("pLDeg1_Deg");
6666    else if (strat->tailRing->pLDeg==pLDeg1c_Deg) PrintS("pLDeg1c_Deg");
6667    else if (strat->tailRing->pLDeg==pLDeg1_Totaldegree) PrintS("pLDeg1_Totaldegree");
6668    else if (strat->tailRing->pLDeg==pLDeg1c_Totaldegree) PrintS("pLDeg1c_Totaldegree");
6669    else if (strat->tailRing->pLDeg==pLDeg1_WFirstTotalDegree) PrintS("pLDeg1_WFirstTotalDegree");
6670    else if (strat->tailRing->pLDeg==pLDeg1c_WFirstTotalDegree) PrintS("pLDeg1c_WFirstTotalDegree");
6671    else Print("? (%lx)", (long)strat->tailRing->pLDeg);
6672    Print(" syzring:%d, syzComp(strat):%d syzComb(ring)\n",rIsSyzIndexRing(currRing),strat->syzComp,rGetCurrSyzLimit());
6673
6674}
6675
6676
6677#ifdef HAVE_SHIFTBBA
6678poly pMove2CurrTail(poly p, kStrategy strat)
6679{
6680  /* assume: p is completely in currRing */
6681  /* produces an object with LM in curring
6682     and TAIL in tailring */
6683  if (pNext(p)!=NULL)
6684  {
6685    pNext(p) = prMoveR(pNext(p), /* src */ currRing, /* dest */ strat->tailRing);
6686  }
6687  return(p);
6688}
6689#endif
6690
6691#ifdef HAVE_SHIFTBBA
6692poly pMoveCurrTail2poly(poly p, kStrategy strat)
6693{
6694  /* assume: p has  LM in curring and TAIL in tailring */
6695  /* convert it to complete currRing */
6696
6697  /* check that LM is in currRing */
6698  assume(p_LmCheckIsFromRing(p, currRing));
6699
6700  if (pNext(p)!=NULL)
6701  {
6702    pNext(p) = prMoveR(pNext(p), /* src */ strat->tailRing, /* dest */currRing);
6703  }
6704  return(p);
6705}
6706#endif
6707
6708#ifdef HAVE_SHIFTBBA
6709poly pCopyL2p(LObject H, kStrategy strat)
6710{
6711    /* restores a poly in currRing from LObject */
6712    LObject h = H;
6713    h.Copy();
6714    poly p;
6715    if (h.p == NULL)
6716    {
6717      if (h.t_p != NULL)
6718      {
6719         p = prMoveR(h.t_p, /* source ring: */ strat->tailRing, /* dest. ring: */ currRing);
6720        return(p);
6721      }
6722      else
6723      {
6724        /* h.tp == NULL -> the object is NULL */
6725        return(NULL);
6726      }
6727    }
6728    /* we're here if h.p != NULL */
6729    if (h.t_p == NULL)
6730    {
6731       /* then h.p is the whole poly in currRing */
6732       p = h.p;
6733      return(p);
6734    }
6735    /* we're here if h.p != NULL and h.t_p != NULL */
6736    // clean h.p, get poly from t_p
6737     pNext(h.p)=NULL;
6738     pDelete(&h.p);
6739     p = prMoveR(h.t_p, /* source ring: */ strat->tailRing,
6740                         /* dest. ring: */ currRing);
6741     // no need to clean h: we re-used the polys
6742    return(p);
6743}
6744#endif
6745
6746//LObject pCopyp2L(poly p, kStrategy strat)
6747//{
6748    /* creates LObject from the poly in currRing */
6749  /* actually put p into L.p and make L.t_p=NULL : does not work */
6750
6751//}
6752
6753// poly pCopyL2p(LObject H, kStrategy strat)
6754// {
6755//   /* restores a poly in currRing from LObject */
6756//   LObject h = H;
6757//   h.Copy();
6758//   poly p;
6759//   if (h.p == NULL)
6760//   {
6761//     if (h.t_p != NULL)
6762//     {
6763//       p = p_ShallowCopyDelete(h.t_p, (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
6764//       return(p);
6765//     }
6766//     else
6767//     {
6768//       /* h.tp == NULL -> the object is NULL */
6769//       return(NULL);
6770//     }
6771//   }
6772//   /* we're here if h.p != NULL */
6773
6774//   if (h.t_p == NULL)
6775//   {
6776//     /* then h.p is the whole poly in tailRing */
6777//     if (strat->tailBin != NULL && (pNext(h.p) != NULL))
6778//     {
6779//       p = p_ShallowCopyDelete(h.p, (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
6780//     }
6781//     return(p);
6782//   }
6783//   /* we're here if h.p != NULL and h.t_p != NULL */
6784//   p = pCopy(pHead(h.p)); // in currRing
6785//   if (strat->tailBin != NULL && (pNext(h.p) != NULL))
6786//   {
6787//     //    pNext(p) = p_ShallowCopyDelete(pNext(h.t_p), (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
6788//     poly pp = p_Copy(pNext(h.p), strat->tailRing);
6789//     //    poly p3 = p_Copy(pNext(h.p), currRing); // error
6790//       // p_ShallowCopyDelete(pNext(h.p), currRing, strat->tailBin); // the same as pp
6791//     poly p5 = p_ShallowCopyDelete(pNext(h.p), strat->tailRing, strat->tailBin);
6792//     pNext(p) = p_ShallowCopyDelete(h.t_p, strat->tailRing, strat->tailBin);
6793//     poly p4 = p_Copy(h.t_p, strat->tailRing);
6794//     //    if (p.t_p != NULL) pNext(p.t_p) = pNext(p.p);
6795//   }
6796//   //  pTest(p);
6797//   return(p);
6798// }
6799
6800#ifdef HAVE_SHIFTBBA
6801/* including the self pairs */
6802void updateSShift(kStrategy strat,int uptodeg,int lV)
6803{
6804  /* to use after updateS(toT=FALSE,strat) */
6805  /* fills T with shifted elt's of S */
6806  int i;
6807  LObject h;
6808  int atT = -1; // or figure out smth better
6809  strat->tl = -1; // init
6810  for (i=0; i<=strat->sl; i++)
6811  {
6812    memset(&h,0,sizeof(h));
6813    h.p =  strat->S[i]; // lm in currRing, tail in TR
6814    strat->initEcart(&h);
6815    h.sev = strat->sevS[i];
6816    h.t_p = NULL;
6817    h.GetTP(); // creates correct t_p
6818    /*puts the elements of S with their shifts to T*/
6819    //    int atT, int uptodeg, int lV)
6820    strat->S_2_R[i] = strat->tl + 1; // the el't with shift 0 will be inserted first
6821    // need a small check for above; we insert >=1 elements
6822    // insert this check into kTest_TS ?
6823    enterTShift(h,strat,atT,uptodeg,lV);
6824  }
6825  /* what about setting strat->tl? */
6826}
6827#endif
6828
6829#ifdef HAVE_SHIFTBBA
6830void initBuchMoraShift (ideal F,ideal Q,kStrategy strat)
6831{
6832  strat->interpt = BTEST1(OPT_INTERRUPT);
6833  strat->kHEdge=NULL;
6834  if (pOrdSgn==1) strat->kHEdgeFound=FALSE;
6835  /*- creating temp data structures------------------- -*/
6836  strat->cp = 0;
6837  strat->c3 = 0;
6838  strat->cv = 0;
6839  strat->tail = pInit();
6840  /*- set s -*/
6841  strat->sl = -1;
6842  /*- set L -*/
6843  strat->Lmax = setmaxL;
6844  strat->Ll = -1;
6845  strat->L = initL();
6846  /*- set B -*/
6847  strat->Bmax = setmaxL;
6848  strat->Bl = -1;
6849  strat->B = initL();
6850  /*- set T -*/
6851  strat->tl = -1;
6852  strat->tmax = setmaxT;
6853  strat->T = initT();
6854  strat->R = initR();
6855  strat->sevT = initsevT();
6856  /*- init local data struct.---------------------------------------- -*/
6857  strat->P.ecart=0;
6858  strat->P.length=0;
6859  if (pOrdSgn==-1)
6860  {
6861    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
6862    if (strat->kNoether!=NULL) pSetComp(strat->kNoetherTail(), strat->ak);
6863  }
6864  if(TEST_OPT_SB_1)
6865  {
6866    int i;
6867    ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
6868    for (i=strat->newIdeal;i<IDELEMS(F);i++)
6869    {
6870      P->m[i-strat->newIdeal] = F->m[i];
6871      F->m[i] = NULL;
6872    }
6873    initSSpecial(F,Q,P,strat);
6874    for (i=strat->newIdeal;i<IDELEMS(F);i++)
6875    {
6876      F->m[i] = P->m[i-strat->newIdeal];
6877      P->m[i-strat->newIdeal] = NULL;
6878    }
6879    idDelete(&P);
6880  }
6881  else
6882  {
6883    /*Shdl=*/initSL(F, Q,strat); /*sets also S, ecartS, fromQ */
6884    // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
6885  }
6886  strat->kIdeal = NULL;
6887  strat->fromT = FALSE;
6888  strat->noTailReduction = !TEST_OPT_REDTAIL;
6889  if (!TEST_OPT_SB_1)
6890  {
6891    /* the only change: we do not fill the set T*/
6892    updateS(FALSE,strat);
6893  }
6894  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
6895  strat->fromQ=NULL;
6896  /* more changes: fill the set T with all the shifts of elts of S*/
6897  /* is done by other procedure */
6898}
6899#endif
6900
6901#ifdef HAVE_SHIFTBBA
6902/*1
6903* put the pairs (sh \dot s[i],p)  into the set B, ecart=ecart(p)
6904*/
6905void enterOnePairManyShifts (int i, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int uptodeg, int lV)
6906{
6907  /* p comes from strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
6908
6909  assume(p_LmCheckIsFromRing(p,currRing));
6910  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
6911
6912  /* cycles through all shifts of s[i] until uptodeg - lastVblock(s[i]) */
6913  /* that is create the pairs (f, s \dot g)  */
6914
6915  poly qq = strat->S[i]; //  lm in currRing, tail in tailRing
6916
6917  //  poly q = pCopy(pHead(strat->S[i])); // lm in currRing
6918  //  pNext(q) = prCopyR(pNext(strat->S[i]),strat->tailRing,currRing); // zero shift
6919
6920 /* determine how many elements we have to insert for a given s[i] */
6921  /* x(0)y(1)z(2) : lastVblock-1=2, to add until lastVblock=uptodeg-1 */
6922  /* hence, a total number of elt's to add is: */
6923  /*  int toInsert = 1 + (uptodeg-1) - (pLastVblock(p.p, lV) -1);  */
6924  int toInsert =  itoInsert(qq, uptodeg,  lV, strat->tailRing);
6925
6926#ifdef KDEBUG
6927    if (TEST_OPT_DEBUG)
6928    {
6929      //      Print("entered ManyShifts: with toInsert=%d",toInsert); PrintLn();
6930    }
6931#endif
6932
6933  assume(i<=strat->sl); // from OnePair
6934  if (strat->interred_flag) return; // ?
6935
6936  /* these vars hold for all shifts of s[i] */
6937  int ecartq = 0; //Hans says it's ok; we're in the homog case, no ecart
6938
6939  int qfromQ;
6940  if (strat->fromQ != NULL)
6941  {
6942    qfromQ = strat->fromQ[i];
6943  }
6944  else
6945  {
6946    qfromQ = -1;
6947  }
6948
6949  int j;
6950
6951  poly q, s;
6952
6953  // for the 0th shift: insert the orig. pair
6954  enterOnePairShift(qq, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, j, i, uptodeg, lV);
6955
6956  for (j=1; j<= toInsert; j++)
6957  {
6958    //    q = pLPshift(strat->S[i],j,uptodeg,lV);
6959    q = p_LPshiftT(qq, j, uptodeg, lV, strat, currRing);
6960    //    q = p_mLPshift(qq,j,uptodeg,lV,currRing); // lm in currRing, shift this monomial
6961    //    s = p_LPshift(pNext(qq), j, uptodeg, lV, strat->tailRing); // from tailRing
6962    //    pNext(q) = s; // in tailRing
6963    /* here we need to call enterOnePair with two polys ... */
6964
6965#ifdef KDEBUG
6966    if (TEST_OPT_DEBUG)
6967    {
6968      //      PrintS("ManyShifts: calling enterOnePairShift(q,p)");      PrintLn();
6969    }
6970#endif
6971    enterOnePairShift(q, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, j, i, uptodeg, lV);
6972  }
6973}
6974#endif
6975
6976#ifdef HAVE_SHIFTBBA
6977/*1
6978* put the pairs (sh \dot qq,p)  into the set B, ecart=ecart(p)
6979* despite the name, not only self shifts
6980*/
6981void enterOnePairSelfShifts (poly qq, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int uptodeg, int lV)
6982{
6983
6984  /* format: p,qq are in LObject form: lm in CR, tail in TR */
6985  /* for true self pairs qq ==p  */
6986  /* we test both qq and p */
6987  assume(p_LmCheckIsFromRing(qq,currRing));
6988  assume(p_CheckIsFromRing(pNext(qq),strat->tailRing));
6989  assume(p_LmCheckIsFromRing(p,currRing));
6990  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
6991
6992  /* since this proc is applied twice for (h, s*g) and (g,s*h), init j with 1 only */
6993
6994  //  int j = 0;
6995  int j = 1;
6996
6997  /* for such self pairs start with 1, not with 0 */
6998  if (qq == p) j=1;
6999
7000  /* should cycle through all shifts of q until uptodeg - lastVblock(q) */
7001  /* that is create the pairs (f, s \dot g)  */
7002
7003  int toInsert =  itoInsert(qq, uptodeg,  lV, strat->tailRing);
7004
7005#ifdef KDEBUG
7006    if (TEST_OPT_DEBUG)
7007    {
7008      //      Print("entered SelfShifts: with toInsert=%d",toInsert); PrintLn();
7009    }
7010#endif
7011
7012  poly q, s;
7013
7014  if (strat->interred_flag) return; // ?
7015
7016  /* these vars hold for all shifts of s[i] */
7017  int ecartq = 0; //Hans says it's ok; we're in the homog case, no ecart
7018  int qfromQ = 0; // strat->fromQ[i];
7019
7020  for (; j<= toInsert; j++)
7021  {
7022    //    q = pLPshift(strat->S[i],j,uptodeg,lV);
7023    /* we increase shifts by one; must delete q there*/
7024    //    q = qq; q = pMoveCurrTail2poly(q,strat);
7025    //    q = pLPshift(q,j,uptodeg,lV); //,currRing);
7026    q = p_LPshiftT(qq, j, uptodeg, lV, strat, currRing);
7027    //    q = p_mLPshift(qq,j,uptodeg,lV,currRing); // lm in currRing, shift this monomial
7028    //    s = p_LPshift(pNext(qq), j, uptodeg, lV, strat->tailRing); // from tailRing
7029    //    pNext(q) = s; // in tailRing
7030    /* here we need to call enterOnePair with two polys ... */
7031#ifdef KDEBUG
7032    if (TEST_OPT_DEBUG)
7033    {
7034      //      PrintS("SelfShifts: calling enterOnePairShift(q,p)");      PrintLn();
7035    }
7036#endif
7037    enterOnePairShift(q, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, j, -1, uptodeg, lV);
7038  }
7039}
7040#endif
7041
7042#ifdef HAVE_SHIFTBBA
7043/*2
7044* put the pair (q,p)  into the set B, ecart=ecart(p), q is the shift of some s[i]
7045*/
7046void 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)
7047{
7048
7049  /* Format: q and p are like strat->P.p, so lm in CR, tail in TR */
7050
7051  /* check this Formats: */
7052  assume(p_LmCheckIsFromRing(q,currRing));
7053  assume(p_CheckIsFromRing(pNext(q),strat->tailRing));
7054  assume(p_LmCheckIsFromRing(p,currRing));
7055  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
7056
7057#ifdef KDEBUG
7058    if (TEST_OPT_DEBUG)
7059    {
7060//       PrintS("enterOnePairShift(q,p) invoked with q = ");
7061//       wrp(q); //      wrp(pHead(q));
7062//       PrintS(", p = ");
7063//       wrp(p); //wrp(pHead(p));
7064//       PrintLn();
7065    }
7066#endif
7067
7068  /* poly q stays for s[i], ecartq = ecart(q), qisFromQ = applies to q */
7069
7070  int qfromQ = qisFromQ;
7071
7072  /* need additionally: int up_to_degree, poly V0 with the variables in (0)  or just the number lV = the length of the first block */
7073
7074  if (strat->interred_flag) return;
7075
7076  int      l,j,compare;
7077  LObject  Lp;
7078  Lp.i_r = -1;
7079
7080#ifdef KDEBUG
7081  Lp.ecart=0; Lp.length=0;
7082#endif
7083  /*- computes the lcm(s[i],p) -*/
7084  Lp.lcm = pInit();
7085
7086  pLcm(p,q, Lp.lcm); // q is what was strat->S[i], so a poly in LM/TR presentation
7087  pSetm(Lp.lcm);
7088
7089  /* apply the V criterion */
7090  if (!isInV(Lp.lcm, lV))
7091  {
7092#ifdef KDEBUG
7093    if (TEST_OPT_DEBUG)
7094    {
7095      PrintS("V crit applied to q = ");
7096      wrp(q); //      wrp(pHead(q));
7097      PrintS(", p = ");
7098      wrp(p); //wrp(pHead(p));
7099      PrintLn();
7100    }
7101#endif
7102    pLmFree(Lp.lcm);
7103    Lp.lcm=NULL;
7104    /* + counter for applying the V criterion */
7105    strat->cv++;
7106    return;
7107  }
7108
7109  if (strat->sugarCrit && ALLOW_PROD_CRIT(strat))
7110  {
7111    if((!((ecartq>0)&&(ecart>0)))
7112    && pHasNotCF(p,q))
7113    {
7114    /*
7115    *the product criterion has applied for (s,p),
7116    *i.e. lcm(s,p)=product of the leading terms of s and p.
7117    *Suppose (s,r) is in L and the leading term
7118    *of p divides lcm(s,r)
7119    *(==> the leading term of p divides the leading term of r)
7120    *but the leading term of s does not divide the leading term of r
7121    *(notice that this condition is automatically satisfied if r is still
7122    *in S), then (s,r) can be cancelled.
7123    *This should be done here because the
7124    *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
7125    *
7126    *Moreover, skipping (s,r) holds also for the noncommutative case.
7127    */
7128      strat->cp++;
7129      pLmFree(Lp.lcm);
7130      Lp.lcm=NULL;
7131      return;
7132    }
7133    else
7134      Lp.ecart = si_max(ecart,ecartq);
7135    if (strat->fromT && (ecartq>ecart))
7136    {
7137      pLmFree(Lp.lcm);
7138      Lp.lcm=NULL;
7139      return;
7140      /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
7141    }
7142    /*
7143    *the set B collects the pairs of type (S[j],p)
7144    *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
7145    *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
7146    *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
7147    */
7148    {
7149      j = strat->Bl;
7150      loop
7151      {
7152        if (j < 0)  break;
7153        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
7154        if ((compare==1)
7155        &&(sugarDivisibleBy(strat->B[j].ecart,Lp.ecart)))
7156        {
7157          strat->c3++;
7158          if ((strat->fromQ==NULL) || (isFromQ==0) || (qfromQ==0))
7159          {
7160            pLmFree(Lp.lcm);
7161            return;
7162          }
7163          break;
7164        }
7165        else
7166        if ((compare ==-1)
7167        && sugarDivisibleBy(Lp.ecart,strat->B[j].ecart))
7168        {
7169          deleteInL(strat->B,&strat->Bl,j,strat);
7170          strat->c3++;
7171        }
7172        j--;
7173      }
7174    }
7175  }
7176  else /*sugarcrit*/
7177  {
7178    if (ALLOW_PROD_CRIT(strat))
7179    {
7180      // if currRing->nc_type!=quasi (or skew)
7181      // TODO: enable productCrit for super commutative algebras...
7182      if(/*(strat->ak==0) && productCrit(p,strat->S[i])*/
7183      pHasNotCF(p,q))
7184      {
7185      /*
7186      *the product criterion has applied for (s,p),
7187      *i.e. lcm(s,p)=product of the leading terms of s and p.
7188      *Suppose (s,r) is in L and the leading term
7189      *of p devides lcm(s,r)
7190      *(==> the leading term of p devides the leading term of r)
7191      *but the leading term of s does not devide the leading term of r
7192      *(notice that tis condition is automatically satisfied if r is still
7193      *in S), then (s,r) can be canceled.
7194      *This should be done here because the
7195      *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
7196      */
7197          strat->cp++;
7198          pLmFree(Lp.lcm);
7199          Lp.lcm=NULL;
7200          return;
7201      }
7202      if (strat->fromT && (ecartq>ecart))
7203      {
7204        pLmFree(Lp.lcm);
7205        Lp.lcm=NULL;
7206        return;
7207        /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
7208      }
7209      /*
7210      *the set B collects the pairs of type (S[j],p)
7211      *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
7212      *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
7213      *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
7214      */
7215      for(j = strat->Bl;j>=0;j--)
7216      {
7217        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
7218        if (compare==1)
7219        {
7220          strat->c3++;
7221          if ((strat->fromQ==NULL) || (isFromQ==0) || (qfromQ==0))
7222          {
7223            pLmFree(Lp.lcm);
7224            return;
7225          }
7226          break;
7227        }
7228        else
7229        if (compare ==-1)
7230        {
7231          deleteInL(strat->B,&strat->Bl,j,strat);
7232          strat->c3++;
7233        }
7234      }
7235    }
7236  }
7237  /*
7238  *the pair (S[i],p) enters B if the spoly != 0
7239  */
7240  /*-  compute the short s-polynomial -*/
7241  if (strat->fromT && !TEST_OPT_INTSTRATEGY)
7242    pNorm(p);
7243  if ((q==NULL) || (p==NULL))
7244    return;
7245  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (qfromQ!=0))
7246    Lp.p=NULL;
7247  else
7248  {
7249//     if ( rIsPluralRing(currRing) )
7250//     {
7251//       if(pHasNotCF(p, q))
7252//       {
7253//         if(ncRingType(currRing) == nc_lie)
7254//         {
7255//             // generalized prod-crit for lie-type
7256//             strat->cp++;
7257//             Lp.p = nc_p_Bracket_qq(pCopy(p),q);
7258//         }
7259//         else
7260//         if( ALLOW_PROD_CRIT(strat) )
7261//         {
7262//             // product criterion for homogeneous case in SCA
7263//             strat->cp++;
7264//             Lp.p = NULL;
7265//         }
7266//         else
7267//           Lp.p = nc_CreateSpoly(q,p,currRing); // ?
7268//       }
7269//       else  Lp.p = nc_CreateSpoly(q,p,currRing);
7270//     }
7271//     else
7272//     {
7273
7274    /* ksCreateShortSpoly needs two Lobject-kind presentations */
7275    /* p is already in this form, so convert q */
7276    //    q = pMove2CurrTail(q, strat);
7277    Lp.p = ksCreateShortSpoly(q, p, strat->tailRing);
7278      //  }
7279  }
7280  if (Lp.p == NULL)
7281  {
7282    /*- the case that the s-poly is 0 -*/
7283    /* TEMPORARILY DISABLED FOR SHIFTS because there is no i*/
7284//      if (strat->pairtest==NULL) initPairtest(strat);
7285//      strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
7286//      strat->pairtest[strat->sl+1] = TRUE;
7287    /* END _ TEMPORARILY DISABLED FOR SHIFTS */
7288    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
7289    /*
7290    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
7291    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
7292    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
7293    *term of p devides the lcm(s,r)
7294    *(this canceling should be done here because
7295    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
7296    *the first case is handeled in chainCrit
7297    */
7298    if (Lp.lcm!=NULL) pLmFree(Lp.lcm);
7299  }
7300  else
7301  {
7302    /*- the pair (S[i],p) enters B -*/
7303    /* both of them should have their LM in currRing and TAIL in tailring */
7304    Lp.p1 = q;  // already in the needed form
7305    Lp.p2 = p; // already in the needed form
7306
7307    if ( !rIsPluralRing(currRing) )
7308      pNext(Lp.p) = strat->tail;
7309
7310    /* TEMPORARILY DISABLED FOR SHIFTS because there's no i*/
7311    /* at the beginning we DO NOT set atR = -1 ANYMORE*/
7312    if ( (atR >= 0) && (shiftcount==0) && (ifromS >=0) )
7313    {
7314      Lp.i_r1 = kFindInT(Lp.p1,strat); //strat->S_2_R[ifromS];
7315      Lp.i_r2 = atR;
7316    }
7317    else
7318    {
7319      /* END _ TEMPORARILY DISABLED FOR SHIFTS */
7320      Lp.i_r1 = -1;
7321      Lp.i_r2 = -1;
7322     }
7323    strat->initEcartPair(&Lp,q,p,ecartq,ecart);
7324
7325    if (TEST_OPT_INTSTRATEGY)
7326    {
7327      if (!rIsPluralRing(currRing))
7328        nDelete(&(Lp.p->coef));
7329    }
7330
7331    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
7332    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
7333  }
7334}
7335#endif
7336
7337#ifdef HAVE_SHIFTBBA
7338/*2
7339*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
7340*superfluous elements in S will be deleted
7341*/
7342void enterpairsShift (poly h,int k,int ecart,int pos,kStrategy strat, int atR,int uptodeg, int lV)
7343{
7344  /* h is strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
7345  /* Q: what is exactly the strat->fromT ? A: a local case trick; don't need it yet*/
7346  int j=pos;
7347
7348#ifdef HAVE_RINGS
7349  assume (!rField_is_Ring(currRing));
7350#endif
7351  initenterpairsShift(h,k,ecart,0,strat, atR,uptodeg,lV);
7352  if ( (!strat->fromT)
7353  && ((strat->syzComp==0)
7354    ||(pGetComp(h)<=strat->syzComp)))
7355  {
7356    //Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
7357    unsigned long h_sev = pGetShortExpVector(h);
7358    loop
7359    {
7360      if (j > k) break;
7361      clearS(h,h_sev, &j,&k,strat);
7362      j++;
7363    }
7364    //Print("end clearS sl=%d\n",strat->sl);
7365  }
7366 // PrintS("end enterpairs\n");
7367}
7368#endif
7369
7370#ifdef HAVE_SHIFTBBA
7371/*3
7372*(s[0], s \dot h),...,(s[k],s \dot h) will be put to the pairset L
7373* also the pairs (h, s\dot s[0]), ..., (h, s\dot s[k]) enter L
7374* additionally we put the pairs (h, s \sdot h) for s>=1 to L
7375*/
7376void initenterpairsShift (poly h,int k,int ecart,int isFromQ, kStrategy strat, int atR, int uptodeg, int lV)
7377{
7378  /* h comes from strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
7379  //  atR = -1;
7380  if ((strat->syzComp==0)
7381  || (pGetComp(h)<=strat->syzComp))
7382  {
7383    int j;
7384    BOOLEAN new_pair=FALSE;
7385
7386    if (pGetComp(h)==0)
7387    {
7388      /* for Q!=NULL: build pairs (f,q),(f1,f2), but not (q1,q2)*/
7389      if ((isFromQ)&&(strat->fromQ!=NULL))
7390      {
7391        for (j=0; j<=k; j++)
7392        {
7393          if (!strat->fromQ[j])
7394          {
7395            new_pair=TRUE;
7396            enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR,uptodeg,lV);
7397            // other side pairs:
7398            enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
7399          //Print("j:%d, Ll:%d\n",j,strat->Ll);
7400          }
7401        }
7402      }
7403      else
7404      {
7405        new_pair=TRUE;
7406        for (j=0; j<=k; j++)
7407        {
7408          enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR,uptodeg,lV);
7409          // other side pairs
7410          enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
7411        }
7412        /* HERE we put (h, s*h) pairs */
7413       /* enterOnePairSelfShifts (poly qq, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int uptodeg, int lV); */
7414       enterOnePairSelfShifts (h, h, ecart, isFromQ, strat, atR, uptodeg, lV);
7415      }
7416    }
7417    else
7418    {
7419      for (j=0; j<=k; j++)
7420      {
7421        if ((pGetComp(h)==pGetComp(strat->S[j]))
7422        || (pGetComp(strat->S[j])==0))
7423        {
7424          new_pair=TRUE;
7425          enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR, uptodeg, lV);
7426          // other side pairs
7427          enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
7428        //Print("j:%d, Ll:%d\n",j,strat->Ll);
7429        }
7430      }
7431      /* HERE we put (h, s*h) pairs */
7432      enterOnePairSelfShifts (h, h, ecart, isFromQ, strat, atR, uptodeg, lV);
7433    }
7434
7435    if (new_pair)
7436    {
7437      strat->chainCrit(h,ecart,strat);
7438    }
7439
7440  }
7441}
7442#endif
7443
7444#ifdef HAVE_SHIFTBBA
7445/*2
7446* puts p to the set T, starting with the at position atT
7447* and inserts all admissible shifts of p
7448*/
7449void enterTShift(LObject p, kStrategy strat, int atT, int uptodeg, int lV)
7450{
7451  /* determine how many elements we have to insert */
7452  /* x(0)y(1)z(2) : lastVblock-1=2, to add until lastVblock=uptodeg-1 */
7453  /* hence, a total number of elt's to add is: */
7454  /*  int toInsert = 1 + (uptodeg-1) - (pLastVblock(p.p, lV) -1);  */
7455
7456  int toInsert =  itoInsert(p.p, uptodeg,  lV, strat->tailRing);
7457
7458#ifdef PDEBUG
7459  //  Print("enterTShift uses toInsert: %d", toInsert);  PrintLn();
7460#endif
7461  int i;
7462
7463  if (atT < 0)
7464    atT = strat->posInT(strat->T, strat->tl, p);
7465
7466  /* can call enterT in a sequence, e.g. */
7467
7468  /* shift0 = it's our model for further shifts */
7469  enterT(p,strat,atT);
7470  LObject qq;
7471  for (i=1; i<=toInsert; i++) // toIns - 1?
7472  {
7473    qq      = p; //qq.Copy();
7474    qq.p    = NULL;
7475    qq.max  = NULL;
7476    qq.t_p = p_LPshift(p_Copy(p.t_p,strat->tailRing), i, uptodeg, lV, strat->tailRing); // direct shift
7477    qq.GetP();
7478    // update q.sev
7479    qq.sev = pGetShortExpVector(qq.p);
7480    /* enter it into T, first el't is with the shift 0 */
7481    // compute the position for qq
7482    atT = strat->posInT(strat->T, strat->tl, qq);
7483    enterT(qq,strat,atT);
7484  }
7485/* Q: what to do with this one in the orig enterT ? */
7486/*  strat->R[strat->tl] = &(strat->T[atT]); */
7487/* Solution: it is done by enterT each time separately */
7488}
7489#endif
7490
7491#ifdef HAVE_SHIFTBBA
7492poly redtailBbaShift (LObject* L, int pos, kStrategy strat, BOOLEAN withT, BOOLEAN normalize)
7493{
7494  /* for the shift case need to run it with withT = TRUE */
7495  strat->redTailChange=FALSE;
7496  if (strat->noTailReduction) return L->GetLmCurrRing();
7497  poly h, p;
7498  p = h = L->GetLmTailRing();
7499  if ((h==NULL) || (pNext(h)==NULL))
7500    return L->GetLmCurrRing();
7501
7502  TObject* With;
7503  // placeholder in case strat->tl < 0
7504  TObject  With_s(strat->tailRing);
7505
7506  LObject Ln(pNext(h), strat->tailRing);
7507  Ln.pLength = L->GetpLength() - 1;
7508
7509  pNext(h) = NULL;
7510  if (L->p != NULL) pNext(L->p) = NULL;
7511  L->pLength = 1;
7512
7513  Ln.PrepareRed(strat->use_buckets);
7514
7515  while(!Ln.IsNull())
7516  {
7517    loop
7518    {
7519      Ln.SetShortExpVector();
7520      if (withT)
7521      {
7522        int j;
7523        j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln);
7524        if (j < 0) break;
7525        With = &(strat->T[j]);
7526      }
7527      else
7528      {
7529        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
7530        if (With == NULL) break;
7531      }
7532      if (normalize && (!TEST_OPT_INTSTRATEGY) && (!nIsOne(pGetCoeff(With->p))))
7533      {
7534        With->pNorm();
7535        //if (TEST_OPT_PROT) { PrintS("n"); mflush(); }
7536      }
7537      strat->redTailChange=TRUE;
7538      if (ksReducePolyTail(L, With, &Ln))
7539      {
7540        // reducing the tail would violate the exp bound
7541        //  set a flag and hope for a retry (in bba)
7542        strat->completeReduce_retry=TRUE;
7543        if ((Ln.p != NULL) && (Ln.t_p != NULL)) Ln.p=NULL;
7544        do
7545        {
7546          pNext(h) = Ln.LmExtractAndIter();
7547          pIter(h);
7548          L->pLength++;
7549        } while (!Ln.IsNull());
7550        goto all_done;
7551      }
7552      if (Ln.IsNull()) goto all_done;
7553      if (! withT) With_s.Init(currRing);
7554    }
7555    pNext(h) = Ln.LmExtractAndIter();
7556    pIter(h);
7557    L->pLength++;
7558  }
7559
7560  all_done:
7561  Ln.Delete();
7562  if (L->p != NULL) pNext(L->p) = pNext(p);
7563
7564  if (strat->redTailChange)
7565  {
7566    L->last = NULL;
7567    L->length = 0;
7568  }
7569  L->Normalize(); // HANNES: should have a test
7570  kTest_L(L);
7571  return L->GetLmCurrRing();
7572}
7573#endif
Note: See TracBrowser for help on using the repository browser.