source: git/Singular/kutil.cc @ 35aab3

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