source: git/kernel/kutil.cc @ b1c0a9

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