source: git/kernel/kutil.cc @ 6ad5ce

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