source: git/kernel/kutil.cc @ a725dae

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