source: git/kernel/kutil.cc @ 32ed4f

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