source: git/kernel/kutil.cc @ 91f1a3

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