source: git/kernel/kutil.cc @ 0179d5

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