source: git/kernel/kutil.cc @ 7523a7

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