source: git/kernel/kutil.cc @ 7f06cca

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