source: git/kernel/kutil.cc @ 3c6379

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