source: git/kernel/kutil.cc @ 4d43ff

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