source: git/kernel/kutil.cc @ c57134

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