source: git/kernel/kutil.cc @ 8e1c4e

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