source: git/kernel/kutil.cc @ 93ebe1

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