source: git/kernel/kutil.cc @ 1e579c6

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