source: git/kernel/kutil.cc @ 0b4ec2

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