source: git/kernel/kutil.cc @ 308a075

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