source: git/kernel/kutil.cc @ d2bf50

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