source: git/Singular/kutil.cc @ 6b32990

spielwiese
Last change on this file since 6b32990 was 6b32990, checked in by Olaf Bachmann <obachman@…>, 23 years ago
* dynamic kernel modules for MP and DBM links * p_Procs improvements git-svn-id: file:///usr/local/Singular/svn/trunk@4865 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 97.6 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: kutil.cc,v 1.82 2000-12-12 08:44:46 obachman 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 <limits.h>
15#include <stdlib.h>
16#include <string.h>
17#include "mod2.h"
18#ifdef KDEBUG
19#undef KDEBUG
20#define KDEBUG 2
21#endif
22
23// define if enterL, enterT should use memmove instead of doing it manually
24// on topgun, this is slightly faster (see monodromy_l.tst, homog_gonnet.sing)
25#define ENTER_USE_MEMMOVE
26
27// define, if the my_memmove inlines should be used instead of
28// system memmove -- it does not seem to pay off, though
29// #define ENTER_USE_MYMEMMOVE
30
31#include "tok.h"
32#include "kutil.h"
33#include "febase.h"
34#include "omalloc.h"
35#include "numbers.h"
36#include "polys.h"
37#include "ring.h"
38#include "ideals.h"
39#include "timer.h"
40#include "cntrlc.h"
41#include "stairc.h"
42#include "subexpr.h"
43#include "kstd1.h"
44#include "pShallowCopyDelete.h"
45
46#ifdef KDEBUG
47#undef KDEBUG
48#define KDEBUG 2
49#endif
50
51#ifdef ENTER_USE_MYMEMMOVE
52inline void _my_memmove_d_gt_s(unsigned long* d, unsigned long* s, long l)
53{
54  register unsigned long* _dl = (unsigned long*) d;
55  register unsigned long* _sl = (unsigned long*) s;
56  register long _i = l - 1;
57
58  do
59  {
60    _dl[_i] = _sl[_i];
61    _i--;
62  }
63  while (_i >= 0);
64}
65
66inline void _my_memmove_d_lt_s(unsigned long* d, unsigned long* s, long l)
67{
68  register long _ll = l;
69  register unsigned long* _dl = (unsigned long*) d;
70  register unsigned long* _sl = (unsigned long*) s;
71  register long _i = 0;
72
73  do
74  {
75    _dl[_i] = _sl[_i];
76    _i++;
77  }
78  while (_i < _ll);
79}
80
81inline void _my_memmove(void* d, void* s, long l)
82{
83  unsigned long _d = (unsigned long) d;
84  unsigned long _s = (unsigned long) s;
85  unsigned long _l = ((l) + SIZEOF_LONG - 1) >> LOG_SIZEOF_LONG;
86
87  if (_d > _s) _my_memmove_d_gt_s(_d, _s, _l);
88  else _my_memmove_d_lt_s(_d, _s, _l);
89}
90
91#undef memmove
92#define memmove(d,s,l) _my_memmove(d, s, l)
93#endif
94
95
96static poly redMora (poly h,int maxIndex,kStrategy strat);
97static poly redBba (poly h,int maxIndex,kStrategy strat);
98
99static inline int pDivComp(poly p, poly q)
100{
101  if (pGetComp(p) == pGetComp(q))
102  {
103    BOOLEAN a=FALSE, b=FALSE;
104    int i;
105    unsigned long la, lb;
106    unsigned long divmask = currRing->divmask;
107    for (i=0; i<currRing->VarL_Size; i++)
108    {
109      la = p->exp[currRing->VarL_Offset[i]];
110      lb = q->exp[currRing->VarL_Offset[i]];
111      if (la != lb)
112      {
113        if (la < lb)
114        {
115          if (b) return 0;
116          if (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask))
117            return 0;
118          a = TRUE;
119        }
120        else
121        {
122          if (a) return 0;
123          if (((la & divmask) ^ (lb & divmask)) != ((la - lb) & divmask))
124            return 0;
125          b = TRUE;
126        }
127      }
128    }
129    if (a) return 1;
130    if (b) return -1;
131  }
132  return 0;
133}
134
135
136BITSET  test=(BITSET)0;
137int     HCord;
138int     Kstd1_deg;
139int     mu=32000;
140
141/*2
142*deletes higher monomial of p, re-compute ecart and length
143*works only for orderings with ecart =pFDeg(end)-pFDeg(start)
144*/
145void deleteHC(LObject *L, kStrategy strat, BOOLEAN fromNext)
146{
147  if (strat->kHEdgeFound)
148  {
149    kTest_L(L);
150    poly p1;
151    poly p = L->GetLmTailRing();
152    int l = 1;
153    kBucket_pt bucket = NULL;
154    if (L->bucket != NULL)
155    {
156      kBucketClear(L->bucket, &pNext(p), &L->pLength);
157      L->pLength++;
158      bucket = L->bucket;
159      L->bucket = NULL;
160      L->last = NULL;
161    }
162
163    if (!fromNext && p_Cmp(p,strat->kNoether, L->tailRing) == -1)
164    {
165      L->Delete();
166      L->Clear();
167      L->ecart = -1;
168      if (bucket != NULL) kBucketDestroy(&bucket);
169      return;
170    }
171    p1 = p;
172    while (pNext(p1)!=NULL)
173    { 
174      if (p_LmCmp(pNext(p1), strat->kNoether, L->tailRing) == -1)
175      {
176        L->last = p1;
177        p_Delete(&pNext(p1), L->tailRing);
178        if (p1 == p)
179        {
180          if (L->t_p != NULL)
181          {
182            assume(L->p != NULL && p == L->t_p);
183            pNext(L->p) = NULL;
184          }
185        }
186        if (L->pLength != 0) L->pLength = l;
187        // Hmmm when called from updateT, then only
188        // reset ecart when cut
189        if (fromNext)
190          L->ecart = L->pLDeg() - L->GetpFDeg();
191        break;
192      }
193      l++;
194      pIter(p1);
195    }
196    if (! fromNext)
197    {
198      L->SetpFDeg();
199      L->ecart = L->pLDeg(strat->LDegLast) - L->GetpFDeg();
200    }
201    if (bucket != NULL)
202    {
203      if (L->pLength > 1) 
204      {
205        kBucketInit(bucket, pNext(p), L->pLength - 1);
206        pNext(p) = NULL;
207        if (L->t_p != NULL) pNext(L->t_p) = NULL;
208        L->pLength = 0;
209        L->bucket = bucket;
210        L->last = NULL;
211      }
212      else
213        kBucketDestroy(&bucket);
214    }
215    kTest_L(L);
216  }
217}
218
219void deleteHC(poly* p, int* e, int* l,kStrategy strat)
220{
221  LObject L(*p, currRing, strat->tailRing);
222
223  deleteHC(&L, strat);
224  *p = L.p;
225  *e = L.ecart;
226  *l = L.length;
227  if (L.t_p != NULL) p_LmFree(L.t_p, strat->tailRing);
228}
229
230/*2
231*tests if p.p=monomial*unit and cancels the unit
232*/
233void cancelunit (LObject* L)
234{
235  int  i;
236  poly h;
237  ring r = L->tailRing;
238  poly p = L->GetLmTailRing();
239
240  if(p_GetComp(p, r) != 0 && !p_OneComp(p, r)) return;
241
242  if (L->ecart != 0)
243  {
244    for(i=1;i<=r->N;i++)
245    {
246      if ((p_GetExp(p,i,r)>0) && (rIsPolyVar(i, r)==TRUE)) return;
247    }
248    h = pNext(p);
249    loop
250    {
251      if (h==NULL)
252      {
253        p_Delete(&pNext(p), r);
254        L->ecart = 0;
255        L->length = 1;
256        if (L->pLength > 0) L->pLength = 1;
257        if (L->last != NULL) L->last = p;
258
259        if (L->t_p != NULL && pNext(L->t_p) != NULL)
260          pNext(L->t_p) = NULL;
261        if (L->p != NULL && pNext(L->p) != NULL)
262          pNext(L->p) = NULL;
263        return;
264      }
265      i = 0;
266      loop
267      {
268        i++;
269        if (p_GetExp(p,i,r) > p_GetExp(h,i,r)) return ;
270        if (i == r->N) break;
271      }
272      pIter(h);
273    }
274  }
275}
276
277/*2
278*pp is the new element in s
279*returns TRUE (in strat->kHEdgeFound) if
280*-HEcke is allowed
281*-we are in the last componente of the vector
282*-on all axis are monomials (all elements in NotUsedAxis are FALSE)
283*returns FALSE for pLexOrderings,
284*assumes in module case an ordering of type c* !!
285* HEckeTest is only called with strat->kHEdgeFound==FALSE !
286*/
287void HEckeTest (poly pp,kStrategy strat)
288{
289  int   j,k,p;
290
291  strat->kHEdgeFound=FALSE;
292  if (pLexOrder)
293  {
294    return;
295  }
296  if (strat->ak > 1)           /*we are in the module case*/
297  {
298    return; // until ....
299    //if (!pVectorOut)     /*pVectorOut <=> order = c,* */
300    //  return FALSE;
301    //if (pGetComp(pp) < strat->ak) /* ak is the number of the last component */
302    //  return FALSE;
303  }
304  k = 0;
305  p=pIsPurePower(pp);
306  if (p!=0) strat->NotUsedAxis[p] = FALSE;
307  /*- the leading term of pp is a power of the p-th variable -*/
308  for (j=pVariables;j>0; j--)
309  {
310    if (strat->NotUsedAxis[j])
311    {
312      return;
313    }
314  }
315  strat->kHEdgeFound=TRUE;
316}
317
318/*2
319*utilities for TSet, LSet
320*/
321inline static intset initec (int maxnr)
322{
323  return (intset)omAlloc(maxnr*sizeof(int));
324}
325
326inline static unsigned long* initsevS (int maxnr)
327{
328  return (unsigned long*)omAlloc0(maxnr*sizeof(unsigned long));
329}
330inline static int* initS_2_R (int maxnr)
331{
332  return (int*)omAlloc0(maxnr*sizeof(int));
333}
334
335static inline void enlargeT (TSet &T, TObject** &R, unsigned long* &sevT,
336                             int &length, int incr)
337{
338  int i;
339  T = (TSet)omrealloc0Size(T, length*sizeof(TObject), 
340                           (length+incr)*sizeof(TObject));
341
342  sevT = (unsigned long*) omreallocSize(sevT, length*sizeof(long*), 
343                           (length+incr)*sizeof(long*));
344
345  R = (TObject**)omrealloc0Size(R,length*sizeof(TObject*),
346                                (length+incr)*sizeof(TObject*));
347  for (i=0;i<length;i++) R[T[i].i_r] = &(T[i]);
348  length += incr;
349}
350
351void cleanT (kStrategy strat)
352{
353  int i,j;
354  poly  p;
355  assume(currRing == strat->tailRing || strat->tailRing != NULL);
356
357  pShallowCopyDeleteProc p_shallow_copy_delete = 
358    (strat->tailRing != currRing ? 
359     pGetShallowCopyDeleteProc(strat->tailRing, currRing) :
360     NULL);
361
362  for (j=0; j<=strat->tl; j++)
363  {
364    p = strat->T[j].p;
365    strat->T[j].p=NULL;
366    if (strat->T[j].max != NULL) 
367      p_LmFree(strat->T[j].max, strat->tailRing);
368    i = -1;
369    loop
370    {
371      i++;
372      if (i>strat->sl)
373      {
374        if (strat->T[j].t_p != NULL)
375        {
376          p_Delete(&(strat->T[j].t_p), strat->tailRing);
377          p_LmFree(p, currRing);
378        }
379        else
380          pDelete(&p);
381        break;
382      }
383      if (p == strat->S[i])
384      {
385        if (strat->T[j].t_p != NULL)
386        {
387          assume(p_shallow_copy_delete != NULL);
388          pNext(p) = p_shallow_copy_delete(pNext(p),strat->tailRing,currRing, 
389                                           currRing->PolyBin);
390          p_LmFree(strat->T[j].t_p, strat->tailRing);
391        }
392        break;
393      }
394    }
395  }
396  strat->tl=-1;
397}
398
399LSet initL ()
400{
401  int i;
402  LSet l = (LSet)omAlloc(setmax*sizeof(LObject));
403  for (i=0;i<setmax;i++)
404  {
405    l[i].tailRing = currRing;
406    l[i].i_r1 = -1;
407    l[i].i_r2 = -1;
408    l[i].i_r = -1;
409  }
410  return l;
411}
412
413static inline void enlargeL (LSet* L,int* length,int incr)
414{
415  LSet h;
416
417  *L = (LSet)omReallocSize((*L),(*length)*sizeof(LObject),
418                                   ((*length)+incr)*sizeof(LObject));
419  (*length) += incr;
420}
421
422void initPairtest(kStrategy strat)
423{
424  strat->pairtest = (BOOLEAN *)omAlloc0((strat->sl+2)*sizeof(BOOLEAN));
425}
426
427/*2
428*test whether (p1,p2) or (p2,p1) is in L up position length
429*it returns TRUE if yes and the position k
430*/
431BOOLEAN isInPairsetL(int length,poly p1,poly p2,int*  k,kStrategy strat)
432{
433  LObject *p=&(strat->L[length]);
434
435  *k = length;
436  loop
437  {
438    if ((*k) < 0) return FALSE;
439    if (((p1 == (*p).p1) && (p2 == (*p).p2))
440    ||  ((p1 == (*p).p2) && (p2 == (*p).p1)))
441      return TRUE;
442    (*k)--;
443    p--;
444  }
445}
446
447/*2
448*in B all pairs have the same element p on the right
449*it tests whether (q,p) is in B and returns TRUE if yes
450*and the position k
451*/
452BOOLEAN isInPairsetB(poly q,int*  k,kStrategy strat)
453{
454  LObject *p=&(strat->B[strat->Bl]);
455
456  *k = strat->Bl;
457  loop
458  {
459    if ((*k) < 0) return FALSE;
460    if (q == (*p).p1)
461      return TRUE;
462    (*k)--;
463    p--;
464  }
465}
466
467int kFindInT(poly p, TSet T, int tlength)
468{
469  int i;
470
471  for (i=0; i<=tlength; i++)
472  {
473    if (T[i].p == p) return i;
474  }
475  return -1;
476}
477
478int kFindInT(poly p, kStrategy strat)
479{
480  int i;
481  do
482  {
483    i = kFindInT(p, strat->T, strat->tl);
484    if (i >= 0) return i;
485    strat = strat->next;
486  }
487  while (strat != NULL);
488  return -1;
489}
490 
491#ifdef KDEBUG
492
493void sTObject::wrp()
494{
495  if (t_p != NULL) p_wrp(t_p, tailRing);
496  else if (p != NULL) p_wrp(p, currRing, tailRing);
497  else ::wrp(NULL);
498}
499
500#define kFalseReturn(x) do { if (!x) return FALSE;} while (0)
501
502// check that Lm's of a poly from T are "equal"
503static const char* kTest_LmEqual(poly p, poly t_p, ring tailRing)
504{
505  int i;
506  for (i=1; i<=tailRing->N; i++)
507  {
508    if (p_GetExp(p, i, currRing) != p_GetExp(t_p, i, tailRing))
509      return "Lm[i] different";
510  }
511  if (p_GetComp(p, currRing) != p_GetComp(t_p, tailRing))
512    return "Lm[0] different";
513  if (pNext(p) != pNext(t_p))
514    return "Lm.next different";
515  if (pGetCoeff(p) != pGetCoeff(t_p))
516    return "Lm.coeff different";
517  return NULL;
518}
519
520BOOLEAN kTest_T(TObject * T, ring strat_tailRing, int i, char TN)
521{
522  ring tailRing = T->tailRing;
523  if (strat_tailRing == NULL) strat_tailRing = tailRing;
524  r_assume(strat_tailRing == tailRing);
525
526  poly p = T->p;
527  ring r = currRing;
528 
529  if (T->p == NULL && T->t_p == NULL && i >= 0)
530    return dReportError("%c[%d].poly is NULL", TN, i);
531
532  if (T->tailRing != currRing)
533  {
534    if (T->t_p == NULL && i > 0)
535      return dReportError("%c[%d].t_p is NULL", TN, i);
536    pFalseReturn(p_Test(T->t_p, T->tailRing));
537    if (T->p != NULL) pFalseReturn(p_LmTest(T->p, currRing));
538    if (T->p != NULL && T->t_p != NULL)
539    {
540      const char* msg = kTest_LmEqual(T->p, T->t_p, T->tailRing);
541      if (msg != NULL)
542        return dReportError("%c[%d] %s", TN, i, msg);
543      r = T->tailRing;
544      p = T->t_p;
545    }
546    if (T->p == NULL)
547    {
548      p = T->t_p;
549      r = T->tailRing;
550    }
551    if (T->t_p != NULL && i >= 0 && TN == 'T')
552    {
553      if (pNext(T->t_p) == NULL)
554      {
555        if (T->max != NULL)
556          return dReportError("%c[%d].max is not NULL as it should be", TN, i);
557      }
558      else
559      {
560        if (T->max == NULL)
561          return dReportError("%c[%d].max is NULL", TN, i);
562        if (pNext(T->max) != NULL)
563          return dReportError("pNext(%c[%d].max) != NULL", TN, i);
564       
565        pFalseReturn(p_CheckPolyRing(T->max, tailRing));
566        omCheckBinAddrSize(T->max, (tailRing->PolyBin->sizeW)*SIZEOF_LONG);
567#if KDEBUG > 0
568        poly test_max = p_GetMaxExpP(pNext(T->t_p), tailRing);
569        p_Setm(T->max, tailRing);
570        p_Setm(test_max, tailRing);
571        BOOLEAN equal = p_ExpVectorEqual(T->max, test_max, tailRing);
572        if (! equal)
573          return dReportError("%c[%d].max out of sync", TN, i);
574        p_LmFree(test_max, tailRing);
575#endif
576      }
577    }
578  }
579  else
580  {
581    if (T->max != NULL) 
582      return dReportError("%c[%d].max != NULL but tailRing == currRing",TN,i);
583    if (T->t_p != NULL)
584      return dReportError("%c[%d].t_p != NULL but tailRing == currRing",TN,i);
585    if (T->p == NULL && i > 0)
586      return dReportError("%c[%d].p is NULL", TN, i);
587    pFalseReturn(p_Test(T->p, currRing));
588  }
589
590  if (i >= 0 && T->pLength != 0 && T->pLength != pLength(p))
591  {
592    return dReportError("%c[%d] pLength error: has %d, specified to have %d",
593                        TN, i , pLength(p), T->pLength);
594  }
595
596  // check FDeg,  for elements in L and T
597  if (i >= 0 && (TN == 'T' || TN == 'L'))
598  {
599    // FDeg has ir element from T of L set
600    if (T->FDeg  != T->pFDeg())
601      return dReportError("%c[%d] FDeg error: has %d, specified to have %d",
602                          TN, i , T->pFDeg(), T->FDeg);
603  }
604
605  // check is_normalized for elements in T
606  if (i >= 0 && TN == 'T')
607  {
608    if (T->is_normalized && ! nIsOne(pGetCoeff(p)))
609      return dReportError("T[%d] is_normalized error", i);
610
611  }
612  return TRUE;
613}
614
615BOOLEAN kTest_L(LObject *L, ring strat_tailRing, 
616                BOOLEAN testp, int lpos, TSet T, int tlength)
617{
618  if (testp)
619  {
620    poly pn = NULL;
621    if (L->bucket != NULL)
622    {
623      kFalseReturn(kbTest(L->bucket));
624      r_assume(L->bucket->bucket_ring == L->tailRing);
625      if (L->p != NULL && pNext(L->p) != NULL)
626      {
627        pn = pNext(L->p);
628        pNext(L->p) = NULL;
629      }
630    }
631    kFalseReturn(kTest_T(L, strat_tailRing, lpos, 'L'));
632    if (pn != NULL)
633      pNext(L->p) = pn;
634
635    ring r;
636    poly p;
637    L->GetLm(p, r);
638    if (L->sev != 0 && p_GetShortExpVector(p, r) != L->sev)
639    {
640      return dReportError("L[%d] wrong sev: has %o, specified to have %o",
641                          lpos, p_GetShortExpVector(p, r), L->sev);
642    }
643    if (lpos > 0 && L->last != NULL && pLast(p) != L->last)
644    {
645      return dReportError("L[%d] last wrong: has %p specified to have %p",
646                          lpos, pLast(p), L->last);
647    }
648  }
649  r_assume(L->max == NULL);
650  if (L->p1 == NULL)
651  {
652    // L->p2 either NULL or "normal" poly
653    pFalseReturn(pp_Test(L->p2, currRing, L->tailRing));
654  }
655  else if (tlength > 0 && T != NULL)
656  {
657    // now p1 and p2 must be != NULL and must be contained in T
658    int i;
659    i = kFindInT(L->p1, T, tlength);
660    if (i < 0)
661      return dReportError("L[%d].p1 not in T",lpos);
662    i = kFindInT(L->p2, T, tlength);
663    if (i < 0)
664      return dReportError("L[%d].p2 not in T",lpos);
665  }
666  return TRUE;
667}
668
669BOOLEAN kTest (kStrategy strat)
670{
671  int i;
672
673  // test P
674  kFalseReturn(kTest_L(&(strat->P), strat->tailRing,
675                       (strat->P.p != NULL && pNext(strat->P.p)!=strat->tail),
676                       -1, strat->T, strat->tl));
677
678  // test T
679  if (strat->T != NULL)
680  {
681    for (i=0; i<=strat->tl; i++)
682    {
683      kFalseReturn(kTest_T(&(strat->T[i]), strat->tailRing, i, 'T'));
684      if (strat->sevT[i] != pGetShortExpVector(strat->T[i].p))
685        return dReportError("strat->sevT[%d] out of sync", i);
686    }
687  }
688 
689  // test L
690  if (strat->L != NULL)
691  {
692    for (i=0; i<=strat->Ll; i++)
693    {
694      kFalseReturn(kTest_L(&(strat->L[i]), strat->tailRing,
695                           (pNext(strat->L[i].p) != strat->tail), i,
696                           strat->T, strat->tl));
697      if (strat->use_buckets && pNext(strat->L[i].p) != strat->tail && 
698          strat->L[i].p1 != NULL)
699      {
700        assume(strat->L[i].bucket != NULL);
701      }
702    }
703  }
704 
705  // test S
706  if (strat->S != NULL)
707    kFalseReturn(kTest_S(strat));
708
709  return TRUE;
710}
711
712BOOLEAN kTest_S(kStrategy strat)
713{
714  int i;
715  BOOLEAN ret = TRUE;
716  for (i=0; i<=strat->sl; i++)
717  {
718    if (strat->S[i] != NULL && 
719        strat->sevS[i] != pGetShortExpVector(strat->S[i]))
720    {
721      return dReportError("S[%d] wrong sev: has %o, specified to have %o",
722                          i , pGetShortExpVector(strat->S[i]), strat->sevS[i]);
723    }
724  }
725  return ret;
726}
727
728
729
730BOOLEAN kTest_TS(kStrategy strat)
731{
732  int i, j;
733  BOOLEAN ret = TRUE;
734  kFalseReturn(kTest(strat));
735
736  // test strat->R, strat->T[i].i_r
737  for (i=0; i<=strat->tl; i++)
738  {
739    if (strat->T[i].i_r < 0 || strat->T[i].i_r > strat->tl)
740      return dReportError("strat->T[%d].i_r == %d out of bounds", i, 
741                          strat->T[i].i_r);
742    if (strat->R[strat->T[i].i_r] != &(strat->T[i]))
743      return dReportError("T[%d].i_r with R out of sync", i);
744  }   
745  // test containment of S inT
746  if (strat->S != NULL)
747  {
748    for (i=0; i<=strat->sl; i++)
749    {
750      j = kFindInT(strat->S[i], strat->T, strat->tl);
751      if (j < 0)
752        return dReportError("S[%d] not in T", i);
753      if (strat->S_2_R[i] != strat->T[j].i_r)
754        return dReportError("S_2_R[%d]=%d != T[%d].i_r=%d\n",
755                            i, strat->S_2_R[i], j, strat->T[j].i_r);
756    }
757  }
758  // test strat->L[i].i_r1
759  for (i=0; i<=strat->Ll; i++)
760  {
761    if (strat->L[i].p1 != NULL && strat->L[i].p2)
762    {
763      if (strat->L[i].i_r1 < 0 ||
764          strat->L[i].i_r1 > strat->tl ||
765          strat->L[i].T_1(strat)->p != strat->L[i].p1)
766        return dReportError("L[%d].i_r1 out of sync", i);
767      if (strat->L[i].i_r2 < 0 ||
768          strat->L[i].i_r2 > strat->tl ||
769          strat->L[i].T_2(strat)->p != strat->L[i].p2);
770    }
771    else
772    {
773      if (strat->L[i].i_r1 != -1)
774        return dReportError("L[%d].i_r1 out of sync", i);
775      if (strat->L[i].i_r2 != -1)
776        return dReportError("L[%d].i_r2 out of sync", i);
777    }
778  }
779  return TRUE;
780}
781
782#endif // KDEBUG
783
784/*2
785*cancels the i-th polynomial in the standardbase s
786*/
787void deleteInS (int i,kStrategy strat)
788{
789  int j;
790
791  for (j=i; j<strat->sl; j++)
792  {
793    strat->S[j] = strat->S[j+1];
794    strat->ecartS[j] = strat->ecartS[j+1];
795    strat->sevS[j] = strat->sevS[j+1];
796    strat->S_2_R[j] = strat->S_2_R[j+1];
797  }
798  if (strat->fromQ!=NULL)
799  {
800    for (j=i; j<strat->sl; j++)
801    {
802      strat->fromQ[j] = strat->fromQ[j+1];
803    }
804  }
805  strat->S[strat->sl] = NULL;
806  strat->sl--;
807}
808
809/*2
810*cancels the j-th polynomial in the set
811*/
812void deleteInL (LSet set, int *length, int j,kStrategy strat)
813{
814  if (set[j].lcm!=NULL)
815    pLmFree(set[j].lcm);
816  if (set[j].p!=NULL)
817  {
818    if (pNext(set[j].p) == strat->tail)
819    {
820      pLmFree(set[j].p);
821      /*- tail belongs to several int spolys -*/
822    }
823    else
824    {
825      // search p in T, if it is there, do not delete it
826      if (pOrdSgn != -1 || kFindInT(set[j].p, strat) < 0)
827      {
828        // assure that for global ordereings kFindInT fails
829        assume(pOrdSgn == -1 || kFindInT(set[j].p, strat) < 0);
830        set[j].Delete();
831      }
832    }
833  }
834  if (*length > 0 && j < *length)
835  {
836#ifdef ENTER_USE_MEMMOVE
837    memmove(&(set[j]), &(set[j+1]), (*length - j)*sizeof(LObject));
838#else   
839    int i;
840    for (i=j; i < (*length); i++)
841      set[i] = set[i+1];
842#endif
843  }
844#ifdef KDEBUG
845  memset(&(set[*length]),0,sizeof(LObject));
846#endif
847  (*length)--;
848}
849
850/*2
851*is used after updating the pairset,if the leading term of p
852*devides the leading term of some S[i] it will be canceled
853*/
854inline void clearS (poly p, unsigned long p_sev, int* at, int* k,
855                    kStrategy strat)
856{
857  assume(p_sev == pGetShortExpVector(p));
858  if (!pLmShortDivisibleBy(p,p_sev, strat->S[*at], ~ strat->sevS[*at])) return;
859  deleteInS((*at),strat);
860  (*at)--;
861  (*k)--;
862}
863
864/*2
865*enters p at position at in L
866*/
867void enterL (LSet *set,int *length, int *LSetmax, LObject p,int at)
868{
869  int i;
870  // this should be corrected
871  assume(p.FDeg == p.pFDeg());
872  if ((*length)>=0)
873  {
874    if ((*length) == (*LSetmax)-1) enlargeL(set,LSetmax,setmax);
875    if (at <= (*length))
876#ifdef ENTER_USE_MEMMOVE
877      memmove(&((*set)[at+1]), &((*set)[at]), ((*length)-at+1)*sizeof(LObject));
878#else
879    for (i=(*length)+1; i>=at+1; i--) (*set)[i] = (*set)[i-1];
880#endif
881  }
882  else at = 0;
883  (*set)[at] = p;
884  (*length)++;
885}
886
887/*2
888* computes the normal ecart;
889* used in mora case and if pLexOrder & sugar in bba case
890*/
891void initEcartNormal (LObject* h)
892{
893  h->FDeg = h->pFDeg();
894  h->ecart = h->pLDeg() - h->FDeg;
895}
896
897void initEcartBBA (LObject* h)
898{
899  h->FDeg = h->pFDeg();
900  (*h).ecart = 0;
901  (*h).length = 0;
902}
903
904void initEcartPairBba (LObject* Lp,poly f,poly g,int ecartF,int ecartG)
905{
906  Lp->FDeg = Lp->pFDeg();
907  (*Lp).ecart = 0;
908  (*Lp).length = 0;
909}
910
911void initEcartPairMora (LObject* Lp,poly f,poly g,int ecartF,int ecartG)
912{
913  Lp->FDeg = Lp->pFDeg();
914  (*Lp).ecart = max(ecartF,ecartG);
915  (*Lp).ecart = (*Lp).ecart- (Lp->FDeg -pFDeg((*Lp).lcm));
916  (*Lp).length = 0;
917}
918
919/*2
920*if ecart1<=ecart2 it returns TRUE
921*/
922BOOLEAN sugarDivisibleBy(int ecart1, int ecart2)
923{
924  return (ecart1 <= ecart2);
925}
926
927/*2
928* put the pair (s[i],p)  into the set B, ecart=ecart(p)
929*/
930void enterOnePair (int i,poly p,int ecart, int isFromQ,kStrategy strat, int atR = -1)
931{
932  assume(i<=strat->sl);
933
934  int      l,j,compare;
935  LObject  Lp;
936
937#ifdef KDEBUG
938  Lp.ecart=0; Lp.length=0;
939#endif
940  /*- computes the lcm(s[i],p) -*/
941  Lp.lcm = pInit();
942
943  pLcm(p,strat->S[i],Lp.lcm);
944  pSetm(Lp.lcm);
945  if (strat->sugarCrit)
946  {
947    if(
948    (!((strat->ecartS[i]>0)&&(ecart>0)))
949    && pHasNotCF(p,strat->S[i]))
950    {
951    /*
952    *the product criterion has applied for (s,p),
953    *i.e. lcm(s,p)=product of the leading terms of s and p.
954    *Suppose (s,r) is in L and the leading term
955    *of p devides lcm(s,r)
956    *(==> the leading term of p devides the leading term of r)
957    *but the leading term of s does not devide the leading term of r
958    *(notice that tis condition is automatically satisfied if r is still
959    *in S), then (s,r) can be canceled.
960    *This should be done here because the
961    *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
962    */
963      strat->cp++;
964      pLmFree(Lp.lcm);
965      Lp.lcm=NULL;
966      return;
967    }
968    else
969      Lp.ecart = max(ecart,strat->ecartS[i]);
970    if (strat->fromT && (strat->ecartS[i]>ecart))
971    {
972      pLmFree(Lp.lcm);
973      Lp.lcm=NULL;
974      return;
975      /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
976    }
977    /*
978    *the set B collects the pairs of type (S[j],p)
979    *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
980    *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
981    *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
982    */
983    {
984      j = strat->Bl;
985      loop
986      {
987        if (j < 0)  break;
988        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
989        if ((compare==1)
990        &&(sugarDivisibleBy(strat->B[j].ecart,Lp.ecart)))
991        {
992          strat->c3++;
993          if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
994          {
995            pLmFree(Lp.lcm);
996            return;
997          }
998          break;
999        }
1000        else
1001        if ((compare ==-1)
1002        && sugarDivisibleBy(Lp.ecart,strat->B[j].ecart))
1003        {
1004          deleteInL(strat->B,&strat->Bl,j,strat);
1005          strat->c3++;
1006        }
1007        j--;
1008      }
1009    }
1010  }
1011  else /*sugarcrit*/
1012  {
1013    if(/*(strat->ak==0) && productCrit(p,strat->S[i])*/
1014    pHasNotCF(p,strat->S[i]))
1015    {
1016    /*
1017    *the product criterion has applied for (s,p),
1018    *i.e. lcm(s,p)=product of the leading terms of s and p.
1019    *Suppose (s,r) is in L and the leading term
1020    *of p devides lcm(s,r)
1021    *(==> the leading term of p devides the leading term of r)
1022    *but the leading term of s does not devide the leading term of r
1023    *(notice that tis condition is automatically satisfied if r is still
1024    *in S), then (s,r) can be canceled.
1025    *This should be done here because the
1026    *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
1027    */
1028      strat->cp++;
1029      pLmFree(Lp.lcm);
1030      Lp.lcm=NULL;
1031      return;
1032    }
1033    if (strat->fromT && (strat->ecartS[i]>ecart))
1034    {
1035      pLmFree(Lp.lcm);
1036      Lp.lcm=NULL;
1037      return;
1038      /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
1039    }
1040    /*
1041    *the set B collects the pairs of type (S[j],p)
1042    *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
1043    *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
1044    *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
1045    */
1046    for(j = strat->Bl;j>=0;j--)
1047    {
1048      compare=pDivComp(strat->B[j].lcm,Lp.lcm);
1049      if (compare==1)
1050      {
1051        strat->c3++;
1052        if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1053        {
1054          pLmFree(Lp.lcm);
1055          return;
1056        }
1057        break;
1058      }
1059      else
1060      if (compare ==-1)
1061      {
1062        deleteInL(strat->B,&strat->Bl,j,strat);
1063        strat->c3++;
1064      }
1065    }
1066  }
1067  /*
1068  *the pair (S[i],p) enters B if the spoly != 0
1069  */
1070  /*-  compute the short s-polynomial -*/
1071  if (strat->fromT && !TEST_OPT_INTSTRATEGY)
1072    pNorm(p);
1073  if ((strat->S[i]==NULL) || (p==NULL))
1074    return;
1075  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (strat->fromQ[i]!=0))
1076    Lp.p=NULL;
1077  else
1078  {
1079    Lp.p = ksCreateShortSpoly(strat->S[i],p, strat->tailRing);
1080  }
1081  if (Lp.p == NULL)
1082  {
1083    /*- the case that the s-poly is 0 -*/
1084    if (strat->pairtest==NULL) initPairtest(strat);
1085    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
1086    strat->pairtest[strat->sl+1] = TRUE;
1087    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
1088    /*
1089    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
1090    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
1091    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
1092    *term of p devides the lcm(s,r)
1093    *(this canceling should be done here because
1094    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
1095    *the first case is handeled in chainCrit
1096    */
1097    if (Lp.lcm!=NULL) pLmFree(Lp.lcm);
1098  }
1099  else
1100  {
1101    /*- the pair (S[i],p) enters B -*/
1102    Lp.p1 = strat->S[i];
1103    Lp.p2 = p;
1104    pNext(Lp.p) = strat->tail;
1105    if (atR >= 0)
1106    {
1107      Lp.i_r2 = atR;
1108      Lp.i_r1 = strat->S_2_R[i];
1109    }
1110    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
1111    if (TEST_OPT_INTSTRATEGY)
1112    {
1113      nDelete(&(Lp.p->coef));
1114    }
1115    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
1116    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
1117  }
1118}
1119
1120/*2
1121* put the pair (s[i],p) into the set L, ecart=ecart(p)
1122* in the case that s forms a SB of (s)
1123*/
1124void enterOnePairSpecial (int i,poly p,int ecart,kStrategy strat, int atR = -1)
1125{
1126  int      l,j,compare;
1127  LObject  Lp;
1128
1129  Lp.lcm = pInit();
1130  pLcm(p,strat->S[i],Lp.lcm);
1131  pSetm(Lp.lcm);
1132  if(pHasNotCF(p,strat->S[i]))
1133  {
1134    strat->cp++;
1135    pLmFree(Lp.lcm);
1136    Lp.lcm=NULL;
1137    return;
1138  }
1139  for(j = strat->Ll;j>=0;j--)
1140  {
1141    compare=pDivComp(strat->L[j].lcm,Lp.lcm);
1142    if ((compare==1) || (pLmEqual(strat->L[j].lcm,Lp.lcm)))
1143    {
1144      strat->c3++;
1145      pLmFree(Lp.lcm);
1146      return;
1147    }
1148    else if (compare ==-1)
1149    {
1150      deleteInL(strat->L,&strat->Ll,j,strat);
1151      strat->c3++;
1152    }
1153  }
1154  /*-  compute the short s-polynomial -*/
1155
1156  Lp.p = ksCreateShortSpoly(strat->S[i],p,strat->tailRing);
1157  if (Lp.p == NULL)
1158  {
1159     pLmFree(Lp.lcm);
1160  }
1161  else
1162  {
1163    /*- the pair (S[i],p) enters B -*/
1164    Lp.p1 = strat->S[i];
1165    Lp.p2 = p;
1166    if (atR >= 0)
1167    {
1168      Lp.i_r1 = strat->S_2_R[i];
1169      Lp.i_r2 = atR;
1170    }
1171    pNext(Lp.p) = strat->tail;
1172    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
1173    if (TEST_OPT_INTSTRATEGY)
1174    {
1175      nDelete(&(Lp.p->coef));
1176    }
1177    l = strat->posInL(strat->L,strat->Ll,&Lp,strat);
1178    enterL(&strat->L,&strat->Ll,&strat->Lmax,Lp,l);
1179  }
1180}
1181
1182/*2
1183*the pairset B of pairs of type (s[i],p) is complete now. It will be updated
1184*using the chain-criterion in B and L and enters B to L
1185*/
1186void chainCrit (poly p,int ecart,kStrategy strat)
1187{
1188  int i,j,l;
1189
1190  /*
1191  *pairtest[i] is TRUE if spoly(S[i],p) == 0.
1192  *In this case all elements in B such
1193  *that their lcm is divisible by the leading term of S[i] can be canceled
1194  */
1195  if (strat->pairtest!=NULL)
1196  {
1197    {
1198      /*- i.e. there is an i with pairtest[i]==TRUE -*/
1199      for (j=0; j<=strat->sl; j++)
1200      {
1201        if (strat->pairtest[j])
1202        {
1203          for (i=strat->Bl; i>=0; i--)
1204          {
1205            if (pDivisibleBy(strat->S[j],strat->B[i].lcm))
1206            {
1207              deleteInL(strat->B,&strat->Bl,i,strat);
1208              strat->c3++;
1209            }
1210          }
1211        }
1212      }
1213    }
1214    omFreeSize(strat->pairtest,(strat->sl+2)*sizeof(BOOLEAN));
1215    strat->pairtest=NULL;
1216  }
1217  if (strat->Gebauer || strat->fromT)
1218  {
1219    if (strat->sugarCrit)
1220    {
1221    /*
1222    *suppose L[j] == (s,r) and p/lcm(s,r)
1223    *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
1224    *and in case the sugar is o.k. then L[j] can be canceled
1225    */
1226      for (j=strat->Ll; j>=0; j--)
1227      {
1228        if (sugarDivisibleBy(ecart,strat->L[j].ecart)
1229        && ((pNext(strat->L[j].p) == strat->tail) || (pOrdSgn==1))
1230        && pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1231        {
1232          if (strat->L[j].p == strat->tail)
1233          {
1234            deleteInL(strat->L,&strat->Ll,j,strat);
1235            strat->c3++;
1236          }
1237        }
1238      }
1239      /*
1240      *this is GEBAUER-MOELLER:
1241      *in B all elements with the same lcm except the "best"
1242      *(i.e. the last one in B with this property) will be canceled
1243      */
1244      j = strat->Bl;
1245      loop /*cannot be changed into a for !!! */
1246      {
1247        if (j <= 0) break;
1248        i = j-1;
1249        loop
1250        {
1251          if (i <  0) break;
1252          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
1253          {
1254            strat->c3++;
1255            if (sugarDivisibleBy(strat->B[j].ecart,strat->B[i].ecart))
1256            {
1257              deleteInL(strat->B,&strat->Bl,i,strat);
1258              j--;
1259            }
1260            else
1261            {
1262              deleteInL(strat->B,&strat->Bl,j,strat);
1263              break;
1264            }
1265          }
1266          i--;
1267        }
1268        j--;
1269      }
1270    }
1271    else /*sugarCrit*/
1272    {
1273      /*
1274      *suppose L[j] == (s,r) and p/lcm(s,r)
1275      *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
1276      *and in case the sugar is o.k. then L[j] can be canceled
1277      */
1278      for (j=strat->Ll; j>=0; j--)
1279      {
1280        if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1281        {
1282          if ((pNext(strat->L[j].p) == strat->tail)||(pOrdSgn==1))
1283          {
1284            deleteInL(strat->L,&strat->Ll,j,strat);
1285            strat->c3++;
1286          }
1287        }
1288      }
1289      /*
1290      *this is GEBAUER-MOELLER:
1291      *in B all elements with the same lcm except the "best"
1292      *(i.e. the last one in B with this property) will be canceled
1293      */
1294      j = strat->Bl;
1295      loop   /*cannot be changed into a for !!! */
1296      {
1297        if (j <= 0) break;
1298        for(i=j-1; i>=0; i--)
1299        {
1300          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
1301          {
1302            strat->c3++;
1303            deleteInL(strat->B,&strat->Bl,i,strat);
1304            j--;
1305          }
1306        }
1307        j--;
1308      }
1309    }
1310    /*
1311    *the elements of B enter L/their order with respect to B is kept
1312    *j = posInL(L,j,B[i]) would permutate the order
1313    *if once B is ordered different from L
1314    *then one should use j = posInL(L,Ll,B[i])
1315    */
1316    j = strat->Ll+1;
1317    for (i=strat->Bl; i>=0; i--)
1318    {
1319      j = strat->posInL(strat->L,j-1,&(strat->B[i]),strat);
1320      enterL(&strat->L,&strat->Ll,&strat->Lmax,strat->B[i],j);
1321    }
1322    strat->Bl = -1;
1323  }
1324  else
1325  {
1326    for (j=strat->Ll; j>=0; j--)
1327    {
1328      if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1329      {
1330        if ((pNext(strat->L[j].p) == strat->tail)||(pOrdSgn==1))
1331        {
1332          deleteInL(strat->L,&strat->Ll,j,strat);
1333          strat->c3++;
1334        }
1335      }
1336    }
1337    /*
1338    *this is our MODIFICATION of GEBAUER-MOELLER:
1339    *First the elements of B enter L,
1340    *then we fix a lcm and the "best" element in L
1341    *(i.e the last in L with this lcm and of type (s,p))
1342    *and cancel all the other elements of type (r,p) with this lcm
1343    *except the case the element (s,r) has also the same lcm
1344    *and is on the worst position with respect to (s,p) and (r,p)
1345    */
1346    /*
1347    *B enters to L/their order with respect to B is permutated for elements
1348    *B[i].p with the same leading term
1349    */
1350    j = strat->Ll;
1351    for (i=strat->Bl; i>=0; i--)
1352    {
1353      j = strat->posInL(strat->L,j,&(strat->B[i]),strat);
1354      enterL(&strat->L,&strat->Ll,&strat->Lmax,strat->B[i],j);
1355    }
1356    strat->Bl = -1;
1357    j = strat->Ll;
1358    loop  /*cannot be changed into a for !!! */
1359    {
1360      if (j <= 0)
1361      {
1362        /*now L[0] cannot be canceled any more and the tail can be removed*/
1363        if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
1364        break;
1365      }
1366      if (strat->L[j].p2 == p)
1367      {
1368        i = j-1;
1369        loop
1370        {
1371          if (i < 0)  break;
1372          if ((strat->L[i].p2 == p) && pLmEqual(strat->L[j].lcm,strat->L[i].lcm))
1373          {
1374            /*L[i] could be canceled but we search for a better one to cancel*/
1375            strat->c3++;
1376            if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
1377            && (pNext(strat->L[l].p) == strat->tail)
1378            && (!pLmEqual(strat->L[i].p,strat->L[l].p))
1379            && pDivisibleBy(p,strat->L[l].lcm))
1380            {
1381              /*
1382              *"NOT equal(...)" because in case of "equal" the element L[l]
1383              *is "older" and has to be from theoretical point of view behind
1384              *L[i], but we do not want to reorder L
1385              */
1386              strat->L[i].p2 = strat->tail;
1387              /*
1388              *L[l] will be canceled, we cannot cancel L[i] later on,
1389              *so we mark it with "tail"
1390              */
1391              deleteInL(strat->L,&strat->Ll,l,strat);
1392              i--;
1393            }
1394            else
1395            {
1396              deleteInL(strat->L,&strat->Ll,i,strat);
1397            }
1398            j--;
1399          }
1400          i--;
1401        }
1402      }
1403      else if (strat->L[j].p2 == strat->tail)
1404      {
1405        /*now L[j] cannot be canceled any more and the tail can be removed*/
1406        strat->L[j].p2 = p;
1407      }
1408      j--;
1409    }
1410  }
1411}
1412
1413/*2
1414*(s[0],h),...,(s[k],h) will be put to the pairset L
1415*/
1416void initenterpairs (poly h,int k,int ecart,int isFromQ,kStrategy strat, int atR = -1)
1417{
1418
1419  if ((strat->syzComp==0)
1420  || (pGetComp(h)<=strat->syzComp))
1421  {
1422    int j;
1423    BOOLEAN new_pair=FALSE;
1424
1425    if (pGetComp(h)==0)
1426    {
1427      /* for Q!=NULL: build pairs (f,q),(f1,f2), but not (q1,q2)*/
1428      if ((isFromQ)&&(strat->fromQ!=NULL))
1429      {
1430        for (j=0; j<=k; j++)
1431        {
1432          if (!strat->fromQ[j])
1433          {
1434            new_pair=TRUE;
1435            enterOnePair(j,h,ecart,isFromQ,strat, atR);
1436          //Print("j:%d, Ll:%d\n",j,strat->Ll);
1437          }
1438        }
1439      }
1440      else
1441      {
1442        new_pair=TRUE;
1443        for (j=0; j<=k; j++)
1444        {
1445          enterOnePair(j,h,ecart,isFromQ,strat, atR);
1446          //Print("j:%d, Ll:%d\n",j,strat->Ll);
1447        }
1448      }
1449    }
1450    else
1451    {
1452      for (j=0; j<=k; j++)
1453      {
1454        if ((pGetComp(h)==pGetComp(strat->S[j]))
1455        || (pGetComp(strat->S[j])==0))
1456        {
1457          new_pair=TRUE;
1458          enterOnePair(j,h,ecart,isFromQ,strat, atR);
1459        //Print("j:%d, Ll:%d\n",j,strat->Ll);
1460        }
1461      }
1462    }
1463    if (new_pair) chainCrit(h,ecart,strat);
1464  }
1465}
1466
1467/*2
1468*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
1469*superfluous elements in S will be deleted
1470*/
1471void enterpairs (poly h,int k,int ecart,int pos,kStrategy strat, int atR = -1)
1472{
1473  int j=pos;
1474
1475  initenterpairs(h,k,ecart,0,strat, atR);
1476  if ((!strat->fromT)
1477  && ((strat->syzComp==0)
1478    ||(pGetComp(h)<=strat->syzComp)))
1479  {
1480    //Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
1481    unsigned long h_sev = pGetShortExpVector(h);
1482    loop
1483    {
1484      if (j > k) break;
1485      clearS(h,h_sev, &j,&k,strat);
1486      j++;
1487    }
1488    //Print("end clearS sl=%d\n",strat->sl);
1489  }
1490 // PrintS("end enterpairs\n");
1491}
1492
1493/*2
1494*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
1495*superfluous elements in S will be deleted
1496*/
1497void enterpairsSpecial (poly h,int k,int ecart,int pos,kStrategy strat, int atR = -1)
1498{
1499  int j;
1500
1501  for (j=0; j<=k; j++)
1502  {
1503    if ((pGetComp(h)==pGetComp(strat->S[j]))
1504    || (0==pGetComp(strat->S[j])))
1505    {
1506      enterOnePairSpecial(j,h,ecart,strat, atR);
1507    }
1508  }
1509  j=pos;
1510  loop
1511  {
1512    unsigned long h_sev = pGetShortExpVector(h);
1513    if (j > k) break;
1514    clearS(h,h_sev,&j,&k,strat);
1515    j++;
1516  }
1517}
1518
1519/*2
1520*constructs the pairset at the beginning
1521*of the buchberger/mora algorithm
1522*/
1523void pairs (kStrategy strat)
1524{
1525  int j,i;
1526//  Print("pairs:sl=%d\n",strat->sl);
1527//  for (i=0; i<=strat->sl; i++)
1528//  {
1529//    Print("s%d:",i);pWrite(strat->S[i]);
1530//  }
1531  if (strat->fromQ!=NULL)
1532  {
1533    for (i=1; i<=strat->sl; i++)
1534    {
1535      initenterpairs(strat->S[i],i-1,strat->ecartS[i],strat->fromQ[i],strat);
1536    }
1537  }
1538  else
1539  {
1540    for (i=1; i<=strat->sl; i++)
1541    {
1542      initenterpairs(strat->S[i],i-1,strat->ecartS[i],0,strat);
1543    }
1544  }
1545  /*deletes superfluous elements in S*/
1546  i = -1;
1547  loop
1548  {
1549    i++;
1550    if (i >= strat->sl) break;
1551    if ((strat->syzComp==0) || (pGetComp(strat->S[i])<=strat->syzComp))
1552    {
1553      j=i;
1554      loop
1555      {
1556        j++;
1557        if (j > strat->sl) break;
1558        if (pLmShortDivisibleBy(strat->S[i], strat->sevS[i],
1559                              strat->S[j], ~ strat->sevS[j]))
1560        {
1561        //  Print("delete %d=",j);
1562        //  wrp(strat->S[j]);
1563        //  Print(" wegen %d=",i);
1564        //  wrp(strat->S[i]);
1565        //  Print("( fromQ=%d)\n", (strat->fromQ) ? strat->fromQ[j]:0);
1566          if ((strat->fromQ==NULL) || (strat->fromQ[j]==0))
1567          {
1568            deleteInS(j,strat);
1569            j--;
1570          }
1571        }
1572      }
1573    }
1574  }
1575}
1576
1577/*2
1578*reorders  s with respect to posInS,
1579*suc is the first changed index or zero
1580*/
1581void reorderS (int* suc,kStrategy strat)
1582{
1583  int i,j,at,ecart, s2r;
1584  int fq=0;
1585  unsigned long sev;
1586  poly  p;
1587
1588  *suc = -1;
1589  for (i=1; i<=strat->sl; i++)
1590  {
1591    at = posInS(strat->S,i-1,strat->S[i]);
1592    if (at != i)
1593    {
1594      if ((*suc > at) || (*suc == -1)) *suc = at;
1595      p = strat->S[i];
1596      ecart = strat->ecartS[i];
1597      sev = strat->sevS[i];
1598      s2r = strat->S_2_R[i];
1599      if (strat->fromQ!=NULL) fq=strat->fromQ[i];
1600      for (j=i; j>=at+1; j--)
1601      {
1602        strat->S[j] = strat->S[j-1];
1603        strat->ecartS[j] = strat->ecartS[j-1];
1604        strat->sevS[j] = strat->sevS[j-1];
1605        strat->S_2_R[j] = strat->S_2_R[j-1];
1606      }
1607      strat->S[at] = p;
1608      strat->ecartS[at] = ecart;
1609      strat->sevS[at] = sev;
1610      strat->S_2_R[at] = s2r;
1611      if (strat->fromQ!=NULL)
1612      {
1613        for (j=i; j>=at+1; j--)
1614        {
1615          strat->fromQ[j] = strat->fromQ[j-1];
1616        }
1617        strat->fromQ[at]=fq;
1618      }
1619    }
1620  }
1621}
1622
1623
1624/*2
1625*looks up the position of p in set
1626*set[0] is the smallest with respect to the ordering-procedure
1627*pComp
1628* Assumption: posInS only depends on the leading term
1629*             otherwise, bba has to be changed
1630*/
1631int posInS (polyset set,int length,poly p)
1632{
1633  if(length==-1) return 0;
1634  int i;
1635  int an = 0;
1636  int en= length;
1637  if (currRing->MixedOrder)
1638  {
1639    int cmp_int=pOrdSgn;
1640    int o=pWTotaldegree(p);
1641    int oo=pWTotaldegree(set[length]);
1642
1643    if ((oo<o)
1644    || ((o==oo) && (pLmCmp(set[length],p)!= cmp_int)))
1645      return length+1;
1646
1647    loop
1648    {
1649      if (an >= en-1)
1650      {
1651        if ((pWTotaldegree(set[an])>=o) && (pLmCmp(set[an],p) == cmp_int))
1652        {
1653          return an;
1654        }
1655        return en;
1656      }
1657      i=(an+en) / 2;
1658      if ((pWTotaldegree(set[an])>=o)
1659      && (pLmCmp(set[i],p) == cmp_int)) en=i;
1660      else                              an=i;
1661    }
1662  }
1663  else
1664  {
1665    if (pLmCmp(set[length],p)!= pOrdSgn)
1666      return length+1;
1667
1668    loop
1669    {
1670      if (an >= en-1)
1671      {
1672        if (pLmCmp(set[an],p) == pOrdSgn) return an;
1673        return en;
1674      }
1675      i=(an+en) / 2;
1676      if (pLmCmp(set[i],p) == pOrdSgn) en=i;
1677      else                             an=i;
1678    }
1679  }
1680}
1681
1682
1683/*2
1684* looks up the position of p in set
1685* the position is the last one
1686*/
1687int posInT0 (const TSet set,const int length,const LObject &p)
1688{
1689  return (length+1);
1690}
1691
1692
1693/*2
1694* looks up the position of p in T
1695* set[0] is the smallest with respect to the ordering-procedure
1696* pComp
1697*/
1698int posInT1 (const TSet set,const int length,const LObject &p)
1699{
1700  if (length==-1) return 0;
1701
1702  if (pLmCmp(set[length].p,p.p)!= pOrdSgn) return length+1;
1703
1704  int i;
1705  int an = 0;
1706  int en= length;
1707
1708  loop
1709  {
1710    if (an >= en-1)
1711    {
1712      if (pLmCmp(set[an].p,p.p) == pOrdSgn) return an;
1713      return en;
1714    }
1715    i=(an+en) / 2;
1716    if (pLmCmp(set[i].p,p.p) == pOrdSgn) en=i;
1717    else                                 an=i;
1718  }
1719}
1720
1721/*2
1722* looks up the position of p in T
1723* set[0] is the smallest with respect to the ordering-procedure
1724* length
1725*/
1726int posInT2 (const TSet set,const int length,const LObject &p)
1727{
1728  if (length==-1)
1729    return 0;
1730  if (set[length].length<p.length)
1731    return length+1;
1732
1733  int i;
1734  int an = 0;
1735  int en= length;
1736
1737  loop
1738  {
1739    if (an >= en-1)
1740    {
1741      if (set[an].length>p.length) return an;
1742      return en;
1743    }
1744    i=(an+en) / 2;
1745    if (set[i].length>p.length) en=i;
1746    else                        an=i;
1747  }
1748}
1749
1750/*2
1751* looks up the position of p in T
1752* set[0] is the smallest with respect to the ordering-procedure
1753* totaldegree,pComp
1754*/
1755int posInT11 (const TSet set,const int length,const LObject &p)
1756/*{
1757 * int j=0;
1758 * int o;
1759 *
1760 * o = p.GetpFDeg();
1761 * loop
1762 * {
1763 *   if ((pFDeg(set[j].p) > o)
1764 *   || ((pFDeg(set[j].p) == o) && (pLmCmp(set[j].p,p.p) == pOrdSgn)))
1765 *   {
1766 *     return j;
1767 *   }
1768 *   j++;
1769 *   if (j > length) return j;
1770 * }
1771 *}
1772 */
1773{
1774  if (length==-1) return 0;
1775
1776  int o = p.GetpFDeg();
1777  int op = set[length].GetpFDeg();
1778
1779  if ((op < o)
1780  || ((op == o) && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
1781    return length+1;
1782
1783  int i;
1784  int an = 0;
1785  int en= length;
1786
1787  loop
1788  {
1789    if (an >= en-1)
1790    {
1791      op= set[an].GetpFDeg();
1792      if ((op > o)
1793      || (( op == o) && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
1794        return an;
1795      return en;
1796    }
1797    i=(an+en) / 2;
1798    op = set[i].GetpFDeg();
1799    if (( op > o)
1800    || (( op == o) && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
1801      en=i;
1802    else
1803      an=i;
1804  }
1805}
1806
1807/*2
1808* looks up the position of p in T
1809* set[0] is the smallest with respect to the ordering-procedure
1810* totaldegree,pComp
1811*/
1812int posInT110 (const TSet set,const int length,const LObject &p)
1813{
1814  if (length==-1) return 0;
1815
1816  int o = p.GetpFDeg();
1817  int op = set[length].GetpFDeg();
1818
1819  if (( op < o)
1820  || (( op == o) && (set[length].length<p.length))
1821  || (( op == o) && (set[length].length == p.length)
1822     && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
1823    return length+1;
1824
1825  int i;
1826  int an = 0;
1827  int en= length;
1828  loop
1829  {
1830    if (an >= en-1)
1831    {
1832      op = set[an].GetpFDeg();
1833      if (( op > o)
1834      || (( op == o) && (set[an].length > p.length))
1835      || (( op == o) && (set[an].length == p.length)
1836         && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
1837        return an;
1838      return en;
1839    }
1840    i=(an+en) / 2;
1841    op = set[i].GetpFDeg();
1842    if (( op > o)
1843    || (( op == o) && (set[i].length > p.length))
1844    || (( op == o) && (set[i].length == p.length)
1845       && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
1846      en=i;
1847    else
1848      an=i;
1849  }
1850}
1851
1852/*2
1853* looks up the position of p in set
1854* set[0] is the smallest with respect to the ordering-procedure
1855* pFDeg
1856*/
1857int posInT13 (const TSet set,const int length,const LObject &p)
1858{
1859  if (length==-1) return 0;
1860
1861  int o = p.GetpFDeg();
1862
1863  if (set[length].GetpFDeg() <= o)
1864    return length+1;
1865
1866  int i;
1867  int an = 0;
1868  int en= length;
1869  loop
1870  {
1871    if (an >= en-1)
1872    {
1873      if (set[an].GetpFDeg() > o)
1874        return an;
1875      return en;
1876    }
1877    i=(an+en) / 2;
1878    if (set[i].GetpFDeg() > o)
1879      en=i;
1880    else
1881      an=i;
1882  }
1883}
1884
1885/*2
1886* looks up the position of p in set
1887* set[0] is the smallest with respect to the ordering-procedure
1888* maximaldegree, pComp
1889*/
1890int posInT15 (const TSet set,const int length,const LObject &p)
1891/*{
1892 *int j=0;
1893 * int o;
1894 *
1895 * o = p.GetpFDeg()+p.ecart;
1896 * loop
1897 * {
1898 *   if ((set[j].GetpFDeg()+set[j].ecart > o)
1899 *   || ((set[j].GetpFDeg()+set[j].ecart == o)
1900 *     && (pLmCmp(set[j].p,p.p) == pOrdSgn)))
1901 *   {
1902 *     return j;
1903 *   }
1904 *   j++;
1905 *   if (j > length) return j;
1906 * }
1907 *}
1908 */
1909{
1910  if (length==-1) return 0;
1911
1912  int o = p.GetpFDeg() + p.ecart;
1913  int op = set[length].GetpFDeg()+set[length].ecart;
1914
1915  if ((op < o)
1916  || ((op == o)
1917     && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
1918    return length+1;
1919
1920  int i;
1921  int an = 0;
1922  int en= length;
1923  loop
1924  {
1925    if (an >= en-1)
1926    {
1927      op = set[an].GetpFDeg()+set[an].ecart;
1928      if (( op > o)
1929      || (( op  == o) && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
1930        return an;
1931      return en;
1932    }
1933    i=(an+en) / 2;
1934    op = set[i].GetpFDeg()+set[i].ecart;
1935    if (( op > o)
1936    || (( op == o) && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
1937      en=i;
1938    else
1939      an=i;
1940  }
1941}
1942
1943/*2
1944* looks up the position of p in set
1945* set[0] is the smallest with respect to the ordering-procedure
1946* pFDeg+ecart, ecart, pComp
1947*/
1948int posInT17 (const TSet set,const int length,const LObject &p)
1949/*
1950*{
1951* int j=0;
1952* int  o;
1953*
1954*  o = p.GetpFDeg()+p.ecart;
1955*  loop
1956*  {
1957*    if ((pFDeg(set[j].p)+set[j].ecart > o)
1958*    || (((pFDeg(set[j].p)+set[j].ecart == o)
1959*      && (set[j].ecart < p.ecart)))
1960*    || ((pFDeg(set[j].p)+set[j].ecart == o)
1961*      && (set[j].ecart==p.ecart)
1962*      && (pLmCmp(set[j].p,p.p)==pOrdSgn)))
1963*      return j;
1964*    j++;
1965*    if (j > length) return j;
1966*  }
1967* }
1968*/
1969{
1970  if (length==-1) return 0;
1971
1972  int o = p.GetpFDeg() + p.ecart;
1973  int op = set[length].GetpFDeg()+set[length].ecart;
1974
1975  if ((op < o)
1976  || (( op == o) && (set[length].ecart > p.ecart))
1977  || (( op == o) && (set[length].ecart==p.ecart)
1978     && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
1979    return length+1;
1980
1981  int i;
1982  int an = 0;
1983  int en= length;
1984  loop
1985  {
1986    if (an >= en-1)
1987    {
1988      op = set[an].GetpFDeg()+set[an].ecart;
1989      if (( op > o)
1990      || (( op == o) && (set[an].ecart < p.ecart))
1991      || (( op  == o) && (set[an].ecart==p.ecart)
1992         && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
1993        return an;
1994      return en;
1995    }
1996    i=(an+en) / 2;
1997    op = set[i].GetpFDeg()+set[i].ecart;
1998    if ((op > o)
1999    || (( op == o) && (set[i].ecart < p.ecart))
2000    || (( op == o) && (set[i].ecart == p.ecart)
2001       && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
2002      en=i;
2003    else
2004      an=i;
2005  }
2006}
2007/*2
2008* looks up the position of p in set
2009* set[0] is the smallest with respect to the ordering-procedure
2010* pGetComp, pFDeg+ecart, ecart, pComp
2011*/
2012int posInT17_c (const TSet set,const int length,const LObject &p)
2013{
2014  if (length==-1) return 0;
2015
2016  int cc = (-1+2*currRing->order[0]==ringorder_c);
2017  /* cc==1 for (c,..), cc==-1 for (C,..) */
2018  int o = p.GetpFDeg() + p.ecart;
2019  int c = pGetComp(p.p)*cc;
2020
2021  if (pGetComp(set[length].p)*cc < c)
2022    return length+1;
2023  if (pGetComp(set[length].p)*cc == c)
2024  {
2025    int op = set[length].GetpFDeg()+set[length].ecart;
2026    if ((op < o)
2027    || ((op == o) && (set[length].ecart > p.ecart))
2028    || ((op == o) && (set[length].ecart==p.ecart)
2029       && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
2030      return length+1;
2031  }
2032
2033  int i;
2034  int an = 0;
2035  int en= length;
2036  loop
2037  {
2038    if (an >= en-1)
2039    {
2040      if (pGetComp(set[an].p)*cc < c)
2041        return en;
2042      if (pGetComp(set[an].p)*cc == c)
2043      {
2044        int op = set[an].GetpFDeg()+set[an].ecart;
2045        if ((op > o)
2046        || ((op == o) && (set[an].ecart < p.ecart))
2047        || ((op == o) && (set[an].ecart==p.ecart)
2048           && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
2049          return an;
2050      }
2051      return en;
2052    }
2053    i=(an+en) / 2;
2054    if (pGetComp(set[i].p)*cc > c)
2055      en=i;
2056    else if (pGetComp(set[i].p)*cc == c)
2057    {
2058      int op = set[i].GetpFDeg()+set[i].ecart;
2059      if ((op > o)
2060      || ((op == o) && (set[i].ecart < p.ecart))
2061      || ((op == o) && (set[i].ecart == p.ecart)
2062         && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
2063        en=i;
2064      else
2065        an=i;
2066    }
2067    else
2068      an=i;
2069  }
2070}
2071
2072/*2
2073* looks up the position of p in set
2074* set[0] is the smallest with respect to
2075* ecart, pFDeg, length
2076*/
2077int posInT19 (const TSet set,const int length,const LObject &p)
2078{
2079  if (length==-1) return 0;
2080
2081  int o = p.ecart;
2082  int op=p.GetpFDeg();
2083
2084  if (set[length].ecart < o)
2085    return length+1;
2086  if (set[length].ecart == o)
2087  {
2088     int oo=set[length].GetpFDeg();
2089     if ((oo < op) || ((oo==op) && (set[length].length < p.length)))
2090       return length+1;
2091  }
2092
2093  int i;
2094  int an = 0;
2095  int en= length;
2096  loop
2097  {
2098    if (an >= en-1)
2099    {
2100      if (set[an].ecart > o)
2101        return an;
2102      if (set[an].ecart == o)
2103      {
2104         int oo=set[an].GetpFDeg();
2105         if((oo > op)
2106         || ((oo==op) && (set[an].length > p.length)))
2107           return an;
2108      }
2109      return en;
2110    }
2111    i=(an+en) / 2;
2112    if (set[i].ecart > o)
2113      en=i;
2114    else if (set[i].ecart == o)
2115    {
2116       int oo=set[i].GetpFDeg();
2117       if ((oo > op)
2118       || ((oo == op) && (set[i].length > p.length)))
2119         en=i;
2120       else
2121        an=i;
2122    }
2123    else
2124      an=i;
2125  }
2126}
2127
2128/*2
2129*looks up the position of polynomial p in set
2130*set[length] is the smallest element in set with respect
2131*to the ordering-procedure pComp
2132*/
2133int posInLSpecial (const LSet set, const int length,
2134                   LObject *p,const kStrategy strat)
2135{
2136  if (length<0) return 0;
2137
2138  int d=p->GetpFDeg();
2139  int op=set[length].GetpFDeg();
2140
2141  if ((op > d)
2142  || ((op == d) && (p->p1!=NULL)&&(set[length].p1==NULL))
2143  || (pLmCmp(set[length].p,p->p)== pOrdSgn))
2144     return length+1;
2145
2146  int i;
2147  int an = 0;
2148  int en= length;
2149  loop
2150  {
2151    if (an >= en-1)
2152    {
2153      op=set[an].GetpFDeg();
2154      if ((op > d)
2155      || ((op == d) && (p->p1!=NULL) && (set[an].p1==NULL))
2156      || (pLmCmp(set[an].p,p->p)== pOrdSgn))
2157         return en;
2158      return an;
2159    }
2160    i=(an+en) / 2;
2161    op=set[i].GetpFDeg();
2162    if ((op>d)
2163    || ((op==d) && (p->p1!=NULL) && (set[i].p1==NULL))
2164    || (pLmCmp(set[i].p,p->p) == pOrdSgn))
2165      an=i;
2166    else
2167      en=i;
2168  }
2169}
2170
2171/*2
2172*looks up the position of polynomial p in set
2173*set[length] is the smallest element in set with respect
2174*to the ordering-procedure pComp
2175*/
2176int posInL0 (const LSet set, const int length,
2177             LObject* p,const kStrategy strat)
2178{
2179  if (length<0) return 0;
2180
2181  if (pLmCmp(set[length].p,p->p)== pOrdSgn)
2182    return length+1;
2183
2184  int i;
2185  int an = 0;
2186  int en= length;
2187  loop
2188  {
2189    if (an >= en-1)
2190    {
2191      if (pLmCmp(set[an].p,p->p) == pOrdSgn) return en;
2192      return an;
2193    }
2194    i=(an+en) / 2;
2195    if (pLmCmp(set[i].p,p->p) == pOrdSgn) an=i;
2196    else                                 en=i;
2197    /*aend. fuer lazy == in !=- machen */
2198  }
2199}
2200
2201/*2
2202* looks up the position of polynomial p in set
2203* e is the ecart of p
2204* set[length] is the smallest element in set with respect
2205* to the ordering-procedure totaldegree,pComp
2206*/
2207int posInL11 (const LSet set, const int length,
2208              LObject* p,const kStrategy strat)
2209/*{
2210 * int j=0;
2211 * int o;
2212 *
2213 * o = p->GetpFDeg();
2214 * loop
2215 * {
2216 *   if (j > length)            return j;
2217 *   if ((set[j].GetpFDeg() < o)) return j;
2218 *   if ((set[j].GetpFDeg() == o) && (pLmCmp(set[j].p,p->p) == -pOrdSgn))
2219 *   {
2220 *     return j;
2221 *   }
2222 *   j++;
2223 * }
2224 *}
2225 */
2226{
2227  if (length<0) return 0;
2228
2229  int o = p->GetpFDeg();
2230  int op = set[length].GetpFDeg();
2231
2232  if ((op > o)
2233  || ((op == o) && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
2234    return length+1;
2235  int i;
2236  int an = 0;
2237  int en= length;
2238  loop
2239  {
2240    if (an >= en-1)
2241    {
2242      op = set[an].GetpFDeg();
2243      if ((op > o)
2244      || ((op == o) && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
2245        return en;
2246      return an;
2247    }
2248    i=(an+en) / 2;
2249    op = set[i].GetpFDeg();
2250    if ((op > o)
2251    || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
2252      an=i;
2253    else
2254      en=i;
2255  }
2256}
2257
2258/*2
2259* looks up the position of polynomial p in set
2260* set[length] is the smallest element in set with respect
2261* to the ordering-procedure totaldegree,pLength0
2262*/
2263int posInL110 (const LSet set, const int length,
2264               LObject* p,const kStrategy strat)
2265{
2266  if (length<0) return 0;
2267
2268  int o = p->GetpFDeg();
2269  int op = set[length].GetpFDeg();
2270
2271  if ((op > o)
2272  || ((op == o) && (set[length].length >2*p->length))
2273  || ((op == o) && (set[length].length <= 2*p->length)
2274     && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
2275    return length+1;
2276  int i;
2277  int an = 0;
2278  int en= length;
2279  loop
2280  {
2281    if (an >= en-1)
2282    {
2283      op = set[an].GetpFDeg();
2284      if ((op > o)
2285      || ((op == o) && (set[an].length >2*p->length))
2286      || ((op == o) && (set[an].length <=2*p->length)
2287         && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
2288        return en;
2289      return an;
2290    }
2291    i=(an+en) / 2;
2292    op = set[i].GetpFDeg();
2293    if ((op > o)
2294    || ((op == o) && (set[i].length > 2*p->length))
2295    || ((op == o) && (set[i].length <= 2*p->length)
2296       && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
2297      an=i;
2298    else
2299      en=i;
2300  }
2301}
2302
2303/*2
2304* looks up the position of polynomial p in set
2305* e is the ecart of p
2306* set[length] is the smallest element in set with respect
2307* to the ordering-procedure totaldegree
2308*/
2309int posInL13 (const LSet set, const int length,
2310              LObject* p,const kStrategy strat)
2311{
2312  if (length<0) return 0;
2313
2314  int o = p->GetpFDeg();
2315
2316  if (set[length].GetpFDeg() > o)
2317    return length+1;
2318
2319  int i;
2320  int an = 0;
2321  int en= length;
2322  loop
2323  {
2324    if (an >= en-1)
2325    {
2326      if (set[an].GetpFDeg() >= o)
2327        return en;
2328      return an;
2329    }
2330    i=(an+en) / 2;
2331    if (set[i].GetpFDeg() >= o)
2332      an=i;
2333    else
2334      en=i;
2335  }
2336}
2337
2338/*2
2339* looks up the position of polynomial p in set
2340* e is the ecart of p
2341* set[length] is the smallest element in set with respect
2342* to the ordering-procedure maximaldegree,pComp
2343*/
2344int posInL15 (const LSet set, const int length,
2345              LObject* p,const kStrategy strat)
2346/*{
2347 * int j=0;
2348 * int o;
2349 *
2350 * o = p->ecart+p->GetpFDeg();
2351 * loop
2352 * {
2353 *   if (j > length)                       return j;
2354 *   if (set[j].GetpFDeg()+set[j].ecart < o) return j;
2355 *   if ((set[j].GetpFDeg()+set[j].ecart == o)
2356 *   && (pLmCmp(set[j].p,p->p) == -pOrdSgn))
2357 *   {
2358 *     return j;
2359 *   }
2360 *   j++;
2361 * }
2362 *}
2363 */
2364{
2365  if (length<0) return 0;
2366
2367  int o = p->GetpFDeg() + p->ecart;
2368  int op = set[length].GetpFDeg() + set[length].ecart;
2369
2370  if ((op > o)
2371  || ((op == o) && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
2372    return length+1;
2373  int i;
2374  int an = 0;
2375  int en= length;
2376  loop
2377  {
2378    if (an >= en-1)
2379    {
2380      op = set[an].GetpFDeg() + set[an].ecart;
2381      if ((op > o)
2382      || ((op == o) && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
2383        return en;
2384      return an;
2385    }
2386    i=(an+en) / 2;
2387    op = set[i].GetpFDeg() + set[i].ecart;
2388    if ((op > o)
2389    || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
2390      an=i;
2391    else
2392      en=i;
2393  }
2394}
2395
2396/*2
2397* looks up the position of polynomial p in set
2398* e is the ecart of p
2399* set[length] is the smallest element in set with respect
2400* to the ordering-procedure totaldegree
2401*/
2402int posInL17 (const LSet set, const int length,
2403              LObject* p,const kStrategy strat)
2404{
2405  if (length<0) return 0;
2406
2407  int o = p->GetpFDeg() + p->ecart;
2408
2409  if ((set[length].GetpFDeg() + set[length].ecart > o)
2410  || ((set[length].GetpFDeg() + set[length].ecart == o)
2411     && (set[length].ecart > p->ecart))
2412  || ((set[length].GetpFDeg() + set[length].ecart == o)
2413     && (set[length].ecart == p->ecart)
2414     && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
2415    return length+1;
2416  int i;
2417  int an = 0;
2418  int en= length;
2419  loop
2420  {
2421    if (an >= en-1)
2422    {
2423      if ((set[an].GetpFDeg() + set[an].ecart > o)
2424      || ((set[an].GetpFDeg() + set[an].ecart == o)
2425         && (set[an].ecart > p->ecart))
2426      || ((set[an].GetpFDeg() + set[an].ecart == o)
2427         && (set[an].ecart == p->ecart)
2428         && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
2429        return en;
2430      return an;
2431    }
2432    i=(an+en) / 2;
2433    if ((set[i].GetpFDeg() + set[i].ecart > o)
2434    || ((set[i].GetpFDeg() + set[i].ecart == o)
2435       && (set[i].ecart > p->ecart))
2436    || ((set[i].GetpFDeg() +set[i].ecart == o)
2437       && (set[i].ecart == p->ecart)
2438       && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
2439      an=i;
2440    else
2441      en=i;
2442  }
2443}
2444/*2
2445* looks up the position of polynomial p in set
2446* e is the ecart of p
2447* set[length] is the smallest element in set with respect
2448* to the ordering-procedure pComp
2449*/
2450int posInL17_c (const LSet set, const int length,
2451                LObject* p,const kStrategy strat)
2452{
2453  if (length<0) return 0;
2454
2455  int cc = (-1+2*currRing->order[0]==ringorder_c);
2456  /* cc==1 for (c,..), cc==-1 for (C,..) */
2457  int c = pGetComp(p->p)*cc;
2458  int o = p->GetpFDeg() + p->ecart;
2459
2460  if (pGetComp(set[length].p)*cc > c)
2461    return length+1;
2462  if (pGetComp(set[length].p)*cc == c)
2463  {
2464    if ((set[length].GetpFDeg() + set[length].ecart > o)
2465    || ((set[length].GetpFDeg() + set[length].ecart == o)
2466       && (set[length].ecart > p->ecart))
2467    || ((set[length].GetpFDeg() + set[length].ecart == o)
2468       && (set[length].ecart == p->ecart)
2469       && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
2470      return length+1;
2471  }
2472  int i;
2473  int an = 0;
2474  int en= length;
2475  loop
2476  {
2477    if (an >= en-1)
2478    {
2479      if (pGetComp(set[an].p)*cc > c)
2480        return en;
2481      if (pGetComp(set[an].p)*cc == c)
2482      {
2483        if ((set[an].GetpFDeg() + set[an].ecart > o)
2484        || ((set[an].GetpFDeg() + set[an].ecart == o)
2485           && (set[an].ecart > p->ecart))
2486        || ((set[an].GetpFDeg() + set[an].ecart == o)
2487           && (set[an].ecart == p->ecart)
2488           && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
2489          return en;
2490      }
2491      return an;
2492    }
2493    i=(an+en) / 2;
2494    if (pGetComp(set[i].p)*cc > c)
2495      an=i;
2496    else if (pGetComp(set[i].p)*cc == c)
2497    {
2498      if ((set[i].GetpFDeg() + set[i].ecart > o)
2499      || ((set[i].GetpFDeg() + set[i].ecart == o)
2500         && (set[i].ecart > p->ecart))
2501      || ((set[i].GetpFDeg() +set[i].ecart == o)
2502         && (set[i].ecart == p->ecart)
2503         && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
2504        an=i;
2505      else
2506        en=i;
2507    }
2508    else
2509      en=i;
2510  }
2511}
2512
2513/***************************************************************
2514 *
2515 * Tail reductions
2516 *
2517 ***************************************************************/
2518static TObject* 
2519kFindDivisibleByInS(kStrategy strat, int pos, LObject* L, TObject *T, 
2520                    long ecart = LONG_MAX)
2521{
2522  int j = 0;
2523  const unsigned long not_sev = ~L->sev;
2524  const unsigned long* sev = strat->sevS;
2525  poly p;
2526  ring r;
2527  L->GetLm(p, r);
2528 
2529  assume(~not_sev == p_GetShortExpVector(p, r));
2530
2531  if (r == currRing)
2532  {
2533    while (1)
2534    {
2535      if (j > pos) return NULL;
2536#if defined(PDEBUG) || defined(PDIV_DEBUG)
2537      if (p_LmShortDivisibleBy(strat->S[j], sev[j], p, not_sev, r) &&
2538          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
2539        break;
2540#else
2541      if (!(sev[j] & not_sev) &&
2542          (ecart== LONG_MAX || ecart>= strat->ecartS[j]) &&
2543          p_LmDivisibleBy(strat->S[j], p, r))
2544        break;
2545     
2546#endif
2547      j++;
2548    }
2549    // if called from NF, T objects do not exist:
2550    if (strat->tl < 0 || strat->S_2_R[j] == -1)
2551    {
2552      T->Set(strat->S[j], r, strat->tailRing);
2553      return T;
2554    }
2555    else
2556    {
2557      assume (j >= 0 && j <= strat->tl && strat->S_2_T(j) != NULL && 
2558              strat->S_2_T(j)->p == strat->S[j]);
2559      return strat->S_2_T(j);
2560    }
2561  }
2562  else
2563  {
2564    TObject* t;
2565    while (1)
2566    {
2567      if (j > pos) return NULL;
2568      assume(strat->S_2_R[j] != -1);
2569#if defined(PDEBUG) || defined(PDIV_DEBUG)
2570      t = strat->S_2_T(j);
2571      assume(t != NULL && t->t_p != NULL && t->tailRing == r);
2572      if (p_LmShortDivisibleBy(t->t_p, sev[j], p, not_sev, r) && 
2573          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
2574        return t;
2575#else     
2576      if (! (sev[j] & not_sev) && (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
2577      {
2578        t = strat->S_2_T(j);
2579        assume(t != NULL && t->t_p != NULL && t->tailRing == r && t->p == strat->S[j]);
2580        if (p_LmDivisibleBy(t->t_p, p, r)) return t;
2581      }
2582#endif
2583      j++;
2584    }
2585  }
2586}
2587
2588
2589poly redtail (LObject* L, int pos, kStrategy strat)
2590{
2591  poly h, hn;
2592  int j;
2593  unsigned long not_sev;
2594  strat->redTailChange=FALSE;
2595
2596  poly p = L->p;
2597  if (strat->noTailReduction || pNext(p) == NULL)
2598    return p;
2599
2600  LObject Ln(strat->tailRing);
2601  TObject* With;
2602  // placeholder in case strat->tl < 0
2603  TObject  With_s(strat->tailRing);
2604  h = p;
2605  hn = pNext(h);
2606  long op = pFDeg(hn, strat->tailRing);
2607  long e;
2608  int l;
2609  BOOLEAN save_HE=strat->kHEdgeFound;
2610  strat->kHEdgeFound |= 
2611    ((Kstd1_deg>0) && (op<=Kstd1_deg)) || TEST_OPT_INFREDTAIL;
2612
2613  while(hn != NULL)
2614  {
2615    op = pFDeg(hn, strat->tailRing);
2616    if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
2617    e = pLDeg(hn, &l, strat->tailRing) - op;
2618    while (1)
2619    {
2620      Ln.Set(hn, strat->tailRing);
2621      Ln.sev = p_GetShortExpVector(hn, strat->tailRing);
2622      if (strat->kHEdgeFound)
2623        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
2624      else
2625        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s, e);
2626      if (With == NULL) break;
2627      strat->redTailChange=TRUE;
2628      if (ksReducePolyTail(L, With, h, strat->kNoether))
2629      {
2630        // reducing the tail would violate the exp bound
2631        if (kStratChangeTailRing(strat, L))
2632        {
2633          strat->kHEdgeFound = save_HE;
2634          return redtail(L, pos, strat);
2635        }
2636        else
2637          return NULL;
2638      }
2639      hn = pNext(h);
2640      if (hn == NULL) goto all_done;
2641      op = pFDeg(hn, strat->tailRing);
2642      if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
2643      e = pLDeg(hn, &l) - op;
2644    }
2645    h = hn;
2646    hn = pNext(h);
2647  }
2648 
2649  all_done:
2650  if (strat->redTailChange)
2651  {
2652    L->last = 0;
2653    L->pLength = 0;
2654  }
2655  strat->kHEdgeFound = save_HE;
2656  return p;
2657}
2658
2659// #define OLD_RED_TAIL
2660#ifdef OLD_RED_TAIL
2661/*2
2662* reduces h using the set S
2663* procedure used in redtail
2664*/
2665/*2
2666*compute the normalform of the tail p->next of p
2667*with respect to S
2668*/
2669poly redtail (poly p, int pos, kStrategy strat)
2670{
2671  if ((!strat->noTailReduction) && (pNext(p)!=NULL))
2672  {
2673    int j, e, l;
2674    unsigned long not_sev;
2675
2676    poly h = p;
2677    poly hn = pNext(h); // !=NULL
2678    int op = pFDeg(hn);
2679    BOOLEAN save_HE=strat->kHEdgeFound;
2680    strat->kHEdgeFound |= ((Kstd1_deg>0) && (op<=Kstd1_deg))
2681                          || TEST_OPT_INFREDTAIL;
2682    loop
2683    {
2684      not_sev = ~ pGetShortExpVector(hn);
2685      e = pLDeg(hn,&l)-op;
2686      j = 0;
2687      while (j <= pos)
2688      {
2689        if (pLmShortDivisibleBy(strat->S[j], strat->sevS[j], hn, not_sev)
2690            && 
2691            ((e >= strat->ecartS[j]) || strat->kHEdgeFound))
2692        {
2693          strat->redTailChange=TRUE;
2694          ksOldSpolyTail(strat->S[j], p, h, strat->kNoether);
2695          hn = pNext(h);
2696          if (hn == NULL) goto all_done;
2697          not_sev = ~ pGetShortExpVector(hn);
2698          op = pFDeg(hn);
2699          if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
2700          e = pLDeg(hn,&l)-op;
2701          j = 0;
2702        }
2703        else
2704        {
2705          j++;
2706        }
2707      } /* while (j <= pos) */
2708      h = hn; /* better for: pIter(h); */
2709      hn = pNext(h);
2710      if (hn==NULL) break;
2711      op = pFDeg(hn);
2712      if ((Kstd1_deg>0)&&(op>Kstd1_deg)) break;
2713    }
2714all_done:
2715    strat->kHEdgeFound = save_HE;
2716  }
2717  return p;
2718}
2719#else
2720poly redtail (poly p, int pos, kStrategy strat)
2721{
2722  LObject L(p, currRing);
2723  return redtail(&L, pos, strat);
2724}
2725#endif
2726
2727poly redtailBba (LObject* L, int pos, kStrategy strat)
2728{
2729  poly h, hn;
2730  int j;
2731  unsigned long not_sev;
2732  strat->redTailChange=FALSE;
2733  poly p = L->p;
2734  LObject Ln(strat->tailRing);
2735  TObject* With;
2736  // placeholder in case strat->tl < 0
2737  TObject  With_s(strat->tailRing);
2738
2739  if (strat->noTailReduction)
2740    return p;
2741  h = p;
2742  hn = pNext(h);
2743  while(hn != NULL)
2744  {
2745    while (1)
2746    {
2747      Ln.Set(hn, strat->tailRing);
2748      Ln.sev = p_GetShortExpVector(hn, strat->tailRing);
2749      With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
2750      if (With == NULL) break;
2751      if (ksReducePolyTail(L, With, h, strat->kNoether))
2752      {
2753        // reducing the tail would violate the exp bound
2754        if (kStratChangeTailRing(strat, L))
2755        {
2756          p = redtailBba(L, pos, strat);
2757          goto all_done;
2758        }
2759        else
2760        {
2761          assume(0);
2762          return NULL;
2763        }
2764      }
2765      strat->redTailChange=TRUE;
2766      hn = pNext(h);
2767      if (hn == NULL) goto all_done;
2768    }
2769    h = hn;
2770    hn = pNext(h);
2771  }
2772
2773  all_done:
2774  if (strat->redTailChange)
2775  {
2776    L->last = NULL;
2777    L->pLength = 0;
2778    L->length = 0;
2779  }
2780  return p;
2781}
2782
2783/*2
2784*checks the change degree and write progress report
2785*/
2786void message (int i,int* reduc,int* olddeg,kStrategy strat)
2787{
2788  if (i != *olddeg)
2789  {
2790    Print("%d",i);
2791    *olddeg = i;
2792  }
2793  if (strat->Ll != *reduc)
2794  {
2795    if (strat->Ll != *reduc-1)
2796      Print("(%d)",strat->Ll+1);
2797    else
2798      PrintS("-");
2799    *reduc = strat->Ll;
2800  }
2801  else
2802    PrintS(".");
2803  mflush();
2804}
2805
2806/*2
2807*statistics
2808*/
2809void messageStat (int srmax,int lrmax,int hilbcount,kStrategy strat)
2810{
2811  //PrintS("\nUsage/Allocation of temporary storage:\n");
2812  //Print("%d/%d polynomials in standard base\n",srmax,IDELEMS(Shdl));
2813  //Print("%d/%d polynomials in set L (for lazy alg.)",lrmax+1,strat->Lmax);
2814  Print("\nproduct criterion:%d chain criterion:%d\n",strat->cp,strat->c3);
2815  if (hilbcount!=0) Print("hilbert series criterion:%d\n",hilbcount);
2816  /*mflush();*/
2817}
2818
2819#ifdef KDEBUG
2820/*2
2821*debugging output: all internal sets, if changed
2822*for testing purpuse only/has to be changed for later use
2823*/
2824void messageSets (kStrategy strat)
2825{
2826  int i;
2827  if (strat->news)
2828  {
2829    PrintS("set S");
2830    for (i=0; i<=strat->sl; i++)
2831    {
2832      Print("\n  %d:",i);
2833      p_wrp(strat->S[i], currRing, strat->tailRing);
2834    }
2835    strat->news = FALSE;
2836  }
2837  if (strat->newt)
2838  {
2839    PrintS("\nset T");
2840    for (i=0; i<=strat->tl; i++)
2841    {
2842      Print("\n  %d:",i);
2843      strat->T[i].wrp();
2844      Print(" o:%d e:%d l:%d",
2845        strat->T[i].pFDeg(),strat->T[i].ecart,strat->T[i].length);
2846    }
2847    strat->newt = FALSE;
2848  }
2849  PrintS("\nset L");
2850  for (i=strat->Ll; i>=0; i--)
2851  {
2852    Print("\n%d:",i);
2853    p_wrp(strat->L[i].p1, currRing, strat->tailRing);
2854    PrintS("  ");
2855    p_wrp(strat->L[i].p2, currRing, strat->tailRing);
2856    PrintS(" lcm: ");p_wrp(strat->L[i].lcm, currRing);
2857    PrintS("\n  p : ");
2858    strat->L[i].wrp();
2859    Print("  o:%d e:%d l:%d",
2860          strat->L[i].pFDeg(),strat->L[i].ecart,strat->L[i].length);
2861  }
2862  PrintLn();
2863}
2864
2865#endif
2866
2867
2868/*2
2869*construct the set s from F
2870*/
2871void initS (ideal F, ideal Q,kStrategy strat)
2872{
2873  int   i,pos;
2874
2875  if (Q!=NULL) i=IDELEMS(Q);
2876  else i=0;
2877  i=((i+IDELEMS(F)+15)/16)*16;
2878  strat->ecartS=initec(i);
2879  strat->sevS=initsevS(i);
2880  strat->S_2_R=initS_2_R(i);
2881  strat->fromQ=NULL;
2882  strat->Shdl=idInit(i,F->rank);
2883  strat->S=strat->Shdl->m;
2884  /*- put polys into S -*/
2885  if (Q!=NULL)
2886  {
2887    strat->fromQ=initec(i);
2888    memset(strat->fromQ,0,i*sizeof(int));
2889    for (i=0; i<IDELEMS(Q); i++)
2890    {
2891      if (Q->m[i]!=NULL)
2892      {
2893        LObject h;
2894        h.p = pCopy(Q->m[i]);
2895        if (TEST_OPT_INTSTRATEGY)
2896        {
2897          //pContent(h.p);
2898          h.pCleardenom(); // also does a pContent
2899        }
2900        else
2901        {
2902          h.pNorm();
2903        }
2904        strat->initEcart(&h);
2905        if (pOrdSgn==-1)
2906        {
2907          deleteHC(&h, strat);
2908        }
2909        if (h.p!=NULL)
2910        {
2911          if (strat->sl==-1)
2912            pos =0;
2913          else
2914          {
2915            pos = posInS(strat->S,strat->sl,h.p);
2916          }
2917          h.sev = pGetShortExpVector(h.p);
2918          strat->enterS(h,pos,strat);
2919          strat->fromQ[pos]=1;
2920        }
2921      }
2922    }
2923  }
2924  for (i=0; i<IDELEMS(F); i++)
2925  {
2926    if (F->m[i]!=NULL)
2927    {
2928      LObject h;
2929      h.p = pCopy(F->m[i]);
2930      if (TEST_OPT_INTSTRATEGY)
2931      {
2932        //pContent(h.p);
2933        h.pCleardenom(); // also does a pContent
2934      }
2935      else
2936      {
2937        h.pNorm();
2938      }
2939      strat->initEcart(&h);
2940      if (pOrdSgn==-1)
2941      {
2942        cancelunit(&h);  /*- tries to cancel a unit -*/
2943        deleteHC(&h, strat);
2944      }
2945      if (TEST_OPT_DEGBOUND
2946          && (((strat->honey) && (h.ecart+pFDeg(h.p)>Kstd1_deg))
2947              || ((!(strat->honey)) && (pFDeg(h.p)>Kstd1_deg))))
2948        pDelete(&h.p);
2949      else
2950        if (h.p!=NULL)
2951        {
2952          if (strat->sl==-1)
2953            pos =0;
2954          else
2955          {
2956            pos = posInS(strat->S,strat->sl,h.p);
2957          }
2958          h.sev = pGetShortExpVector(h.p);
2959          strat->enterS(h,pos,strat);
2960        }
2961    }
2962  }
2963  /*- test, if a unit is in F -*/
2964  if ((strat->sl>=0) && pIsConstant(strat->S[0]))
2965  {
2966    while (strat->sl>0) deleteInS(strat->sl,strat);
2967  }
2968}
2969
2970void initSL (ideal F, ideal Q,kStrategy strat)
2971{
2972  int   i,pos;
2973
2974  if (Q!=NULL) i=IDELEMS(Q);
2975  else i=0;
2976  i=((i+16)/16)*16;
2977  strat->ecartS=initec(i);
2978  strat->sevS=initsevS(i);
2979  strat->S_2_R=initS_2_R(i);
2980  strat->fromQ=NULL;
2981  strat->Shdl=idInit(i,F->rank);
2982  strat->S=strat->Shdl->m;
2983  /*- put polys into S -*/
2984  if (Q!=NULL)
2985  {
2986    strat->fromQ=initec(i);
2987    memset(strat->fromQ,0,i*sizeof(int));
2988    for (i=0; i<IDELEMS(Q); i++)
2989    {
2990      if (Q->m[i]!=NULL)
2991      {
2992        LObject h;
2993        h.p = pCopy(Q->m[i]);
2994        if (TEST_OPT_INTSTRATEGY)
2995        {
2996          //pContent(h.p);
2997          h.pCleardenom(); // also does a pContent
2998        }
2999        else
3000        {
3001          h.pNorm();
3002        }
3003        strat->initEcart(&h);
3004        if (pOrdSgn==-1)
3005        {
3006          deleteHC(&h,strat);
3007        }
3008        if (h.p!=NULL)
3009        {
3010          if (strat->sl==-1)
3011            pos =0;
3012          else
3013          {
3014            pos = posInS(strat->S,strat->sl,h.p);
3015          }
3016          h.sev = pGetShortExpVector(h.p);
3017          strat->enterS(h,pos,strat);
3018          strat->fromQ[pos]=1;
3019        }
3020      }
3021    }
3022  }
3023  for (i=0; i<IDELEMS(F); i++)
3024  {
3025    if (F->m[i]!=NULL)
3026    {
3027      LObject h;
3028      h.p = pCopy(F->m[i]);
3029      if (TEST_OPT_INTSTRATEGY)
3030      {
3031        //pContent(h.p);
3032        h.pCleardenom(); // also does a pContent
3033      }
3034      else
3035      {
3036        h.pNorm();
3037      }
3038      strat->initEcart(&h);
3039      if (pOrdSgn==-1)
3040      {
3041        cancelunit(&h);  /*- tries to cancel a unit -*/
3042        deleteHC(&h, strat);
3043      }
3044      if (TEST_OPT_DEGBOUND
3045          && (((strat->honey) && (h.ecart+pFDeg(h.p)>Kstd1_deg))
3046              || ((!(strat->honey)) && (pFDeg(h.p)>Kstd1_deg))))
3047        pDelete(&h.p);
3048      else
3049        if (h.p!=NULL)
3050        {
3051          if (strat->Ll==-1)
3052            pos =0;
3053          else
3054          {
3055            pos = strat->posInL(strat->L,strat->Ll,&h,strat);
3056          }
3057          h.sev = pGetShortExpVector(h.p);
3058          enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
3059        }
3060    }
3061  }
3062  /*- test, if a unit is in F -*/
3063  if ((strat->Ll>=0) && pIsConstant(strat->L[strat->Ll].p))
3064  {
3065    while (strat->Ll>0) deleteInL(strat->L,&strat->Ll,strat->Ll-1,strat);
3066  }
3067}
3068
3069
3070/*2
3071*construct the set s from F u {P}
3072*/
3073void initSSpecial (ideal F, ideal Q, ideal P,kStrategy strat)
3074{
3075  int   i,pos;
3076
3077  if (Q!=NULL) i=IDELEMS(Q);
3078  else i=0;
3079  i=((i+IDELEMS(F)+15)/16)*16;
3080  strat->ecartS=initec(i);
3081  strat->sevS=initsevS(i);
3082  strat->S_2_R=initS_2_R(i);
3083  strat->fromQ=NULL;
3084  strat->Shdl=idInit(i,F->rank);
3085  strat->S=strat->Shdl->m;
3086
3087  /*- put polys into S -*/
3088  if (Q!=NULL)
3089  {
3090    strat->fromQ=initec(i);
3091    memset(strat->fromQ,0,i*sizeof(int));
3092    for (i=0; i<IDELEMS(Q); i++)
3093    {
3094      if (Q->m[i]!=NULL)
3095      {
3096        LObject h;
3097        h.p = pCopy(Q->m[i]);
3098        //if (TEST_OPT_INTSTRATEGY)
3099        //{
3100        //  //pContent(h.p);
3101        //  h.pCleardenom(); // also does a pContent
3102        //}
3103        //else
3104        //{
3105        //  h.pNorm();
3106        //}
3107        strat->initEcart(&h);
3108        if (pOrdSgn==-1)
3109        {
3110          deleteHC(&h,strat);
3111        }
3112        if (h.p!=NULL)
3113        {
3114          if (strat->sl==-1)
3115            pos =0;
3116          else
3117          {
3118            pos = posInS(strat->S,strat->sl,h.p);
3119          }
3120          h.sev = pGetShortExpVector(h.p);
3121          h.SetpFDeg();
3122          strat->enterS(h,pos,strat, strat->tl+1);
3123          enterT(h, strat);
3124          strat->fromQ[pos]=1;
3125        }
3126      }
3127    }
3128  }
3129  /*- put polys into S -*/
3130  for (i=0; i<IDELEMS(F); i++)
3131  {
3132    if (F->m[i]!=NULL)
3133    {
3134      LObject h;
3135      h.p = pCopy(F->m[i]);
3136      if (pOrdSgn==1)
3137      {
3138        h.p=redtailBba(h.p,strat->sl,strat);
3139      }
3140      strat->initEcart(&h);
3141      if (pOrdSgn==-1)
3142      {
3143        deleteHC(&h,strat);
3144      }
3145      if (TEST_OPT_DEGBOUND
3146      && (((strat->honey) && (h.ecart+pFDeg(h.p)>Kstd1_deg))
3147        || ((!(strat->honey)) && (pFDeg(h.p)>Kstd1_deg))))
3148        pDelete(&h.p);
3149      else
3150      if (h.p!=NULL)
3151      {
3152        if (strat->sl==-1)
3153          pos =0;
3154        else
3155        {
3156          pos = posInS(strat->S,strat->sl,h.p);
3157        }
3158        h.sev = pGetShortExpVector(h.p);
3159        strat->enterS(h,pos,strat, strat->tl+1);
3160        h.length = pLength(h.p);
3161        h.SetpFDeg();
3162        enterT(h,strat);
3163      }
3164    }
3165  }
3166  for (i=0; i<IDELEMS(P); i++)
3167  {
3168    if (P->m[i]!=NULL)
3169    {
3170      LObject h;
3171      h.p=pCopy(P->m[i]);
3172      strat->initEcart(&h);
3173      h.length = pLength(h.p);
3174      if (TEST_OPT_INTSTRATEGY)
3175      {
3176        h.pCleardenom();
3177      }
3178      else
3179      {
3180        h.pNorm();
3181      }
3182      if(strat->sl>=0)
3183      {
3184        if (pOrdSgn==1)
3185        {
3186          h.p=redBba(h.p,strat->sl,strat);
3187          if (h.p!=NULL)
3188            h.p=redtailBba(h.p,strat->sl,strat);
3189        }
3190        else
3191        {
3192          h.p=redMora(h.p,strat->sl,strat);
3193          strat->initEcart(&h);
3194        }
3195        if(h.p!=NULL)
3196        {
3197          if (TEST_OPT_INTSTRATEGY)
3198          {
3199            h.pCleardenom();
3200          }
3201          else
3202          {
3203            h.is_normalized = 0;
3204            h.pNorm();
3205          }
3206          h.sev = pGetShortExpVector(h.p);
3207          h.SetpFDeg();
3208          pos = posInS(strat->S,strat->sl,h.p);
3209          enterpairsSpecial(h.p,strat->sl,h.ecart,pos,strat,strat->tl+1);
3210          strat->enterS(h,pos,strat, strat->tl+1);
3211          enterT(h,strat);
3212        }
3213      }
3214      else
3215      {
3216        h.sev = pGetShortExpVector(h.p);
3217        h.SetpFDeg();
3218        strat->enterS(h,0,strat, strat->tl+1);
3219        enterT(h,strat);
3220      }
3221    }
3222  }
3223}
3224/*2
3225* reduces h using the set S
3226* procedure used in cancelunit1
3227*/
3228static poly redBba1 (poly h,int maxIndex,kStrategy strat)
3229{
3230  int j = 0;
3231  unsigned long not_sev = ~ pGetShortExpVector(h);
3232
3233  while (j <= maxIndex)
3234  {
3235    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j],h, not_sev))
3236       return ksOldSpolyRedNew(strat->S[j],h,strat->kNoether);
3237    else j++;
3238  }
3239  return h;
3240}
3241
3242/*2
3243*tests if p.p=monomial*unit and cancels the unit
3244*/
3245void cancelunit1 (LObject* p,int index,kStrategy strat )
3246{
3247  int k;
3248  poly r,h,h1,q;
3249
3250  if (!pIsVector((*p).p) && ((*p).ecart != 0))
3251  {
3252    k = 0;
3253    h1 = r = pCopy((*p).p);
3254    h =pNext(r);
3255    loop
3256    {
3257      if (h==NULL)
3258      {
3259        pDelete(&r);
3260        pDelete(&(pNext((*p).p)));
3261        (*p).ecart = 0;
3262        (*p).length = 1;
3263        return;
3264      }
3265      if (!pDivisibleBy(r,h))
3266      {
3267        q=redBba1(h,index ,strat);
3268        if (q != h)
3269        {
3270          k++;
3271          pDelete(&h);
3272          pNext(h1) = h = q;
3273        }
3274        else
3275        {
3276          pDelete(&r);
3277          return;
3278        }
3279      }
3280      else
3281      {
3282        h1 = h;
3283        pIter(h);
3284      }
3285      if (k > 10)
3286      {
3287        pDelete(&r);
3288        return;
3289      }
3290    }
3291  }
3292}
3293
3294/*2
3295* reduces h using the elements from Q in the set S
3296* procedure used in updateS
3297* must not be used for elements of Q or elements of an ideal !
3298*/
3299static poly redQ (poly h, int j, kStrategy strat)
3300{
3301  int start;
3302  unsigned long not_sev = ~ pGetShortExpVector(h);
3303  while ((j <= strat->sl) && (pGetComp(strat->S[j])!=0)) j++;
3304  start=j;
3305  while (j<=strat->sl)
3306  {
3307    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev))
3308    {
3309      h = ksOldSpolyRed(strat->S[j],h,strat->kNoether);
3310      if (h==NULL) return NULL;
3311      j = start;
3312      not_sev = ~ pGetShortExpVector(h);
3313    }
3314    else j++;
3315  }
3316  return h;
3317}
3318
3319/*2
3320* reduces h using the set S
3321* procedure used in updateS
3322*/
3323static poly redBba (poly h,int maxIndex,kStrategy strat)
3324{
3325  int j = 0;
3326  unsigned long not_sev = ~ pGetShortExpVector(h);
3327
3328  while (j <= maxIndex)
3329  {
3330    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev))
3331    {
3332      h = ksOldSpolyRed(strat->S[j],h,strat->kNoether);
3333      if (h==NULL) return NULL;
3334      j = 0;
3335      not_sev = ~ pGetShortExpVector(h);    }
3336    else j++;
3337  }
3338  return h;
3339}
3340
3341/*2
3342* reduces h using the set S
3343*e is the ecart of h
3344*procedure used in updateS
3345*/
3346static poly redMora (poly h,int maxIndex,kStrategy strat)
3347{
3348  int  j=0;
3349  int  e,l;
3350  unsigned long not_sev = ~ pGetShortExpVector(h);
3351
3352  if (maxIndex >= 0)
3353  {
3354    e = pLDeg(h,&l)-pFDeg(h);
3355    do
3356    {
3357      if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev)
3358      && ((e >= strat->ecartS[j]) || strat->kHEdgeFound))
3359      {
3360#ifdef KDEBUG
3361        if (TEST_OPT_DEBUG)
3362          {PrintS("reduce ");wrp(h);Print(" with S[%d] (",j);wrp(strat->S[j]);}
3363       
3364#endif         
3365        h = ksOldSpolyRed(strat->S[j],h,strat->kNoether);
3366#ifdef KDEBUG
3367        if(TEST_OPT_DEBUG)
3368          {PrintS(")\nto "); wrp(h); PrintLn();}
3369       
3370#endif
3371        // pDelete(&h);
3372        if (h == NULL) return NULL;
3373        e = pLDeg(h,&l)-pFDeg(h);
3374        j = 0;
3375        not_sev = ~ pGetShortExpVector(h);
3376      }
3377      else j++;
3378    }
3379    while (j <= maxIndex);
3380  }
3381  return h;
3382}
3383
3384/*2
3385*updates S:
3386*the result is a set of polynomials which are in
3387*normalform with respect to S
3388*/
3389void updateS(BOOLEAN toT,kStrategy strat)
3390{
3391  LObject h;
3392  int i, suc=0;
3393  poly redSi=NULL;
3394//Print("nach initS: updateS start mit sl=%d\n",(strat->sl));
3395//  for (i=0; i<=(strat->sl); i++)
3396//  {
3397//    Print("s%d:",i);
3398//    if (strat->fromQ!=NULL) Print("(Q:%d) ",strat->fromQ[i]);
3399//    pWrite(strat->S[i]);
3400//  }
3401  if (pOrdSgn==1)
3402  {
3403    while (suc != -1)
3404    {
3405      i=suc+1;
3406      while (i<=strat->sl)
3407      {
3408        if (((strat->syzComp==0) || (pGetComp(strat->S[i])<=strat->syzComp))
3409        && ((strat->fromQ==NULL) || (strat->fromQ[i]==0)))
3410        {
3411          pDelete(&redSi);
3412          redSi = pHead(strat->S[i]);
3413          strat->S[i] = redBba(strat->S[i],i-1,strat);
3414          if ((strat->ak!=0)&&(strat->S[i]!=NULL))
3415            strat->S[i]=redQ(strat->S[i],i+1,strat); /*reduce S[i] mod Q*/
3416          if (TEST_OPT_DEBUG && (pCmp(redSi,strat->S[i])!=0))
3417          {
3418            PrintS("reduce:");
3419            wrp(redSi);PrintS(" to ");p_wrp(strat->S[i], currRing, strat->tailRing);PrintLn();
3420          }
3421          if (TEST_OPT_PROT && (pCmp(redSi,strat->S[i])!=0))
3422          {
3423            if (strat->S[i]==NULL)
3424              PrintS("V");
3425            else
3426              PrintS("v");
3427            mflush();
3428          }
3429          if (strat->S[i]==NULL)
3430          {
3431            pDelete(&redSi);
3432            deleteInS(i,strat);
3433            i--;
3434          }
3435          else
3436          {
3437            pDelete(&redSi);
3438            if (TEST_OPT_INTSTRATEGY)
3439            {
3440              //pContent(strat->S[i]);
3441              pCleardenom(strat->S[i]);// also does a pContent
3442            }
3443            else
3444            {
3445              pNorm(strat->S[i]);
3446            }
3447            strat->sevS[i] = pGetShortExpVector(strat->S[i]);
3448          }
3449        }
3450        i++;
3451      }
3452      reorderS(&suc,strat);
3453    }
3454    if (toT)
3455    {
3456      for (i=0; i<=strat->sl; i++)
3457      {
3458        if (((strat->fromQ==NULL) || (strat->fromQ[i]==0))
3459        )
3460          h.p = redtailBba(strat->S[i],i-1,strat);
3461        else
3462        {
3463          h.p = strat->S[i];
3464        }
3465        if (strat->honey)
3466        {
3467          strat->initEcart(&h);
3468          strat->ecartS[i] = h.ecart;
3469        }
3470        if (strat->sevS[i] == 0) {strat->sevS[i] = pGetShortExpVector(h.p);}
3471        else assume(strat->sevS[i] == pGetShortExpVector(h.p));
3472        h.sev = strat->sevS[i];
3473        h.SetpFDeg();
3474        /*puts the elements of S also to T*/
3475        enterT(h,strat);
3476        strat->S_2_R[i] = strat->tl;
3477      }
3478    }
3479  }
3480  else
3481  {
3482    while (suc != -1)
3483    {
3484      i=suc+1;
3485      while (i<=strat->sl)
3486      {
3487        if (((strat->syzComp==0) || (pGetComp(strat->S[i])<=strat->syzComp))
3488        && ((strat->fromQ==NULL) || (strat->fromQ[i]==0)))
3489        {
3490          pDelete(&redSi);
3491          redSi=pHead((strat->S)[i]);
3492          (strat->S)[i] = redMora((strat->S)[i],i-1,strat);
3493          if ((strat->S)[i]==NULL)
3494          {
3495            deleteInS(i,strat);
3496            i--;
3497          }
3498          else
3499          {
3500            if (TEST_OPT_INTSTRATEGY)
3501            {
3502              pDelete(&redSi);
3503              pCleardenom(strat->S[i]);// also does a pContent
3504              h.p = strat->S[i];
3505              strat->initEcart(&h);
3506              strat->ecartS[i] = h.ecart;
3507            }
3508            else
3509            {
3510              pDelete(&redSi);
3511              pNorm(strat->S[i]);
3512              h.p = strat->S[i];
3513              strat->initEcart(&h);
3514              strat->ecartS[i] = h.ecart;
3515            }
3516            h.sev =  pGetShortExpVector(h.p);
3517            strat->sevS[i] = h.sev;
3518          }
3519          kTest(strat);
3520        }
3521        i++;
3522      }
3523#ifdef KDEBUG
3524      kTest(strat);
3525#endif
3526      reorderS(&suc,strat);
3527      if (h.p!=NULL)
3528      {
3529        if (!strat->kHEdgeFound)
3530        {
3531          /*strat->kHEdgeFound =*/ HEckeTest(h.p,strat);
3532        }
3533        if (strat->kHEdgeFound)
3534          newHEdge(strat->S,strat->ak,strat);
3535      }
3536    }
3537    for (i=0; i<=strat->sl; i++)
3538    {
3539      if (((strat->fromQ==NULL) || (strat->fromQ[i]==0))
3540      )
3541      {
3542        strat->S[i] = h.p = redtail(strat->S[i],strat->sl,strat);
3543        strat->initEcart(&h);
3544        strat->ecartS[i] = h.ecart;
3545        h.sev = pGetShortExpVector(h.p);
3546        strat->sevS[i] = h.sev;
3547      }
3548      else
3549      {
3550        h.p = strat->S[i];
3551        h.ecart=strat->ecartS[i];
3552        h.sev = strat->sevS[i];
3553      }
3554      if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
3555        cancelunit1(&h,strat->sl,strat);
3556      h.length = pLength(h.p);
3557      h.SetpFDeg();
3558      /*puts the elements of S also to T*/
3559      enterT(h,strat);
3560      strat->S_2_R[i] = strat->tl;
3561    }
3562  }
3563  if (redSi!=NULL) pDeleteLm(&redSi);
3564#ifdef KDEBUG
3565  kTest(strat);
3566#endif
3567}
3568
3569
3570/*2
3571* -puts p to the standardbasis s at position at
3572* -saves the result in S
3573*/
3574void enterSBba (LObject p,int atS,kStrategy strat, int atR)
3575{
3576  int i;
3577  strat->news = TRUE;
3578  /*- puts p to the standardbasis s at position at -*/
3579  if (strat->sl == IDELEMS(strat->Shdl)-1)
3580  {
3581    strat->sevS = (unsigned long*) omRealloc0Size(strat->sevS,
3582                                    IDELEMS(strat->Shdl)*sizeof(unsigned long),
3583                                    (IDELEMS(strat->Shdl)+setmax)
3584                                                  *sizeof(unsigned long));
3585    strat->ecartS = (intset)omReallocSize(strat->ecartS,
3586                                          IDELEMS(strat->Shdl)*sizeof(int),
3587                                          (IDELEMS(strat->Shdl)+setmax)*sizeof(int));
3588    strat->S_2_R = (int*) omRealloc0Size(strat->S_2_R, 
3589                                         IDELEMS(strat->Shdl)*sizeof(int),
3590                                         (IDELEMS(strat->Shdl)+setmax)
3591                                                  *sizeof(int));
3592    if (strat->fromQ!=NULL)
3593    {
3594      strat->fromQ = (intset)omReallocSize(strat->fromQ,
3595                                    IDELEMS(strat->Shdl)*sizeof(int),
3596                                    (IDELEMS(strat->Shdl)+setmax)*sizeof(int));
3597    }
3598    pEnlargeSet(&strat->S,IDELEMS(strat->Shdl),setmax);
3599    IDELEMS(strat->Shdl)+=setmax;
3600    strat->Shdl->m=strat->S;
3601  }
3602  if (atS <= strat->sl)
3603  {
3604#ifdef ENTER_USE_MEMMOVE
3605// #if 0
3606    memmove(&(strat->S[atS+1]), &(strat->S[atS]), 
3607            (strat->sl - atS + 1)*sizeof(poly));
3608    memmove(&(strat->ecartS[atS+1]), &(strat->ecartS[atS]), 
3609            (strat->sl - atS + 1)*sizeof(int));
3610    memmove(&(strat->sevS[atS+1]), &(strat->sevS[atS]), 
3611            (strat->sl - atS + 1)*sizeof(unsigned long));
3612    memmove(&(strat->S_2_R[atS+1]), &(strat->S_2_R[atS]), 
3613            (strat->sl - atS + 1)*sizeof(int));
3614#else   
3615    for (i=strat->sl+1; i>=atS+1; i--)
3616    {
3617      strat->S[i] = strat->S[i-1];
3618      strat->ecartS[i] = strat->ecartS[i-1];
3619      strat->sevS[i] = strat->sevS[i-1];
3620      strat->S_2_R[i] = strat->S_2_R[i-1];
3621    }
3622#endif
3623  }
3624  if (strat->fromQ!=NULL)
3625  {
3626    for (i=strat->sl+1; i>=atS+1; i--)
3627    {
3628      strat->fromQ[i] = strat->fromQ[i-1];
3629    }
3630    strat->fromQ[atS]=0;
3631  }
3632
3633  /*- save result -*/
3634  strat->S[atS] = p.p;
3635  if (strat->honey) strat->ecartS[atS] = p.ecart;
3636  if (p.sev == 0)
3637    p.sev = pGetShortExpVector(p.p);
3638  else
3639    assume(p.sev == pGetShortExpVector(p.p));
3640  strat->sevS[atS] = p.sev;
3641  strat->ecartS[atS] = p.ecart;
3642  strat->S_2_R[atS] = atR;
3643  strat->sl++;
3644}
3645
3646/*2
3647* puts p to the set T at position atT
3648*/
3649void enterT(LObject p, kStrategy strat, int atT = -1)
3650{
3651  int i;
3652
3653  pp_Test(p.p, currRing, p.tailRing);
3654  assume(strat->tailRing == p.tailRing);
3655  // redMoraNF complains about this -- but, we don't really
3656  // neeed this so far
3657  // assume(p.pLength == 0 || pLength(p.p) == p.pLength);
3658  assume(p.FDeg == p.pFDeg());
3659  assume(!p.is_normalized || nIsOne(pGetCoeff(p.p)));
3660
3661  strat->newt = TRUE;
3662  if (atT < 0)
3663    atT = strat->posInT(strat->T, strat->tl, p);
3664  if (strat->tl == strat->tmax-1) 
3665    enlargeT(strat->T,strat->R,strat->sevT,strat->tmax,setmax);
3666  if (atT <= strat->tl)
3667  {
3668#ifdef ENTER_USE_MEMMOVE
3669    memmove(&(strat->T[atT+1]), &(strat->T[atT]), 
3670            (strat->tl-atT+1)*sizeof(TObject));
3671    memmove(&(strat->sevT[atT+1]), &(strat->sevT[atT]), 
3672            (strat->tl-atT+1)*sizeof(unsigned long));
3673#endif
3674    for (i=strat->tl+1; i>=atT+1; i--)
3675    {
3676#ifndef ENTER_USE_MEMMOVE
3677      strat->T[i] = strat->T[i-1];
3678      strat->sevT[i] = strat->sevT[i-1];
3679#endif
3680      strat->R[strat->T[i].i_r] = &(strat->T[i]);
3681    }
3682  }
3683
3684  if (strat->tailBin != NULL && (pNext(p.p) != NULL))
3685  {
3686    pNext(p.p)=p_ShallowCopyDelete(pNext(p.p),
3687                                   (strat->tailRing != NULL ? 
3688                                    strat->tailRing : currRing),
3689                                   strat->tailBin);
3690    if (p.t_p != NULL) pNext(p.t_p) = pNext(p.p);
3691  }
3692  strat->T[atT] = (TObject) p;
3693
3694  if (strat->tailRing != currRing && pNext(p.p) != NULL)
3695    strat->T[atT].max = p_GetMaxExpP(pNext(p.p), strat->tailRing);
3696  else
3697    strat->T[atT].max = NULL;
3698
3699  strat->tl++;
3700  strat->R[strat->tl] = &(strat->T[atT]);
3701  strat->T[atT].i_r = strat->tl;
3702  assume(p.sev == 0 || pGetShortExpVector(p.p) == p.sev);
3703  strat->sevT[atT] = (p.sev == 0 ? pGetShortExpVector(p.p) : p.sev);
3704  kTest_T(&(strat->T[atT]));
3705}
3706
3707void initHilbCrit(ideal F, ideal Q, intvec **hilb,kStrategy strat)
3708{
3709  if (strat->homog!=isHomog)
3710  {
3711    *hilb=NULL;
3712  }
3713}
3714
3715void initBuchMoraCrit(kStrategy strat)
3716{
3717  strat->sugarCrit =        TEST_OPT_SUGARCRIT;
3718  // obachman: Hmm.. I need BTEST1(2) for notBuckets ..
3719  //  strat->Gebauer =          BTEST1(2) || strat->homog || strat->sugarCrit;
3720  strat->Gebauer =          strat->homog || strat->sugarCrit;
3721  strat->honey =            !strat->homog || strat->sugarCrit || TEST_OPT_WEIGHTM;
3722  if (TEST_OPT_NOT_SUGAR) strat->honey = FALSE;
3723  strat->pairtest = NULL;
3724  /* alway use tailreduction, except:
3725  * - in local rings, - in lex order case, -in ring over extensions */
3726  strat->noTailReduction = !TEST_OPT_REDTAIL;
3727  if (TEST_OPT_DEBUG)
3728  {
3729    if (strat->homog) PrintS("ideal/module is homogeneous\n");
3730    else              PrintS("ideal/module is not homogeneous\n");
3731  }
3732}
3733
3734BOOLEAN kPosInLDependsOnLength(int (*pos_in_l)
3735                               (const LSet set, const int length,
3736                                LObject* L,const kStrategy strat))
3737{
3738  if (pos_in_l == posInL110 ||
3739      pos_in_l == posInL10) 
3740    return TRUE;
3741
3742  return FALSE;
3743}
3744
3745void initBuchMoraPos (kStrategy strat)
3746{
3747  if (pOrdSgn==1)
3748  {
3749    if (strat->honey)
3750    {
3751      strat->posInL = posInL15;
3752      strat->posInT = posInT15;
3753    }
3754    else if (pLexOrder && !TEST_OPT_INTSTRATEGY)
3755    {
3756      strat->posInL = posInL11;
3757      strat->posInT = posInT11;
3758    }
3759    else if (TEST_OPT_INTSTRATEGY)
3760    {
3761      strat->posInL = posInL11;
3762      strat->posInT = posInT11;
3763    }
3764    else
3765    {
3766      strat->posInL = posInL0;
3767      strat->posInT = posInT0;
3768    }
3769    //if (strat->minim>0) strat->posInL =posInLSpecial;
3770  }
3771  else
3772  {
3773    if (strat->homog)
3774    {
3775      strat->posInL = posInL11;
3776      strat->posInT = posInT11;
3777    }
3778    else
3779    {
3780      if ((currRing->order[0]==ringorder_c)
3781      ||(currRing->order[0]==ringorder_C))
3782      {
3783        strat->posInL = posInL17_c;
3784        strat->posInT = posInT17_c;
3785      }
3786      else
3787      {
3788        strat->posInL = posInL17;
3789        strat->posInT = posInT17;
3790      }
3791    }
3792  }
3793  if (strat->minim>0) strat->posInL =posInLSpecial;
3794  // for further tests only
3795  if ((BTEST1(11)) || (BTEST1(12)))
3796    strat->posInL = posInL11;
3797  else if ((BTEST1(13)) || (BTEST1(14)))
3798    strat->posInL = posInL13;
3799  else if ((BTEST1(15)) || (BTEST1(16)))
3800    strat->posInL = posInL15;
3801  else if ((BTEST1(17)) || (BTEST1(18)))
3802    strat->posInL = posInL17;
3803  if (BTEST1(11))
3804    strat->posInT = posInT11;
3805  else if (BTEST1(13))
3806    strat->posInT = posInT13;
3807  else if (BTEST1(15))
3808    strat->posInT = posInT15;
3809  else if ((BTEST1(17)))
3810    strat->posInT = posInT17;
3811  else if ((BTEST1(19)))
3812    strat->posInT = posInT19;
3813  else if (BTEST1(12) || BTEST1(14) || BTEST1(16) || BTEST1(18))
3814    strat->posInT = posInT1;
3815  strat->posInLDependsOnLength = kPosInLDependsOnLength(strat->posInL);
3816}
3817
3818void initBuchMora (ideal F,ideal Q,kStrategy strat)
3819{
3820  strat->interpt = BTEST1(OPT_INTERRUPT);
3821  strat->kHEdge=NULL;
3822  if (pOrdSgn==1) strat->kHEdgeFound=FALSE;
3823  /*- creating temp data structures------------------- -*/
3824  strat->cp = 0;
3825  strat->c3 = 0;
3826  strat->tail = pInit();
3827  /*- set s -*/
3828  strat->sl = -1;
3829  /*- set L -*/
3830  strat->Lmax = setmax;
3831  strat->Ll = -1;
3832  strat->L = initL();
3833  /*- set B -*/
3834  strat->Bmax = setmax;
3835  strat->Bl = -1;
3836  strat->B = initL();
3837  /*- set T -*/
3838  strat->tl = -1;
3839  strat->tmax = setmax;
3840  strat->T = initT();
3841  strat->R = initR();
3842  strat->sevT = initsevT();
3843  /*- init local data struct.---------------------------------------- -*/
3844  strat->P.ecart=0;
3845  strat->P.length=0;
3846  if (pOrdSgn==-1)
3847  {
3848    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
3849    if (strat->kNoether!=NULL) pSetComp(strat->kNoether, strat->ak);
3850  }
3851  if(TEST_OPT_SB_1)
3852  {
3853    int i;
3854    ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
3855    for (i=strat->newIdeal;i<IDELEMS(F);i++)
3856    {
3857      P->m[i-strat->newIdeal] = F->m[i];
3858      F->m[i] = NULL;
3859    }
3860    initSSpecial(F,Q,P,strat);
3861    for (i=strat->newIdeal;i<IDELEMS(F);i++)
3862    {
3863      F->m[i] = P->m[i-strat->newIdeal];
3864      P->m[i-strat->newIdeal] = NULL;
3865    }
3866    idDelete(&P);
3867  }
3868  else
3869  {
3870    /*Shdl=*/initSL(F, Q,strat); /*sets also S, ecartS, fromQ */
3871    // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
3872  }
3873  strat->kIdeal = NULL;
3874  strat->fromT = FALSE;
3875  strat->noTailReduction = !TEST_OPT_REDTAIL;
3876  if(!TEST_OPT_SB_1)
3877  {
3878    updateS(TRUE,strat);
3879    pairs(strat);
3880  }
3881  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
3882  strat->fromQ=NULL;
3883}
3884
3885void exitBuchMora (kStrategy strat)
3886{
3887  /*- release temp data -*/
3888  cleanT(strat);
3889  omFreeSize(strat->T,(strat->tmax)*sizeof(TObject));
3890  omFreeSize(strat->R,(strat->tmax)*sizeof(TObject*));
3891  omFreeSize(strat->sevT, (strat->tmax)*sizeof(unsigned long));
3892  omFreeSize(strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
3893  omFreeSize(strat->sevS,IDELEMS(strat->Shdl)*sizeof(int));
3894  omFreeSize(strat->S_2_R,IDELEMS(strat->Shdl)*sizeof(int));
3895  /*- set L: should be empty -*/
3896  omFreeSize(strat->L,(strat->Lmax)*sizeof(LObject));
3897  /*- set B: should be empty -*/
3898  omFreeSize(strat->B,(strat->Bmax)*sizeof(LObject));
3899  pDeleteLm(&strat->tail);
3900  strat->syzComp=0;
3901  if (strat->kIdeal!=NULL)
3902  {
3903    omFreeBin(strat->kIdeal, sleftv_bin);
3904    strat->kIdeal=NULL;
3905  }
3906}
3907
3908/*2
3909* in the case of a standardbase of a module over a qring:
3910* replace polynomials in i by ak vectors,
3911* (the polynomial * unit vectors gen(1)..gen(ak)
3912* in every case (also for ideals:)
3913* deletes divisible vectors/polynomials
3914*/
3915void updateResult(ideal r,ideal Q,kStrategy strat)
3916{
3917  int l;
3918  if (strat->ak>0)
3919  {
3920    for (l=IDELEMS(r)-1;l>=0;l--)
3921    {
3922      if ((r->m[l]!=NULL) && (pGetComp(r->m[l])==0))
3923      {
3924        pDelete(&r->m[l]); // and set it to NULL
3925      }
3926    }
3927  }
3928  else
3929  {
3930    int q;
3931    poly p;
3932    for (l=IDELEMS(r)-1;l>=0;l--)
3933    {
3934      if (r->m[l]!=NULL)
3935      {
3936        for(q=IDELEMS(Q)-1; q>=0;q--)
3937        {
3938          if ((Q->m[q]!=NULL)
3939          &&(pLmEqual(r->m[l],Q->m[q])))
3940          {
3941            if (TEST_OPT_REDSB)
3942            {
3943              p=r->m[l];
3944              r->m[l]=kNF(Q,NULL,p);
3945              pDelete(&p);
3946            }
3947            else
3948            {
3949              pDelete(&r->m[l]); // and set it to NULL
3950            }
3951            break;
3952          }
3953        }
3954      }
3955    }
3956  }
3957  idSkipZeroes(r);
3958}
3959
3960void completeReduce (kStrategy strat)
3961{
3962  int i;
3963
3964  strat->noTailReduction = FALSE;
3965  if (TEST_OPT_PROT)
3966  {
3967    PrintLn();
3968    if (timerv) writeTime("standard base computed:");
3969  }
3970  if (TEST_OPT_PROT)
3971  {
3972    Print("(S:%d)",strat->sl);mflush();
3973  }
3974  if(pOrdSgn==1)
3975  {
3976    for (i=strat->sl; i>0; i--)
3977    {
3978      //if (strat->interpt) test_int_std(strat->kIdeal);
3979      strat->S[i] = redtailBba(strat->S[i],i-1,strat);
3980      if (TEST_OPT_INTSTRATEGY)
3981      {
3982        //if (strat->redTailChange)
3983          pCleardenom(strat->S[i]);
3984      }
3985      if (TEST_OPT_PROT)
3986      {
3987        PrintS("-");mflush();
3988      }
3989    }
3990  }
3991  else
3992  {
3993    for (i=strat->sl; i>=0; i--)
3994    {
3995      strat->S[i] = redtail(strat->S[i],strat->sl,strat);
3996      // Hmm .. this might also change strat->T[i]
3997      // but, we don't need it any more
3998      if (TEST_OPT_INTSTRATEGY)
3999        pCleardenom(strat->S[i]);
4000      if (TEST_OPT_PROT)
4001        PrintS("-");
4002    }
4003  }
4004}
4005
4006
4007/*2
4008* computes the new strat->kHEdge and the new pNoether,
4009* returns TRUE, if pNoether has changed
4010*/
4011BOOLEAN newHEdge(polyset S, int ak,kStrategy strat)
4012{
4013  int i,j;
4014  poly newNoether;
4015
4016  scComputeHC(strat->Shdl,ak,strat->kHEdge);
4017  /* compare old and new noether*/
4018  newNoether = pLmInit(strat->kHEdge);
4019  j = pFDeg(newNoether);
4020  for (i=1; i<=pVariables; i++)
4021  {
4022    if (pGetExp(newNoether, i) > 0) pDecrExp(newNoether,i);
4023  }
4024  pSetm(newNoether);
4025  if (j < strat->HCord) /*- statistics -*/
4026  {
4027    if (TEST_OPT_PROT)
4028    {
4029      Print("H(%d)",j);
4030      mflush();
4031    }
4032    strat->HCord=j;
4033    if (TEST_OPT_DEBUG)
4034    {
4035      Print("H(%d):",j);
4036      wrp(strat->kHEdge);
4037      PrintLn();
4038    }
4039  }
4040  if (pCmp(strat->kNoether,newNoether)!=1)
4041  {
4042    pDelete(&strat->kNoether);
4043    strat->kNoether=newNoether;
4044    return TRUE;
4045  }
4046  pLmFree(newNoether);
4047  return FALSE;
4048}
4049
4050/***************************************************************
4051 *
4052 * Routines related for ring changes during std computations
4053 *
4054 ***************************************************************/
4055BOOLEAN kCheckSpolyCreation(LObject *L, kStrategy strat, poly &m1, poly &m2)
4056{
4057  assume(L->p1 != NULL && L->p2 != NULL);
4058  assume(L->i_r1 >= 0 && L->i_r1 <= strat->tl);
4059  assume(L->i_r2 >= 0 && L->i_r2 <= strat->tl);
4060  assume(strat->tailRing != currRing);
4061 
4062  if (! k_GetLeadTerms(L->p1, L->p2, currRing, m1, m2, strat->tailRing))
4063    return FALSE;
4064  poly p1_max = (strat->R[L->i_r1])->max;
4065  poly p2_max = (strat->R[L->i_r2])->max;
4066 
4067  if ((p1_max != NULL && !p_LmExpVectorAddIsOk(m1, p1_max, strat->tailRing)) ||
4068      (p2_max != NULL && !p_LmExpVectorAddIsOk(m2, p2_max, strat->tailRing)))
4069  {
4070    p_LmFree(m1, strat->tailRing);
4071    p_LmFree(m2, strat->tailRing);
4072    m1 = NULL;
4073    m2 = NULL;
4074    return FALSE;
4075  }
4076  return TRUE;
4077}
4078                       
4079BOOLEAN kStratChangeTailRing(kStrategy strat, LObject *L, TObject* T, unsigned long expbound)
4080{
4081  if (expbound == 0) expbound = strat->tailRing->bitmask << 1;
4082  if (expbound >= currRing->bitmask) return FALSE;
4083  ring new_tailRing = rModifyRing(currRing,
4084                                  // Hmmm .. the condition pFDeg == pDeg
4085                                  // might be too strong
4086                                  (strat->homog && pFDeg == pDeg && pOrdSgn == 1), 
4087                                  !strat->ak, 
4088                                  expbound);
4089
4090  if (new_tailRing == currRing) return TRUE;
4091  if (TEST_OPT_PROT)
4092    Print("[%d:%d", (long) new_tailRing->bitmask, new_tailRing->ExpL_Size);
4093  kTest_TS(strat);
4094  assume(new_tailRing != strat->tailRing);
4095  pShallowCopyDeleteProc p_shallow_copy_delete
4096    = pGetShallowCopyDeleteProc(strat->tailRing, new_tailRing);
4097 
4098  omBin new_tailBin = omGetStickyBinOfBin(new_tailRing->PolyBin);
4099 
4100  int i;
4101  for (i=0; i<=strat->tl; i++)
4102  {
4103    strat->T[i].ShallowCopyDelete(new_tailRing, new_tailBin, 
4104                                  p_shallow_copy_delete);
4105  }
4106  for (i=0; i<=strat->Ll; i++)
4107  {
4108    assume(strat->L[i].p != NULL);
4109    if (pNext(strat->L[i].p) != strat->tail)
4110      strat->L[i].ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
4111  }
4112  if (strat->P.t_p != NULL || 
4113      (strat->P.p != NULL && pNext(strat->P.p) != strat->tail))
4114    strat->P.ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
4115 
4116  if (L != NULL && L->tailRing != new_tailRing)
4117    L->ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
4118  if (T != NULL && T->tailRing != new_tailRing)
4119    T->ShallowCopyDelete(new_tailRing, new_tailBin, p_shallow_copy_delete);
4120   
4121  omMergeStickyBinIntoBin(strat->tailBin, strat->tailRing->PolyBin);
4122  if (strat->tailRing != currRing)
4123    rKillModifiedRing(strat->tailRing);
4124 
4125  strat->tailRing = new_tailRing;
4126  strat->tailBin = new_tailBin;
4127  strat->p_shallow_copy_delete
4128    = pGetShallowCopyDeleteProc(currRing, new_tailRing);
4129  kTest_TS(strat);
4130  if (TEST_OPT_PROT)
4131    PrintS("]");
4132  return TRUE;
4133}
4134
4135void kStratInitChangeTailRing(kStrategy strat)
4136{
4137  unsigned long l = 0;
4138  int i;
4139  Exponent_t e;
4140  ring new_tailRing;
4141 
4142  assume(strat->tailRing == currRing);
4143
4144  for (i=0; i<= strat->Ll; i++)
4145  {
4146    l = p_GetMaxExpL(strat->L[i].p, currRing, l);
4147  }
4148  for (i=0; i<=strat->tl; i++)
4149  {
4150    // Hmm ... this we could do in one Step
4151    l = p_GetMaxExpL(strat->T[i].p, currRing, l);
4152  }
4153  e = p_GetMaxExp(l, currRing);
4154  if (e <= 1) e = 2;
4155 
4156  kStratChangeTailRing(strat, NULL, NULL, e);
4157}
4158
4159#endif // KUTIL_CC
Note: See TracBrowser for help on using the repository browser.