source: git/kernel/kutil.cc @ d945f3

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