source: git/kernel/kutil.cc @ 660ed3

spielwiese
Last change on this file since 660ed3 was 660ed3, checked in by Hans Schönemann <hannes@…>, 17 years ago
*hannes: degBound git-svn-id: file:///usr/local/Singular/svn/trunk@9149 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 127.1 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: kutil.cc,v 1.23 2006-05-19 10:22:36 Singular Exp $ */
5/*
6* ABSTRACT: kernel: utils for kStd
7*/
8
9#ifndef KUTIL_CC
10#define KUTIL_CC
11
12// #define PDEBUG 2
13// #define PDIV_DEBUG
14#include <stdlib.h>
15#include <string.h>
16#include "mod2.h"
17#include <mylimits.h>
18#include "structs.h"
19#ifdef HAVE_PLURAL
20#include "gring.h"
21#endif
22#ifdef KDEBUG
23#undef KDEBUG
24#define KDEBUG 2
25#endif
26
27// define if enterL, enterT should use memmove instead of doing it manually
28// on topgun, this is slightly faster (see monodromy_l.tst, homog_gonnet.sing)
29#ifndef SunOS_4
30#define ENTER_USE_MEMMOVE
31#endif
32
33// define, if the my_memmove inlines should be used instead of
34// system memmove -- it does not seem to pay off, though
35// #define ENTER_USE_MYMEMMOVE
36
37#include "kutil.h"
38#include "febase.h"
39#include "omalloc.h"
40#include "numbers.h"
41#include "polys.h"
42#include "ring.h"
43#include "ideals.h"
44#include "timer.h"
45//#include "cntrlc.h"
46#include "stairc.h"
47#include "kstd1.h"
48#include "pShallowCopyDelete.h"
49
50#ifdef KDEBUG
51#undef KDEBUG
52#define KDEBUG 2
53#endif
54
55#ifdef ENTER_USE_MYMEMMOVE
56inline void _my_memmove_d_gt_s(unsigned long* d, unsigned long* s, long l)
57{
58  register unsigned long* _dl = (unsigned long*) d;
59  register unsigned long* _sl = (unsigned long*) s;
60  register long _i = l - 1;
61
62  do
63  {
64    _dl[_i] = _sl[_i];
65    _i--;
66  }
67  while (_i >= 0);
68}
69
70inline void _my_memmove_d_lt_s(unsigned long* d, unsigned long* s, long l)
71{
72  register long _ll = l;
73  register unsigned long* _dl = (unsigned long*) d;
74  register unsigned long* _sl = (unsigned long*) s;
75  register long _i = 0;
76
77  do
78  {
79    _dl[_i] = _sl[_i];
80    _i++;
81  }
82  while (_i < _ll);
83}
84
85inline void _my_memmove(void* d, void* s, long l)
86{
87  unsigned long _d = (unsigned long) d;
88  unsigned long _s = (unsigned long) s;
89  unsigned long _l = ((l) + SIZEOF_LONG - 1) >> LOG_SIZEOF_LONG;
90
91  if (_d > _s) _my_memmove_d_gt_s(_d, _s, _l);
92  else _my_memmove_d_lt_s(_d, _s, _l);
93}
94
95#undef memmove
96#define memmove(d,s,l) _my_memmove(d, s, l)
97#endif
98
99static poly redMora (poly h,int maxIndex,kStrategy strat);
100static poly redBba (poly h,int maxIndex,kStrategy strat);
101
102static inline int pDivComp(poly p, poly q)
103{
104  if (pGetComp(p) == pGetComp(q))
105  {
106    BOOLEAN a=FALSE, b=FALSE;
107    int i;
108    unsigned long la, lb;
109    unsigned long divmask = currRing->divmask;
110    for (i=0; i<currRing->VarL_Size; i++)
111    {
112      la = p->exp[currRing->VarL_Offset[i]];
113      lb = q->exp[currRing->VarL_Offset[i]];
114      if (la != lb)
115      {
116        if (la < lb)
117        {
118          if (b) return 0;
119          if (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask))
120            return 0;
121          a = TRUE;
122        }
123        else
124        {
125          if (a) return 0;
126          if (((la & divmask) ^ (lb & divmask)) != ((la - lb) & divmask))
127            return 0;
128          b = TRUE;
129        }
130      }
131    }
132    if (a) return 1;
133    if (b) return -1;
134  }
135  return 0;
136}
137
138
139BITSET  test=(BITSET)0;
140int     HCord;
141int     Kstd1_deg;
142int     mu=32000;
143
144/*2
145*deletes higher monomial of p, re-compute ecart and length
146*works only for orderings with ecart =pFDeg(end)-pFDeg(start)
147*/
148void deleteHC(LObject *L, kStrategy strat, BOOLEAN fromNext)
149{
150  if (strat->kHEdgeFound)
151  {
152    kTest_L(L);
153    poly p1;
154    poly p = L->GetLmTailRing();
155    int l = 1;
156    kBucket_pt bucket = NULL;
157    if (L->bucket != NULL)
158    {
159      kBucketClear(L->bucket, &pNext(p), &L->pLength);
160      L->pLength++;
161      bucket = L->bucket;
162      L->bucket = NULL;
163      L->last = NULL;
164    }
165
166    if (!fromNext && p_Cmp(p,strat->kNoetherTail(), L->tailRing) == -1)
167    {
168      L->Delete();
169      L->Clear();
170      L->ecart = -1;
171      if (bucket != NULL) kBucketDestroy(&bucket);
172      return;
173    }
174    p1 = p;
175    while (pNext(p1)!=NULL)
176    {
177      if (p_LmCmp(pNext(p1), strat->kNoetherTail(), L->tailRing) == -1)
178      {
179        L->last = p1;
180        p_Delete(&pNext(p1), L->tailRing);
181        if (p1 == p)
182        {
183          if (L->t_p != NULL)
184          {
185            assume(L->p != NULL && p == L->t_p);
186            pNext(L->p) = NULL;
187          }
188          L->max  = NULL;
189        }
190        else if (fromNext)
191          L->max  = p_GetMaxExpP(pNext(L->p), L->tailRing ); // p1;
192        if (L->pLength != 0) L->pLength = l;
193        // Hmmm when called from updateT, then only
194        // reset ecart when cut
195        if (fromNext)
196          L->ecart = L->pLDeg() - L->GetpFDeg();
197        break;
198      }
199      l++;
200      pIter(p1);
201    }
202    if (! fromNext)
203    {
204      L->SetpFDeg();
205      L->ecart = L->pLDeg(strat->LDegLast) - L->GetpFDeg();
206    }
207    if (bucket != NULL)
208    {
209      if (L->pLength > 1)
210      {
211        kBucketInit(bucket, pNext(p), L->pLength - 1);
212        pNext(p) = NULL;
213        if (L->t_p != NULL) pNext(L->t_p) = NULL;
214        L->pLength = 0;
215        L->bucket = bucket;
216        L->last = NULL;
217      }
218      else
219        kBucketDestroy(&bucket);
220    }
221    kTest_L(L);
222  }
223}
224
225void deleteHC(poly* p, int* e, int* l,kStrategy strat)
226{
227  LObject L(*p, currRing, strat->tailRing);
228
229  deleteHC(&L, strat);
230  *p = L.p;
231  *e = L.ecart;
232  *l = L.length;
233  if (L.t_p != NULL) p_LmFree(L.t_p, strat->tailRing);
234}
235
236/*2
237*tests if p.p=monomial*unit and cancels the unit
238*/
239void cancelunit (LObject* L)
240{
241  int  i;
242  poly h;
243
244  if(currRing->OrdSgn != -1) return;
245  if(TEST_OPT_CANCELUNIT) return;
246
247  ring r = L->tailRing;
248  poly p = L->GetLmTailRing();
249
250  if(p_GetComp(p, r) != 0 && !p_OneComp(p, r)) return;
251
252  if (L->ecart != 0)
253  {
254//    for(i=r->N;i>0;i--)
255//    {
256//      if ((p_GetExp(p,i,r)>0) && (rIsPolyVar(i, r)==TRUE)) return;
257//    }
258    h = pNext(p);
259    loop
260    {
261      if (h==NULL)
262      {
263        p_Delete(&pNext(p), r);
264        number eins=nInit(1);
265        if (L->p != NULL)  pSetCoeff(L->p,eins);
266        else if (L->t_p != NULL) nDelete(&pGetCoeff(L->t_p));
267        if (L->t_p != NULL) pSetCoeff0(L->t_p,eins);
268        L->ecart = 0;
269        L->length = 1;
270        if (L->pLength > 0) L->pLength = 1;
271        if (L->last != NULL) L->last = p;
272
273        if (L->t_p != NULL && pNext(L->t_p) != NULL)
274          pNext(L->t_p) = NULL;
275        if (L->p != NULL && pNext(L->p) != NULL)
276          pNext(L->p) = NULL;
277        return;
278      }
279      i = 0;
280      loop
281      {
282        i++;
283        if (p_GetExp(p,i,r) > p_GetExp(h,i,r)) return ; // does not divide
284        if (i == r->N) break; // does divide, try next monom
285      }
286      pIter(h);
287    }
288  }
289}
290
291/*2
292*pp is the new element in s
293*returns TRUE (in strat->kHEdgeFound) if
294*-HEcke is allowed
295*-we are in the last componente of the vector
296*-on all axis are monomials (all elements in NotUsedAxis are FALSE)
297*returns FALSE for pLexOrderings,
298*assumes in module case an ordering of type c* !!
299* HEckeTest is only called with strat->kHEdgeFound==FALSE !
300*/
301void HEckeTest (poly pp,kStrategy strat)
302{
303  int   j,k,p;
304
305  strat->kHEdgeFound=FALSE;
306  if (pLexOrder || currRing->MixedOrder)
307  {
308    return;
309  }
310  if (strat->ak > 1)           /*we are in the module case*/
311  {
312    return; // until ....
313    //if (!pVectorOut)     /*pVectorOut <=> order = c,* */
314    //  return FALSE;
315    //if (pGetComp(pp) < strat->ak) /* ak is the number of the last component */
316    //  return FALSE;
317  }
318  k = 0;
319  p=pIsPurePower(pp);
320  if (p!=0) strat->NotUsedAxis[p] = FALSE;
321  /*- the leading term of pp is a power of the p-th variable -*/
322  for (j=pVariables;j>0; j--)
323  {
324    if (strat->NotUsedAxis[j])
325    {
326      return;
327    }
328  }
329  strat->kHEdgeFound=TRUE;
330}
331
332/*2
333*utilities for TSet, LSet
334*/
335inline static intset initec (const int maxnr)
336{
337  return (intset)omAlloc(maxnr*sizeof(int));
338}
339
340inline static unsigned long* initsevS (const int maxnr)
341{
342  return (unsigned long*)omAlloc0(maxnr*sizeof(unsigned long));
343}
344inline static int* initS_2_R (const int maxnr)
345{
346  return (int*)omAlloc0(maxnr*sizeof(int));
347}
348
349static inline void enlargeT (TSet &T, TObject** &R, unsigned long* &sevT,
350                             int &length, const int incr)
351{
352  assume(T!=NULL);
353  assume(sevT!=NULL);
354  assume(R!=NULL);
355  assume((length+incr) > 0);
356
357  int i;
358  T = (TSet)omRealloc0Size(T, length*sizeof(TObject),
359                           (length+incr)*sizeof(TObject));
360
361  sevT = (unsigned long*) omReallocSize(sevT, length*sizeof(long*),
362                           (length+incr)*sizeof(long*));
363
364  R = (TObject**)omRealloc0Size(R,length*sizeof(TObject*),
365                                (length+incr)*sizeof(TObject*));
366  for (i=length-1;i>=0;i--) R[T[i].i_r] = &(T[i]);
367  length += incr;
368}
369
370void cleanT (kStrategy strat)
371{
372  int i,j;
373  poly  p;
374  assume(currRing == strat->tailRing || strat->tailRing != NULL);
375
376  pShallowCopyDeleteProc p_shallow_copy_delete =
377    (strat->tailRing != currRing ?
378     pGetShallowCopyDeleteProc(strat->tailRing, currRing) :
379     NULL);
380
381  for (j=0; j<=strat->tl; j++)
382  {
383    p = strat->T[j].p;
384    strat->T[j].p=NULL;
385    if (strat->T[j].max != NULL)
386      p_LmFree(strat->T[j].max, strat->tailRing);
387    i = -1;
388    loop
389    {
390      i++;
391      if (i>strat->sl)
392      {
393        if (strat->T[j].t_p != NULL)
394        {
395          p_Delete(&(strat->T[j].t_p), strat->tailRing);
396          p_LmFree(p, currRing);
397        }
398        else
399          pDelete(&p);
400        break;
401      }
402      if (p == strat->S[i])
403      {
404        if (strat->T[j].t_p != NULL)
405        {
406          assume(p_shallow_copy_delete != NULL);
407          pNext(p) = p_shallow_copy_delete(pNext(p),strat->tailRing,currRing,
408                                           currRing->PolyBin);
409          p_LmFree(strat->T[j].t_p, strat->tailRing);
410        }
411        break;
412      }
413    }
414  }
415  strat->tl=-1;
416}
417
418//LSet initL ()
419//{
420//  int i;
421//  LSet l = (LSet)omAlloc(setmaxL*sizeof(LObject));
422//  return l;
423//}
424
425static inline void enlargeL (LSet* L,int* length,const int incr)
426{
427  assume((*L)!=NULL);
428  assume((length+incr)>0);
429
430  *L = (LSet)omReallocSize((*L),(*length)*sizeof(LObject),
431                                   ((*length)+incr)*sizeof(LObject));
432  (*length) += incr;
433}
434
435void initPairtest(kStrategy strat)
436{
437  strat->pairtest = (BOOLEAN *)omAlloc0((strat->sl+2)*sizeof(BOOLEAN));
438}
439
440/*2
441*test whether (p1,p2) or (p2,p1) is in L up position length
442*it returns TRUE if yes and the position k
443*/
444BOOLEAN isInPairsetL(int length,poly p1,poly p2,int*  k,kStrategy strat)
445{
446  LObject *p=&(strat->L[length]);
447
448  *k = length;
449  loop
450  {
451    if ((*k) < 0) return FALSE;
452    if (((p1 == (*p).p1) && (p2 == (*p).p2))
453    ||  ((p1 == (*p).p2) && (p2 == (*p).p1)))
454      return TRUE;
455    (*k)--;
456    p--;
457  }
458}
459
460/*2
461*in B all pairs have the same element p on the right
462*it tests whether (q,p) is in B and returns TRUE if yes
463*and the position k
464*/
465BOOLEAN isInPairsetB(poly q,int*  k,kStrategy strat)
466{
467  LObject *p=&(strat->B[strat->Bl]);
468
469  *k = strat->Bl;
470  loop
471  {
472    if ((*k) < 0) return FALSE;
473    if (q == (*p).p1)
474      return TRUE;
475    (*k)--;
476    p--;
477  }
478}
479
480int kFindInT(poly p, TSet T, int tlength)
481{
482  int i;
483
484  for (i=0; i<=tlength; i++)
485  {
486    if (T[i].p == p) return i;
487  }
488  return -1;
489}
490
491int kFindInT(poly p, kStrategy strat)
492{
493  int i;
494  do
495  {
496    i = kFindInT(p, strat->T, strat->tl);
497    if (i >= 0) return i;
498    strat = strat->next;
499  }
500  while (strat != NULL);
501  return -1;
502}
503
504#ifdef KDEBUG
505
506void sTObject::wrp()
507{
508  if (t_p != NULL) p_wrp(t_p, tailRing);
509  else if (p != NULL) p_wrp(p, currRing, tailRing);
510  else ::wrp(NULL);
511}
512
513#define kFalseReturn(x) do { if (!x) return FALSE;} while (0)
514
515// check that Lm's of a poly from T are "equal"
516static const char* kTest_LmEqual(poly p, poly t_p, ring tailRing)
517{
518  int i;
519  for (i=1; i<=tailRing->N; i++)
520  {
521    if (p_GetExp(p, i, currRing) != p_GetExp(t_p, i, tailRing))
522      return "Lm[i] different";
523  }
524  if (p_GetComp(p, currRing) != p_GetComp(t_p, tailRing))
525    return "Lm[0] different";
526  if (pNext(p) != pNext(t_p))
527    return "Lm.next different";
528  if (pGetCoeff(p) != pGetCoeff(t_p))
529    return "Lm.coeff different";
530  return NULL;
531}
532
533static BOOLEAN sloppy_max = FALSE;
534BOOLEAN kTest_T(TObject * T, ring strat_tailRing, int i, char TN)
535{
536  ring tailRing = T->tailRing;
537  if (strat_tailRing == NULL) strat_tailRing = tailRing;
538  r_assume(strat_tailRing == tailRing);
539
540  poly p = T->p;
541  ring r = currRing;
542
543  if (T->p == NULL && T->t_p == NULL && i >= 0)
544    return dReportError("%c[%d].poly is NULL", TN, i);
545
546  if (T->tailRing != currRing)
547  {
548    if (T->t_p == NULL && i > 0)
549      return dReportError("%c[%d].t_p is NULL", TN, i);
550    pFalseReturn(p_Test(T->t_p, T->tailRing));
551    if (T->p != NULL) pFalseReturn(p_LmTest(T->p, currRing));
552    if (T->p != NULL && T->t_p != NULL)
553    {
554      const char* msg = kTest_LmEqual(T->p, T->t_p, T->tailRing);
555      if (msg != NULL)
556        return dReportError("%c[%d] %s", TN, i, msg);
557      r = T->tailRing;
558      p = T->t_p;
559    }
560    if (T->p == NULL)
561    {
562      p = T->t_p;
563      r = T->tailRing;
564    }
565    if (T->t_p != NULL && i >= 0 && TN == 'T')
566    {
567      if (pNext(T->t_p) == NULL)
568      {
569        if (T->max != NULL)
570          return dReportError("%c[%d].max is not NULL as it should be", TN, i);
571      }
572      else
573      {
574        if (T->max == NULL)
575          return dReportError("%c[%d].max is NULL", TN, i);
576        if (pNext(T->max) != NULL)
577          return dReportError("pNext(%c[%d].max) != NULL", TN, i);
578
579        pFalseReturn(p_CheckPolyRing(T->max, tailRing));
580        omCheckBinAddrSize(T->max, (tailRing->PolyBin->sizeW)*SIZEOF_LONG);
581#if KDEBUG > 0
582        if (! sloppy_max)
583        {
584          poly test_max = p_GetMaxExpP(pNext(T->t_p), tailRing);
585          p_Setm(T->max, tailRing);
586          p_Setm(test_max, tailRing);
587          BOOLEAN equal = p_ExpVectorEqual(T->max, test_max, tailRing);
588          if (! equal)
589            return dReportError("%c[%d].max out of sync", TN, i);
590          p_LmFree(test_max, tailRing);
591        }
592#endif
593      }
594    }
595  }
596  else
597  {
598    if (T->max != NULL)
599      return dReportError("%c[%d].max != NULL but tailRing == currRing",TN,i);
600    if (T->t_p != NULL)
601      return dReportError("%c[%d].t_p != NULL but tailRing == currRing",TN,i);
602    if (T->p == NULL && i > 0)
603      return dReportError("%c[%d].p is NULL", TN, i);
604    pFalseReturn(p_Test(T->p, currRing));
605  }
606
607  if (i >= 0 && T->pLength != 0 && T->pLength != pLength(p))
608  {
609    return dReportError("%c[%d] pLength error: has %d, specified to have %d",
610                        TN, i , pLength(p), T->pLength);
611  }
612
613  // check FDeg,  for elements in L and T
614  if (i >= 0 && (TN == 'T' || TN == 'L'))
615  {
616    // FDeg has ir element from T of L set
617    if (T->FDeg  != T->pFDeg())
618      return dReportError("%c[%d] FDeg error: has %d, specified to have %d",
619                          TN, i , T->pFDeg(), T->FDeg);
620  }
621
622  // check is_normalized for elements in T
623  if (i >= 0 && TN == 'T')
624  {
625    if (T->is_normalized && ! nIsOne(pGetCoeff(p)))
626      return dReportError("T[%d] is_normalized error", i);
627
628  }
629  return TRUE;
630}
631
632BOOLEAN kTest_L(LObject *L, ring strat_tailRing,
633                BOOLEAN testp, int lpos, TSet T, int tlength)
634{
635  if (testp)
636  {
637    poly pn = NULL;
638    if (L->bucket != NULL)
639    {
640      kFalseReturn(kbTest(L->bucket));
641      r_assume(L->bucket->bucket_ring == L->tailRing);
642      if (L->p != NULL && pNext(L->p) != NULL)
643      {
644        pn = pNext(L->p);
645        pNext(L->p) = NULL;
646      }
647    }
648    kFalseReturn(kTest_T(L, strat_tailRing, lpos, 'L'));
649    if (pn != NULL)
650      pNext(L->p) = pn;
651
652    ring r;
653    poly p;
654    L->GetLm(p, r);
655    if (L->sev != 0 && p_GetShortExpVector(p, r) != L->sev)
656    {
657      return dReportError("L[%d] wrong sev: has %o, specified to have %o",
658                          lpos, p_GetShortExpVector(p, r), L->sev);
659    }
660    if (lpos > 0 && L->last != NULL && pLast(p) != L->last)
661    {
662      return dReportError("L[%d] last wrong: has %p specified to have %p",
663                          lpos, pLast(p), L->last);
664    }
665  }
666  if (L->p1 == NULL)
667  {
668    // L->p2 either NULL or "normal" poly
669    pFalseReturn(pp_Test(L->p2, currRing, L->tailRing));
670  }
671  else if (tlength > 0 && T != NULL && (lpos >=0))
672  {
673    // now p1 and p2 must be != NULL and must be contained in T
674    int i;
675    i = kFindInT(L->p1, T, tlength);
676    if (i < 0)
677      return dReportError("L[%d].p1 not in T",lpos);
678    i = kFindInT(L->p2, T, tlength);
679    if (i < 0)
680      return dReportError("L[%d].p2 not in T",lpos);
681  }
682  return TRUE;
683}
684
685BOOLEAN kTest (kStrategy strat)
686{
687  int i;
688
689  // test P
690  kFalseReturn(kTest_L(&(strat->P), strat->tailRing,
691                       (strat->P.p != NULL && pNext(strat->P.p)!=strat->tail),
692                       -1, strat->T, strat->tl));
693
694  // test T
695  if (strat->T != NULL)
696  {
697    for (i=0; i<=strat->tl; i++)
698    {
699      kFalseReturn(kTest_T(&(strat->T[i]), strat->tailRing, i, 'T'));
700      if (strat->sevT[i] != pGetShortExpVector(strat->T[i].p))
701        return dReportError("strat->sevT[%d] out of sync", i);
702    }
703  }
704
705  // test L
706  if (strat->L != NULL)
707  {
708    for (i=0; i<=strat->Ll; i++)
709    {
710      kFalseReturn(kTest_L(&(strat->L[i]), strat->tailRing,
711                           strat->L[i].Next() != strat->tail, i,
712                           strat->T, strat->tl));
713      if (strat->use_buckets && strat->L[i].Next() != strat->tail &&
714          strat->L[i].Next() != NULL && strat->L[i].p1 != NULL)
715      {
716        assume(strat->L[i].bucket != NULL);
717      }
718    }
719  }
720
721  // test S
722  if (strat->S != NULL)
723    kFalseReturn(kTest_S(strat));
724
725  return TRUE;
726}
727
728BOOLEAN kTest_S(kStrategy strat)
729{
730  int i;
731  BOOLEAN ret = TRUE;
732  for (i=0; i<=strat->sl; i++)
733  {
734    if (strat->S[i] != NULL &&
735        strat->sevS[i] != pGetShortExpVector(strat->S[i]))
736    {
737      return dReportError("S[%d] wrong sev: has %o, specified to have %o",
738                          i , pGetShortExpVector(strat->S[i]), strat->sevS[i]);
739    }
740  }
741  return ret;
742}
743
744
745
746BOOLEAN kTest_TS(kStrategy strat)
747{
748  int i, j;
749  BOOLEAN ret = TRUE;
750  kFalseReturn(kTest(strat));
751
752  // test strat->R, strat->T[i].i_r
753  for (i=0; i<=strat->tl; i++)
754  {
755    if (strat->T[i].i_r < 0 || strat->T[i].i_r > strat->tl)
756      return dReportError("strat->T[%d].i_r == %d out of bounds", i,
757                          strat->T[i].i_r);
758    if (strat->R[strat->T[i].i_r] != &(strat->T[i]))
759      return dReportError("T[%d].i_r with R out of sync", i);
760  }
761  // test containment of S inT
762  if (strat->S != NULL)
763  {
764    for (i=0; i<=strat->sl; i++)
765    {
766      j = kFindInT(strat->S[i], strat->T, strat->tl);
767      if (j < 0)
768        return dReportError("S[%d] not in T", i);
769      if (strat->S_2_R[i] != strat->T[j].i_r)
770        return dReportError("S_2_R[%d]=%d != T[%d].i_r=%d\n",
771                            i, strat->S_2_R[i], j, strat->T[j].i_r);
772    }
773  }
774  // test strat->L[i].i_r1
775  for (i=0; i<=strat->Ll; i++)
776  {
777    if (strat->L[i].p1 != NULL && strat->L[i].p2)
778    {
779      if (strat->L[i].i_r1 < 0 ||
780          strat->L[i].i_r1 > strat->tl ||
781          strat->L[i].T_1(strat)->p != strat->L[i].p1)
782        return dReportError("L[%d].i_r1 out of sync", i);
783      if (strat->L[i].i_r2 < 0 ||
784          strat->L[i].i_r2 > strat->tl ||
785          strat->L[i].T_2(strat)->p != strat->L[i].p2);
786    }
787    else
788    {
789      if (strat->L[i].i_r1 != -1)
790        return dReportError("L[%d].i_r1 out of sync", i);
791      if (strat->L[i].i_r2 != -1)
792        return dReportError("L[%d].i_r2 out of sync", i);
793    }
794    if (strat->L[i].i_r != -1)
795      return dReportError("L[%d].i_r out of sync", i);
796  }
797  return TRUE;
798}
799
800#endif // KDEBUG
801
802/*2
803*cancels the i-th polynomial in the standardbase s
804*/
805void deleteInS (int i,kStrategy strat)
806{
807#ifdef ENTER_USE_MEMMOVE
808  memmove(&(strat->S[i]), &(strat->S[i+1]), (strat->sl - i)*sizeof(poly));
809  memmove(&(strat->ecartS[i]),&(strat->ecartS[i+1]),(strat->sl - i)*sizeof(int));
810  memmove(&(strat->sevS[i]),&(strat->sevS[i+1]),(strat->sl - i)*sizeof(long));
811  memmove(&(strat->S_2_R[i]),&(strat->S_2_R[i+1]),(strat->sl - i)*sizeof(int));
812#else
813  int j;
814  for (j=i; j<strat->sl; j++)
815  {
816    strat->S[j] = strat->S[j+1];
817    strat->ecartS[j] = strat->ecartS[j+1];
818    strat->sevS[j] = strat->sevS[j+1];
819    strat->S_2_R[j] = strat->S_2_R[j+1];
820  }
821#endif
822  if (strat->lenS!=NULL)
823  {
824#ifdef ENTER_USE_MEMMOVE
825    memmove(&(strat->lenS[i]),&(strat->lenS[i+1]),(strat->sl - i)*sizeof(int));
826#else
827    for (j=i; j<strat->sl; j++) strat->lenS[j] = strat->lenS[j+1];
828#endif
829  }
830  if (strat->lenSw!=NULL)
831  {
832#ifdef ENTER_USE_MEMMOVE
833    memmove(&(strat->lenSw[i]),&(strat->lenSw[i+1]),(strat->sl - i)*sizeof(wlen_type));
834#else
835    for (j=i; j<strat->sl; j++) strat->lenSw[j] = strat->lenSw[j+1];
836#endif
837  }
838  if (strat->fromQ!=NULL)
839  {
840#ifdef ENTER_USE_MEMMOVE
841    memmove(&(strat->fromQ[i]),&(strat->fromQ[i+1]),(strat->sl - i)*sizeof(int));
842#else
843    for (j=i; j<strat->sl; j++)
844    {
845      strat->fromQ[j] = strat->fromQ[j+1];
846    }
847#endif
848  }
849  strat->S[strat->sl] = NULL;
850  strat->sl--;
851}
852
853/*2
854*cancels the j-th polynomial in the set
855*/
856void deleteInL (LSet set, int *length, int j,kStrategy strat)
857{
858  if (set[j].lcm!=NULL)
859    pLmFree(set[j].lcm);
860  if (set[j].p!=NULL)
861  {
862    if (pNext(set[j].p) == strat->tail)
863    {
864      pLmFree(set[j].p);
865      /*- tail belongs to several int spolys -*/
866    }
867    else
868    {
869      // search p in T, if it is there, do not delete it
870      if (pOrdSgn != -1 || kFindInT(set[j].p, strat) < 0)
871      {
872        // assure that for global ordereings kFindInT fails
873        assume(pOrdSgn == -1 || kFindInT(set[j].p, strat) < 0);
874        set[j].Delete();
875      }
876    }
877  }
878  if (*length > 0 && j < *length)
879  {
880#ifdef ENTER_USE_MEMMOVE
881    memmove(&(set[j]), &(set[j+1]), (*length - j)*sizeof(LObject));
882#else
883    int i;
884    for (i=j; i < (*length); i++)
885      set[i] = set[i+1];
886#endif
887  }
888#ifdef KDEBUG
889  memset(&(set[*length]),0,sizeof(LObject));
890#endif
891  (*length)--;
892}
893
894/*2
895*is used after updating the pairset,if the leading term of p
896*divides the leading term of some S[i] it will be canceled
897*/
898static inline void clearS (poly p, unsigned long p_sev, int* at, int* k,
899                    kStrategy strat)
900{
901  assume(p_sev == pGetShortExpVector(p));
902  if (strat->noClearS) return;
903  if (!pLmShortDivisibleBy(p,p_sev, strat->S[*at], ~ strat->sevS[*at])) return;
904  deleteInS((*at),strat);
905  (*at)--;
906  (*k)--;
907}
908
909/*2
910*enters p at position at in L
911*/
912#ifdef PDEBUG
913/* int zaehler=0; */
914/* for counting number of pairs in Plural */
915#endif /*PDEBUG*/
916
917void enterL (LSet *set,int *length, int *LSetmax, LObject p,int at)
918{
919#ifdef PDEBUG
920  /*  zaehler++; */
921#endif /*PDEBUG*/
922  int i;
923  // this should be corrected
924  assume(p.FDeg == p.pFDeg());
925
926  if ((*length)>=0)
927  {
928    if ((*length) == (*LSetmax)-1) enlargeL(set,LSetmax,setmaxLinc);
929    if (at <= (*length))
930#ifdef ENTER_USE_MEMMOVE
931      memmove(&((*set)[at+1]), &((*set)[at]), ((*length)-at+1)*sizeof(LObject));
932#else
933    for (i=(*length)+1; i>=at+1; i--) (*set)[i] = (*set)[i-1];
934#endif
935  }
936  else at = 0;
937  (*set)[at] = p;
938  (*length)++;
939}
940
941/*2
942* computes the normal ecart;
943* used in mora case and if pLexOrder & sugar in bba case
944*/
945void initEcartNormal (LObject* h)
946{
947  h->FDeg = h->pFDeg();
948  h->ecart = h->pLDeg() - h->FDeg;
949}
950
951void initEcartBBA (LObject* h)
952{
953  h->FDeg = h->pFDeg();
954  (*h).ecart = 0;
955  (*h).length = 0;
956}
957
958void initEcartPairBba (LObject* Lp,poly f,poly g,int ecartF,int ecartG)
959{
960  Lp->FDeg = Lp->pFDeg();
961  (*Lp).ecart = 0;
962  (*Lp).length = 0;
963}
964
965void initEcartPairMora (LObject* Lp,poly f,poly g,int ecartF,int ecartG)
966{
967  Lp->FDeg = Lp->pFDeg();
968  (*Lp).ecart = si_max(ecartF,ecartG);
969  (*Lp).ecart = (*Lp).ecart- (Lp->FDeg -pFDeg((*Lp).lcm,currRing));
970  (*Lp).length = 0;
971}
972
973/*2
974*if ecart1<=ecart2 it returns TRUE
975*/
976BOOLEAN sugarDivisibleBy(int ecart1, int ecart2)
977{
978  return (ecart1 <= ecart2);
979}
980
981#ifdef HAVE_RING2TOM
982/* TODO move to numbers.cc
983 */
984inline int nComp(long a, long b)
985{
986  assume(a != 0 && b != 0);
987  while (a % 2 == 0 && b % 2 == 0)
988  {
989    a = a / 2;
990    b = b / 2;
991  }
992  if (a % 2 == 0)
993  {
994    return -1;
995  }
996  else
997  {
998    if (b % 2 == 1) 
999    {
1000      return 0;
1001    }
1002    else
1003    {
1004      return 1;
1005    }
1006  }
1007}
1008
1009/*2
1010* put the pair (s[i],p)  into the set B, ecart=ecart(p) (ring case)
1011*/
1012void enterOnePairRing (int i,poly p,int ecart, int isFromQ,kStrategy strat, int atR = -1)
1013{
1014  assume(i<=strat->sl);
1015  int      l,j,compare,compareCoeff;
1016  LObject  Lp;
1017
1018  if (strat->interred_flag) return;
1019#ifdef KDEBUG
1020  Lp.ecart=0; Lp.length=0;
1021#endif
1022  /*- computes the lcm(s[i],p) -*/
1023  Lp.lcm = pInit();
1024
1025  pLcm(p,strat->S[i],Lp.lcm);
1026  pSetm(Lp.lcm);
1027  pSetCoeff(Lp.lcm, nLcm(pGetCoeff(p), pGetCoeff(strat->S[i]), currRing));
1028  if (strat->sugarCrit)
1029  {
1030        WarnS("Sugar Criterion not yet available on in the ring case");
1031  }
1032  else /*sugarcrit*/
1033  {
1034      // basic product criterion
1035      if (pHasNotCF(p,strat->S[i]) && (long) pGetCoeff(p) % 2 == 1 && (long) pGetCoeff(strat->S[i]) % 2 == 1)
1036      {
1037          strat->cp++;
1038          pLmFree(Lp.lcm);
1039          Lp.lcm=NULL;
1040          return;
1041      }
1042      if (strat->fromT) // && (strat->ecartS[i]>ecart))
1043      {
1044          WarnS("Sugar Criterion not yet available on in the ring case");
1045      }
1046      /*
1047      *the set B collects the pairs of type (S[j],p)
1048      *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
1049      *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
1050      *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
1051      */
1052      for(j = strat->Bl;j>=0;j--)
1053      {
1054        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
1055        compareCoeff = nComp((long) pGetCoeff(strat->B[j].lcm), (long) pGetCoeff(Lp.lcm));
1056        if (compareCoeff == 0 || compare == compareCoeff)
1057        {
1058          if (compare==1)
1059          {
1060            strat->c3++;
1061            if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1062            {
1063              pLmFree(Lp.lcm);
1064              return;
1065            }
1066            break;
1067          }
1068          else
1069          if (compare ==-1)
1070          {
1071            deleteInL(strat->B,&strat->Bl,j,strat);
1072            strat->c3++;
1073          }
1074        }
1075      }
1076    }
1077  /*
1078  *the pair (S[i],p) enters B if the spoly != 0
1079  */
1080  /*-  compute the short s-polynomial -*/
1081  if ((strat->S[i]==NULL) || (p==NULL)) return;
1082  pNorm(p);
1083  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (strat->fromQ[i]!=0))
1084  {
1085    WarnS("Oliver weiss nicht, was dieses genau macht.");
1086    Lp.p=NULL;
1087  }
1088  else
1089  {
1090    Lp.p = ksCreateShortSpoly(strat->S[i],p, strat->tailRing);
1091  }
1092  if (Lp.p == NULL)
1093  {
1094    /*- the case that the s-poly is 0 -*/
1095    if (strat->pairtest==NULL) initPairtest(strat);
1096    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
1097    strat->pairtest[strat->sl+1] = TRUE;
1098    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
1099    /*
1100    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
1101    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
1102    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
1103    *term of p devides the lcm(s,r)
1104    *(this canceling should be done here because
1105    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
1106    *the first case is handeled in chainCrit
1107    */
1108    if (Lp.lcm!=NULL) pLmFree(Lp.lcm);
1109  }
1110  else
1111  {
1112    /*- the pair (S[i],p) enters B -*/
1113    Lp.p1 = strat->S[i];
1114    Lp.p2 = p;
1115
1116    pNext(Lp.p) = strat->tail;
1117
1118    if (atR >= 0)
1119    {
1120      Lp.i_r2 = atR;
1121      Lp.i_r1 = strat->S_2_R[i];
1122    }
1123    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
1124    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
1125    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
1126  }
1127}
1128#endif
1129
1130/*2
1131* put the pair (s[i],p)  into the set B, ecart=ecart(p)
1132*/
1133
1134void enterOnePair (int i,poly p,int ecart, int isFromQ,kStrategy strat, int atR = -1)
1135{
1136  assume(i<=strat->sl);
1137  if (strat->interred_flag) return;
1138
1139  int      l,j,compare;
1140  LObject  Lp;
1141  Lp.i_r = -1;
1142
1143#ifdef KDEBUG
1144  Lp.ecart=0; Lp.length=0;
1145#endif
1146  /*- computes the lcm(s[i],p) -*/
1147  Lp.lcm = pInit();
1148
1149  pLcm(p,strat->S[i],Lp.lcm);
1150  pSetm(Lp.lcm);
1151  if (strat->sugarCrit)
1152  {
1153    if(
1154    (!((strat->ecartS[i]>0)&&(ecart>0)))
1155    && pHasNotCF(p,strat->S[i]))
1156    {
1157    /*
1158    *the product criterion has applied for (s,p),
1159    *i.e. lcm(s,p)=product of the leading terms of s and p.
1160    *Suppose (s,r) is in L and the leading term
1161    *of p divides lcm(s,r)
1162    *(==> the leading term of p divides the leading term of r)
1163    *but the leading term of s does not divide the leading term of r
1164    *(notice that tis condition is automatically satisfied if r is still
1165    *in S), then (s,r) can be cancelled.
1166    *This should be done here because the
1167    *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
1168    *
1169    *Moreover, skipping (s,r) holds also for the noncommutative case.
1170    */
1171      strat->cp++;
1172      pLmFree(Lp.lcm);
1173      Lp.lcm=NULL;
1174      return;
1175    }
1176    else
1177      Lp.ecart = si_max(ecart,strat->ecartS[i]);
1178    if (strat->fromT && (strat->ecartS[i]>ecart))
1179    {
1180      pLmFree(Lp.lcm);
1181      Lp.lcm=NULL;
1182      return;
1183      /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
1184    }
1185    /*
1186    *the set B collects the pairs of type (S[j],p)
1187    *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
1188    *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
1189    *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
1190    */
1191    {
1192      j = strat->Bl;
1193      loop
1194      {
1195        if (j < 0)  break;
1196        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
1197        if ((compare==1)
1198        &&(sugarDivisibleBy(strat->B[j].ecart,Lp.ecart)))
1199        {
1200          strat->c3++;
1201          if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1202          {
1203            pLmFree(Lp.lcm);
1204            return;
1205          }
1206          break;
1207        }
1208        else
1209        if ((compare ==-1)
1210        && sugarDivisibleBy(Lp.ecart,strat->B[j].ecart))
1211        {
1212          deleteInL(strat->B,&strat->Bl,j,strat);
1213          strat->c3++;
1214        }
1215        j--;
1216      }
1217    }
1218  }
1219  else /*sugarcrit*/
1220  {
1221#ifdef HAVE_PLURAL
1222    if (!rIsPluralRing(currRing))
1223    {
1224      // if currRing->nc_type!=quasi (or skew)
1225#endif
1226      if(/*(strat->ak==0) && productCrit(p,strat->S[i])*/
1227      pHasNotCF(p,strat->S[i]))
1228      {
1229      /*
1230      *the product criterion has applied for (s,p),
1231      *i.e. lcm(s,p)=product of the leading terms of s and p.
1232      *Suppose (s,r) is in L and the leading term
1233      *of p devides lcm(s,r)
1234      *(==> the leading term of p devides the leading term of r)
1235      *but the leading term of s does not devide the leading term of r
1236      *(notice that tis condition is automatically satisfied if r is still
1237      *in S), then (s,r) can be canceled.
1238      *This should be done here because the
1239      *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
1240      */
1241          strat->cp++;
1242          pLmFree(Lp.lcm);
1243          Lp.lcm=NULL;
1244          return;
1245      }
1246      if (strat->fromT && (strat->ecartS[i]>ecart))
1247      {
1248        pLmFree(Lp.lcm);
1249        Lp.lcm=NULL;
1250        return;
1251        /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
1252      }
1253      /*
1254      *the set B collects the pairs of type (S[j],p)
1255      *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
1256      *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
1257      *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
1258      */
1259      for(j = strat->Bl;j>=0;j--)
1260      {
1261        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
1262        if (compare==1)
1263        {
1264          strat->c3++;
1265          if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1266          {
1267            pLmFree(Lp.lcm);
1268            return;
1269          }
1270          break;
1271        }
1272        else
1273        if (compare ==-1)
1274        {
1275          deleteInL(strat->B,&strat->Bl,j,strat);
1276          strat->c3++;
1277        }
1278      }
1279    }
1280#ifdef HAVE_PLURAL
1281  }
1282#endif
1283  /*
1284  *the pair (S[i],p) enters B if the spoly != 0
1285  */
1286  /*-  compute the short s-polynomial -*/
1287  if (strat->fromT && !TEST_OPT_INTSTRATEGY)
1288    pNorm(p);
1289  if ((strat->S[i]==NULL) || (p==NULL))
1290    return;
1291  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (strat->fromQ[i]!=0))
1292    Lp.p=NULL;
1293  else
1294  {
1295#ifdef HAVE_PLURAL
1296    if (currRing->nc!=NULL)
1297    {
1298      if ((currRing->nc->type==nc_lie) && (pHasNotCF(p,strat->S[i])))
1299        /* generalized prod-crit for lie-type */
1300      {
1301          strat->cp++;
1302          Lp.p = nc_p_Bracket_qq(pCopy(p),strat->S[i]);
1303      }
1304      else  Lp.p = nc_CreateSpoly(strat->S[i],p,NULL,currRing);
1305    }
1306    else
1307    {
1308#endif
1309    Lp.p = ksCreateShortSpoly(strat->S[i],p, strat->tailRing);
1310#ifdef HAVE_PLURAL
1311    }
1312#endif
1313  }
1314  if (Lp.p == NULL)
1315  {
1316    /*- the case that the s-poly is 0 -*/
1317    if (strat->pairtest==NULL) initPairtest(strat);
1318    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
1319    strat->pairtest[strat->sl+1] = TRUE;
1320    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
1321    /*
1322    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
1323    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
1324    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
1325    *term of p devides the lcm(s,r)
1326    *(this canceling should be done here because
1327    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
1328    *the first case is handeled in chainCrit
1329    */
1330    if (Lp.lcm!=NULL) pLmFree(Lp.lcm);
1331  }
1332  else
1333  {
1334    /*- the pair (S[i],p) enters B -*/
1335    Lp.p1 = strat->S[i];
1336    Lp.p2 = p;
1337
1338#ifdef HAVE_PLURAL
1339    if (currRing->nc==NULL)
1340    {
1341#endif
1342
1343     pNext(Lp.p) = strat->tail;
1344
1345#ifdef HAVE_PLURAL
1346    }
1347#endif
1348
1349    if (atR >= 0)
1350    {
1351      Lp.i_r1 = strat->S_2_R[i];
1352      Lp.i_r2 = atR;
1353    }
1354    else
1355    {
1356      Lp.i_r1 = -1;
1357      Lp.i_r2 = -1;
1358    }
1359    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
1360    if (TEST_OPT_INTSTRATEGY)
1361    {
1362
1363#ifdef HAVE_PLURAL
1364      if (currRing->nc==NULL)
1365      {
1366#endif
1367
1368      nDelete(&(Lp.p->coef));
1369
1370#ifdef HAVE_PLURAL
1371      }
1372#endif
1373
1374    }
1375    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
1376    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
1377  }
1378}
1379
1380/*2
1381* put the pair (s[i],p) into the set L, ecart=ecart(p)
1382* in the case that s forms a SB of (s)
1383*/
1384void enterOnePairSpecial (int i,poly p,int ecart,kStrategy strat, int atR = -1)
1385{
1386  //PrintS("try ");wrp(strat->S[i]);PrintS(" and ");wrp(p);PrintLn();
1387  if(pHasNotCF(p,strat->S[i]))
1388  {
1389    //PrintS("prod-crit\n");
1390      if (!rIsPluralRing(currRing))
1391      {
1392        strat->cp++;
1393        return;
1394      }
1395  }
1396
1397  int      l,j,compare;
1398  LObject  Lp;
1399  Lp.i_r = -1;
1400
1401  Lp.lcm = pInit();
1402  pLcm(p,strat->S[i],Lp.lcm);
1403  pSetm(Lp.lcm);
1404  for(j = strat->Ll;j>=0;j--)
1405  {
1406    compare=pDivComp(strat->L[j].lcm,Lp.lcm);
1407    if ((compare==1) || (pLmEqual(strat->L[j].lcm,Lp.lcm)))
1408    {
1409      //PrintS("c3-crit\n");
1410      strat->c3++;
1411      pLmFree(Lp.lcm);
1412      return;
1413    }
1414    else if (compare ==-1)
1415    {
1416      //Print("c3-crit with L[%d]\n",j);
1417      deleteInL(strat->L,&strat->Ll,j,strat);
1418      strat->c3++;
1419    }
1420  }
1421  /*-  compute the short s-polynomial -*/
1422
1423  Lp.p = ksCreateShortSpoly(strat->S[i],p,strat->tailRing);
1424  if (Lp.p == NULL)
1425  {
1426     pLmFree(Lp.lcm);
1427  }
1428  else
1429  {
1430    /*- the pair (S[i],p) enters L -*/
1431    Lp.p1 = strat->S[i];
1432    Lp.p2 = p;
1433    if (atR >= 0)
1434    {
1435      Lp.i_r1 = strat->S_2_R[i];
1436      Lp.i_r2 = atR;
1437    }
1438    else
1439    {
1440      Lp.i_r1 = -1;
1441      Lp.i_r2 = -1;
1442    }
1443    pNext(Lp.p) = strat->tail;
1444    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
1445    if (TEST_OPT_INTSTRATEGY)
1446    {
1447      nDelete(&(Lp.p->coef));
1448    }
1449    l = strat->posInL(strat->L,strat->Ll,&Lp,strat);
1450    //Print("-> L[%d]\n",l);
1451    enterL(&strat->L,&strat->Ll,&strat->Lmax,Lp,l);
1452  }
1453}
1454
1455/*2
1456*the pairset B of pairs of type (s[i],p) is complete now. It will be updated
1457*using the chain-criterion in B and L and enters B to L
1458*/
1459void chainCrit (poly p,int ecart,kStrategy strat)
1460{
1461  int i,j,l;
1462
1463  /*
1464  *pairtest[i] is TRUE if spoly(S[i],p) == 0.
1465  *In this case all elements in B such
1466  *that their lcm is divisible by the leading term of S[i] can be canceled
1467  */
1468  if (strat->pairtest!=NULL)
1469  {
1470    {
1471      /*- i.e. there is an i with pairtest[i]==TRUE -*/
1472      for (j=0; j<=strat->sl; j++)
1473      {
1474        if (strat->pairtest[j])
1475        {
1476          for (i=strat->Bl; i>=0; i--)
1477          {
1478            if (pDivisibleBy(strat->S[j],strat->B[i].lcm))
1479            {
1480              deleteInL(strat->B,&strat->Bl,i,strat);
1481              strat->c3++;
1482            }
1483          }
1484        }
1485      }
1486    }
1487    omFreeSize(strat->pairtest,(strat->sl+2)*sizeof(BOOLEAN));
1488    strat->pairtest=NULL;
1489  }
1490  if (strat->Gebauer || strat->fromT)
1491  {
1492    if (strat->sugarCrit)
1493    {
1494    /*
1495    *suppose L[j] == (s,r) and p/lcm(s,r)
1496    *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
1497    *and in case the sugar is o.k. then L[j] can be canceled
1498    */
1499      for (j=strat->Ll; j>=0; j--)
1500      {
1501        if (sugarDivisibleBy(ecart,strat->L[j].ecart)
1502        && ((pNext(strat->L[j].p) == strat->tail) || (pOrdSgn==1))
1503        && pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1504        {
1505          if (strat->L[j].p == strat->tail)
1506          {
1507              deleteInL(strat->L,&strat->Ll,j,strat);
1508              strat->c3++;
1509          }
1510        }
1511      }
1512      /*
1513      *this is GEBAUER-MOELLER:
1514      *in B all elements with the same lcm except the "best"
1515      *(i.e. the last one in B with this property) will be canceled
1516      */
1517      j = strat->Bl;
1518      loop /*cannot be changed into a for !!! */
1519      {
1520        if (j <= 0) break;
1521        i = j-1;
1522        loop
1523        {
1524          if (i <  0) break;
1525          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
1526          {
1527            strat->c3++;
1528            if (sugarDivisibleBy(strat->B[j].ecart,strat->B[i].ecart))
1529            {
1530              deleteInL(strat->B,&strat->Bl,i,strat);
1531              j--;
1532            }
1533            else
1534            {
1535              deleteInL(strat->B,&strat->Bl,j,strat);
1536              break;
1537            }
1538          }
1539          i--;
1540        }
1541        j--;
1542      }
1543    }
1544    else /*sugarCrit*/
1545    {
1546      /*
1547      *suppose L[j] == (s,r) and p/lcm(s,r)
1548      *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
1549      *and in case the sugar is o.k. then L[j] can be canceled
1550      */
1551      for (j=strat->Ll; j>=0; j--)
1552      {
1553        if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1554        {
1555          if ((pNext(strat->L[j].p) == strat->tail)||(pOrdSgn==1))
1556          {
1557            deleteInL(strat->L,&strat->Ll,j,strat);
1558            strat->c3++;
1559          }
1560        }
1561      }
1562      /*
1563      *this is GEBAUER-MOELLER:
1564      *in B all elements with the same lcm except the "best"
1565      *(i.e. the last one in B with this property) will be canceled
1566      */
1567      j = strat->Bl;
1568      loop   /*cannot be changed into a for !!! */
1569      {
1570        if (j <= 0) break;
1571        for(i=j-1; i>=0; i--)
1572        {
1573          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
1574          {
1575            strat->c3++;
1576            deleteInL(strat->B,&strat->Bl,i,strat);
1577            j--;
1578          }
1579        }
1580        j--;
1581      }
1582    }
1583    /*
1584    *the elements of B enter L/their order with respect to B is kept
1585    *j = posInL(L,j,B[i]) would permutate the order
1586    *if once B is ordered different from L
1587    *then one should use j = posInL(L,Ll,B[i])
1588    */
1589    j = strat->Ll+1;
1590    for (i=strat->Bl; i>=0; i--)
1591    {
1592      j = strat->posInL(strat->L,j-1,&(strat->B[i]),strat);
1593      enterL(&strat->L,&strat->Ll,&strat->Lmax,strat->B[i],j);
1594    }
1595    strat->Bl = -1;
1596  }
1597  else
1598  {
1599    for (j=strat->Ll; j>=0; j--)
1600    {
1601      if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1602      {
1603        if ((pNext(strat->L[j].p) == strat->tail)||(pOrdSgn==1))
1604        {
1605          deleteInL(strat->L,&strat->Ll,j,strat);
1606          strat->c3++;
1607        }
1608      }
1609    }
1610    /*
1611    *this is our MODIFICATION of GEBAUER-MOELLER:
1612    *First the elements of B enter L,
1613    *then we fix a lcm and the "best" element in L
1614    *(i.e the last in L with this lcm and of type (s,p))
1615    *and cancel all the other elements of type (r,p) with this lcm
1616    *except the case the element (s,r) has also the same lcm
1617    *and is on the worst position with respect to (s,p) and (r,p)
1618    */
1619    /*
1620    *B enters to L/their order with respect to B is permutated for elements
1621    *B[i].p with the same leading term
1622    */
1623    j = strat->Ll;
1624    for (i=strat->Bl; i>=0; i--)
1625    {
1626      j = strat->posInL(strat->L,j,&(strat->B[i]),strat);
1627      enterL(&strat->L,&strat->Ll,&strat->Lmax,strat->B[i],j);
1628    }
1629    strat->Bl = -1;
1630    j = strat->Ll;
1631    loop  /*cannot be changed into a for !!! */
1632    {
1633      if (j <= 0)
1634      {
1635        /*now L[0] cannot be canceled any more and the tail can be removed*/
1636        if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
1637        break;
1638      }
1639      if (strat->L[j].p2 == p)
1640      {
1641        i = j-1;
1642        loop
1643        {
1644          if (i < 0)  break;
1645          if ((strat->L[i].p2 == p) && pLmEqual(strat->L[j].lcm,strat->L[i].lcm))
1646          {
1647            /*L[i] could be canceled but we search for a better one to cancel*/
1648            strat->c3++;
1649            if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
1650            && (pNext(strat->L[l].p) == strat->tail)
1651            && (!pLmEqual(strat->L[i].p,strat->L[l].p))
1652            && pDivisibleBy(p,strat->L[l].lcm))
1653            {
1654              /*
1655              *"NOT equal(...)" because in case of "equal" the element L[l]
1656              *is "older" and has to be from theoretical point of view behind
1657              *L[i], but we do not want to reorder L
1658              */
1659              strat->L[i].p2 = strat->tail;
1660              /*
1661              *L[l] will be canceled, we cannot cancel L[i] later on,
1662              *so we mark it with "tail"
1663              */
1664              deleteInL(strat->L,&strat->Ll,l,strat);
1665              i--;
1666            }
1667            else
1668            {
1669              deleteInL(strat->L,&strat->Ll,i,strat);
1670            }
1671            j--;
1672          }
1673          i--;
1674        }
1675      }
1676      else if (strat->L[j].p2 == strat->tail)
1677      {
1678        /*now L[j] cannot be canceled any more and the tail can be removed*/
1679        strat->L[j].p2 = p;
1680      }
1681      j--;
1682    }
1683  }
1684}
1685
1686/*2
1687*(s[0],h),...,(s[k],h) will be put to the pairset L
1688*/
1689void initenterpairs (poly h,int k,int ecart,int isFromQ,kStrategy strat, int atR = -1)
1690{
1691
1692  if ((strat->syzComp==0)
1693  || (pGetComp(h)<=strat->syzComp))
1694  {
1695    int j;
1696    BOOLEAN new_pair=FALSE;
1697
1698    if (pGetComp(h)==0)
1699    {
1700      /* for Q!=NULL: build pairs (f,q),(f1,f2), but not (q1,q2)*/
1701      if ((isFromQ)&&(strat->fromQ!=NULL))
1702      {
1703        for (j=0; j<=k; j++)
1704        {
1705          if (!strat->fromQ[j])
1706          {
1707            new_pair=TRUE;
1708            enterOnePair(j,h,ecart,isFromQ,strat, atR);
1709          //Print("j:%d, Ll:%d\n",j,strat->Ll);
1710          }
1711        }
1712      }
1713      else
1714      {
1715        new_pair=TRUE;
1716        for (j=0; j<=k; j++)
1717        {
1718          enterOnePair(j,h,ecart,isFromQ,strat, atR);
1719          //Print("j:%d, Ll:%d\n",j,strat->Ll);
1720        }
1721      }
1722    }
1723    else
1724    {
1725      for (j=0; j<=k; j++)
1726      {
1727        if ((pGetComp(h)==pGetComp(strat->S[j]))
1728        || (pGetComp(strat->S[j])==0))
1729        {
1730          new_pair=TRUE;
1731          enterOnePair(j,h,ecart,isFromQ,strat, atR);
1732        //Print("j:%d, Ll:%d\n",j,strat->Ll);
1733        }
1734      }
1735    }
1736
1737    if (new_pair) chainCrit(h,ecart,strat);
1738
1739  }
1740}
1741
1742#ifdef HAVE_RING2TOM
1743/*2
1744*the pairset B of pairs of type (s[i],p) is complete now. It will be updated
1745*using the chain-criterion in B and L and enters B to L
1746*/
1747void chainCritRing (poly p,int ecart,kStrategy strat)
1748{
1749  int i,j,l;
1750
1751  /*
1752  *pairtest[i] is TRUE if spoly(S[i],p) == 0.
1753  *In this case all elements in B such
1754  *that their lcm is divisible by the leading term of S[i] can be canceled
1755  */
1756  if (strat->pairtest!=NULL)
1757  {
1758    {
1759      /*- i.e. there is an i with pairtest[i]==TRUE -*/
1760      for (j=0; j<=strat->sl; j++)
1761      {
1762        if (strat->pairtest[j])
1763        {
1764          for (i=strat->Bl; i>=0; i--)
1765          {
1766            if (pDivisibleBy(strat->S[j],strat->B[i].lcm))
1767            {
1768              deleteInL(strat->B,&strat->Bl,i,strat);
1769              strat->c3++;
1770            }
1771          }
1772        }
1773      }
1774    }
1775    omFreeSize(strat->pairtest,(strat->sl+2)*sizeof(BOOLEAN));
1776    strat->pairtest=NULL;
1777  }
1778  if (strat->Gebauer || strat->fromT)
1779  {
1780    WarnS("Gebauer or fromT not tested yet in chainCritRing.");
1781    if (strat->sugarCrit)
1782    {
1783        WarnS("Sugar Criterion not yet available for coefficient rings.");
1784    }
1785    else /*sugarCrit*/
1786    {
1787      /*
1788      *suppose L[j] == (s,r) and p/lcm(s,r)
1789      *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
1790      *and in case the sugar is o.k. then L[j] can be canceled
1791      */
1792      for (j=strat->Ll; j>=0; j--)
1793      {
1794        if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1795        {
1796          if ((pNext(strat->L[j].p) == strat->tail)||(pOrdSgn==1))
1797          {
1798            deleteInL(strat->L,&strat->Ll,j,strat);
1799            strat->c3++;
1800          }
1801        }
1802      }
1803      /*
1804      *this is GEBAUER-MOELLER:
1805      *in B all elements with the same lcm except the "best"
1806      *(i.e. the last one in B with this property) will be canceled
1807      */
1808      j = strat->Bl;
1809      loop   /*cannot be changed into a for !!! */
1810      {
1811        if (j <= 0) break;
1812        for(i=j-1; i>=0; i--)
1813        {
1814          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
1815          {
1816            strat->c3++;
1817            deleteInL(strat->B,&strat->Bl,i,strat);
1818            j--;
1819          }
1820        }
1821        j--;
1822      }
1823    }
1824    /*
1825    *the elements of B enter L/their order with respect to B is kept
1826    *j = posInL(L,j,B[i]) would permutate the order
1827    *if once B is ordered different from L
1828    *then one should use j = posInL(L,Ll,B[i])
1829    */
1830    j = strat->Ll+1;
1831    for (i=strat->Bl; i>=0; i--)
1832    {
1833      j = strat->posInL(strat->L,j-1,&(strat->B[i]),strat);
1834      enterL(&strat->L,&strat->Ll,&strat->Lmax,strat->B[i],j);
1835    }
1836    strat->Bl = -1;
1837  }
1838  else /* Gebauer or fromT */
1839  {
1840    for (j=strat->Ll; j>=0; j--)
1841    {
1842      if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1843      {
1844        if ((pNext(strat->L[j].p) == strat->tail)||(pOrdSgn==1))
1845        {
1846          deleteInL(strat->L,&strat->Ll,j,strat);
1847          strat->c3++;
1848        }
1849      }
1850    }
1851    /*
1852    *this is our MODIFICATION of GEBAUER-MOELLER:
1853    *First the elements of B enter L,
1854    *then we fix a lcm and the "best" element in L
1855    *(i.e the last in L with this lcm and of type (s,p))
1856    *and cancel all the other elements of type (r,p) with this lcm
1857    *except the case the element (s,r) has also the same lcm
1858    *and is on the worst position with respect to (s,p) and (r,p)
1859    */
1860    /*
1861    *B enters to L/their order with respect to B is permutated for elements
1862    *B[i].p with the same leading term
1863    */
1864    j = strat->Ll;
1865    for (i=strat->Bl; i>=0; i--)
1866    {
1867      j = strat->posInL(strat->L,j,&(strat->B[i]),strat);
1868      enterL(&strat->L,&strat->Ll,&strat->Lmax,strat->B[i],j);
1869    }
1870    strat->Bl = -1;
1871    j = strat->Ll;
1872    loop  /*cannot be changed into a for !!! */
1873    {
1874      if (j <= 0)
1875      {
1876        /*now L[0] cannot be canceled any more and the tail can be removed*/
1877        if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
1878        break;
1879      }
1880      if (strat->L[j].p2 == p)
1881      {
1882        i = j-1;
1883        loop
1884        {
1885          if (i < 0)  break;
1886          if ((strat->L[i].p2 == p) && pLmEqual(strat->L[j].lcm,strat->L[i].lcm))
1887          {
1888            /*L[i] could be canceled but we search for a better one to cancel*/
1889            strat->c3++;
1890            if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
1891            && (pNext(strat->L[l].p) == strat->tail)
1892            && (!pLmEqual(strat->L[i].p,strat->L[l].p))
1893            && pDivisibleBy(p,strat->L[l].lcm))
1894            {
1895              /*
1896              *"NOT equal(...)" because in case of "equal" the element L[l]
1897              *is "older" and has to be from theoretical point of view behind
1898              *L[i], but we do not want to reorder L
1899              */
1900              strat->L[i].p2 = strat->tail;
1901              /*
1902              *L[l] will be canceled, we cannot cancel L[i] later on,
1903              *so we mark it with "tail"
1904              */
1905              deleteInL(strat->L,&strat->Ll,l,strat);
1906              i--;
1907            }
1908            else
1909            {
1910              deleteInL(strat->L,&strat->Ll,i,strat);
1911            }
1912            j--;
1913          }
1914          i--;
1915        }
1916      }
1917      else if (strat->L[j].p2 == strat->tail)
1918      {
1919        /*now L[j] cannot be canceled any more and the tail can be removed*/
1920        strat->L[j].p2 = p;
1921      }
1922      j--;
1923    }
1924  }
1925}
1926
1927long twoPow(long arg)
1928{
1929  return 1L << arg;
1930}
1931
1932/*2
1933*(s[0],h),...,(s[k],h) will be put to the pairset L
1934*/
1935void initenterpairsRing (poly h,int k,int ecart,int isFromQ,kStrategy strat, int atR = -1)
1936{
1937
1938  if ((strat->syzComp==0) || (pGetComp(h)<=strat->syzComp))
1939  {
1940    int j;
1941    BOOLEAN new_pair=FALSE;
1942
1943    if (pGetComp(h)==0)
1944    {
1945      /* for Q!=NULL: build pairs (f,q),(f1,f2), but not (q1,q2)*/
1946      if ((isFromQ)&&(strat->fromQ!=NULL))
1947      {
1948        for (j=0; j<=k; j++)
1949        {
1950          if (!strat->fromQ[j])
1951          {
1952            new_pair=TRUE;
1953            enterOnePairRing(j,h,ecart,isFromQ,strat, atR);
1954            //Print("j:%d, Ll:%d\n",j,strat->Ll);
1955          }
1956        }
1957      }
1958      else
1959      {
1960        new_pair=TRUE;
1961        for (j=0; j<=k; j++)
1962        {
1963          enterOnePairRing(j,h,ecart,isFromQ,strat, atR);
1964          //Print("j:%d, Ll:%d\n",j,strat->Ll);
1965        }
1966      }
1967    }
1968    else
1969    {
1970      for (j=0; j<=k; j++)
1971      {
1972        if ((pGetComp(h)==pGetComp(strat->S[j])) || (pGetComp(strat->S[j])==0))
1973        {
1974          new_pair=TRUE;
1975          enterOnePairRing(j,h,ecart,isFromQ,strat, atR);
1976          //Print("j:%d, Ll:%d\n",j,strat->Ll);
1977        }
1978      }
1979    }
1980
1981    if (new_pair) chainCrit(h,ecart,strat);
1982
1983  }
1984/*
1985ring r=256,(x,y,z),dp;
1986ideal I=12xz-133y, 2xy-z;
1987*/
1988
1989}
1990
1991/*2
1992* Generates spoly(0, h) if applicable. Assumes ring in Z/2^n.
1993*/
1994void enterExtendedSpoly(poly h,kStrategy strat)
1995{
1996  if (((long) ((h)->coef)) % 2 == 0)
1997  {
1998    long a = ((long) ((h)->coef)) / 2;
1999    long b = currRing->ch - 1;
2000    poly p = p_Copy(h->next, strat->tailRing);
2001    while (a % 2 == 0)
2002    {
2003      a = a / 2;
2004      b--;
2005    }
2006    p = p_Mult_nn(p, (number) twoPow(b), strat->tailRing);
2007
2008    if (p != NULL)
2009    {
2010      if (TEST_OPT_PROT)
2011      {
2012        PrintS("Z");
2013      }
2014      poly tmp = p_ISet((long) ((p)->coef), currRing);
2015      for (int i = 1; i <= currRing->N; i++) {
2016        pSetExp(tmp, i, p_GetExp(p, i, strat->tailRing));
2017      }
2018      p_Setm(tmp, currRing);
2019      p = p_LmDeleteAndNext(p, strat->tailRing);
2020      pNext(tmp) = p;
2021
2022      LObject h;
2023      h.p = tmp;
2024      h.tailRing = strat->tailRing;
2025      if (TEST_OPT_INTSTRATEGY)
2026      {
2027        //pContent(h.p);
2028        h.pCleardenom(); // also does a pContent
2029      }
2030      else
2031      {
2032        h.pNorm();
2033      }
2034      strat->initEcart(&h);
2035      int posx;
2036      if (h.p!=NULL)
2037      {
2038        if (strat->Ll==-1)
2039          posx =0;
2040        else
2041          posx = strat->posInL(strat->L,strat->Ll,&h,strat);
2042        h.sev = pGetShortExpVector(h.p);
2043        h.t_p = k_LmInit_currRing_2_tailRing(h.p, strat->tailRing);
2044        if (pNext(p) != NULL)
2045        {
2046          pShallowCopyDeleteProc p_shallow_copy_delete
2047               = pGetShallowCopyDeleteProc(strat->tailRing, new_tailRing);
2048          pNext(p) = p_shallow_copy_delete(pNext(p),
2049                       currRing, strat->tailRing, strat->tailRing->PolyBin);
2050        }
2051        enterL(&strat->L,&strat->Ll,&strat->Lmax,h,posx);
2052      }
2053    }
2054  }
2055}
2056
2057void clearSbatch (poly h,int k,int pos,kStrategy strat)
2058{
2059  int j = pos;
2060  if ( (!strat->fromT)
2061  && ((strat->syzComp==0)
2062    ||(pGetComp(h)<=strat->syzComp)))
2063  {
2064    //Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
2065    unsigned long h_sev = pGetShortExpVector(h);
2066    loop
2067    {
2068      if (j > k) break;
2069      clearS(h,h_sev, &j,&k,strat);
2070      j++;
2071    }
2072    //Print("end clearS sl=%d\n",strat->sl);
2073  }
2074}
2075
2076/*2
2077* Generates a sufficient set of spolys (maybe just a finite generating
2078* set of the syzygys)
2079*/
2080void superenterpairs (poly h,int k,int ecart,int pos,kStrategy strat, int atR)
2081{
2082  if (currRing->cring == 1)
2083  {
2084    // enter also zero divisor * poly, if this is non zero and of smaller degree
2085    enterExtendedSpoly(h, strat);
2086    initenterpairsRing(h, k, ecart, 0, strat, atR);
2087  }
2088  else 
2089  {
2090    initenterpairs(h, k, ecart, 0, strat, atR);
2091  }
2092  clearSbatch(h, k, pos, strat);
2093}
2094#endif
2095
2096/*2
2097*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
2098*superfluous elements in S will be deleted
2099*/
2100void enterpairs (poly h,int k,int ecart,int pos,kStrategy strat, int atR)
2101{
2102  int j=pos;
2103
2104  initenterpairs(h,k,ecart,0,strat, atR);
2105  if ( (!strat->fromT)
2106  && ((strat->syzComp==0)
2107    ||(pGetComp(h)<=strat->syzComp)))
2108  {
2109    //Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
2110    unsigned long h_sev = pGetShortExpVector(h);
2111    loop
2112    {
2113      if (j > k) break;
2114      clearS(h,h_sev, &j,&k,strat);
2115      j++;
2116    }
2117    //Print("end clearS sl=%d\n",strat->sl);
2118  }
2119 // PrintS("end enterpairs\n");
2120}
2121
2122/*2
2123*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
2124*superfluous elements in S will be deleted
2125*/
2126void enterpairsSpecial (poly h,int k,int ecart,int pos,kStrategy strat, int atR = -1)
2127{
2128  int j;
2129
2130  for (j=0; j<=k; j++)
2131  {
2132    if ((pGetComp(h)==pGetComp(strat->S[j]))
2133    || (0==pGetComp(strat->S[j])))
2134    {
2135      enterOnePairSpecial(j,h,ecart,strat, atR);
2136    }
2137  }
2138  j=pos;
2139  loop
2140  {
2141    unsigned long h_sev = pGetShortExpVector(h);
2142    if (j > k) break;
2143    clearS(h,h_sev,&j,&k,strat);
2144    j++;
2145  }
2146}
2147
2148/*2
2149*constructs the pairset at the beginning
2150*of the buchberger/mora algorithm
2151*/
2152void pairs (kStrategy strat)
2153{
2154  int j,i;
2155//  Print("pairs:sl=%d\n",strat->sl);
2156//  for (i=0; i<=strat->sl; i++)
2157//  {
2158//    Print("s%d:",i);pWrite(strat->S[i]);
2159//  }
2160  if (strat->fromQ!=NULL)
2161  {
2162    for (i=1; i<=strat->sl; i++)
2163    {
2164      initenterpairs(strat->S[i],i-1,strat->ecartS[i],strat->fromQ[i],strat);
2165    }
2166  }
2167  else
2168  {
2169    for (i=1; i<=strat->sl; i++)
2170    {
2171      initenterpairs(strat->S[i],i-1,strat->ecartS[i],0,strat);
2172    }
2173  }
2174  /*deletes superfluous elements in S*/
2175  i = -1;
2176  loop
2177  {
2178    i++;
2179    if (i >= strat->sl) break;
2180    if ((strat->syzComp==0) || (pGetComp(strat->S[i])<=strat->syzComp))
2181    {
2182      j=i;
2183      loop
2184      {
2185        j++;
2186        if (j > strat->sl) break;
2187        if (pLmShortDivisibleBy(strat->S[i], strat->sevS[i],
2188                              strat->S[j], ~ strat->sevS[j]))
2189        {
2190        //  Print("delete %d=",j);
2191        //  wrp(strat->S[j]);
2192        //  Print(" wegen %d=",i);
2193        //  wrp(strat->S[i]);
2194        //  Print("( fromQ=%d)\n", (strat->fromQ) ? strat->fromQ[j]:0);
2195          if ((strat->fromQ==NULL) || (strat->fromQ[j]==0))
2196          {
2197            deleteInS(j,strat);
2198            j--;
2199          }
2200        }
2201      }
2202    }
2203  }
2204}
2205
2206/*2
2207*reorders  s with respect to posInS,
2208*suc is the first changed index or zero
2209*/
2210void reorderS (int* suc,kStrategy strat)
2211{
2212  int i,j,at,ecart, s2r;
2213  int fq=0;
2214  unsigned long sev;
2215  poly  p;
2216
2217  *suc = -1;
2218  for (i=1; i<=strat->sl; i++)
2219  {
2220    at = posInS(strat,i-1,strat->S[i],strat->ecartS[i]);
2221    if (at != i)
2222    {
2223      if ((*suc > at) || (*suc == -1)) *suc = at;
2224      p = strat->S[i];
2225      ecart = strat->ecartS[i];
2226      sev = strat->sevS[i];
2227      s2r = strat->S_2_R[i];
2228      if (strat->fromQ!=NULL) fq=strat->fromQ[i];
2229      for (j=i; j>=at+1; j--)
2230      {
2231        strat->S[j] = strat->S[j-1];
2232        strat->ecartS[j] = strat->ecartS[j-1];
2233        strat->sevS[j] = strat->sevS[j-1];
2234        strat->S_2_R[j] = strat->S_2_R[j-1];
2235      }
2236      strat->S[at] = p;
2237      strat->ecartS[at] = ecart;
2238      strat->sevS[at] = sev;
2239      strat->S_2_R[at] = s2r;
2240      if (strat->fromQ!=NULL)
2241      {
2242        for (j=i; j>=at+1; j--)
2243        {
2244          strat->fromQ[j] = strat->fromQ[j-1];
2245        }
2246        strat->fromQ[at]=fq;
2247      }
2248    }
2249  }
2250}
2251
2252
2253/*2
2254*looks up the position of p in set
2255*set[0] is the smallest with respect to the ordering-procedure
2256*pComp
2257* Assumption: posInS only depends on the leading term
2258*             otherwise, bba has to be changed
2259*/
2260int posInS (kStrategy strat, int length,poly p, int ecart_p)
2261{
2262  if(length==-1) return 0;
2263  polyset set=strat->S;
2264  int i;
2265  int an = 0;
2266  int en= length;
2267  int cmp_int=pOrdSgn;
2268  if (currRing->MixedOrder)
2269  {
2270    int o=pWTotaldegree(p);
2271    int oo=pWTotaldegree(set[length]);
2272
2273    if ((oo<o)
2274    || ((o==oo) && (pLmCmp(set[length],p)!= cmp_int)))
2275      return length+1;
2276
2277    loop
2278    {
2279      if (an >= en-1)
2280      {
2281        if ((pWTotaldegree(set[an])>=o) && (pLmCmp(set[an],p) == cmp_int))
2282        {
2283          return an;
2284        }
2285        return en;
2286      }
2287      i=(an+en) / 2;
2288      if ((pWTotaldegree(set[an])>=o)
2289      && (pLmCmp(set[i],p) == cmp_int)) en=i;
2290      else                              an=i;
2291    }
2292  }
2293  else
2294  {
2295#ifdef HAVE_RING2TOM
2296    if (currRing->cring == 1)
2297    {
2298      if (pLmCmp(set[length],p)== -cmp_int)
2299        return length+1;
2300
2301      loop
2302      {
2303        if (an >= en-1)
2304        {
2305          if (pLmCmp(set[an],p) == cmp_int)  return an;
2306          if (pLmCmp(set[an],p) == -cmp_int) return en;
2307          if (currRing->cring == 1) {
2308              if (nGreater(pGetCoeff(p), pGetCoeff(set[an]))) return en;
2309              return an;
2310          }
2311          if ((cmp_int!=1) && ((strat->ecartS[an])>ecart_p)) return an;
2312          return en;
2313        }
2314        i=(an+en) / 2;
2315        if (pLmCmp(set[i],p) == cmp_int)         en=i;
2316        else if (pLmCmp(set[i],p) == -cmp_int)   an=i;
2317        else
2318        {
2319          if (currRing->cring == 1) {
2320              if (nGreater(pGetCoeff(p), pGetCoeff(set[i]))) an = i;
2321              else en = i;
2322          }
2323          else
2324          {
2325            if ((cmp_int!=1) && ((strat->ecartS[i])<ecart_p))
2326              en=i;
2327            else
2328              an=i;
2329          }
2330        }
2331      }
2332    }
2333    else
2334#endif
2335    if (pLmCmp(set[length],p)== -cmp_int)
2336      return length+1;
2337
2338    loop
2339    {
2340      if (an >= en-1)
2341      {
2342        if (pLmCmp(set[an],p) == cmp_int) return an;
2343        if (pLmCmp(set[an],p) == -cmp_int) return en;
2344        if ((cmp_int!=1)
2345        && ((strat->ecartS[an])>ecart_p))
2346          return an;
2347        return en;
2348      }
2349      i=(an+en) / 2;
2350      if (pLmCmp(set[i],p) == cmp_int) en=i;
2351      else if (pLmCmp(set[i],p) == -cmp_int) an=i;
2352      else
2353      {
2354        if ((cmp_int!=1)
2355        &&((strat->ecartS[i])<ecart_p))
2356          en=i;
2357        else
2358          an=i;
2359      }
2360    }
2361  }
2362}
2363
2364
2365/*2
2366* looks up the position of p in set
2367* the position is the last one
2368*/
2369int posInT0 (const TSet set,const int length,LObject &p)
2370{
2371  return (length+1);
2372}
2373
2374
2375/*2
2376* looks up the position of p in T
2377* set[0] is the smallest with respect to the ordering-procedure
2378* pComp
2379*/
2380int posInT1 (const TSet set,const int length,LObject &p)
2381{
2382  if (length==-1) return 0;
2383
2384  if (pLmCmp(set[length].p,p.p)!= pOrdSgn) return length+1;
2385
2386  int i;
2387  int an = 0;
2388  int en= length;
2389
2390  loop
2391  {
2392    if (an >= en-1)
2393    {
2394      if (pLmCmp(set[an].p,p.p) == pOrdSgn) return an;
2395      return en;
2396    }
2397    i=(an+en) / 2;
2398    if (pLmCmp(set[i].p,p.p) == pOrdSgn) en=i;
2399    else                                 an=i;
2400  }
2401}
2402
2403/*2
2404* looks up the position of p in T
2405* set[0] is the smallest with respect to the ordering-procedure
2406* length
2407*/
2408int posInT2 (const TSet set,const int length,LObject &p)
2409{
2410  if (length==-1)
2411    return 0;
2412  if (set[length].length<p.length)
2413    return length+1;
2414
2415  int i;
2416  int an = 0;
2417  int en= length;
2418
2419  loop
2420  {
2421    if (an >= en-1)
2422    {
2423      if (set[an].length>p.length) return an;
2424      return en;
2425    }
2426    i=(an+en) / 2;
2427    if (set[i].length>p.length) en=i;
2428    else                        an=i;
2429  }
2430}
2431
2432/*2
2433* looks up the position of p in T
2434* set[0] is the smallest with respect to the ordering-procedure
2435* totaldegree,pComp
2436*/
2437int posInT11 (const TSet set,const int length,LObject &p)
2438/*{
2439 * int j=0;
2440 * int o;
2441 *
2442 * o = p.GetpFDeg();
2443 * loop
2444 * {
2445 *   if ((pFDeg(set[j].p) > o)
2446 *   || ((pFDeg(set[j].p) == o) && (pLmCmp(set[j].p,p.p) == pOrdSgn)))
2447 *   {
2448 *     return j;
2449 *   }
2450 *   j++;
2451 *   if (j > length) return j;
2452 * }
2453 *}
2454 */
2455{
2456  if (length==-1) return 0;
2457
2458  int o = p.GetpFDeg();
2459  int op = set[length].GetpFDeg();
2460
2461  if ((op < o)
2462  || ((op == o) && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
2463    return length+1;
2464
2465  int i;
2466  int an = 0;
2467  int en= length;
2468
2469  loop
2470  {
2471    if (an >= en-1)
2472    {
2473      op= set[an].GetpFDeg();
2474      if ((op > o)
2475      || (( op == o) && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
2476        return an;
2477      return en;
2478    }
2479    i=(an+en) / 2;
2480    op = set[i].GetpFDeg();
2481    if (( op > o)
2482    || (( op == o) && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
2483      en=i;
2484    else
2485      an=i;
2486  }
2487}
2488
2489/*2
2490* looks up the position of p in T
2491* set[0] is the smallest with respect to the ordering-procedure
2492* totaldegree,pComp
2493*/
2494int posInT110 (const TSet set,const int length,LObject &p)
2495{
2496  if (length==-1) return 0;
2497
2498  int o = p.GetpFDeg();
2499  int op = set[length].GetpFDeg();
2500
2501  if (( op < o)
2502  || (( op == o) && (set[length].length<p.length))
2503  || (( op == o) && (set[length].length == p.length)
2504     && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
2505    return length+1;
2506
2507  int i;
2508  int an = 0;
2509  int en= length;
2510  loop
2511  {
2512    if (an >= en-1)
2513    {
2514      op = set[an].GetpFDeg();
2515      if (( op > o)
2516      || (( op == o) && (set[an].length > p.length))
2517      || (( op == o) && (set[an].length == p.length)
2518         && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
2519        return an;
2520      return en;
2521    }
2522    i=(an+en) / 2;
2523    op = set[i].GetpFDeg();
2524    if (( op > o)
2525    || (( op == o) && (set[i].length > p.length))
2526    || (( op == o) && (set[i].length == p.length)
2527       && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
2528      en=i;
2529    else
2530      an=i;
2531  }
2532}
2533
2534/*2
2535* looks up the position of p in set
2536* set[0] is the smallest with respect to the ordering-procedure
2537* pFDeg
2538*/
2539int posInT13 (const TSet set,const int length,LObject &p)
2540{
2541  if (length==-1) return 0;
2542
2543  int o = p.GetpFDeg();
2544
2545  if (set[length].GetpFDeg() <= o)
2546    return length+1;
2547
2548  int i;
2549  int an = 0;
2550  int en= length;
2551  loop
2552  {
2553    if (an >= en-1)
2554    {
2555      if (set[an].GetpFDeg() > o)
2556        return an;
2557      return en;
2558    }
2559    i=(an+en) / 2;
2560    if (set[i].GetpFDeg() > o)
2561      en=i;
2562    else
2563      an=i;
2564  }
2565}
2566
2567// determines the position based on: 1.) Ecart 2.) pLength
2568int posInT_EcartpLength(const TSet set,const int length,LObject &p)
2569{
2570  if (length==-1) return 0;
2571
2572  int op=p.ecart;
2573  int ol = p.GetpLength();
2574
2575  int oo=set[length].ecart;
2576  if ((oo < op) || ((oo==op) && (set[length].length < ol)))
2577    return length+1;
2578
2579  int i;
2580  int an = 0;
2581  int en= length;
2582  loop
2583    {
2584      if (an >= en-1)
2585      {
2586        int oo=set[an].ecart;
2587        if((oo > op)
2588           || ((oo==op) && (set[an].pLength > ol)))
2589          return an;
2590        return en;
2591      }
2592      i=(an+en) / 2;
2593      int oo=set[i].ecart;
2594      if ((oo > op)
2595          || ((oo == op) && (set[i].pLength > ol)))
2596        en=i;
2597      else
2598        an=i;
2599    }
2600}
2601
2602/*2
2603* looks up the position of p in set
2604* set[0] is the smallest with respect to the ordering-procedure
2605* maximaldegree, pComp
2606*/
2607int posInT15 (const TSet set,const int length,LObject &p)
2608/*{
2609 *int j=0;
2610 * int o;
2611 *
2612 * o = p.GetpFDeg()+p.ecart;
2613 * loop
2614 * {
2615 *   if ((set[j].GetpFDeg()+set[j].ecart > o)
2616 *   || ((set[j].GetpFDeg()+set[j].ecart == o)
2617 *     && (pLmCmp(set[j].p,p.p) == pOrdSgn)))
2618 *   {
2619 *     return j;
2620 *   }
2621 *   j++;
2622 *   if (j > length) return j;
2623 * }
2624 *}
2625 */
2626{
2627  if (length==-1) return 0;
2628
2629  int o = p.GetpFDeg() + p.ecart;
2630  int op = set[length].GetpFDeg()+set[length].ecart;
2631
2632  if ((op < o)
2633  || ((op == o)
2634     && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
2635    return length+1;
2636
2637  int i;
2638  int an = 0;
2639  int en= length;
2640  loop
2641  {
2642    if (an >= en-1)
2643    {
2644      op = set[an].GetpFDeg()+set[an].ecart;
2645      if (( op > o)
2646      || (( op  == o) && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
2647        return an;
2648      return en;
2649    }
2650    i=(an+en) / 2;
2651    op = set[i].GetpFDeg()+set[i].ecart;
2652    if (( op > o)
2653    || (( op == o) && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
2654      en=i;
2655    else
2656      an=i;
2657  }
2658}
2659
2660/*2
2661* looks up the position of p in set
2662* set[0] is the smallest with respect to the ordering-procedure
2663* pFDeg+ecart, ecart, pComp
2664*/
2665int posInT17 (const TSet set,const int length,LObject &p)
2666/*
2667*{
2668* int j=0;
2669* int  o;
2670*
2671*  o = p.GetpFDeg()+p.ecart;
2672*  loop
2673*  {
2674*    if ((pFDeg(set[j].p)+set[j].ecart > o)
2675*    || (((pFDeg(set[j].p)+set[j].ecart == o)
2676*      && (set[j].ecart < p.ecart)))
2677*    || ((pFDeg(set[j].p)+set[j].ecart == o)
2678*      && (set[j].ecart==p.ecart)
2679*      && (pLmCmp(set[j].p,p.p)==pOrdSgn)))
2680*      return j;
2681*    j++;
2682*    if (j > length) return j;
2683*  }
2684* }
2685*/
2686{
2687  if (length==-1) return 0;
2688
2689  int o = p.GetpFDeg() + p.ecart;
2690  int op = set[length].GetpFDeg()+set[length].ecart;
2691
2692  if ((op < o)
2693  || (( op == o) && (set[length].ecart > p.ecart))
2694  || (( op == o) && (set[length].ecart==p.ecart)
2695     && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
2696    return length+1;
2697
2698  int i;
2699  int an = 0;
2700  int en= length;
2701  loop
2702  {
2703    if (an >= en-1)
2704    {
2705      op = set[an].GetpFDeg()+set[an].ecart;
2706      if (( op > o)
2707      || (( op == o) && (set[an].ecart < p.ecart))
2708      || (( op  == o) && (set[an].ecart==p.ecart)
2709         && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
2710        return an;
2711      return en;
2712    }
2713    i=(an+en) / 2;
2714    op = set[i].GetpFDeg()+set[i].ecart;
2715    if ((op > o)
2716    || (( op == o) && (set[i].ecart < p.ecart))
2717    || (( op == o) && (set[i].ecart == p.ecart)
2718       && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
2719      en=i;
2720    else
2721      an=i;
2722  }
2723}
2724/*2
2725* looks up the position of p in set
2726* set[0] is the smallest with respect to the ordering-procedure
2727* pGetComp, pFDeg+ecart, ecart, pComp
2728*/
2729int posInT17_c (const TSet set,const int length,LObject &p)
2730{
2731  if (length==-1) return 0;
2732
2733  int cc = (-1+2*currRing->order[0]==ringorder_c);
2734  /* cc==1 for (c,..), cc==-1 for (C,..) */
2735  int o = p.GetpFDeg() + p.ecart;
2736  int c = pGetComp(p.p)*cc;
2737
2738  if (pGetComp(set[length].p)*cc < c)
2739    return length+1;
2740  if (pGetComp(set[length].p)*cc == c)
2741  {
2742    int op = set[length].GetpFDeg()+set[length].ecart;
2743    if ((op < o)
2744    || ((op == o) && (set[length].ecart > p.ecart))
2745    || ((op == o) && (set[length].ecart==p.ecart)
2746       && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
2747      return length+1;
2748  }
2749
2750  int i;
2751  int an = 0;
2752  int en= length;
2753  loop
2754  {
2755    if (an >= en-1)
2756    {
2757      if (pGetComp(set[an].p)*cc < c)
2758        return en;
2759      if (pGetComp(set[an].p)*cc == c)
2760      {
2761        int op = set[an].GetpFDeg()+set[an].ecart;
2762        if ((op > o)
2763        || ((op == o) && (set[an].ecart < p.ecart))
2764        || ((op == o) && (set[an].ecart==p.ecart)
2765           && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
2766          return an;
2767      }
2768      return en;
2769    }
2770    i=(an+en) / 2;
2771    if (pGetComp(set[i].p)*cc > c)
2772      en=i;
2773    else if (pGetComp(set[i].p)*cc == c)
2774    {
2775      int op = set[i].GetpFDeg()+set[i].ecart;
2776      if ((op > o)
2777      || ((op == o) && (set[i].ecart < p.ecart))
2778      || ((op == o) && (set[i].ecart == p.ecart)
2779         && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
2780        en=i;
2781      else
2782        an=i;
2783    }
2784    else
2785      an=i;
2786  }
2787}
2788
2789/*2
2790* looks up the position of p in set
2791* set[0] is the smallest with respect to
2792* ecart, pFDeg, length
2793*/
2794int posInT19 (const TSet set,const int length,LObject &p)
2795{
2796  if (length==-1) return 0;
2797
2798  int o = p.ecart;
2799  int op=p.GetpFDeg();
2800
2801  if (set[length].ecart < o)
2802    return length+1;
2803  if (set[length].ecart == o)
2804  {
2805     int oo=set[length].GetpFDeg();
2806     if ((oo < op) || ((oo==op) && (set[length].length < p.length)))
2807       return length+1;
2808  }
2809
2810  int i;
2811  int an = 0;
2812  int en= length;
2813  loop
2814  {
2815    if (an >= en-1)
2816    {
2817      if (set[an].ecart > o)
2818        return an;
2819      if (set[an].ecart == o)
2820      {
2821         int oo=set[an].GetpFDeg();
2822         if((oo > op)
2823         || ((oo==op) && (set[an].length > p.length)))
2824           return an;
2825      }
2826      return en;
2827    }
2828    i=(an+en) / 2;
2829    if (set[i].ecart > o)
2830      en=i;
2831    else if (set[i].ecart == o)
2832    {
2833       int oo=set[i].GetpFDeg();
2834       if ((oo > op)
2835       || ((oo == op) && (set[i].length > p.length)))
2836         en=i;
2837       else
2838        an=i;
2839    }
2840    else
2841      an=i;
2842  }
2843}
2844
2845/*2
2846*looks up the position of polynomial p in set
2847*set[length] is the smallest element in set with respect
2848*to the ordering-procedure pComp
2849*/
2850int posInLSpecial (const LSet set, const int length,
2851                   LObject *p,const kStrategy strat)
2852{
2853  if (length<0) return 0;
2854
2855  int d=p->GetpFDeg();
2856  int op=set[length].GetpFDeg();
2857
2858  if ((op > d)
2859  || ((op == d) && (p->p1!=NULL)&&(set[length].p1==NULL))
2860  || (pLmCmp(set[length].p,p->p)== pOrdSgn))
2861     return length+1;
2862
2863  int i;
2864  int an = 0;
2865  int en= length;
2866  loop
2867  {
2868    if (an >= en-1)
2869    {
2870      op=set[an].GetpFDeg();
2871      if ((op > d)
2872      || ((op == d) && (p->p1!=NULL) && (set[an].p1==NULL))
2873      || (pLmCmp(set[an].p,p->p)== pOrdSgn))
2874         return en;
2875      return an;
2876    }
2877    i=(an+en) / 2;
2878    op=set[i].GetpFDeg();
2879    if ((op>d)
2880    || ((op==d) && (p->p1!=NULL) && (set[i].p1==NULL))
2881    || (pLmCmp(set[i].p,p->p) == pOrdSgn))
2882      an=i;
2883    else
2884      en=i;
2885  }
2886}
2887
2888/*2
2889*looks up the position of polynomial p in set
2890*set[length] is the smallest element in set with respect
2891*to the ordering-procedure pComp
2892*/
2893int posInL0 (const LSet set, const int length,
2894             LObject* p,const kStrategy strat)
2895{
2896  if (length<0) return 0;
2897
2898  if (pLmCmp(set[length].p,p->p)== pOrdSgn)
2899    return length+1;
2900
2901  int i;
2902  int an = 0;
2903  int en= length;
2904  loop
2905  {
2906    if (an >= en-1)
2907    {
2908      if (pLmCmp(set[an].p,p->p) == pOrdSgn) return en;
2909      return an;
2910    }
2911    i=(an+en) / 2;
2912    if (pLmCmp(set[i].p,p->p) == pOrdSgn) an=i;
2913    else                                 en=i;
2914    /*aend. fuer lazy == in !=- machen */
2915  }
2916}
2917
2918/*2
2919* looks up the position of polynomial p in set
2920* e is the ecart of p
2921* set[length] is the smallest element in set with respect
2922* to the ordering-procedure totaldegree,pComp
2923*/
2924int posInL11 (const LSet set, const int length,
2925              LObject* p,const kStrategy strat)
2926/*{
2927 * int j=0;
2928 * int o;
2929 *
2930 * o = p->GetpFDeg();
2931 * loop
2932 * {
2933 *   if (j > length)            return j;
2934 *   if ((set[j].GetpFDeg() < o)) return j;
2935 *   if ((set[j].GetpFDeg() == o) && (pLmCmp(set[j].p,p->p) == -pOrdSgn))
2936 *   {
2937 *     return j;
2938 *   }
2939 *   j++;
2940 * }
2941 *}
2942 */
2943{
2944  if (length<0) return 0;
2945
2946  int o = p->GetpFDeg();
2947  int op = set[length].GetpFDeg();
2948
2949  if ((op > o)
2950  || ((op == o) && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
2951    return length+1;
2952  int i;
2953  int an = 0;
2954  int en= length;
2955  loop
2956  {
2957    if (an >= en-1)
2958    {
2959      op = set[an].GetpFDeg();
2960      if ((op > o)
2961      || ((op == o) && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
2962        return en;
2963      return an;
2964    }
2965    i=(an+en) / 2;
2966    op = set[i].GetpFDeg();
2967    if ((op > o)
2968    || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
2969      an=i;
2970    else
2971      en=i;
2972  }
2973}
2974
2975/*2
2976* looks up the position of polynomial p in set
2977* set[length] is the smallest element in set with respect
2978* to the ordering-procedure totaldegree,pLength0
2979*/
2980int posInL110 (const LSet set, const int length,
2981               LObject* p,const kStrategy strat)
2982{
2983  if (length<0) return 0;
2984
2985  int o = p->GetpFDeg();
2986  int op = set[length].GetpFDeg();
2987
2988  if ((op > o)
2989  || ((op == o) && (set[length].length >p->length))
2990  || ((op == o) && (set[length].length <= p->length)
2991     && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
2992    return length+1;
2993  int i;
2994  int an = 0;
2995  int en= length;
2996  loop
2997  {
2998    if (an >= en-1)
2999    {
3000      op = set[an].GetpFDeg();
3001      if ((op > o)
3002      || ((op == o) && (set[an].length >p->length))
3003      || ((op == o) && (set[an].length <=p->length)
3004         && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
3005        return en;
3006      return an;
3007    }
3008    i=(an+en) / 2;
3009    op = set[i].GetpFDeg();
3010    if ((op > o)
3011    || ((op == o) && (set[i].length > p->length))
3012    || ((op == o) && (set[i].length <= p->length)
3013       && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
3014      an=i;
3015    else
3016      en=i;
3017  }
3018}
3019
3020/*2
3021* looks up the position of polynomial p in set
3022* e is the ecart of p
3023* set[length] is the smallest element in set with respect
3024* to the ordering-procedure totaldegree
3025*/
3026int posInL13 (const LSet set, const int length,
3027              LObject* p,const kStrategy strat)
3028{
3029  if (length<0) return 0;
3030
3031  int o = p->GetpFDeg();
3032
3033  if (set[length].GetpFDeg() > o)
3034    return length+1;
3035
3036  int i;
3037  int an = 0;
3038  int en= length;
3039  loop
3040  {
3041    if (an >= en-1)
3042    {
3043      if (set[an].GetpFDeg() >= o)
3044        return en;
3045      return an;
3046    }
3047    i=(an+en) / 2;
3048    if (set[i].GetpFDeg() >= o)
3049      an=i;
3050    else
3051      en=i;
3052  }
3053}
3054
3055/*2
3056* looks up the position of polynomial p in set
3057* e is the ecart of p
3058* set[length] is the smallest element in set with respect
3059* to the ordering-procedure maximaldegree,pComp
3060*/
3061int posInL15 (const LSet set, const int length,
3062              LObject* p,const kStrategy strat)
3063/*{
3064 * int j=0;
3065 * int o;
3066 *
3067 * o = p->ecart+p->GetpFDeg();
3068 * loop
3069 * {
3070 *   if (j > length)                       return j;
3071 *   if (set[j].GetpFDeg()+set[j].ecart < o) return j;
3072 *   if ((set[j].GetpFDeg()+set[j].ecart == o)
3073 *   && (pLmCmp(set[j].p,p->p) == -pOrdSgn))
3074 *   {
3075 *     return j;
3076 *   }
3077 *   j++;
3078 * }
3079 *}
3080 */
3081{
3082  if (length<0) return 0;
3083
3084  int o = p->GetpFDeg() + p->ecart;
3085  int op = set[length].GetpFDeg() + set[length].ecart;
3086
3087  if ((op > o)
3088  || ((op == o) && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
3089    return length+1;
3090  int i;
3091  int an = 0;
3092  int en= length;
3093  loop
3094  {
3095    if (an >= en-1)
3096    {
3097      op = set[an].GetpFDeg() + set[an].ecart;
3098      if ((op > o)
3099      || ((op == o) && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
3100        return en;
3101      return an;
3102    }
3103    i=(an+en) / 2;
3104    op = set[i].GetpFDeg() + set[i].ecart;
3105    if ((op > o)
3106    || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
3107      an=i;
3108    else
3109      en=i;
3110  }
3111}
3112
3113/*2
3114* looks up the position of polynomial p in set
3115* e is the ecart of p
3116* set[length] is the smallest element in set with respect
3117* to the ordering-procedure totaldegree
3118*/
3119int posInL17 (const LSet set, const int length,
3120              LObject* p,const kStrategy strat)
3121{
3122  if (length<0) return 0;
3123
3124  int o = p->GetpFDeg() + p->ecart;
3125
3126  if ((set[length].GetpFDeg() + set[length].ecart > o)
3127  || ((set[length].GetpFDeg() + set[length].ecart == o)
3128     && (set[length].ecart > p->ecart))
3129  || ((set[length].GetpFDeg() + set[length].ecart == o)
3130     && (set[length].ecart == p->ecart)
3131     && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
3132    return length+1;
3133  int i;
3134  int an = 0;
3135  int en= length;
3136  loop
3137  {
3138    if (an >= en-1)
3139    {
3140      if ((set[an].GetpFDeg() + set[an].ecart > o)
3141      || ((set[an].GetpFDeg() + set[an].ecart == o)
3142         && (set[an].ecart > p->ecart))
3143      || ((set[an].GetpFDeg() + set[an].ecart == o)
3144         && (set[an].ecart == p->ecart)
3145         && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
3146        return en;
3147      return an;
3148    }
3149    i=(an+en) / 2;
3150    if ((set[i].GetpFDeg() + set[i].ecart > o)
3151    || ((set[i].GetpFDeg() + set[i].ecart == o)
3152       && (set[i].ecart > p->ecart))
3153    || ((set[i].GetpFDeg() +set[i].ecart == o)
3154       && (set[i].ecart == p->ecart)
3155       && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
3156      an=i;
3157    else
3158      en=i;
3159  }
3160}
3161/*2
3162* looks up the position of polynomial p in set
3163* e is the ecart of p
3164* set[length] is the smallest element in set with respect
3165* to the ordering-procedure pComp
3166*/
3167int posInL17_c (const LSet set, const int length,
3168                LObject* p,const kStrategy strat)
3169{
3170  if (length<0) return 0;
3171
3172  int cc = (-1+2*currRing->order[0]==ringorder_c);
3173  /* cc==1 for (c,..), cc==-1 for (C,..) */
3174  int c = pGetComp(p->p)*cc;
3175  int o = p->GetpFDeg() + p->ecart;
3176
3177  if (pGetComp(set[length].p)*cc > c)
3178    return length+1;
3179  if (pGetComp(set[length].p)*cc == c)
3180  {
3181    if ((set[length].GetpFDeg() + set[length].ecart > o)
3182    || ((set[length].GetpFDeg() + set[length].ecart == o)
3183       && (set[length].ecart > p->ecart))
3184    || ((set[length].GetpFDeg() + set[length].ecart == o)
3185       && (set[length].ecart == p->ecart)
3186       && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
3187      return length+1;
3188  }
3189  int i;
3190  int an = 0;
3191  int en= length;
3192  loop
3193  {
3194    if (an >= en-1)
3195    {
3196      if (pGetComp(set[an].p)*cc > c)
3197        return en;
3198      if (pGetComp(set[an].p)*cc == c)
3199      {
3200        if ((set[an].GetpFDeg() + set[an].ecart > o)
3201        || ((set[an].GetpFDeg() + set[an].ecart == o)
3202           && (set[an].ecart > p->ecart))
3203        || ((set[an].GetpFDeg() + set[an].ecart == o)
3204           && (set[an].ecart == p->ecart)
3205           && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
3206          return en;
3207      }
3208      return an;
3209    }
3210    i=(an+en) / 2;
3211    if (pGetComp(set[i].p)*cc > c)
3212      an=i;
3213    else if (pGetComp(set[i].p)*cc == c)
3214    {
3215      if ((set[i].GetpFDeg() + set[i].ecart > o)
3216      || ((set[i].GetpFDeg() + set[i].ecart == o)
3217         && (set[i].ecart > p->ecart))
3218      || ((set[i].GetpFDeg() +set[i].ecart == o)
3219         && (set[i].ecart == p->ecart)
3220         && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
3221        an=i;
3222      else
3223        en=i;
3224    }
3225    else
3226      en=i;
3227  }
3228}
3229
3230/***************************************************************
3231 *
3232 * Tail reductions
3233 *
3234 ***************************************************************/
3235TObject*
3236kFindDivisibleByInS(kStrategy strat, int pos, LObject* L, TObject *T,
3237                    long ecart)
3238{
3239  int j = 0;
3240  const unsigned long not_sev = ~L->sev;
3241  const unsigned long* sev = strat->sevS;
3242  poly p;
3243  ring r;
3244  L->GetLm(p, r);
3245
3246  assume(~not_sev == p_GetShortExpVector(p, r));
3247
3248  if (r == currRing)
3249  {
3250    loop
3251    {
3252      if (j > pos) return NULL;
3253#if defined(PDEBUG) || defined(PDIV_DEBUG)
3254      if (p_LmShortDivisibleBy(strat->S[j], sev[j], p, not_sev, r) &&
3255          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
3256        break;
3257#else
3258      if (!(sev[j] & not_sev) &&
3259          (ecart== LONG_MAX || ecart>= strat->ecartS[j]) &&
3260          p_LmDivisibleBy(strat->S[j], p, r))
3261        break;
3262
3263#endif
3264      j++;
3265    }
3266    // if called from NF, T objects do not exist:
3267    if (strat->tl < 0 || strat->S_2_R[j] == -1)
3268    {
3269      T->Set(strat->S[j], r, strat->tailRing);
3270      return T;
3271    }
3272    else
3273    {
3274      assume (j >= 0 && j <= strat->tl && strat->S_2_T(j) != NULL &&
3275              strat->S_2_T(j)->p == strat->S[j]);
3276      return strat->S_2_T(j);
3277    }
3278  }
3279  else
3280  {
3281    TObject* t;
3282    loop
3283    {
3284      if (j > pos) return NULL;
3285      assume(strat->S_2_R[j] != -1);
3286#if defined(PDEBUG) || defined(PDIV_DEBUG)
3287      t = strat->S_2_T(j);
3288      assume(t != NULL && t->t_p != NULL && t->tailRing == r);
3289      if (p_LmShortDivisibleBy(t->t_p, sev[j], p, not_sev, r) &&
3290          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
3291        return t;
3292#else
3293      if (! (sev[j] & not_sev) && (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
3294      {
3295        t = strat->S_2_T(j);
3296        assume(t != NULL && t->t_p != NULL && t->tailRing == r && t->p == strat->S[j]);
3297        if (p_LmDivisibleBy(t->t_p, p, r)) return t;
3298      }
3299#endif
3300      j++;
3301    }
3302  }
3303}
3304/*
3305#ifdef HAVE_RING2TOM
3306TObject*
3307kRingFindDivisibleByInS(kStrategy strat, int pos, LObject* L, TObject *T,
3308                    long ecart)
3309{
3310  int j = 0;
3311  const unsigned long not_sev = ~L->sev;
3312  const unsigned long* sev = strat->sevS;
3313  poly p;
3314  ring r;
3315  L->GetLm(p, r);
3316
3317  assume(~not_sev == p_GetShortExpVector(p, r));
3318
3319  if (r == currRing)
3320  {
3321    loop
3322    {
3323      if (j > pos) return NULL;
3324#if defined(PDEBUG) || defined(PDIV_DEBUG)
3325      if (p_LmRingShortDivisibleBy(strat->S[j], sev[j], p, not_sev, r) &&
3326          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
3327        break;
3328#else
3329      if (!(sev[j] & not_sev) &&
3330          (ecart== LONG_MAX || ecart>= strat->ecartS[j]) &&
3331          p_LmRingDivisibleBy(strat->S[j], p, r))
3332        break;
3333
3334#endif
3335      j++;
3336    }
3337    // if called from NF, T objects do not exist:
3338    if (strat->tl < 0 || strat->S_2_R[j] == -1)
3339    {
3340      T->Set(strat->S[j], r, strat->tailRing);
3341      return T;
3342    }
3343    else
3344    {
3345      assume (j >= 0 && j <= strat->tl && strat->S_2_T(j) != NULL &&
3346              strat->S_2_T(j)->p == strat->S[j]);
3347      return strat->S_2_T(j);
3348    }
3349  }
3350  else
3351  {
3352    TObject* t;
3353    loop
3354    {
3355      if (j > pos) return NULL;
3356      assume(strat->S_2_R[j] != -1);
3357#if defined(PDEBUG) || defined(PDIV_DEBUG)
3358      t = strat->S_2_T(j);
3359      assume(t != NULL && t->t_p != NULL && t->tailRing == r);
3360      if (p_LmRingShortDivisibleBy(t->t_p, sev[j], p, not_sev, r) &&
3361          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
3362        return t;
3363#else
3364      if (! (sev[j] & not_sev) && (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
3365      {
3366        t = strat->S_2_T(j);
3367        assume(t != NULL && t->t_p != NULL && t->tailRing == r && t->p == strat->S[j]);
3368        if (p_LmRingDivisibleBy(t->t_p, p, r)) return t;
3369      }
3370#endif
3371      j++;
3372    }
3373  }
3374}
3375#endif
3376*/
3377
3378poly redtail (LObject* L, int pos, kStrategy strat)
3379{
3380  poly h, hn;
3381  int j;
3382  unsigned long not_sev;
3383  strat->redTailChange=FALSE;
3384
3385  poly p = L->p;
3386  if (strat->noTailReduction || pNext(p) == NULL)
3387    return p;
3388
3389  LObject Ln(strat->tailRing);
3390  TObject* With;
3391  // placeholder in case strat->tl < 0
3392  TObject  With_s(strat->tailRing);
3393  h = p;
3394  hn = pNext(h);
3395  long op = strat->tailRing->pFDeg(hn, strat->tailRing);
3396  long e;
3397  int l;
3398  BOOLEAN save_HE=strat->kHEdgeFound;
3399  strat->kHEdgeFound |=
3400    ((Kstd1_deg>0) && (op<=Kstd1_deg)) || TEST_OPT_INFREDTAIL;
3401
3402  while(hn != NULL)
3403  {
3404    op = strat->tailRing->pFDeg(hn, strat->tailRing);
3405    if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
3406    e = strat->tailRing->pLDeg(hn, &l, strat->tailRing) - op;
3407    loop
3408    {
3409      Ln.Set(hn, strat->tailRing);
3410      Ln.sev = p_GetShortExpVector(hn, strat->tailRing);
3411      if (strat->kHEdgeFound)
3412        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
3413      else
3414        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s, e);
3415      if (With == NULL) break;
3416      strat->redTailChange=TRUE;
3417      if (ksReducePolyTail(L, With, h, strat->kNoetherTail()))
3418      {
3419        // reducing the tail would violate the exp bound
3420        if (kStratChangeTailRing(strat, L))
3421        {
3422          strat->kHEdgeFound = save_HE;
3423          return redtail(L, pos, strat);
3424        }
3425        else
3426          return NULL;
3427      }
3428      hn = pNext(h);
3429      if (hn == NULL) goto all_done;
3430      op = strat->tailRing->pFDeg(hn, strat->tailRing);
3431      if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
3432      e = strat->tailRing->pLDeg(hn, &l, strat->tailRing) - op;
3433    }
3434    h = hn;
3435    hn = pNext(h);
3436  }
3437
3438  all_done:
3439  if (strat->redTailChange)
3440  {
3441    L->last = 0;
3442    L->pLength = 0;
3443  }
3444  strat->kHEdgeFound = save_HE;
3445  return p;
3446}
3447
3448poly redtail (poly p, int pos, kStrategy strat)
3449{
3450  LObject L(p, currRing);
3451  return redtail(&L, pos, strat);
3452}
3453
3454poly redtailBba (LObject* L, int pos, kStrategy strat, BOOLEAN withT)
3455{
3456  strat->redTailChange=FALSE;
3457  if (strat->noTailReduction) return L->GetLmCurrRing();
3458  poly h, p;
3459  p = h = L->GetLmTailRing();
3460  if ((h==NULL) || (pNext(h)==NULL))
3461    return L->GetLmCurrRing();
3462
3463  TObject* With;
3464  // placeholder in case strat->tl < 0
3465  TObject  With_s(strat->tailRing);
3466
3467  LObject Ln(pNext(h), strat->tailRing);
3468  Ln.pLength = L->GetpLength() - 1;
3469
3470  pNext(h) = NULL;
3471  if (L->p != NULL) pNext(L->p) = NULL;
3472  L->pLength = 1;
3473
3474  Ln.PrepareRed(strat->use_buckets);
3475
3476  while(!Ln.IsNull())
3477  {
3478    loop
3479    {
3480      Ln.SetShortExpVector();
3481      if (! withT)
3482      {
3483/* obsolete
3484#ifdef HAVE_RING2TOM
3485        if (currRing->cring == 1) {
3486            With = kRingFindDivisibleByInS(strat, pos, &Ln, &With_s);
3487        } else
3488#endif
3489*/
3490            With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
3491        if (With == NULL) break;
3492      }
3493      else
3494      {
3495        int j;
3496/* Obsolete
3497#ifdef HAVE_RING2TOM
3498        if (currRing->cring == 1) {
3499           j = kRingFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln);
3500        } else
3501#endif
3502*/
3503           j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln);
3504        if (j < 0) break;
3505        With = &(strat->T[j]);
3506      }
3507      if (ksReducePolyTail(L, With, &Ln))
3508      {
3509        // reducing the tail would violate the exp bound
3510        pNext(h) = Ln.GetTP();
3511        L->pLength += Ln.GetpLength();
3512        if (L->p != NULL) pNext(L->p) = pNext(p);
3513        if (kStratChangeTailRing(strat, L))
3514          return redtailBba(L, pos, strat, withT);
3515        else
3516        { // should never get here -- need to fix this
3517          assume(0);
3518          return NULL;
3519        }
3520      }
3521      strat->redTailChange=TRUE;
3522      if (Ln.IsNull()) goto all_done;
3523      if (! withT) With_s.Init(currRing);
3524    }
3525    pNext(h) = Ln.LmExtractAndIter();
3526    pIter(h);
3527    L->pLength++;
3528  }
3529
3530  all_done:
3531  if (L->p != NULL) pNext(L->p) = pNext(p);
3532  assume(pLength(L->p != NULL ? L->p : L->t_p) == L->pLength);
3533
3534  if (strat->redTailChange)
3535  {
3536    L->last = NULL;
3537    L->length = 0;
3538  }
3539  L->Normalize(); // HANNES: should have a test
3540  kTest_L(L);
3541  return L->GetLmCurrRing();
3542}
3543
3544/*2
3545*checks the change degree and write progress report
3546*/
3547void message (int i,int* reduc,int* olddeg,kStrategy strat, int red_result)
3548{
3549  if (i != *olddeg)
3550  {
3551    Print("%d",i);
3552    *olddeg = i;
3553  }
3554  if (K_TEST_OPT_OLDSTD)
3555  {
3556    if (strat->Ll != *reduc)
3557    {
3558      if (strat->Ll != *reduc-1)
3559        Print("(%d)",strat->Ll+1);
3560      else
3561        PrintS("-");
3562      *reduc = strat->Ll;
3563    }
3564    else
3565      PrintS(".");
3566    mflush();
3567  }
3568  else
3569  {
3570    if (red_result == 0)
3571      PrintS("-");
3572    else if (red_result < 0)
3573      PrintS(".");
3574    if ((red_result > 0) || ((strat->Ll % 100)==99))
3575    {
3576      if (strat->Ll != *reduc && strat->Ll > 0)
3577      {
3578        Print("(%d)",strat->Ll+1);
3579        *reduc = strat->Ll;
3580      }
3581    }
3582  }
3583}
3584
3585/*2
3586*statistics
3587*/
3588void messageStat (int srmax,int lrmax,int hilbcount,kStrategy strat)
3589{
3590  //PrintS("\nUsage/Allocation of temporary storage:\n");
3591  //Print("%d/%d polynomials in standard base\n",srmax,IDELEMS(Shdl));
3592  //Print("%d/%d polynomials in set L (for lazy alg.)",lrmax+1,strat->Lmax);
3593  Print("\nproduct criterion:%d chain criterion:%d\n",strat->cp,strat->c3);
3594  if (hilbcount!=0) Print("hilbert series criterion:%d\n",hilbcount);
3595  /*mflush();*/
3596}
3597
3598#ifdef KDEBUG
3599/*2
3600*debugging output: all internal sets, if changed
3601*for testing purpuse only/has to be changed for later use
3602*/
3603void messageSets (kStrategy strat)
3604{
3605  int i;
3606  if (strat->news)
3607  {
3608    PrintS("set S");
3609    for (i=0; i<=strat->sl; i++)
3610    {
3611      Print("\n  %d:",i);
3612      p_wrp(strat->S[i], currRing, strat->tailRing);
3613    }
3614    strat->news = FALSE;
3615  }
3616  if (strat->newt)
3617  {
3618    PrintS("\nset T");
3619    for (i=0; i<=strat->tl; i++)
3620    {
3621      Print("\n  %d:",i);
3622      strat->T[i].wrp();
3623      Print(" o:%d e:%d l:%d",
3624        strat->T[i].pFDeg(),strat->T[i].ecart,strat->T[i].length);
3625    }
3626    strat->newt = FALSE;
3627  }
3628  PrintS("\nset L");
3629  for (i=strat->Ll; i>=0; i--)
3630  {
3631    Print("\n%d:",i);
3632    p_wrp(strat->L[i].p1, currRing, strat->tailRing);
3633    PrintS("  ");
3634    p_wrp(strat->L[i].p2, currRing, strat->tailRing);
3635    PrintS(" lcm: ");p_wrp(strat->L[i].lcm, currRing);
3636    PrintS("\n  p : ");
3637    strat->L[i].wrp();
3638    Print("  o:%d e:%d l:%d",
3639          strat->L[i].pFDeg(),strat->L[i].ecart,strat->L[i].length);
3640  }
3641  PrintLn();
3642}
3643
3644#endif
3645
3646
3647/*2
3648*construct the set s from F
3649*/
3650void initS (ideal F, ideal Q,kStrategy strat)
3651{
3652  int   i,pos;
3653
3654  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
3655  else i=setmaxT;
3656  strat->ecartS=initec(i);
3657  strat->sevS=initsevS(i);
3658  strat->S_2_R=initS_2_R(i);
3659  strat->fromQ=NULL;
3660  strat->Shdl=idInit(i,F->rank);
3661  strat->S=strat->Shdl->m;
3662  /*- put polys into S -*/
3663  if (Q!=NULL)
3664  {
3665    strat->fromQ=initec(i);
3666    memset(strat->fromQ,0,i*sizeof(int));
3667    for (i=0; i<IDELEMS(Q); i++)
3668    {
3669      if (Q->m[i]!=NULL)
3670      {
3671        LObject h;
3672        h.p = pCopy(Q->m[i]);
3673        if (TEST_OPT_INTSTRATEGY)
3674        {
3675          //pContent(h.p);
3676          h.pCleardenom(); // also does a pContent
3677        }
3678        else
3679        {
3680          h.pNorm();
3681        }
3682        strat->initEcart(&h);
3683        if (pOrdSgn==-1)
3684        {
3685          deleteHC(&h, strat);
3686        }
3687        if (h.p!=NULL)
3688        {
3689          if (strat->sl==-1)
3690            pos =0;
3691          else
3692          {
3693            pos = posInS(strat,strat->sl,h.p,h.ecart);
3694          }
3695          h.sev = pGetShortExpVector(h.p);
3696          strat->enterS(h,pos,strat,-1);
3697          strat->fromQ[pos]=1;
3698        }
3699      }
3700    }
3701  }
3702  for (i=0; i<IDELEMS(F); i++)
3703  {
3704    if (F->m[i]!=NULL)
3705    {
3706      LObject h;
3707      h.p = pCopy(F->m[i]);
3708      if (TEST_OPT_INTSTRATEGY)
3709      {
3710        //pContent(h.p);
3711        h.pCleardenom(); // also does a pContent
3712      }
3713      else
3714      {
3715        h.pNorm();
3716      }
3717      strat->initEcart(&h);
3718      if (pOrdSgn==-1)
3719      {
3720        cancelunit(&h);  /*- tries to cancel a unit -*/
3721        deleteHC(&h, strat);
3722      }
3723      if (h.p!=NULL)
3724      {
3725        if (strat->sl==-1)
3726          pos =0;
3727        else
3728          pos = posInS(strat,strat->sl,h.p,h.ecart);
3729        h.sev = pGetShortExpVector(h.p);
3730        strat->enterS(h,pos,strat,-1);
3731      }
3732    }
3733  }
3734  /*- test, if a unit is in F -*/
3735  if ((strat->sl>=0) && pIsConstant(strat->S[0]))
3736  {
3737    while (strat->sl>0) deleteInS(strat->sl,strat);
3738  }
3739}
3740
3741void initSL (ideal F, ideal Q,kStrategy strat)
3742{
3743  int   i,pos;
3744
3745  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
3746  else i=setmaxT;
3747  strat->ecartS=initec(i);
3748  strat->sevS=initsevS(i);
3749  strat->S_2_R=initS_2_R(i);
3750  strat->fromQ=NULL;
3751  strat->Shdl=idInit(i,F->rank);
3752  strat->S=strat->Shdl->m;
3753  /*- put polys into S -*/
3754  if (Q!=NULL)
3755  {
3756    strat->fromQ=initec(i);
3757    memset(strat->fromQ,0,i*sizeof(int));
3758    for (i=0; i<IDELEMS(Q); i++)
3759    {
3760      if (Q->m[i]!=NULL)
3761      {
3762        LObject h;
3763        h.p = pCopy(Q->m[i]);
3764        if (TEST_OPT_INTSTRATEGY)
3765        {
3766          //pContent(h.p);
3767          h.pCleardenom(); // also does a pContent
3768        }
3769        else
3770        {
3771          h.pNorm();
3772        }
3773        strat->initEcart(&h);
3774        if (pOrdSgn==-1)
3775        {
3776          deleteHC(&h,strat);
3777        }
3778        if (h.p!=NULL)
3779        {
3780          if (strat->sl==-1)
3781            pos =0;
3782          else
3783          {
3784            pos = posInS(strat,strat->sl,h.p,h.ecart);
3785          }
3786          h.sev = pGetShortExpVector(h.p);
3787          strat->enterS(h,pos,strat,-1);
3788          strat->fromQ[pos]=1;
3789        }
3790      }
3791    }
3792  }
3793  for (i=0; i<IDELEMS(F); i++)
3794  {
3795    if (F->m[i]!=NULL)
3796    {
3797      LObject h;
3798      h.p = pCopy(F->m[i]);
3799      if (TEST_OPT_INTSTRATEGY)
3800      {
3801        //pContent(h.p);
3802        h.pCleardenom(); // also does a pContent
3803      }
3804      else
3805      {
3806        h.pNorm();
3807      }
3808      strat->initEcart(&h);
3809      if (pOrdSgn==-1)
3810      {
3811        cancelunit(&h);  /*- tries to cancel a unit -*/
3812        deleteHC(&h, strat);
3813      }
3814      if (h.p!=NULL)
3815      {
3816        if (strat->Ll==-1)
3817          pos =0;
3818        else
3819          pos = strat->posInL(strat->L,strat->Ll,&h,strat);
3820        h.sev = pGetShortExpVector(h.p);
3821        enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
3822      }
3823    }
3824  }
3825  /*- test, if a unit is in F -*/
3826  if ((strat->Ll>=0) && pIsConstant(strat->L[strat->Ll].p))
3827  {
3828    while (strat->Ll>0) deleteInL(strat->L,&strat->Ll,strat->Ll-1,strat);
3829  }
3830}
3831
3832
3833/*2
3834*construct the set s from F and {P}
3835*/
3836void initSSpecial (ideal F, ideal Q, ideal P,kStrategy strat)
3837{
3838  int   i,pos;
3839
3840  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
3841  else i=setmaxT;
3842  i=((i+IDELEMS(F)+15)/16)*16;
3843  strat->ecartS=initec(i);
3844  strat->sevS=initsevS(i);
3845  strat->S_2_R=initS_2_R(i);
3846  strat->fromQ=NULL;
3847  strat->Shdl=idInit(i,F->rank);
3848  strat->S=strat->Shdl->m;
3849
3850  /*- put polys into S -*/
3851  if (Q!=NULL)
3852  {
3853    strat->fromQ=initec(i);
3854    memset(strat->fromQ,0,i*sizeof(int));
3855    for (i=0; i<IDELEMS(Q); i++)
3856    {
3857      if (Q->m[i]!=NULL)
3858      {
3859        LObject h;
3860        h.p = pCopy(Q->m[i]);
3861        //if (TEST_OPT_INTSTRATEGY)
3862        //{
3863        //  //pContent(h.p);
3864        //  h.pCleardenom(); // also does a pContent
3865        //}
3866        //else
3867        //{
3868        //  h.pNorm();
3869        //}
3870        strat->initEcart(&h);
3871        if (pOrdSgn==-1)
3872        {
3873          deleteHC(&h,strat);
3874        }
3875        if (h.p!=NULL)
3876        {
3877          if (strat->sl==-1)
3878            pos =0;
3879          else
3880          {
3881            pos = posInS(strat,strat->sl,h.p,h.ecart);
3882          }
3883          h.sev = pGetShortExpVector(h.p);
3884          h.SetpFDeg();
3885          strat->enterS(h,pos,strat, strat->tl+1);
3886          enterT(h, strat);
3887          strat->fromQ[pos]=1;
3888        }
3889      }
3890    }
3891  }
3892  /*- put polys into S -*/
3893  for (i=0; i<IDELEMS(F); i++)
3894  {
3895    if (F->m[i]!=NULL)
3896    {
3897      LObject h;
3898      h.p = pCopy(F->m[i]);
3899      if (pOrdSgn==1)
3900      {
3901        h.p=redtailBba(h.p,strat->sl,strat);
3902      }
3903      strat->initEcart(&h);
3904      if (pOrdSgn==-1)
3905      {
3906        deleteHC(&h,strat);
3907      }
3908      if (h.p!=NULL)
3909      {
3910        if (strat->sl==-1)
3911          pos =0;
3912        else
3913          pos = posInS(strat,strat->sl,h.p,h.ecart);
3914        h.sev = pGetShortExpVector(h.p);
3915        strat->enterS(h,pos,strat, strat->tl+1);
3916        h.length = pLength(h.p);
3917        h.SetpFDeg();
3918        enterT(h,strat);
3919      }
3920    }
3921  }
3922  for (i=0; i<IDELEMS(P); i++)
3923  {
3924    if (P->m[i]!=NULL)
3925    {
3926      LObject h;
3927      h.p=pCopy(P->m[i]);
3928      strat->initEcart(&h);
3929      h.length = pLength(h.p);
3930      if (TEST_OPT_INTSTRATEGY)
3931      {
3932        h.pCleardenom();
3933      }
3934      else
3935      {
3936        h.pNorm();
3937      }
3938      if(strat->sl>=0)
3939      {
3940        if (pOrdSgn==1)
3941        {
3942          h.p=redBba(h.p,strat->sl,strat);
3943          if (h.p!=NULL)
3944            h.p=redtailBba(h.p,strat->sl,strat);
3945        }
3946        else
3947        {
3948          h.p=redMora(h.p,strat->sl,strat);
3949          strat->initEcart(&h);
3950        }
3951        if(h.p!=NULL)
3952        {
3953          if (TEST_OPT_INTSTRATEGY)
3954          {
3955            h.pCleardenom();
3956          }
3957          else
3958          {
3959            h.is_normalized = 0;
3960            h.pNorm();
3961          }
3962          h.sev = pGetShortExpVector(h.p);
3963          h.SetpFDeg();
3964          pos = posInS(strat,strat->sl,h.p,h.ecart);
3965          enterpairsSpecial(h.p,strat->sl,h.ecart,pos,strat,strat->tl+1);
3966          strat->enterS(h,pos,strat, strat->tl+1);
3967          enterT(h,strat);
3968        }
3969      }
3970      else
3971      {
3972        h.sev = pGetShortExpVector(h.p);
3973        h.SetpFDeg();
3974        strat->enterS(h,0,strat, strat->tl+1);
3975        enterT(h,strat);
3976      }
3977    }
3978  }
3979}
3980/*2
3981* reduces h using the set S
3982* procedure used in cancelunit1
3983*/
3984static poly redBba1 (poly h,int maxIndex,kStrategy strat)
3985{
3986  int j = 0;
3987  unsigned long not_sev = ~ pGetShortExpVector(h);
3988
3989  while (j <= maxIndex)
3990  {
3991    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j],h, not_sev))
3992       return ksOldSpolyRedNew(strat->S[j],h,strat->kNoetherTail());
3993    else j++;
3994  }
3995  return h;
3996}
3997
3998/*2
3999*tests if p.p=monomial*unit and cancels the unit
4000*/
4001void cancelunit1 (LObject* p,int *suc, int index,kStrategy strat )
4002{
4003  int k;
4004  poly r,h,h1,q;
4005
4006  if (!pIsVector((*p).p) && ((*p).ecart != 0))
4007  {
4008    k = 0;
4009    h1 = r = pCopy((*p).p);
4010    h =pNext(r);
4011    loop
4012    {
4013      if (h==NULL)
4014      {
4015        pDelete(&r);
4016        pDelete(&(pNext((*p).p)));
4017        (*p).ecart = 0;
4018        (*p).length = 1;
4019        (*suc)=0;
4020        return;
4021      }
4022      if (!pDivisibleBy(r,h))
4023      {
4024        q=redBba1(h,index ,strat);
4025        if (q != h)
4026        {
4027          k++;
4028          pDelete(&h);
4029          pNext(h1) = h = q;
4030        }
4031        else
4032        {
4033          pDelete(&r);
4034          return;
4035        }
4036      }
4037      else
4038      {
4039        h1 = h;
4040        pIter(h);
4041      }
4042      if (k > 10)
4043      {
4044        pDelete(&r);
4045        return;
4046      }
4047    }
4048  }
4049}
4050
4051/*2
4052* reduces h using the elements from Q in the set S
4053* procedure used in updateS
4054* must not be used for elements of Q or elements of an ideal !
4055*/
4056static poly redQ (poly h, int j, kStrategy strat)
4057{
4058  int start;
4059  unsigned long not_sev = ~ pGetShortExpVector(h);
4060  while ((j <= strat->sl) && (pGetComp(strat->S[j])!=0)) j++;
4061  start=j;
4062  while (j<=strat->sl)
4063  {
4064    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev))
4065    {
4066      h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
4067      if (h==NULL) return NULL;
4068      j = start;
4069      not_sev = ~ pGetShortExpVector(h);
4070    }
4071    else j++;
4072  }
4073  return h;
4074}
4075
4076/*2
4077* reduces h using the set S
4078* procedure used in updateS
4079*/
4080static poly redBba (poly h,int maxIndex,kStrategy strat)
4081{
4082  int j = 0;
4083  unsigned long not_sev = ~ pGetShortExpVector(h);
4084
4085  while (j <= maxIndex)
4086  {
4087#ifdef HAVE_RING2TOM
4088    if ((currRing->cring == 1 && pLmRingShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev)) ||
4089        (currRing->cring == 0 && pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev)))
4090#else
4091    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev))
4092#endif
4093    {
4094      h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
4095      if (h==NULL) return NULL;
4096      j = 0;
4097      not_sev = ~ pGetShortExpVector(h);    }
4098    else j++;
4099  }
4100  return h;
4101}
4102
4103/*2
4104* reduces h using the set S
4105*e is the ecart of h
4106*procedure used in updateS
4107*/
4108static poly redMora (poly h,int maxIndex,kStrategy strat)
4109{
4110  int  j=0;
4111  int  e,l;
4112  unsigned long not_sev = ~ pGetShortExpVector(h);
4113
4114  if (maxIndex >= 0)
4115  {
4116    e = pLDeg(h,&l,currRing)-pFDeg(h,currRing);
4117    do
4118    {
4119      if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev)
4120      && ((e >= strat->ecartS[j]) || strat->kHEdgeFound))
4121      {
4122#ifdef KDEBUG
4123        if (TEST_OPT_DEBUG)
4124          {PrintS("reduce ");wrp(h);Print(" with S[%d] (",j);wrp(strat->S[j]);}
4125
4126#endif
4127        h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
4128#ifdef KDEBUG
4129        if(TEST_OPT_DEBUG)
4130          {PrintS(")\nto "); wrp(h); PrintLn();}
4131
4132#endif
4133        // pDelete(&h);
4134        if (h == NULL) return NULL;
4135        e = pLDeg(h,&l,currRing)-pFDeg(h,currRing);
4136        j = 0;
4137        not_sev = ~ pGetShortExpVector(h);
4138      }
4139      else j++;
4140    }
4141    while (j <= maxIndex);
4142  }
4143  return h;
4144}
4145
4146/*2
4147*updates S:
4148*the result is a set of polynomials which are in
4149*normalform with respect to S
4150*/
4151void updateS(BOOLEAN toT,kStrategy strat)
4152{
4153  LObject h;
4154  int i, suc=0;
4155  poly redSi=NULL;
4156//  Print("nach initS: updateS start mit sl=%d\n",(strat->sl));
4157//  for (i=0; i<=(strat->sl); i++)
4158//  {
4159//    Print("s%d:",i);
4160//    if (strat->fromQ!=NULL) Print("(Q:%d) ",strat->fromQ[i]);
4161//    pWrite(strat->S[i]);
4162//  }
4163//  Print("pOrdSgn=%d\n", pOrdSgn);
4164  if (pOrdSgn==1)
4165  {
4166    while (suc != -1)
4167    {
4168      i=suc+1;
4169      while (i<=strat->sl)
4170      {
4171        if (((strat->syzComp==0) || (pGetComp(strat->S[i])<=strat->syzComp))
4172        && ((strat->fromQ==NULL) || (strat->fromQ[i]==0)))
4173        {
4174          pDelete(&redSi);
4175          redSi = pHead(strat->S[i]);
4176          strat->S[i] = redBba(strat->S[i],i-1,strat);
4177          if ((strat->ak!=0)&&(strat->S[i]!=NULL))
4178            strat->S[i]=redQ(strat->S[i],i+1,strat); /*reduce S[i] mod Q*/
4179          if (TEST_OPT_DEBUG && (pCmp(redSi,strat->S[i])!=0))
4180          {
4181            PrintS("reduce:");
4182            wrp(redSi);PrintS(" to ");p_wrp(strat->S[i], currRing, strat->tailRing);PrintLn();
4183          }
4184          if (TEST_OPT_PROT && (pCmp(redSi,strat->S[i])!=0))
4185          {
4186            if (strat->S[i]==NULL)
4187              PrintS("V");
4188            else
4189              PrintS("v");
4190            mflush();
4191          }
4192          if (strat->S[i]==NULL)
4193          {
4194            pDelete(&redSi);
4195            deleteInS(i,strat);
4196            i--;
4197          }
4198          else
4199          {
4200            pDelete(&redSi);
4201            if (TEST_OPT_INTSTRATEGY)
4202            {
4203              //pContent(strat->S[i]);
4204              pCleardenom(strat->S[i]);// also does a pContent
4205            }
4206            else
4207            {
4208              pNorm(strat->S[i]);
4209            }
4210            strat->sevS[i] = pGetShortExpVector(strat->S[i]);
4211          }
4212        }
4213        i++;
4214      }
4215      reorderS(&suc,strat);
4216    }
4217    if (toT)
4218    {
4219      for (i=0; i<=strat->sl; i++)
4220      {
4221        if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
4222        {
4223          h.p = redtailBba(strat->S[i],i-1,strat);
4224          if (TEST_OPT_INTSTRATEGY)
4225          {
4226            pCleardenom(h.p);// also does a pContent
4227          }
4228        }
4229        else
4230        {
4231          h.p = strat->S[i];
4232        }
4233        if (strat->honey)
4234        {
4235          strat->initEcart(&h);
4236          strat->ecartS[i] = h.ecart;
4237        }
4238        if (strat->sevS[i] == 0) {strat->sevS[i] = pGetShortExpVector(h.p);}
4239        else assume(strat->sevS[i] == pGetShortExpVector(h.p));
4240        h.sev = strat->sevS[i];
4241        h.SetpFDeg();
4242        /*puts the elements of S also to T*/
4243        enterT(h,strat);
4244        strat->S_2_R[i] = strat->tl;
4245      }
4246    }
4247  }
4248  else
4249  {
4250    while (suc != -1)
4251    {
4252      i=suc;
4253      while (i<=strat->sl)
4254      {
4255        if (((strat->syzComp==0) || (pGetComp(strat->S[i])<=strat->syzComp))
4256        && ((strat->fromQ==NULL) || (strat->fromQ[i]==0)))
4257        {
4258          pDelete(&redSi);
4259          redSi=pHead((strat->S)[i]);
4260          (strat->S)[i] = redMora((strat->S)[i],i-1,strat);
4261          if ((strat->S)[i]==NULL)
4262          {
4263            deleteInS(i,strat);
4264            i--;
4265          }
4266          else
4267          {
4268            if (TEST_OPT_INTSTRATEGY)
4269            {
4270              pDelete(&redSi);
4271              pCleardenom(strat->S[i]);// also does a pContent
4272              h.p = strat->S[i];
4273              strat->initEcart(&h);
4274              strat->ecartS[i] = h.ecart;
4275            }
4276            else
4277            {
4278              pDelete(&redSi);
4279              pNorm(strat->S[i]);
4280              h.p = strat->S[i];
4281              strat->initEcart(&h);
4282              strat->ecartS[i] = h.ecart;
4283            }
4284            h.sev =  pGetShortExpVector(h.p);
4285            strat->sevS[i] = h.sev;
4286          }
4287          kTest(strat);
4288        }
4289        i++;
4290      }
4291#ifdef KDEBUG
4292      kTest(strat);
4293#endif
4294      reorderS(&suc,strat);
4295      if (h.p!=NULL)
4296      {
4297        if (!strat->kHEdgeFound)
4298        {
4299          /*strat->kHEdgeFound =*/ HEckeTest(h.p,strat);
4300        }
4301        if (strat->kHEdgeFound)
4302          newHEdge(strat->S,strat);
4303      }
4304    }
4305    for (i=0; i<=strat->sl; i++)
4306    {
4307      if (((strat->fromQ==NULL) || (strat->fromQ[i]==0))
4308      )
4309      {
4310        strat->S[i] = h.p = redtail(strat->S[i],strat->sl,strat);
4311        strat->initEcart(&h);
4312        strat->ecartS[i] = h.ecart;
4313        h.sev = pGetShortExpVector(h.p);
4314        strat->sevS[i] = h.sev;
4315      }
4316      else
4317      {
4318        h.p = strat->S[i];
4319        h.ecart=strat->ecartS[i];
4320        h.sev = strat->sevS[i];
4321      }
4322      if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
4323        cancelunit1(&h,&suc,strat->sl,strat);
4324      h.length = pLength(h.p);
4325      h.SetpFDeg();
4326      /*puts the elements of S also to T*/
4327      enterT(h,strat);
4328      strat->S_2_R[i] = strat->tl;
4329    }
4330    if (suc!= -1) updateS(toT,strat);
4331  }
4332  if (redSi!=NULL) pDeleteLm(&redSi);
4333#ifdef KDEBUG
4334  kTest(strat);
4335#endif
4336}
4337
4338
4339/*2
4340* -puts p to the standardbasis s at position at
4341* -saves the result in S
4342*/
4343void enterSBba (LObject p,int atS,kStrategy strat, int atR)
4344{
4345  int i;
4346  strat->news = TRUE;
4347  /*- puts p to the standardbasis s at position at -*/
4348  if (strat->sl == IDELEMS(strat->Shdl)-1)
4349  {
4350    strat->sevS = (unsigned long*) omRealloc0Size(strat->sevS,
4351                                    IDELEMS(strat->Shdl)*sizeof(unsigned long),
4352                                    (IDELEMS(strat->Shdl)+setmaxTinc)
4353                                                  *sizeof(unsigned long));
4354    strat->ecartS = (intset)omReallocSize(strat->ecartS,
4355                                          IDELEMS(strat->Shdl)*sizeof(int),
4356                                          (IDELEMS(strat->Shdl)+setmaxTinc)
4357                                                  *sizeof(int));
4358    strat->S_2_R = (int*) omRealloc0Size(strat->S_2_R,
4359                                         IDELEMS(strat->Shdl)*sizeof(int),
4360                                         (IDELEMS(strat->Shdl)+setmaxTinc)
4361                                                  *sizeof(int));
4362    if (strat->lenS!=NULL)
4363      strat->lenS=(int*)omRealloc0Size(strat->lenS,
4364                                       IDELEMS(strat->Shdl)*sizeof(int),
4365                                       (IDELEMS(strat->Shdl)+setmaxTinc)
4366                                                 *sizeof(int));
4367    if (strat->lenSw!=NULL)
4368      strat->lenSw=(wlen_type*)omRealloc0Size(strat->lenSw,
4369                                       IDELEMS(strat->Shdl)*sizeof(wlen_type),
4370                                       (IDELEMS(strat->Shdl)+setmaxTinc)
4371                                                 *sizeof(wlen_type));
4372    if (strat->fromQ!=NULL)
4373    {
4374      strat->fromQ = (intset)omReallocSize(strat->fromQ,
4375                                    IDELEMS(strat->Shdl)*sizeof(int),
4376                                    (IDELEMS(strat->Shdl)+setmaxTinc)*sizeof(int));
4377    }
4378    pEnlargeSet(&strat->S,IDELEMS(strat->Shdl),setmaxTinc);
4379    IDELEMS(strat->Shdl)+=setmaxTinc;
4380    strat->Shdl->m=strat->S;
4381  }
4382  if (atS <= strat->sl)
4383  {
4384#ifdef ENTER_USE_MEMMOVE
4385// #if 0
4386    memmove(&(strat->S[atS+1]), &(strat->S[atS]),
4387            (strat->sl - atS + 1)*sizeof(poly));
4388    memmove(&(strat->ecartS[atS+1]), &(strat->ecartS[atS]),
4389            (strat->sl - atS + 1)*sizeof(int));
4390    memmove(&(strat->sevS[atS+1]), &(strat->sevS[atS]),
4391            (strat->sl - atS + 1)*sizeof(unsigned long));
4392    memmove(&(strat->S_2_R[atS+1]), &(strat->S_2_R[atS]),
4393            (strat->sl - atS + 1)*sizeof(int));
4394    if (strat->lenS!=NULL)
4395    memmove(&(strat->lenS[atS+1]), &(strat->lenS[atS]),
4396            (strat->sl - atS + 1)*sizeof(int));
4397    if (strat->lenSw!=NULL)
4398    memmove(&(strat->lenSw[atS+1]), &(strat->lenSw[atS]),
4399            (strat->sl - atS + 1)*sizeof(wlen_type));
4400#else
4401    for (i=strat->sl+1; i>=atS+1; i--)
4402    {
4403      strat->S[i] = strat->S[i-1];
4404      strat->ecartS[i] = strat->ecartS[i-1];
4405      strat->sevS[i] = strat->sevS[i-1];
4406      strat->S_2_R[i] = strat->S_2_R[i-1];
4407    }
4408    if (strat->lenS!=NULL)
4409    for (i=strat->sl+1; i>=atS+1; i--)
4410      strat->lenS[i] = strat->lenS[i-1];
4411    if (strat->lenSw!=NULL)
4412    for (i=strat->sl+1; i>=atS+1; i--)
4413      strat->lenSw[i] = strat->lenSw[i-1];
4414#endif
4415  }
4416  if (strat->fromQ!=NULL)
4417  {
4418#ifdef ENTER_USE_MEMMOVE
4419    memmove(&(strat->fromQ[atS+1]), &(strat->fromQ[atS]),
4420                  (strat->sl - atS + 1)*sizeof(int));
4421#else
4422    for (i=strat->sl+1; i>=atS+1; i--)
4423    {
4424      strat->fromQ[i] = strat->fromQ[i-1];
4425    }
4426#endif
4427    strat->fromQ[atS]=0;
4428  }
4429
4430  /*- save result -*/
4431  strat->S[atS] = p.p;
4432  if (strat->honey) strat->ecartS[atS] = p.ecart;
4433  if (p.sev == 0)
4434    p.sev = pGetShortExpVector(p.p);
4435  else
4436    assume(p.sev == pGetShortExpVector(p.p));
4437  strat->sevS[atS] = p.sev;
4438  strat->ecartS[atS] = p.ecart;
4439  strat->S_2_R[atS] = atR;
4440  strat->sl++;
4441}
4442
4443/*2
4444* puts p to the set T at position atT
4445*/
4446void enterT(LObject p, kStrategy strat, int atT)
4447{
4448  int i;
4449
4450  pp_Test(p.p, currRing, p.tailRing);
4451  assume(strat->tailRing == p.tailRing);
4452  // redMoraNF complains about this -- but, we don't really
4453  // neeed this so far
4454  // assume(p.pLength == 0 || pLength(p.p) == p.pLength);
4455  assume(p.FDeg == p.pFDeg());
4456  assume(!p.is_normalized || nIsOne(pGetCoeff(p.p)));
4457
4458  strat->newt = TRUE;
4459  if (atT < 0)
4460    atT = strat->posInT(strat->T, strat->tl, p);
4461  if (strat->tl == strat->tmax-1)
4462    enlargeT(strat->T,strat->R,strat->sevT,strat->tmax,setmaxTinc);
4463  if (atT <= strat->tl)
4464  {
4465#ifdef ENTER_USE_MEMMOVE
4466    memmove(&(strat->T[atT+1]), &(strat->T[atT]),
4467            (strat->tl-atT+1)*sizeof(TObject));
4468    memmove(&(strat->sevT[atT+1]), &(strat->sevT[atT]),
4469            (strat->tl-atT+1)*sizeof(unsigned long));
4470#endif
4471    for (i=strat->tl+1; i>=atT+1; i--)
4472    {
4473#ifndef ENTER_USE_MEMMOVE
4474      strat->T[i] = strat->T[i-1];
4475      strat->sevT[i] = strat->sevT[i-1];
4476#endif
4477      strat->R[strat->T[i].i_r] = &(strat->T[i]);
4478    }
4479  }
4480
4481  if (strat->tailBin != NULL && (pNext(p.p) != NULL))
4482  {
4483    pNext(p.p)=p_ShallowCopyDelete(pNext(p.p),
4484                                   (strat->tailRing != NULL ?
4485                                    strat->tailRing : currRing),
4486                                   strat->tailBin);
4487    if (p.t_p != NULL) pNext(p.t_p) = pNext(p.p);
4488  }
4489  strat->T[atT] = (TObject) p;
4490
4491  if (strat->tailRing != currRing && pNext(p.p) != NULL)
4492    strat->T[atT].max = p_GetMaxExpP(pNext(p.p), strat->tailRing);
4493  else
4494    strat->T[atT].max = NULL;
4495
4496  strat->tl++;
4497  strat->R[strat->tl] = &(strat->T[atT]);
4498  strat->T[atT].i_r = strat->tl;
4499  assume(p.sev == 0 || pGetShortExpVector(p.p) == p.sev);
4500  strat->sevT[atT] = (p.sev == 0 ? pGetShortExpVector(p.p) : p.sev);
4501  kTest_T(&(strat->T[atT]));
4502}
4503
4504void initHilbCrit(ideal F, ideal Q, intvec **hilb,kStrategy strat)
4505{
4506  if (strat->homog!=isHomog)
4507  {
4508    *hilb=NULL;
4509  }
4510}
4511
4512void initBuchMoraCrit(kStrategy strat)
4513{
4514  strat->sugarCrit =        TEST_OPT_SUGARCRIT;
4515  // obachman: Hmm.. I need BTEST1(2) for notBuckets ..
4516  //  strat->Gebauer =          BTEST1(2) || strat->homog || strat->sugarCrit;
4517  strat->Gebauer =          strat->homog || strat->sugarCrit;
4518  strat->honey =            !strat->homog || strat->sugarCrit || TEST_OPT_WEIGHTM;
4519  if (TEST_OPT_NOT_SUGAR) strat->honey = FALSE;
4520  strat->pairtest = NULL;
4521  /* alway use tailreduction, except:
4522  * - in local rings, - in lex order case, -in ring over extensions */
4523  strat->noTailReduction = !TEST_OPT_REDTAIL;
4524#ifdef HAVE_PLURAL
4525  // and r is plural_ring
4526  if (currRing->nc!=NULL)
4527    //or it has non-quasi-comm type... later
4528  {
4529    strat->sugarCrit = FALSE;
4530    strat->Gebauer = FALSE ;
4531    strat->honey = FALSE;
4532  }
4533#endif
4534  if (TEST_OPT_DEBUG)
4535  {
4536    if (strat->homog) PrintS("ideal/module is homogeneous\n");
4537    else              PrintS("ideal/module is not homogeneous\n");
4538  }
4539}
4540
4541BOOLEAN kPosInLDependsOnLength(int (*pos_in_l)
4542                               (const LSet set, const int length,
4543                                LObject* L,const kStrategy strat))
4544{
4545  if (pos_in_l == posInL110 ||
4546      pos_in_l == posInL10)
4547    return TRUE;
4548
4549  return FALSE;
4550}
4551
4552void initBuchMoraPos (kStrategy strat)
4553{
4554  if (pOrdSgn==1)
4555  {
4556    if (strat->honey)
4557    {
4558      strat->posInL = posInL15;
4559      // ok -- here is the deal: from my experiments for Singular-2-0
4560      // I conclude that that posInT_EcartpLength is the best of
4561      // posInT15, posInT_EcartFDegpLength, posInT_FDegLength, posInT_pLength
4562      // see the table at the end of this file
4563      if (K_TEST_OPT_OLDSTD)
4564        strat->posInT = posInT15;
4565      else
4566        strat->posInT = posInT_EcartpLength;
4567    }
4568    else if (pLexOrder && !TEST_OPT_INTSTRATEGY)
4569    {
4570      strat->posInL = posInL11;
4571      strat->posInT = posInT11;
4572    }
4573    else if (TEST_OPT_INTSTRATEGY)
4574    {
4575      strat->posInL = posInL11;
4576      strat->posInT = posInT11;
4577    }
4578    else
4579    {
4580      strat->posInL = posInL0;
4581      strat->posInT = posInT0;
4582    }
4583    //if (strat->minim>0) strat->posInL =posInLSpecial;
4584    if (strat->homog)
4585    {
4586       strat->posInL = posInL110;
4587       strat->posInT = posInT110;
4588    }
4589  }
4590  else
4591  {
4592    if (strat->homog)
4593    {
4594      strat->posInL = posInL11;
4595      strat->posInT = posInT11;
4596    }
4597    else
4598    {
4599      if ((currRing->order[0]==ringorder_c)
4600      ||(currRing->order[0]==ringorder_C))
4601      {
4602        strat->posInL = posInL17_c;
4603        strat->posInT = posInT17_c;
4604      }
4605      else
4606      {
4607        strat->posInL = posInL17;
4608        strat->posInT = posInT17;
4609      }
4610    }
4611  }
4612  if (strat->minim>0) strat->posInL =posInLSpecial;
4613  // for further tests only
4614  if ((BTEST1(11)) || (BTEST1(12)))
4615    strat->posInL = posInL11;
4616  else if ((BTEST1(13)) || (BTEST1(14)))
4617    strat->posInL = posInL13;
4618  else if ((BTEST1(15)) || (BTEST1(16)))
4619    strat->posInL = posInL15;
4620  else if ((BTEST1(17)) || (BTEST1(18)))
4621    strat->posInL = posInL17;
4622  if (BTEST1(11))
4623    strat->posInT = posInT11;
4624  else if (BTEST1(13))
4625    strat->posInT = posInT13;
4626  else if (BTEST1(15))
4627    strat->posInT = posInT15;
4628  else if ((BTEST1(17)))
4629    strat->posInT = posInT17;
4630  else if ((BTEST1(19)))
4631    strat->posInT = posInT19;
4632  else if (BTEST1(12) || BTEST1(14) || BTEST1(16) || BTEST1(18))
4633    strat->posInT = posInT1;
4634  strat->posInLDependsOnLength = kPosInLDependsOnLength(strat->posInL);
4635}
4636
4637void initBuchMora (ideal F,ideal Q,kStrategy strat)
4638{
4639  strat->interpt = BTEST1(OPT_INTERRUPT);
4640  strat->kHEdge=NULL;
4641  if (pOrdSgn==1) strat->kHEdgeFound=FALSE;
4642  /*- creating temp data structures------------------- -*/
4643  strat->cp = 0;
4644  strat->c3 = 0;
4645  strat->tail = pInit();
4646  /*- set s -*/
4647  strat->sl = -1;
4648  /*- set L -*/
4649  strat->Lmax = setmaxL;
4650  strat->Ll = -1;
4651  strat->L = initL();
4652  /*- set B -*/
4653  strat->Bmax = setmaxL;
4654  strat->Bl = -1;
4655  strat->B = initL();
4656  /*- set T -*/
4657  strat->tl = -1;
4658  strat->tmax = setmaxT;
4659  strat->T = initT();
4660  strat->R = initR();
4661  strat->sevT = initsevT();
4662  /*- init local data struct.---------------------------------------- -*/
4663  strat->P.ecart=0;
4664  strat->P.length=0;
4665  if (pOrdSgn==-1)
4666  {
4667    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
4668    if (strat->kNoether!=NULL) pSetComp(strat->kNoetherTail(), strat->ak);
4669  }
4670  if(TEST_OPT_SB_1)
4671  {
4672    int i;
4673    ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
4674    for (i=strat->newIdeal;i<IDELEMS(F);i++)
4675    {
4676      P->m[i-strat->newIdeal] = F->m[i];
4677      F->m[i] = NULL;
4678    }
4679    initSSpecial(F,Q,P,strat);
4680    for (i=strat->newIdeal;i<IDELEMS(F);i++)
4681    {
4682      F->m[i] = P->m[i-strat->newIdeal];
4683      P->m[i-strat->newIdeal] = NULL;
4684    }
4685    idDelete(&P);
4686  }
4687  else
4688  {
4689    /*Shdl=*/initSL(F, Q,strat); /*sets also S, ecartS, fromQ */
4690    // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
4691  }
4692  strat->kIdeal = NULL;
4693  strat->fromT = FALSE;
4694  strat->noTailReduction = !TEST_OPT_REDTAIL;
4695  if(!TEST_OPT_SB_1)
4696  {
4697    updateS(TRUE,strat);
4698    pairs(strat);
4699  }
4700  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
4701  strat->fromQ=NULL;
4702}
4703
4704void exitBuchMora (kStrategy strat)
4705{
4706  /*- release temp data -*/
4707  cleanT(strat);
4708  omFreeSize(strat->T,(strat->tmax)*sizeof(TObject));
4709  omFreeSize(strat->R,(strat->tmax)*sizeof(TObject*));
4710  omFreeSize(strat->sevT, (strat->tmax)*sizeof(unsigned long));
4711  omFreeSize(strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
4712  omFreeSize(strat->sevS,IDELEMS(strat->Shdl)*sizeof(int));
4713  omFreeSize(strat->S_2_R,IDELEMS(strat->Shdl)*sizeof(int));
4714  /*- set L: should be empty -*/
4715  omFreeSize(strat->L,(strat->Lmax)*sizeof(LObject));
4716  /*- set B: should be empty -*/
4717  omFreeSize(strat->B,(strat->Bmax)*sizeof(LObject));
4718  pDeleteLm(&strat->tail);
4719  strat->syzComp=0;
4720  if (strat->kIdeal!=NULL)
4721  {
4722    omFreeBin(strat->kIdeal, sleftv_bin);
4723    strat->kIdeal=NULL;
4724  }
4725}
4726
4727/*2
4728* in the case of a standardbase of a module over a qring:
4729* replace polynomials in i by ak vectors,
4730* (the polynomial * unit vectors gen(1)..gen(ak)
4731* in every case (also for ideals:)
4732* deletes divisible vectors/polynomials
4733*/
4734void updateResult(ideal r,ideal Q, kStrategy strat)
4735{
4736  int l;
4737  if (strat->ak>0)
4738  {
4739    for (l=IDELEMS(r)-1;l>=0;l--)
4740    {
4741      if ((r->m[l]!=NULL) && (pGetComp(r->m[l])==0))
4742      {
4743        pDelete(&r->m[l]); // and set it to NULL
4744      }
4745    }
4746    int q;
4747    poly p;
4748    for (l=IDELEMS(r)-1;l>=0;l--)
4749    {
4750      if ((r->m[l]!=NULL)
4751      && (strat->syzComp>0)
4752      && (pGetComp(r->m[l])<=strat->syzComp))
4753      {
4754        for(q=IDELEMS(Q)-1; q>=0;q--)
4755        {
4756          if ((Q->m[q]!=NULL)
4757          &&(pLmDivisibleBy(Q->m[q],r->m[l])))
4758          {
4759            if (TEST_OPT_REDSB)
4760            {
4761              p=r->m[l];
4762              r->m[l]=kNF(Q,NULL,p);
4763              pDelete(&p);
4764            }
4765            else
4766            {
4767              pDelete(&r->m[l]); // and set it to NULL
4768            }
4769            break;
4770          }
4771        }
4772      }
4773    }
4774  }
4775  else
4776  {
4777    int q;
4778    poly p;
4779    for (l=IDELEMS(r)-1;l>=0;l--)
4780    {
4781      if (r->m[l]!=NULL)
4782      {
4783        for(q=IDELEMS(Q)-1; q>=0;q--)
4784        {
4785          if ((Q->m[q]!=NULL)
4786          &&(pLmEqual(r->m[l],Q->m[q])))
4787          {
4788            if (TEST_OPT_REDSB)
4789            {
4790              p=r->m[l];
4791              r->m[l]=kNF(Q,NULL,p);
4792              pDelete(&p);
4793            }
4794            else
4795            {
4796              pDelete(&r->m[l]); // and set it to NULL
4797            }
4798            break;
4799          }
4800        }
4801      }
4802    }
4803  }
4804  idSkipZeroes(r);
4805}
4806
4807void completeReduce (kStrategy strat)
4808{
4809  int i;
4810  int low = (pOrdSgn == 1 ? 1 : 0);
4811  LObject L;
4812
4813#ifdef KDEBUG
4814  // need to set this: during tailreductions of T[i], T[i].max is out of
4815  // sync
4816  sloppy_max = TRUE;
4817#endif
4818
4819  strat->noTailReduction = FALSE;
4820  if (TEST_OPT_PROT)
4821  {
4822    PrintLn();
4823    if (timerv) writeTime("standard base computed:");
4824  }
4825  if (TEST_OPT_PROT)
4826  {
4827    Print("(S:%d)",strat->sl);mflush();
4828  }
4829  for (i=strat->sl; i>=low; i--)
4830  {
4831    TObject* T_j = strat->s_2_t(i);
4832    if (T_j != NULL)
4833    {
4834      L = *T_j;
4835      poly p;
4836      if (pOrdSgn == 1)
4837        strat->S[i] = redtailBba(&L, i-1, strat, FALSE);
4838      else
4839        strat->S[i] = redtail(&L, strat->sl, strat);
4840
4841      if (strat->redTailChange && strat->tailRing != currRing)
4842      {
4843        if (T_j->max != NULL) p_LmFree(T_j->max, strat->tailRing);
4844        if (pNext(T_j->p) != NULL)
4845          T_j->max = p_GetMaxExpP(pNext(T_j->p), strat->tailRing);
4846        else
4847          T_j->max = NULL;
4848      }
4849      if (TEST_OPT_INTSTRATEGY)
4850        T_j->pCleardenom();
4851    }
4852    else
4853    {
4854      assume(currRing == strat->tailRing);
4855      if (pOrdSgn == 1)
4856        strat->S[i] = redtailBba(strat->S[i], i-1, strat);
4857      else
4858        strat->S[i] = redtail(strat->S[i], strat->sl, strat);
4859      if (TEST_OPT_INTSTRATEGY)
4860        pCleardenom(strat->S[i]);
4861    }
4862    if (TEST_OPT_PROT)
4863      PrintS("-");
4864  }
4865#ifdef KDEBUG
4866  sloppy_max = FALSE;
4867#endif
4868}
4869
4870
4871/*2
4872* computes the new strat->kHEdge and the new pNoether,
4873* returns TRUE, if pNoether has changed
4874*/
4875BOOLEAN newHEdge(polyset S, kStrategy strat)
4876{
4877  int i,j;
4878  poly newNoether;
4879
4880  scComputeHC(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
4881  if (strat->t_kHEdge != NULL) p_LmFree(strat->t_kHEdge, strat->tailRing);
4882  if (strat->tailRing != currRing)
4883    strat->t_kHEdge = k_LmInit_currRing_2_tailRing(strat->kHEdge, strat->tailRing);
4884  /* compare old and new noether*/
4885  newNoether = pLmInit(strat->kHEdge);
4886  j = pFDeg(newNoether,currRing);
4887  for (i=1; i<=pVariables; i++)
4888  {
4889    if (pGetExp(newNoether, i) > 0) pDecrExp(newNoether,i);
4890  }
4891  pSetm(newNoether);
4892  if (j < strat->HCord) /*- statistics -*/
4893  {
4894    if (TEST_OPT_PROT)
4895    {
4896      Print("H(%d)",j);
4897      mflush();
4898    }
4899    strat->HCord=j;
4900    if (TEST_OPT_DEBUG)
4901    {
4902      Print("H(%d):",j);
4903      wrp(strat->kHEdge);
4904      PrintLn();
4905    }
4906  }
4907  if (pCmp(strat->kNoether,newNoether)!=1)
4908  {
4909    pDelete(&strat->kNoether);
4910    strat->kNoether=newNoether;
4911    if (strat->t_kNoether != NULL) p_LmFree(strat->t_kNoether, strat->tailRing);
4912    if (strat->tailRing != currRing)
4913      strat->t_kNoether = k_LmInit_currRing_2_tailRing(strat->kNoether, strat->tailRing);
4914
4915    return TRUE;
4916  }
4917  pLmFree(newNoether);
4918  return FALSE;
4919}
4920
4921/***************************************************************
4922 *
4923 * Routines related for ring changes during std computations
4924 *
4925 ***************************************************************/
4926BOOLEAN kCheckSpolyCreation(LObject *L, kStrategy strat, poly &m1, poly &m2)
4927{
4928  assume(L->p1 != NULL && L->p2 != NULL);
4929  assume(L->i_r1 >= 0 && L->i_r1 <= strat->tl);
4930  assume(L->i_r2 >= 0 && L->i_r2 <= strat->tl);
4931  assume(strat->tailRing != currRing);
4932
4933  if (! k_GetLeadTerms(L->p1, L->p2, currRing, m1, m2, strat->tailRing))
4934    return FALSE;
4935  poly p1_max = (strat->R[L->i_r1])->max;
4936  poly p2_max = (strat->R[L->i_r2])->max;
4937
4938  if ((p1_max != NULL && !p_LmExpVectorAddIsOk(m1, p1_max, strat->tailRing)) ||
4939      (p2_max != NULL && !p_LmExpVectorAddIsOk(m2, p2_max, strat->tailRing)))
4940  {
4941    p_LmFree(m1, strat->tailRing);
4942    p_LmFree(m2, strat->tailRing);
4943    m1 = NULL;
4944    m2 = NULL;
4945    return FALSE;
4946  }
4947  return TRUE;
4948}
4949
4950BOOLEAN kStratChangeTailRing(kStrategy strat, LObject *L, TObject* T, unsigned long expbound)
4951{
4952  if (expbound == 0) expbound = strat->tailRing->bitmask << 1;
4953  if (expbound >= currRing->bitmask) return FALSE;
4954  ring new_tailRing = rModifyRing(currRing,
4955                                  // Hmmm .. the condition pFDeg == pDeg
4956                                  // might be too strong
4957#ifdef HAVE_RING2TOM
4958                                  (strat->homog && pFDeg == pDeg && currRing->cring == 0), // TODO Oliver
4959#else
4960                                  (strat->homog && pFDeg == pDeg),
4961#endif
4962                                  !strat->ak,
4963                                  expbound);
4964  if (new_tailRing == currRing) return TRUE;
4965
4966  strat->pOrigFDeg_TailRing = new_tailRing->pFDeg;
4967  strat->pOrigLDeg_TailRing = new_tailRing->pLDeg;
4968
4969  if (currRing->pFDeg != currRing->pFDegOrig)
4970  {
4971    new_tailRing->pFDeg = currRing->pFDeg;
4972    new_tailRing->pLDeg = currRing->pLDeg;
4973  }
4974
4975  if (TEST_OPT_PROT)
4976    Print("[%lu:%d", (unsigned long) new_tailRing->bitmask, new_tailRing->ExpL_Size);
4977  kTest_TS(strat);
4978  assume(new_tailRing != strat->tailRing);
4979  pShallowCopyDeleteProc p_shallow_copy_delete
4980    = pGetShallowCopyDeleteProc(strat->tailRing, new_tailRing);
4981
4982  omBin new_tailBin = omGetStickyBinOfBin(new_tailRing->PolyBin);
4983
4984  int i;
4985  for (i=0; i<=strat->tl; i++)
4986  {
4987    strat->T[i].ShallowCopyDelete(new_tailRing, new_tailBin,
4988                                  p_shallow_copy_delete);
4989  }
4990  for (i=0; i<=strat->Ll; i++)
4991  {
4992    assume(strat->L[i].p != NULL);
4993    if (pNext(strat->L[i].p) != strat->tail)
4994      strat->L[i].ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
4995  }
4996  if (strat->P.t_p != NULL ||
4997      (strat->P.p != NULL && pNext(strat->P.p) != strat->tail))
4998    strat->P.ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
4999
5000  if (L != NULL && L->tailRing != new_tailRing)
5001  {
5002    if (L->i_r < 0)
5003      L->ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
5004    else
5005    {
5006      assume(L->i_r <= strat->tl);
5007      TObject* t_l = strat->R[L->i_r];
5008      assume(t_l != NULL);
5009      L->tailRing = new_tailRing;
5010      L->p = t_l->p;
5011      L->t_p = t_l->t_p;
5012      L->max = t_l->max;
5013    }
5014  }
5015
5016  if (T != NULL && T->tailRing != new_tailRing && T->i_r < 0)
5017    T->ShallowCopyDelete(new_tailRing, new_tailBin, p_shallow_copy_delete);
5018
5019  omMergeStickyBinIntoBin(strat->tailBin, strat->tailRing->PolyBin);
5020  if (strat->tailRing != currRing)
5021    rKillModifiedRing(strat->tailRing);
5022
5023  strat->tailRing = new_tailRing;
5024  strat->tailBin = new_tailBin;
5025  strat->p_shallow_copy_delete
5026    = pGetShallowCopyDeleteProc(currRing, new_tailRing);
5027
5028  if (strat->kHEdge != NULL)
5029  {
5030    if (strat->t_kHEdge != NULL)
5031      p_LmFree(strat->t_kHEdge, strat->tailRing);
5032    strat->t_kHEdge=k_LmInit_currRing_2_tailRing(strat->kHEdge, new_tailRing);
5033  }
5034
5035  if (strat->kNoether != NULL)
5036  {
5037    if (strat->t_kNoether != NULL)
5038      p_LmFree(strat->t_kNoether, strat->tailRing);
5039    strat->t_kNoether=k_LmInit_currRing_2_tailRing(strat->kNoether,
5040                                                   new_tailRing);
5041  }
5042  kTest_TS(strat);
5043  if (TEST_OPT_PROT)
5044    PrintS("]");
5045  return TRUE;
5046}
5047
5048void kStratInitChangeTailRing(kStrategy strat)
5049{
5050  unsigned long l = 0;
5051  int i;
5052  Exponent_t e;
5053  ring new_tailRing;
5054
5055  assume(strat->tailRing == currRing);
5056
5057  for (i=0; i<= strat->Ll; i++)
5058  {
5059    l = p_GetMaxExpL(strat->L[i].p, currRing, l);
5060  }
5061  for (i=0; i<=strat->tl; i++)
5062  {
5063    // Hmm ... this we could do in one Step
5064    l = p_GetMaxExpL(strat->T[i].p, currRing, l);
5065  }
5066  e = p_GetMaxExp(l, currRing);
5067  if (e <= 1) e = 2;
5068
5069  kStratChangeTailRing(strat, NULL, NULL, e);
5070}
5071
5072skStrategy::skStrategy()
5073{
5074  memset(this, 0, sizeof(skStrategy));
5075#ifndef NDEBUG
5076  strat_nr++;
5077  nr=strat_nr;
5078  if (strat_fac_debug) Print("s(%d) created\n",nr);
5079#endif
5080  tailRing = currRing;
5081  P.tailRing = currRing;
5082  tl = -1;
5083  sl = -1;
5084#ifdef HAVE_LM_BIN
5085  lmBin = omGetStickyBinOfBin(currRing->PolyBin);
5086#endif
5087#ifdef HAVE_TAIL_BIN
5088  tailBin = omGetStickyBinOfBin(currRing->PolyBin);
5089#endif
5090  pOrigFDeg = pFDeg;
5091  pOrigLDeg = pLDeg;
5092}
5093
5094
5095skStrategy::~skStrategy()
5096{
5097  if (lmBin != NULL)
5098    omMergeStickyBinIntoBin(lmBin, currRing->PolyBin);
5099  if (tailBin != NULL)
5100    omMergeStickyBinIntoBin(tailBin,
5101                            (tailRing != NULL ? tailRing->PolyBin:
5102                             currRing->PolyBin));
5103  if (t_kHEdge != NULL)
5104    p_LmFree(t_kHEdge, tailRing);
5105  if (t_kNoether != NULL)
5106    p_LmFree(t_kNoether, tailRing);
5107
5108  if (currRing != tailRing)
5109    rKillModifiedRing(tailRing);
5110  pRestoreDegProcs(pOrigFDeg, pOrigLDeg);
5111}
5112
5113#if 0
5114Timings for the different possibilities of posInT:
5115            T15           EDL         DL          EL            L         1-2-3
5116Gonnet      43.26       42.30       38.34       41.98       38.40      100.04
5117Hairer_2_1   1.11        1.15        1.04        1.22        1.08        4.7
5118Twomat3      1.62        1.69        1.70        1.65        1.54       11.32
5119ahml         4.48        4.03        4.03        4.38        4.96       26.50
5120c7          15.02       13.98       15.16       13.24       17.31       47.89
5121c8         505.09      407.46      852.76      413.21      499.19        n/a
5122f855        12.65        9.27       14.97        8.78       14.23       33.12
5123gametwo6    11.47       11.35       14.57       11.20       12.02       35.07
5124gerhard_3    2.73        2.83        2.93        2.64        3.12        6.24
5125ilias13     22.89       22.46       24.62       20.60       23.34       53.86
5126noon8       40.68       37.02       37.99       36.82       35.59      877.16
5127rcyclic_19  48.22       42.29       43.99       45.35       51.51      204.29
5128rkat9       82.37       79.46       77.20       77.63       82.54      267.92
5129schwarz_11  16.46       16.81       16.76       16.81       16.72       35.56
5130test016     16.39       14.17       14.40       13.50       14.26       34.07
5131test017     34.70       36.01       33.16       35.48       32.75       71.45
5132test042     10.76       10.99       10.27       11.57       10.45       23.04
5133test058      6.78        6.75        6.51        6.95        6.22        9.47
5134test066     10.71       10.94       10.76       10.61       10.56       19.06
5135test073     10.75       11.11       10.17       10.79        8.63       58.10
5136test086     12.23       11.81       12.88       12.24       13.37       66.68
5137test103      5.05        4.80        5.47        4.64        4.89       11.90
5138test154     12.96       11.64       13.51       12.46       14.61       36.35
5139test162     65.27       64.01       67.35       59.79       67.54      196.46
5140test164      7.50        6.50        7.68        6.70        7.96       17.13
5141virasoro     3.39        3.50        3.35        3.47        3.70        7.66
5142#endif
5143
5144
5145#ifdef HAVE_MORE_POS_IN_T
5146// determines the position based on: 1.) Ecart 2.) FDeg 3.) pLength
5147int posInT_EcartFDegpLength(const TSet set,const int length,LObject &p)
5148{
5149
5150  if (length==-1) return 0;
5151
5152  int o = p.ecart;
5153  int op=p.GetpFDeg();
5154  int ol = p.GetpLength();
5155
5156  if (set[length].ecart < o)
5157    return length+1;
5158  if (set[length].ecart == o)
5159  {
5160     int oo=set[length].GetpFDeg();
5161     if ((oo < op) || ((oo==op) && (set[length].length < ol)))
5162       return length+1;
5163  }
5164
5165  int i;
5166  int an = 0;
5167  int en= length;
5168  loop
5169  {
5170    if (an >= en-1)
5171    {
5172      if (set[an].ecart > o)
5173        return an;
5174      if (set[an].ecart == o)
5175      {
5176         int oo=set[an].GetpFDeg();
5177         if((oo > op)
5178         || ((oo==op) && (set[an].pLength > ol)))
5179           return an;
5180      }
5181      return en;
5182    }
5183    i=(an+en) / 2;
5184    if (set[i].ecart > o)
5185      en=i;
5186    else if (set[i].ecart == o)
5187    {
5188       int oo=set[i].GetpFDeg();
5189       if ((oo > op)
5190       || ((oo == op) && (set[i].pLength > ol)))
5191         en=i;
5192       else
5193        an=i;
5194    }
5195    else
5196      an=i;
5197  }
5198}
5199
5200// determines the position based on: 1.) FDeg 2.) pLength
5201int posInT_FDegpLength(const TSet set,const int length,LObject &p)
5202{
5203
5204  if (length==-1) return 0;
5205
5206  int op=p.GetpFDeg();
5207  int ol = p.GetpLength();
5208
5209  int oo=set[length].GetpFDeg();
5210  if ((oo < op) || ((oo==op) && (set[length].length < ol)))
5211    return length+1;
5212
5213  int i;
5214  int an = 0;
5215  int en= length;
5216  loop
5217    {
5218      if (an >= en-1)
5219      {
5220        int oo=set[an].GetpFDeg();
5221        if((oo > op)
5222           || ((oo==op) && (set[an].pLength > ol)))
5223          return an;
5224        return en;
5225      }
5226      i=(an+en) / 2;
5227      int oo=set[i].GetpFDeg();
5228      if ((oo > op)
5229          || ((oo == op) && (set[i].pLength > ol)))
5230        en=i;
5231      else
5232        an=i;
5233    }
5234}
5235
5236
5237// determines the position based on: 1.) Ecart 2.) FDeg 3.) pLength
5238int posInT_pLength(const TSet set,const int length,LObject &p)
5239{
5240  if (length==-1)
5241    return 0;
5242  if (set[length].length<p.length)
5243    return length+1;
5244
5245  int i;
5246  int an = 0;
5247  int en= length;
5248  int ol = p.GetpLength();
5249
5250  loop
5251  {
5252    if (an >= en-1)
5253    {
5254      if (set[an].pLength>ol) return an;
5255      return en;
5256    }
5257    i=(an+en) / 2;
5258    if (set[i].pLength>ol) en=i;
5259    else                        an=i;
5260  }
5261}
5262
5263#endif
5264
5265#endif // KUTIL_CC
Note: See TracBrowser for help on using the repository browser.