source: git/kernel/kutil.cc @ 151000

spielwiese
Last change on this file since 151000 was 151000, checked in by Motsak Oleksandr <motsak@…>, 15 years ago
*motsak: some more NC ShortSpoly! in kutil... git-svn-id: file:///usr/local/Singular/svn/trunk@10747 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 172.3 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: kutil.cc,v 1.92 2008-06-10 14:35:41 motsak 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  strat->newt = TRUE;
5237  if (atT < 0)
5238    atT = strat->posInT(strat->T, strat->tl, p);
5239  if (strat->tl == strat->tmax-1)
5240    enlargeT(strat->T,strat->R,strat->sevT,strat->tmax,setmaxTinc);
5241  if (atT <= strat->tl)
5242  {
5243#ifdef ENTER_USE_MEMMOVE
5244    memmove(&(strat->T[atT+1]), &(strat->T[atT]),
5245            (strat->tl-atT+1)*sizeof(TObject));
5246    memmove(&(strat->sevT[atT+1]), &(strat->sevT[atT]),
5247            (strat->tl-atT+1)*sizeof(unsigned long));
5248#endif
5249    for (i=strat->tl+1; i>=atT+1; i--)
5250    {
5251#ifndef ENTER_USE_MEMMOVE
5252      strat->T[i] = strat->T[i-1];
5253      strat->sevT[i] = strat->sevT[i-1];
5254#endif
5255      strat->R[strat->T[i].i_r] = &(strat->T[i]);
5256    }
5257  }
5258
5259  if (strat->tailBin != NULL && (pNext(p.p) != NULL))
5260  {
5261    pNext(p.p)=p_ShallowCopyDelete(pNext(p.p),
5262                                   (strat->tailRing != NULL ?
5263                                    strat->tailRing : currRing),
5264                                   strat->tailBin);
5265    if (p.t_p != NULL) pNext(p.t_p) = pNext(p.p);
5266  }
5267  strat->T[atT] = (TObject) p;
5268
5269  if (strat->tailRing != currRing && pNext(p.p) != NULL)
5270    strat->T[atT].max = p_GetMaxExpP(pNext(p.p), strat->tailRing);
5271  else
5272    strat->T[atT].max = NULL;
5273
5274  strat->tl++;
5275  strat->R[strat->tl] = &(strat->T[atT]);
5276  strat->T[atT].i_r = strat->tl;
5277  assume(p.sev == 0 || pGetShortExpVector(p.p) == p.sev);
5278  strat->sevT[atT] = (p.sev == 0 ? pGetShortExpVector(p.p) : p.sev);
5279  kTest_T(&(strat->T[atT]));
5280}
5281
5282void initHilbCrit(ideal F, ideal Q, intvec **hilb,kStrategy strat)
5283{
5284  if (strat->homog!=isHomog)
5285  {
5286    *hilb=NULL;
5287  }
5288}
5289
5290void initBuchMoraCrit(kStrategy strat)
5291{
5292  strat->sugarCrit =        TEST_OPT_SUGARCRIT;
5293  // obachman: Hmm.. I need BTEST1(2) for notBuckets ..
5294  //  strat->Gebauer =          BTEST1(2) || strat->homog || strat->sugarCrit;
5295  strat->Gebauer =          strat->homog || strat->sugarCrit;
5296  strat->honey =            !strat->homog || strat->sugarCrit || TEST_OPT_WEIGHTM;
5297  if (TEST_OPT_NOT_SUGAR) strat->honey = FALSE;
5298  strat->pairtest = NULL;
5299  /* alway use tailreduction, except:
5300  * - in local rings, - in lex order case, -in ring over extensions */
5301  strat->noTailReduction = !TEST_OPT_REDTAIL;
5302
5303#ifdef HAVE_PLURAL
5304  // and r is plural_ring
5305  if( rIsPluralRing(currRing) || (rIsSCA(currRing) && !strat->homog) )
5306  {    //or it has non-quasi-comm type... later
5307    strat->sugarCrit = FALSE;
5308    strat->Gebauer = FALSE;
5309    strat->honey = FALSE;
5310  }
5311#endif
5312
5313#ifdef HAVE_RINGS
5314  // Coefficient ring?
5315  if (rField_is_Ring(currRing))
5316  {
5317    strat->sugarCrit = FALSE;
5318    strat->Gebauer = FALSE ;
5319    strat->honey = FALSE;
5320  }
5321#endif
5322  #ifdef KDEBUG
5323  if (TEST_OPT_DEBUG)
5324  {
5325    if (strat->homog) PrintS("ideal/module is homogeneous\n");
5326    else              PrintS("ideal/module is not homogeneous\n");
5327  }
5328  #endif
5329}
5330
5331BOOLEAN kPosInLDependsOnLength(int (*pos_in_l)
5332                               (const LSet set, const int length,
5333                                LObject* L,const kStrategy strat))
5334{
5335  if (pos_in_l == posInL110 ||
5336      pos_in_l == posInL10)
5337    return TRUE;
5338
5339  return FALSE;
5340}
5341
5342void initBuchMoraPos (kStrategy strat)
5343{
5344  if (pOrdSgn==1)
5345  {
5346    if (strat->honey)
5347    {
5348      strat->posInL = posInL15;
5349      // ok -- here is the deal: from my experiments for Singular-2-0
5350      // I conclude that that posInT_EcartpLength is the best of
5351      // posInT15, posInT_EcartFDegpLength, posInT_FDegLength, posInT_pLength
5352      // see the table at the end of this file
5353      if (K_TEST_OPT_OLDSTD)
5354        strat->posInT = posInT15;
5355      else
5356        strat->posInT = posInT_EcartpLength;
5357    }
5358    else if (pLexOrder && !TEST_OPT_INTSTRATEGY)
5359    {
5360      strat->posInL = posInL11;
5361      strat->posInT = posInT11;
5362    }
5363    else if (TEST_OPT_INTSTRATEGY)
5364    {
5365      strat->posInL = posInL11;
5366      strat->posInT = posInT11;
5367    }
5368    else
5369    {
5370      strat->posInL = posInL0;
5371      strat->posInT = posInT0;
5372    }
5373    //if (strat->minim>0) strat->posInL =posInLSpecial;
5374    if (strat->homog)
5375    {
5376       strat->posInL = posInL110;
5377       strat->posInT = posInT110;
5378    }
5379  }
5380  else
5381  {
5382    if (strat->homog)
5383    {
5384      strat->posInL = posInL11;
5385      strat->posInT = posInT11;
5386    }
5387    else
5388    {
5389      if ((currRing->order[0]==ringorder_c)
5390      ||(currRing->order[0]==ringorder_C))
5391      {
5392        strat->posInL = posInL17_c;
5393        strat->posInT = posInT17_c;
5394      }
5395      else
5396      {
5397        strat->posInL = posInL17;
5398        strat->posInT = posInT17;
5399      }
5400    }
5401  }
5402  if (strat->minim>0) strat->posInL =posInLSpecial;
5403  // for further tests only
5404  if ((BTEST1(11)) || (BTEST1(12)))
5405    strat->posInL = posInL11;
5406  else if ((BTEST1(13)) || (BTEST1(14)))
5407    strat->posInL = posInL13;
5408  else if ((BTEST1(15)) || (BTEST1(16)))
5409    strat->posInL = posInL15;
5410  else if ((BTEST1(17)) || (BTEST1(18)))
5411    strat->posInL = posInL17;
5412  if (BTEST1(11))
5413    strat->posInT = posInT11;
5414  else if (BTEST1(13))
5415    strat->posInT = posInT13;
5416  else if (BTEST1(15))
5417    strat->posInT = posInT15;
5418  else if ((BTEST1(17)))
5419    strat->posInT = posInT17;
5420  else if ((BTEST1(19)))
5421    strat->posInT = posInT19;
5422  else if (BTEST1(12) || BTEST1(14) || BTEST1(16) || BTEST1(18))
5423    strat->posInT = posInT1;
5424#ifdef HAVE_RINGS
5425  if (rField_is_Ring(currRing))
5426  {
5427    strat->posInL = posInL11;
5428    strat->posInT = posInT11;
5429  }
5430#endif
5431  strat->posInLDependsOnLength = kPosInLDependsOnLength(strat->posInL);
5432}
5433
5434void initBuchMora (ideal F,ideal Q,kStrategy strat)
5435{
5436  strat->interpt = BTEST1(OPT_INTERRUPT);
5437  strat->kHEdge=NULL;
5438  if (pOrdSgn==1) strat->kHEdgeFound=FALSE;
5439  /*- creating temp data structures------------------- -*/
5440  strat->cp = 0;
5441  strat->c3 = 0;
5442  strat->tail = pInit();
5443  /*- set s -*/
5444  strat->sl = -1;
5445  /*- set L -*/
5446  strat->Lmax = setmaxL;
5447  strat->Ll = -1;
5448  strat->L = initL();
5449  /*- set B -*/
5450  strat->Bmax = setmaxL;
5451  strat->Bl = -1;
5452  strat->B = initL();
5453  /*- set T -*/
5454  strat->tl = -1;
5455  strat->tmax = setmaxT;
5456  strat->T = initT();
5457  strat->R = initR();
5458  strat->sevT = initsevT();
5459  /*- init local data struct.---------------------------------------- -*/
5460  strat->P.ecart=0;
5461  strat->P.length=0;
5462  if (pOrdSgn==-1)
5463  {
5464    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
5465    if (strat->kNoether!=NULL) pSetComp(strat->kNoetherTail(), strat->ak);
5466  }
5467  if(TEST_OPT_SB_1)
5468  {
5469    int i;
5470    ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
5471    for (i=strat->newIdeal;i<IDELEMS(F);i++)
5472    {
5473      P->m[i-strat->newIdeal] = F->m[i];
5474      F->m[i] = NULL;
5475    }
5476    initSSpecial(F,Q,P,strat);
5477    for (i=strat->newIdeal;i<IDELEMS(F);i++)
5478    {
5479      F->m[i] = P->m[i-strat->newIdeal];
5480      P->m[i-strat->newIdeal] = NULL;
5481    }
5482    idDelete(&P);
5483  }
5484  else
5485  {
5486    /*Shdl=*/initSL(F, Q,strat); /*sets also S, ecartS, fromQ */
5487    // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
5488  }
5489  strat->kIdeal = NULL;
5490  strat->fromT = FALSE;
5491  strat->noTailReduction = !TEST_OPT_REDTAIL;
5492  if (!TEST_OPT_SB_1)
5493  {
5494    updateS(TRUE,strat);
5495  }
5496  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
5497  strat->fromQ=NULL;
5498}
5499
5500void exitBuchMora (kStrategy strat)
5501{
5502  /*- release temp data -*/
5503  cleanT(strat);
5504  omFreeSize(strat->T,(strat->tmax)*sizeof(TObject));
5505  omFreeSize(strat->R,(strat->tmax)*sizeof(TObject*));
5506  omFreeSize(strat->sevT, (strat->tmax)*sizeof(unsigned long));
5507  omFreeSize(strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
5508  omFreeSize(strat->sevS,IDELEMS(strat->Shdl)*sizeof(int));
5509  omFreeSize(strat->S_2_R,IDELEMS(strat->Shdl)*sizeof(int));
5510  /*- set L: should be empty -*/
5511  omFreeSize(strat->L,(strat->Lmax)*sizeof(LObject));
5512  /*- set B: should be empty -*/
5513  omFreeSize(strat->B,(strat->Bmax)*sizeof(LObject));
5514  pDeleteLm(&strat->tail);
5515  strat->syzComp=0;
5516  if (strat->kIdeal!=NULL)
5517  {
5518    omFreeBin(strat->kIdeal, sleftv_bin);
5519    strat->kIdeal=NULL;
5520  }
5521}
5522
5523/*2
5524* in the case of a standardbase of a module over a qring:
5525* replace polynomials in i by ak vectors,
5526* (the polynomial * unit vectors gen(1)..gen(ak)
5527* in every case (also for ideals:)
5528* deletes divisible vectors/polynomials
5529*/
5530void updateResult(ideal r,ideal Q, kStrategy strat)
5531{
5532  int l;
5533  if (strat->ak>0)
5534  {
5535    for (l=IDELEMS(r)-1;l>=0;l--)
5536    {
5537      if ((r->m[l]!=NULL) && (pGetComp(r->m[l])==0))
5538      {
5539        pDelete(&r->m[l]); // and set it to NULL
5540      }
5541    }
5542    int q;
5543    poly p;
5544    for (l=IDELEMS(r)-1;l>=0;l--)
5545    {
5546      if ((r->m[l]!=NULL)
5547      && (strat->syzComp>0)
5548      && (pGetComp(r->m[l])<=strat->syzComp))
5549      {
5550        for(q=IDELEMS(Q)-1; q>=0;q--)
5551        {
5552          if ((Q->m[q]!=NULL)
5553          &&(pLmDivisibleBy(Q->m[q],r->m[l])))
5554          {
5555            if (TEST_OPT_REDSB)
5556            {
5557              p=r->m[l];
5558              r->m[l]=kNF(Q,NULL,p);
5559              pDelete(&p);
5560            }
5561            else
5562            {
5563              pDelete(&r->m[l]); // and set it to NULL
5564            }
5565            break;
5566          }
5567        }
5568      }
5569    }
5570  }
5571  else
5572  {
5573    int q;
5574    poly p;
5575    for (l=IDELEMS(r)-1;l>=0;l--)
5576    {
5577      if (r->m[l]!=NULL)
5578      {
5579        for(q=IDELEMS(Q)-1; q>=0;q--)
5580        {
5581          if ((Q->m[q]!=NULL)
5582          &&(pLmEqual(r->m[l],Q->m[q])))
5583          {
5584            if (TEST_OPT_REDSB)
5585            {
5586              p=r->m[l];
5587              r->m[l]=kNF(Q,NULL,p);
5588              pDelete(&p);
5589            }
5590            else
5591            {
5592              pDelete(&r->m[l]); // and set it to NULL
5593            }
5594            break;
5595          }
5596        }
5597      }
5598    }
5599  }
5600  idSkipZeroes(r);
5601}
5602
5603void completeReduce (kStrategy strat, BOOLEAN withT)
5604{
5605  int i;
5606  int low = (pOrdSgn == 1 ? 1 : 0);
5607  LObject L;
5608
5609#ifdef KDEBUG
5610  // need to set this: during tailreductions of T[i], T[i].max is out of
5611  // sync
5612  sloppy_max = TRUE;
5613#endif
5614
5615  strat->noTailReduction = FALSE;
5616  if (TEST_OPT_PROT)
5617  {
5618    PrintLn();
5619    if (timerv) writeTime("standard base computed:");
5620  }
5621  if (TEST_OPT_PROT)
5622  {
5623    Print("(S:%d)",strat->sl);mflush();
5624  }
5625  for (i=strat->sl; i>=low; i--)
5626  {
5627    TObject* T_j = strat->s_2_t(i);
5628    if (T_j != NULL)
5629    {
5630      L = *T_j;
5631      poly p;
5632      if (pOrdSgn == 1)
5633        strat->S[i] = redtailBba(&L, i-1, strat, withT);
5634      else
5635        strat->S[i] = redtail(&L, strat->sl, strat);
5636
5637      if (strat->redTailChange && strat->tailRing != currRing)
5638      {
5639        if (T_j->max != NULL) p_LmFree(T_j->max, strat->tailRing);
5640        if (pNext(T_j->p) != NULL)
5641          T_j->max = p_GetMaxExpP(pNext(T_j->p), strat->tailRing);
5642        else
5643          T_j->max = NULL;
5644      }
5645      if (TEST_OPT_INTSTRATEGY)
5646        T_j->pCleardenom();
5647    }
5648    else
5649    {
5650      assume(currRing == strat->tailRing);
5651      if (pOrdSgn == 1)
5652        strat->S[i] = redtailBba(strat->S[i], i-1, strat, withT);
5653      else
5654        strat->S[i] = redtail(strat->S[i], strat->sl, strat);
5655      if (TEST_OPT_INTSTRATEGY)
5656        pCleardenom(strat->S[i]);
5657    }
5658    if (TEST_OPT_PROT)
5659      PrintS("-");
5660  }
5661  if (TEST_OPT_PROT) PrintLn();
5662#ifdef KDEBUG
5663  sloppy_max = FALSE;
5664#endif
5665}
5666
5667
5668/*2
5669* computes the new strat->kHEdge and the new pNoether,
5670* returns TRUE, if pNoether has changed
5671*/
5672BOOLEAN newHEdge(polyset S, kStrategy strat)
5673{
5674  int i,j;
5675  poly newNoether;
5676
5677#if 0
5678  if (currRing->weight_all_1)
5679    scComputeHC(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
5680  else
5681    scComputeHCw(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
5682#else   
5683  scComputeHC(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
5684#endif 
5685  if (strat->t_kHEdge != NULL) p_LmFree(strat->t_kHEdge, strat->tailRing);
5686  if (strat->tailRing != currRing)
5687    strat->t_kHEdge = k_LmInit_currRing_2_tailRing(strat->kHEdge, strat->tailRing);
5688  /* compare old and new noether*/
5689  newNoether = pLmInit(strat->kHEdge);
5690  j = pFDeg(newNoether,currRing);
5691  for (i=1; i<=pVariables; i++)
5692  {
5693    if (pGetExp(newNoether, i) > 0) pDecrExp(newNoether,i);
5694  }
5695  pSetm(newNoether);
5696  if (j < strat->HCord) /*- statistics -*/
5697  {
5698    if (TEST_OPT_PROT)
5699    {
5700      Print("H(%d)",j);
5701      mflush();
5702    }
5703    strat->HCord=j;
5704    #ifdef KDEBUG
5705    if (TEST_OPT_DEBUG)
5706    {
5707      Print("H(%d):",j);
5708      wrp(strat->kHEdge);
5709      PrintLn();
5710    }
5711    #endif
5712  }
5713  if (pCmp(strat->kNoether,newNoether)!=1)
5714  {
5715    pDelete(&strat->kNoether);
5716    strat->kNoether=newNoether;
5717    if (strat->t_kNoether != NULL) p_LmFree(strat->t_kNoether, strat->tailRing);
5718    if (strat->tailRing != currRing)
5719      strat->t_kNoether = k_LmInit_currRing_2_tailRing(strat->kNoether, strat->tailRing);
5720
5721    return TRUE;
5722  }
5723  pLmFree(newNoether);
5724  return FALSE;
5725}
5726
5727/***************************************************************
5728 *
5729 * Routines related for ring changes during std computations
5730 *
5731 ***************************************************************/
5732BOOLEAN kCheckSpolyCreation(LObject *L, kStrategy strat, poly &m1, poly &m2)
5733{
5734  assume(L->p1 != NULL && L->p2 != NULL);
5735  // shift changes: from 0 to -1
5736  assume(L->i_r1 >= -1 && L->i_r1 <= strat->tl);
5737  assume(L->i_r2 >= -1 && L->i_r2 <= strat->tl);
5738  assume(strat->tailRing != currRing);
5739
5740  if (! k_GetLeadTerms(L->p1, L->p2, currRing, m1, m2, strat->tailRing))
5741    return FALSE;
5742  // shift changes: extra case inserted
5743  if ((L->i_r1 == -1) || (L->i_r2 == -1) )
5744  {
5745    return TRUE;
5746  }
5747  poly p1_max = (strat->R[L->i_r1])->max;
5748  poly p2_max = (strat->R[L->i_r2])->max;
5749
5750  if ((p1_max != NULL && !p_LmExpVectorAddIsOk(m1, p1_max, strat->tailRing)) ||
5751      (p2_max != NULL && !p_LmExpVectorAddIsOk(m2, p2_max, strat->tailRing)))
5752  {
5753    p_LmFree(m1, strat->tailRing);
5754    p_LmFree(m2, strat->tailRing);
5755    m1 = NULL;
5756    m2 = NULL;
5757    return FALSE;
5758  }
5759  return TRUE;
5760}
5761
5762BOOLEAN kStratChangeTailRing(kStrategy strat, LObject *L, TObject* T, unsigned long expbound)
5763{
5764  if (expbound == 0) expbound = strat->tailRing->bitmask << 1;
5765  if (expbound >= currRing->bitmask) return FALSE;
5766  ring new_tailRing = rModifyRing(currRing,
5767                                  // Hmmm .. the condition pFDeg == pDeg
5768                                  // might be too strong
5769#ifdef HAVE_RINGS
5770                                  (strat->homog && pFDeg == pDeg && !(rField_is_Ring(currRing))), // TODO Oliver
5771#else
5772                                  (strat->homog && pFDeg == pDeg),
5773#endif
5774                                  !strat->ak,
5775                                  expbound);
5776  if (new_tailRing == currRing) return TRUE;
5777
5778  strat->pOrigFDeg_TailRing = new_tailRing->pFDeg;
5779  strat->pOrigLDeg_TailRing = new_tailRing->pLDeg;
5780
5781  if (currRing->pFDeg != currRing->pFDegOrig)
5782  {
5783    new_tailRing->pFDeg = currRing->pFDeg;
5784    new_tailRing->pLDeg = currRing->pLDeg;
5785  }
5786
5787  if (TEST_OPT_PROT)
5788    Print("[%lu:%d", (unsigned long) new_tailRing->bitmask, new_tailRing->ExpL_Size);
5789  kTest_TS(strat);
5790  assume(new_tailRing != strat->tailRing);
5791  pShallowCopyDeleteProc p_shallow_copy_delete
5792    = pGetShallowCopyDeleteProc(strat->tailRing, new_tailRing);
5793
5794  omBin new_tailBin = omGetStickyBinOfBin(new_tailRing->PolyBin);
5795
5796  int i;
5797  for (i=0; i<=strat->tl; i++)
5798  {
5799    strat->T[i].ShallowCopyDelete(new_tailRing, new_tailBin,
5800                                  p_shallow_copy_delete);
5801  }
5802  for (i=0; i<=strat->Ll; i++)
5803  {
5804    assume(strat->L[i].p != NULL);
5805    if (pNext(strat->L[i].p) != strat->tail)
5806      strat->L[i].ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
5807  }
5808  if (strat->P.t_p != NULL ||
5809      (strat->P.p != NULL && pNext(strat->P.p) != strat->tail))
5810    strat->P.ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
5811
5812  if (L != NULL && L->tailRing != new_tailRing)
5813  {
5814    if (L->i_r < 0)
5815      L->ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
5816    else
5817    {
5818      assume(L->i_r <= strat->tl);
5819      TObject* t_l = strat->R[L->i_r];
5820      assume(t_l != NULL);
5821      L->tailRing = new_tailRing;
5822      L->p = t_l->p;
5823      L->t_p = t_l->t_p;
5824      L->max = t_l->max;
5825    }
5826  }
5827
5828  if (T != NULL && T->tailRing != new_tailRing && T->i_r < 0)
5829    T->ShallowCopyDelete(new_tailRing, new_tailBin, p_shallow_copy_delete);
5830
5831  omMergeStickyBinIntoBin(strat->tailBin, strat->tailRing->PolyBin);
5832  if (strat->tailRing != currRing)
5833    rKillModifiedRing(strat->tailRing);
5834
5835  strat->tailRing = new_tailRing;
5836  strat->tailBin = new_tailBin;
5837  strat->p_shallow_copy_delete
5838    = pGetShallowCopyDeleteProc(currRing, new_tailRing);
5839
5840  if (strat->kHEdge != NULL)
5841  {
5842    if (strat->t_kHEdge != NULL)
5843      p_LmFree(strat->t_kHEdge, strat->tailRing);
5844    strat->t_kHEdge=k_LmInit_currRing_2_tailRing(strat->kHEdge, new_tailRing);
5845  }
5846
5847  if (strat->kNoether != NULL)
5848  {
5849    if (strat->t_kNoether != NULL)
5850      p_LmFree(strat->t_kNoether, strat->tailRing);
5851    strat->t_kNoether=k_LmInit_currRing_2_tailRing(strat->kNoether,
5852                                                   new_tailRing);
5853  }
5854  kTest_TS(strat);
5855  if (TEST_OPT_PROT)
5856    PrintS("]");
5857  return TRUE;
5858}
5859
5860void kStratInitChangeTailRing(kStrategy strat)
5861{
5862  unsigned long l = 0;
5863  int i;
5864  Exponent_t e;
5865  ring new_tailRing;
5866
5867  assume(strat->tailRing == currRing);
5868
5869  for (i=0; i<= strat->Ll; i++)
5870  {
5871    l = p_GetMaxExpL(strat->L[i].p, currRing, l);
5872  }
5873  for (i=0; i<=strat->tl; i++)
5874  {
5875    // Hmm ... this we could do in one Step
5876    l = p_GetMaxExpL(strat->T[i].p, currRing, l);
5877  }
5878  e = p_GetMaxExp(l, currRing);
5879  if (e <= 1) e = 2;
5880
5881  kStratChangeTailRing(strat, NULL, NULL, e);
5882}
5883
5884skStrategy::skStrategy()
5885{
5886  memset(this, 0, sizeof(skStrategy));
5887#ifndef NDEBUG
5888  strat_nr++;
5889  nr=strat_nr;
5890  if (strat_fac_debug) Print("s(%d) created\n",nr);
5891#endif
5892  tailRing = currRing;
5893  P.tailRing = currRing;
5894  tl = -1;
5895  sl = -1;
5896#ifdef HAVE_LM_BIN
5897  lmBin = omGetStickyBinOfBin(currRing->PolyBin);
5898#endif
5899#ifdef HAVE_TAIL_BIN
5900  tailBin = omGetStickyBinOfBin(currRing->PolyBin);
5901#endif
5902  pOrigFDeg = pFDeg;
5903  pOrigLDeg = pLDeg;
5904}
5905
5906
5907skStrategy::~skStrategy()
5908{
5909  if (lmBin != NULL)
5910    omMergeStickyBinIntoBin(lmBin, currRing->PolyBin);
5911  if (tailBin != NULL)
5912    omMergeStickyBinIntoBin(tailBin,
5913                            (tailRing != NULL ? tailRing->PolyBin:
5914                             currRing->PolyBin));
5915  if (t_kHEdge != NULL)
5916    p_LmFree(t_kHEdge, tailRing);
5917  if (t_kNoether != NULL)
5918    p_LmFree(t_kNoether, tailRing);
5919
5920  if (currRing != tailRing)
5921    rKillModifiedRing(tailRing);
5922  pRestoreDegProcs(pOrigFDeg, pOrigLDeg);
5923}
5924
5925#if 0
5926Timings for the different possibilities of posInT:
5927            T15           EDL         DL          EL            L         1-2-3
5928Gonnet      43.26       42.30       38.34       41.98       38.40      100.04
5929Hairer_2_1   1.11        1.15        1.04        1.22        1.08        4.7
5930Twomat3      1.62        1.69        1.70        1.65        1.54       11.32
5931ahml         4.48        4.03        4.03        4.38        4.96       26.50
5932c7          15.02       13.98       15.16       13.24       17.31       47.89
5933c8         505.09      407.46      852.76      413.21      499.19        n/a
5934f855        12.65        9.27       14.97        8.78       14.23       33.12
5935gametwo6    11.47       11.35       14.57       11.20       12.02       35.07
5936gerhard_3    2.73        2.83        2.93        2.64        3.12        6.24
5937ilias13     22.89       22.46       24.62       20.60       23.34       53.86
5938noon8       40.68       37.02       37.99       36.82       35.59      877.16
5939rcyclic_19  48.22       42.29       43.99       45.35       51.51      204.29
5940rkat9       82.37       79.46       77.20       77.63       82.54      267.92
5941schwarz_11  16.46       16.81       16.76       16.81       16.72       35.56
5942test016     16.39       14.17       14.40       13.50       14.26       34.07
5943test017     34.70       36.01       33.16       35.48       32.75       71.45
5944test042     10.76       10.99       10.27       11.57       10.45       23.04
5945test058      6.78        6.75        6.51        6.95        6.22        9.47
5946test066     10.71       10.94       10.76       10.61       10.56       19.06
5947test073     10.75       11.11       10.17       10.79        8.63       58.10
5948test086     12.23       11.81       12.88       12.24       13.37       66.68
5949test103      5.05        4.80        5.47        4.64        4.89       11.90
5950test154     12.96       11.64       13.51       12.46       14.61       36.35
5951test162     65.27       64.01       67.35       59.79       67.54      196.46
5952test164      7.50        6.50        7.68        6.70        7.96       17.13
5953virasoro     3.39        3.50        3.35        3.47        3.70        7.66
5954#endif
5955
5956
5957#ifdef HAVE_MORE_POS_IN_T
5958// determines the position based on: 1.) Ecart 2.) FDeg 3.) pLength
5959int posInT_EcartFDegpLength(const TSet set,const int length,LObject &p)
5960{
5961
5962  if (length==-1) return 0;
5963
5964  int o = p.ecart;
5965  int op=p.GetpFDeg();
5966  int ol = p.GetpLength();
5967
5968  if (set[length].ecart < o)
5969    return length+1;
5970  if (set[length].ecart == o)
5971  {
5972     int oo=set[length].GetpFDeg();
5973     if ((oo < op) || ((oo==op) && (set[length].length < ol)))
5974       return length+1;
5975  }
5976
5977  int i;
5978  int an = 0;
5979  int en= length;
5980  loop
5981  {
5982    if (an >= en-1)
5983    {
5984      if (set[an].ecart > o)
5985        return an;
5986      if (set[an].ecart == o)
5987      {
5988         int oo=set[an].GetpFDeg();
5989         if((oo > op)
5990         || ((oo==op) && (set[an].pLength > ol)))
5991           return an;
5992      }
5993      return en;
5994    }
5995    i=(an+en) / 2;
5996    if (set[i].ecart > o)
5997      en=i;
5998    else if (set[i].ecart == o)
5999    {
6000       int oo=set[i].GetpFDeg();
6001       if ((oo > op)
6002       || ((oo == op) && (set[i].pLength > ol)))
6003         en=i;
6004       else
6005        an=i;
6006    }
6007    else
6008      an=i;
6009  }
6010}
6011
6012// determines the position based on: 1.) FDeg 2.) pLength
6013int posInT_FDegpLength(const TSet set,const int length,LObject &p)
6014{
6015
6016  if (length==-1) return 0;
6017
6018  int op=p.GetpFDeg();
6019  int ol = p.GetpLength();
6020
6021  int oo=set[length].GetpFDeg();
6022  if ((oo < op) || ((oo==op) && (set[length].length < ol)))
6023    return length+1;
6024
6025  int i;
6026  int an = 0;
6027  int en= length;
6028  loop
6029    {
6030      if (an >= en-1)
6031      {
6032        int oo=set[an].GetpFDeg();
6033        if((oo > op)
6034           || ((oo==op) && (set[an].pLength > ol)))
6035          return an;
6036        return en;
6037      }
6038      i=(an+en) / 2;
6039      int oo=set[i].GetpFDeg();
6040      if ((oo > op)
6041          || ((oo == op) && (set[i].pLength > ol)))
6042        en=i;
6043      else
6044        an=i;
6045    }
6046}
6047
6048
6049// determines the position based on: 1.) Ecart 2.) FDeg 3.) pLength
6050int posInT_pLength(const TSet set,const int length,LObject &p)
6051{
6052  if (length==-1)
6053    return 0;
6054  if