source: git/kernel/kutil.cc @ 1d9b39

spielwiese
Last change on this file since 1d9b39 was 76cfef, checked in by Oleksandr Motsak <motsak@…>, 13 years ago
FIX: fixed #includes in the kernel/ sources ADD: dummy headers in some strange cases
  • Property mode set to 100644
File size: 194.5 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id$ */
5/*
6* ABSTRACT: kernel: utils for kStd
7*/
8
9// #define PDEBUG 2
10// #define PDIV_DEBUG
11#define KUTIL_CC
12#include <stdlib.h>
13#include <string.h>
14#include <kernel/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 <omalloc/mylimits.h>
24#include <misc/options.h>
25#include <polys/nc/nc.h>
26#include <polys/nc/sca.h>
27#ifdef KDEBUG
28#undef KDEBUG
29#define KDEBUG 2
30#endif
31
32#ifdef HAVE_RINGS
33#include <kernel/ideals.h>
34#endif
35
36// define if enterL, enterT should use memmove instead of doing it manually
37// on topgun, this is slightly faster (see monodromy_l.tst, homog_gonnet.sing)
38#ifndef SunOS_4
39#define ENTER_USE_MEMMOVE
40#endif
41
42// define, if the my_memmove inlines should be used instead of
43// system memmove -- it does not seem to pay off, though
44// #define ENTER_USE_MYMEMMOVE
45
46#include <kernel/kutil.h>
47#include <polys/kbuckets.h>
48#include <kernel/febase.h>
49#include <omalloc/omalloc.h>
50#include <coeffs/numbers.h>
51#include <polys/polys.h>
52#include <polys/monomials/ring.h>
53#include <kernel/ideals.h>
54#include <kernel/timer.h>
55//#include "cntrlc.h"
56#include <kernel/stairc.h>
57#include <kernel/kstd1.h>
58#include <polys/operations/pShallowCopyDelete.h>
59
60/* shiftgb stuff */
61#include <kernel/shiftgb.h>
62#include <polys/prCopy.h>
63
64#ifdef HAVE_RATGRING
65#include <kernel/ratgring.h>
66#endif
67
68#ifdef KDEBUG
69#undef KDEBUG
70#define KDEBUG 2
71#endif
72
73denominator_list DENOMINATOR_LIST=NULL;
74
75
76#ifdef ENTER_USE_MYMEMMOVE
77inline void _my_memmove_d_gt_s(unsigned long* d, unsigned long* s, long l)
78{
79  register unsigned long* _dl = (unsigned long*) d;
80  register unsigned long* _sl = (unsigned long*) s;
81  register long _i = l - 1;
82
83  do
84  {
85    _dl[_i] = _sl[_i];
86    _i--;
87  }
88  while (_i >= 0);
89}
90
91inline void _my_memmove_d_lt_s(unsigned long* d, unsigned long* s, long l)
92{
93  register long _ll = l;
94  register unsigned long* _dl = (unsigned long*) d;
95  register unsigned long* _sl = (unsigned long*) s;
96  register long _i = 0;
97
98  do
99  {
100    _dl[_i] = _sl[_i];
101    _i++;
102  }
103  while (_i < _ll);
104}
105
106inline void _my_memmove(void* d, void* s, long l)
107{
108  unsigned long _d = (unsigned long) d;
109  unsigned long _s = (unsigned long) s;
110  unsigned long _l = ((l) + SIZEOF_LONG - 1) >> LOG_SIZEOF_LONG;
111
112  if (_d > _s) _my_memmove_d_gt_s(_d, _s, _l);
113  else _my_memmove_d_lt_s(_d, _s, _l);
114}
115
116#undef memmove
117#define memmove(d,s,l) _my_memmove(d, s, l)
118#endif
119
120static poly redMora (poly h,int maxIndex,kStrategy strat);
121static poly redBba (poly h,int maxIndex,kStrategy strat);
122
123#ifdef HAVE_RINGS
124#define pDivComp_EQUAL 2
125#define pDivComp_LESS 1
126#define pDivComp_GREATER -1
127#define pDivComp_INCOMP 0
128/* Checks the relation of LM(p) and LM(q)
129     LM(p) = LM(q) => return pDivComp_EQUAL
130     LM(p) | LM(q) => return pDivComp_LESS
131     LM(q) | LM(p) => return pDivComp_GREATER
132     else return pDivComp_INCOMP */
133static inline int pDivCompRing(poly p, poly q)
134{
135  if (pGetComp(p) == pGetComp(q))
136  {
137    BOOLEAN a=FALSE, b=FALSE;
138    int i;
139    unsigned long la, lb;
140    unsigned long divmask = currRing->divmask;
141    for (i=0; i<currRing->VarL_Size; i++)
142    {
143      la = p->exp[currRing->VarL_Offset[i]];
144      lb = q->exp[currRing->VarL_Offset[i]];
145      if (la != lb)
146      {
147        if (la < lb)
148        {
149          if (b) return pDivComp_INCOMP;
150          if (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask))
151            return pDivComp_INCOMP;
152          a = TRUE;
153        }
154        else
155        {
156          if (a) return pDivComp_INCOMP;
157          if (((la & divmask) ^ (lb & divmask)) != ((la - lb) & divmask))
158            return pDivComp_INCOMP;
159          b = TRUE;
160        }
161      }
162    }
163    if (a) return pDivComp_LESS;
164    if (b) return pDivComp_GREATER;
165    if (!a & !b) return pDivComp_EQUAL;
166  }
167  return pDivComp_INCOMP;
168}
169#endif
170
171static inline int pDivComp(poly p, poly q)
172{
173  if (pGetComp(p) == pGetComp(q))
174  {
175#ifdef HAVE_RATGRING
176    if (rIsRatGRing(currRing))
177    {
178      if (_p_LmDivisibleByPart(p,currRing,
179                           q,currRing,
180                           currRing->real_var_start, currRing->real_var_end))
181        return 0;
182      return pLmCmp(q,p); // ONLY FOR GLOBAL ORDER!
183    }
184#endif
185    BOOLEAN a=FALSE, b=FALSE;
186    int i;
187    unsigned long la, lb;
188    unsigned long divmask = currRing->divmask;
189    for (i=0; i<currRing->VarL_Size; i++)
190    {
191      la = p->exp[currRing->VarL_Offset[i]];
192      lb = q->exp[currRing->VarL_Offset[i]];
193      if (la != lb)
194      {
195        if (la < lb)
196        {
197          if (b) return 0;
198          if (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask))
199            return 0;
200          a = TRUE;
201        }
202        else
203        {
204          if (a) return 0;
205          if (((la & divmask) ^ (lb & divmask)) != ((la - lb) & divmask))
206            return 0;
207          b = TRUE;
208        }
209      }
210    }
211    if (a) { /*assume(pLmCmp(q,p)==1);*/ return 1; }
212    if (b) { /*assume(pLmCmp(q,p)==-1);*/return -1; }
213    /*assume(pLmCmp(q,p)==0);*/
214  }
215  return 0;
216}
217
218
219int     HCord;
220int     Kstd1_deg;
221int     Kstd1_mu=32000;
222
223/*2
224*deletes higher monomial of p, re-compute ecart and length
225*works only for orderings with ecart =pFDeg(end)-pFDeg(start)
226*/
227void deleteHC(LObject *L, kStrategy strat, BOOLEAN fromNext)
228{
229  if (strat->kHEdgeFound)
230  {
231    kTest_L(L);
232    poly p1;
233    poly p = L->GetLmTailRing();
234    int l = 1;
235    kBucket_pt bucket = NULL;
236    if (L->bucket != NULL)
237    {
238      kBucketClear(L->bucket, &pNext(p), &L->pLength);
239      L->pLength++;
240      bucket = L->bucket;
241      L->bucket = NULL;
242      L->last = NULL;
243    }
244
245    if (!fromNext && p_Cmp(p,strat->kNoetherTail(), L->tailRing) == -1)
246    {
247      L->Delete();
248      L->Clear();
249      L->ecart = -1;
250      if (bucket != NULL) kBucketDestroy(&bucket);
251      return;
252    }
253    p1 = p;
254    while (pNext(p1)!=NULL)
255    {
256      if (p_LmCmp(pNext(p1), strat->kNoetherTail(), L->tailRing) == -1)
257      {
258        L->last = p1;
259        p_Delete(&pNext(p1), L->tailRing);
260        if (p1 == p)
261        {
262          if (L->t_p != NULL)
263          {
264            assume(L->p != NULL && p == L->t_p);
265            pNext(L->p) = NULL;
266          }
267          L->max  = NULL;
268        }
269        else if (fromNext)
270          L->max  = p_GetMaxExpP(pNext(L->p), L->tailRing ); // p1;
271        //if (L->pLength != 0)
272        L->pLength = l;
273        // Hmmm when called from updateT, then only
274        // reset ecart when cut
275        if (fromNext)
276          L->ecart = L->pLDeg() - L->GetpFDeg();
277        break;
278      }
279      l++;
280      pIter(p1);
281    }
282    if (! fromNext)
283    {
284      L->SetpFDeg();
285      L->ecart = L->pLDeg(strat->LDegLast) - L->GetpFDeg();
286    }
287    if (bucket != NULL)
288    {
289      if (L->pLength > 1)
290      {
291        kBucketInit(bucket, pNext(p), L->pLength - 1);
292        pNext(p) = NULL;
293        if (L->t_p != NULL) pNext(L->t_p) = NULL;
294        L->pLength = 0;
295        L->bucket = bucket;
296        L->last = NULL;
297      }
298      else
299        kBucketDestroy(&bucket);
300    }
301    kTest_L(L);
302  }
303}
304
305void deleteHC(poly* p, int* e, int* l,kStrategy strat)
306{
307  LObject L(*p, currRing, strat->tailRing);
308
309  deleteHC(&L, strat);
310  *p = L.p;
311  *e = L.ecart;
312  *l = L.length;
313  if (L.t_p != NULL) p_LmFree(L.t_p, strat->tailRing);
314}
315
316/*2
317*tests if p.p=monomial*unit and cancels the unit
318*/
319void cancelunit (LObject* L,BOOLEAN inNF)
320{
321  int  i;
322  poly h;
323
324  if(rHasGlobalOrdering_currRing()) return;
325  if(TEST_OPT_CANCELUNIT) return;
326
327  ring r = L->tailRing;
328  poly p = L->GetLmTailRing();
329
330#ifdef HAVE_RINGS_LOC
331  // Leading coef have to be a unit
332  if ( !(nIsUnit(p_GetCoeff(p, r))) ) return;
333#endif
334
335  if(p_GetComp(p, r) != 0 && !p_OneComp(p, r)) return;
336
337//    for(i=r->N;i>0;i--)
338//    {
339//      if ((p_GetExp(p,i,r)>0) && (rIsPolyVar(i, r)==TRUE)) return;
340//    }
341  h = pNext(p);
342  loop
343  {
344    if (h==NULL)
345    {
346      p_Delete(&pNext(p), r);
347      if (!inNF)
348      {
349        number eins=nInit(1);
350        if (L->p != NULL)  pSetCoeff(L->p,eins);
351        else if (L->t_p != NULL) nDelete(&pGetCoeff(L->t_p));
352        if (L->t_p != NULL) pSetCoeff0(L->t_p,eins);
353      }
354      L->ecart = 0;
355      L->length = 1;
356      //if (L->pLength > 0)
357      L->pLength = 1;
358      if (L->last != NULL) L->last = p;
359      L->max = NULL;
360
361      if (L->t_p != NULL && pNext(L->t_p) != NULL)
362        pNext(L->t_p) = NULL;
363      if (L->p != NULL && pNext(L->p) != NULL)
364        pNext(L->p) = NULL;
365      return;
366    }
367    i = 0;
368    loop
369    {
370      i++;
371      if (p_GetExp(p,i,r) > p_GetExp(h,i,r)) return ; // does not divide
372      if (i == r->N) break; // does divide, try next monom
373    }
374    pIter(h);
375  }
376}
377
378/*2
379*pp is the new element in s
380*returns TRUE (in strat->kHEdgeFound) if
381*-HEcke is allowed
382*-we are in the last componente of the vector
383*-on all axis are monomials (all elements in NotUsedAxis are FALSE)
384*returns FALSE for pLexOrderings,
385*assumes in module case an ordering of type c* !!
386* HEckeTest is only called with strat->kHEdgeFound==FALSE !
387*/
388void HEckeTest (poly pp,kStrategy strat)
389{
390  int   j,k,p;
391
392  strat->kHEdgeFound=FALSE;
393  if (pLexOrder || currRing->MixedOrder)
394  {
395    return;
396  }
397  if (strat->ak > 1)           /*we are in the module case*/
398  {
399    return; // until ....
400    //if (!pVectorOut)     /*pVectorOut <=> order = c,* */
401    //  return FALSE;
402    //if (pGetComp(pp) < strat->ak) /* ak is the number of the last component */
403    //  return FALSE;
404  }
405  k = 0;
406  p=pIsPurePower(pp);
407  if (p!=0) strat->NotUsedAxis[p] = FALSE;
408  /*- the leading term of pp is a power of the p-th variable -*/
409  for (j=pVariables;j>0; j--)
410  {
411    if (strat->NotUsedAxis[j])
412    {
413      return;
414    }
415  }
416  strat->kHEdgeFound=TRUE;
417}
418
419/*2
420*utilities for TSet, LSet
421*/
422inline static intset initec (const int maxnr)
423{
424  return (intset)omAlloc(maxnr*sizeof(int));
425}
426
427inline static unsigned long* initsevS (const int maxnr)
428{
429  return (unsigned long*)omAlloc0(maxnr*sizeof(unsigned long));
430}
431inline static int* initS_2_R (const int maxnr)
432{
433  return (int*)omAlloc0(maxnr*sizeof(int));
434}
435
436static inline void enlargeT (TSet &T, TObject** &R, unsigned long* &sevT,
437                             int &length, const int incr)
438{
439  assume(T!=NULL);
440  assume(sevT!=NULL);
441  assume(R!=NULL);
442  assume((length+incr) > 0);
443
444  int i;
445  T = (TSet)omRealloc0Size(T, length*sizeof(TObject),
446                           (length+incr)*sizeof(TObject));
447
448  sevT = (unsigned long*) omReallocSize(sevT, length*sizeof(long*),
449                           (length+incr)*sizeof(long*));
450
451  R = (TObject**)omRealloc0Size(R,length*sizeof(TObject*),
452                                (length+incr)*sizeof(TObject*));
453  for (i=length-1;i>=0;i--) R[T[i].i_r] = &(T[i]);
454  length += incr;
455}
456
457void cleanT (kStrategy strat)
458{
459  int i,j;
460  poly  p;
461  assume(currRing == strat->tailRing || strat->tailRing != NULL);
462
463  pShallowCopyDeleteProc p_shallow_copy_delete =
464    (strat->tailRing != currRing ?
465     pGetShallowCopyDeleteProc(strat->tailRing, currRing) :
466     NULL);
467
468  for (j=0; j<=strat->tl; j++)
469  {
470    p = strat->T[j].p;
471    strat->T[j].p=NULL;
472    if (strat->T[j].max != NULL)
473    {
474      p_LmFree(strat->T[j].max, strat->tailRing);
475    }
476    i = -1;
477    loop
478    {
479      i++;
480      if (i>strat->sl)
481      {
482        if (strat->T[j].t_p != NULL)
483        {
484          p_Delete(&(strat->T[j].t_p), strat->tailRing);
485          p_LmFree(p, currRing);
486        }
487        else
488          pDelete(&p);
489        break;
490      }
491      if (p == strat->S[i])
492      {
493        if (strat->T[j].t_p != NULL)
494        {
495          assume(p_shallow_copy_delete != NULL);
496          pNext(p) = p_shallow_copy_delete(pNext(p),strat->tailRing,currRing,
497                                           currRing->PolyBin);
498          p_LmFree(strat->T[j].t_p, strat->tailRing);
499        }
500        break;
501      }
502    }
503  }
504  strat->tl=-1;
505}
506
507//LSet initL ()
508//{
509//  int i;
510//  LSet l = (LSet)omAlloc(setmaxL*sizeof(LObject));
511//  return l;
512//}
513
514static inline void enlargeL (LSet* L,int* length,const int incr)
515{
516  assume((*L)!=NULL);
517  assume((length+incr)>0);
518
519  *L = (LSet)omReallocSize((*L),(*length)*sizeof(LObject),
520                                   ((*length)+incr)*sizeof(LObject));
521  (*length) += incr;
522}
523
524void initPairtest(kStrategy strat)
525{
526  strat->pairtest = (BOOLEAN *)omAlloc0((strat->sl+2)*sizeof(BOOLEAN));
527}
528
529/*2
530*test whether (p1,p2) or (p2,p1) is in L up position length
531*it returns TRUE if yes and the position k
532*/
533BOOLEAN isInPairsetL(int length,poly p1,poly p2,int*  k,kStrategy strat)
534{
535  LObject *p=&(strat->L[length]);
536
537  *k = length;
538  loop
539  {
540    if ((*k) < 0) return FALSE;
541    if (((p1 == (*p).p1) && (p2 == (*p).p2))
542    ||  ((p1 == (*p).p2) && (p2 == (*p).p1)))
543      return TRUE;
544    (*k)--;
545    p--;
546  }
547}
548
549/*2
550*in B all pairs have the same element p on the right
551*it tests whether (q,p) is in B and returns TRUE if yes
552*and the position k
553*/
554BOOLEAN isInPairsetB(poly q,int*  k,kStrategy strat)
555{
556  LObject *p=&(strat->B[strat->Bl]);
557
558  *k = strat->Bl;
559  loop
560  {
561    if ((*k) < 0) return FALSE;
562    if (q == (*p).p1)
563      return TRUE;
564    (*k)--;
565    p--;
566  }
567}
568
569int kFindInT(poly p, TSet T, int tlength)
570{
571  int i;
572
573  for (i=0; i<=tlength; i++)
574  {
575    if (T[i].p == p) return i;
576  }
577  return -1;
578}
579
580int kFindInT(poly p, kStrategy strat)
581{
582  int i;
583  do
584  {
585    i = kFindInT(p, strat->T, strat->tl);
586    if (i >= 0) return i;
587    strat = strat->next;
588  }
589  while (strat != NULL);
590  return -1;
591}
592
593#ifdef KDEBUG
594
595void sTObject::wrp()
596{
597  if (t_p != NULL) p_wrp(t_p, tailRing);
598  else if (p != NULL) p_wrp(p, currRing, tailRing);
599  else ::wrp(NULL);
600}
601
602#define kFalseReturn(x) do { if (!x) return FALSE;} while (0)
603
604// check that Lm's of a poly from T are "equal"
605static const char* kTest_LmEqual(poly p, poly t_p, ring tailRing)
606{
607  int i;
608  for (i=1; i<=tailRing->N; i++)
609  {
610    if (p_GetExp(p, i, currRing) != p_GetExp(t_p, i, tailRing))
611      return "Lm[i] different";
612  }
613  if (p_GetComp(p, currRing) != p_GetComp(t_p, tailRing))
614    return "Lm[0] different";
615  if (pNext(p) != pNext(t_p))
616    return "Lm.next different";
617  if (pGetCoeff(p) != pGetCoeff(t_p))
618    return "Lm.coeff different";
619  return NULL;
620}
621
622static BOOLEAN sloppy_max = FALSE;
623BOOLEAN kTest_T(TObject * T, ring strat_tailRing, int i, char TN)
624{
625  ring tailRing = T->tailRing;
626  if (strat_tailRing == NULL) strat_tailRing = tailRing;
627  r_assume(strat_tailRing == tailRing);
628
629  poly p = T->p;
630  ring r = currRing;
631
632  if (T->p == NULL && T->t_p == NULL && i >= 0)
633    return dReportError("%c[%d].poly is NULL", TN, i);
634
635  if (T->tailRing != currRing)
636  {
637    if (T->t_p == NULL && i > 0)
638      return dReportError("%c[%d].t_p is NULL", TN, i);
639    pFalseReturn(p_Test(T->t_p, T->tailRing));
640    if (T->p != NULL) pFalseReturn(p_LmTest(T->p, currRing));
641    if (T->p != NULL && T->t_p != NULL)
642    {
643      const char* msg = kTest_LmEqual(T->p, T->t_p, T->tailRing);
644      if (msg != NULL)
645        return dReportError("%c[%d] %s", TN, i, msg);
646      r = T->tailRing;
647      p = T->t_p;
648    }
649    if (T->p == NULL)
650    {
651      p = T->t_p;
652      r = T->tailRing;
653    }
654    if (T->t_p != NULL && i >= 0 && TN == 'T')
655    {
656      if (pNext(T->t_p) == NULL)
657      {
658        if (T->max != NULL)
659          return dReportError("%c[%d].max is not NULL as it should be", TN, i);
660      }
661      else
662      {
663        if (T->max == NULL)
664          return dReportError("%c[%d].max is NULL", TN, i);
665        if (pNext(T->max) != NULL)
666          return dReportError("pNext(%c[%d].max) != NULL", TN, i);
667
668        pFalseReturn(p_CheckPolyRing(T->max, tailRing));
669        omCheckBinAddrSize(T->max, (tailRing->PolyBin->sizeW)*SIZEOF_LONG);
670#if KDEBUG > 0
671        if (! sloppy_max)
672        {
673          poly test_max = p_GetMaxExpP(pNext(T->t_p), tailRing);
674          p_Setm(T->max, tailRing);
675          p_Setm(test_max, tailRing);
676          BOOLEAN equal = p_ExpVectorEqual(T->max, test_max, tailRing);
677          if (! equal)
678            return dReportError("%c[%d].max out of sync", TN, i);
679          p_LmFree(test_max, tailRing);
680        }
681#endif
682      }
683    }
684  }
685  else
686  {
687    if (T->max != NULL)
688      return dReportError("%c[%d].max != NULL but tailRing == currRing",TN,i);
689    if (T->t_p != NULL)
690      return dReportError("%c[%d].t_p != NULL but tailRing == currRing",TN,i);
691    if (T->p == NULL && i > 0)
692      return dReportError("%c[%d].p is NULL", TN, i);
693    pFalseReturn(p_Test(T->p, currRing));
694  }
695
696  if (i >= 0 && T->pLength != 0
697  && ! rIsSyzIndexRing(currRing) && T->pLength != pLength(p))
698  {
699    int l=T->pLength;
700    T->pLength=pLength(p);
701    return dReportError("%c[%d] pLength error: has %d, specified to have %d",
702                        TN, i , pLength(p), l);
703  }
704
705  // check FDeg,  for elements in L and T
706  if (i >= 0 && (TN == 'T' || TN == 'L'))
707  {
708    // FDeg has ir element from T of L set
709    if (T->FDeg  != T->pFDeg())
710    {
711      int d=T->FDeg;
712      T->FDeg=T->pFDeg();
713      return dReportError("%c[%d] FDeg error: has %d, specified to have %d",
714                          TN, i , T->pFDeg(), d);
715    }
716  }
717
718  // check is_normalized for elements in T
719  if (i >= 0 && TN == 'T')
720  {
721    if (T->is_normalized && ! nIsOne(pGetCoeff(p)))
722      return dReportError("T[%d] is_normalized error", i);
723
724  }
725  return TRUE;
726}
727
728BOOLEAN kTest_L(LObject *L, ring strat_tailRing,
729                BOOLEAN testp, int lpos, TSet T, int tlength)
730{
731  if (testp)
732  {
733    poly pn = NULL;
734    if (L->bucket != NULL)
735    {
736      kFalseReturn(kbTest(L->bucket));
737      r_assume(L->bucket->bucket_ring == L->tailRing);
738      if (L->p != NULL && pNext(L->p) != NULL)
739      {
740        pn = pNext(L->p);
741        pNext(L->p) = NULL;
742      }
743    }
744    kFalseReturn(kTest_T(L, strat_tailRing, lpos, 'L'));
745    if (pn != NULL)
746      pNext(L->p) = pn;
747
748    ring r;
749    poly p;
750    L->GetLm(p, r);
751    if (L->sev != 0 && p_GetShortExpVector(p, r) != L->sev)
752    {
753      return dReportError("L[%d] wrong sev: has %o, specified to have %o",
754                          lpos, p_GetShortExpVector(p, r), L->sev);
755    }
756    if (lpos > 0 && L->last != NULL && pLast(p) != L->last)
757    {
758      return dReportError("L[%d] last wrong: has %p specified to have %p",
759                          lpos, pLast(p), L->last);
760    }
761  }
762  if (L->p1 == NULL)
763  {
764    // L->p2 either NULL or "normal" poly
765    pFalseReturn(pp_Test(L->p2, currRing, L->tailRing));
766  }
767  else if (tlength > 0 && T != NULL && (lpos >=0))
768  {
769    // now p1 and p2 must be != NULL and must be contained in T
770    int i;
771    i = kFindInT(L->p1, T, tlength);
772    if (i < 0)
773      return dReportError("L[%d].p1 not in T",lpos);
774    i = kFindInT(L->p2, T, tlength);
775    if (i < 0)
776      return dReportError("L[%d].p2 not in T",lpos);
777  }
778  return TRUE;
779}
780
781BOOLEAN kTest (kStrategy strat)
782{
783  int i;
784
785  // test P
786  kFalseReturn(kTest_L(&(strat->P), strat->tailRing,
787                       (strat->P.p != NULL && pNext(strat->P.p)!=strat->tail),
788                       -1, strat->T, strat->tl));
789
790  // test T
791  if (strat->T != NULL)
792  {
793    for (i=0; i<=strat->tl; i++)
794    {
795      kFalseReturn(kTest_T(&(strat->T[i]), strat->tailRing, i, 'T'));
796      if (strat->sevT[i] != pGetShortExpVector(strat->T[i].p))
797        return dReportError("strat->sevT[%d] out of sync", i);
798    }
799  }
800
801  // test L
802  if (strat->L != NULL)
803  {
804    for (i=0; i<=strat->Ll; i++)
805    {
806      kFalseReturn(kTest_L(&(strat->L[i]), strat->tailRing,
807                           strat->L[i].Next() != strat->tail, i,
808                           strat->T, strat->tl));
809      // may be unused
810      //if (strat->use_buckets && strat->L[i].Next() != strat->tail &&
811      //    strat->L[i].Next() != NULL && strat->L[i].p1 != NULL)
812      //{
813      //  assume(strat->L[i].bucket != NULL);
814      //}
815    }
816  }
817
818  // test S
819  if (strat->S != NULL)
820    kFalseReturn(kTest_S(strat));
821
822  return TRUE;
823}
824
825BOOLEAN kTest_S(kStrategy strat)
826{
827  int i;
828  BOOLEAN ret = TRUE;
829  for (i=0; i<=strat->sl; i++)
830  {
831    if (strat->S[i] != NULL &&
832        strat->sevS[i] != pGetShortExpVector(strat->S[i]))
833    {
834      return dReportError("S[%d] wrong sev: has %o, specified to have %o",
835                          i , pGetShortExpVector(strat->S[i]), strat->sevS[i]);
836    }
837  }
838  return ret;
839}
840
841
842
843BOOLEAN kTest_TS(kStrategy strat)
844{
845  int i, j;
846  BOOLEAN ret = TRUE;
847  kFalseReturn(kTest(strat));
848
849  // test strat->R, strat->T[i].i_r
850  for (i=0; i<=strat->tl; i++)
851  {
852    if (strat->T[i].i_r < 0 || strat->T[i].i_r > strat->tl)
853      return dReportError("strat->T[%d].i_r == %d out of bounds", i,
854                          strat->T[i].i_r);
855    if (strat->R[strat->T[i].i_r] != &(strat->T[i]))
856      return dReportError("T[%d].i_r with R out of sync", i);
857  }
858  // test containment of S inT
859  if (strat->S != NULL)
860  {
861    for (i=0; i<=strat->sl; i++)
862    {
863      j = kFindInT(strat->S[i], strat->T, strat->tl);
864      if (j < 0)
865        return dReportError("S[%d] not in T", i);
866      if (strat->S_2_R[i] != strat->T[j].i_r)
867        return dReportError("S_2_R[%d]=%d != T[%d].i_r=%d\n",
868                            i, strat->S_2_R[i], j, strat->T[j].i_r);
869    }
870  }
871  // test strat->L[i].i_r1
872  for (i=0; i<=strat->Ll; i++)
873  {
874    if (strat->L[i].p1 != NULL && strat->L[i].p2)
875    {
876      if (strat->L[i].i_r1 < 0 ||
877          strat->L[i].i_r1 > strat->tl ||
878          strat->L[i].T_1(strat)->p != strat->L[i].p1)
879        return dReportError("L[%d].i_r1 out of sync", i);
880      if (strat->L[i].i_r2 < 0 ||
881          strat->L[i].i_r2 > strat->tl ||
882          strat->L[i].T_2(strat)->p != strat->L[i].p2);
883    }
884    else
885    {
886      if (strat->L[i].i_r1 != -1)
887        return dReportError("L[%d].i_r1 out of sync", i);
888      if (strat->L[i].i_r2 != -1)
889        return dReportError("L[%d].i_r2 out of sync", i);
890    }
891    if (strat->L[i].i_r != -1)
892      return dReportError("L[%d].i_r out of sync", i);
893  }
894  return TRUE;
895}
896
897#endif // KDEBUG
898
899/*2
900*cancels the i-th polynomial in the standardbase s
901*/
902void deleteInS (int i,kStrategy strat)
903{
904#ifdef ENTER_USE_MEMMOVE
905  memmove(&(strat->S[i]), &(strat->S[i+1]), (strat->sl - i)*sizeof(poly));
906  memmove(&(strat->ecartS[i]),&(strat->ecartS[i+1]),(strat->sl - i)*sizeof(int));
907  memmove(&(strat->sevS[i]),&(strat->sevS[i+1]),(strat->sl - i)*sizeof(long));
908  memmove(&(strat->S_2_R[i]),&(strat->S_2_R[i+1]),(strat->sl - i)*sizeof(int));
909#else
910  int j;
911  for (j=i; j<strat->sl; j++)
912  {
913    strat->S[j] = strat->S[j+1];
914    strat->ecartS[j] = strat->ecartS[j+1];
915    strat->sevS[j] = strat->sevS[j+1];
916    strat->S_2_R[j] = strat->S_2_R[j+1];
917  }
918#endif
919  if (strat->lenS!=NULL)
920  {
921#ifdef ENTER_USE_MEMMOVE
922    memmove(&(strat->lenS[i]),&(strat->lenS[i+1]),(strat->sl - i)*sizeof(int));
923#else
924    for (j=i; j<strat->sl; j++) strat->lenS[j] = strat->lenS[j+1];
925#endif
926  }
927  if (strat->lenSw!=NULL)
928  {
929#ifdef ENTER_USE_MEMMOVE
930    memmove(&(strat->lenSw[i]),&(strat->lenSw[i+1]),(strat->sl - i)*sizeof(wlen_type));
931#else
932    for (j=i; j<strat->sl; j++) strat->lenSw[j] = strat->lenSw[j+1];
933#endif
934  }
935  if (strat->fromQ!=NULL)
936  {
937#ifdef ENTER_USE_MEMMOVE
938    memmove(&(strat->fromQ[i]),&(strat->fromQ[i+1]),(strat->sl - i)*sizeof(int));
939#else
940    for (j=i; j<strat->sl; j++)
941    {
942      strat->fromQ[j] = strat->fromQ[j+1];
943    }
944#endif
945  }
946  strat->S[strat->sl] = NULL;
947  strat->sl--;
948}
949
950/*2
951*cancels the j-th polynomial in the set
952*/
953void deleteInL (LSet set, int *length, int j,kStrategy strat)
954{
955  if (set[j].lcm!=NULL)
956  {
957#ifdef HAVE_RINGS
958    if (pGetCoeff(set[j].lcm) != NULL)
959      pLmDelete(set[j].lcm);
960    else
961#endif
962      pLmFree(set[j].lcm);
963  }
964  if (set[j].p!=NULL)
965  {
966    if (pNext(set[j].p) == strat->tail)
967    {
968#ifdef HAVE_RINGS
969      if (pGetCoeff(set[j].p) != NULL)
970        pLmDelete(set[j].p);
971      else
972#endif
973        pLmFree(set[j].p);
974      /*- tail belongs to several int spolys -*/
975    }
976    else
977    {
978      // search p in T, if it is there, do not delete it
979      if (pOrdSgn != -1 || kFindInT(set[j].p, strat) < 0)
980      {
981        // assure that for global orderings kFindInT fails
982        assume(pOrdSgn == -1 || kFindInT(set[j].p, strat) < 0);
983        set[j].Delete();
984      }
985    }
986  }
987  if (*length > 0 && j < *length)
988  {
989#ifdef ENTER_USE_MEMMOVE
990    memmove(&(set[j]), &(set[j+1]), (*length - j)*sizeof(LObject));
991#else
992    int i;
993    for (i=j; i < (*length); i++)
994      set[i] = set[i+1];
995#endif
996  }
997#ifdef KDEBUG
998  memset(&(set[*length]),0,sizeof(LObject));
999#endif
1000  (*length)--;
1001}
1002
1003/*2
1004*enters p at position at in L
1005*/
1006void enterL (LSet *set,int *length, int *LSetmax, LObject p,int at)
1007{
1008#ifdef PDEBUG
1009  /*  zaehler++; */
1010#endif /*PDEBUG*/
1011  int i;
1012  // this should be corrected
1013  assume(p.FDeg == p.pFDeg());
1014
1015  if ((*length)>=0)
1016  {
1017    if ((*length) == (*LSetmax)-1) enlargeL(set,LSetmax,setmaxLinc);
1018    if (at <= (*length))
1019#ifdef ENTER_USE_MEMMOVE
1020      memmove(&((*set)[at+1]), &((*set)[at]), ((*length)-at+1)*sizeof(LObject));
1021#else
1022    for (i=(*length)+1; i>=at+1; i--) (*set)[i] = (*set)[i-1];
1023#endif
1024  }
1025  else at = 0;
1026  (*set)[at] = p;
1027  (*length)++;
1028}
1029
1030/*2
1031* computes the normal ecart;
1032* used in mora case and if pLexOrder & sugar in bba case
1033*/
1034void initEcartNormal (LObject* h)
1035{
1036  h->FDeg = h->pFDeg();
1037  h->ecart = h->pLDeg() - h->FDeg;
1038  // h->length is set by h->pLDeg
1039  h->length=h->pLength=pLength(h->p);
1040}
1041
1042void initEcartBBA (LObject* h)
1043{
1044  h->FDeg = h->pFDeg();
1045  (*h).ecart = 0;
1046  h->length=h->pLength=pLength(h->p);
1047}
1048
1049void initEcartPairBba (LObject* Lp,poly f,poly g,int ecartF,int ecartG)
1050{
1051  Lp->FDeg = Lp->pFDeg();
1052  (*Lp).ecart = 0;
1053  (*Lp).length = 0;
1054}
1055
1056void initEcartPairMora (LObject* Lp,poly f,poly g,int ecartF,int ecartG)
1057{
1058  Lp->FDeg = Lp->pFDeg();
1059  (*Lp).ecart = si_max(ecartF,ecartG);
1060  (*Lp).ecart = (*Lp).ecart- (Lp->FDeg -pFDeg((*Lp).lcm,currRing));
1061  (*Lp).length = 0;
1062}
1063
1064/*2
1065*if ecart1<=ecart2 it returns TRUE
1066*/
1067static inline BOOLEAN sugarDivisibleBy(int ecart1, int ecart2)
1068{
1069  return (ecart1 <= ecart2);
1070}
1071
1072#ifdef HAVE_RINGS
1073/*2
1074* put the pair (s[i],p)  into the set B, ecart=ecart(p) (ring case)
1075*/
1076void enterOnePairRing (int i,poly p,int ecart, int isFromQ,kStrategy strat, int atR = -1)
1077{
1078  assume(i<=strat->sl);
1079  int      l,j,compare,compareCoeff;
1080  LObject  Lp;
1081
1082  if (strat->interred_flag) return;
1083#ifdef KDEBUG
1084  Lp.ecart=0; Lp.length=0;
1085#endif
1086  /*- computes the lcm(s[i],p) -*/
1087  Lp.lcm = pInit();
1088  pSetCoeff0(Lp.lcm, nLcm(pGetCoeff(p), pGetCoeff(strat->S[i]), currRing));
1089  // Lp.lcm == 0
1090  if (nIsZero(pGetCoeff(Lp.lcm)))
1091  {
1092#ifdef KDEBUG
1093      if (TEST_OPT_DEBUG)
1094      {
1095        PrintS("--- Lp.lcm == 0\n");
1096        PrintS("p:");
1097        wrp(p);
1098        Print("  strat->S[%d]:", i);
1099        wrp(strat->S[i]);
1100        PrintLn();
1101      }
1102#endif
1103      strat->cp++;
1104      pLmDelete(Lp.lcm);
1105      return;
1106  }
1107  // basic product criterion
1108  pLcm(p,strat->S[i],Lp.lcm);
1109  pSetm(Lp.lcm);
1110  assume(!strat->sugarCrit);
1111  if (pHasNotCF(p,strat->S[i]) && nIsUnit(pGetCoeff(p)) && nIsUnit(pGetCoeff(strat->S[i])))
1112  {
1113#ifdef KDEBUG
1114      if (TEST_OPT_DEBUG)
1115      {
1116        PrintS("--- product criterion func enterOnePairRing type 1\n");
1117        PrintS("p:");
1118        wrp(p);
1119        Print("  strat->S[%d]:", i);
1120        wrp(strat->S[i]);
1121        PrintLn();
1122      }
1123#endif
1124      strat->cp++;
1125      pLmDelete(Lp.lcm);
1126      return;
1127  }
1128  assume(!strat->fromT);
1129  /*
1130  *the set B collects the pairs of type (S[j],p)
1131  *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p) != lcm(r,p)
1132  *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
1133  *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
1134  */
1135  for(j = strat->Bl;j>=0;j--)
1136  {
1137    compare=pDivCompRing(strat->B[j].lcm,Lp.lcm);
1138    compareCoeff = nDivComp(pGetCoeff(strat->B[j].lcm), pGetCoeff(Lp.lcm));
1139    if (compareCoeff == pDivComp_EQUAL || compare == compareCoeff)
1140    {
1141      if (compare == 1)
1142      {
1143        strat->c3++;
1144#ifdef KDEBUG
1145        if (TEST_OPT_DEBUG)
1146        {
1147          PrintS("--- chain criterion type 1\n");
1148          PrintS("strat->B[j]:");
1149          wrp(strat->B[j].lcm);
1150          PrintS("  Lp.lcm:");
1151          wrp(Lp.lcm);
1152          PrintLn();
1153        }
1154#endif
1155        if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1156        {
1157          pLmDelete(Lp.lcm);
1158          return;
1159        }
1160        break;
1161      }
1162      else
1163      if (compare == -1)
1164      {
1165#ifdef KDEBUG
1166        if (TEST_OPT_DEBUG)
1167        {
1168          PrintS("--- chain criterion type 2\n");
1169          Print("strat->B[%d].lcm:",j);
1170          wrp(strat->B[j].lcm);
1171          PrintS("  Lp.lcm:");
1172          wrp(Lp.lcm);
1173          PrintLn();
1174        }
1175#endif
1176        deleteInL(strat->B,&strat->Bl,j,strat);
1177        strat->c3++;
1178      }
1179    }
1180    if ((compare == pDivComp_EQUAL) && (compareCoeff != 2))
1181    {
1182      if (compareCoeff == pDivComp_LESS)
1183      {
1184#ifdef KDEBUG
1185        if (TEST_OPT_DEBUG)
1186        {
1187          PrintS("--- chain criterion type 3\n");
1188          Print("strat->B[%d].lcm:", j);
1189          wrp(strat->B[j].lcm);
1190          PrintS("  Lp.lcm:");
1191          wrp(Lp.lcm);
1192          PrintLn();
1193        }
1194#endif
1195        strat->c3++;
1196        if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1197        {
1198          pLmDelete(Lp.lcm);
1199          return;
1200        }
1201        break;
1202      }
1203      else
1204      // Add hint for same LM and LC (later) (TODO Oliver)
1205      // if (compareCoeff == pDivComp_GREATER)
1206      {
1207#ifdef KDEBUG
1208        if (TEST_OPT_DEBUG)
1209        {
1210          PrintS("--- chain criterion type 4\n");
1211          Print("strat->B[%d].lcm:", j);
1212          wrp(strat->B[j].lcm);
1213          PrintS("  Lp.lcm:");
1214          wrp(Lp.lcm);
1215          PrintLn();
1216        }
1217#endif
1218        deleteInL(strat->B,&strat->Bl,j,strat);
1219        strat->c3++;
1220      }
1221    }
1222  }
1223  /*
1224  *the pair (S[i],p) enters B if the spoly != 0
1225  */
1226  /*-  compute the short s-polynomial -*/
1227  if ((strat->S[i]==NULL) || (p==NULL)) {
1228#ifdef KDEBUG
1229    if (TEST_OPT_DEBUG)
1230    {
1231      PrintS("--- spoly = NULL\n");
1232    }
1233#endif
1234    pLmDelete(Lp.lcm);
1235    return;
1236  }
1237  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (strat->fromQ[i]!=0))
1238  {
1239    // Is from a previous computed GB, therefore we know that spoly will
1240    // reduce to zero. Oliver.
1241    WarnS("Could we come here? 8738947389");
1242    Lp.p=NULL;
1243  }
1244  else
1245  {
1246    Lp.p = ksCreateShortSpoly(strat->S[i], p, strat->tailRing);
1247  }
1248  if (Lp.p == NULL)
1249  {
1250#ifdef KDEBUG
1251    if (TEST_OPT_DEBUG)
1252    {
1253      PrintS("--- spoly = NULL\n");
1254    }
1255#endif
1256    /*- the case that the s-poly is 0 -*/
1257    if (strat->pairtest==NULL) initPairtest(strat);
1258    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
1259    strat->pairtest[strat->sl+1] = TRUE;
1260    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
1261    /*
1262    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
1263    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
1264    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
1265    *term of p devides the lcm(s,r)
1266    *(this canceling should be done here because
1267    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
1268    *the first case is handeled in chainCrit
1269    */
1270    pLmDelete(Lp.lcm);
1271  }
1272  else
1273  {
1274    /*- the pair (S[i],p) enters B -*/
1275    Lp.p1 = strat->S[i];
1276    Lp.p2 = p;
1277
1278    pNext(Lp.p) = strat->tail;
1279
1280    if (atR >= 0)
1281    {
1282      Lp.i_r2 = atR;
1283      Lp.i_r1 = strat->S_2_R[i];
1284    }
1285    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
1286    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
1287    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
1288  }
1289}
1290
1291
1292/*2
1293* put the  lcm(s[i],p)  into the set B
1294*/
1295
1296BOOLEAN enterOneStrongPoly (int i,poly p,int ecart, int isFromQ,kStrategy strat, int atR = -1)
1297{
1298  number d, s, t;
1299  assume(i<=strat->sl);
1300  assume(atR >= 0);
1301  poly m1, m2, gcd;
1302
1303  d = nExtGcd(pGetCoeff(p), pGetCoeff(strat->S[i]), &s, &t);
1304
1305  if (nIsZero(s) || nIsZero(t))  // evtl. durch divBy tests ersetzen
1306  {
1307    nDelete(&d);
1308    nDelete(&s);
1309    nDelete(&t);
1310    return FALSE;
1311  }
1312
1313  k_GetStrongLeadTerms(p, strat->S[i], currRing, m1, m2, gcd, strat->tailRing);
1314  //p_Test(m1,strat->tailRing);
1315  //p_Test(m2,strat->tailRing);
1316  while (! kCheckStrongCreation(atR, m1, i, m2, strat) )
1317  {
1318    memset(&(strat->P), 0, sizeof(strat->P));
1319    kStratChangeTailRing(strat);
1320    strat->P = *(strat->R[atR]);
1321    p_LmFree(m1, strat->tailRing);
1322    p_LmFree(m2, strat->tailRing);
1323    p_LmFree(gcd, currRing);
1324    k_GetStrongLeadTerms(p, strat->S[i], currRing, m1, m2, gcd, strat->tailRing);
1325  }
1326  pSetCoeff0(m1, s);
1327  pSetCoeff0(m2, t);
1328  pSetCoeff0(gcd, d);
1329  p_Test(m1,strat->tailRing);
1330  p_Test(m2,strat->tailRing);
1331
1332#ifdef KDEBUG
1333  if (TEST_OPT_DEBUG)
1334  {
1335    // Print("t = %d; s = %d; d = %d\n", nInt(t), nInt(s), nInt(d));
1336    PrintS("m1 = ");
1337    p_wrp(m1, strat->tailRing);
1338    PrintS(" ; m2 = ");
1339    p_wrp(m2, strat->tailRing);
1340    PrintS(" ; gcd = ");
1341    wrp(gcd);
1342    PrintS("\n--- create strong gcd poly: ");
1343    Print("\n p: ", i);
1344    wrp(p);
1345    Print("\n strat->S[%d]: ", i);
1346    wrp(strat->S[i]);
1347    PrintS(" ---> ");
1348  }
1349#endif
1350
1351  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);
1352  p_LmDelete(m1, strat->tailRing);
1353  p_LmDelete(m2, strat->tailRing);
1354
1355#ifdef KDEBUG
1356  if (TEST_OPT_DEBUG)
1357  {
1358    wrp(gcd);
1359    PrintLn();
1360  }
1361#endif
1362
1363  LObject h;
1364  h.p = gcd;
1365  h.tailRing = strat->tailRing;
1366  int posx;
1367  h.pCleardenom();
1368  strat->initEcart(&h);
1369  if (strat->Ll==-1)
1370    posx =0;
1371  else
1372    posx = strat->posInL(strat->L,strat->Ll,&h,strat);
1373  h.sev = pGetShortExpVector(h.p);
1374  if (currRing!=strat->tailRing)
1375    h.t_p = k_LmInit_currRing_2_tailRing(h.p, strat->tailRing);
1376  enterL(&strat->L,&strat->Ll,&strat->Lmax,h,posx);
1377  return TRUE;
1378}
1379#endif
1380
1381/*2
1382* put the pair (s[i],p)  into the set B, ecart=ecart(p)
1383*/
1384
1385void enterOnePairNormal (int i,poly p,int ecart, int isFromQ,kStrategy strat, int atR = -1)
1386{
1387  assume(i<=strat->sl);
1388  if (strat->interred_flag) return;
1389
1390  int      l,j,compare;
1391  LObject  Lp;
1392  Lp.i_r = -1;
1393
1394#ifdef KDEBUG
1395  Lp.ecart=0; Lp.length=0;
1396#endif
1397  /*- computes the lcm(s[i],p) -*/
1398  Lp.lcm = pInit();
1399
1400#ifndef HAVE_RATGRING
1401  pLcm(p,strat->S[i],Lp.lcm);
1402#elif defined(HAVE_RATGRING)
1403  //  if (rIsRatGRing(currRing))
1404  pLcmRat(p,strat->S[i],Lp.lcm, currRing->real_var_start); // int rat_shift
1405#endif
1406  pSetm(Lp.lcm);
1407
1408
1409  if (strat->sugarCrit && ALLOW_PROD_CRIT(strat))
1410  {
1411    if((!((strat->ecartS[i]>0)&&(ecart>0)))
1412    && pHasNotCF(p,strat->S[i]))
1413    {
1414    /*
1415    *the product criterion has applied for (s,p),
1416    *i.e. lcm(s,p)=product of the leading terms of s and p.
1417    *Suppose (s,r) is in L and the leading term
1418    *of p divides lcm(s,r)
1419    *(==> the leading term of p divides the leading term of r)
1420    *but the leading term of s does not divide the leading term of r
1421    *(notice that tis condition is automatically satisfied if r is still
1422    *in S), then (s,r) can be cancelled.
1423    *This should be done here because the
1424    *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
1425    *
1426    *Moreover, skipping (s,r) holds also for the noncommutative case.
1427    */
1428      strat->cp++;
1429      pLmFree(Lp.lcm);
1430      Lp.lcm=NULL;
1431      return;
1432    }
1433    else
1434      Lp.ecart = si_max(ecart,strat->ecartS[i]);
1435    if (strat->fromT && (strat->ecartS[i]>ecart))
1436    {
1437      pLmFree(Lp.lcm);
1438      Lp.lcm=NULL;
1439      return;
1440      /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
1441    }
1442    /*
1443    *the set B collects the pairs of type (S[j],p)
1444    *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
1445    *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
1446    *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
1447    */
1448    {
1449      j = strat->Bl;
1450      loop
1451      {
1452        if (j < 0)  break;
1453        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
1454        if ((compare==1)
1455        &&(sugarDivisibleBy(strat->B[j].ecart,Lp.ecart)))
1456        {
1457          strat->c3++;
1458          if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1459          {
1460            pLmFree(Lp.lcm);
1461            return;
1462          }
1463          break;
1464        }
1465        else
1466        if ((compare ==-1)
1467        && sugarDivisibleBy(Lp.ecart,strat->B[j].ecart))
1468        {
1469          deleteInL(strat->B,&strat->Bl,j,strat);
1470          strat->c3++;
1471        }
1472        j--;
1473      }
1474    }
1475  }
1476  else /*sugarcrit*/
1477  {
1478    if (ALLOW_PROD_CRIT(strat))
1479    {
1480      // if currRing->nc_type!=quasi (or skew)
1481      // TODO: enable productCrit for super commutative algebras...
1482      if(/*(strat->ak==0) && productCrit(p,strat->S[i])*/
1483      pHasNotCF(p,strat->S[i]))
1484      {
1485      /*
1486      *the product criterion has applied for (s,p),
1487      *i.e. lcm(s,p)=product of the leading terms of s and p.
1488      *Suppose (s,r) is in L and the leading term
1489      *of p devides lcm(s,r)
1490      *(==> the leading term of p devides the leading term of r)
1491      *but the leading term of s does not devide the leading term of r
1492      *(notice that tis condition is automatically satisfied if r is still
1493      *in S), then (s,r) can be canceled.
1494      *This should be done here because the
1495      *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
1496      */
1497          strat->cp++;
1498          pLmFree(Lp.lcm);
1499          Lp.lcm=NULL;
1500          return;
1501      }
1502      if (strat->fromT && (strat->ecartS[i]>ecart))
1503      {
1504        pLmFree(Lp.lcm);
1505        Lp.lcm=NULL;
1506        return;
1507        /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
1508      }
1509      /*
1510      *the set B collects the pairs of type (S[j],p)
1511      *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
1512      *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
1513      *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
1514      */
1515      for(j = strat->Bl;j>=0;j--)
1516      {
1517        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
1518        if (compare==1)
1519        {
1520          strat->c3++;
1521          if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1522          {
1523            pLmFree(Lp.lcm);
1524            return;
1525          }
1526          break;
1527        }
1528        else
1529        if (compare ==-1)
1530        {
1531          deleteInL(strat->B,&strat->Bl,j,strat);
1532          strat->c3++;
1533        }
1534      }
1535    }
1536  }
1537  /*
1538  *the pair (S[i],p) enters B if the spoly != 0
1539  */
1540  /*-  compute the short s-polynomial -*/
1541  if (strat->fromT && !TEST_OPT_INTSTRATEGY)
1542    pNorm(p);
1543
1544  if ((strat->S[i]==NULL) || (p==NULL))
1545    return;
1546
1547  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (strat->fromQ[i]!=0))
1548    Lp.p=NULL;
1549  else
1550  {
1551    #ifdef HAVE_PLURAL
1552    if ( rIsPluralRing(currRing) )
1553    {
1554      if(pHasNotCF(p, strat->S[i]))
1555      {
1556         if(ncRingType(currRing) == nc_lie)
1557         {
1558             // generalized prod-crit for lie-type
1559             strat->cp++;
1560             Lp.p = nc_p_Bracket_qq(pCopy(p),strat->S[i]);
1561         }
1562         else
1563        if( ALLOW_PROD_CRIT(strat) )
1564        {
1565            // product criterion for homogeneous case in SCA
1566            strat->cp++;
1567            Lp.p = NULL;
1568        }
1569        else
1570        {
1571          Lp.p = // nc_CreateSpoly(strat->S[i],p,currRing);
1572                nc_CreateShortSpoly(strat->S[i], p, currRing);
1573
1574          assume(pNext(Lp.p)==NULL); // TODO: this may be violated whenever ext.prod.crit. for Lie alg. is used
1575          pNext(Lp.p) = strat->tail; // !!!
1576        }
1577      }
1578      else
1579      {
1580        Lp.p = // nc_CreateSpoly(strat->S[i],p,currRing);
1581              nc_CreateShortSpoly(strat->S[i], p, currRing);
1582
1583        assume(pNext(Lp.p)==NULL); // TODO: this may be violated whenever ext.prod.crit. for Lie alg. is used
1584        pNext(Lp.p) = strat->tail; // !!!
1585
1586      }
1587
1588
1589#if MYTEST
1590      if (TEST_OPT_DEBUG)
1591      {
1592        PrintS("enterOnePairNormal::\n strat->S[i]: "); pWrite(strat->S[i]);
1593        PrintS("p: "); pWrite(p);
1594        PrintS("SPoly: "); pWrite(Lp.p);
1595      }
1596#endif
1597
1598    }
1599    else
1600    #endif
1601    {
1602      assume(!rIsPluralRing(currRing));
1603      Lp.p = ksCreateShortSpoly(strat->S[i], p, strat->tailRing);
1604#if MYTEST
1605      if (TEST_OPT_DEBUG)
1606      {
1607        PrintS("enterOnePairNormal::\n strat->S[i]: "); pWrite(strat->S[i]);
1608        PrintS("p: "); pWrite(p);
1609        PrintS("commutative SPoly: "); pWrite(Lp.p);
1610      }
1611#endif
1612
1613      }
1614  }
1615  if (Lp.p == NULL)
1616  {
1617    /*- the case that the s-poly is 0 -*/
1618    if (strat->pairtest==NULL) initPairtest(strat);
1619    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
1620    strat->pairtest[strat->sl+1] = TRUE;
1621    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
1622    /*
1623    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
1624    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
1625    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
1626    *term of p devides the lcm(s,r)
1627    *(this canceling should be done here because
1628    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
1629    *the first case is handeled in chainCrit
1630    */
1631    if (Lp.lcm!=NULL) pLmFree(Lp.lcm);
1632  }
1633  else
1634  {
1635    /*- the pair (S[i],p) enters B -*/
1636    Lp.p1 = strat->S[i];
1637    Lp.p2 = p;
1638
1639    if (
1640        (!rIsPluralRing(currRing))
1641//      ||  (rIsPluralRing(currRing) && (ncRingType(currRing) != nc_lie))
1642       )
1643    {
1644      assume(pNext(Lp.p)==NULL); // TODO: this may be violated whenever ext.prod.crit. for Lie alg. is used
1645      pNext(Lp.p) = strat->tail; // !!!
1646    }
1647
1648    if (atR >= 0)
1649    {
1650      Lp.i_r1 = strat->S_2_R[i];
1651      Lp.i_r2 = atR;
1652    }
1653    else
1654    {
1655      Lp.i_r1 = -1;
1656      Lp.i_r2 = -1;
1657    }
1658    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
1659
1660    if (TEST_OPT_INTSTRATEGY)
1661    {
1662      if (!rIsPluralRing(currRing))
1663        nDelete(&(Lp.p->coef));
1664    }
1665
1666    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
1667    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
1668  }
1669}
1670
1671/*2
1672* put the pair (s[i],p) into the set L, ecart=ecart(p)
1673* in the case that s forms a SB of (s)
1674*/
1675void enterOnePairSpecial (int i,poly p,int ecart,kStrategy strat, int atR = -1)
1676{
1677  //PrintS("try ");wrp(strat->S[i]);PrintS(" and ");wrp(p);PrintLn();
1678  if(pHasNotCF(p,strat->S[i]))
1679  {
1680    //PrintS("prod-crit\n");
1681    if(ALLOW_PROD_CRIT(strat))
1682    {
1683      //PrintS("prod-crit\n");
1684      strat->cp++;
1685      return;
1686    }
1687  }
1688
1689  int      l,j,compare;
1690  LObject  Lp;
1691  Lp.i_r = -1;
1692
1693  Lp.lcm = pInit();
1694  pLcm(p,strat->S[i],Lp.lcm);
1695  pSetm(Lp.lcm);
1696  for(j = strat->Ll;j>=0;j--)
1697  {
1698    compare=pDivComp(strat->L[j].lcm,Lp.lcm);
1699    if ((compare==1) || (pLmEqual(strat->L[j].lcm,Lp.lcm)))
1700    {
1701      //PrintS("c3-crit\n");
1702      strat->c3++;
1703      pLmFree(Lp.lcm);
1704      return;
1705    }
1706    else if (compare ==-1)
1707    {
1708      //Print("c3-crit with L[%d]\n",j);
1709      deleteInL(strat->L,&strat->Ll,j,strat);
1710      strat->c3++;
1711    }
1712  }
1713  /*-  compute the short s-polynomial -*/
1714
1715  #ifdef HAVE_PLURAL
1716  if (rIsPluralRing(currRing))
1717  {
1718    Lp.p = nc_CreateShortSpoly(strat->S[i],p); // ??? strat->tailRing?
1719  }
1720  else
1721  #endif
1722    Lp.p = ksCreateShortSpoly(strat->S[i],p,strat->tailRing);
1723
1724  if (Lp.p == NULL)
1725  {
1726     //PrintS("short spoly==NULL\n");
1727     pLmFree(Lp.lcm);
1728  }
1729  else
1730  {
1731    /*- the pair (S[i],p) enters L -*/
1732    Lp.p1 = strat->S[i];
1733    Lp.p2 = p;
1734    if (atR >= 0)
1735    {
1736      Lp.i_r1 = strat->S_2_R[i];
1737      Lp.i_r2 = atR;
1738    }
1739    else
1740    {
1741      Lp.i_r1 = -1;
1742      Lp.i_r2 = -1;
1743    }
1744    assume(pNext(Lp.p) == NULL);
1745    pNext(Lp.p) = strat->tail;
1746    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
1747    if (TEST_OPT_INTSTRATEGY)
1748    {
1749      nDelete(&(Lp.p->coef));
1750    }
1751    l = strat->posInL(strat->L,strat->Ll,&Lp,strat);
1752    //Print("-> L[%d]\n",l);
1753    enterL(&strat->L,&strat->Ll,&strat->Lmax,Lp,l);
1754  }
1755}
1756
1757/*2
1758* merge set B into L
1759*/
1760void kMergeBintoL(kStrategy strat)
1761{
1762  int j=strat->Ll+strat->Bl+1;
1763  if (j>strat->Lmax)
1764  {
1765    j=((j+setmaxLinc-1)/setmaxLinc)*setmaxLinc;
1766    strat->L = (LSet)omReallocSize(strat->L,strat->Lmax*sizeof(LObject),
1767                                 j*sizeof(LObject));
1768    strat->Lmax=j;
1769  }
1770  j = strat->Ll;
1771  int i;
1772  for (i=strat->Bl; i>=0; i--)
1773  {
1774    j = strat->posInL(strat->L,j,&(strat->B[i]),strat);
1775    enterL(&strat->L,&strat->Ll,&strat->Lmax,strat->B[i],j);
1776  }
1777  strat->Bl = -1;
1778}
1779/*2
1780*the pairset B of pairs of type (s[i],p) is complete now. It will be updated
1781*using the chain-criterion in B and L and enters B to L
1782*/
1783void chainCritNormal (poly p,int ecart,kStrategy strat)
1784{
1785  int i,j,l;
1786
1787  /*
1788  *pairtest[i] is TRUE if spoly(S[i],p) == 0.
1789  *In this case all elements in B such
1790  *that their lcm is divisible by the leading term of S[i] can be canceled
1791  */
1792  if (strat->pairtest!=NULL)
1793  {
1794    {
1795      /*- i.e. there is an i with pairtest[i]==TRUE -*/
1796      for (j=0; j<=strat->sl; j++)
1797      {
1798        if (strat->pairtest[j])
1799        {
1800          for (i=strat->Bl; i>=0; i--)
1801          {
1802            if (pDivisibleBy(strat->S[j],strat->B[i].lcm))
1803            {
1804              deleteInL(strat->B,&strat->Bl,i,strat);
1805              strat->c3++;
1806            }
1807          }
1808        }
1809      }
1810    }
1811    omFreeSize(strat->pairtest,(strat->sl+2)*sizeof(BOOLEAN));
1812    strat->pairtest=NULL;
1813  }
1814  if (strat->Gebauer || strat->fromT)
1815  {
1816    if (strat->sugarCrit)
1817    {
1818    /*
1819    *suppose L[j] == (s,r) and p/lcm(s,r)
1820    *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
1821    *and in case the sugar is o.k. then L[j] can be canceled
1822    */
1823      for (j=strat->Ll; j>=0; j--)
1824      {
1825        if (sugarDivisibleBy(ecart,strat->L[j].ecart)
1826        && ((pNext(strat->L[j].p) == strat->tail) || (pOrdSgn==1))
1827        && pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1828        {
1829          if (strat->L[j].p == strat->tail)
1830          {
1831              deleteInL(strat->L,&strat->Ll,j,strat);
1832              strat->c3++;
1833          }
1834        }
1835      }
1836      /*
1837      *this is GEBAUER-MOELLER:
1838      *in B all elements with the same lcm except the "best"
1839      *(i.e. the last one in B with this property) will be canceled
1840      */
1841      j = strat->Bl;
1842      loop /*cannot be changed into a for !!! */
1843      {
1844        if (j <= 0) break;
1845        i = j-1;
1846        loop
1847        {
1848          if (i <  0) break;
1849          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
1850          {
1851            strat->c3++;
1852            if (sugarDivisibleBy(strat->B[j].ecart,strat->B[i].ecart))
1853            {
1854              deleteInL(strat->B,&strat->Bl,i,strat);
1855              j--;
1856            }
1857            else
1858            {
1859              deleteInL(strat->B,&strat->Bl,j,strat);
1860              break;
1861            }
1862          }
1863          i--;
1864        }
1865        j--;
1866      }
1867    }
1868    else /*sugarCrit*/
1869    {
1870      /*
1871      *suppose L[j] == (s,r) and p/lcm(s,r)
1872      *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
1873      *and in case the sugar is o.k. then L[j] can be canceled
1874      */
1875      for (j=strat->Ll; j>=0; j--)
1876      {
1877        if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1878        {
1879          if ((pNext(strat->L[j].p) == strat->tail)||(pOrdSgn==1))
1880          {
1881            deleteInL(strat->L,&strat->Ll,j,strat);
1882            strat->c3++;
1883          }
1884        }
1885      }
1886      /*
1887      *this is GEBAUER-MOELLER:
1888      *in B all elements with the same lcm except the "best"
1889      *(i.e. the last one in B with this property) will be canceled
1890      */
1891      j = strat->Bl;
1892      loop   /*cannot be changed into a for !!! */
1893      {
1894        if (j <= 0) break;
1895        for(i=j-1; i>=0; i--)
1896        {
1897          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
1898          {
1899            strat->c3++;
1900            deleteInL(strat->B,&strat->Bl,i,strat);
1901            j--;
1902          }
1903        }
1904        j--;
1905      }
1906    }
1907    /*
1908    *the elements of B enter L
1909    */
1910    kMergeBintoL(strat);
1911  }
1912  else
1913  {
1914    for (j=strat->Ll; j>=0; j--)
1915    {
1916      if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1917      {
1918        if ((pNext(strat->L[j].p) == strat->tail)||(pOrdSgn==1))
1919        {
1920          deleteInL(strat->L,&strat->Ll,j,strat);
1921          strat->c3++;
1922        }
1923      }
1924    }
1925    /*
1926    *this is our MODIFICATION of GEBAUER-MOELLER:
1927    *First the elements of B enter L,
1928    *then we fix a lcm and the "best" element in L
1929    *(i.e the last in L with this lcm and of type (s,p))
1930    *and cancel all the other elements of type (r,p) with this lcm
1931    *except the case the element (s,r) has also the same lcm
1932    *and is on the worst position with respect to (s,p) and (r,p)
1933    */
1934    /*
1935    *B enters to L/their order with respect to B is permutated for elements
1936    *B[i].p with the same leading term
1937    */
1938    kMergeBintoL(strat);
1939    j = strat->Ll;
1940    loop  /*cannot be changed into a for !!! */
1941    {
1942      if (j <= 0)
1943      {
1944        /*now L[0] cannot be canceled any more and the tail can be removed*/
1945        if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
1946        break;
1947      }
1948      if (strat->L[j].p2 == p)
1949      {
1950        i = j-1;
1951        loop
1952        {
1953          if (i < 0)  break;
1954          if ((strat->L[i].p2 == p) && pLmEqual(strat->L[j].lcm,strat->L[i].lcm))
1955          {
1956            /*L[i] could be canceled but we search for a better one to cancel*/
1957            strat->c3++;
1958            if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
1959            && (pNext(strat->L[l].p) == strat->tail)
1960            && (!pLmEqual(strat->L[i].p,strat->L[l].p))
1961            && pDivisibleBy(p,strat->L[l].lcm))
1962            {
1963              /*
1964              *"NOT equal(...)" because in case of "equal" the element L[l]
1965              *is "older" and has to be from theoretical point of view behind
1966              *L[i], but we do not want to reorder L
1967              */
1968              strat->L[i].p2 = strat->tail;
1969              /*
1970              *L[l] will be canceled, we cannot cancel L[i] later on,
1971              *so we mark it with "tail"
1972              */
1973              deleteInL(strat->L,&strat->Ll,l,strat);
1974              i--;
1975            }
1976            else
1977            {
1978              deleteInL(strat->L,&strat->Ll,i,strat);
1979            }
1980            j--;
1981          }
1982          i--;
1983        }
1984      }
1985      else if (strat->L[j].p2 == strat->tail)
1986      {
1987        /*now L[j] cannot be canceled any more and the tail can be removed*/
1988        strat->L[j].p2 = p;
1989      }
1990      j--;
1991    }
1992  }
1993}
1994#ifdef HAVE_RATGRING
1995void chainCritPart (poly p,int ecart,kStrategy strat)
1996{
1997  int i,j,l;
1998
1999  /*
2000  *pairtest[i] is TRUE if spoly(S[i],p) == 0.
2001  *In this case all elements in B such
2002  *that their lcm is divisible by the leading term of S[i] can be canceled
2003  */
2004  if (strat->pairtest!=NULL)
2005  {
2006    {
2007      /*- i.e. there is an i with pairtest[i]==TRUE -*/
2008      for (j=0; j<=strat->sl; j++)
2009      {
2010        if (strat->pairtest[j])
2011        {
2012          for (i=strat->Bl; i>=0; i--)
2013          {
2014            if (_p_LmDivisibleByPart(strat->S[j],currRing,
2015               strat->B[i].lcm,currRing,
2016               currRing->real_var_start,currRing->real_var_end))
2017            {
2018              if(TEST_OPT_DEBUG)
2019              {
2020                 Print("chain-crit-part: S[%d]=",j);
2021                 p_wrp(strat->S[j],currRing);
2022                 Print(" divide B[%d].lcm=",i);
2023                 p_wrp(strat->B[i].lcm,currRing);
2024                 PrintLn();
2025              }
2026              deleteInL(strat->B,&strat->Bl,i,strat);
2027              strat->c3++;
2028            }
2029          }
2030        }
2031      }
2032    }
2033    omFreeSize(strat->pairtest,(strat->sl+2)*sizeof(BOOLEAN));
2034    strat->pairtest=NULL;
2035  }
2036  if (strat->Gebauer || strat->fromT)
2037  {
2038    if (strat->sugarCrit)
2039    {
2040    /*
2041    *suppose L[j] == (s,r) and p/lcm(s,r)
2042    *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
2043    *and in case the sugar is o.k. then L[j] can be canceled
2044    */
2045      for (j=strat->Ll; j>=0; j--)
2046      {
2047        if (sugarDivisibleBy(ecart,strat->L[j].ecart)
2048        && ((pNext(strat->L[j].p) == strat->tail) || (pOrdSgn==1))
2049        && pCompareChainPart(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
2050        {
2051          if (strat->L[j].p == strat->tail)
2052          {
2053              if(TEST_OPT_DEBUG)
2054              {
2055                 PrintS("chain-crit-part: pCompareChainPart p=");
2056                 p_wrp(p,currRing);
2057                 Print(" delete L[%d]",j);
2058                 p_wrp(strat->L[j].lcm,currRing);
2059                 PrintLn();
2060              }
2061              deleteInL(strat->L,&strat->Ll,j,strat);
2062              strat->c3++;
2063          }
2064        }
2065      }
2066      /*
2067      *this is GEBAUER-MOELLER:
2068      *in B all elements with the same lcm except the "best"
2069      *(i.e. the last one in B with this property) will be canceled
2070      */
2071      j = strat->Bl;
2072      loop /*cannot be changed into a for !!! */
2073      {
2074        if (j <= 0) break;
2075        i = j-1;
2076        loop
2077        {
2078          if (i <  0) break;
2079          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
2080          {
2081            strat->c3++;
2082            if (sugarDivisibleBy(strat->B[j].ecart,strat->B[i].ecart))
2083            {
2084              if(TEST_OPT_DEBUG)
2085              {
2086                 Print("chain-crit-part: sugar B[%d].lcm=",j);
2087                 p_wrp(strat->B[j].lcm,currRing);
2088                 Print(" delete B[%d]",i);
2089                 p_wrp(strat->B[i].lcm,currRing);
2090                 PrintLn();
2091              }
2092              deleteInL(strat->B,&strat->Bl,i,strat);
2093              j--;
2094            }
2095            else
2096            {
2097              if(TEST_OPT_DEBUG)
2098              {
2099                 Print("chain-crit-part: sugar B[%d].lcm=",i);
2100                 p_wrp(strat->B[i].lcm,currRing);
2101                 Print(" delete B[%d]",j);
2102                 p_wrp(strat->B[j].lcm,currRing);
2103                 PrintLn();
2104              }
2105              deleteInL(strat->B,&strat->Bl,j,strat);
2106              break;
2107            }
2108          }
2109          i--;
2110        }
2111        j--;
2112      }
2113    }
2114    else /*sugarCrit*/
2115    {
2116      /*
2117      *suppose L[j] == (s,r) and p/lcm(s,r)
2118      *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
2119      *and in case the sugar is o.k. then L[j] can be canceled
2120      */
2121      for (j=strat->Ll; j>=0; j--)
2122      {
2123        if (pCompareChainPart(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
2124        {
2125          if ((pNext(strat->L[j].p) == strat->tail)||(pOrdSgn==1))
2126          {
2127              if(TEST_OPT_DEBUG)
2128              {
2129                 PrintS("chain-crit-part: sugar:pCompareChainPart p=");
2130                 p_wrp(p,currRing);
2131                 Print(" delete L[%d]",j);
2132                 p_wrp(strat->L[j].lcm,currRing);
2133                 PrintLn();
2134              }
2135            deleteInL(strat->L,&strat->Ll,j,strat);
2136            strat->c3++;
2137          }
2138        }
2139      }
2140      /*
2141      *this is GEBAUER-MOELLER:
2142      *in B all elements with the same lcm except the "best"
2143      *(i.e. the last one in B with this property) will be canceled
2144      */
2145      j = strat->Bl;
2146      loop   /*cannot be changed into a for !!! */
2147      {
2148        if (j <= 0) break;
2149        for(i=j-1; i>=0; i--)
2150        {
2151          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
2152          {
2153              if(TEST_OPT_DEBUG)
2154              {
2155                 Print("chain-crit-part: equal lcm B[%d].lcm=",j);
2156                 p_wrp(strat->B[j].lcm,currRing);
2157                 Print(" delete B[%d]\n",i);
2158              }
2159            strat->c3++;
2160            deleteInL(strat->B,&strat->Bl,i,strat);
2161            j--;
2162          }
2163        }
2164        j--;
2165      }
2166    }
2167    /*
2168    *the elements of B enter L
2169    */
2170    kMergeBintoL(strat);
2171  }
2172  else
2173  {
2174    for (j=strat->Ll; j>=0; j--)
2175    {
2176      if (pCompareChainPart(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
2177      {
2178        if ((pNext(strat->L[j].p) == strat->tail)||(pOrdSgn==1))
2179        {
2180              if(TEST_OPT_DEBUG)
2181              {
2182                 PrintS("chain-crit-part: pCompareChainPart p=");
2183                 p_wrp(p,currRing);
2184                 Print(" delete L[%d]",j);
2185                 p_wrp(strat->L[j].lcm,currRing);
2186                 PrintLn();
2187              }
2188          deleteInL(strat->L,&strat->Ll,j,strat);
2189          strat->c3++;
2190        }
2191      }
2192    }
2193    /*
2194    *this is our MODIFICATION of GEBAUER-MOELLER:
2195    *First the elements of B enter L,
2196    *then we fix a lcm and the "best" element in L
2197    *(i.e the last in L with this lcm and of type (s,p))
2198    *and cancel all the other elements of type (r,p) with this lcm
2199    *except the case the element (s,r) has also the same lcm
2200    *and is on the worst position with respect to (s,p) and (r,p)
2201    */
2202    /*
2203    *B enters to L/their order with respect to B is permutated for elements
2204    *B[i].p with the same leading term
2205    */
2206    kMergeBintoL(strat);
2207    j = strat->Ll;
2208    loop  /*cannot be changed into a for !!! */
2209    {
2210      if (j <= 0)
2211      {
2212        /*now L[0] cannot be canceled any more and the tail can be removed*/
2213        if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
2214        break;
2215      }
2216      if (strat->L[j].p2 == p)
2217      {
2218        i = j-1;
2219        loop
2220        {
2221          if (i < 0)  break;
2222          if ((strat->L[i].p2 == p) && pLmEqual(strat->L[j].lcm,strat->L[i].lcm))
2223          {
2224            /*L[i] could be canceled but we search for a better one to cancel*/
2225            strat->c3++;
2226            if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
2227            && (pNext(strat->L[l].p) == strat->tail)
2228            && (!pLmEqual(strat->L[i].p,strat->L[l].p))
2229            && _p_LmDivisibleByPart(p,currRing,
2230                           strat->L[l].lcm,currRing,
2231                           currRing->real_var_start, currRing->real_var_end))
2232
2233            {
2234              /*
2235              *"NOT equal(...)" because in case of "equal" the element L[l]
2236              *is "older" and has to be from theoretical point of view behind
2237              *L[i], but we do not want to reorder L
2238              */
2239              strat->L[i].p2 = strat->tail;
2240              /*
2241              *L[l] will be canceled, we cannot cancel L[i] later on,
2242              *so we mark it with "tail"
2243              */
2244              if(TEST_OPT_DEBUG)
2245              {
2246                 PrintS("chain-crit-part: divisible_by p=");
2247                 p_wrp(p,currRing);
2248                 Print(" delete L[%d]",l);
2249                 p_wrp(strat->L[l].lcm,currRing);
2250                 PrintLn();
2251              }
2252              deleteInL(strat->L,&strat->Ll,l,strat);
2253              i--;
2254            }
2255            else
2256            {
2257              if(TEST_OPT_DEBUG)
2258              {
2259                 PrintS("chain-crit-part: divisible_by(2) p=");
2260                 p_wrp(p,currRing);
2261                 Print(" delete L[%d]",i);
2262                 p_wrp(strat->L[i].lcm,currRing);
2263                 PrintLn();
2264              }
2265              deleteInL(strat->L,&strat->Ll,i,strat);
2266            }
2267            j--;
2268          }
2269          i--;
2270        }
2271      }
2272      else if (strat->L[j].p2 == strat->tail)
2273      {
2274        /*now L[j] cannot be canceled any more and the tail can be removed*/
2275        strat->L[j].p2 = p;
2276      }
2277      j--;
2278    }
2279  }
2280}
2281#endif
2282
2283/*2
2284*(s[0],h),...,(s[k],h) will be put to the pairset L
2285*/
2286void initenterpairs (poly h,int k,int ecart,int isFromQ,kStrategy strat, int atR = -1)
2287{
2288
2289  if ((strat->syzComp==0)
2290  || (pGetComp(h)<=strat->syzComp))
2291  {
2292    int j;
2293    BOOLEAN new_pair=FALSE;
2294
2295    if (pGetComp(h)==0)
2296    {
2297      /* for Q!=NULL: build pairs (f,q),(f1,f2), but not (q1,q2)*/
2298      if ((isFromQ)&&(strat->fromQ!=NULL))
2299      {
2300        for (j=0; j<=k; j++)
2301        {
2302          if (!strat->fromQ[j])
2303          {
2304            new_pair=TRUE;
2305            strat->enterOnePair(j,h,ecart,isFromQ,strat, atR);
2306          //Print("j:%d, Ll:%d\n",j,strat->Ll);
2307          }
2308        }
2309      }
2310      else
2311      {
2312        new_pair=TRUE;
2313        for (j=0; j<=k; j++)
2314        {
2315          strat->enterOnePair(j,h,ecart,isFromQ,strat, atR);
2316          //Print("j:%d, Ll:%d\n",j,strat->Ll);
2317        }
2318      }
2319    }
2320    else
2321    {
2322      for (j=0; j<=k; j++)
2323      {
2324        if ((pGetComp(h)==pGetComp(strat->S[j]))
2325        || (pGetComp(strat->S[j])==0))
2326        {
2327          new_pair=TRUE;
2328          strat->enterOnePair(j,h,ecart,isFromQ,strat, atR);
2329        //Print("j:%d, Ll:%d\n",j,strat->Ll);
2330        }
2331      }
2332    }
2333
2334    if (new_pair)
2335    {
2336#ifdef HAVE_RATGRING
2337      if (currRing->real_var_start>0)
2338        chainCritPart(h,ecart,strat);
2339      else
2340#endif
2341      strat->chainCrit(h,ecart,strat);
2342    }
2343  }
2344}
2345
2346#ifdef HAVE_RINGS
2347/*2
2348*the pairset B of pairs of type (s[i],p) is complete now. It will be updated
2349*using the chain-criterion in B and L and enters B to L
2350*/
2351void chainCritRing (poly p,int ecart,kStrategy strat)
2352{
2353  int i,j,l;
2354  /*
2355  *pairtest[i] is TRUE if spoly(S[i],p) == 0.
2356  *In this case all elements in B such
2357  *that their lcm is divisible by the leading term of S[i] can be canceled
2358  */
2359  if (strat->pairtest!=NULL)
2360  {
2361    {
2362      /*- i.e. there is an i with pairtest[i]==TRUE -*/
2363      for (j=0; j<=strat->sl; j++)
2364      {
2365        if (strat->pairtest[j])
2366        {
2367          for (i=strat->Bl; i>=0; i--)
2368          {
2369            if (pDivisibleBy(strat->S[j],strat->B[i].lcm))
2370            {
2371#ifdef KDEBUG
2372              if (TEST_OPT_DEBUG)
2373              {
2374                PrintS("--- chain criterion func chainCritRing type 1\n");
2375                PrintS("strat->S[j]:");
2376                wrp(strat->S[j]);
2377                PrintS("  strat->B[i].lcm:");
2378                wrp(strat->B[i].lcm);
2379                PrintLn();
2380              }
2381#endif
2382              deleteInL(strat->B,&strat->Bl,i,strat);
2383              strat->c3++;
2384            }
2385          }
2386        }
2387      }
2388    }
2389    omFreeSize(strat->pairtest,(strat->sl+2)*sizeof(BOOLEAN));
2390    strat->pairtest=NULL;
2391  }
2392  assume(!(strat->Gebauer || strat->fromT));
2393  for (j=strat->Ll; j>=0; j--)
2394  {
2395    if (strat->L[j].lcm != NULL && nDivBy(pGetCoeff(strat->L[j].lcm), pGetCoeff(p)))
2396    {
2397      if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
2398      {
2399        if ((pNext(strat->L[j].p) == strat->tail) || (pOrdSgn==1))
2400        {
2401          deleteInL(strat->L,&strat->Ll,j,strat);
2402          strat->c3++;
2403#ifdef KDEBUG
2404              if (TEST_OPT_DEBUG)
2405              {
2406                PrintS("--- chain criterion func chainCritRing type 2\n");
2407                PrintS("strat->L[j].p:");
2408                wrp(strat->L[j].p);
2409                PrintS("  p:");
2410                wrp(p);
2411                PrintLn();
2412              }
2413#endif
2414        }
2415      }
2416    }
2417  }
2418  /*
2419  *this is our MODIFICATION of GEBAUER-MOELLER:
2420  *First the elements of B enter L,
2421  *then we fix a lcm and the "best" element in L
2422  *(i.e the last in L with this lcm and of type (s,p))
2423  *and cancel all the other elements of type (r,p) with this lcm
2424  *except the case the element (s,r) has also the same lcm
2425  *and is on the worst position with respect to (s,p) and (r,p)
2426  */
2427  /*
2428  *B enters to L/their order with respect to B is permutated for elements
2429  *B[i].p with the same leading term
2430  */
2431  kMergeBintoL(strat);
2432  j = strat->Ll;
2433  loop  /*cannot be changed into a for !!! */
2434  {
2435    if (j <= 0)
2436    {
2437      /*now L[0] cannot be canceled any more and the tail can be removed*/
2438      if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
2439      break;
2440    }
2441    if (strat->L[j].p2 == p) // Was the element added from B?
2442    {
2443      i = j-1;
2444      loop
2445      {
2446        if (i < 0)  break;
2447        // Element is from B and has the same lcm as L[j]
2448        if ((strat->L[i].p2 == p) && nDivBy(pGetCoeff(strat->L[j].lcm), pGetCoeff(strat->L[i].lcm))
2449             && pLmEqual(strat->L[j].lcm,strat->L[i].lcm))
2450        {
2451          /*L[i] could be canceled but we search for a better one to cancel*/
2452          strat->c3++;
2453#ifdef KDEBUG
2454          if (TEST_OPT_DEBUG)
2455          {
2456            PrintS("--- chain criterion func chainCritRing type 3\n");
2457            PrintS("strat->L[j].lcm:");
2458            wrp(strat->L[j].lcm);
2459            PrintS("  strat->L[i].lcm:");
2460            wrp(strat->L[i].lcm);
2461            PrintLn();
2462          }
2463#endif
2464          if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
2465          && (pNext(strat->L[l].p) == strat->tail)
2466          && (!pLmEqual(strat->L[i].p,strat->L[l].p))
2467          && pDivisibleBy(p,strat->L[l].lcm))
2468          {
2469            /*
2470            *"NOT equal(...)" because in case of "equal" the element L[l]
2471            *is "older" and has to be from theoretical point of view behind
2472            *L[i], but we do not want to reorder L
2473            */
2474            strat->L[i].p2 = strat->tail;
2475            /*
2476            *L[l] will be canceled, we cannot cancel L[i] later on,
2477            *so we mark it with "tail"
2478            */
2479            deleteInL(strat->L,&strat->Ll,l,strat);
2480            i--;
2481          }
2482          else
2483          {
2484            deleteInL(strat->L,&strat->Ll,i,strat);
2485          }
2486          j--;
2487        }
2488        i--;
2489      }
2490    }
2491    else if (strat->L[j].p2 == strat->tail)
2492    {
2493      /*now L[j] cannot be canceled any more and the tail can be removed*/
2494      strat->L[j].p2 = p;
2495    }
2496    j--;
2497  }
2498}
2499#endif
2500
2501#ifdef HAVE_RINGS
2502long ind2(long arg)
2503{
2504  long ind = 0;
2505  if (arg <= 0) return 0;
2506  while (arg%2 == 0)
2507  {
2508    arg = arg / 2;
2509    ind++;
2510  }
2511  return ind;
2512}
2513
2514long ind_fact_2(long arg)
2515{
2516  long ind = 0;
2517  if (arg <= 0) return 0;
2518  if (arg%2 == 1) { arg--; }
2519  while (arg > 0)
2520  {
2521    ind += ind2(arg);
2522    arg = arg - 2;
2523  }
2524  return ind;
2525}
2526#endif
2527
2528#ifdef HAVE_VANIDEAL
2529long twoPow(long arg)
2530{
2531  return 1L << arg;
2532}
2533
2534/*2
2535* put the pair (p, f) in B and f in T
2536*/
2537void enterOneZeroPairRing (poly f, poly t_p, poly p, int ecart, kStrategy strat, int atR = -1)
2538{
2539  int      l,j,compare,compareCoeff;
2540  LObject  Lp;
2541
2542  if (strat->interred_flag) return;
2543#ifdef KDEBUG
2544  Lp.ecart=0; Lp.length=0;
2545#endif
2546  /*- computes the lcm(s[i],p) -*/
2547  Lp.lcm = pInit();
2548
2549  pLcm(p,f,Lp.lcm);
2550  pSetm(Lp.lcm);
2551  pSetCoeff(Lp.lcm, nLcm(pGetCoeff(p), pGetCoeff(f), currRing));
2552  assume(!strat->sugarCrit);
2553  assume(!strat->fromT);
2554  /*
2555  *the set B collects the pairs of type (S[j],p)
2556  *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p) != lcm(r,p)
2557  *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
2558  *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
2559  */
2560  for(j = strat->Bl;j>=0;j--)
2561  {
2562    compare=pDivCompRing(strat->B[j].lcm,Lp.lcm);
2563    compareCoeff = nDivComp(pGetCoeff(strat->B[j].lcm), pGetCoeff(Lp.lcm));
2564    if (compareCoeff == 0 || compare == compareCoeff)
2565    {
2566      if (compare == 1)
2567      {
2568        strat->c3++;
2569        pLmDelete(Lp.lcm);
2570        return;
2571      }
2572      else
2573      if (compare == -1)
2574      {
2575        deleteInL(strat->B,&strat->Bl,j,strat);
2576        strat->c3++;
2577      }
2578    }
2579    if (compare == pDivComp_EQUAL)
2580    {
2581      // Add hint for same LM and direction of LC (later) (TODO Oliver)
2582      if (compareCoeff == 1)
2583      {
2584        strat->c3++;
2585        pLmDelete(Lp.lcm);
2586        return;
2587      }
2588      else
2589      if (compareCoeff == -1)
2590      {
2591        deleteInL(strat->B,&strat->Bl,j,strat);
2592        strat->c3++;
2593      }
2594    }
2595  }
2596  /*
2597  *the pair (S[i],p) enters B if the spoly != 0
2598  */
2599  /*-  compute the short s-polynomial -*/
2600  if ((f==NULL) || (p==NULL)) return;
2601  pNorm(p);
2602  {
2603    Lp.p = ksCreateShortSpoly(f, p, strat->tailRing);
2604  }
2605  if (Lp.p == NULL) //deactivated, as we are adding pairs with zeropoly and not from S
2606  {
2607    /*- the case that the s-poly is 0 -*/
2608//    if (strat->pairtest==NULL) initPairtest(strat);
2609//    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
2610//    strat->pairtest[strat->sl+1] = TRUE;
2611    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
2612    /*
2613    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
2614    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
2615    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
2616    *term of p devides the lcm(s,r)
2617    *(this canceling should be done here because
2618    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
2619    *the first case is handeled in chainCrit
2620    */
2621    if (Lp.lcm!=NULL) pLmDelete(Lp.lcm);
2622  }
2623  else
2624  {
2625    /*- the pair (S[i],p) enters B -*/
2626    Lp.p1 = f;
2627    Lp.p2 = p;
2628
2629    pNext(Lp.p) = strat->tail;
2630
2631    LObject tmp_h(f, currRing, strat->tailRing);
2632    tmp_h.SetShortExpVector();
2633    strat->initEcart(&tmp_h);
2634    tmp_h.sev = pGetShortExpVector(tmp_h.p);
2635    tmp_h.t_p = t_p;
2636
2637    enterT(tmp_h, strat, strat->tl + 1);
2638
2639    if (atR >= 0)
2640    {
2641      Lp.i_r2 = atR;
2642      Lp.i_r1 = strat->tl;
2643    }
2644
2645    strat->initEcartPair(&Lp,f,p,0/*strat->ecartS[i]*/,ecart);     // Attention: TODO: break ecart
2646    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
2647    enterL(&strat->B, &strat->Bl, &strat->Bmax, Lp, l);
2648  }
2649}
2650
2651/* Helper for kCreateZeroPoly
2652 * enumerating the exponents
2653ring r = 2^2, (a, b, c), lp; ideal G0 = system("createG0"); ideal G = interred(G0); ncols(G0); ncols(G);
2654 */
2655
2656int nextZeroSimplexExponent (long exp[], long ind[], long cexp[], long cind[], long* cabsind, long step[], long bound, long N)
2657/* gives the next exponent from the set H_1 */
2658{
2659  long add = ind2(cexp[1] + 2);
2660  if ((*cabsind < bound) && (*cabsind - step[1] + add < bound))
2661  {
2662    cexp[1] += 2;
2663    cind[1] += add;
2664    *cabsind += add;
2665  }
2666  else
2667  {
2668    // cabsind >= habsind
2669    if (N == 1) return 0;
2670    int i = 1;
2671    while (exp[i] == cexp[i] && i <= N) i++;
2672    cexp[i] = exp[i];
2673    *cabsind -= cind[i];
2674    cind[i] = ind[i];
2675    step[i] = 500000;
2676    *cabsind += cind[i];
2677    // Print("in: %d\n", *cabsind);
2678    i += 1;
2679    if (i > N) return 0;
2680    do
2681    {
2682      step[1] = 500000;
2683      for (int j = i + 1; j <= N; j++)
2684      {
2685        if (step[1] > step[j]) step[1] = step[j];
2686      }
2687      add = ind2(cexp[i] + 2);
2688      if (*cabsind - step[1] + add >= bound)
2689      {
2690        cexp[i] = exp[i];
2691        *cabsind -= cind[i];
2692        cind[i] = ind[i];
2693        *cabsind += cind[i];
2694        step[i] = 500000;
2695        i += 1;
2696        if (i > N) return 0;
2697      }
2698      else step[1] = -1;
2699    } while (step[1] != -1);
2700    step[1] = 500000;
2701    cexp[i] += 2;
2702    cind[i] += add;
2703    *cabsind += add;
2704    if (add < step[i]) step[i] = add;
2705    for (i = 2; i <= N; i++)
2706    {
2707      if (step[1] > step[i]) step[1] = step[i];
2708    }
2709  }
2710  return 1;
2711}
2712
2713/*
2714 * Creates the zero Polynomial on position exp
2715 * long exp[] : exponent of leading term
2716 * cabsind    : total 2-ind of exp (if -1 will be computed)
2717 * poly* t_p  : will hold the LT in tailRing
2718 * leadRing   : ring for the LT
2719 * tailRing   : ring for the tail
2720 */
2721
2722poly kCreateZeroPoly(long exp[], long cabsind, poly* t_p, ring leadRing, ring tailRing)
2723{
2724
2725  poly zeroPoly = NULL;
2726
2727  number tmp1;
2728  poly tmp2, tmp3;
2729
2730  if (cabsind == -1)
2731  {
2732    cabsind = 0;
2733    for (int i = 1; i <= leadRing->N; i++)
2734    {
2735      cabsind += ind_fact_2(exp[i]);
2736    }
2737//    Print("cabsind: %d\n", cabsind);
2738  }
2739  if (cabsind < leadRing->ch)
2740  {
2741    zeroPoly = p_ISet(twoPow(leadRing->ch - cabsind), tailRing);
2742  }
2743  else
2744  {
2745    zeroPoly = p_ISet(1, tailRing);
2746  }
2747  for (int i = 1; i <= leadRing->N; i++)
2748  {
2749    for (long j = 1; j <= exp[i]; j++)
2750    {
2751      tmp1 = nInit(j);
2752      tmp2 = p_ISet(1, tailRing);
2753      p_SetExp(tmp2, i, 1, tailRing);
2754      p_Setm(tmp2, tailRing);
2755      if (nIsZero(tmp1))
2756      { // should nowbe obsolet, test ! TODO OLIVER
2757        zeroPoly = p_Mult_q(zeroPoly, tmp2, tailRing);
2758      }
2759      else
2760      {
2761        tmp3 = p_NSet(nCopy(tmp1), tailRing);
2762        zeroPoly = p_Mult_q(zeroPoly, p_Add_q(tmp3, tmp2, tailRing), tailRing);
2763      }
2764    }
2765  }
2766  tmp2 = p_NSet(nCopy(pGetCoeff(zeroPoly)), leadRing);
2767  for (int i = 1; i <= leadRing->N; i++)
2768  {
2769    pSetExp(tmp2, i, p_GetExp(zeroPoly, i, tailRing));
2770  }
2771  p_Setm(tmp2, leadRing);
2772  *t_p = zeroPoly;
2773  zeroPoly = pNext(zeroPoly);
2774  pNext(*t_p) = NULL;
2775  pNext(tmp2) = zeroPoly;
2776  return tmp2;
2777}
2778
2779// #define OLI_DEBUG
2780
2781/*
2782 * Generate the s-polynomial for the virtual set of zero-polynomials
2783 */
2784
2785void initenterzeropairsRing (poly p, int ecart, kStrategy strat, int atR)
2786{
2787  // Initialize
2788  long exp[50];            // The exponent of \hat{X} (basepoint)
2789  long cexp[50];           // The current exponent for iterating over all
2790  long ind[50];            // The power of 2 in the i-th component of exp
2791  long cind[50];           // analog for cexp
2792  long mult[50];           // How to multiply the elements of G
2793  long cabsind = 0;        // The abs. index of cexp, i.e. the sum of cind
2794  long habsind = 0;        // The abs. index of the coefficient of h
2795  long step[50];           // The last increases
2796  for (int i = 1; i <= currRing->N; i++)
2797  {
2798    exp[i] = p_GetExp(p, i, currRing);
2799    if (exp[i] & 1 != 0)
2800    {
2801      exp[i] = exp[i] - 1;
2802      mult[i] = 1;
2803    }
2804    cexp[i] = exp[i];
2805    ind[i] = ind_fact_2(exp[i]);
2806    cabsind += ind[i];
2807    cind[i] = ind[i];
2808    step[i] = 500000;
2809  }
2810  step[1] = 500000;
2811  habsind = ind2((long) p_GetCoeff(p, currRing));
2812  long bound = currRing->ch - habsind;
2813#ifdef OLI_DEBUG
2814  PrintS("-------------\npoly  :");
2815  wrp(p);
2816  Print("\nexp   : (%d, %d)\n", exp[1] + mult[1], exp[2] + mult[1]);
2817  Print("cexp  : (%d, %d)\n", cexp[1], cexp[2]);
2818  Print("cind  : (%d, %d)\n", cind[1], cind[2]);
2819  Print("bound : %d\n", bound);
2820  Print("cind  : %d\n", cabsind);
2821#endif
2822  if (cabsind == 0)
2823  {
2824    if (!(nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N)))
2825    {
2826      return;
2827    }
2828  }
2829  // Now the whole simplex
2830  do
2831  {
2832    // Build s-polynomial
2833    // 2**ind-def * mult * g - exp-def * h
2834    poly t_p;
2835    poly zeroPoly = kCreateZeroPoly(cexp, cabsind, &t_p, currRing, strat->tailRing);
2836#ifdef OLI_DEBUG
2837    Print("%d, (%d, %d), ind = (%d, %d)\n", cabsind, cexp[1], cexp[2], cind[1], cind[2]);
2838    Print("zPoly : ");
2839    wrp(zeroPoly);
2840    Print("\n");
2841#endif
2842    enterOneZeroPairRing(zeroPoly, t_p, p, ecart, strat, atR);
2843  }
2844  while ( nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N) );
2845}
2846
2847/*
2848 * Create the Groebner basis of the vanishing polynomials.
2849 */
2850
2851ideal createG0()
2852{
2853  // Initialize
2854  long exp[50];            // The exponent of \hat{X} (basepoint)
2855  long cexp[50];           // The current exponent for iterating over all
2856  long ind[50];            // The power of 2 in the i-th component of exp
2857  long cind[50];           // analog for cexp
2858  long mult[50];           // How to multiply the elements of G
2859  long cabsind = 0;        // The abs. index of cexp, i.e. the sum of cind
2860  long habsind = 0;        // The abs. index of the coefficient of h
2861  long step[50];           // The last increases
2862  for (int i = 1; i <= currRing->N; i++)
2863  {
2864    exp[i] = 0;
2865    cexp[i] = exp[i];
2866    ind[i] = 0;
2867    step[i] = 500000;
2868    cind[i] = ind[i];
2869  }
2870  long bound = currRing->ch;
2871  step[1] = 500000;
2872#ifdef OLI_DEBUG
2873  PrintS("-------------\npoly  :");
2874//  wrp(p);
2875  Print("\nexp   : (%d, %d)\n", exp[1] + mult[1], exp[2] + mult[1]);
2876  Print("cexp  : (%d, %d)\n", cexp[1], cexp[2]);
2877  Print("cind  : (%d, %d)\n", cind[1], cind[2]);
2878  Print("bound : %d\n", bound);
2879  Print("cind  : %d\n", cabsind);
2880#endif
2881  if (cabsind == 0)
2882  {
2883    if (!(nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N)))
2884    {
2885      return idInit(1, 1);
2886    }
2887  }
2888  ideal G0 = idInit(1, 1);
2889  // Now the whole simplex
2890  do
2891  {
2892    // Build s-polynomial
2893    // 2**ind-def * mult * g - exp-def * h
2894    poly t_p;
2895    poly zeroPoly = kCreateZeroPoly(cexp, cabsind, &t_p, currRing, currRing);
2896#ifdef OLI_DEBUG
2897    Print("%d, (%d, %d), ind = (%d, %d)\n", cabsind, cexp[1], cexp[2], cind[1], cind[2]);
2898    Print("zPoly : ");
2899    wrp(zeroPoly);
2900    Print("\n");
2901#endif
2902    // Add to ideal
2903    pEnlargeSet(&(G0->m), IDELEMS(G0), 1);
2904    IDELEMS(G0) += 1;
2905    G0->m[IDELEMS(G0) - 1] = zeroPoly;
2906  }
2907  while ( nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N) );
2908  idSkipZeroes(G0);
2909  return G0;
2910}
2911#endif
2912
2913#ifdef HAVE_RINGS
2914/*2
2915*(s[0],h),...,(s[k],h) will be put to the pairset L
2916*/
2917void initenterstrongPairs (poly h,int k,int ecart,int isFromQ,kStrategy strat, int atR = -1)
2918{
2919  const int iCompH = pGetComp(h);
2920  if (!nIsOne(pGetCoeff(h)))
2921  {
2922    int j;
2923    BOOLEAN new_pair=FALSE;
2924
2925    for (j=0; j<=k; j++)
2926    {
2927      // Print("j:%d, Ll:%d\n",j,strat->Ll);
2928//      if (((unsigned long) pGetCoeff(h) % (unsigned long) pGetCoeff(strat->S[j]) != 0) &&
2929//         ((unsigned long) pGetCoeff(strat->S[j]) % (unsigned long) pGetCoeff(h) != 0))
2930      if ( iCompH == pGetComp(strat->S[j]) )
2931      {
2932        {
2933          if (enterOneStrongPoly(j,h,ecart,isFromQ,strat, atR))
2934            new_pair=TRUE;
2935        }
2936      }
2937    }
2938  }
2939/*
2940ring r=256,(x,y,z),dp;
2941ideal I=12xz-133y, 2xy-z;
2942*/
2943
2944}
2945
2946/*2
2947* Generates spoly(0, h) if applicable. Assumes ring in Z/2^n.
2948*/
2949void enterExtendedSpoly(poly h,kStrategy strat)
2950{
2951  if (nIsOne(pGetCoeff(h))) return;
2952  number gcd;
2953  bool go = false;
2954  if (nDivBy((number) 0, pGetCoeff(h)))
2955  {
2956    gcd = nIntDiv((number) 0, pGetCoeff(h));
2957    go = true;
2958  }
2959  else
2960    gcd = nGcd((number) 0, pGetCoeff(h), strat->tailRing);
2961  if (go || !nIsOne(gcd))
2962  {
2963    poly p = h->next;
2964    if (!go)
2965    {
2966      number tmp = gcd;
2967      gcd = nIntDiv(0, gcd);
2968      nDelete(&tmp);
2969    }
2970    p_Test(p,strat->tailRing);
2971    p = pp_Mult_nn(p, gcd, strat->tailRing);
2972    nDelete(&gcd);
2973
2974    if (p != NULL)
2975    {
2976      if (TEST_OPT_PROT)
2977      {
2978        PrintS("Z");
2979      }
2980#ifdef KDEBUG
2981      if (TEST_OPT_DEBUG)
2982      {
2983        PrintS("--- create zero spoly: ");
2984        p_wrp(h,currRing,strat->tailRing);
2985        PrintS(" ---> ");
2986      }
2987#endif
2988      poly tmp = pInit();
2989      pSetCoeff0(tmp, pGetCoeff(p));
2990      for (int i = 1; i <= rVar(currRing); i++)
2991      {
2992        pSetExp(tmp, i, p_GetExp(p, i, strat->tailRing));
2993      }
2994      if (rRing_has_Comp(currRing) && rRing_has_Comp(strat->tailRing))
2995      {
2996        p_SetComp(tmp, p_GetComp(p, strat->tailRing), currRing);
2997      }
2998      p_Setm(tmp, currRing);
2999      p = p_LmFreeAndNext(p, strat->tailRing);
3000      pNext(tmp) = p;
3001      LObject h;
3002      h.Init();
3003      h.p = tmp;
3004      h.tailRing = strat->tailRing;
3005      int posx;
3006      if (h.p!=NULL)
3007      {
3008        if (TEST_OPT_INTSTRATEGY)
3009        {
3010          //pContent(h.p);
3011          h.pCleardenom(); // also does a pContent
3012        }
3013        else
3014        {
3015          h.pNorm();
3016        }
3017        strat->initEcart(&h);
3018        if (strat->Ll==-1)
3019          posx =0;
3020        else
3021          posx = strat->posInL(strat->L,strat->Ll,&h,strat);
3022        h.sev = pGetShortExpVector(h.p);
3023        if (strat->tailRing != currRing)
3024        {
3025          h.t_p = k_LmInit_currRing_2_tailRing(h.p, strat->tailRing);
3026        }
3027#ifdef KDEBUG
3028        if (TEST_OPT_DEBUG)
3029        {
3030          p_wrp(tmp,currRing,strat->tailRing);
3031          PrintLn();
3032        }
3033#endif
3034        enterL(&strat->L,&strat->Ll,&strat->Lmax,h,posx);
3035      }
3036    }
3037  }
3038  nDelete(&gcd);
3039}
3040
3041void clearSbatch (poly h,int k,int pos,kStrategy strat)
3042{
3043  int j = pos;
3044  if ( (!strat->fromT)
3045  && (1//(strat->syzComp==0)
3046    //||(pGetComp(h)<=strat->syzComp)))
3047  ))
3048  {
3049    // Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
3050    unsigned long h_sev = pGetShortExpVector(h);
3051    loop
3052    {
3053      if (j > k) break;
3054      clearS(h,h_sev, &j,&k,strat);
3055      j++;
3056    }
3057    // Print("end clearS sl=%d\n",strat->sl);
3058  }
3059}
3060
3061/*2
3062* Generates a sufficient set of spolys (maybe just a finite generating
3063* set of the syzygys)
3064*/
3065void superenterpairs (poly h,int k,int ecart,int pos,kStrategy strat, int atR)
3066{
3067    assume (rField_is_Ring(currRing));
3068    // enter also zero divisor * poly, if this is non zero and of smaller degree
3069    if (!(rField_is_Domain(currRing))) enterExtendedSpoly(h, strat);
3070    initenterpairs(h, k, ecart, 0, strat, atR);
3071    initenterstrongPairs(h, k, ecart, 0, strat, atR);
3072    clearSbatch(h, k, pos, strat);
3073}
3074#endif
3075
3076/*2
3077*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
3078*superfluous elements in S will be deleted
3079*/
3080void enterpairs (poly h,int k,int ecart,int pos,kStrategy strat, int atR)
3081{
3082  int j=pos;
3083
3084#ifdef HAVE_RINGS
3085  assume (!rField_is_Ring(currRing));
3086#endif
3087
3088  initenterpairs(h,k,ecart,0,strat, atR);
3089  if ( (!strat->fromT)
3090  && ((strat->syzComp==0)
3091    ||(pGetComp(h)<=strat->syzComp)))
3092  {
3093    //Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
3094    unsigned long h_sev = pGetShortExpVector(h);
3095    loop
3096    {
3097      if (j > k) break;
3098      clearS(h,h_sev, &j,&k,strat);
3099      j++;
3100    }
3101    //Print("end clearS sl=%d\n",strat->sl);
3102  }
3103 // PrintS("end enterpairs\n");
3104}
3105
3106/*2
3107*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
3108*superfluous elements in S will be deleted
3109*/
3110void enterpairsSpecial (poly h,int k,int ecart,int pos,kStrategy strat, int atR = -1)
3111{
3112  int j;
3113  const int iCompH = pGetComp(h);
3114
3115  for (j=0; j<=k; j++)
3116  {
3117    const int iCompSj = pGetComp(strat->S[j]);
3118    if ((iCompH==iCompSj)
3119        || (0==iCompH) // TODO: what about this case???
3120        || (0==iCompSj))
3121    {
3122      enterOnePairSpecial(j,h,ecart,strat, atR);
3123    }
3124  }
3125
3126  if (strat->noClearS) return;
3127
3128//   #ifdef HAVE_PLURAL
3129/*
3130  if (rIsPluralRing(currRing))
3131  {
3132    j=pos;
3133    loop
3134    {
3135      if (j > k) break;
3136
3137      if (pLmDivisibleBy(h, strat->S[j]))
3138      {
3139        deleteInS(j, strat);
3140        j--;
3141        k--;
3142      }
3143
3144      j++;
3145    }
3146  }
3147  else
3148*/
3149//   #endif // ??? Why was the following cancelation disabled for non-commutative rings?
3150  {
3151    j=pos;
3152    loop
3153    {
3154      unsigned long h_sev = pGetShortExpVector(h);
3155      if (j > k) break;
3156      clearS(h,h_sev,&j,&k,strat);
3157      j++;
3158    }
3159  }
3160}
3161
3162/*2
3163*reorders  s with respect to posInS,
3164*suc is the first changed index or zero
3165*/
3166
3167void reorderS (int* suc,kStrategy strat)
3168{
3169  int i,j,at,ecart, s2r;
3170  int fq=0;
3171  unsigned long sev;
3172  poly  p;
3173  int new_suc=strat->sl+1;
3174  i= *suc;
3175  if (i<0) i=0;
3176
3177  for (; i<=strat->sl; i++)
3178  {
3179    at = posInS(strat,i-1,strat->S[i],strat->ecartS[i]);
3180    if (at != i)
3181    {
3182      if (new_suc > at) new_suc = at;
3183      p = strat->S[i];
3184      ecart = strat->ecartS[i];
3185      sev = strat->sevS[i];
3186      s2r = strat->S_2_R[i];
3187      if (strat->fromQ!=NULL) fq=strat->fromQ[i];
3188      for (j=i; j>=at+1; j--)
3189      {
3190        strat->S[j] = strat->S[j-1];
3191        strat->ecartS[j] = strat->ecartS[j-1];
3192        strat->sevS[j] = strat->sevS[j-1];
3193        strat->S_2_R[j] = strat->S_2_R[j-1];
3194      }
3195      strat->S[at] = p;
3196      strat->ecartS[at] = ecart;
3197      strat->sevS[at] = sev;
3198      strat->S_2_R[at] = s2r;
3199      if (strat->fromQ!=NULL)
3200      {
3201        for (j=i; j>=at+1; j--)
3202        {
3203          strat->fromQ[j] = strat->fromQ[j-1];
3204        }
3205        strat->fromQ[at]=fq;
3206      }
3207    }
3208  }
3209  if (new_suc <= strat->sl) *suc=new_suc;
3210  else                      *suc=-1;
3211}
3212
3213
3214/*2
3215*looks up the position of p in set
3216*set[0] is the smallest with respect to the ordering-procedure deg/pComp
3217* Assumption: posInS only depends on the leading term
3218*             otherwise, bba has to be changed
3219*/
3220int posInS (const kStrategy strat, const int length,const poly p,
3221            const int ecart_p)
3222{
3223  if(length==-1) return 0;
3224  polyset set=strat->S;
3225  int i;
3226  int an = 0;
3227  int en = length;
3228  int cmp_int = pOrdSgn;
3229  int pc=pGetComp(p);
3230  if ((currRing->MixedOrder)
3231#ifdef HAVE_PLURAL
3232  && (currRing->real_var_start==0)
3233#endif
3234#if 0
3235  || ((strat->ak>0) && ((currRing->order[0]==ringorder_c)||((currRing->order[0]==ringorder_C))))
3236#endif
3237  )
3238  {
3239    int o=pDeg(p);
3240    int oo=pDeg(set[length]);
3241
3242    if ((oo<o)
3243    || ((o==oo) && (pLmCmp(set[length],p)!= cmp_int)))
3244      return length+1;
3245
3246    loop
3247    {
3248      if (an >= en-1)
3249      {
3250        if ((pDeg(set[an])>=o) && (pLmCmp(set[an],p) == cmp_int))
3251        {
3252          return an;
3253        }
3254        return en;
3255      }
3256      i=(an+en) / 2;
3257      if ((pDeg(set[i])>=o) && (pLmCmp(set[i],p) == cmp_int)) en=i;
3258      else                              an=i;
3259    }
3260  }
3261  else
3262  {
3263#ifdef HAVE_RINGS
3264    if (rField_is_Ring(currRing))
3265    {
3266      if (pLmCmp(set[length],p)== -cmp_int)
3267        return length+1;
3268      int cmp;
3269      loop
3270      {
3271        if (an >= en-1)
3272        {
3273          cmp = pLmCmp(set[an],p);
3274          if (cmp == cmp_int)  return an;
3275          if (cmp == -cmp_int) return en;
3276          if (nDivBy(pGetCoeff(p), pGetCoeff(set[an]))) return en;
3277          return an;
3278        }
3279        i = (an+en) / 2;
3280        cmp = pLmCmp(set[i],p);
3281        if (cmp == cmp_int)         en = i;
3282        else if (cmp == -cmp_int)   an = i;
3283        else
3284        {
3285          if (nDivBy(pGetCoeff(p), pGetCoeff(set[i]))) an = i;
3286          else en = i;
3287        }
3288      }
3289    }
3290    else
3291#endif
3292    if (pLmCmp(set[length],p)== -cmp_int)
3293      return length+1;
3294
3295    loop
3296    {
3297      if (an >= en-1)
3298      {
3299        if (pLmCmp(set[an],p) == cmp_int) return an;
3300        if (pLmCmp(set[an],p) == -cmp_int) return en;
3301        if ((cmp_int!=1)
3302        && ((strat->ecartS[an])>ecart_p))
3303          return an;
3304        return en;
3305      }
3306      i=(an+en) / 2;
3307      if (pLmCmp(set[i],p) == cmp_int) en=i;
3308      else if (pLmCmp(set[i],p) == -cmp_int) an=i;
3309      else
3310      {
3311        if ((cmp_int!=1)
3312        &&((strat->ecartS[i])<ecart_p))
3313          en=i;
3314        else
3315          an=i;
3316      }
3317    }
3318  }
3319}
3320
3321
3322/*2
3323* looks up the position of p in set
3324* the position is the last one
3325*/
3326int posInT0 (const TSet set,const int length,LObject &p)
3327{
3328  return (length+1);
3329}
3330
3331
3332/*2
3333* looks up the position of p in T
3334* set[0] is the smallest with respect to the ordering-procedure
3335* pComp
3336*/
3337int posInT1 (const TSet set,const int length,LObject &p)
3338{
3339  if (length==-1) return 0;
3340
3341  if (pLmCmp(set[length].p,p.p)!= pOrdSgn) return length+1;
3342
3343  int i;
3344  int an = 0;
3345  int en= length;
3346
3347  loop
3348  {
3349    if (an >= en-1)
3350    {
3351      if (pLmCmp(set[an].p,p.p) == pOrdSgn) return an;
3352      return en;
3353    }
3354    i=(an+en) / 2;
3355    if (pLmCmp(set[i].p,p.p) == pOrdSgn) en=i;
3356    else                                 an=i;
3357  }
3358}
3359
3360/*2
3361* looks up the position of p in T
3362* set[0] is the smallest with respect to the ordering-procedure
3363* length
3364*/
3365int posInT2 (const TSet set,const int length,LObject &p)
3366{
3367  p.GetpLength();
3368  if (length==-1)
3369    return 0;
3370  if (set[length].length<p.length)
3371    return length+1;
3372
3373  int i;
3374  int an = 0;
3375  int en= length;
3376
3377  loop
3378  {
3379    if (an >= en-1)
3380    {
3381      if (set[an].length>p.length) return an;
3382      return en;
3383    }
3384    i=(an+en) / 2;
3385    if (set[i].length>p.length) en=i;
3386    else                        an=i;
3387  }
3388}
3389
3390/*2
3391* looks up the position of p in T
3392* set[0] is the smallest with respect to the ordering-procedure
3393* totaldegree,pComp
3394*/
3395int posInT11 (const TSet set,const int length,LObject &p)
3396/*{
3397 * int j=0;
3398 * int o;
3399 *
3400 * o = p.GetpFDeg();
3401 * loop
3402 * {
3403 *   if ((pFDeg(set[j].p) > o)
3404 *   || ((pFDeg(set[j].p) == o) && (pLmCmp(set[j].p,p.p) == pOrdSgn)))
3405 *   {
3406 *     return j;
3407 *   }
3408 *   j++;
3409 *   if (j > length) return j;
3410 * }
3411 *}
3412 */
3413{
3414  if (length==-1) return 0;
3415
3416  int o = p.GetpFDeg();
3417  int op = set[length].GetpFDeg();
3418
3419  if ((op < o)
3420  || ((op == o) && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
3421    return length+1;
3422
3423  int i;
3424  int an = 0;
3425  int en= length;
3426
3427  loop
3428  {
3429    if (an >= en-1)
3430    {
3431      op= set[an].GetpFDeg();
3432      if ((op > o)
3433      || (( op == o) && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
3434        return an;
3435      return en;
3436    }
3437    i=(an+en) / 2;
3438    op = set[i].GetpFDeg();
3439    if (( op > o)
3440    || (( op == o) && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
3441      en=i;
3442    else
3443      an=i;
3444  }
3445}
3446
3447/*2 Pos for rings T: Here I am
3448* looks up the position of p in T
3449* set[0] is the smallest with respect to the ordering-procedure
3450* totaldegree,pComp
3451*/
3452int posInTrg0 (const TSet set,const int length,LObject &p)
3453{
3454  if (length==-1) return 0;
3455  int o = p.GetpFDeg();
3456  int op = set[length].GetpFDeg();
3457  int i;
3458  int an = 0;
3459  int en = length;
3460  int cmp_int = pOrdSgn;
3461  if ((op < o) || (pLmCmp(set[length].p,p.p)== -cmp_int))
3462    return length+1;
3463  int cmp;
3464  loop
3465  {
3466    if (an >= en-1)
3467    {
3468      op = set[an].GetpFDeg();
3469      if (op > o) return an;
3470      if (op < 0) return en;
3471      cmp = pLmCmp(set[an].p,p.p);
3472      if (cmp == cmp_int)  return an;
3473      if (cmp == -cmp_int) return en;
3474      if (nGreater(pGetCoeff(p.p), pGetCoeff(set[an].p))) return en;
3475      return an;
3476    }
3477    i = (an + en) / 2;
3478    op = set[i].GetpFDeg();
3479    if (op > o)       en = i;
3480    else if (op < o)  an = i;
3481    else
3482    {
3483      cmp = pLmCmp(set[i].p,p.p);
3484      if (cmp == cmp_int)                                     en = i;
3485      else if (cmp == -cmp_int)                               an = i;
3486      else if (nGreater(pGetCoeff(p.p), pGetCoeff(set[i].p))) an = i;
3487      else                                                    en = i;
3488    }
3489  }
3490}
3491/*
3492  int o = p.GetpFDeg();
3493  int op = set[length].GetpFDeg();
3494
3495  if ((op < o)
3496  || ((op == o) && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
3497    return length+1;
3498
3499  int i;
3500  int an = 0;
3501  int en= length;
3502
3503  loop
3504  {
3505    if (an >= en-1)
3506    {
3507      op= set[an].GetpFDeg();
3508      if ((op > o)
3509      || (( op == o) && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
3510        return an;
3511      return en;
3512    }
3513    i=(an+en) / 2;
3514    op = set[i].GetpFDeg();
3515    if (( op > o)
3516    || (( op == o) && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
3517      en=i;
3518    else
3519      an=i;
3520  }
3521}
3522  */
3523/*2
3524* looks up the position of p in T
3525* set[0] is the smallest with respect to the ordering-procedure
3526* totaldegree,pComp
3527*/
3528int posInT110 (const TSet set,const int length,LObject &p)
3529{
3530  p.GetpLength();
3531  if (length==-1) return 0;
3532
3533  int o = p.GetpFDeg();
3534  int op = set[length].GetpFDeg();
3535
3536  if (( op < o)
3537  || (( op == o) && (set[length].length<p.length))
3538  || (( op == o) && (set[length].length == p.length)
3539     && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
3540    return length+1;
3541
3542  int i;
3543  int an = 0;
3544  int en= length;
3545  loop
3546  {
3547    if (an >= en-1)
3548    {
3549      op = set[an].GetpFDeg();
3550      if (( op > o)
3551      || (( op == o) && (set[an].length > p.length))
3552      || (( op == o) && (set[an].length == p.length)
3553         && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
3554        return an;
3555      return en;
3556    }
3557    i=(an+en) / 2;
3558    op = set[i].GetpFDeg();
3559    if (( op > o)
3560    || (( op == o) && (set[i].length > p.length))
3561    || (( op == o) && (set[i].length == p.length)
3562       && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
3563      en=i;
3564    else
3565      an=i;
3566  }
3567}
3568
3569/*2
3570* looks up the position of p in set
3571* set[0] is the smallest with respect to the ordering-procedure
3572* pFDeg
3573*/
3574int posInT13 (const TSet set,const int length,LObject &p)
3575{
3576  if (length==-1) return 0;
3577
3578  int o = p.GetpFDeg();
3579
3580  if (set[length].GetpFDeg() <= o)
3581    return length+1;
3582
3583  int i;
3584  int an = 0;
3585  int en= length;
3586  loop
3587  {
3588    if (an >= en-1)
3589    {
3590      if (set[an].GetpFDeg() > o)
3591        return an;
3592      return en;
3593    }
3594    i=(an+en) / 2;
3595    if (set[i].GetpFDeg() > o)
3596      en=i;
3597    else
3598      an=i;
3599  }
3600}
3601
3602// determines the position based on: 1.) Ecart 2.) pLength
3603int posInT_EcartpLength(const TSet set,const int length,LObject &p)
3604{
3605  int ol = p.GetpLength();
3606  if (length==-1) return 0;
3607
3608  int op=p.ecart;
3609
3610  int oo=set[length].ecart;
3611  if ((oo < op) || ((oo==op) && (set[length].length < ol)))
3612    return length+1;
3613
3614  int i;
3615  int an = 0;
3616  int en= length;
3617  loop
3618    {
3619      if (an >= en-1)
3620      {
3621        int oo=set[an].ecart;
3622        if((oo > op)
3623           || ((oo==op) && (set[an].pLength > ol)))
3624          return an;
3625        return en;
3626      }
3627      i=(an+en) / 2;
3628      int oo=set[i].ecart;
3629      if ((oo > op)
3630          || ((oo == op) && (set[i].pLength > ol)))
3631        en=i;
3632      else
3633        an=i;
3634    }
3635}
3636
3637/*2
3638* looks up the position of p in set
3639* set[0] is the smallest with respect to the ordering-procedure
3640* maximaldegree, pComp
3641*/
3642int posInT15 (const TSet set,const int length,LObject &p)
3643/*{
3644 *int j=0;
3645 * int o;
3646 *
3647 * o = p.GetpFDeg()+p.ecart;
3648 * loop
3649 * {
3650 *   if ((set[j].GetpFDeg()+set[j].ecart > o)
3651 *   || ((set[j].GetpFDeg()+set[j].ecart == o)
3652 *     && (pLmCmp(set[j].p,p.p) == pOrdSgn)))
3653 *   {
3654 *     return j;
3655 *   }
3656 *   j++;
3657 *   if (j > length) return j;
3658 * }
3659 *}
3660 */
3661{
3662  if (length==-1) return 0;
3663
3664  int o = p.GetpFDeg() + p.ecart;
3665  int op = set[length].GetpFDeg()+set[length].ecart;
3666
3667  if ((op < o)
3668  || ((op == o)
3669     && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
3670    return length+1;
3671
3672  int i;
3673  int an = 0;
3674  int en= length;
3675  loop
3676  {
3677    if (an >= en-1)
3678    {
3679      op = set[an].GetpFDeg()+set[an].ecart;
3680      if (( op > o)
3681      || (( op  == o) && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
3682        return an;
3683      return en;
3684    }
3685    i=(an+en) / 2;
3686    op = set[i].GetpFDeg()+set[i].ecart;
3687    if (( op > o)
3688    || (( op == o) && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
3689      en=i;
3690    else
3691      an=i;
3692  }
3693}
3694
3695/*2
3696* looks up the position of p in set
3697* set[0] is the smallest with respect to the ordering-procedure
3698* pFDeg+ecart, ecart, pComp
3699*/
3700int posInT17 (const TSet set,const int length,LObject &p)
3701/*
3702*{
3703* int j=0;
3704* int  o;
3705*
3706*  o = p.GetpFDeg()+p.ecart;
3707*  loop
3708*  {
3709*    if ((pFDeg(set[j].p)+set[j].ecart > o)
3710*    || (((pFDeg(set[j].p)+set[j].ecart == o)
3711*      && (set[j].ecart < p.ecart)))
3712*    || ((pFDeg(set[j].p)+set[j].ecart == o)
3713*      && (set[j].ecart==p.ecart)
3714*      && (pLmCmp(set[j].p,p.p)==pOrdSgn)))
3715*      return j;
3716*    j++;
3717*    if (j > length) return j;
3718*  }
3719* }
3720*/
3721{
3722  if (length==-1) return 0;
3723
3724  int o = p.GetpFDeg() + p.ecart;
3725  int op = set[length].GetpFDeg()+set[length].ecart;
3726
3727  if ((op < o)
3728  || (( op == o) && (set[length].ecart > p.ecart))
3729  || (( op == o) && (set[length].ecart==p.ecart)
3730     && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
3731    return length+1;
3732
3733  int i;
3734  int an = 0;
3735  int en= length;
3736  loop
3737  {
3738    if (an >= en-1)
3739    {
3740      op = set[an].GetpFDeg()+set[an].ecart;
3741      if (( op > o)
3742      || (( op == o) && (set[an].ecart < p.ecart))
3743      || (( op  == o) && (set[an].ecart==p.ecart)
3744         && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
3745        return an;
3746      return en;
3747    }
3748    i=(an+en) / 2;
3749    op = set[i].GetpFDeg()+set[i].ecart;
3750    if ((op > o)
3751    || (( op == o) && (set[i].ecart < p.ecart))
3752    || (( op == o) && (set[i].ecart == p.ecart)
3753       && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
3754      en=i;
3755    else
3756      an=i;
3757  }
3758}
3759/*2
3760* looks up the position of p in set
3761* set[0] is the smallest with respect to the ordering-procedure
3762* pGetComp, pFDeg+ecart, ecart, pComp
3763*/
3764int posInT17_c (const TSet set,const int length,LObject &p)
3765{
3766  if (length==-1) return 0;
3767
3768  int cc = (-1+2*currRing->order[0]==ringorder_c);
3769  /* cc==1 for (c,..), cc==-1 for (C,..) */
3770  int o = p.GetpFDeg() + p.ecart;
3771  int c = pGetComp(p.p)*cc;
3772
3773  if (pGetComp(set[length].p)*cc < c)
3774    return length+1;
3775  if (pGetComp(set[length].p)*cc == c)
3776  {
3777    int op = set[length].GetpFDeg()+set[length].ecart;
3778    if ((op < o)
3779    || ((op == o) && (set[length].ecart > p.ecart))
3780    || ((op == o) && (set[length].ecart==p.ecart)
3781       && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
3782      return length+1;
3783  }
3784
3785  int i;
3786  int an = 0;
3787  int en= length;
3788  loop
3789  {
3790    if (an >= en-1)
3791    {
3792      if (pGetComp(set[an].p)*cc < c)
3793        return en;
3794      if (pGetComp(set[an].p)*cc == c)
3795      {
3796        int op = set[an].GetpFDeg()+set[an].ecart;
3797        if ((op > o)
3798        || ((op == o) && (set[an].ecart < p.ecart))
3799        || ((op == o) && (set[an].ecart==p.ecart)
3800           && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
3801          return an;
3802      }
3803      return en;
3804    }
3805    i=(an+en) / 2;
3806    if (pGetComp(set[i].p)*cc > c)
3807      en=i;
3808    else if (pGetComp(set[i].p)*cc == c)
3809    {
3810      int op = set[i].GetpFDeg()+set[i].ecart;
3811      if ((op > o)
3812      || ((op == o) && (set[i].ecart < p.ecart))
3813      || ((op == o) && (set[i].ecart == p.ecart)
3814         && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
3815        en=i;
3816      else
3817        an=i;
3818    }
3819    else
3820      an=i;
3821  }
3822}
3823
3824/*2
3825* looks up the position of p in set
3826* set[0] is the smallest with respect to
3827* ecart, pFDeg, length
3828*/
3829int posInT19 (const TSet set,const int length,LObject &p)
3830{
3831  p.GetpLength();
3832  if (length==-1) return 0;
3833
3834  int o = p.ecart;
3835  int op=p.GetpFDeg();
3836
3837  if (set[length].ecart < o)
3838    return length+1;
3839  if (set[length].ecart == o)
3840  {
3841     int oo=set[length].GetpFDeg();
3842     if ((oo < op) || ((oo==op) && (set[length].length < p.length)))
3843       return length+1;
3844  }
3845
3846  int i;
3847  int an = 0;
3848  int en= length;
3849  loop
3850  {
3851    if (an >= en-1)
3852    {
3853      if (set[an].ecart > o)
3854        return an;
3855      if (set[an].ecart == o)
3856      {
3857         int oo=set[an].GetpFDeg();
3858         if((oo > op)
3859         || ((oo==op) && (set[an].length > p.length)))
3860           return an;
3861      }
3862      return en;
3863    }
3864    i=(an+en) / 2;
3865    if (set[i].ecart > o)
3866      en=i;
3867    else if (set[i].ecart == o)
3868    {
3869       int oo=set[i].GetpFDeg();
3870       if ((oo > op)
3871       || ((oo == op) && (set[i].length > p.length)))
3872         en=i;
3873       else
3874        an=i;
3875    }
3876    else
3877      an=i;
3878  }
3879}
3880
3881/*2
3882*looks up the position of polynomial p in set
3883*set[length] is the smallest element in set with respect
3884*to the ordering-procedure pComp
3885*/
3886int posInLSpecial (const LSet set, const int length,
3887                   LObject *p,const kStrategy strat)
3888{
3889  if (length<0) return 0;
3890
3891  int d=p->GetpFDeg();
3892  int op=set[length].GetpFDeg();
3893
3894  if ((op > d)
3895  || ((op == d) && (p->p1!=NULL)&&(set[length].p1==NULL))
3896  || (pLmCmp(set[length].p,p->p)== pOrdSgn))
3897     return length+1;
3898
3899  int i;
3900  int an = 0;
3901  int en= length;
3902  loop
3903  {
3904    if (an >= en-1)
3905    {
3906      op=set[an].GetpFDeg();
3907      if ((op > d)
3908      || ((op == d) && (p->p1!=NULL) && (set[an].p1==NULL))
3909      || (pLmCmp(set[an].p,p->p)== pOrdSgn))
3910         return en;
3911      return an;
3912    }
3913    i=(an+en) / 2;
3914    op=set[i].GetpFDeg();
3915    if ((op>d)
3916    || ((op==d) && (p->p1!=NULL) && (set[i].p1==NULL))
3917    || (pLmCmp(set[i].p,p->p) == pOrdSgn))
3918      an=i;
3919    else
3920      en=i;
3921  }
3922}
3923
3924/*2
3925*looks up the position of polynomial p in set
3926*set[length] is the smallest element in set with respect
3927*to the ordering-procedure pComp
3928*/
3929int posInL0 (const LSet set, const int length,
3930             LObject* p,const kStrategy strat)
3931{
3932  if (length<0) return 0;
3933
3934  if (pLmCmp(set[length].p,p->p)== pOrdSgn)
3935    return length+1;
3936
3937  int i;
3938  int an = 0;
3939  int en= length;
3940  loop
3941  {
3942    if (an >= en-1)
3943    {
3944      if (pLmCmp(set[an].p,p->p) == pOrdSgn) return en;
3945      return an;
3946    }
3947    i=(an+en) / 2;
3948    if (pLmCmp(set[i].p,p->p) == pOrdSgn) an=i;
3949    else                                 en=i;
3950    /*aend. fuer lazy == in !=- machen */
3951  }
3952}
3953
3954/*2
3955* looks up the position of polynomial p in set
3956* e is the ecart of p
3957* set[length] is the smallest element in set with respect
3958* to the ordering-procedure totaldegree,pComp
3959*/
3960int posInL11 (const LSet set, const int length,
3961              LObject* p,const kStrategy strat)
3962/*{
3963 * int j=0;
3964 * int o;
3965 *
3966 * o = p->GetpFDeg();
3967 * loop
3968 * {
3969 *   if (j > length)            return j;
3970 *   if ((set[j].GetpFDeg() < o)) return j;
3971 *   if ((set[j].GetpFDeg() == o) && (pLmCmp(set[j].p,p->p) == -pOrdSgn))
3972 *   {
3973 *     return j;
3974 *   }
3975 *   j++;
3976 * }
3977 *}
3978 */
3979{
3980  if (length<0) return 0;
3981
3982  int o = p->GetpFDeg();
3983  int op = set[length].GetpFDeg();
3984
3985  if ((op > o)
3986  || ((op == o) && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
3987    return length+1;
3988  int i;
3989  int an = 0;
3990  int en= length;
3991  loop
3992  {
3993    if (an >= en-1)
3994    {
3995      op = set[an].GetpFDeg();
3996      if ((op > o)
3997      || ((op == o) && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
3998        return en;
3999      return an;
4000    }
4001    i=(an+en) / 2;
4002    op = set[i].GetpFDeg();
4003    if ((op > o)
4004    || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
4005      an=i;
4006    else
4007      en=i;
4008  }
4009}
4010
4011/*2 Position for rings L: Here I am
4012* looks up the position of polynomial p in set
4013* e is the ecart of p
4014* set[length] is the smallest element in set with respect
4015* to the ordering-procedure totaldegree,pComp
4016*/
4017inline int getIndexRng(long coeff)
4018{
4019  if (coeff == 0) return -1;
4020  long tmp = coeff;
4021  int ind = 0;
4022  while (tmp % 2 == 0)
4023  {
4024    tmp = tmp / 2;
4025    ind++;
4026  }
4027  return ind;
4028}
4029
4030int posInLrg0 (const LSet set, const int length,
4031              LObject* p,const kStrategy strat)
4032/*          if (nGreater(pGetCoeff(p), pGetCoeff(set[an]))) return en;
4033        if (pLmCmp(set[i],p) == cmp_int)         en = i;
4034        else if (pLmCmp(set[i],p) == -cmp_int)   an = i;
4035        else
4036        {
4037          if (nGreater(pGetCoeff(p), pGetCoeff(set[i]))) an = i;
4038          else en = i;
4039        }*/
4040{
4041  if (length < 0) return 0;
4042
4043  int o = p->GetpFDeg();
4044  int op = set[length].GetpFDeg();
4045
4046  if ((op > o) || ((op == o) && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
4047    return length + 1;
4048  int i;
4049  int an = 0;
4050  int en = length;
4051  loop
4052  {
4053    if (an >= en - 1)
4054    {
4055      op = set[an].GetpFDeg();
4056      if ((op > o) || ((op == o) && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
4057        return en;
4058      return an;
4059    }
4060    i = (an+en) / 2;
4061    op = set[i].GetpFDeg();
4062    if ((op > o) || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
4063      an = i;
4064    else
4065      en = i;
4066  }
4067}
4068
4069/*{
4070  if (length < 0) return 0;
4071
4072  int o = p->GetpFDeg();
4073  int op = set[length].GetpFDeg();
4074
4075  int inde = getIndexRng((unsigned long) pGetCoeff(set[length].p));
4076  int indp = getIndexRng((unsigned long) pGetCoeff(p->p));
4077  int inda;
4078  int indi;
4079
4080  if ((inda > indp) || ((inda == inde) && ((op > o) || ((op == o) && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))))
4081    return length + 1;
4082  int i;
4083  int an = 0;
4084  inda = getIndexRng((unsigned long) pGetCoeff(set[an].p));
4085  int en = length;
4086  loop
4087  {
4088    if (an >= en-1)
4089    {
4090      op = set[an].GetpFDeg();
4091      if ((indp > inda) || ((indp == inda) && ((op > o) || ((op == o) && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))))
4092        return en;
4093      return an;
4094    }
4095    i = (an + en) / 2;
4096    indi = getIndexRng((unsigned long) pGetCoeff(set[i].p));
4097    op = set[i].GetpFDeg();
4098    if ((indi > indp) || ((indi == indp) && ((op > o) || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))))
4099    // if ((op > o) || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
4100    {
4101      an = i;
4102      inda = getIndexRng((unsigned long) pGetCoeff(set[an].p));
4103    }
4104    else
4105      en = i;
4106  }
4107} */
4108
4109/*2
4110* looks up the position of polynomial p in set
4111* set[length] is the smallest element in set with respect
4112* to the ordering-procedure totaldegree,pLength0
4113*/
4114int posInL110 (const LSet set, const int length,
4115               LObject* p,const kStrategy strat)
4116{
4117  if (length<0) return 0;
4118
4119  int o = p->GetpFDeg();
4120  int op = set[length].GetpFDeg();
4121
4122  if ((op > o)
4123  || ((op == o) && (set[length].length >p->length))
4124  || ((op == o) && (set[length].length <= p->length)
4125     && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
4126    return length+1;
4127  int i;
4128  int an = 0;
4129  int en= length;
4130  loop
4131  {
4132    if (an >= en-1)
4133    {
4134      op = set[an].GetpFDeg();
4135      if ((op > o)
4136      || ((op == o) && (set[an].length >p->length))
4137      || ((op == o) && (set[an].length <=p->length)
4138         && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
4139        return en;
4140      return an;
4141    }
4142    i=(an+en) / 2;
4143    op = set[i].GetpFDeg();
4144    if ((op > o)
4145    || ((op == o) && (set[i].length > p->length))
4146    || ((op == o) && (set[i].length <= p->length)
4147       && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
4148      an=i;
4149    else
4150      en=i;
4151  }
4152}
4153
4154/*2
4155* looks up the position of polynomial p in set
4156* e is the ecart of p
4157* set[length] is the smallest element in set with respect
4158* to the ordering-procedure totaldegree
4159*/
4160int posInL13 (const LSet set, const int length,
4161              LObject* p,const kStrategy strat)
4162{
4163  if (length<0) return 0;
4164
4165  int o = p->GetpFDeg();
4166
4167  if (set[length].GetpFDeg() > o)
4168    return length+1;
4169
4170  int i;
4171  int an = 0;
4172  int en= length;
4173  loop
4174  {
4175    if (an >= en-1)
4176    {
4177      if (set[an].GetpFDeg() >= o)
4178        return en;
4179      return an;
4180    }
4181    i=(an+en) / 2;
4182    if (set[i].GetpFDeg() >= o)
4183      an=i;
4184    else
4185      en=i;
4186  }
4187}
4188
4189/*2
4190* looks up the position of polynomial p in set
4191* e is the ecart of p
4192* set[length] is the smallest element in set with respect
4193* to the ordering-procedure maximaldegree,pComp
4194*/
4195int posInL15 (const LSet set, const int length,
4196              LObject* p,const kStrategy strat)
4197/*{
4198 * int j=0;
4199 * int o;
4200 *
4201 * o = p->ecart+p->GetpFDeg();
4202 * loop
4203 * {
4204 *   if (j > length)                       return j;
4205 *   if (set[j].GetpFDeg()+set[j].ecart < o) return j;
4206 *   if ((set[j].GetpFDeg()+set[j].ecart == o)
4207 *   && (pLmCmp(set[j].p,p->p) == -pOrdSgn))
4208 *   {
4209 *     return j;
4210 *   }
4211 *   j++;
4212 * }
4213 *}
4214 */
4215{
4216  if (length<0) return 0;
4217
4218  int o = p->GetpFDeg() + p->ecart;
4219  int op = set[length].GetpFDeg() + set[length].ecart;
4220
4221  if ((op > o)
4222  || ((op == o) && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
4223    return length+1;
4224  int i;
4225  int an = 0;
4226  int en= length;
4227  loop
4228  {
4229    if (an >= en-1)
4230    {
4231      op = set[an].GetpFDeg() + set[an].ecart;
4232      if ((op > o)
4233      || ((op == o) && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
4234        return en;
4235      return an;
4236    }
4237    i=(an+en) / 2;
4238    op = set[i].GetpFDeg() + set[i].ecart;
4239    if ((op > o)
4240    || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
4241      an=i;
4242    else
4243      en=i;
4244  }
4245}
4246
4247/*2
4248* looks up the position of polynomial p in set
4249* e is the ecart of p
4250* set[length] is the smallest element in set with respect
4251* to the ordering-procedure totaldegree
4252*/
4253int posInL17 (const LSet set, const int length,
4254              LObject* p,const kStrategy strat)
4255{
4256  if (length<0) return 0;
4257
4258  int o = p->GetpFDeg() + p->ecart;
4259
4260  if ((set[length].GetpFDeg() + set[length].ecart > o)
4261  || ((set[length].GetpFDeg() + set[length].ecart == o)
4262     && (set[length].ecart > p->ecart))
4263  || ((set[length].GetpFDeg() + set[length].ecart == o)
4264     && (set[length].ecart == p->ecart)
4265     && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
4266    return length+1;
4267  int i;
4268  int an = 0;
4269  int en= length;
4270  loop
4271  {
4272    if (an >= en-1)
4273    {
4274      if ((set[an].GetpFDeg() + set[an].ecart > o)
4275      || ((set[an].GetpFDeg() + set[an].ecart == o)
4276         && (set[an].ecart > p->ecart))
4277      || ((set[an].GetpFDeg() + set[an].ecart == o)
4278         && (set[an].ecart == p->ecart)
4279         && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
4280        return en;
4281      return an;
4282    }
4283    i=(an+en) / 2;
4284    if ((set[i].GetpFDeg() + set[i].ecart > o)
4285    || ((set[i].GetpFDeg() + set[i].ecart == o)
4286       && (set[i].ecart > p->ecart))
4287    || ((set[i].GetpFDeg() +set[i].ecart == o)
4288       && (set[i].ecart == p->ecart)
4289       && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
4290      an=i;
4291    else
4292      en=i;
4293  }
4294}
4295/*2
4296* looks up the position of polynomial p in set
4297* e is the ecart of p
4298* set[length] is the smallest element in set with respect
4299* to the ordering-procedure pComp
4300*/
4301int posInL17_c (const LSet set, const int length,
4302                LObject* p,const kStrategy strat)
4303{
4304  if (length<0) return 0;
4305
4306  int cc = (-1+2*currRing->order[0]==ringorder_c);
4307  /* cc==1 for (c,..), cc==-1 for (C,..) */
4308  int c = pGetComp(p->p)*cc;
4309  int o = p->GetpFDeg() + p->ecart;
4310
4311  if (pGetComp(set[length].p)*cc > c)
4312    return length+1;
4313  if (pGetComp(set[length].p)*cc == c)
4314  {
4315    if ((set[length].GetpFDeg() + set[length].ecart > o)
4316    || ((set[length].GetpFDeg() + set[length].ecart == o)
4317       && (set[length].ecart > p->ecart))
4318    || ((set[length].GetpFDeg() + set[length].ecart == o)
4319       && (set[length].ecart == p->ecart)
4320       && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
4321      return length+1;
4322  }
4323  int i;
4324  int an = 0;
4325  int en= length;
4326  loop
4327  {
4328    if (an >= en-1)
4329    {
4330      if (pGetComp(set[an].p)*cc > c)
4331        return en;
4332      if (pGetComp(set[an].p)*cc == c)
4333      {
4334        if ((set[an].GetpFDeg() + set[an].ecart > o)
4335        || ((set[an].GetpFDeg() + set[an].ecart == o)
4336           && (set[an].ecart > p->ecart))
4337        || ((set[an].GetpFDeg() + set[an].ecart == o)
4338           && (set[an].ecart == p->ecart)
4339           && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
4340          return en;
4341      }
4342      return an;
4343    }
4344    i=(an+en) / 2;
4345    if (pGetComp(set[i].p)*cc > c)
4346      an=i;
4347    else if (pGetComp(set[i].p)*cc == c)
4348    {
4349      if ((set[i].GetpFDeg() + set[i].ecart > o)
4350      || ((set[i].GetpFDeg() + set[i].ecart == o)
4351         && (set[i].ecart > p->ecart))
4352      || ((set[i].GetpFDeg() +set[i].ecart == o)
4353         && (set[i].ecart == p->ecart)
4354         && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
4355        an=i;
4356      else
4357        en=i;
4358    }
4359    else
4360      en=i;
4361  }
4362}
4363
4364/***************************************************************
4365 *
4366 * Tail reductions
4367 *
4368 ***************************************************************/
4369TObject*
4370kFindDivisibleByInS(kStrategy strat, int pos, LObject* L, TObject *T,
4371                    long ecart)
4372{
4373  int j = 0;
4374  const unsigned long not_sev = ~L->sev;
4375  const unsigned long* sev = strat->sevS;
4376  poly p;
4377  ring r;
4378  L->GetLm(p, r);
4379
4380  assume(~not_sev == p_GetShortExpVector(p, r));
4381
4382  if (r == currRing)
4383  {
4384    loop
4385    {
4386      if (j > pos) return NULL;
4387#if defined(PDEBUG) || defined(PDIV_DEBUG)
4388      if (p_LmShortDivisibleBy(strat->S[j], sev[j], p, not_sev, r) &&
4389          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
4390        break;
4391#else
4392      if (!(sev[j] & not_sev) &&
4393          (ecart== LONG_MAX || ecart>= strat->ecartS[j]) &&
4394          p_LmDivisibleBy(strat->S[j], p, r))
4395        break;
4396
4397#endif
4398      j++;
4399    }
4400    // if called from NF, T objects do not exist:
4401    if (strat->tl < 0 || strat->S_2_R[j] == -1)
4402    {
4403      T->Set(strat->S[j], r, strat->tailRing);
4404      return T;
4405    }
4406    else
4407    {
4408/////      assume (j >= 0 && j <= strat->tl && strat->S_2_T(j) != NULL
4409/////      && strat->S_2_T(j)->p == strat->S[j]); // wrong?
4410//      assume (j >= 0 && j <= strat->sl && strat->S_2_T(j) != NULL && strat->S_2_T(j)->p == strat->S[j]);
4411      return strat->S_2_T(j);
4412    }
4413  }
4414  else
4415  {
4416    TObject* t;
4417    loop
4418    {
4419      if (j > pos) return NULL;
4420      assume(strat->S_2_R[j] != -1);
4421#if defined(PDEBUG) || defined(PDIV_DEBUG)
4422      t = strat->S_2_T(j);
4423      assume(t != NULL && t->t_p != NULL && t->tailRing == r);
4424      if (p_LmShortDivisibleBy(t->t_p, sev[j], p, not_sev, r) &&
4425          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
4426        return t;
4427#else
4428      if (! (sev[j] & not_sev) && (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
4429      {
4430        t = strat->S_2_T(j);
4431        assume(t != NULL && t->t_p != NULL && t->tailRing == r && t->p == strat->S[j]);
4432        if (p_LmDivisibleBy(t->t_p, p, r)) return t;
4433      }
4434#endif
4435      j++;
4436    }
4437  }
4438}
4439
4440poly redtail (LObject* L, int pos, kStrategy strat)
4441{
4442  poly h, hn;
4443  int j;
4444  unsigned long not_sev;
4445  strat->redTailChange=FALSE;
4446
4447  poly p = L->p;
4448  if (strat->noTailReduction || pNext(p) == NULL)
4449    return p;
4450
4451  LObject Ln(strat->tailRing);
4452  TObject* With;
4453  // placeholder in case strat->tl < 0
4454  TObject  With_s(strat->tailRing);
4455  h = p;
4456  hn = pNext(h);
4457  long op = strat->tailRing->pFDeg(hn, strat->tailRing);
4458  long e;
4459  int l;
4460  BOOLEAN save_HE=strat->kHEdgeFound;
4461  strat->kHEdgeFound |=
4462    ((Kstd1_deg>0) && (op<=Kstd1_deg)) || TEST_OPT_INFREDTAIL;
4463
4464  while(hn != NULL)
4465  {
4466    op = strat->tailRing->pFDeg(hn, strat->tailRing);
4467    if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
4468    e = strat->tailRing->pLDeg(hn, &l, strat->tailRing) - op;
4469    loop
4470    {
4471      Ln.Set(hn, strat->tailRing);
4472      Ln.sev = p_GetShortExpVector(hn, strat->tailRing);
4473      if (strat->kHEdgeFound)
4474        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
4475      else
4476        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s, e);
4477      if (With == NULL) break;
4478      With->length=0;
4479      With->pLength=0;
4480      strat->redTailChange=TRUE;
4481      if (ksReducePolyTail(L, With, h, strat->kNoetherTail()))
4482      {
4483        // reducing the tail would violate the exp bound
4484        if (kStratChangeTailRing(strat, L))
4485        {
4486          strat->kHEdgeFound = save_HE;
4487          return redtail(L, pos, strat);
4488        }
4489        else
4490          return NULL;
4491      }
4492      hn = pNext(h);
4493      if (hn == NULL) goto all_done;
4494      op = strat->tailRing->pFDeg(hn, strat->tailRing);
4495      if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
4496      e = strat->tailRing->pLDeg(hn, &l, strat->tailRing) - op;
4497    }
4498    h = hn;
4499    hn = pNext(h);
4500  }
4501
4502  all_done:
4503  if (strat->redTailChange)
4504  {
4505    L->last = NULL;
4506    L->pLength = 0;
4507  }
4508  strat->kHEdgeFound = save_HE;
4509  return p;
4510}
4511
4512poly redtail (poly p, int pos, kStrategy strat)
4513{
4514  LObject L(p, currRing);
4515  return redtail(&L, pos, strat);
4516}
4517
4518poly redtailBba (LObject* L, int pos, kStrategy strat, BOOLEAN withT, BOOLEAN normalize)
4519{
4520#define REDTAIL_CANONICALIZE 100
4521  strat->redTailChange=FALSE;
4522  if (strat->noTailReduction) return L->GetLmCurrRing();
4523  poly h, p;
4524  p = h = L->GetLmTailRing();
4525  if ((h==NULL) || (pNext(h)==NULL))
4526    return L->GetLmCurrRing();
4527
4528  TObject* With;
4529  // placeholder in case strat->tl < 0
4530  TObject  With_s(strat->tailRing);
4531
4532  LObject Ln(pNext(h), strat->tailRing);
4533  Ln.pLength = L->GetpLength() - 1;
4534
4535  pNext(h) = NULL;
4536  if (L->p != NULL) pNext(L->p) = NULL;
4537  L->pLength = 1;
4538
4539  Ln.PrepareRed(strat->use_buckets);
4540
4541  int cnt=REDTAIL_CANONICALIZE;
4542  while(!Ln.IsNull())
4543  {
4544    loop
4545    {
4546      Ln.SetShortExpVector();
4547      if (withT)
4548      {
4549        int j;
4550        j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln);
4551        if (j < 0) break;
4552        With = &(strat->T[j]);
4553      }
4554      else
4555      {
4556        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
4557        if (With == NULL) break;
4558      }
4559      cnt--;
4560      if (cnt==0)
4561      {
4562        cnt=REDTAIL_CANONICALIZE;
4563        poly tmp=Ln.CanonicalizeP();
4564        if (normalize)
4565        {
4566          Ln.Normalize();
4567          //pNormalize(tmp);
4568          //if (TEST_OPT_PROT) { PrintS("n"); mflush(); }
4569        }
4570      }
4571      if (normalize && (!TEST_OPT_INTSTRATEGY) && (!nIsOne(pGetCoeff(With->p))))
4572      {
4573        With->pNorm();
4574      }
4575      strat->redTailChange=TRUE;
4576      if (ksReducePolyTail(L, With, &Ln))
4577      {
4578        // reducing the tail would violate the exp bound
4579        //  set a flag and hope for a retry (in bba)
4580        strat->completeReduce_retry=TRUE;
4581        if ((Ln.p != NULL) && (Ln.t_p != NULL)) Ln.p=NULL;
4582        do
4583        {
4584          pNext(h) = Ln.LmExtractAndIter();
4585          pIter(h);
4586          L->pLength++;
4587        } while (!Ln.IsNull());
4588        goto all_done;
4589      }
4590      if (Ln.IsNull()) goto all_done;
4591      if (! withT) With_s.Init(currRing);
4592    }
4593    pNext(h) = Ln.LmExtractAndIter();
4594    pIter(h);
4595    pNormalize(h);
4596    L->pLength++;
4597  }
4598
4599  all_done:
4600  Ln.Delete();
4601  if (L->p != NULL) pNext(L->p) = pNext(p);
4602
4603  if (strat->redTailChange)
4604  {
4605    L->last = NULL;
4606    L->length = 0;
4607  }
4608
4609  //if (TEST_OPT_PROT) { PrintS("N"); mflush(); }
4610  //L->Normalize(); // HANNES: should have a test
4611  kTest_L(L);
4612  return L->GetLmCurrRing();
4613}
4614
4615#ifdef HAVE_RINGS
4616poly redtailBba_Z (LObject* L, int pos, kStrategy strat )
4617// normalize=FALSE, withT=FALSE, coeff=Z
4618{
4619  strat->redTailChange=FALSE;
4620  if (strat->noTailReduction) return L->GetLmCurrRing();
4621  poly h, p;
4622  p = h = L->GetLmTailRing();
4623  if ((h==NULL) || (pNext(h)==NULL))
4624    return L->GetLmCurrRing();
4625
4626  TObject* With;
4627  // placeholder in case strat->tl < 0
4628  TObject  With_s(strat->tailRing);
4629
4630  LObject Ln(pNext(h), strat->tailRing);
4631  Ln.pLength = L->GetpLength() - 1;
4632
4633  pNext(h) = NULL;
4634  if (L->p != NULL) pNext(L->p) = NULL;
4635  L->pLength = 1;
4636
4637  Ln.PrepareRed(strat->use_buckets);
4638
4639  int cnt=REDTAIL_CANONICALIZE;
4640  while(!Ln.IsNull())
4641  {
4642    loop
4643    {
4644      Ln.SetShortExpVector();
4645      With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
4646      if (With == NULL) break;
4647      cnt--;
4648      if (cnt==0)
4649      {
4650        cnt=REDTAIL_CANONICALIZE;
4651        poly tmp=Ln.CanonicalizeP();
4652      }
4653      // we are in Z, do not Ccall pNorm
4654      strat->redTailChange=TRUE;
4655      // test divisibility of coefs:
4656      poly p_Ln=Ln.GetLmCurrRing();
4657      poly p_With=With->GetLmCurrRing();
4658      number z=nIntMod(pGetCoeff(p_Ln),pGetCoeff(p_With));
4659      if (!nIsZero(z))
4660      {
4661        // subtract z*Ln, add z.Ln to L
4662        poly m=pHead(p_Ln);
4663        pSetCoeff(m,z);
4664        poly mm=pHead(m);
4665        pNext(h) = m;
4666        pIter(h);
4667        L->pLength++;
4668        mm=pNeg(mm);
4669        if (Ln.bucket!=NULL)
4670        {
4671          int dummy=1;
4672          kBucket_Add_q(Ln.bucket,mm,&dummy);
4673        }
4674        else
4675        {
4676          if (Ln.p!=NULL) Ln.p=pAdd(Ln.p,mm);
4677          else if (Ln.t_p!=NULL)  Ln.t_p=p_Add_q(Ln.t_p,mm,strat->tailRing);
4678        }
4679      }
4680      else
4681        nDelete(&z);
4682
4683      if (ksReducePolyTail(L, With, &Ln))
4684      {
4685        // reducing the tail would violate the exp bound
4686        //  set a flag and hope for a retry (in bba)
4687        strat->completeReduce_retry=TRUE;
4688        if ((Ln.p != NULL) && (Ln.t_p != NULL)) Ln.p=NULL;
4689        do
4690        {
4691          pNext(h) = Ln.LmExtractAndIter();
4692          pIter(h);
4693          L->pLength++;
4694        } while (!Ln.IsNull());
4695        goto all_done;
4696      }
4697      if (Ln.IsNull()) goto all_done;
4698      With_s.Init(currRing);
4699    }
4700    pNext(h) = Ln.LmExtractAndIter();
4701    pIter(h);
4702    pNormalize(h);
4703    L->pLength++;
4704  }
4705
4706  all_done:
4707  Ln.Delete();
4708  if (L->p != NULL) pNext(L->p) = pNext(p);
4709
4710  if (strat->redTailChange)
4711  {
4712    L->last = NULL;
4713    L->length = 0;
4714  }
4715
4716  //if (TEST_OPT_PROT) { PrintS("N"); mflush(); }
4717  //L->Normalize(); // HANNES: should have a test
4718  kTest_L(L);
4719  return L->GetLmCurrRing();
4720}
4721#endif
4722
4723/*2
4724*checks the change degree and write progress report
4725*/
4726void message (int i,int* reduc,int* olddeg,kStrategy strat, int red_result)
4727{
4728  if (i != *olddeg)
4729  {
4730    Print("%d",i);
4731    *olddeg = i;
4732  }
4733  if (TEST_OPT_OLDSTD)
4734  {
4735    if (strat->Ll != *reduc)
4736    {
4737      if (strat->Ll != *reduc-1)
4738        Print("(%d)",strat->Ll+1);
4739      else
4740        PrintS("-");
4741      *reduc = strat->Ll;
4742    }
4743    else
4744      PrintS(".");
4745    mflush();
4746  }
4747  else
4748  {
4749    if (red_result == 0)
4750      PrintS("-");
4751    else if (red_result < 0)
4752      PrintS(".");
4753    if ((red_result > 0) || ((strat->Ll % 100)==99))
4754    {
4755      if (strat->Ll != *reduc && strat->Ll > 0)
4756      {
4757        Print("(%d)",strat->Ll+1);
4758        *reduc = strat->Ll;
4759      }
4760    }
4761  }
4762}
4763
4764/*2
4765*statistics
4766*/
4767void messageStat (int srmax,int lrmax,int hilbcount,kStrategy strat)
4768{
4769  //PrintS("\nUsage/Allocation of temporary storage:\n");
4770  //Print("%d/%d polynomials in standard base\n",srmax,IDELEMS(Shdl));
4771  //Print("%d/%d polynomials in set L (for lazy alg.)",lrmax+1,strat->Lmax);
4772  Print("product criterion:%d chain criterion:%d\n",strat->cp,strat->c3);
4773  if (hilbcount!=0) Print("hilbert series criterion:%d\n",hilbcount);
4774  /* in usual case strat->cv is 0, it gets changed only in shift routines */
4775  if (strat->cv!=0) Print("shift V criterion:%d\n",strat->cv);
4776  /*mflush();*/
4777}
4778
4779#ifdef KDEBUG
4780/*2
4781*debugging output: all internal sets, if changed
4782*for testing purpuse only/has to be changed for later use
4783*/
4784void messageSets (kStrategy strat)
4785{
4786  int i;
4787  if (strat->news)
4788  {
4789    PrintS("set S");
4790    for (i=0; i<=strat->sl; i++)
4791    {
4792      Print("\n  %d:",i);
4793      p_wrp(strat->S[i], currRing, strat->tailRing);
4794    }
4795    strat->news = FALSE;
4796  }
4797  if (strat->newt)
4798  {
4799    PrintS("\nset T");
4800    for (i=0; i<=strat->tl; i++)
4801    {
4802      Print("\n  %d:",i);
4803      strat->T[i].wrp();
4804      Print(" o:%ld e:%d l:%d",
4805        strat->T[i].pFDeg(),strat->T[i].ecart,strat->T[i].length);
4806    }
4807    strat->newt = FALSE;
4808  }
4809  PrintS("\nset L");
4810  for (i=strat->Ll; i>=0; i--)
4811  {
4812    Print("\n%d:",i);
4813    p_wrp(strat->L[i].p1, currRing, strat->tailRing);
4814    PrintS("  ");
4815    p_wrp(strat->L[i].p2, currRing, strat->tailRing);
4816    PrintS(" lcm: ");p_wrp(strat->L[i].lcm, currRing);
4817    PrintS("\n  p : ");
4818    strat->L[i].wrp();
4819    Print("  o:%ld e:%d l:%d",
4820          strat->L[i].pFDeg(),strat->L[i].ecart,strat->L[i].length);
4821  }
4822  PrintLn();
4823}
4824
4825#endif
4826
4827
4828/*2
4829*construct the set s from F
4830*/
4831void initS (ideal F, ideal Q, kStrategy strat)
4832{
4833  int   i,pos;
4834
4835  if (Q!=NULL) i=((IDELEMS(F)+IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
4836  else         i=((IDELEMS(F)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
4837  strat->ecartS=initec(i);
4838  strat->sevS=initsevS(i);
4839  strat->S_2_R=initS_2_R(i);
4840  strat->fromQ=NULL;
4841  strat->Shdl=idInit(i,F->rank);
4842  strat->S=strat->Shdl->m;
4843  /*- put polys into S -*/
4844  if (Q!=NULL)
4845  {
4846    strat->fromQ=initec(i);
4847    memset(strat->fromQ,0,i*sizeof(int));
4848    for (i=0; i<IDELEMS(Q); i++)
4849    {
4850      if (Q->m[i]!=NULL)
4851      {
4852        LObject h;
4853        h.p = pCopy(Q->m[i]);
4854        if (TEST_OPT_INTSTRATEGY)
4855        {
4856          //pContent(h.p);
4857          h.pCleardenom(); // also does a pContent
4858        }
4859        else
4860        {
4861          h.pNorm();
4862        }
4863        if (pOrdSgn==-1)
4864        {
4865          deleteHC(&h, strat);
4866        }
4867        if (h.p!=NULL)
4868        {
4869          strat->initEcart(&h);
4870          if (strat->sl==-1)
4871            pos =0;
4872          else
4873          {
4874            pos = posInS(strat,strat->sl,h.p,h.ecart);
4875          }
4876          h.sev = pGetShortExpVector(h.p);
4877          strat->enterS(h,pos,strat,-1);
4878          strat->fromQ[pos]=1;
4879        }
4880      }
4881    }
4882  }
4883  for (i=0; i<IDELEMS(F); i++)
4884  {
4885    if (F->m[i]!=NULL)
4886    {
4887      LObject h;
4888      h.p = pCopy(F->m[i]);
4889      if (pOrdSgn==-1)
4890      {
4891        cancelunit(&h);  /*- tries to cancel a unit -*/
4892        deleteHC(&h, strat);
4893      }
4894      if (h.p!=NULL)
4895      // do not rely on the input being a SB!
4896      {
4897        if (TEST_OPT_INTSTRATEGY)
4898        {
4899          //pContent(h.p);
4900          h.pCleardenom(); // also does a pContent
4901        }
4902        else
4903        {
4904          h.pNorm();
4905        }
4906        strat->initEcart(&h);
4907        if (strat->sl==-1)
4908          pos =0;
4909        else
4910          pos = posInS(strat,strat->sl,h.p,h.ecart);
4911        h.sev = pGetShortExpVector(h.p);
4912        strat->enterS(h,pos,strat,-1);
4913      }
4914    }
4915  }
4916  /*- test, if a unit is in F -*/
4917  if ((strat->sl>=0)
4918#ifdef HAVE_RINGS
4919       && nIsUnit(pGetCoeff(strat->S[0]))
4920#endif
4921       && pIsConstant(strat->S[0]))
4922  {
4923    while (strat->sl>0) deleteInS(strat->sl,strat);
4924  }
4925}
4926
4927void initSL (ideal F, ideal Q,kStrategy strat)
4928{
4929  int   i,pos;
4930
4931  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
4932  else i=setmaxT;
4933  strat->ecartS=initec(i);
4934  strat->sevS=initsevS(i);
4935  strat->S_2_R=initS_2_R(i);
4936  strat->fromQ=NULL;
4937  strat->Shdl=idInit(i,F->rank);
4938  strat->S=strat->Shdl->m;
4939  /*- put polys into S -*/
4940  if (Q!=NULL)
4941  {
4942    strat->fromQ=initec(i);
4943    memset(strat->fromQ,0,i*sizeof(int));
4944    for (i=0; i<IDELEMS(Q); i++)
4945    {
4946      if (Q->m[i]!=NULL)
4947      {
4948        LObject h;
4949        h.p = pCopy(Q->m[i]);
4950        if (pOrdSgn==-1)
4951        {
4952          deleteHC(&h,strat);
4953        }
4954        if (TEST_OPT_INTSTRATEGY)
4955        {
4956          //pContent(h.p);
4957          h.pCleardenom(); // also does a pContent
4958        }
4959        else
4960        {
4961          h.pNorm();
4962        }
4963        if (h.p!=NULL)
4964        {
4965          strat->initEcart(&h);
4966          if (strat->sl==-1)
4967            pos =0;
4968          else
4969          {
4970            pos = posInS(strat,strat->sl,h.p,h.ecart);
4971          }
4972          h.sev = pGetShortExpVector(h.p);
4973          strat->enterS(h,pos,strat,-1);
4974          strat->fromQ[pos]=1;
4975        }
4976      }
4977    }
4978  }
4979  for (i=0; i<IDELEMS(F); i++)
4980  {
4981    if (F->m[i]!=NULL)
4982    {
4983      LObject h;
4984      h.p = pCopy(F->m[i]);
4985      if (h.p!=NULL)
4986      {
4987        if (pOrdSgn==-1)
4988        {
4989          cancelunit(&h);  /*- tries to cancel a unit -*/
4990          deleteHC(&h, strat);
4991        }
4992        if (h.p!=NULL)
4993        {
4994          if (TEST_OPT_INTSTRATEGY)
4995          {
4996            //pContent(h.p);
4997            h.pCleardenom(); // also does a pContent
4998          }
4999          else
5000          {
5001            h.pNorm();
5002          }
5003          strat->initEcart(&h);
5004          if (strat->Ll==-1)
5005            pos =0;
5006          else
5007            pos = strat->posInL(strat->L,strat->Ll,&h,strat);
5008          h.sev = pGetShortExpVector(h.p);
5009          enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
5010        }
5011      }
5012    }
5013  }
5014  /*- test, if a unit is in F -*/
5015
5016  if ((strat->Ll>=0)
5017#ifdef HAVE_RINGS
5018       && nIsUnit(pGetCoeff(strat->L[strat->Ll].p))
5019#endif
5020       && pIsConstant(strat->L[strat->Ll].p))
5021  {
5022    while (strat->Ll>0) deleteInL(strat->L,&strat->Ll,strat->Ll-1,strat);
5023  }
5024}
5025
5026
5027/*2
5028*construct the set s from F and {P}
5029*/
5030void initSSpecial (ideal F, ideal Q, ideal P,kStrategy strat)
5031{
5032  int   i,pos;
5033
5034  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
5035  else i=setmaxT;
5036  i=((i+IDELEMS(F)+IDELEMS(P)+15)/16)*16;
5037  strat->ecartS=initec(i);
5038  strat->sevS=initsevS(i);
5039  strat->S_2_R=initS_2_R(i);
5040  strat->fromQ=NULL;
5041  strat->Shdl=idInit(i,F->rank);
5042  strat->S=strat->Shdl->m;
5043
5044  /*- put polys into S -*/
5045  if (Q!=NULL)
5046  {
5047    strat->fromQ=initec(i);
5048    memset(strat->fromQ,0,i*sizeof(int));
5049    for (i=0; i<IDELEMS(Q); i++)
5050    {
5051      if (Q->m[i]!=NULL)
5052      {
5053        LObject h;
5054        h.p = pCopy(Q->m[i]);
5055        //if (TEST_OPT_INTSTRATEGY)
5056        //{
5057        //  //pContent(h.p);
5058        //  h.pCleardenom(); // also does a pContent
5059        //}
5060        //else
5061        //{
5062        //  h.pNorm();
5063        //}
5064        if (pOrdSgn==-1)
5065        {
5066          deleteHC(&h,strat);
5067        }
5068        if (h.p!=NULL)
5069        {
5070          strat->initEcart(&h);
5071          if (strat->sl==-1)
5072            pos =0;
5073          else
5074          {
5075            pos = posInS(strat,strat->sl,h.p,h.ecart);
5076          }
5077          h.sev = pGetShortExpVector(h.p);
5078          strat->enterS(h,pos,strat, strat->tl+1);
5079          enterT(h, strat);
5080          strat->fromQ[pos]=1;
5081        }
5082      }
5083    }
5084  }
5085  /*- put polys into S -*/
5086  for (i=0; i<IDELEMS(F); i++)
5087  {
5088    if (F->m[i]!=NULL)
5089    {
5090      LObject h;
5091      h.p = pCopy(F->m[i]);
5092      if (pOrdSgn==-1)
5093      {
5094        deleteHC(&h,strat);
5095      }
5096      else
5097      {
5098        h.p=redtailBba(h.p,strat->sl,strat);
5099      }
5100      if (h.p!=NULL)
5101      {
5102        strat->initEcart(&h);
5103        if (strat->sl==-1)
5104          pos =0;
5105        else
5106          pos = posInS(strat,strat->sl,h.p,h.ecart);
5107        h.sev = pGetShortExpVector(h.p);
5108        strat->enterS(h,pos,strat, strat->tl+1);
5109        enterT(h,strat);
5110      }
5111    }
5112  }
5113  for (i=0; i<IDELEMS(P); i++)
5114  {
5115    if (P->m[i]!=NULL)
5116    {
5117      LObject h;
5118      h.p=pCopy(P->m[i]);
5119      if (TEST_OPT_INTSTRATEGY)
5120      {
5121        h.pCleardenom();
5122      }
5123      else
5124      {
5125        h.pNorm();
5126      }
5127      if(strat->sl>=0)
5128      {
5129        if (pOrdSgn==1)
5130        {
5131          h.p=redBba(h.p,strat->sl,strat);
5132          if (h.p!=NULL)
5133          {
5134            h.p=redtailBba(h.p,strat->sl,strat);
5135          }
5136        }
5137        else
5138        {
5139          h.p=redMora(h.p,strat->sl,strat);
5140        }
5141        if(h.p!=NULL)
5142        {
5143          strat->initEcart(&h);
5144          if (TEST_OPT_INTSTRATEGY)
5145          {
5146            h.pCleardenom();
5147          }
5148          else
5149          {
5150            h.is_normalized = 0;
5151            h.pNorm();
5152          }
5153          h.sev = pGetShortExpVector(h.p);
5154          h.SetpFDeg();
5155          pos = posInS(strat,strat->sl,h.p,h.ecart);
5156          enterpairsSpecial(h.p,strat->sl,h.ecart,pos,strat,strat->tl+1);
5157          strat->enterS(h,pos,strat, strat->tl+1);
5158          enterT(h,strat);
5159        }
5160      }
5161      else
5162      {
5163        h.sev = pGetShortExpVector(h.p);
5164        strat->initEcart(&h);
5165        strat->enterS(h,0,strat, strat->tl+1);
5166        enterT(h,strat);
5167      }
5168    }
5169  }
5170}
5171/*2
5172* reduces h using the set S
5173* procedure used in cancelunit1
5174*/
5175static poly redBba1 (poly h,int maxIndex,kStrategy strat)
5176{
5177  int j = 0;
5178  unsigned long not_sev = ~ pGetShortExpVector(h);
5179
5180  while (j <= maxIndex)
5181  {
5182    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j],h, not_sev))
5183       return ksOldSpolyRedNew(strat->S[j],h,strat->kNoetherTail());
5184    else j++;
5185  }
5186  return h;
5187}
5188
5189/*2
5190*tests if p.p=monomial*unit and cancels the unit
5191*/
5192void cancelunit1 (LObject* p,int *suc, int index,kStrategy strat )
5193{
5194  int k;
5195  poly r,h,h1,q;
5196
5197  if (!pIsVector((*p).p) && ((*p).ecart != 0))
5198  {
5199#ifdef HAVE_RINGS_LOC
5200    // Leading coef have to be a unit
5201    if ( !(nIsUnit(p_GetCoeff((*p).p, r))) ) return;
5202#endif
5203    k = 0;
5204    h1 = r = pCopy((*p).p);
5205    h =pNext(r);
5206    loop
5207    {
5208      if (h==NULL)
5209      {
5210        pDelete(&r);
5211        pDelete(&(pNext((*p).p)));
5212        (*p).ecart = 0;
5213        (*p).length = 1;
5214#ifdef HAVE_RINGS_LOC
5215        (*p).pLength = 1;  // Why wasn't this set already?
5216#endif
5217        (*suc)=0;
5218        return;
5219      }
5220      if (!pDivisibleBy(r,h))
5221      {
5222        q=redBba1(h,index ,strat);
5223        if (q != h)
5224        {
5225          k++;
5226          pDelete(&h);
5227          pNext(h1) = h = q;
5228        }
5229        else
5230        {
5231          pDelete(&r);
5232          return;
5233        }
5234      }
5235      else
5236      {
5237        h1 = h;
5238        pIter(h);
5239      }
5240      if (k > 10)
5241      {
5242        pDelete(&r);
5243        return;
5244      }
5245    }
5246  }
5247}
5248
5249#if 0
5250/*2
5251* reduces h using the elements from Q in the set S
5252* procedure used in updateS
5253* must not be used for elements of Q or elements of an ideal !
5254*/
5255static poly redQ (poly h, int j, kStrategy strat)
5256{
5257  int start;
5258  unsigned long not_sev = ~ pGetShortExpVector(h);
5259  while ((j <= strat->sl) && (pGetComp(strat->S[j])!=0)) j++;
5260  start=j;
5261  while (j<=strat->sl)
5262  {
5263    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev))
5264    {
5265      h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
5266      if (h==NULL) return NULL;
5267      j = start;
5268      not_sev = ~ pGetShortExpVector(h);
5269    }
5270    else j++;
5271  }
5272  return h;
5273}
5274#endif
5275
5276/*2
5277* reduces h using the set S
5278* procedure used in updateS
5279*/
5280static poly redBba (poly h,int maxIndex,kStrategy strat)
5281{
5282  int j = 0;
5283  unsigned long not_sev = ~ pGetShortExpVector(h);
5284
5285  while (j <= maxIndex)
5286  {
5287    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev))
5288    {
5289      h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
5290      if (h==NULL) return NULL;
5291      j = 0;
5292      not_sev = ~ pGetShortExpVector(h);    }
5293    else j++;
5294  }
5295  return h;
5296}
5297
5298/*2
5299* reduces h using the set S
5300*e is the ecart of h
5301*procedure used in updateS
5302*/
5303static poly redMora (poly h,int maxIndex,kStrategy strat)
5304{
5305  int  j=0;
5306  int  e,l;
5307  unsigned long not_sev = ~ pGetShortExpVector(h);
5308
5309  if (maxIndex >= 0)
5310  {
5311    e = pLDeg(h,&l,currRing)-pFDeg(h,currRing);
5312    do
5313    {
5314      if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev)
5315      && ((e >= strat->ecartS[j]) || strat->kHEdgeFound))
5316      {
5317#ifdef KDEBUG
5318        if (TEST_OPT_DEBUG)
5319          {PrintS("reduce ");wrp(h);Print(" with S[%d] (",j);wrp(strat->S[j]);}
5320#endif
5321        h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
5322#ifdef KDEBUG
5323        if(TEST_OPT_DEBUG)
5324          {PrintS(")\nto "); wrp(h); PrintLn();}
5325#endif
5326        // pDelete(&h);
5327        if (h == NULL) return NULL;
5328        e = pLDeg(h,&l,currRing)-pFDeg(h,currRing);
5329        j = 0;
5330        not_sev = ~ pGetShortExpVector(h);
5331      }
5332      else j++;
5333    }
5334    while (j <= maxIndex);
5335  }
5336  return h;
5337}
5338
5339/*2
5340*updates S:
5341*the result is a set of polynomials which are in
5342*normalform with respect to S
5343*/
5344void updateS(BOOLEAN toT,kStrategy strat)
5345{
5346  LObject h;
5347  int i, suc=0;
5348  poly redSi=NULL;
5349  BOOLEAN change,any_change;
5350//  Print("nach initS: updateS start mit sl=%d\n",(strat->sl));
5351//  for (i=0; i<=(strat->sl); i++)
5352//  {
5353//    Print("s%d:",i);
5354//    if (strat->fromQ!=NULL) Print("(Q:%d) ",strat->fromQ[i]);
5355//    pWrite(strat->S[i]);
5356//  }
5357//  Print("pOrdSgn=%d\n", pOrdSgn);
5358  any_change=FALSE;
5359  if (pOrdSgn==1)
5360  {
5361    while (suc != -1)
5362    {
5363      i=suc+1;
5364      while (i<=strat->sl)
5365      {
5366        change=FALSE;
5367        if (((strat->fromQ==NULL) || (strat->fromQ[i]==0)) && (i>0))
5368        {
5369          redSi = pHead(strat->S[i]);
5370          strat->S[i] = redBba(strat->S[i],i-1,strat);
5371          //if ((strat->ak!=0)&&(strat->S[i]!=NULL))
5372          //  strat->S[i]=redQ(strat->S[i],i+1,strat); /*reduce S[i] mod Q*/
5373          if (pCmp(redSi,strat->S[i])!=0)
5374          {
5375            change=TRUE;
5376            any_change=TRUE;
5377            #ifdef KDEBUG
5378            if (TEST_OPT_DEBUG)
5379            {
5380              PrintS("reduce:");
5381              wrp(redSi);PrintS(" to ");p_wrp(strat->S[i], currRing, strat->tailRing);PrintLn();
5382            }
5383            #endif
5384            if (TEST_OPT_PROT)
5385            {
5386              if (strat->S[i]==NULL)
5387                PrintS("V");
5388              else
5389                PrintS("v");
5390              mflush();
5391            }
5392          }
5393          pLmDelete(&redSi);
5394          if (strat->S[i]==NULL)
5395          {
5396            deleteInS(i,strat);
5397            i--;
5398          }
5399          else if (change)
5400          {
5401            if (TEST_OPT_INTSTRATEGY)
5402            {
5403              if (TEST_OPT_CONTENTSB)
5404                {
5405                  number n;
5406                  p_Cleardenom_n(strat->S[i], currRing, n);// also does a pContent
5407                  if (!nIsOne(n))
5408                    {
5409                      denominator_list denom=(denominator_list)omAlloc(sizeof(denominator_list_s));
5410                      denom->n=nInvers(n);
5411                      denom->next=DENOMINATOR_LIST;
5412                      DENOMINATOR_LIST=denom;
5413                    }
5414                  nDelete(&n);
5415                }
5416              else
5417                {
5418                  //pContent(strat->S[i]);
5419                  strat->S[i]=p_Cleardenom(strat->S[i], currRing);// also does a pContent
5420                }
5421            }
5422            else
5423            {
5424              pNorm(strat->S[i]);
5425            }
5426            strat->sevS[i] = pGetShortExpVector(strat->S[i]);
5427          }
5428        }
5429        i++;
5430      }
5431      if (any_change) reorderS(&suc,strat);
5432      else break;
5433    }
5434    if (toT)
5435    {
5436      for (i=0; i<=strat->sl; i++)
5437      {
5438        if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
5439        {
5440          h.p = redtailBba(strat->S[i],i-1,strat);
5441          if (TEST_OPT_INTSTRATEGY)
5442          {
5443            h.pCleardenom();// also does a pContent
5444          }
5445        }
5446        else
5447        {
5448          h.p = strat->S[i];
5449        }
5450        strat->initEcart(&h);
5451        if (strat->honey)
5452        {
5453          strat->ecartS[i] = h.ecart;
5454        }
5455        if (strat->sevS[i] == 0) {strat->sevS[i] = pGetShortExpVector(h.p);}
5456        else assume(strat->sevS[i] == pGetShortExpVector(h.p));
5457        h.sev = strat->sevS[i];
5458        /*puts the elements of S also to T*/
5459        strat->initEcart(&h);
5460        enterT(h,strat);
5461        strat->S_2_R[i] = strat->tl;
5462      }
5463    }
5464  }
5465  else
5466  {
5467    while (suc != -1)
5468    {
5469      i=suc;
5470      while (i<=strat->sl)
5471      {
5472        change=FALSE;
5473        if (((strat->fromQ==NULL) || (strat->fromQ[i]==0)) && (i>0))
5474        {
5475          redSi=pHead((strat->S)[i]);
5476          (strat->S)[i] = redMora((strat->S)[i],i-1,strat);
5477          if ((strat->S)[i]==NULL)
5478          {
5479            deleteInS(i,strat);
5480            i--;
5481          }
5482          else if (pCmp((strat->S)[i],redSi)!=0)
5483          {
5484            any_change=TRUE;
5485            h.p = strat->S[i];
5486            strat->initEcart(&h);
5487            strat->ecartS[i] = h.ecart;
5488            if (TEST_OPT_INTSTRATEGY)
5489            {
5490              if (TEST_OPT_CONTENTSB)
5491                {
5492                  number n;
5493                  p_Cleardenom_n(strat->S[i], currRing, n);// also does a pContent
5494                  if (!nIsOne(n))
5495                    {
5496                      denominator_list denom=(denominator_list)omAlloc(sizeof(denominator_list_s));
5497                      denom->n=nInvers(n);
5498                      denom->next=DENOMINATOR_LIST;
5499                      DENOMINATOR_LIST=denom;
5500                    }
5501                  nDelete(&n);
5502                }
5503              else
5504                {
5505                  //pContent(strat->S[i]);
5506                  strat->S[i]=p_Cleardenom(strat->S[i], currRing);// also does a pContent
5507                }
5508            }
5509            else
5510            {
5511              pNorm(strat->S[i]); // == h.p
5512            }
5513            h.sev =  pGetShortExpVector(h.p);
5514            strat->sevS[i] = h.sev;
5515          }
5516          pLmDelete(&redSi);
5517          kTest(strat);
5518        }
5519        i++;
5520      }
5521#ifdef KDEBUG
5522      kTest(strat);
5523#endif
5524      if (any_change) reorderS(&suc,strat);
5525      else { suc=-1; break; }
5526      if (h.p!=NULL)
5527      {
5528        if (!strat->kHEdgeFound)
5529        {
5530          /*strat->kHEdgeFound =*/ HEckeTest(h.p,strat);
5531        }
5532        if (strat->kHEdgeFound)
5533          newHEdge(strat->S,strat);
5534      }
5535    }
5536    for (i=0; i<=strat->sl; i++)
5537    {
5538      if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
5539      {
5540        strat->S[i] = h.p = redtail(strat->S[i],strat->sl,strat);
5541        strat->initEcart(&h);
5542        strat->ecartS[i] = h.ecart;
5543        h.sev = pGetShortExpVector(h.p);
5544        strat->sevS[i] = h.sev;
5545      }
5546      else
5547      {
5548        h.p = strat->S[i];
5549        h.ecart=strat->ecartS[i];
5550        h.sev = strat->sevS[i];
5551        h.length = h.pLength = pLength(h.p);
5552      }
5553      if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
5554        cancelunit1(&h,&suc,strat->sl,strat);
5555      h.SetpFDeg();
5556      /*puts the elements of S also to T*/
5557      enterT(h,strat);
5558      strat->S_2_R[i] = strat->tl;
5559    }
5560    if (suc!= -1) updateS(toT,strat);
5561  }
5562#ifdef KDEBUG
5563  kTest(strat);
5564#endif
5565}
5566
5567
5568/*2
5569* -puts p to the standardbasis s at position at
5570* -saves the result in S
5571*/
5572void enterSBba (LObject p,int atS,kStrategy strat, int atR)
5573{
5574  int i;
5575  strat->news = TRUE;
5576  /*- puts p to the standardbasis s at position at -*/
5577  if (strat->sl == IDELEMS(strat->Shdl)-1)
5578  {
5579    strat->sevS = (unsigned long*) omRealloc0Size(strat->sevS,
5580                                    IDELEMS(strat->Shdl)*sizeof(unsigned long),
5581                                    (IDELEMS(strat->Shdl)+setmaxTinc)
5582                                                  *sizeof(unsigned long));
5583    strat->ecartS = (intset)omReallocSize(strat->ecartS,
5584                                          IDELEMS(strat->Shdl)*sizeof(int),
5585                                          (IDELEMS(strat->Shdl)+setmaxTinc)
5586                                                  *sizeof(int));
5587    strat->S_2_R = (int*) omRealloc0Size(strat->S_2_R,
5588                                         IDELEMS(strat->Shdl)*sizeof(int),
5589                                         (IDELEMS(strat->Shdl)+setmaxTinc)
5590                                                  *sizeof(int));
5591    if (strat->lenS!=NULL)
5592      strat->lenS=(int*)omRealloc0Size(strat->lenS,
5593                                       IDELEMS(strat->Shdl)*sizeof(int),
5594                                       (IDELEMS(strat->Shdl)+setmaxTinc)
5595                                                 *sizeof(int));
5596    if (strat->lenSw!=NULL)
5597      strat->lenSw=(wlen_type*)omRealloc0Size(strat->lenSw,
5598                                       IDELEMS(strat->Shdl)*sizeof(wlen_type),
5599                                       (IDELEMS(strat->Shdl)+setmaxTinc)
5600                                                 *sizeof(wlen_type));
5601    if (strat->fromQ!=NULL)
5602    {
5603      strat->fromQ = (intset)omReallocSize(strat->fromQ,
5604                                    IDELEMS(strat->Shdl)*sizeof(int),
5605                                    (IDELEMS(strat->Shdl)+setmaxTinc)*sizeof(int));
5606    }
5607    pEnlargeSet(&strat->S,IDELEMS(strat->Shdl),setmaxTinc);
5608    IDELEMS(strat->Shdl)+=setmaxTinc;
5609    strat->Shdl->m=strat->S;
5610  }
5611  if (atS <= strat->sl)
5612  {
5613#ifdef ENTER_USE_MEMMOVE
5614// #if 0
5615    memmove(&(strat->S[atS+1]), &(strat->S[atS]),
5616            (strat->sl - atS + 1)*sizeof(poly));
5617    memmove(&(strat->ecartS[atS+1]), &(strat->ecartS[atS]),
5618            (strat->sl - atS + 1)*sizeof(int));
5619    memmove(&(strat->sevS[atS+1]), &(strat->sevS[atS]),
5620            (strat->sl - atS + 1)*sizeof(unsigned long));
5621    memmove(&(strat->S_2_R[atS+1]), &(strat->S_2_R[atS]),
5622            (strat->sl - atS + 1)*sizeof(int));
5623    if (strat->lenS!=NULL)
5624    memmove(&(strat->lenS[atS+1]), &(strat->lenS[atS]),
5625            (strat->sl - atS + 1)*sizeof(int));
5626    if (strat->lenSw!=NULL)
5627    memmove(&(strat->lenSw[atS+1]), &(strat->lenSw[atS]),
5628            (strat->sl - atS + 1)*sizeof(wlen_type));
5629#else
5630    for (i=strat->sl+1; i>=atS+1; i--)
5631    {
5632      strat->S[i] = strat->S[i-1];
5633      strat->ecartS[i] = strat->ecartS[i-1];
5634      strat->sevS[i] = strat->sevS[i-1];
5635      strat->S_2_R[i] = strat->S_2_R[i-1];
5636    }
5637    if (strat->lenS!=NULL)
5638    for (i=strat->sl+1; i>=atS+1; i--)
5639      strat->lenS[i] = strat->lenS[i-1];
5640    if (strat->lenSw!=NULL)
5641    for (i=strat->sl+1; i>=atS+1; i--)
5642      strat->lenSw[i] = strat->lenSw[i-1];
5643#endif
5644  }
5645  if (strat->fromQ!=NULL)
5646  {
5647#ifdef ENTER_USE_MEMMOVE
5648    memmove(&(strat->fromQ[atS+1]), &(strat->fromQ[atS]),
5649                  (strat->sl - atS + 1)*sizeof(int));
5650#else
5651    for (i=strat->sl+1; i>=atS+1; i--)
5652    {
5653      strat->fromQ[i] = strat->fromQ[i-1];
5654    }
5655#endif
5656    strat->fromQ[atS]=0;
5657  }
5658
5659  /*- save result -*/
5660  strat->S[atS] = p.p;
5661  if (strat->honey) strat->ecartS[atS] = p.ecart;
5662  if (p.sev == 0)
5663    p.sev = pGetShortExpVector(p.p);
5664  else
5665    assume(p.sev == pGetShortExpVector(p.p));
5666  strat->sevS[atS] = p.sev;
5667  strat->ecartS[atS] = p.ecart;
5668  strat->S_2_R[atS] = atR;
5669  strat->sl++;
5670}
5671
5672/*2
5673* puts p to the set T at position atT
5674*/
5675void enterT(LObject p, kStrategy strat, int atT)
5676{
5677  int i;
5678
5679  pp_Test(p.p, currRing, p.tailRing);
5680  assume(strat->tailRing == p.tailRing);
5681  // redMoraNF complains about this -- but, we don't really
5682  // neeed this so far
5683  assume(p.pLength == 0 || pLength(p.p) == p.pLength || rIsSyzIndexRing(currRing)); // modulo syzring
5684  assume(p.FDeg == p.pFDeg());
5685  assume(!p.is_normalized || nIsOne(pGetCoeff(p.p)));
5686
5687#ifdef KDEBUG
5688  // do not put an LObject twice into T:
5689  for(i=strat->tl;i>=0;i--)
5690  {
5691    if (p.p==strat->T[i].p)
5692    {
5693      printf("already in T at pos %d of %d, atT=%d\n",i,strat->tl,atT);
5694      return;
5695    }
5696  }
5697#endif
5698  strat->newt = TRUE;
5699  if (atT < 0)
5700    atT = strat->posInT(strat->T, strat->tl, p);
5701  if (strat->tl == strat->tmax-1)
5702    enlargeT(strat->T,strat->R,strat->sevT,strat->tmax,setmaxTinc);
5703  if (atT <= strat->tl)
5704  {
5705#ifdef ENTER_USE_MEMMOVE
5706    memmove(&(strat->T[atT+1]), &(strat->T[atT]),
5707            (strat->tl-atT+1)*sizeof(TObject));
5708    memmove(&(strat->sevT[atT+1]), &(strat->sevT[atT]),
5709            (strat->tl-atT+1)*sizeof(unsigned long));
5710#endif
5711    for (i=strat->tl+1; i>=atT+1; i--)
5712    {
5713#ifndef ENTER_USE_MEMMOVE
5714      strat->T[i] = strat->T[i-1];
5715      strat->sevT[i] = strat->sevT[i-1];
5716#endif
5717      strat->R[strat->T[i].i_r] = &(strat->T[i]);
5718    }
5719  }
5720
5721  if (strat->tailBin != NULL && (pNext(p.p) != NULL))
5722  {
5723    pNext(p.p)=p_ShallowCopyDelete(pNext(p.p),
5724                                   (strat->tailRing != NULL ?
5725                                    strat->tailRing : currRing),
5726                                   strat->tailBin);
5727    if (p.t_p != NULL) pNext(p.t_p) = pNext(p.p);
5728  }
5729  strat->T[atT] = (TObject) p;
5730
5731  if (strat->tailRing != currRing && pNext(p.p) != NULL)
5732    strat->T[atT].max = p_GetMaxExpP(pNext(p.p), strat->tailRing);
5733  else
5734    strat->T[atT].max = NULL;
5735
5736  strat->tl++;
5737  strat->R[strat->tl] = &(strat->T[atT]);
5738  strat->T[atT].i_r = strat->tl;
5739  assume(p.sev == 0 || pGetShortExpVector(p.p) == p.sev);
5740  strat->sevT[atT] = (p.sev == 0 ? pGetShortExpVector(p.p) : p.sev);
5741  kTest_T(&(strat->T[atT]));
5742}
5743
5744void initHilbCrit(ideal F, ideal Q, intvec **hilb,kStrategy strat)
5745{
5746  if (strat->homog!=isHomog)
5747  {
5748    *hilb=NULL;
5749  }
5750}
5751
5752void initBuchMoraCrit(kStrategy strat)
5753{
5754  strat->enterOnePair=enterOnePairNormal;
5755  strat->chainCrit=chainCritNormal;
5756#ifdef HAVE_RINGS
5757  if (rField_is_Ring(currRing))
5758  {
5759    strat->enterOnePair=enterOnePairRing;
5760    strat->chainCrit=chainCritRing;
5761  }
5762#endif
5763#ifdef HAVE_RATGRING
5764  if (rIsRatGRing(currRing))
5765  {
5766     strat->chainCrit=chainCritPart;
5767     /* enterOnePairNormal get rational part in it */
5768  }
5769#endif
5770
5771  strat->sugarCrit =        TEST_OPT_SUGARCRIT;
5772  strat->Gebauer =          strat->homog || strat->sugarCrit;
5773  strat->honey =            !strat->homog || strat->sugarCrit || TEST_OPT_WEIGHTM;
5774  if (TEST_OPT_NOT_SUGAR) strat->honey = FALSE;
5775  strat->pairtest = NULL;
5776  /* alway use tailreduction, except:
5777  * - in local rings, - in lex order case, -in ring over extensions */
5778  strat->noTailReduction = !TEST_OPT_REDTAIL;
5779
5780#ifdef HAVE_PLURAL
5781  // and r is plural_ring
5782  //  hence this holds for r a rational_plural_ring
5783  if( rIsPluralRing(currRing) || (rIsSCA(currRing) && !strat->z2homog) )
5784  {    //or it has non-quasi-comm type... later
5785    strat->sugarCrit = FALSE;
5786    strat->Gebauer = FALSE;
5787    strat->honey = FALSE;
5788  }
5789#endif
5790
5791#ifdef HAVE_RINGS
5792  // Coefficient ring?
5793  if (rField_is_Ring(currRing))
5794  {
5795    strat->sugarCrit = FALSE;
5796    strat->Gebauer = FALSE ;
5797    strat->honey = FALSE;
5798  }
5799#endif
5800  #ifdef KDEBUG
5801  if (TEST_OPT_DEBUG)
5802  {
5803    if (strat->homog) PrintS("ideal/module is homogeneous\n");
5804    else              PrintS("ideal/module is not homogeneous\n");
5805  }
5806  #endif
5807}
5808
5809BOOLEAN kPosInLDependsOnLength(int (*pos_in_l)
5810                               (const LSet set, const int length,
5811                                LObject* L,const kStrategy strat))
5812{
5813  if (pos_in_l == posInL110 ||
5814      pos_in_l == posInL10)
5815    return TRUE;
5816
5817  return FALSE;
5818}
5819
5820void initBuchMoraPos (kStrategy strat)
5821{
5822  if (pOrdSgn==1)
5823  {
5824    if (strat->honey)
5825    {
5826      strat->posInL = posInL15;
5827      // ok -- here is the deal: from my experiments for Singular-2-0
5828      // I conclude that that posInT_EcartpLength is the best of
5829      // posInT15, posInT_EcartFDegpLength, posInT_FDegLength, posInT_pLength
5830      // see the table at the end of this file
5831      if (TEST_OPT_OLDSTD)
5832        strat->posInT = posInT15;
5833      else
5834        strat->posInT = posInT_EcartpLength;
5835    }
5836    else if (pLexOrder && !TEST_OPT_INTSTRATEGY)
5837    {
5838      strat->posInL = posInL11;
5839      strat->posInT = posInT11;
5840    }
5841    else if (TEST_OPT_INTSTRATEGY)
5842    {
5843      strat->posInL = posInL11;
5844      strat->posInT = posInT11;
5845    }
5846    else
5847    {
5848      strat->posInL = posInL0;
5849      strat->posInT = posInT0;
5850    }
5851    //if (strat->minim>0) strat->posInL =posInLSpecial;
5852    if (strat->homog)
5853    {
5854       strat->posInL = posInL110;
5855       strat->posInT = posInT110;
5856    }
5857  }
5858  else
5859  {
5860    if (strat->homog)
5861    {
5862      strat->posInL = posInL11;
5863      strat->posInT = posInT11;
5864    }
5865    else
5866    {
5867      if ((currRing->order[0]==ringorder_c)
5868      ||(currRing->order[0]==ringorder_C))
5869      {
5870        strat->posInL = posInL17_c;
5871        strat->posInT = posInT17_c;
5872      }
5873      else
5874      {
5875        strat->posInL = posInL17;
5876        strat->posInT = posInT17;
5877      }
5878    }
5879  }
5880  if (strat->minim>0) strat->posInL =posInLSpecial;
5881  // for further tests only
5882  if ((BTEST1(11)) || (BTEST1(12)))
5883    strat->posInL = posInL11;
5884  else if ((BTEST1(13)) || (BTEST1(14)))
5885    strat->posInL = posInL13;
5886  else if ((BTEST1(15)) || (BTEST1(16)))
5887    strat->posInL = posInL15;
5888  else if ((BTEST1(17)) || (BTEST1(18)))
5889    strat->posInL = posInL17;
5890  if (BTEST1(11))
5891    strat->posInT = posInT11;
5892  else if (BTEST1(13))
5893    strat->posInT = posInT13;
5894  else if (BTEST1(15))
5895    strat->posInT = posInT15;
5896  else if ((BTEST1(17)))
5897    strat->posInT = posInT17;
5898  else if ((BTEST1(19)))
5899    strat->posInT = posInT19;
5900  else if (BTEST1(12) || BTEST1(14) || BTEST1(16) || BTEST1(18))
5901    strat->posInT = posInT1;
5902#ifdef HAVE_RINGS
5903  if (rField_is_Ring(currRing))
5904  {
5905    strat->posInL = posInL11;
5906    strat->posInT = posInT11;
5907  }
5908#endif
5909  strat->posInLDependsOnLength = kPosInLDependsOnLength(strat->posInL);
5910}
5911
5912void initBuchMora (ideal F,ideal Q,kStrategy strat)
5913{
5914  strat->interpt = BTEST1(OPT_INTERRUPT);
5915  strat->kHEdge=NULL;
5916  if (pOrdSgn==1) strat->kHEdgeFound=FALSE;
5917  /*- creating temp data structures------------------- -*/
5918  strat->cp = 0;
5919  strat->c3 = 0;
5920  strat->tail = pInit();
5921  /*- set s -*/
5922  strat->sl = -1;
5923  /*- set L -*/
5924  strat->Lmax = ((IDELEMS(F)+setmaxLinc-1)/setmaxLinc)*setmaxLinc;
5925  strat->Ll = -1;
5926  strat->L = initL(((IDELEMS(F)+setmaxLinc-1)/setmaxLinc)*setmaxLinc);
5927  /*- set B -*/
5928  strat->Bmax = setmaxL;
5929  strat->Bl = -1;
5930  strat->B = initL();
5931  /*- set T -*/
5932  strat->tl = -1;
5933  strat->tmax = setmaxT;
5934  strat->T = initT();
5935  strat->R = initR();
5936  strat->sevT = initsevT();
5937  /*- init local data struct.---------------------------------------- -*/
5938  strat->P.ecart=0;
5939  strat->P.length=0;
5940  if (pOrdSgn==-1)
5941  {
5942    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
5943    if (strat->kNoether!=NULL) pSetComp(strat->kNoetherTail(), strat->ak);
5944  }
5945  if(TEST_OPT_SB_1)
5946  {
5947    int i;
5948    ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
5949    for (i=strat->newIdeal;i<IDELEMS(F);i++)
5950    {
5951      P->m[i-strat->newIdeal] = F->m[i];
5952      F->m[i] = NULL;
5953    }
5954    initSSpecial(F,Q,P,strat);
5955    for (i=strat->newIdeal;i<IDELEMS(F);i++)
5956    {
5957      F->m[i] = P->m[i-strat->newIdeal];
5958      P->m[i-strat->newIdeal] = NULL;
5959    }
5960    idDelete(&P);
5961  }
5962  else
5963  {
5964    /*Shdl=*/initSL(F, Q,strat); /*sets also S, ecartS, fromQ */
5965    // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
5966  }
5967  strat->kIdeal = NULL;
5968  strat->fromT = FALSE;
5969  strat->noTailReduction = !TEST_OPT_REDTAIL;
5970  if (!TEST_OPT_SB_1)
5971  {
5972    updateS(TRUE,strat);
5973  }
5974  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
5975  strat->fromQ=NULL;
5976}
5977
5978void exitBuchMora (kStrategy strat)
5979{
5980  /*- release temp data -*/
5981  cleanT(strat);
5982  omFreeSize(strat->T,(strat->tmax)*sizeof(TObject));
5983  omFreeSize(strat->R,(strat->tmax)*sizeof(TObject*));
5984  omFreeSize(strat->sevT, (strat->tmax)*sizeof(unsigned long));
5985  omFreeSize(strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
5986  omFreeSize(strat->sevS,IDELEMS(strat->Shdl)*sizeof(int));
5987  omFreeSize(strat->S_2_R,IDELEMS(strat->Shdl)*sizeof(int));
5988  /*- set L: should be empty -*/
5989  omFreeSize(strat->L,(strat->Lmax)*sizeof(LObject));
5990  /*- set B: should be empty -*/
5991  omFreeSize(strat->B,(strat->Bmax)*sizeof(LObject));
5992  pLmDelete(&strat->tail);
5993  strat->syzComp=0;
5994  if (strat->kIdeal!=NULL)
5995  {
5996    omFreeBin(strat->kIdeal, sleftv_bin);
5997    strat->kIdeal=NULL;
5998  }
5999}
6000
6001/*2
6002* in the case of a standardbase of a module over a qring:
6003* replace polynomials in i by ak vectors,
6004* (the polynomial * unit vectors gen(1)..gen(ak)
6005* in every case (also for ideals:)
6006* deletes divisible vectors/polynomials
6007*/
6008void updateResult(ideal r,ideal Q, kStrategy strat)
6009{
6010  int l;
6011  if (strat->ak>0)
6012  {
6013    for (l=IDELEMS(r)-1;l>=0;l--)
6014    {
6015      if ((r->m[l]!=NULL) && (pGetComp(r->m[l])==0))
6016      {
6017        pDelete(&r->m[l]); // and set it to NULL
6018      }
6019    }
6020    int q;
6021    poly p;
6022    for (l=IDELEMS(r)-1;l>=0;l--)
6023    {
6024      if ((r->m[l]!=NULL)
6025      //&& (strat->syzComp>0)
6026      //&& (pGetComp(r->m[l])<=strat->syzComp)
6027      )
6028      {
6029        for(q=IDELEMS(Q)-1; q>=0;q--)
6030        {
6031          if ((Q->m[q]!=NULL)
6032          &&(pLmDivisibleBy(Q->m[q],r->m[l])))
6033          {
6034            if (TEST_OPT_REDSB)
6035            {
6036              p=r->m[l];
6037              r->m[l]=kNF(Q,NULL,p);
6038              pDelete(&p);
6039            }
6040            else
6041            {
6042              pDelete(&r->m[l]); // and set it to NULL
6043            }
6044            break;
6045          }
6046        }
6047      }
6048    }
6049  }
6050  else
6051  {
6052    int q;
6053    poly p;
6054    BOOLEAN reduction_found=FALSE;
6055    for (l=IDELEMS(r)-1;l>=0;l--)
6056    {
6057      if (r->m[l]!=NULL)
6058      {
6059        for(q=IDELEMS(Q)-1; q>=0;q--)
6060        {
6061          if ((Q->m[q]!=NULL)
6062          &&(pLmEqual(r->m[l],Q->m[q])))
6063          {
6064            if (TEST_OPT_REDSB)
6065            {
6066              p=r->m[l];
6067              r->m[l]=kNF(Q,NULL,p);
6068              pDelete(&p);
6069              reduction_found=TRUE;
6070            }
6071            else
6072            {
6073              pDelete(&r->m[l]); // and set it to NULL
6074            }
6075            break;
6076          }
6077        }
6078      }
6079    }
6080    if (/*TEST_OPT_REDSB &&*/ reduction_found)
6081    {
6082      for (l=IDELEMS(r)-1;l>=0;l--)
6083      {
6084        if (r->m[l]!=NULL)
6085        {
6086          for(q=IDELEMS(r)-1;q>=0;q--)
6087          {
6088            if ((l!=q)
6089            && (r->m[q]!=NULL)
6090            &&(pLmDivisibleBy(r->m[l],r->m[q])))
6091            {
6092              pDelete(&r->m[q]);
6093            }
6094          }
6095        }
6096      }
6097    }
6098  }
6099  idSkipZeroes(r);
6100}
6101
6102void completeReduce (kStrategy strat, BOOLEAN withT)
6103{
6104  int i;
6105  int low = (((pOrdSgn==1) && (strat->ak==0)) ? 1 : 0);
6106  LObject L;
6107
6108#ifdef KDEBUG
6109  // need to set this: during tailreductions of T[i], T[i].max is out of
6110  // sync
6111  sloppy_max = TRUE;
6112#endif
6113
6114  strat->noTailReduction = FALSE;
6115  if (TEST_OPT_PROT)
6116  {
6117    PrintLn();
6118    if (timerv) writeTime("standard base computed:");
6119  }
6120  if (TEST_OPT_PROT)
6121  {
6122    Print("(S:%d)",strat->sl);mflush();
6123  }
6124  for (i=strat->sl; i>=low; i--)
6125  {
6126    int end_pos=strat->sl;
6127    if ((strat->fromQ!=NULL) && (strat->fromQ[i])) continue; // do not reduce Q_i
6128    if (strat->ak==0) end_pos=i-1;
6129    TObject* T_j = strat->s_2_t(i);
6130    if ((T_j != NULL)&&(T_j->p==strat->S[i]))
6131    {
6132      L = *T_j;
6133      #ifdef KDEBUG
6134      if (TEST_OPT_DEBUG)
6135      {
6136        Print("test S[%d]:",i);
6137        p_wrp(L.p,currRing,strat->tailRing);
6138        PrintLn();
6139      }
6140      #endif
6141      poly p;
6142      if (pOrdSgn == 1)
6143        strat->S[i] = redtailBba(&L, end_pos, strat, withT);
6144      else
6145        strat->S[i] = redtail(&L, strat->sl, strat);
6146      #ifdef KDEBUG
6147      if (TEST_OPT_DEBUG)
6148      {
6149        Print("to (tailR) S[%d]:",i);
6150        p_wrp(strat->S[i],currRing,strat->tailRing);
6151        PrintLn();
6152      }
6153      #endif
6154
6155      if (strat->redTailChange && strat->tailRing != currRing)
6156      {
6157        if (T_j->max != NULL) p_LmFree(T_j->max, strat->tailRing);
6158        if (pNext(T_j->p) != NULL)
6159          T_j->max = p_GetMaxExpP(pNext(T_j->p), strat->tailRing);
6160        else
6161          T_j->max = NULL;
6162      }
6163      if (TEST_OPT_INTSTRATEGY)
6164        T_j->pCleardenom();
6165    }
6166    else
6167    {
6168      assume(currRing == strat->tailRing);
6169      #ifdef KDEBUG
6170      if (TEST_OPT_DEBUG)
6171      {
6172        Print("test S[%d]:",i);
6173        p_wrp(strat->S[i],currRing,strat->tailRing);
6174        PrintLn();
6175      }
6176      #endif
6177      if (pOrdSgn == 1)
6178        strat->S[i] = redtailBba(strat->S[i], end_pos, strat, withT);
6179      else
6180        strat->S[i] = redtail(strat->S[i], strat->sl, strat);
6181      if (TEST_OPT_INTSTRATEGY)
6182      {
6183        if (TEST_OPT_CONTENTSB)
6184        {
6185          number n;
6186          p_Cleardenom_n(strat->S[i], currRing, n);// also does a pContent
6187          if (!nIsOne(n))
6188          {
6189            denominator_list denom=(denominator_list)omAlloc(sizeof(denominator_list_s));
6190            denom->n=nInvers(n);
6191            denom->next=DENOMINATOR_LIST;
6192            DENOMINATOR_LIST=denom;
6193          }
6194          nDelete(&n);
6195        }
6196        else
6197        {
6198          //pContent(strat->S[i]);
6199          strat->S[i]=p_Cleardenom(strat->S[i], currRing);// also does a pContent
6200        }
6201      }
6202      #ifdef KDEBUG
6203      if (TEST_OPT_DEBUG)
6204      {
6205        Print("to (-tailR) S[%d]:",i);
6206        p_wrp(strat->S[i],currRing,strat->tailRing);
6207        PrintLn();
6208      }
6209      #endif
6210    }
6211    if (TEST_OPT_PROT)
6212      PrintS("-");
6213  }
6214  if (TEST_OPT_PROT) PrintLn();
6215#ifdef KDEBUG
6216  sloppy_max = FALSE;
6217#endif
6218}
6219
6220
6221/*2
6222* computes the new strat->kHEdge and the new pNoether,
6223* returns TRUE, if pNoether has changed
6224*/
6225BOOLEAN newHEdge(polyset S, kStrategy strat)
6226{
6227  int i,j;
6228  poly newNoether;
6229
6230#if 0
6231  if (currRing->weight_all_1)
6232    scComputeHC(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
6233  else
6234    scComputeHCw(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
6235#else
6236  scComputeHC(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
6237#endif
6238  if (strat->t_kHEdge != NULL) p_LmFree(strat->t_kHEdge, strat->tailRing);
6239  if (strat->tailRing != currRing)
6240    strat->t_kHEdge = k_LmInit_currRing_2_tailRing(strat->kHEdge, strat->tailRing);
6241  /* compare old and new noether*/
6242  newNoether = pLmInit(strat->kHEdge);
6243  j = pFDeg(newNoether,currRing);
6244  for (i=1; i<=pVariables; i++)
6245  {
6246    if (pGetExp(newNoether, i) > 0) pDecrExp(newNoether,i);
6247  }
6248  pSetm(newNoether);
6249  if (j < strat->HCord) /*- statistics -*/
6250  {
6251    if (TEST_OPT_PROT)
6252    {
6253      Print("H(%d)",j);
6254      mflush();
6255    }
6256    strat->HCord=j;
6257    #ifdef KDEBUG
6258    if (TEST_OPT_DEBUG)
6259    {
6260      Print("H(%d):",j);
6261      wrp(strat->kHEdge);
6262      PrintLn();
6263    }
6264    #endif
6265  }
6266  if (pCmp(strat->kNoether,newNoether)!=1)
6267  {
6268    pDelete(&strat->kNoether);
6269    strat->kNoether=newNoether;
6270    if (strat->t_kNoether != NULL) p_LmFree(strat->t_kNoether, strat->tailRing);
6271    if (strat->tailRing != currRing)
6272      strat->t_kNoether = k_LmInit_currRing_2_tailRing(strat->kNoether, strat->tailRing);
6273
6274    return TRUE;
6275  }
6276  pLmFree(newNoether);
6277  return FALSE;
6278}
6279
6280/***************************************************************
6281 *
6282 * Routines related for ring changes during std computations
6283 *
6284 ***************************************************************/
6285BOOLEAN kCheckSpolyCreation(LObject *L, kStrategy strat, poly &m1, poly &m2)
6286{
6287  if (strat->overflow) return FALSE;
6288  assume(L->p1 != NULL && L->p2 != NULL);
6289  // shift changes: from 0 to -1
6290  assume(L->i_r1 >= -1 && L->i_r1 <= strat->tl);
6291  assume(L->i_r2 >= -1 && L->i_r2 <= strat->tl);
6292  assume(strat->tailRing != currRing);
6293
6294  if (! k_GetLeadTerms(L->p1, L->p2, currRing, m1, m2, strat->tailRing))
6295    return FALSE;
6296  // shift changes: extra case inserted
6297  if ((L->i_r1 == -1) || (L->i_r2 == -1) )
6298  {
6299    return TRUE;
6300  }
6301  poly p1_max = (strat->R[L->i_r1])->max;
6302  poly p2_max = (strat->R[L->i_r2])->max;
6303
6304  if ((p1_max != NULL && !p_LmExpVectorAddIsOk(m1, p1_max, strat->tailRing)) ||
6305      (p2_max != NULL && !p_LmExpVectorAddIsOk(m2, p2_max, strat->tailRing)))
6306  {
6307    p_LmFree(m1, strat->tailRing);
6308    p_LmFree(m2, strat->tailRing);
6309    m1 = NULL;
6310    m2 = NULL;
6311    return FALSE;
6312  }
6313  return TRUE;
6314}
6315
6316#ifdef HAVE_RINGS
6317/***************************************************************
6318 *
6319 * Checks, if we can compute the gcd poly / strong pair
6320 * gcd-poly = m1 * R[atR] + m2 * S[atS]
6321 *
6322 ***************************************************************/
6323BOOLEAN kCheckStrongCreation(int atR, poly m1, int atS, poly m2, kStrategy strat)
6324{
6325  assume(strat->S_2_R[atS] >= -1 && strat->S_2_R[atS] <= strat->tl);
6326  //assume(strat->tailRing != currRing);
6327
6328  poly p1_max = (strat->R[atR])->max;
6329  poly p2_max = (strat->R[strat->S_2_R[atS]])->max;
6330
6331  if ((p1_max != NULL && !p_LmExpVectorAddIsOk(m1, p1_max, strat->tailRing)) ||
6332      (p2_max != NULL && !p_LmExpVectorAddIsOk(m2, p2_max, strat->tailRing)))
6333  {
6334    return FALSE;
6335  }
6336  return TRUE;
6337}
6338#endif
6339
6340BOOLEAN kStratChangeTailRing(kStrategy strat, LObject *L, TObject* T, unsigned long expbound)
6341{
6342  assume((strat->tailRing == currRing) || (strat->tailRing->bitmask < currRing->bitmask));
6343  /* initial setup or extending */
6344
6345  if (expbound == 0) expbound = strat->tailRing->bitmask << 1;
6346  if (expbound >= currRing->bitmask) return FALSE;
6347  strat->overflow=FALSE;
6348  ring new_tailRing = rModifyRing(currRing,
6349                                  // Hmmm .. the condition pFDeg == pDeg
6350                                  // might be too strong
6351#ifdef HAVE_RINGS
6352                                  (strat->homog && pFDeg == pDeg && !(rField_is_Ring(currRing))), // TODO Oliver
6353#else
6354                                  (strat->homog && pFDeg == pDeg), // omit_degree
6355#endif
6356                                  (strat->ak==0), // omit_comp if the input is an ideal
6357                                  expbound); // exp_limit
6358
6359  if (new_tailRing == currRing) return TRUE;
6360
6361  strat->pOrigFDeg_TailRing = new_tailRing->pFDeg;
6362  strat->pOrigLDeg_TailRing = new_tailRing->pLDeg;
6363
6364  if (currRing->pFDeg != currRing->pFDegOrig)
6365  {
6366    new_tailRing->pFDeg = currRing->pFDeg;
6367    new_tailRing->pLDeg = currRing->pLDeg;
6368  }
6369
6370  if (TEST_OPT_PROT)
6371    Print("[%lu:%d", (unsigned long) new_tailRing->bitmask, new_tailRing->ExpL_Size);
6372  kTest_TS(strat);
6373  assume(new_tailRing != strat->tailRing);
6374  pShallowCopyDeleteProc p_shallow_copy_delete
6375    = pGetShallowCopyDeleteProc(strat->tailRing, new_tailRing);
6376
6377  omBin new_tailBin = omGetStickyBinOfBin(new_tailRing->PolyBin);
6378
6379  int i;
6380  for (i=0; i<=strat->tl; i++)
6381  {
6382    strat->T[i].ShallowCopyDelete(new_tailRing, new_tailBin,
6383                                  p_shallow_copy_delete);
6384  }
6385  for (i=0; i<=strat->Ll; i++)
6386  {
6387    assume(strat->L[i].p != NULL);
6388    if (pNext(strat->L[i].p) != strat->tail)
6389      strat->L[i].ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
6390  }
6391  if (strat->P.t_p != NULL ||
6392      (strat->P.p != NULL && pNext(strat->P.p) != strat->tail))
6393    strat->P.ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
6394
6395  if (L != NULL && L->tailRing != new_tailRing)
6396  {
6397    if (L->i_r < 0)
6398      L->ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
6399    else
6400    {
6401      assume(L->i_r <= strat->tl);
6402      TObject* t_l = strat->R[L->i_r];
6403      assume(t_l != NULL);
6404      L->tailRing = new_tailRing;
6405      L->p = t_l->p;
6406      L->t_p = t_l->t_p;
6407      L->max = t_l->max;
6408    }
6409  }
6410
6411  if (T != NULL && T->tailRing != new_tailRing && T->i_r < 0)
6412    T->ShallowCopyDelete(new_tailRing, new_tailBin, p_shallow_copy_delete);
6413
6414  omMergeStickyBinIntoBin(strat->tailBin, strat->tailRing->PolyBin);
6415  if (strat->tailRing != currRing)
6416    rKillModifiedRing(strat->tailRing);
6417
6418  strat->tailRing = new_tailRing;
6419  strat->tailBin = new_tailBin;
6420  strat->p_shallow_copy_delete
6421    = pGetShallowCopyDeleteProc(currRing, new_tailRing);
6422
6423  if (strat->kHEdge != NULL)
6424  {
6425    if (strat->t_kHEdge != NULL)
6426      p_LmFree(strat->t_kHEdge, strat->tailRing);
6427    strat->t_kHEdge=k_LmInit_currRing_2_tailRing(strat->kHEdge, new_tailRing);
6428  }
6429
6430  if (strat->kNoether != NULL)
6431  {
6432    if (strat->t_kNoether != NULL)
6433      p_LmFree(strat->t_kNoether, strat->tailRing);
6434    strat->t_kNoether=k_LmInit_currRing_2_tailRing(strat->kNoether,
6435                                                   new_tailRing);
6436  }
6437  kTest_TS(strat);
6438  if (TEST_OPT_PROT)
6439    PrintS("]");
6440  return TRUE;
6441}
6442
6443void kStratInitChangeTailRing(kStrategy strat)
6444{
6445  unsigned long l = 0;
6446  int i;
6447  long e;
6448
6449  assume(strat->tailRing == currRing);
6450
6451  for (i=0; i<= strat->Ll; i++)
6452  {
6453    l = p_GetMaxExpL(strat->L[i].p, currRing, l);
6454  }
6455  for (i=0; i<=strat->tl; i++)
6456  {
6457    // Hmm ... this we could do in one Step
6458    l = p_GetMaxExpL(strat->T[i].p, currRing, l);
6459  }
6460  if (rField_is_Ring(currRing))
6461  {
6462    l *= 2;
6463  }
6464  e = p_GetMaxExp(l, currRing);
6465  if (e <= 1) e = 2;
6466
6467  kStratChangeTailRing(strat, NULL, NULL, e);
6468}
6469
6470skStrategy::skStrategy()
6471{
6472  memset(this, 0, sizeof(skStrategy));
6473#ifndef NDEBUG
6474  strat_nr++;
6475  nr=strat_nr;
6476  if (strat_fac_debug) Print("s(%d) created\n",nr);
6477#endif
6478  tailRing = currRing;
6479  P.tailRing = currRing;
6480  tl = -1;
6481  sl = -1;
6482#ifdef HAVE_LM_BIN
6483  lmBin = omGetStickyBinOfBin(currRing->PolyBin);
6484#endif
6485#ifdef HAVE_TAIL_BIN
6486  tailBin = omGetStickyBinOfBin(currRing->PolyBin);
6487#endif
6488  pOrigFDeg = pFDeg;
6489  pOrigLDeg = pLDeg;
6490}
6491
6492
6493skStrategy::~skStrategy()
6494{
6495  if (lmBin != NULL)
6496    omMergeStickyBinIntoBin(lmBin, currRing->PolyBin);
6497  if (tailBin != NULL)
6498    omMergeStickyBinIntoBin(tailBin,
6499                            (tailRing != NULL ? tailRing->PolyBin:
6500                             currRing->PolyBin));
6501  if (t_kHEdge != NULL)
6502    p_LmFree(t_kHEdge, tailRing);
6503  if (t_kNoether != NULL)
6504    p_LmFree(t_kNoether, tailRing);
6505
6506  if (currRing != tailRing)
6507    rKillModifiedRing(tailRing);
6508  pRestoreDegProcs(pOrigFDeg, pOrigLDeg);
6509}
6510
6511#if 0
6512Timings for the different possibilities of posInT:
6513            T15           EDL         DL          EL            L         1-2-3
6514Gonnet      43.26       42.30       38.34       41.98       38.40      100.04
6515Hairer_2_1   1.11        1.15        1.04        1.22        1.08        4.7
6516Twomat3      1.62        1.69        1.70        1.65        1.54       11.32
6517ahml         4.48        4.03        4.03        4.38        4.96       26.50
6518c7          15.02       13.98       15.16       13.24       17.31       47.89
6519c8         505.09      407.46      852.76      413.21      499.19        n/a
6520f855        12.65        9.27       14.97        8.78       14.23       33.12
6521gametwo6    11.47       11.35       14.57       11.20       12.02       35.07
6522gerhard_3    2.73        2.83        2.93        2.64        3.12        6.24
6523ilias13     22.89       22.46       24.62       20.60       23.34       53.86
6524noon8       40.68       37.02       37.99       36.82       35.59      877.16
6525rcyclic_19  48.22       42.29       43.99       45.35       51.51      204.29
6526rkat9       82.37       79.46       77.20       77.63       82.54      267.92
6527schwarz_11  16.46       16.81       16.76       16.81       16.72       35.56
6528test016     16.39       14.17       14.40       13.50       14.26       34.07
6529test017     34.70       36.01       33.16       35.48       32.75       71.45
6530test042     10.76       10.99       10.27       11.57       10.45       23.04
6531test058      6.78        6.75        6.51        6.95        6.22        9.47
6532test066     10.71       10.94       10.76       10.61       10.56       19.06
6533test073     10.75       11.11       10.17       10.79        8.63       58.10
6534test086     12.23       11.81       12.88       12.24       13.37       66.68
6535test103      5.05        4.80        5.47        4.64        4.89       11.90
6536test154     12.96       11.64       13.51       12.46       14.61       36.35
6537test162     65.27       64.01       67.35       59.79       67.54      196.46
6538test164      7.50        6.50        7.68        6.70        7.96       17.13
6539virasoro     3.39        3.50        3.35        3.47        3.70        7.66
6540#endif
6541
6542
6543//#ifdef HAVE_MORE_POS_IN_T
6544#if 1
6545// determines the position based on: 1.) Ecart 2.) FDeg 3.) pLength
6546int posInT_EcartFDegpLength(const TSet set,const int length,LObject &p)
6547{
6548
6549  if (length==-1) return 0;
6550
6551  int o = p.ecart;
6552  int op=p.GetpFDeg();
6553  int ol = p.GetpLength();
6554
6555  if (set[length].ecart < o)
6556    return length+1;
6557  if (set[length].ecart == o)
6558  {
6559     int oo=set[length].GetpFDeg();
6560     if ((oo < op) || ((oo==op) && (set[length].length < ol)))
6561       return length+1;
6562  }
6563
6564  int i;
6565  int an = 0;
6566  int en= length;
6567  loop
6568  {
6569    if (an >= en-1)
6570    {
6571      if (set[an].ecart > o)
6572        return an;
6573      if (set[an].ecart == o)
6574      {
6575         int oo=set[an].GetpFDeg();
6576         if((oo > op)
6577         || ((oo==op) && (set[an].pLength > ol)))
6578           return an;
6579      }
6580      return en;
6581    }
6582    i=(an+en) / 2;
6583    if (set[i].ecart > o)
6584      en=i;
6585    else if (set[i].ecart == o)
6586    {
6587       int oo=set[i].GetpFDeg();
6588       if ((oo > op)
6589       || ((oo == op) && (set[i].pLength > ol)))
6590         en=i;
6591       else
6592        an=i;
6593    }
6594    else
6595      an=i;
6596  }
6597}
6598
6599// determines the position based on: 1.) FDeg 2.) pLength
6600int posInT_FDegpLength(const TSet set,const int length,LObject &p)
6601{
6602
6603  if (length==-1) return 0;
6604
6605  int op=p.GetpFDeg();
6606  int ol = p.GetpLength();
6607
6608  int oo=set[length].GetpFDeg();
6609  if ((oo < op) || ((oo==op) && (set[length].length < ol)))
6610    return length+1;
6611
6612  int i;
6613  int an = 0;
6614  int en= length;
6615  loop
6616    {
6617      if (an >= en-1)
6618      {
6619        int oo=set[an].GetpFDeg();
6620        if((oo > op)
6621           || ((oo==op) && (set[an].pLength > ol)))
6622          return an;
6623        return en;
6624      }
6625      i=(an+en) / 2;
6626      int oo=set[i].GetpFDeg();
6627      if ((oo > op)
6628          || ((oo == op) && (set[i].pLength > ol)))
6629        en=i;
6630      else
6631        an=i;
6632    }
6633}
6634
6635
6636// determines the position based on: 1.) pLength
6637int posInT_pLength(const TSet set,const int length,LObject &p)
6638{
6639  int ol = p.GetpLength();
6640  if (length==-1)
6641    return 0;
6642  if (set[length].length<p.length)
6643    return length+1;
6644
6645  int i;
6646  int an = 0;
6647  int en= length;
6648
6649  loop
6650  {
6651    if (an >= en-1)
6652    {
6653      if (set[an].pLength>ol) return an;
6654      return en;
6655    }
6656    i=(an+en) / 2;
6657    if (set[i].pLength>ol) en=i;
6658    else                        an=i;
6659  }
6660}
6661#endif
6662
6663// kstd1.cc:
6664int redFirst (LObject* h,kStrategy strat);
6665int redEcart (LObject* h,kStrategy strat);
6666void enterSMora (LObject p,int atS,kStrategy strat, int atR=-1);
6667void enterSMoraNF (LObject p,int atS,kStrategy strat, int atR=-1);
6668// ../Singular/misc.cc:
6669char *  showOption();
6670
6671void kDebugPrint(kStrategy strat)
6672{
6673  PrintS("red: ");
6674    if (strat->red==redFirst) PrintS("redFirst\n");
6675    else if (strat->red==redHoney) PrintS("redHoney\n");
6676    else if (strat->red==redEcart) PrintS("redEcart\n");
6677    else if (strat->red==redHomog) PrintS("redHomog\n");
6678    else  Print("%p\n",(void*)strat->red);
6679  PrintS("posInT: ");
6680    if (strat->posInT==posInT0) PrintS("posInT0\n");
6681    else if (strat->posInT==posInT0) PrintS("posInT0\n");
6682    else if (strat->posInT==posInT1) PrintS("posInT1\n");
6683    else if (strat->posInT==posInT11) PrintS("posInT11\n");
6684    else if (strat->posInT==posInT110) PrintS("posInT110\n");
6685    else if (strat->posInT==posInT13) PrintS("posInT13\n");
6686    else if (strat->posInT==posInT15) PrintS("posInT15\n");
6687    else if (strat->posInT==posInT17) PrintS("posInT17\n");
6688    else if (strat->posInT==posInT17_c) PrintS("posInT17_c\n");
6689    else if (strat->posInT==posInT19) PrintS("posInT19\n");
6690    else if (strat->posInT==posInT2) PrintS("posInT2\n");
6691#ifdef HAVE_MORE_POS_IN_T
6692    else if (strat->posInT==posInT_EcartFDegpLength) PrintS("posInT_EcartFDegpLength\n");
6693    else if (strat->posInT==posInT_FDegpLength) PrintS("posInT_FDegpLength\n");
6694    else if (strat->posInT==posInT_pLength) PrintS("posInT_pLength\n");
6695#endif
6696    else if (strat->posInT==posInT_EcartpLength) PrintS("posInT_EcartpLength\n");
6697    else if (strat->posInT==posInTrg0) PrintS("posInTrg0\n");
6698    else  Print("%p\n",(void*)strat->posInT);
6699  PrintS("posInL: ");
6700    if (strat->posInL==posInL0) PrintS("posInL0\n");
6701    else if (strat->posInL==posInL10) PrintS("posInL10\n");
6702    else if (strat->posInL==posInL11) PrintS("posInL11\n");
6703    else if (strat->posInL==posInL110) PrintS("posInL110\n");
6704    else if (strat->posInL==posInL13) PrintS("posInL13\n");
6705    else if (strat->posInL==posInL15) PrintS("posInL15\n");
6706    else if (strat->posInL==posInL17) PrintS("posInL17\n");
6707    else if (strat->posInL==posInL17_c) PrintS("posInL17_c\n");
6708    else if (strat->posInL==posInLSpecial) PrintS("posInLSpecial\n");
6709    else if (strat->posInL==posInLrg0) PrintS("posInLrg0\n");
6710    else  Print("%p\n",(void*)strat->posInL);
6711  PrintS("enterS: ");
6712    if (strat->enterS==enterSBba) PrintS("enterSBba\n");
6713    else if (strat->enterS==enterSMora) PrintS("enterSMora\n");
6714    else if (strat->enterS==enterSMoraNF) PrintS("enterSMoraNF\n");
6715    else  Print("%p\n",(void*)strat->enterS);
6716  PrintS("initEcart: ");
6717    if (strat->initEcart==initEcartBBA) PrintS("initEcartBBA\n");
6718    else if (strat->initEcart==initEcartNormal) PrintS("initEcartNormal\n");
6719    else  Print("%p\n",(void*)strat->initEcart);
6720  PrintS("initEcartPair: ");
6721    if (strat->initEcartPair==initEcartPairBba) PrintS("initEcartPairBba\n");
6722    else if (strat->initEcartPair==initEcartPairMora) PrintS("initEcartPairMora\n");
6723    else  Print("%p\n",(void*)strat->initEcartPair);
6724  Print("homog=%d, LazyDegree=%d, LazyPass=%d, ak=%d,\n",
6725         strat->homog, strat->LazyDegree,strat->LazyPass, strat->ak);
6726  Print("honey=%d, sugarCrit=%d, Gebauer=%d, noTailReduction=%d\n",
6727         strat->honey,strat->sugarCrit,strat->Gebauer,strat->noTailReduction,strat->use_buckets);
6728  Print("posInLDependsOnLength=%d, use_buckets=%d\n",
6729         strat->posInLDependsOnLength,strat->use_buckets);
6730  PrintS(showOption());PrintLn();
6731  PrintS("LDeg: ");
6732    if (currRing->pLDeg==pLDeg0) PrintS("pLDeg0");
6733    else if (currRing->pLDeg==pLDeg0c) PrintS("pLDeg0c");
6734    else if (currRing->pLDeg==pLDegb) PrintS("pLDegb");
6735    else if (currRing->pLDeg==pLDeg1) PrintS("pLDeg1");
6736    else if (currRing->pLDeg==pLDeg1c) PrintS("pLDeg1c");
6737    else if (currRing->pLDeg==pLDeg1_Deg) PrintS("pLDeg1_Deg");
6738    else if (currRing->pLDeg==pLDeg1c_Deg) PrintS("pLDeg1c_Deg");
6739    else if (currRing->pLDeg==pLDeg1_Totaldegree) PrintS("pLDeg1_Totaldegree");
6740    else if (currRing->pLDeg==pLDeg1c_Totaldegree) PrintS("pLDeg1c_Totaldegree");
6741    else if (currRing->pLDeg==pLDeg1_WFirstTotalDegree) PrintS("pLDeg1_WFirstTotalDegree");
6742    else if (currRing->pLDeg==pLDeg1c_WFirstTotalDegree) PrintS("pLDeg1c_WFirstTotalDegree");
6743    else Print("? (%lx)", (long)currRing->pLDeg);
6744    PrintS(" / ");
6745    if (strat->tailRing->pLDeg==pLDeg0) PrintS("pLDeg0");
6746    else if (strat->tailRing->pLDeg==pLDeg0c) PrintS("pLDeg0c");
6747    else if (strat->tailRing->pLDeg==pLDegb) PrintS("pLDegb");
6748    else if (strat->tailRing->pLDeg==pLDeg1) PrintS("pLDeg1");
6749    else if (strat->tailRing->pLDeg==pLDeg1c) PrintS("pLDeg1c");
6750    else if (strat->tailRing->pLDeg==pLDeg1_Deg) PrintS("pLDeg1_Deg");
6751    else if (strat->tailRing->pLDeg==pLDeg1c_Deg) PrintS("pLDeg1c_Deg");
6752    else if (strat->tailRing->pLDeg==pLDeg1_Totaldegree) PrintS("pLDeg1_Totaldegree");
6753    else if (strat->tailRing->pLDeg==pLDeg1c_Totaldegree) PrintS("pLDeg1c_Totaldegree");
6754    else if (strat->tailRing->pLDeg==pLDeg1_WFirstTotalDegree) PrintS("pLDeg1_WFirstTotalDegree");
6755    else if (strat->tailRing->pLDeg==pLDeg1c_WFirstTotalDegree) PrintS("pLDeg1c_WFirstTotalDegree");
6756    else Print("? (%lx)", (long)strat->tailRing->pLDeg);
6757    Print(" syzring:%d, syzComp(strat):%d syzComb(ring)\n",rIsSyzIndexRing(currRing),strat->syzComp,rGetCurrSyzLimit());
6758    if(TEST_OPT_DEGBOUND)
6759      Print(" degBound: %d\n", Kstd1_deg);
6760
6761}
6762
6763
6764#ifdef HAVE_SHIFTBBA
6765poly pMove2CurrTail(poly p, kStrategy strat)
6766{
6767  /* assume: p is completely in currRing */
6768  /* produces an object with LM in curring
6769     and TAIL in tailring */
6770  if (pNext(p)!=NULL)
6771  {
6772    pNext(p) = prMoveR(pNext(p), /* src */ currRing, /* dest */ strat->tailRing);
6773  }
6774  return(p);
6775}
6776#endif
6777
6778#ifdef HAVE_SHIFTBBA
6779poly pMoveCurrTail2poly(poly p, kStrategy strat)
6780{
6781  /* assume: p has  LM in curring and TAIL in tailring */
6782  /* convert it to complete currRing */
6783
6784  /* check that LM is in currRing */
6785  assume(p_LmCheckIsFromRing(p, currRing));
6786
6787  if (pNext(p)!=NULL)
6788  {
6789    pNext(p) = prMoveR(pNext(p), /* src */ strat->tailRing, /* dest */currRing);
6790  }
6791  return(p);
6792}
6793#endif
6794
6795#ifdef HAVE_SHIFTBBA
6796poly pCopyL2p(LObject H, kStrategy strat)
6797{
6798    /* restores a poly in currRing from LObject */
6799    LObject h = H;
6800    h.Copy();
6801    poly p;
6802    if (h.p == NULL)
6803    {
6804      if (h.t_p != NULL)
6805      {
6806         p = prMoveR(h.t_p, /* source ring: */ strat->tailRing, /* dest. ring: */ currRing);
6807        return(p);
6808      }
6809      else
6810      {
6811        /* h.tp == NULL -> the object is NULL */
6812        return(NULL);
6813      }
6814    }
6815    /* we're here if h.p != NULL */
6816    if (h.t_p == NULL)
6817    {
6818       /* then h.p is the whole poly in currRing */
6819       p = h.p;
6820      return(p);
6821    }
6822    /* we're here if h.p != NULL and h.t_p != NULL */
6823    // clean h.p, get poly from t_p
6824     pNext(h.p)=NULL;
6825     pDelete(&h.p);
6826     p = prMoveR(h.t_p, /* source ring: */ strat->tailRing,
6827                         /* dest. ring: */ currRing);
6828     // no need to clean h: we re-used the polys
6829    return(p);
6830}
6831#endif
6832
6833//LObject pCopyp2L(poly p, kStrategy strat)
6834//{
6835    /* creates LObject from the poly in currRing */
6836  /* actually put p into L.p and make L.t_p=NULL : does not work */
6837
6838//}
6839
6840// poly pCopyL2p(LObject H, kStrategy strat)
6841// {
6842//   /* restores a poly in currRing from LObject */
6843//   LObject h = H;
6844//   h.Copy();
6845//   poly p;
6846//   if (h.p == NULL)
6847//   {
6848//     if (h.t_p != NULL)
6849//     {
6850//       p = p_ShallowCopyDelete(h.t_p, (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
6851//       return(p);
6852//     }
6853//     else
6854//     {
6855//       /* h.tp == NULL -> the object is NULL */
6856//       return(NULL);
6857//     }
6858//   }
6859//   /* we're here if h.p != NULL */
6860
6861//   if (h.t_p == NULL)
6862//   {
6863//     /* then h.p is the whole poly in tailRing */
6864//     if (strat->tailBin != NULL && (pNext(h.p) != NULL))
6865//     {
6866//       p = p_ShallowCopyDelete(h.p, (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
6867//     }
6868//     return(p);
6869//   }
6870//   /* we're here if h.p != NULL and h.t_p != NULL */
6871//   p = pCopy(pHead(h.p)); // in currRing
6872//   if (strat->tailBin != NULL && (pNext(h.p) != NULL))
6873//   {
6874//     //    pNext(p) = p_ShallowCopyDelete(pNext(h.t_p), (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
6875//     poly pp = p_Copy(pNext(h.p), strat->tailRing);
6876//     //    poly p3 = p_Copy(pNext(h.p), currRing); // error
6877//       // p_ShallowCopyDelete(pNext(h.p), currRing, strat->tailBin); // the same as pp
6878//     poly p5 = p_ShallowCopyDelete(pNext(h.p), strat->tailRing, strat->tailBin);
6879//     pNext(p) = p_ShallowCopyDelete(h.t_p, strat->tailRing, strat->tailBin);
6880//     poly p4 = p_Copy(h.t_p, strat->tailRing);
6881//     //    if (p.t_p != NULL) pNext(p.t_p) = pNext(p.p);
6882//   }
6883//   //  pTest(p);
6884//   return(p);
6885// }
6886
6887#ifdef HAVE_SHIFTBBA
6888/* including the self pairs */
6889void updateSShift(kStrategy strat,int uptodeg,int lV)
6890{
6891  /* to use after updateS(toT=FALSE,strat) */
6892  /* fills T with shifted elt's of S */
6893  int i;
6894  LObject h;
6895  int atT = -1; // or figure out smth better
6896  strat->tl = -1; // init
6897  for (i=0; i<=strat->sl; i++)
6898  {
6899    memset(&h,0,sizeof(h));
6900    h.p =  strat->S[i]; // lm in currRing, tail in TR
6901    strat->initEcart(&h);
6902    h.sev = strat->sevS[i];
6903    h.t_p = NULL;
6904    h.GetTP(); // creates correct t_p
6905    /*puts the elements of S with their shifts to T*/
6906    //    int atT, int uptodeg, int lV)
6907    strat->S_2_R[i] = strat->tl + 1; // the el't with shift 0 will be inserted first
6908    // need a small check for above; we insert >=1 elements
6909    // insert this check into kTest_TS ?
6910    enterTShift(h,strat,atT,uptodeg,lV);
6911  }
6912  /* what about setting strat->tl? */
6913}
6914#endif
6915
6916#ifdef HAVE_SHIFTBBA
6917void initBuchMoraShift (ideal F,ideal Q,kStrategy strat)
6918{
6919  strat->interpt = BTEST1(OPT_INTERRUPT);
6920  strat->kHEdge=NULL;
6921  if (pOrdSgn==1) strat->kHEdgeFound=FALSE;
6922  /*- creating temp data structures------------------- -*/
6923  strat->cp = 0;
6924  strat->c3 = 0;
6925  strat->cv = 0;
6926  strat->tail = pInit();
6927  /*- set s -*/
6928  strat->sl = -1;
6929  /*- set L -*/
6930  strat->Lmax = setmaxL;
6931  strat->Ll = -1;
6932  strat->L = initL();
6933  /*- set B -*/
6934  strat->Bmax = setmaxL;
6935  strat->Bl = -1;
6936  strat->B = initL();
6937  /*- set T -*/
6938  strat->tl = -1;
6939  strat->tmax = setmaxT;
6940  strat->T = initT();
6941  strat->R = initR();
6942  strat->sevT = initsevT();
6943  /*- init local data struct.---------------------------------------- -*/
6944  strat->P.ecart=0;
6945  strat->P.length=0;
6946  if (pOrdSgn==-1)
6947  {
6948    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
6949    if (strat->kNoether!=NULL) pSetComp(strat->kNoetherTail(), strat->ak);
6950  }
6951  if(TEST_OPT_SB_1)
6952  {
6953    int i;
6954    ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
6955    for (i=strat->newIdeal;i<IDELEMS(F);i++)
6956    {
6957      P->m[i-strat->newIdeal] = F->m[i];
6958      F->m[i] = NULL;
6959    }
6960    initSSpecial(F,Q,P,strat);
6961    for (i=strat->newIdeal;i<IDELEMS(F);i++)
6962    {
6963      F->m[i] = P->m[i-strat->newIdeal];
6964      P->m[i-strat->newIdeal] = NULL;
6965    }
6966    idDelete(&P);
6967  }
6968  else
6969  {
6970    /*Shdl=*/initSL(F, Q,strat); /*sets also S, ecartS, fromQ */
6971    // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
6972  }
6973  strat->kIdeal = NULL;
6974  strat->fromT = FALSE;
6975  strat->noTailReduction = !TEST_OPT_REDTAIL;
6976  if (!TEST_OPT_SB_1)
6977  {
6978    /* the only change: we do not fill the set T*/
6979    updateS(FALSE,strat);
6980  }
6981  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
6982  strat->fromQ=NULL;
6983  /* more changes: fill the set T with all the shifts of elts of S*/
6984  /* is done by other procedure */
6985}
6986#endif
6987
6988#ifdef HAVE_SHIFTBBA
6989/*1
6990* put the pairs (sh \dot s[i],p)  into the set B, ecart=ecart(p)
6991*/
6992void enterOnePairManyShifts (int i, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int uptodeg, int lV)
6993{
6994  /* p comes from strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
6995
6996  assume(p_LmCheckIsFromRing(p,currRing));
6997  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
6998
6999  /* cycles through all shifts of s[i] until uptodeg - lastVblock(s[i]) */
7000  /* that is create the pairs (f, s \dot g)  */
7001
7002  poly qq = strat->S[i]; //  lm in currRing, tail in tailRing
7003
7004  //  poly q = pCopy(pHead(strat->S[i])); // lm in currRing
7005  //  pNext(q) = prCopyR(pNext(strat->S[i]),strat->tailRing,currRing); // zero shift
7006
7007 /* determine how many elements we have to insert for a given s[i] */
7008  /* x(0)y(1)z(2) : lastVblock-1=2, to add until lastVblock=uptodeg-1 */
7009  /* hence, a total number of elt's to add is: */
7010  /*  int toInsert = 1 + (uptodeg-1) - (pLastVblock(p.p, lV) -1);  */
7011  int toInsert =  itoInsert(qq, uptodeg,  lV, strat->tailRing);
7012
7013#ifdef KDEBUG
7014    if (TEST_OPT_DEBUG)
7015    {
7016      //      Print("entered ManyShifts: with toInsert=%d",toInsert); PrintLn();
7017    }
7018#endif
7019
7020  assume(i<=strat->sl); // from OnePair
7021  if (strat->interred_flag) return; // ?
7022
7023  /* these vars hold for all shifts of s[i] */
7024  int ecartq = 0; //Hans says it's ok; we're in the homog case, no ecart
7025
7026  int qfromQ;
7027  if (strat->fromQ != NULL)
7028  {
7029    qfromQ = strat->fromQ[i];
7030  }
7031  else
7032  {
7033    qfromQ = -1;
7034  }
7035
7036  int j;
7037
7038  poly q, s;
7039
7040  // for the 0th shift: insert the orig. pair
7041  enterOnePairShift(qq, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, 0, i, uptodeg, lV);
7042
7043  for (j=1; j<= toInsert; j++)
7044  {
7045    //    q = pLPshift(strat->S[i],j,uptodeg,lV);
7046    q = p_LPshiftT(qq, j, uptodeg, lV, strat, currRing);
7047    //    q = p_mLPshift(qq,j,uptodeg,lV,currRing); // lm in currRing, shift this monomial
7048    //    s = p_LPshift(pNext(qq), j, uptodeg, lV, strat->tailRing); // from tailRing
7049    //    pNext(q) = s; // in tailRing
7050    /* here we need to call enterOnePair with two polys ... */
7051
7052#ifdef KDEBUG
7053    if (TEST_OPT_DEBUG)
7054    {
7055      //      PrintS("ManyShifts: calling enterOnePairShift(q,p)");      PrintLn();
7056    }
7057#endif
7058    enterOnePairShift(q, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, j, i, uptodeg, lV);
7059  }
7060}
7061#endif
7062
7063#ifdef HAVE_SHIFTBBA
7064/*1
7065* put the pairs (sh \dot qq,p)  into the set B, ecart=ecart(p)
7066* despite the name, not only self shifts
7067*/
7068void enterOnePairSelfShifts (poly qq, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int uptodeg, int lV)
7069{
7070
7071  /* format: p,qq are in LObject form: lm in CR, tail in TR */
7072  /* for true self pairs qq ==p  */
7073  /* we test both qq and p */
7074  assume(p_LmCheckIsFromRing(qq,currRing));
7075  assume(p_CheckIsFromRing(pNext(qq),strat->tailRing));
7076  assume(p_LmCheckIsFromRing(p,currRing));
7077  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
7078
7079  /* since this proc is applied twice for (h, s*g) and (g,s*h), init j with 1 only */
7080
7081  //  int j = 0;
7082  int j = 1;
7083
7084  /* for such self pairs start with 1, not with 0 */
7085  if (qq == p) j=1;
7086
7087  /* should cycle through all shifts of q until uptodeg - lastVblock(q) */
7088  /* that is create the pairs (f, s \dot g)  */
7089
7090  int toInsert =  itoInsert(qq, uptodeg,  lV, strat->tailRing);
7091
7092#ifdef KDEBUG
7093    if (TEST_OPT_DEBUG)
7094    {
7095      //      Print("entered SelfShifts: with toInsert=%d",toInsert); PrintLn();
7096    }
7097#endif
7098
7099  poly q, s;
7100
7101  if (strat->interred_flag) return; // ?
7102
7103  /* these vars hold for all shifts of s[i] */
7104  int ecartq = 0; //Hans says it's ok; we're in the homog case, no ecart
7105  int qfromQ = 0; // strat->fromQ[i];
7106
7107  for (; j<= toInsert; j++)
7108  {
7109    //    q = pLPshift(strat->S[i],j,uptodeg,lV);
7110    /* we increase shifts by one; must delete q there*/
7111    //    q = qq; q = pMoveCurrTail2poly(q,strat);
7112    //    q = pLPshift(q,j,uptodeg,lV); //,currRing);
7113    q = p_LPshiftT(qq, j, uptodeg, lV, strat, currRing);
7114    //    q = p_mLPshift(qq,j,uptodeg,lV,currRing); // lm in currRing, shift this monomial
7115    //    s = p_LPshift(pNext(qq), j, uptodeg, lV, strat->tailRing); // from tailRing
7116    //    pNext(q) = s; // in tailRing
7117    /* here we need to call enterOnePair with two polys ... */
7118#ifdef KDEBUG
7119    if (TEST_OPT_DEBUG)
7120    {
7121      //      PrintS("SelfShifts: calling enterOnePairShift(q,p)");      PrintLn();
7122    }
7123#endif
7124    enterOnePairShift(q, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, j, -1, uptodeg, lV);
7125  }
7126}
7127#endif
7128
7129#ifdef HAVE_SHIFTBBA
7130/*2
7131* put the pair (q,p)  into the set B, ecart=ecart(p), q is the shift of some s[i]
7132*/
7133void enterOnePairShift (poly q, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int ecartq, int qisFromQ, int shiftcount, int ifromS, int uptodeg, int lV)
7134{
7135
7136  /* Format: q and p are like strat->P.p, so lm in CR, tail in TR */
7137
7138  /* check this Formats: */
7139  assume(p_LmCheckIsFromRing(q,currRing));
7140  assume(p_CheckIsFromRing(pNext(q),strat->tailRing));
7141  assume(p_LmCheckIsFromRing(p,currRing));
7142  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
7143
7144#ifdef KDEBUG
7145    if (TEST_OPT_DEBUG)
7146    {
7147//       PrintS("enterOnePairShift(q,p) invoked with q = ");
7148//       wrp(q); //      wrp(pHead(q));
7149//       PrintS(", p = ");
7150//       wrp(p); //wrp(pHead(p));
7151//       PrintLn();
7152    }
7153#endif
7154
7155  /* poly q stays for s[i], ecartq = ecart(q), qisFromQ = applies to q */
7156
7157  int qfromQ = qisFromQ;
7158
7159  /* need additionally: int up_to_degree, poly V0 with the variables in (0)  or just the number lV = the length of the first block */
7160
7161  if (strat->interred_flag) return;
7162
7163  int      l,j,compare;
7164  LObject  Lp;
7165  Lp.i_r = -1;
7166
7167#ifdef KDEBUG
7168  Lp.ecart=0; Lp.length=0;
7169#endif
7170  /*- computes the lcm(s[i],p) -*/
7171  Lp.lcm = pInit();
7172
7173  pLcm(p,q, Lp.lcm); // q is what was strat->S[i], so a poly in LM/TR presentation
7174  pSetm(Lp.lcm);
7175
7176  /* apply the V criterion */
7177  if (!isInV(Lp.lcm, lV))
7178  {
7179#ifdef KDEBUG
7180    if (TEST_OPT_DEBUG)
7181    {
7182      PrintS("V crit applied to q = ");
7183      wrp(q); //      wrp(pHead(q));
7184      PrintS(", p = ");
7185      wrp(p); //wrp(pHead(p));
7186      PrintLn();
7187    }
7188#endif
7189    pLmFree(Lp.lcm);
7190    Lp.lcm=NULL;
7191    /* + counter for applying the V criterion */
7192    strat->cv++;
7193    return;
7194  }
7195
7196  if (strat->sugarCrit && ALLOW_PROD_CRIT(strat))
7197  {
7198    if((!((ecartq>0)&&(ecart>0)))
7199    && pHasNotCF(p,q))
7200    {
7201    /*
7202    *the product criterion has applied for (s,p),
7203    *i.e. lcm(s,p)=product of the leading terms of s and p.
7204    *Suppose (s,r) is in L and the leading term
7205    *of p divides lcm(s,r)
7206    *(==> the leading term of p divides the leading term of r)
7207    *but the leading term of s does not divide the leading term of r
7208    *(notice that this condition is automatically satisfied if r is still
7209    *in S), then (s,r) can be cancelled.
7210    *This should be done here because the
7211    *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
7212    *
7213    *Moreover, skipping (s,r) holds also for the noncommutative case.
7214    */
7215      strat->cp++;
7216      pLmFree(Lp.lcm);
7217      Lp.lcm=NULL;
7218      return;
7219    }
7220    else
7221      Lp.ecart = si_max(ecart,ecartq);
7222    if (strat->fromT && (ecartq>ecart))
7223    {
7224      pLmFree(Lp.lcm);
7225      Lp.lcm=NULL;
7226      return;
7227      /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
7228    }
7229    /*
7230    *the set B collects the pairs of type (S[j],p)
7231    *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
7232    *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
7233    *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
7234    */
7235    {
7236      j = strat->Bl;
7237      loop
7238      {
7239        if (j < 0)  break;
7240        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
7241        if ((compare==1)
7242        &&(sugarDivisibleBy(strat->B[j].ecart,Lp.ecart)))
7243        {
7244          strat->c3++;
7245          if ((strat->fromQ==NULL) || (isFromQ==0) || (qfromQ==0))
7246          {
7247            pLmFree(Lp.lcm);
7248            return;
7249          }
7250          break;
7251        }
7252        else
7253        if ((compare ==-1)
7254        && sugarDivisibleBy(Lp.ecart,strat->B[j].ecart))
7255        {
7256          deleteInL(strat->B,&strat->Bl,j,strat);
7257          strat->c3++;
7258        }
7259        j--;
7260      }
7261    }
7262  }
7263  else /*sugarcrit*/
7264  {
7265    if (ALLOW_PROD_CRIT(strat))
7266    {
7267      // if currRing->nc_type!=quasi (or skew)
7268      // TODO: enable productCrit for super commutative algebras...
7269      if(/*(strat->ak==0) && productCrit(p,strat->S[i])*/
7270      pHasNotCF(p,q))
7271      {
7272      /*
7273      *the product criterion has applied for (s,p),
7274      *i.e. lcm(s,p)=product of the leading terms of s and p.
7275      *Suppose (s,r) is in L and the leading term
7276      *of p devides lcm(s,r)
7277      *(==> the leading term of p devides the leading term of r)
7278      *but the leading term of s does not devide the leading term of r
7279      *(notice that tis condition is automatically satisfied if r is still
7280      *in S), then (s,r) can be canceled.
7281      *This should be done here because the
7282      *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
7283      */
7284          strat->cp++;
7285          pLmFree(Lp.lcm);
7286          Lp.lcm=NULL;
7287          return;
7288      }
7289      if (strat->fromT && (ecartq>ecart))
7290      {
7291        pLmFree(Lp.lcm);
7292        Lp.lcm=NULL;
7293        return;
7294        /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
7295      }
7296      /*
7297      *the set B collects the pairs of type (S[j],p)
7298      *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
7299      *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
7300      *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
7301      */
7302      for(j = strat->Bl;j>=0;j--)
7303      {
7304        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
7305        if (compare==1)
7306        {
7307          strat->c3++;
7308          if ((strat->fromQ==NULL) || (isFromQ==0) || (qfromQ==0))
7309          {
7310            pLmFree(Lp.lcm);
7311            return;
7312          }
7313          break;
7314        }
7315        else
7316        if (compare ==-1)
7317        {
7318          deleteInL(strat->B,&strat->Bl,j,strat);
7319          strat->c3++;
7320        }
7321      }
7322    }
7323  }
7324  /*
7325  *the pair (S[i],p) enters B if the spoly != 0
7326  */
7327  /*-  compute the short s-polynomial -*/
7328  if (strat->fromT && !TEST_OPT_INTSTRATEGY)
7329    pNorm(p);
7330  if ((q==NULL) || (p==NULL))
7331    return;
7332  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (qfromQ!=0))
7333    Lp.p=NULL;
7334  else
7335  {
7336//     if ( rIsPluralRing(currRing) )
7337//     {
7338//       if(pHasNotCF(p, q))
7339//       {
7340//         if(ncRingType(currRing) == nc_lie)
7341//         {
7342//             // generalized prod-crit for lie-type
7343//             strat->cp++;
7344//             Lp.p = nc_p_Bracket_qq(pCopy(p),q);
7345//         }
7346//         else
7347//         if( ALLOW_PROD_CRIT(strat) )
7348//         {
7349//             // product criterion for homogeneous case in SCA
7350//             strat->cp++;
7351//             Lp.p = NULL;
7352//         }
7353//         else
7354//           Lp.p = nc_CreateSpoly(q,p,currRing); // ?
7355//       }
7356//       else  Lp.p = nc_CreateSpoly(q,p,currRing);
7357//     }
7358//     else
7359//     {
7360
7361    /* ksCreateShortSpoly needs two Lobject-kind presentations */
7362    /* p is already in this form, so convert q */
7363    //    q = pMove2CurrTail(q, strat);
7364    Lp.p = ksCreateShortSpoly(q, p, strat->tailRing);
7365      //  }
7366  }
7367  if (Lp.p == NULL)
7368  {
7369    /*- the case that the s-poly is 0 -*/
7370    /* TEMPORARILY DISABLED FOR SHIFTS because there is no i*/
7371//      if (strat->pairtest==NULL) initPairtest(strat);
7372//      strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
7373//      strat->pairtest[strat->sl+1] = TRUE;
7374    /* END _ TEMPORARILY DISABLED FOR SHIFTS */
7375    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
7376    /*
7377    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
7378    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
7379    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
7380    *term of p devides the lcm(s,r)
7381    *(this canceling should be done here because
7382    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
7383    *the first case is handeled in chainCrit
7384    */
7385    if (Lp.lcm!=NULL) pLmFree(Lp.lcm);
7386  }
7387  else
7388  {
7389    /*- the pair (S[i],p) enters B -*/
7390    /* both of them should have their LM in currRing and TAIL in tailring */
7391    Lp.p1 = q;  // already in the needed form
7392    Lp.p2 = p; // already in the needed form
7393
7394    if ( !rIsPluralRing(currRing) )
7395      pNext(Lp.p) = strat->tail;
7396
7397    /* TEMPORARILY DISABLED FOR SHIFTS because there's no i*/
7398    /* at the beginning we DO NOT set atR = -1 ANYMORE*/
7399    if ( (atR >= 0) && (shiftcount==0) && (ifromS >=0) )
7400    {
7401      Lp.i_r1 = kFindInT(Lp.p1,strat); //strat->S_2_R[ifromS];
7402      Lp.i_r2 = atR;
7403    }
7404    else
7405    {
7406      /* END _ TEMPORARILY DISABLED FOR SHIFTS */
7407      Lp.i_r1 = -1;
7408      Lp.i_r2 = -1;
7409     }
7410    strat->initEcartPair(&Lp,q,p,ecartq,ecart);
7411
7412    if (TEST_OPT_INTSTRATEGY)
7413    {
7414      if (!rIsPluralRing(currRing))
7415        nDelete(&(Lp.p->coef));
7416    }
7417
7418    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
7419    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
7420  }
7421}
7422#endif
7423
7424#ifdef HAVE_SHIFTBBA
7425/*2
7426*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
7427*superfluous elements in S will be deleted
7428*/
7429void enterpairsShift (poly h,int k,int ecart,int pos,kStrategy strat, int atR,int uptodeg, int lV)
7430{
7431  /* h is strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
7432  /* Q: what is exactly the strat->fromT ? A: a local case trick; don't need it yet*/
7433  int j=pos;
7434
7435#ifdef HAVE_RINGS
7436  assume (!rField_is_Ring(currRing));
7437#endif
7438  initenterpairsShift(h,k,ecart,0,strat, atR,uptodeg,lV);
7439  if ( (!strat->fromT)
7440  && ((strat->syzComp==0)
7441    ||(pGetComp(h)<=strat->syzComp)))
7442  {
7443    //Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
7444    unsigned long h_sev = pGetShortExpVector(h);
7445    loop
7446    {
7447      if (j > k) break;
7448      clearS(h,h_sev, &j,&k,strat);
7449      j++;
7450    }
7451    //Print("end clearS sl=%d\n",strat->sl);
7452  }
7453 // PrintS("end enterpairs\n");
7454}
7455#endif
7456
7457#ifdef HAVE_SHIFTBBA
7458/*3
7459*(s[0], s \dot h),...,(s[k],s \dot h) will be put to the pairset L
7460* also the pairs (h, s\dot s[0]), ..., (h, s\dot s[k]) enter L
7461* additionally we put the pairs (h, s \sdot h) for s>=1 to L
7462*/
7463void initenterpairsShift (poly h,int k,int ecart,int isFromQ, kStrategy strat, int atR, int uptodeg, int lV)
7464{
7465  /* h comes from strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
7466  //  atR = -1;
7467  if ((strat->syzComp==0)
7468  || (pGetComp(h)<=strat->syzComp))
7469  {
7470    int j;
7471    BOOLEAN new_pair=FALSE;
7472
7473    if (pGetComp(h)==0)
7474    {
7475      /* for Q!=NULL: build pairs (f,q),(f1,f2), but not (q1,q2)*/
7476      if ((isFromQ)&&(strat->fromQ!=NULL))
7477      {
7478        for (j=0; j<=k; j++)
7479        {
7480          if (!strat->fromQ[j])
7481          {
7482            new_pair=TRUE;
7483            enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR,uptodeg,lV);
7484            // other side pairs:
7485            enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
7486          //Print("j:%d, Ll:%d\n",j,strat->Ll);
7487          }
7488        }
7489      }
7490      else
7491      {
7492        new_pair=TRUE;
7493        for (j=0; j<=k; j++)
7494        {
7495          enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR,uptodeg,lV);
7496          // other side pairs
7497          enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
7498        }
7499        /* HERE we put (h, s*h) pairs */
7500       /* enterOnePairSelfShifts (poly qq, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int uptodeg, int lV); */
7501       enterOnePairSelfShifts (h, h, ecart, isFromQ, strat, atR, uptodeg, lV);
7502      }
7503    }
7504    else
7505    {
7506      for (j=0; j<=k; j++)
7507      {
7508        if ((pGetComp(h)==pGetComp(strat->S[j]))
7509        || (pGetComp(strat->S[j])==0))
7510        {
7511          new_pair=TRUE;
7512          enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR, uptodeg, lV);
7513          // other side pairs
7514          enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
7515        //Print("j:%d, Ll:%d\n",j,strat->Ll);
7516        }
7517      }
7518      /* HERE we put (h, s*h) pairs */
7519      enterOnePairSelfShifts (h, h, ecart, isFromQ, strat, atR, uptodeg, lV);
7520    }
7521
7522    if (new_pair)
7523    {
7524      strat->chainCrit(h,ecart,strat);
7525    }
7526
7527  }
7528}
7529#endif
7530
7531#ifdef HAVE_SHIFTBBA
7532/*2
7533* puts p to the set T, starting with the at position atT
7534* and inserts all admissible shifts of p
7535*/
7536void enterTShift(LObject p, kStrategy strat, int atT, int uptodeg, int lV)
7537{
7538  /* determine how many elements we have to insert */
7539  /* x(0)y(1)z(2) : lastVblock-1=2, to add until lastVblock=uptodeg-1 */
7540  /* hence, a total number of elt's to add is: */
7541  /*  int toInsert = 1 + (uptodeg-1) - (pLastVblock(p.p, lV) -1);  */
7542
7543  int toInsert =  itoInsert(p.p, uptodeg,  lV, strat->tailRing);
7544
7545#ifdef PDEBUG
7546  //  Print("enterTShift uses toInsert: %d", toInsert);  PrintLn();
7547#endif
7548  int i;
7549
7550  if (atT < 0)
7551    atT = strat->posInT(strat->T, strat->tl, p);
7552
7553  /* can call enterT in a sequence, e.g. */
7554
7555  /* shift0 = it's our model for further shifts */
7556  enterT(p,strat,atT);
7557  LObject qq;
7558  for (i=1; i<=toInsert; i++) // toIns - 1?
7559  {
7560    qq      = p; //qq.Copy();
7561    qq.p    = NULL;
7562    qq.max  = NULL;
7563    qq.t_p = p_LPshift(p_Copy(p.t_p,strat->tailRing), i, uptodeg, lV, strat->tailRing); // direct shift
7564    qq.GetP();
7565    // update q.sev
7566    qq.sev = pGetShortExpVector(qq.p);
7567    /* enter it into T, first el't is with the shift 0 */
7568    // compute the position for qq
7569    atT = strat->posInT(strat->T, strat->tl, qq);
7570    enterT(qq,strat,atT);
7571  }
7572/* Q: what to do with this one in the orig enterT ? */
7573/*  strat->R[strat->tl] = &(strat->T[atT]); */
7574/* Solution: it is done by enterT each time separately */
7575}
7576#endif
7577
7578#ifdef HAVE_SHIFTBBA
7579poly redtailBbaShift (LObject* L, int pos, kStrategy strat, BOOLEAN withT, BOOLEAN normalize)
7580{
7581  /* for the shift case need to run it with withT = TRUE */
7582  strat->redTailChange=FALSE;
7583  if (strat->noTailReduction) return L->GetLmCurrRing();
7584  poly h, p;
7585  p = h = L->GetLmTailRing();
7586  if ((h==NULL) || (pNext(h)==NULL))
7587    return L->GetLmCurrRing();
7588
7589  TObject* With;
7590  // placeholder in case strat->tl < 0
7591  TObject  With_s(strat->tailRing);
7592
7593  LObject Ln(pNext(h), strat->tailRing);
7594  Ln.pLength = L->GetpLength() - 1;
7595
7596  pNext(h) = NULL;
7597  if (L->p != NULL) pNext(L->p) = NULL;
7598  L->pLength = 1;
7599
7600  Ln.PrepareRed(strat->use_buckets);
7601
7602  while(!Ln.IsNull())
7603  {
7604    loop
7605    {
7606      Ln.SetShortExpVector();
7607      if (withT)
7608      {
7609        int j;
7610        j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln);
7611        if (j < 0) break;
7612        With = &(strat->T[j]);
7613      }
7614      else
7615      {
7616        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
7617        if (With == NULL) break;
7618      }
7619      if (normalize && (!TEST_OPT_INTSTRATEGY) && (!nIsOne(pGetCoeff(With->p))))
7620      {
7621        With->pNorm();
7622        //if (TEST_OPT_PROT) { PrintS("n"); mflush(); }
7623      }
7624      strat->redTailChange=TRUE;
7625      if (ksReducePolyTail(L, With, &Ln))
7626      {
7627        // reducing the tail would violate the exp bound
7628        //  set a flag and hope for a retry (in bba)
7629        strat->completeReduce_retry=TRUE;
7630        if ((Ln.p != NULL) && (Ln.t_p != NULL)) Ln.p=NULL;
7631        do
7632        {
7633          pNext(h) = Ln.LmExtractAndIter();
7634          pIter(h);
7635          L->pLength++;
7636        } while (!Ln.IsNull());
7637        goto all_done;
7638      }
7639      if (Ln.IsNull()) goto all_done;
7640      if (! withT) With_s.Init(currRing);
7641    }
7642    pNext(h) = Ln.LmExtractAndIter();
7643    pIter(h);
7644    L->pLength++;
7645  }
7646
7647  all_done:
7648  Ln.Delete();
7649  if (L->p != NULL) pNext(L->p) = pNext(p);
7650
7651  if (strat->redTailChange)
7652  {
7653    L->last = NULL;
7654    L->length = 0;
7655  }
7656  L->Normalize(); // HANNES: should have a test
7657  kTest_L(L);
7658  return L->GetLmCurrRing();
7659}
7660#endif
Note: See TracBrowser for help on using the repository browser.