source: git/kernel/kutil.cc @ a589e6

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