source: git/Singular/kutil.cc @ 512a2b

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