source: git/Singular/kbuckets.cc @ 416465

spielwiese
Last change on this file since 416465 was 416465, checked in by Olaf Bachmann <obachman@…>, 24 years ago
* bug-fixes from work with Thomas git-svn-id: file:///usr/local/Singular/svn/trunk@3826 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 23.1 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: kbuckets.cc,v 1.12 1999-11-15 17:20:12 obachman Exp $ */
5
6#include "mod2.h"
7#include "tok.h"
8#include "structs.h"
9#include "mmemory.h"
10#include "polys.h"
11#include "febase.h"
12#include "prProcs.h"
13#include "kbuckets.h"
14#include "numbers.h"
15
16#ifdef HAVE_BUCKETS
17
18//////////////////////////////////////////////////////////////////////////
19///
20/// Some internal stuff
21///
22
23// returns ceil(log_4(l))
24inline unsigned int pLogLength(unsigned int l)
25{
26  unsigned int i = 0;
27
28  if (l == 0) return 0;
29  l--;
30  while ((l = (l >> 2))) i++;
31  return i+1;
32}
33
34// returns ceil(log_4(pLength(p)))
35inline unsigned int pLogLength(poly p)
36{
37  return pLogLength((unsigned int) pLength(p));
38}
39
40
41
42#if defined(PDEBUG) && ! defined(HAVE_PSEUDO_BUCKETS)
43
44#define kbTests(bucket) kbDBTests(bucket, __FILE__, __LINE__)
45#define kbTest(bucket, i) kbDBTest(bucket, i, __FILE__, __LINE__)
46
47void kbDBTest(kBucket_pt bucket, int i, char* file, int line)
48{
49  if (pDBTest(bucket->buckets[i], file, line))
50  {
51    if (bucket->buckets_length[i] != pLength(bucket->buckets[i]))
52    {
53      Warn("Bucket %d lengths difference should:%d has:%d in %s:%d",
54            i, bucket->buckets_length[i], pLength(bucket->buckets[i]),
55            file, line);
56      assume(0);
57    }
58    else if (i > 0 && (int) pLogLength(bucket->buckets_length[i]) > i)
59    {
60      Warn("Bucket %d too long %d in %s:%d",
61            i, bucket->buckets_length[i], file, line);
62      assume(0);
63    }
64  }
65  if (i==0 && bucket->buckets_length[0] > 1)
66  {
67    Warn("Bucket 0 too long");
68  }
69}
70
71
72void kbDBTests(kBucket_pt bucket, char* file, int line)
73{
74  int i;
75  poly lm = bucket->buckets[0];
76
77  kbDBTest(bucket, 0, file, line);
78  for (i=1; i<= (int) bucket->buckets_used; i++)
79  {
80    kbDBTest(bucket, i, file, line);
81    if (lm != NULL &&  bucket->buckets[i] != NULL
82        && pComp0(lm, bucket->buckets[i]) != 1)
83    {
84      Warn("Bucket %d larger than lm in %s:%d", i, file, line);
85      assume(0);
86    }
87  }
88
89  for (; i<=MAX_BUCKET; i++)
90  {
91    if (bucket->buckets[i] != NULL || bucket->buckets_length[i] != 0)
92    {
93      Warn("Bucket %d not zero in %s:%d", i, file, line);
94      assume(0);
95    }
96  }
97}
98
99#else
100
101#define kbTests(bucket) (NULL)
102#define kbTest(bucket, i) (NULL)
103
104#endif // PDEBUG
105
106//////////////////////////////////////////////////////////////////////////
107///
108/// Creation/Destruction of buckets
109///
110
111kBucket_pt kBucketCreate()
112{
113  kBucket_pt bucket = (kBucket_pt) Alloc0SizeOf(kBucket);
114  return bucket;
115}
116
117void kBucketDestroy(kBucket_pt *bucket)
118{
119  FreeSizeOf(*bucket, kBucket);
120  *bucket = NULL;
121}
122
123
124/////////////////////////////////////////////////////////////////////////////
125// Convertion from/to Bpolys
126//
127#ifndef HAVE_PSEUDO_BUCKETS
128
129inline void kBucketAdjustBucketsUsed(kBucket_pt bucket)
130{
131  while ( bucket->buckets_used > 0 &&
132          bucket->buckets[bucket->buckets_used] == NULL)
133    (bucket->buckets_used)--;
134}
135
136inline void kBucketMergeLm(kBucket_pt bucket)
137{
138  if (bucket->buckets[0] != NULL)
139  {
140    poly lm = bucket->buckets[0];
141    int i = 1;
142    int l = 4;
143    while ( bucket->buckets_length[i] >= l)
144    {
145      i++;
146      l = l << 2;
147    }
148    pNext(lm) = bucket->buckets[i];
149    bucket->buckets[i] = lm;
150    bucket->buckets_length[i]++;
151    assume(i <= bucket->buckets_used+1);
152    if (i > bucket->buckets_used)  bucket->buckets_used = i;
153    bucket->buckets[0] = NULL;
154    bucket->buckets_length[0] = 0;
155  }
156}
157
158
159static BOOLEAN kBucketIsCleared(kBucket_pt bucket)
160{
161  int i;
162
163  for (i = 0;i<=MAX_BUCKET;i++)
164  {
165    if (bucket->buckets[i] != NULL) return FALSE;
166    if (bucket->buckets_length[i] != 0) return FALSE;
167  }
168  return TRUE;
169}
170
171void kBucketInit(kBucket_pt bucket, poly lm, int length,
172                 memHeap heap)
173{
174  int i;
175  assume(bucket != NULL);
176  assume(length <= 0 || length == pLength(lm));
177  assume(kBucketIsCleared(bucket));
178
179  if (length <= 0)
180    length = pLength(lm);
181
182  bucket->buckets[0] = lm;
183  if (length > 1)
184  {
185    unsigned int i = pLogLength(length-1);
186    bucket->buckets[i] = pNext(lm);
187    pNext(lm) = NULL;
188    bucket->buckets_length[i] = length-1;
189    bucket->buckets_used = i;
190    bucket->buckets_length[0] = 1;
191  }
192  else
193  {
194    bucket->buckets_used = 0;
195    bucket->buckets_length[0] = 0;
196  }
197  if (heap == NULL) bucket->heap = mm_specHeap;
198  else bucket->heap = heap;
199}
200
201static int kBucketCanonicalize(kBucket_pt bucket);
202
203static void kBucketSetLm(kBucket_pt bucket)
204{
205  int j = 0;
206  poly lt;
207  BOOLEAN zero = FALSE;
208  assume(bucket->buckets[0] == NULL && bucket->buckets_length[0] == 0);
209
210  do
211  {
212    j = 0;
213    for (int i = 1; i<=bucket->buckets_used; i++)
214    {
215      if (bucket->buckets[i] != NULL)
216      {
217        int comp = (j == 0 ? 1 :
218                    pComp0(bucket->buckets[i], bucket->buckets[j]));
219
220        if (comp > 0)
221        {
222          if (j > 0 &&
223              bucket->buckets[j] != NULL &&
224              nIsZero(pGetCoeff(bucket->buckets[j])))
225          {
226            kb_pDelete1AndAdvance(bucket->buckets[j], bucket->heap);
227            (bucket->buckets_length[j])--;
228          }
229          j = i;
230        }
231        else if (comp == 0)
232        {
233          number tn = pGetCoeff(bucket->buckets[j]);
234          pSetCoeff0(bucket->buckets[j],
235                     nAdd(pGetCoeff(bucket->buckets[i]), tn));
236          nDelete(&tn);
237          kb_pDelete1AndAdvance(bucket->buckets[i], bucket->heap);
238          (bucket->buckets_length[i])--;
239        }
240      }
241    }
242    if (j > 0 && nIsZero(pGetCoeff(bucket->buckets[j])))
243    {
244      kb_pDelete1AndAdvance(bucket->buckets[j], bucket->heap);
245      (bucket->buckets_length[j])--;
246      j = -1;
247    }
248  }
249  while (j < 0);
250
251  if (j == 0)
252  {
253    return;
254  }
255
256  assume(bucket->buckets[j] != NULL);
257  lt = bucket->buckets[j];
258  bucket->buckets[j] = pNext(lt);
259  bucket->buckets_length[j]--;
260  pNext(lt) = NULL;
261  bucket->buckets[0] = lt;
262  bucket->buckets_length[0] = 1;
263
264  kBucketAdjustBucketsUsed(bucket);
265}
266
267const poly kBucketGetLm(kBucket_pt bucket)
268{
269  if (bucket->buckets[0] == NULL)
270    kBucketSetLm(bucket);
271  return bucket->buckets[0];
272}
273
274poly kBucketExtractLm(kBucket_pt bucket)
275{
276  poly lm;
277  if (bucket->buckets[0] == NULL) kBucketSetLm(bucket);
278  lm = bucket->buckets[0];
279  bucket->buckets[0] = NULL;
280  bucket->buckets_length[0] = 0;
281  return lm;
282}
283
284static int kBucketCanonicalize(kBucket_pt bucket)
285{
286  poly p = bucket->buckets[1];
287  poly lm;
288  int pl = bucket->buckets_length[1], i;
289  bucket->buckets[1] = NULL;
290  bucket->buckets_length[1] = 0;
291
292
293  for (i=2; i<=bucket->buckets_used; i++)
294  {
295    p = pr_Add_q(p, bucket->buckets[i],
296                 &pl, bucket->buckets_length[i]);
297    bucket->buckets[i] = NULL;
298    bucket->buckets_length[i] = 0;
299  }
300
301  lm = bucket->buckets[0];
302  if (lm != NULL)
303  {
304    pNext(lm) = p;
305    p = lm;
306    pl++;
307    bucket->buckets[0] = NULL;
308    bucket->buckets_length[0] = 0;
309  }
310  if (pl > 0)
311  {
312    i = pLogLength(pl);
313    bucket->buckets[i] = p;
314    bucket->buckets_length[i] = pl;
315  }
316  else
317  {
318    i = 0;
319  }
320  bucket->buckets_used = i;
321  assume(pLength(p) == (int) pl);
322  return i;
323}
324
325void kBucketClear(kBucket_pt bucket, poly *p, int *length)
326{
327  int i = kBucketCanonicalize(bucket);
328  if (i > 0)
329  {
330    *p = bucket->buckets[i];
331    *length = bucket->buckets_length[i];
332    bucket->buckets[i] = NULL;
333    bucket->buckets_length[i] = 0;
334    bucket->buckets_used = 0;
335  }
336  else
337  {
338    *p = NULL;
339    *length = 0;
340  }
341}
342
343#else // HAVE_PSEUDO_BUCKETS
344
345void kBucketInit(kBucket_pt bucket, poly lm, int length,
346                 memHeap heap)
347{
348  int i;
349
350  assume(bucket != NULL);
351  assume(length <= 0 || length == pLength(lm));
352
353  bucket->p = lm;
354  if (length <= 0) bucket->l = pLength(lm);
355  else bucket->l = length;
356
357  bucket->heap = heap;
358}
359
360const poly kBucketGetLm(kBucket_pt bucket)
361{
362  return bucket->p;
363}
364
365poly kBucketExtractLm(kBucket_pt bucket)
366{
367  poly lm = bucket->p;
368  assume(pLength(bucket->p) == bucket->l);
369  pIter(bucket->p);
370  (bucket->l)--;
371  pNext(lm) = NULL;
372  return lm;
373}
374
375void kBucketClear(kBucket_pt bucket, poly *p, int *length)
376{
377  assume(pLength(bucket->p) == bucket->l);
378  *p = bucket->p;
379  *length = bucket->l;
380  bucket->p = NULL;
381  bucket->l = 0;
382}
383
384#endif // ! HAVE_PSEUDO_BUCKETS
385
386/////////////////////////////////////////////////////////////////////////////
387// Compactification
388//
389
390#if 0
391// #if defined(KB_USE_HEAPS) && defined(KB_HAVE_HEAPS_GC)
392
393void kBucketCompactifyIfNecessary(kBucket_pt bucket)
394{
395  if (pShouldCompactify(bucket->heap, bucket->length))
396  {
397    int i = kBucketCanonicalize(bucket);
398    assume(i > 0 && bucket->length > 0);
399    pCompactifyHeap(bucket->heap, &(bucket->buckets[i]), bucket->length);
400    bucket->buckets[0] = bucket->buckets[i];
401    bucket->buckets[i] = pNext(bucket->buckets[i]);
402    (bucket->buckets_length[i])--;
403    pNext(bucket->buckets[0]) = NULL;
404  }
405}
406
407#else
408
409#define kBucketCompactifyIfNecessary(b)
410
411#endif
412
413//////////////////////////////////////////////////////////////////////////
414///
415/// Multiply Bucket by number ,i.e. Bpoly == n*Bpoly
416///
417void kBucket_Mult_n(kBucket_pt bucket, number n)
418{
419#ifndef HAVE_PSEUDO_BUCKETS
420  int i;
421
422  for (i=0; i<= bucket->buckets_used; i++)
423    if (bucket->buckets[i] != NULL)
424      bucket->buckets[i] = pr_Mult_n(bucket->buckets[i], n);
425#else
426  bucket->p = pr_Mult_n(bucket->p, n);
427#endif
428}
429
430//////////////////////////////////////////////////////////////////////////
431///
432/// Bpoly == Bpoly - m*p; where m is a monom
433/// Does not destroy p and m
434/// assume (*l <= 0 || pLength(p) == *l)
435void kBucket_Minus_m_Mult_p(kBucket_pt bucket, poly m, poly p, int *l,
436                            poly spNoether)
437{
438  assume (*l <= 0 || pLength(p) == *l);
439  int i, l1;
440  poly p1 = p;
441
442  if (*l <= 0)
443  {
444    l1 = pLength(p1);
445    *l = l1;
446  }
447  else
448    l1 = *l;
449
450  if (m == NULL || p == NULL) return;
451
452#ifndef HAVE_PSEUDO_BUCKETS
453  kBucketMergeLm(bucket);
454  kbTests(bucket);
455  i = pLogLength(l1);
456
457  if (i <= bucket->buckets_used && bucket->buckets[i] != NULL)
458  {
459    p1 = pr_Minus_m_Mult_q(bucket->buckets[i], m, p1,
460                         spNoether,
461                         &(bucket->buckets_length[i]), l1);
462    l1 = bucket->buckets_length[i];
463    bucket->buckets[i] = NULL;
464    bucket->buckets_length[i] = 0;
465    i = pLogLength(l1);
466    while (bucket->buckets[i] != NULL)
467    {
468      p1 = pr_Add_q(p1, bucket->buckets[i],
469                   &l1, bucket->buckets_length[i]);
470      bucket->buckets[i] = NULL;
471      bucket->buckets_length[i] = 0;
472      i = pLogLength(l1);
473    }
474  }
475  else
476  {
477    pSetCoeff0(m, nNeg(pGetCoeff(m)));
478    p1 = pr_Mult_m(p1, m, spNoether);
479    pSetCoeff0(m, nNeg(pGetCoeff(m)));
480  }
481
482  bucket->buckets[i] = p1;
483  bucket->buckets_length[i]=l1;
484  if (i >= bucket->buckets_used)
485    bucket->buckets_used = i;
486  else
487    kBucketAdjustBucketsUsed(bucket);
488#else // HAVE_PSEUDO_BUCKETS
489  bucket->p = pr_Minus_m_Mult_q(bucket->p, m,  p,
490                               &(bucket->l), l1,
491                               spNoether);
492#endif
493  kbTests(bucket);
494}
495
496/////////////////////////////////////////////////////////////////////////////
497//
498// Extract all monomials from bucket with component comp
499// Return as a polynomial *p with length *l
500// In other words, afterwards
501// Bpoly == Bpoly - (poly consisting of all monomials with component comp)
502// and components of monomials of *p are all 0
503//
504void kBucketTakeOutComp(kBucket_pt bucket,
505                        Exponent_t comp,
506                        poly *r_p, int *l)
507{
508  poly p = NULL, q;
509  int i, lp = 0, lq;
510
511#ifndef HAVE_PSEUDO_BUCKETS
512  kBucketMergeLm(bucket);
513  for (i=1; i<=bucket->buckets_used; i++)
514  {
515    if (bucket->buckets[i] != NULL)
516    {
517      pTakeOutComp(&(bucket->buckets[i]), comp, &q, &lq);
518      if (q != NULL)
519      {
520        assume(pLength(q) == lq);
521        bucket->buckets_length[i] -= lq;
522        assume(pLength(bucket->buckets[i]) == bucket->buckets_length[i]);
523        p = pr_Add_q(p, q, &lp, lq);
524      }
525    }
526  }
527  kBucketAdjustBucketsUsed(bucket);
528#else
529  pTakeOutComp(&(bucket->p), comp, &p, &lp);
530  (bucket->l) -= lp;
531#endif
532  *r_p = p;
533  *l = lp;
534
535  kbTests(bucket);
536}
537
538void kBucketDecrOrdTakeOutComp(kBucket_pt bucket,
539                               Exponent_t comp, Order_t order,
540                               poly *r_p, int *l)
541{
542  poly p = NULL, q;
543  int i, lp = 0, lq;
544
545#ifndef HAVE_PSEUDO_BUCKETS
546  kBucketMergeLm(bucket);
547  for (i=1; i<=bucket->buckets_used; i++)
548  {
549    if (bucket->buckets[i] != NULL)
550    {
551      pDecrOrdTakeOutComp(&(bucket->buckets[i]), comp, order, &q, &lq);
552      if (q != NULL)
553      {
554        bucket->buckets_length[i] -= lq;
555        p = pr_Add_q(p, q, &lp, lq);
556      }
557    }
558  }
559  kBucketAdjustBucketsUsed(bucket);
560#else
561  pDecrOrdTakeOutComp(&(bucket->p), comp, order, &p, &lp);
562  (bucket->l) -= lp;
563#endif
564
565  *r_p = p;
566  *l = lp;
567}
568
569/////////////////////////////////////////////////////////////////////////////
570// Reduction of Bpoly with a given poly
571//
572
573extern int ksCheckCoeff(number *a, number *b);
574
575number kBucketPolyRed(kBucket_pt bucket,
576                      poly p1, int l1,
577                      poly spNoether)
578{
579  assume(p1 != NULL &&
580         pDivisibleBy(p1,  kBucketGetLm(bucket)));
581  assume(pLength(p1) == (int) l1);
582
583  poly a1 = pNext(p1), lm = kBucketExtractLm(bucket);
584  BOOLEAN reset_vec=FALSE;
585  number rn;
586
587  if(a1==NULL)
588  {
589    kb_pDelete1(lm, bucket->heap);
590    return nInit(1);
591  }
592
593  if (! nIsOne(pGetCoeff(p1)))
594  {
595    number an = pGetCoeff(p1), bn = pGetCoeff(lm);
596    int ct = ksCheckCoeff(&an, &bn);
597    pSetCoeff(lm, bn);
598    if ((ct == 0) || (ct == 2)) kBucket_Mult_n(bucket, an);
599    rn = an;
600  }
601  else
602  {
603    rn = nInit(1);
604  }
605
606  if (pGetComp(p1) != pGetComp(lm))
607  {
608    pSetCompP(a1, pGetComp(lm));
609    reset_vec = TRUE;
610    pSetComp(lm, pGetComp(p1));
611    pSetm(lm);
612  }
613
614  pMonSubFrom(lm,p1);
615  l1--;
616
617  kBucket_Minus_m_Mult_p(bucket, lm, a1, &l1, spNoether);
618
619  kb_pDelete1(lm, bucket->heap);
620  if (reset_vec) pSetCompP(a1, 0);
621  kbTests(bucket);
622  return rn;
623}
624
625/////////////////////////////////////////////////////////////////////////////
626// Reduction of a poly using buckets
627//
628
629#ifdef KB_USE_BUCKETS
630/*2
631*  reduction procedure for the homogeneous case
632*  and the case of a degree-ordering
633*/
634void kBucketRedHomog (LObject* h,kStrategy strat)
635{
636  if (strat->tl<0)
637  {
638    return;
639  }
640  int j = 0;
641  int k = 0;
642  poly lm;
643#ifdef KDEBUG
644  if (TEST_OPT_DEBUG)
645  {
646    PrintS("red:");
647    wrp(h->p);
648    PrintS(" ");
649  }
650#endif
651
652  kBucketInit(&(strat->bucket), h->p, h->length, h->heap);
653
654  lm = kBucketGetLm(&(strat->bucket));
655
656  for(;;)
657  {
658#ifdef KDEBUG
659    if (TEST_OPT_DEBUG) Print("%d",j);
660#endif
661    j = 0;
662
663#ifdef KB_HAVE_SHORT_EVECTORS
664    unsigned long ev = ~ pGetShortExpVector(lm);
665#endif
666
667    if (strat->ak)
668    {
669      while(j <= strat->tl)
670      {
671        if (pDivisibleBy1(strat->T[j].p,lm)) goto Found;
672        j++;
673      }
674    }
675    else
676    {
677      while(j <= strat->tl)
678      {
679#ifdef KB_HAVE_SHORT_EVECTORS
680        if ((strat->T[j].sev & ev) || ! pDivisibleBy2(strat->T[j].p,lm))
681          j++;
682        else
683          goto Found;
684#else
685        if (pDivisibleBy2(strat->T[j].p,lm)) goto Found;
686        j++;
687#endif
688      }
689    }
690
691    assume(j > strat->tl);
692    kBucketClear(&(strat->bucket), &(h->p), &(h->length));
693    if (TEST_OPT_INTSTRATEGY) pCleardenom((*h).p);
694    assume(pLength(h->p) == h->length);
695    return;
696
697    Found:
698    // now we found one to reduce with
699    assume(pDivisibleBy(strat->T[j].p,lm));
700
701#ifdef KDEBUG
702    if (TEST_OPT_DEBUG)
703    {
704        wrp(strat->T[j].p);
705    }
706#endif
707    assume(strat->T[j].length <= 0 ||
708           strat->T[j].length == pLength(strat->T[j].p));
709      /*- compute the s-polynomial -*/
710    if (strat->T[j].length <= 0)
711      strat->T[j].length = pLength(strat->T[j].p);
712
713    // Compactify
714    kBucketCompactifyIfNecessary(&(strat->bucket));
715
716    number up = kBucketPolyRed(&(strat->bucket),
717                               strat->T[j].p, strat->T[j].length,
718                               strat->kNoether);
719    nDelete(&up);
720    lm = kBucketGetLm(&(strat->bucket));
721
722    if (lm == NULL)
723    {
724      h->p = NULL;
725      h->length = 0;
726#ifdef KDEBUG
727      if (TEST_OPT_DEBUG) PrintS(" to 0\n");
728#endif
729      if (h->lcm!=NULL) pFree1((*h).lcm);
730#ifdef KDEBUG
731      (*h).lcm=NULL;
732#endif
733      return;
734    }
735  }
736}
737
738
739/*2
740*  reduction procedure for the sugar-strategy (honey)
741* reduces h with elements from T choosing first possible
742* element in T with respect to the given ecart
743*/
744void kBucketRedHoney (LObject*  h,kStrategy strat)
745{
746  if (strat->tl<0)
747  {
748    return;
749  }
750
751  poly pi;
752  int i,j,at,reddeg,d,pass,ei, li;
753
754  pass = j = 0;
755  d = reddeg = pFDeg((*h).p)+(*h).ecart;
756#ifdef KDEBUG
757  if (TEST_OPT_DEBUG)
758  {
759    PrintS("red:");
760    wrp((*h).p);
761  }
762#endif
763  kTest(strat);
764
765  if (strat->fromT)
766  {
767    HeapPoly b_hp(h->heap), r_hp(h->p, h->length);
768    pCopyHeapPoly(&b_hp, &r_hp, FALSE);
769    kBucketInit(&(strat->bucket), b_hp.p, b_hp.length, h->heap);
770  }
771  else
772    kBucketInit(&(strat->bucket),  h->p, h->length, h->heap);
773
774  poly lm = kBucketGetLm(&(strat->bucket));
775
776  strat->fromT=FALSE;
777
778  while (1)
779  {
780    j = 0;
781#ifdef KB_HAVE_SHORT_EVECTORS
782    unsigned long ev = ~ pGetShortExpVector(lm);
783#endif
784
785    if (strat->ak)
786    {
787      while(j <= strat->tl)
788      {
789        if (pDivisibleBy1(strat->T[j].p,lm)) goto Found;
790        j++;
791      }
792    }
793    else
794    {
795      while(j <= strat->tl)
796      {
797#ifdef KB_HAVE_SHORT_EVECTORS
798        if ((strat->T[j].sev & ev) || ! pDivisibleBy2(strat->T[j].p,lm))
799          j++;
800        else
801          goto Found;
802#else
803        if (pDivisibleBy2(strat->T[j].p,lm)) goto Found;
804        j++;
805#endif
806      }
807    }
808
809    assume(j > strat->tl);
810#ifdef KDEBUG
811    if (TEST_OPT_DEBUG) PrintLn();
812#endif
813    kBucketClear(&(strat->bucket), &(h->p), &(h->length));
814    if (TEST_OPT_INTSTRATEGY) pCleardenom(h->p);// also does a pContent
815    return;
816
817    Found:
818    assume(pDivisibleBy(strat->T[j].p,lm));
819#ifdef KDEBUG
820    if (TEST_OPT_DEBUG) Print(" T[%d]",j);
821#endif
822    pi = strat->T[j].p;
823    ei = strat->T[j].ecart;
824    li = strat->T[j].length;
825    if (li == 0)
826    {
827      strat->T[j].length = pLength(pi);
828      li =  strat->T[j].length;
829    }
830
831
832    /*
833     * the polynomial to reduce with (up to the moment) is;
834     * pi with ecart ei
835     */
836    i = j;
837    loop
838      {
839        /*- takes the first possible with respect to ecart -*/
840        i++;
841        if (i > strat->tl)
842          break;
843        if ((!BTEST1(20)) && (ei <= (*h).ecart))
844          break;
845        if ((strat->T[i].ecart < ei) && pDivisibleBy1(strat->T[i].p,lm))
846        {
847#ifdef KDEBUG
848          if (TEST_OPT_DEBUG) Print(" T[%d]",i);
849#endif
850          /*
851           * the polynomial to reduce with is now;
852           */
853          pi = strat->T[i].p;
854          ei = strat->T[i].ecart;
855          li = strat->T[i].length;
856          if (li == 0)
857          {
858            strat->T[i].length = pLength(pi);
859            li =  strat->T[i].length;
860          }
861        }
862      }
863
864    /*
865     * end of search: have to reduce with pi
866     */
867    if ((pass!=0) && (ei > (*h).ecart))
868    {
869      /*
870       * It is not possible to reduce h with smaller ecart;
871       * if possible h goes to the lazy-set L,i.e
872       * if its position in L would be not the last one
873       */
874      if (strat->Ll >= 0) /* L is not empty */
875      {
876        h->p = lm;
877        at = strat->posInL(strat->L,strat->Ll,*h,strat);
878        if(at <= strat->Ll)
879          /*- h will not become the next element to reduce -*/
880        {
881          kBucketClear(&(strat->bucket), &(h->p), &(h->length));
882          pCompactifyHeap( h->heap, &(h->p), h->length);
883          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
884#ifdef KDEBUG
885          if (TEST_OPT_DEBUG) Print(" ecart too big: -> L%d\n",at);
886#endif
887          h->p = NULL;
888          h->length = 0;
889          h->heap = NULL;
890          return;
891        }
892      }
893    }
894#ifdef KDEBUG
895    if (TEST_OPT_DEBUG)
896    {
897      PrintS("\nwith ");
898      wrp(pi);
899    }
900#endif
901
902    // Poly Reduction
903    kBucketCompactifyIfNecessary(&(strat->bucket));
904    number up = kBucketPolyRed(&(strat->bucket),
905                               pi, li,
906                               strat->kNoether);
907    nDelete(&up);
908    lm = kBucketGetLm(&(strat->bucket));
909
910#ifdef KDEBUG
911    if (TEST_OPT_DEBUG)
912    {
913      PrintS(" to ");
914      wrp((*h).p);
915      PrintLn();
916    }
917#endif
918    if (lm == NULL)
919    {
920      if (h->lcm!=NULL) pFree1((*h).lcm);
921#ifdef KDEBUG
922      (*h).lcm=NULL;
923#endif
924      h->p = NULL;
925      h->length = 0;
926      return;
927    }
928    /* compute the ecart */
929    if (ei <= (*h).ecart)
930      (*h).ecart = d-pFDeg(lm);
931    else
932      (*h).ecart = d-pFDeg(lm)+ei-(*h).ecart;
933    /*
934     * try to reduce the s-polynomial h
935     *test first whether h should go to the lazyset L
936     *-if the degree jumps
937     *-if the number of pre-defined reductions jumps
938     */
939    pass++;
940    d = pFDeg(lm)+(*h).ecart;
941    if ((strat->Ll >= 0) && ((d > reddeg) || (pass > strat->LazyPass)))
942    {
943      h->p = lm;
944      at = strat->posInL(strat->L,strat->Ll,*h,strat);
945      if (at <= strat->Ll)
946      {
947        kBucketClear(&(strat->bucket), &(h->p), &(h->length));
948        assume(pLength(h->p) == h->length);
949        /*test if h is already standardbasis element*/
950        i=strat->sl+1;
951        do
952        {
953          i--;
954          if (i<0)
955          {
956            // we actually should do a pCleardenom(h->p) here
957            return;
958          }
959        } while (!pDivisibleBy1(strat->S[i], h->p));
960
961        // enter in Lazyset and return
962        pCompactifyHeap( h->heap, &(h->p), h->length);
963        enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
964#ifdef KDEBUG
965        if (TEST_OPT_DEBUG)
966          Print(" degree jumped: -> L%d\n",at);
967#endif
968        h->p = NULL;
969        h->length = 0;
970        h->heap = NULL;
971        return;
972      }
973    }
974    else if (TEST_OPT_PROT && (strat->Ll < 0) && (d > reddeg))
975    {
976      reddeg = d;
977      Print(".%d",d); mflush();
978    }
979  }
980}
981
982/*2
983*compute the normalform of the tail p->next of p
984*with respect to S
985*/
986void kBucketRedTail(LObject *hp, int pos, kStrategy strat)
987{
988  poly h, hn, redstart = NULL;
989  int length = 1, j;
990
991  if (strat->noTailReduction) return;
992  h = hp->p;
993  hn = pNext(h);
994  strat->redTailChange=FALSE;
995
996  while(hn != NULL)
997  {
998    j = 0;
999    while (j <= pos)
1000    {
1001      if (pDivisibleBy(strat->S[j], hn))
1002      {
1003        if (redstart == NULL)
1004        {
1005#ifdef KB_USE_HEAPS
1006          int i;
1007          if (hp->length <= 0) hp->length = pLength(hp->p);
1008          pCompactifyHeap(hp->heap, &(hp->p), hp->length);
1009          h = hp->p;
1010          for (i = 1, h = hp->p; i < length; i++, h = pNext(h));
1011          hn = pNext(h);
1012#endif
1013          strat->redTailChange = TRUE;
1014          redstart = h;
1015
1016          kBucketInit(&(strat->bucket), hn, -1, hp->heap);
1017        }
1018        number up = kBucketPolyRed(&(strat->bucket), strat->S[j],
1019                                   pLength(strat->S[j]),
1020                                   strat->kNoether);
1021        nDelete(&up);
1022        hn = kBucketGetLm(&(strat->bucket));
1023        if (hn == NULL)
1024        {
1025          pNext(h) = NULL;
1026          goto Finish;
1027        }
1028        j = 0;
1029      }
1030      else
1031      {
1032        j++;
1033      }
1034    }
1035
1036    if (redstart != NULL)
1037    {
1038      hn = kBucketExtractLm(&(strat->bucket));
1039      pNext(h) = hn;
1040      h = hn;
1041      hn = kBucketGetLm(&(strat->bucket));
1042    }
1043    else
1044    {
1045      pNext(h) = hn;
1046      h = hn;
1047      hn = pNext(h);
1048    }
1049    length++;
1050  }
1051
1052
1053  Finish:
1054  assume(pLength(hp->p) == length);
1055  hp->length = length;
1056}
1057
1058#endif // KB_USE_BUCKETS
1059
1060#endif // HAVE_BUCKETS
Note: See TracBrowser for help on using the repository browser.