source: git/kernel/kutil.cc @ 9b3ad3

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