source: git/kernel/kutil.cc @ 5c9d99

spielwiese
Last change on this file since 5c9d99 was 5c9d99, checked in by Oliver Wienand <wienand@…>, 16 years ago
kutil.cc: Debug Ausgabe wegen Fehler in Windows geaendert. git-svn-id: file:///usr/local/Singular/svn/trunk@11138 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 189.4 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: kutil.cc,v 1.112 2008-10-14 09:18:36 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
6050  if (! k_GetLeadTerms(L->p1, L->p2, currRing, m1, m2, strat->tailRing))
6051    return FALSE;
6052  // shift changes: extra case inserted
6053  if ((L->i_r1 == -1) || (L->i_r2 == -1) )
6054  {
6055    return TRUE;
6056  }
6057  poly p1_max = (strat->R[L->i_r1])->max;
6058  poly p2_max = (strat->R[L->i_r2])->max;
6059
6060  if ((p1_max != NULL && !p_LmExpVectorAddIsOk(m1, p1_max, strat->tailRing)) ||
6061      (p2_max != NULL && !p_LmExpVectorAddIsOk(m2, p2_max, strat->tailRing)))
6062  {
6063    p_LmFree(m1, strat->tailRing);
6064    p_LmFree(m2, strat->tailRing);
6065    m1 = NULL;
6066    m2 = NULL;
6067    return FALSE;
6068  }
6069  return TRUE;
6070}
6071
6072#ifdef HAVE_RINGS
6073/***************************************************************
6074 *
6075 * Checks, if we can compute the gcd poly / strong pair
6076 * gcd-poly = m1 * R[atR] + m2 * S[atS]
6077 *
6078 ***************************************************************/
6079BOOLEAN kCheckStrongCreation(int atR, poly m1, int atS, poly m2, kStrategy strat)
6080{
6081  assume(strat->S_2_R[atS] >= -1 && strat->S_2_R[atS] <= strat->tl);
6082  assume(strat->tailRing != currRing);
6083
6084  poly p1_max = (strat->R[atR])->max;
6085  poly p2_max = (strat->R[strat->S_2_R[atS]])->max;
6086
6087  if ((p1_max != NULL && !p_LmExpVectorAddIsOk(m1, p1_max, strat->tailRing)) ||
6088      (p2_max != NULL && !p_LmExpVectorAddIsOk(m2, p2_max, strat->tailRing)))
6089  {
6090    return FALSE;
6091  }
6092  return TRUE;
6093}
6094#endif
6095
6096BOOLEAN kStratChangeTailRing(kStrategy strat, LObject *L, TObject* T, unsigned long expbound)
6097{
6098  if (expbound == 0) expbound = strat->tailRing->bitmask << 1;
6099  if (expbound >= currRing->bitmask) return FALSE;
6100  ring new_tailRing = rModifyRing(currRing,
6101                                  // Hmmm .. the condition pFDeg == pDeg
6102                                  // might be too strong
6103#ifdef HAVE_RINGS
6104                                  (strat->homog && pFDeg == pDeg && !(rField_is_Ring(currRing))), // TODO Oliver
6105#else
6106                                  (strat->homog && pFDeg == pDeg),
6107#endif
6108                                  !strat->ak,
6109                                  expbound);
6110  if (new_tailRing == currRing) return TRUE;
6111
6112  strat->pOrigFDeg_TailRing = new_tailRing->pFDeg;
6113  strat->pOrigLDeg_TailRing = new_tailRing->pLDeg;
6114
6115  if (currRing->pFDeg != currRing->pFDegOrig)
6116  {
6117    new_tailRing->pFDeg = currRing->pFDeg;
6118    new_tailRing->pLDeg = currRing->pLDeg;
6119  }
6120
6121  if (TEST_OPT_PROT)
6122    Print("[%lu:%d", (unsigned long) new_tailRing->bitmask, new_tailRing->ExpL_Size);
6123  kTest_TS(strat);
6124  assume(new_tailRing != strat->tailRing);
6125  pShallowCopyDeleteProc p_shallow_copy_delete
6126    = pGetShallowCopyDeleteProc(strat->tailRing, new_tailRing);
6127
6128  omBin new_tailBin = omGetStickyBinOfBin(new_tailRing->PolyBin);
6129
6130  int i;
6131  for (i=0; i<=strat->tl; i++)
6132  {
6133    strat->T[i].ShallowCopyDelete(new_tailRing, new_tailBin,
6134                                  p_shallow_copy_delete);
6135  }
6136  for (i=0; i<=strat->Ll; i++)
6137  {
6138    assume(strat->L[i].p != NULL);
6139    if (pNext(strat->L[i].p) != strat->tail)
6140      strat->L[i].ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
6141  }
6142  if (strat->P.t_p != NULL ||
6143      (strat->P.p != NULL && pNext(strat->P.p) != strat->tail))
6144    strat->P.ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
6145
6146  if (L != NULL && L->tailRing != new_tailRing)
6147  {
6148    if (L->i_r < 0)
6149      L->ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
6150    else
6151    {
6152      assume(L->i_r <= strat->tl);
6153      TObject* t_l = strat->R[L->i_r];
6154      assume(t_l != NULL);
6155      L->tailRing = new_tailRing;
6156      L->p = t_l->p;
6157      L->t_p = t_l->t_p;
6158      L->max = t_l->max;
6159    }
6160  }
6161
6162  if (T != NULL && T->tailRing != new_tailRing && T->i_r < 0)
6163    T->ShallowCopyDelete(new_tailRing, new_tailBin, p_shallow_copy_delete);
6164
6165  omMergeStickyBinIntoBin(strat->tailBin, strat->tailRing->PolyBin);
6166  if (strat->tailRing != currRing)
6167    rKillModifiedRing(strat->tailRing);
6168
6169  strat->tailRing = new_tailRing;
6170  strat->tailBin = new_tailBin;
6171  strat->p_shallow_copy_delete
6172    = pGetShallowCopyDeleteProc(currRing, new_tailRing);
6173
6174  if (strat->kHEdge != NULL)
6175  {
6176    if (strat->t_kHEdge != NULL)
6177      p_LmFree(strat->t_kHEdge, strat->tailRing);
6178    strat->t_kHEdge=k_LmInit_currRing_2_tailRing(strat->kHEdge, new_tailRing);
6179  }
6180
6181  if (strat->kNoether != NULL)
6182  {
6183    if (strat->t_kNoether != NULL)
6184      p_LmFree(strat->t_kNoether, strat->tailRing);
6185    strat->t_kNoether=k_LmInit_currRing_2_tailRing(strat->kNoether,
6186                                                   new_tailRing);
6187  }
6188  kTest_TS(strat);
6189  if (TEST_OPT_PROT)
6190    PrintS("]");
6191  return TRUE;
6192}
6193
6194void kStratInitChangeTailRing(kStrategy strat)
6195{
6196  unsigned long l = 0;
6197  int i;
6198  Exponent_t e;
6199  ring new_tailRing;
6200
6201  assume(strat->tailRing == currRing);
6202
6203  for (i=0; i<= strat->Ll; i++)
6204  {
6205    l = p_GetMaxExpL(strat->L[i].p, currRing, l);
6206  }
6207  for (i=0; i<=strat->tl; i++)
6208  {
6209    // Hmm ... this we could do in one Step
6210    l = p_GetMaxExpL(strat->T[i].p, currRing, l);
6211  }
6212  if (rField_is_Ring(currRing))
6213  {
6214    l *= 2;
6215  }
6216  e = p_GetMaxExp(l, currRing);
6217  if (e <= 1) e = 2;
6218
6219  kStratChangeTailRing(strat, NULL, NULL, e);
6220}
6221
6222skStrategy::skStrategy()
6223{
6224  memset(this, 0, sizeof(skStrategy));
6225#ifndef NDEBUG
6226  strat_nr++;
6227  nr=strat_nr;
6228  if (strat_fac_debug) Print("s(%d) created\n",nr);
6229#endif
6230  tailRing = currRing;
6231  P.tailRing = currRing;
6232  tl = -1;
6233  sl = -1;
6234#ifdef HAVE_LM_BIN
6235  lmBin = omGetStickyBinOfBin(currRing->PolyBin);
6236#endif
6237#ifdef HAVE_TAIL_BIN
6238  tailBin = omGetStickyBinOfBin(currRing->PolyBin);
6239#endif
6240  pOrigFDeg = pFDeg;
6241  pOrigLDeg = pLDeg;
6242}
6243
6244
6245skStrategy::~skStrategy()
6246{
6247  if (lmBin != NULL)
6248    omMergeStickyBinIntoBin(lmBin, currRing->PolyBin);
6249  if (tailBin != NULL)
6250    omMergeStickyBinIntoBin(tailBin,
6251                            (tailRing != NULL ? tailRing->PolyBin:
6252                             currRing->PolyBin));
6253  if (t_kHEdge != NULL)
6254    p_LmFree(t_kHEdge, tailRing);
6255  if (t_kNoether != NULL)
6256    p_LmFree(t_kNoether, tailRing);
6257
6258  if (currRing != tailRing)
6259    rKillModifiedRing(tailRing);
6260  pRestoreDegProcs(pOrigFDeg, pOrigLDeg);
6261}
6262
6263#if 0
6264Timings for the different possibilities of posInT:
6265            T15           EDL         DL          EL            L         1-2-3
6266Gonnet      43.26       42.30       38.34       41.98       38.40      100.04
6267Hairer_2_1   1.11        1.15        1.04        1.22        1.08        4.7
6268Twomat3      1.62        1.69        1.70        1.65        1.54       11.32
6269ahml         4.48        4.03        4.03        4.38        4.96       26.50
6270c7          15.02       13.98       15.16       13.24       17.31       47.89
6271c8         505.09      407.46      852.76      413.21      499.19        n/a
6272f855        12.65        9.27       14.97        8.78       14.23       33.12
6273gametwo6    11.47       11.35       14.57       11.20       12.02       35.07
6274gerhard_3    2.73        2.83        2.93        2.64        3.12        6.24
6275ilias13     22.89       22.46       24.62       20.60       23.34       53.86
6276noon8       40.68       37.02       37.99       36.82       35.59      877.16
6277rcyclic_19  48.22       42.29       43.99       45.35       51.51      204.29
6278rkat9       82.37       79.46       77.20       77.63       82.54      267.92
6279schwarz_11  16.46       16.81       16.76       16.81       16.72       35.56
6280test016     16.39       14.17       14.40       13.50       14.26       34.07
6281test017     34.70       36.01       33.16       35.48       32.75       71.45
6282test042     10.76       10.99       10.27       11.57       10.45       23.04
6283test058      6.78        6.75        6.51        6.95        6.22        9.47
6284test066     10.71       10.94       10.76       10.61       10.56       19.06
6285test073     10.75       11.11       10.17       10.79        8.63       58.10
6286test086     12.23       11.81       12.88       12.24       13.37       66.68
6287test103      5.05        4.80        5.47        4.64        4.89       11.90
6288test154     12.96       11.64       13.51       12.46       14.61       36.35
6289test162     65.27       64.01       67.35       59.79       67.54      196.46
6290test164      7.50        6.50        7.68        6.70        7.96       17.13
6291virasoro     3.39        3.50        3.35        3.47        3.70        7.66
6292#endif
6293
6294
6295#ifdef HAVE_MORE_POS_IN_T
6296// determines the position based on: 1.) Ecart 2.) FDeg 3.) pLength
6297int posInT_EcartFDegpLength(const TSet set,const int length,LObject &p)
6298{
6299
6300  if (length==-1) return 0;
6301
6302  int o = p.ecart;
6303  int op=p.GetpFDeg();
6304  int ol = p.GetpLength();
6305
6306  if (set[length].ecart < o)
6307    return length+1;
6308  if (set[length].ecart == o)
6309  {
6310     int oo=set[length].GetpFDeg();
6311     if ((oo < op) || ((oo==op) && (set[length].length < ol)))
6312       return length+1;
6313  }
6314
6315  int i;
6316  int an = 0;
6317  int en= length;
6318  loop
6319  {
6320    if (an >= en-1)
6321    {
6322      if (set[an].ecart > o)
6323        return an;
6324      if (set[an].ecart == o)
6325      {
6326         int oo=set[an].GetpFDeg();
6327         if((oo > op)
6328         || ((oo==op) && (set[an].pLength > ol)))
6329           return an;
6330      }
6331      return en;
6332    }
6333    i=(an+en) / 2;
6334    if (set[i].ecart > o)
6335      en=i;
6336    else if (set[i].ecart == o)
6337    {
6338       int oo=set[i].GetpFDeg();
6339       if ((oo > op)
6340       || ((oo == op) && (set[i].pLength > ol)))
6341         en=i;
6342       else
6343        an=i;
6344    }
6345    else
6346      an=i;
6347  }
6348}
6349
6350// determines the position based on: 1.) FDeg 2.) pLength
6351int posInT_FDegpLength(const TSet set,const int length,LObject &p)
6352{
6353
6354  if (length==-1) return 0;
6355
6356  int op=p.GetpFDeg();
6357  int ol = p.GetpLength();
6358
6359  int oo=set[length].GetpFDeg();
6360  if ((oo < op) || ((oo==op) && (set[length].length < ol)))
6361    return length+1;
6362
6363  int i;
6364  int an = 0;
6365  int en= length;
6366  loop
6367    {
6368      if (an >= en-1)
6369      {
6370        int oo=set[an].GetpFDeg();
6371        if((oo > op)
6372           || ((oo==op) && (set[an].pLength > ol)))
6373          return an;
6374        return en;
6375      }
6376      i=(an+en) / 2;
6377      int oo=set[i].GetpFDeg();
6378      if ((oo > op)
6379          || ((oo == op) && (set[i].pLength > ol)))
6380        en=i;
6381      else
6382        an=i;
6383    }
6384}
6385
6386
6387// determines the position based on: 1.) Ecart 2.) FDeg 3.) pLength
6388int posInT_pLength(const TSet set,const int length,LObject &p)
6389{
6390  if (length==-1)
6391    return 0;
6392  if (set[length].length<p.length)
6393    return length+1;
6394
6395  int i;
6396  int an = 0;
6397  int en= length;
6398  int ol = p.GetpLength();
6399
6400  loop
6401  {
6402    if (an >= en-1)
6403    {
6404      if (set[an].pLength>ol) return an;
6405      return en;
6406    }
6407    i=(an+en) / 2;
6408    if (set[i].pLength>ol) en=i;
6409    else                        an=i;
6410  }
6411}
6412#endif
6413
6414#ifdef HAVE_SHIFTBBA
6415poly pMove2CurrTail(poly p, kStrategy strat)
6416{
6417  /* assume: p is completely in currRing */
6418  /* produces an object with LM in curring
6419     and TAIL in tailring */
6420  if (pNext(p)!=NULL)
6421  {
6422    pNext(p) = prMoveR(pNext(p), /* src */ currRing, /* dest */ strat->tailRing);
6423  }
6424  return(p);
6425}
6426#endif
6427
6428#ifdef HAVE_SHIFTBBA
6429poly pMoveCurrTail2poly(poly p, kStrategy strat)
6430{
6431  /* assume: p has  LM in curring and TAIL in tailring */
6432  /* convert it to complete currRing */
6433
6434  /* check that LM is in currRing */
6435  assume(p_LmCheckIsFromRing(p, currRing));
6436
6437  if (pNext(p)!=NULL)
6438  {
6439    pNext(p) = prMoveR(pNext(p), /* src */ strat->tailRing, /* dest */currRing);
6440  }
6441  return(p);
6442}
6443#endif
6444
6445#ifdef HAVE_SHIFTBBA
6446poly pCopyL2p(LObject H, kStrategy strat)
6447{
6448    /* restores a poly in currRing from LObject */
6449    LObject h = H;
6450    h.Copy();
6451    poly p;
6452    if (h.p == NULL)
6453    {
6454      if (h.t_p != NULL)
6455      {
6456         p = prMoveR(h.t_p, /* source ring: */ strat->tailRing, /* dest. ring: */ currRing);
6457        return(p);
6458      }
6459      else
6460      {
6461        /* h.tp == NULL -> the object is NULL */
6462        return(NULL);
6463      }
6464    }
6465    /* we're here if h.p != NULL */
6466    if (h.t_p == NULL)
6467    {
6468       /* then h.p is the whole poly in currRing */
6469       p = h.p;
6470      return(p);
6471    }
6472    /* we're here if h.p != NULL and h.t_p != NULL */
6473    // clean h.p, get poly from t_p
6474     pNext(h.p)=NULL;
6475     pDelete(&h.p);
6476     p = prMoveR(h.t_p, /* source ring: */ strat->tailRing,
6477                         /* dest. ring: */ currRing);
6478     // no need to clean h: we re-used the polys
6479    return(p);
6480}
6481#endif
6482
6483//LObject pCopyp2L(poly p, kStrategy strat)
6484//{
6485    /* creates LObject from the poly in currRing */
6486  /* actually put p into L.p and make L.t_p=NULL : does not work */
6487 
6488//}
6489
6490// poly pCopyL2p(LObject H, kStrategy strat)
6491// {
6492//   /* restores a poly in currRing from LObject */
6493//   LObject h = H;
6494//   h.Copy();
6495//   poly p;
6496//   if (h.p == NULL)
6497//   {
6498//     if (h.t_p != NULL)
6499//     {
6500//       p = p_ShallowCopyDelete(h.t_p, (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
6501//       return(p);
6502//     }
6503//     else
6504//     {
6505//       /* h.tp == NULL -> the object is NULL */
6506//       return(NULL);
6507//     }
6508//   }
6509//   /* we're here if h.p != NULL */
6510
6511//   if (h.t_p == NULL)
6512//   {
6513//     /* then h.p is the whole poly in tailRing */
6514//     if (strat->tailBin != NULL && (pNext(h.p) != NULL))
6515//     {
6516//       p = p_ShallowCopyDelete(h.p, (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
6517//     }
6518//     return(p);
6519//   }
6520//   /* we're here if h.p != NULL and h.t_p != NULL */
6521//   p = pCopy(pHead(h.p)); // in currRing
6522//   if (strat->tailBin != NULL && (pNext(h.p) != NULL))
6523//   {
6524//     //    pNext(p) = p_ShallowCopyDelete(pNext(h.t_p), (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
6525//     poly pp = p_Copy(pNext(h.p), strat->tailRing);
6526//     //    poly p3 = p_Copy(pNext(h.p), currRing); // error
6527//       // p_ShallowCopyDelete(pNext(h.p), currRing, strat->tailBin); // the same as pp
6528//     poly p5 = p_ShallowCopyDelete(pNext(h.p), strat->tailRing, strat->tailBin);
6529//     pNext(p) = p_ShallowCopyDelete(h.t_p, strat->tailRing, strat->tailBin);
6530//     poly p4 = p_Copy(h.t_p, strat->tailRing);
6531//     //    if (p.t_p != NULL) pNext(p.t_p) = pNext(p.p);
6532//   }
6533//   //  pTest(p);
6534//   return(p);
6535// }
6536
6537#ifdef HAVE_SHIFTBBA
6538/* including the self pairs */
6539void updateSShift(kStrategy strat,int uptodeg,int lV)
6540{
6541  /* to use after updateS(toT=FALSE,strat) */
6542  /* fills T with shifted elt's of S */
6543  int i;
6544  LObject h;
6545  int atT = -1; // or figure out smth better
6546  strat->tl = -1; // init
6547  for (i=0; i<=strat->sl; i++)
6548  {
6549    memset(&h,0,sizeof(h));
6550    h.p =  strat->S[i]; // lm in currRing, tail in TR
6551    strat->initEcart(&h);
6552    h.sev = strat->sevS[i];
6553    h.t_p = NULL;
6554    h.GetTP(); // creates correct t_p
6555    /*puts the elements of S with their shifts to T*/
6556    //    int atT, int uptodeg, int lV)
6557    strat->S_2_R[i] = strat->tl + 1; // the el't with shift 0 will be inserted first
6558    // need a small check for above; we insert >=1 elements
6559    // insert this check into kTest_TS ?
6560    enterTShift(h,strat,atT,uptodeg,lV);
6561  }
6562  /* what about setting strat->tl? */
6563}
6564#endif
6565
6566#ifdef HAVE_SHIFTBBA
6567void initBuchMoraShift (ideal F,ideal Q,kStrategy strat)
6568{
6569  strat->interpt = BTEST1(OPT_INTERRUPT);
6570  strat->kHEdge=NULL;
6571  if (pOrdSgn==1) strat->kHEdgeFound=FALSE;
6572  /*- creating temp data structures------------------- -*/
6573  strat->cp = 0;
6574  strat->c3 = 0;
6575  strat->cv = 0;
6576  strat->tail = pInit();
6577  /*- set s -*/
6578  strat->sl = -1;
6579  /*- set L -*/
6580  strat->Lmax = setmaxL;
6581  strat->Ll = -1;
6582  strat->L = initL();
6583  /*- set B -*/
6584  strat->Bmax = setmaxL;
6585  strat->Bl = -1;
6586  strat->B = initL();
6587  /*- set T -*/
6588  strat->tl = -1;
6589  strat->tmax = setmaxT;
6590  strat->T = initT();
6591  strat->R = initR();
6592  strat->sevT = initsevT();
6593  /*- init local data struct.---------------------------------------- -*/
6594  strat->P.ecart=0;
6595  strat->P.length=0;
6596  if (pOrdSgn==-1)
6597  {
6598    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
6599    if (strat->kNoether!=NULL) pSetComp(strat->kNoetherTail(), strat->ak);
6600  }
6601  if(TEST_OPT_SB_1)
6602  {
6603    int i;
6604    ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
6605    for (i=strat->newIdeal;i<IDELEMS(F);i++)
6606    {
6607      P->m[i-strat->newIdeal] = F->m[i];
6608      F->m[i] = NULL;
6609    }
6610    initSSpecial(F,Q,P,strat);
6611    for (i=strat->newIdeal;i<IDELEMS(F);i++)
6612    {
6613      F->m[i] = P->m[i-strat->newIdeal];
6614      P->m[i-strat->newIdeal] = NULL;
6615    }
6616    idDelete(&P);
6617  }
6618  else
6619  {
6620    /*Shdl=*/initSL(F, Q,strat); /*sets also S, ecartS, fromQ */
6621    // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
6622  }
6623  strat->kIdeal = NULL;
6624  strat->fromT = FALSE;
6625  strat->noTailReduction = !TEST_OPT_REDTAIL;
6626  if (!TEST_OPT_SB_1)
6627  {
6628    /* the only change: we do not fill the set T*/
6629    updateS(FALSE,strat);
6630  }
6631  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
6632  strat->fromQ=NULL;
6633  /* more changes: fill the set T with all the shifts of elts of S*/
6634  /* is done by other procedure */
6635}
6636#endif
6637
6638#ifdef HAVE_SHIFTBBA
6639/*1
6640* put the pairs (sh \dot s[i],p)  into the set B, ecart=ecart(p)
6641*/
6642void enterOnePairManyShifts (int i, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int uptodeg, int lV)
6643{
6644  /* p comes from strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
6645
6646  assume(p_LmCheckIsFromRing(p,currRing));
6647  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
6648
6649  /* cycles through all shifts of s[i] until uptodeg - lastVblock(s[i]) */
6650  /* that is create the pairs (f, s \dot g)  */
6651
6652  poly qq = strat->S[i]; //  lm in currRing, tail in tailRing
6653
6654  //  poly q = pCopy(pHead(strat->S[i])); // lm in currRing
6655  //  pNext(q) = prCopyR(pNext(strat->S[i]),strat->tailRing,currRing); // zero shift
6656
6657 /* determine how many elements we have to insert for a given s[i] */
6658  /* x(0)y(1)z(2) : lastVblock-1=2, to add until lastVblock=uptodeg-1 */
6659  /* hence, a total number of elt's to add is: */
6660  /*  int toInsert = 1 + (uptodeg-1) - (pLastVblock(p.p, lV) -1);  */
6661  int toInsert =  itoInsert(qq, uptodeg,  lV, strat->tailRing);
6662
6663#ifdef KDEBUG
6664    if (TEST_OPT_DEBUG)
6665    {
6666      //      Print("entered ManyShifts: with toInsert=%d",toInsert); PrintLn();
6667    }
6668#endif
6669
6670  assume(i<=strat->sl); // from OnePair
6671  if (strat->interred_flag) return; // ?
6672
6673  /* these vars hold for all shifts of s[i] */
6674  int ecartq = 0; //Hans says it's ok; we're in the homog case, no ecart
6675 
6676  int qfromQ;
6677  if (strat->fromQ != NULL)
6678  {
6679    qfromQ = strat->fromQ[i]; 
6680  }
6681  else
6682  {
6683    qfromQ = -1;
6684  }
6685
6686  int j;
6687
6688  poly q, s;
6689
6690  // for the 0th shift: insert the orig. pair
6691  enterOnePairShift(qq, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, j, i, uptodeg, lV);
6692
6693  for (j=1; j<= toInsert; j++) 
6694  {
6695    //    q = pLPshift(strat->S[i],j,uptodeg,lV);
6696    q = p_LPshiftT(qq, j, uptodeg, lV, strat, currRing); 
6697    //    q = p_mLPshift(qq,j,uptodeg,lV,currRing); // lm in currRing, shift this monomial
6698    //    s = p_LPshift(pNext(qq), j, uptodeg, lV, strat->tailRing); // from tailRing
6699    //    pNext(q) = s; // in tailRing
6700    /* here we need to call enterOnePair with two polys ... */
6701
6702#ifdef KDEBUG
6703    if (TEST_OPT_DEBUG)
6704    {
6705      //      PrintS("ManyShifts: calling enterOnePairShift(q,p)");      PrintLn();
6706    }
6707#endif
6708    enterOnePairShift(q, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, j, i, uptodeg, lV);
6709  }
6710}
6711#endif
6712
6713#ifdef HAVE_SHIFTBBA
6714/*1
6715* put the pairs (sh \dot qq,p)  into the set B, ecart=ecart(p)
6716* despite the name, not only self shifts
6717*/
6718void enterOnePairSelfShifts (poly qq, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int uptodeg, int lV)
6719{
6720
6721  /* format: p,qq are in LObject form: lm in CR, tail in TR */
6722  /* for true self pairs qq ==p  */
6723  /* we test both qq and p */
6724  assume(p_LmCheckIsFromRing(qq,currRing));
6725  assume(p_CheckIsFromRing(pNext(qq),strat->tailRing));
6726  assume(p_LmCheckIsFromRing(p,currRing));
6727  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
6728
6729  /* since this proc is applied twice for (h, s*g) and (g,s*h), init j with 1 only */
6730
6731  //  int j = 0;
6732  int j = 1;
6733
6734  /* for such self pairs start with 1, not with 0 */
6735  if (qq == p) j=1;
6736
6737  /* should cycle through all shifts of q until uptodeg - lastVblock(q) */
6738  /* that is create the pairs (f, s \dot g)  */
6739
6740  int toInsert =  itoInsert(qq, uptodeg,  lV, strat->tailRing);
6741
6742#ifdef KDEBUG
6743    if (TEST_OPT_DEBUG)
6744    {
6745      //      Print("entered SelfShifts: with toInsert=%d",toInsert); PrintLn();
6746    }
6747#endif
6748
6749  poly q, s;
6750
6751  if (strat->interred_flag) return; // ?
6752
6753  /* these vars hold for all shifts of s[i] */
6754  int ecartq = 0; //Hans says it's ok; we're in the homog case, no ecart
6755  int qfromQ = 0; // strat->fromQ[i];
6756
6757  for (; j<= toInsert; j++)
6758  {
6759    //    q = pLPshift(strat->S[i],j,uptodeg,lV);
6760    /* we increase shifts by one; must delete q there*/
6761    //    q = qq; q = pMoveCurrTail2poly(q,strat);
6762    //    q = pLPshift(q,j,uptodeg,lV); //,currRing);
6763    q = p_LPshiftT(qq, j, uptodeg, lV, strat, currRing);
6764    //    q = p_mLPshift(qq,j,uptodeg,lV,currRing); // lm in currRing, shift this monomial
6765    //    s = p_LPshift(pNext(qq), j, uptodeg, lV, strat->tailRing); // from tailRing
6766    //    pNext(q) = s; // in tailRing
6767    /* here we need to call enterOnePair with two polys ... */
6768#ifdef KDEBUG
6769    if (TEST_OPT_DEBUG)
6770    {
6771      //      PrintS("SelfShifts: calling enterOnePairShift(q,p)");      PrintLn();
6772    }
6773#endif
6774    enterOnePairShift(q, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, j, -1, uptodeg, lV);
6775  }
6776}
6777#endif
6778
6779#ifdef HAVE_SHIFTBBA
6780/*2
6781* put the pair (q,p)  into the set B, ecart=ecart(p), q is the shift of some s[i]
6782*/
6783void enterOnePairShift (poly q, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int ecartq, int qisFromQ, int shiftcount, int ifromS, int uptodeg, int lV)
6784{
6785
6786  /* Format: q and p are like strat->P.p, so lm in CR, tail in TR */
6787
6788  /* check this Formats: */
6789  assume(p_LmCheckIsFromRing(q,currRing));
6790  assume(p_CheckIsFromRing(pNext(q),strat->tailRing));
6791  assume(p_LmCheckIsFromRing(p,currRing));
6792  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
6793
6794#ifdef KDEBUG
6795    if (TEST_OPT_DEBUG)
6796    {
6797//       PrintS("enterOnePairShift(q,p) invoked with q = ");
6798//       wrp(q); //      wrp(pHead(q));
6799//       PrintS(", p = ");
6800//       wrp(p); //wrp(pHead(p));
6801//       PrintLn();
6802    }
6803#endif
6804
6805  /* poly q stays for s[i], ecartq = ecart(q), qisFromQ = applies to q */
6806
6807  int qfromQ = qisFromQ;
6808
6809  /* need additionally: int up_to_degree, poly V0 with the variables in (0)  or just the number lV = the length of the first block */
6810
6811  if (strat->interred_flag) return;
6812
6813  int      l,j,compare;
6814  LObject  Lp;
6815  Lp.i_r = -1;
6816
6817#ifdef KDEBUG
6818  Lp.ecart=0; Lp.length=0;
6819#endif
6820  /*- computes the lcm(s[i],p) -*/
6821  Lp.lcm = pInit();
6822
6823  pLcm(p,q, Lp.lcm); // q is what was strat->S[i], so a poly in LM/TR presentation
6824  pSetm(Lp.lcm);
6825
6826  /* apply the V criterion */
6827  if (!isInV(Lp.lcm, lV))
6828  {
6829#ifdef KDEBUG
6830    if (TEST_OPT_DEBUG)
6831    {
6832      PrintS("V crit applied to q = ");
6833      wrp(q); //      wrp(pHead(q));
6834      PrintS(", p = ");
6835      wrp(p); //wrp(pHead(p));
6836      PrintLn();
6837    }
6838#endif
6839    pLmFree(Lp.lcm);
6840    Lp.lcm=NULL;
6841    /* + counter for applying the V criterion */
6842    strat->cv++;
6843    return;
6844  }
6845
6846  const BOOLEAN bIsPluralRing = rIsPluralRing(currRing);
6847  const BOOLEAN bIsSCA        = rIsSCA(currRing) && strat->z2homog; // for prod-crit
6848  const BOOLEAN bNCProdCrit   = ( !bIsPluralRing || bIsSCA ); // commutative or homogeneous SCA
6849
6850  if (strat->sugarCrit && bNCProdCrit)
6851  {
6852    if((!((ecartq>0)&&(ecart>0)))
6853    && pHasNotCF(p,q))
6854    {
6855    /*
6856    *the product criterion has applied for (s,p),
6857    *i.e. lcm(s,p)=product of the leading terms of s and p.
6858    *Suppose (s,r) is in L and the leading term
6859    *of p divides lcm(s,r)
6860    *(==> the leading term of p divides the leading term of r)
6861    *but the leading term of s does not divide the leading term of r
6862    *(notice that this condition is automatically satisfied if r is still
6863    *in S), then (s,r) can be cancelled.
6864    *This should be done here because the
6865    *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
6866    *
6867    *Moreover, skipping (s,r) holds also for the noncommutative case.
6868    */
6869      strat->cp++;
6870      pLmFree(Lp.lcm);
6871      Lp.lcm=NULL;
6872      return;
6873    }
6874    else
6875      Lp.ecart = si_max(ecart,ecartq);
6876    if (strat->fromT && (ecartq>ecart))
6877    {
6878      pLmFree(Lp.lcm);
6879      Lp.lcm=NULL;
6880      return;
6881      /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
6882    }
6883    /*
6884    *the set B collects the pairs of type (S[j],p)
6885    *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
6886    *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
6887    *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
6888    */
6889    {
6890      j = strat->Bl;
6891      loop
6892      {
6893        if (j < 0)  break;
6894        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
6895        if ((compare==1)
6896        &&(sugarDivisibleBy(strat->B[j].ecart,Lp.ecart)))
6897        {
6898          strat->c3++;
6899          if ((strat->fromQ==NULL) || (isFromQ==0) || (qfromQ==0))
6900          {
6901            pLmFree(Lp.lcm);
6902            return;
6903          }
6904          break;
6905        }
6906        else
6907        if ((compare ==-1)
6908        && sugarDivisibleBy(Lp.ecart,strat->B[j].ecart))
6909        {
6910          deleteInL(strat->B,&strat->Bl,j,strat);
6911          strat->c3++;
6912        }
6913        j--;
6914      }
6915    }
6916  }
6917  else /*sugarcrit*/
6918  {
6919    if (bNCProdCrit)
6920    {
6921      // if currRing->nc_type!=quasi (or skew)
6922      // TODO: enable productCrit for super commutative algebras...
6923      if(/*(strat->ak==0) && productCrit(p,strat->S[i])*/
6924      pHasNotCF(p,q))
6925      {
6926      /*
6927      *the product criterion has applied for (s,p),
6928      *i.e. lcm(s,p)=product of the leading terms of s and p.
6929      *Suppose (s,r) is in L and the leading term
6930      *of p devides lcm(s,r)
6931      *(==> the leading term of p devides the leading term of r)
6932      *but the leading term of s does not devide the leading term of r
6933      *(notice that tis condition is automatically satisfied if r is still
6934      *in S), then (s,r) can be canceled.
6935      *This should be done here because the
6936      *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
6937      */
6938          strat->cp++;
6939          pLmFree(Lp.lcm);
6940          Lp.lcm=NULL;
6941          return;
6942      }
6943      if (strat->fromT && (ecartq>ecart))
6944      {
6945        pLmFree(Lp.lcm);
6946        Lp.lcm=NULL;
6947        return;
6948        /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
6949      }
6950      /*
6951      *the set B collects the pairs of type (S[j],p)
6952      *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
6953      *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
6954      *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
6955      */
6956      for(j = strat->Bl;j>=0;j--)
6957      {
6958        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
6959        if (compare==1)
6960        {
6961          strat->c3++;
6962          if ((strat->fromQ==NULL) || (isFromQ==0) || (qfromQ==0))
6963          {
6964            pLmFree(Lp.lcm);
6965            return;
6966          }
6967          break;
6968        }
6969        else
6970        if (compare ==-1)
6971        {
6972          deleteInL(strat->B,&strat->Bl,j,strat);
6973          strat->c3++;
6974        }
6975      }
6976    }
6977  }
6978  /*
6979  *the pair (S[i],p) enters B if the spoly != 0
6980  */
6981  /*-  compute the short s-polynomial -*/
6982  if (strat->fromT && !TEST_OPT_INTSTRATEGY)
6983    pNorm(p);
6984  if ((q==NULL) || (p==NULL))
6985    return;
6986  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (qfromQ!=0))
6987    Lp.p=NULL;
6988  else
6989  {
6990//     if ( bIsPluralRing )
6991//     {
6992//       if(pHasNotCF(p, q))
6993//       {
6994//         if(ncRingType(currRing) == nc_lie)
6995//         {
6996//             // generalized prod-crit for lie-type
6997//             strat->cp++;
6998//             Lp.p = nc_p_Bracket_qq(pCopy(p),q);
6999//         }
7000//         else
7001//         if( bIsSCA )
7002//         {
7003//             // product criterion for homogeneous case in SCA
7004//             strat->cp++;
7005//             Lp.p = NULL;
7006//         }
7007//         else
7008//           Lp.p = nc_CreateSpoly(q,p,currRing); // ?
7009//       }
7010//       else  Lp.p = nc_CreateSpoly(q,p,currRing);
7011//     }
7012//     else
7013//     {
7014   
7015    /* ksCreateShortSpoly needs two Lobject-kind presentations */
7016    /* p is already in this form, so convert q */
7017    //    q = pMove2CurrTail(q, strat);
7018    Lp.p = ksCreateShortSpoly(q, p, strat->tailRing);
7019      //  }
7020  }
7021  if (Lp.p == NULL)
7022  {
7023    /*- the case that the s-poly is 0 -*/
7024    /* TEMPORARILY DISABLED FOR SHIFTS because there is no i*/
7025//      if (strat->pairtest==NULL) initPairtest(strat);
7026//      strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
7027//      strat->pairtest[strat->sl+1] = TRUE;
7028    /* END _ TEMPORARILY DISABLED FOR SHIFTS */
7029    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
7030    /*
7031    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
7032    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
7033    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
7034    *term of p devides the lcm(s,r)
7035    *(this canceling should be done here because
7036    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
7037    *the first case is handeled in chainCrit
7038    */
7039    if (Lp.lcm!=NULL) pLmFree(Lp.lcm);
7040  }
7041  else
7042  {
7043    /*- the pair (S[i],p) enters B -*/
7044    /* both of them should have their LM in currRing and TAIL in tailring */
7045    Lp.p1 = q;  // already in the needed form
7046    Lp.p2 = p; // already in the needed form
7047
7048    if ( !bIsPluralRing )
7049      pNext(Lp.p) = strat->tail;
7050
7051    /* TEMPORARILY DISABLED FOR SHIFTS because there's no i*/
7052    /* at the beginning we DO NOT set atR = -1 ANYMORE*/
7053    if ( (atR >= 0) && (shiftcount==0) && (ifromS >=0) )
7054    {
7055      Lp.i_r1 = kFindInT(Lp.p1,strat); //strat->S_2_R[ifromS];
7056      Lp.i_r2 = atR;
7057    }
7058    else
7059    {
7060      /* END _ TEMPORARILY DISABLED FOR SHIFTS */
7061      Lp.i_r1 = -1;
7062      Lp.i_r2 = -1;
7063     }
7064    strat->initEcartPair(&Lp,q,p,ecartq,ecart);
7065
7066    if (TEST_OPT_INTSTRATEGY)
7067    {
7068      if (!bIsPluralRing)
7069        nDelete(&(Lp.p->coef));
7070    }
7071
7072    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
7073    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
7074  }
7075}
7076#endif
7077
7078#ifdef HAVE_SHIFTBBA
7079/*2
7080*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
7081*superfluous elements in S will be deleted
7082*/
7083void enterpairsShift (poly h,int k,int ecart,int pos,kStrategy strat, int atR,int uptodeg, int lV)
7084{
7085  /* h is strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
7086  /* Q: what is exactly the strat->fromT ? A: a local case trick; don't need it yet*/
7087  int j=pos;
7088
7089#ifdef HAVE_RINGS
7090  assume (!rField_is_Ring(currRing));
7091#endif
7092  initenterpairsShift(h,k,ecart,0,strat, atR,uptodeg,lV);
7093  if ( (!strat->fromT)
7094  && ((strat->syzComp==0)
7095    ||(pGetComp(h)<=strat->syzComp)))
7096  {
7097    //Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
7098    unsigned long h_sev = pGetShortExpVector(h);
7099    loop
7100    {
7101      if (j > k) break;
7102      clearS(h,h_sev, &j,&k,strat);
7103      j++;
7104    }
7105    //Print("end clearS sl=%d\n",strat->sl);
7106  }
7107 // PrintS("end enterpairs\n");
7108}
7109#endif
7110
7111#ifdef HAVE_SHIFTBBA
7112/*3
7113*(s[0], s \dot h),...,(s[k],s \dot h) will be put to the pairset L
7114* also the pairs (h, s\dot s[0]), ..., (h, s\dot s[k]) enter L
7115* additionally we put the pairs (h, s \sdot h) for s>=1 to L
7116*/
7117void initenterpairsShift (poly h,int k,int ecart,int isFromQ, kStrategy strat, int atR, int uptodeg, int lV)
7118{
7119  /* h comes from strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
7120  //  atR = -1;
7121  if ((strat->syzComp==0)
7122  || (pGetComp(h)<=strat->syzComp))
7123  {
7124    int j;
7125    BOOLEAN new_pair=FALSE;
7126
7127    if (pGetComp(h)==0)
7128    {
7129      /* for Q!=NULL: build pairs (f,q),(f1,f2), but not (q1,q2)*/
7130      if ((isFromQ)&&(strat->fromQ!=NULL))
7131      {
7132        for (j=0; j<=k; j++)
7133        {
7134          if (!strat->fromQ[j])
7135          {
7136            new_pair=TRUE;
7137            enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR,uptodeg,lV);
7138            // other side pairs:
7139            enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
7140          //Print("j:%d, Ll:%d\n",j,strat->Ll);
7141          }
7142        }
7143      }
7144      else
7145      {
7146        new_pair=TRUE;
7147        for (j=0; j<=k; j++)
7148        {
7149          enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR,uptodeg,lV);
7150          // other side pairs
7151          enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
7152        }
7153        /* HERE we put (h, s*h) pairs */
7154       /* enterOnePairSelfShifts (poly qq, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int uptodeg, int lV); */
7155       enterOnePairSelfShifts (h, h, ecart, isFromQ, strat, atR, uptodeg, lV);
7156      }
7157    }
7158    else
7159    {
7160      for (j=0; j<=k; j++)
7161      {
7162        if ((pGetComp(h)==pGetComp(strat->S[j]))
7163        || (pGetComp(strat->S[j])==0))
7164        {
7165          new_pair=TRUE;
7166          enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR, uptodeg, lV);
7167          // other side pairs
7168          enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
7169        //Print("j:%d, Ll:%d\n",j,strat->Ll);
7170        }
7171      }
7172      /* HERE we put (h, s*h) pairs */
7173      enterOnePairSelfShifts (h, h, ecart, isFromQ, strat, atR, uptodeg, lV);
7174    }
7175
7176    if (new_pair)
7177    {
7178#ifdef HAVE_PLURAL
7179      if (currRing->real_var_start>0)
7180        chainCritPart(h,ecart,strat);
7181      else
7182#endif
7183      chainCrit(h,ecart,strat);
7184    }
7185
7186  }
7187}
7188#endif
7189
7190#ifdef HAVE_SHIFTBBA
7191/*2
7192* puts p to the set T, starting with the at position atT
7193* and inserts all admissible shifts of p
7194*/
7195void enterTShift(LObject p, kStrategy strat, int atT, int uptodeg, int lV)
7196{
7197  /* determine how many elements we have to insert */
7198  /* x(0)y(1)z(2) : lastVblock-1=2, to add until lastVblock=uptodeg-1 */
7199  /* hence, a total number of elt's to add is: */
7200  /*  int toInsert = 1 + (uptodeg-1) - (pLastVblock(p.p, lV) -1);  */
7201
7202  int toInsert =  itoInsert(p.p, uptodeg,  lV, strat->tailRing);
7203
7204#ifdef PDEBUG
7205  //  Print("enterTShift uses toInsert: %d", toInsert);  PrintLn();
7206#endif
7207  int i;
7208
7209  if (atT < 0)
7210    atT = strat->posInT(strat->T, strat->tl, p);
7211 
7212  /* can call enterT in a sequence, e.g. */
7213
7214  /* shift0 = it's our model for further shifts */
7215  enterT(p,strat,atT);
7216  LObject qq;
7217  for (i=1; i<=toInsert; i++) // toIns - 1?
7218  {
7219    qq      = p; //qq.Copy();
7220    qq.p    = NULL; 
7221    qq.max  = NULL;
7222    qq.t_p = p_LPshift(p_Copy(p.t_p,strat->tailRing), i, uptodeg, lV, strat->tailRing); // direct shift
7223    qq.GetP();
7224    // update q.sev
7225    qq.sev = pGetShortExpVector(qq.p);
7226    /* enter it into T, first el't is with the shift 0 */
7227    // compute the position for qq
7228    atT = strat->posInT(strat->T, strat->tl, qq);
7229    enterT(qq,strat,atT);
7230  }
7231/* Q: what to do with this one in the orig enterT ? */
7232/*  strat->R[strat->tl] = &(strat->T[atT]); */
7233/* Solution: it is done by enterT each time separately */
7234}
7235#endif
7236
7237#ifdef HAVE_SHIFTBBA
7238poly redtailBbaShift (LObject* L, int pos, kStrategy strat, BOOLEAN withT, BOOLEAN normalize)
7239{
7240  /* for the shift case need to run it with withT = TRUE */
7241  strat->redTailChange=FALSE;
7242  if (strat->noTailReduction) return L->GetLmCurrRing();
7243  poly h, p;
7244  p = h = L->GetLmTailRing();
7245  if ((h==NULL) || (pNext(h)==NULL))
7246    return L->GetLmCurrRing();
7247
7248  TObject* With;
7249  // placeholder in case strat->tl < 0
7250  TObject  With_s(strat->tailRing);
7251
7252  LObject Ln(pNext(h), strat->tailRing);
7253  Ln.pLength = L->GetpLength() - 1;
7254
7255  pNext(h) = NULL;
7256  if (L->p != NULL) pNext(L->p) = NULL;
7257  L->pLength = 1;
7258
7259  Ln.PrepareRed(strat->use_buckets);
7260
7261  while(!Ln.IsNull())
7262  {
7263    loop
7264    {
7265      Ln.SetShortExpVector();
7266      if (withT)
7267      {
7268        int j;
7269        j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln);
7270        if (j < 0) break;
7271        With = &(strat->T[j]);
7272      }
7273      else
7274      {
7275        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
7276        if (With == NULL) break;
7277      }
7278      if (normalize && (!TEST_OPT_INTSTRATEGY) && (!nIsOne(pGetCoeff(With->p))))
7279      {
7280        With->pNorm();
7281        //if (TEST_OPT_PROT) { PrintS("n"); mflush(); }
7282      }
7283      strat->redTailChange=TRUE;
7284      if (ksReducePolyTail(L, With, &Ln))
7285      {
7286        // reducing the tail would violate the exp bound
7287        //  set a flag and hope for a retry (in bba)
7288        strat->completeReduce_retry=TRUE;
7289        do
7290        {
7291          pNext(h) = Ln.LmExtractAndIter();
7292          pIter(h);
7293          L->pLength++;
7294        } while (!Ln.IsNull());
7295        goto all_done;
7296      }
7297      if (Ln.IsNull()) goto all_done;
7298      if (! withT) With_s.Init(currRing);
7299    }
7300    pNext(h) = Ln.LmExtractAndIter();
7301    pIter(h);
7302    L->pLength++;
7303  }
7304
7305  all_done:
7306  Ln.Delete();
7307  if (L->p != NULL) pNext(L->p) = pNext(p);
7308
7309  if (strat->redTailChange)
7310  {
7311    L->last = NULL;
7312    L->length = 0;
7313  }
7314  L->Normalize(); // HANNES: should have a test
7315  kTest_L(L);
7316  return L->GetLmCurrRing();
7317}
7318#endif
Note: See TracBrowser for help on using the repository browser.