source: git/kernel/kutil.cc @ a2466f

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