source: git/kernel/kutil.cc @ d351d8

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