source: git/Singular/kutil.cc @ 24d587

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