source: git/kernel/kutil.cc @ 3a67ea7

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