source: git/kernel/kutil.cc @ 093f30e

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