source: git/Singular/kbuckets.cc @ faea11

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