source: git/kernel/f5gb.cc @ 835d83

spielwiese
Last change on this file since 835d83 was 418bd6, checked in by Christian Eder, 15 years ago
added idea for termination of F5: split critical pairs in "useful" and "useless" ones, check later on if there are "useful" ones left, else terminate the algorithm. git-svn-id: file:///usr/local/Singular/svn/trunk@12147 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 76.4 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5* ABSTRACT: f5gb interface
6*/
7
8#include "mod2.h"
9#ifdef HAVE_F5
10#include <unistd.h>
11#include "structs.h"
12#include "kutil.h"
13#include "omalloc.h"
14#include "polys.h"
15#include "p_polys.h"
16#include "p_Procs.h"
17#include "ideals.h"
18#include "febase.h"
19#include "kstd1.h"
20#include "khstd.h"
21#include "kbuckets.h"
22#include "weight.h"
23#include "intvec.h"
24#include "pInline1.h"
25#include "f5gb.h"
26#include "f5data.h"
27#include "f5lists.h"
28#include "timer.h"
29int notInG              =   0;
30int numberOfRules       =   0;
31int reductionsToZero    =   0;
32int reductionTime       =   0;
33int spolsTime           =   0;
34int highestDegree       =   0;
35int degreeBound         =   0;
36int numberUsefulPairs   =   0;
37int numberUselessPairs  =   0;
38/*
39====================================================================
40sorting ideals by decreasing total degree "left" and "right" are the
41pointer of the first and last polynomial in the considered ideal
42====================================================================
43*/
44void qsortDegree(poly* left, poly* right) {
45    poly* ptr1 = left;
46    poly* ptr2 = right;
47    poly p1,p2;
48    p2 = *(left + (right - left >> 1));
49    do {
50            while(pTotaldegree(*ptr1, currRing) < pTotaldegree(p2, currRing)) {
51                    ptr1++;
52            } 
53            while(pTotaldegree(*ptr2, currRing) > pTotaldegree(p2,currRing)) {
54                    ptr2--;
55            }
56            if(ptr1 > ptr2) {
57                    break;
58            }
59            p1    = *ptr1;
60            *ptr1 = *ptr2;
61            *ptr2 = p1;
62    } while(++ptr1 <= --ptr2);
63
64    if(left < ptr2) {
65            qsortDegree(left,ptr2);
66    }
67    if(ptr1 < right) {
68            qsortDegree(ptr1,right);
69    }
70}
71
72/*!
73 * ======================================================================
74 * builds the sum of the entries of the exponent vectors, i.e. the degree
75 * of the corresponding monomial
76 * ======================================================================
77*/
78long sumVector(int* v, int k) {
79    int i;
80    long sum =  0;
81    for(i=1; i<=k; i++) {
82        Print("%d\n",v[i]);
83        Print("%ld\n",sum);
84        sum =   sum + v[i];
85    }
86    return sum;
87}
88
89/*!
90==========================================================================
91compares monomials, i.e. divisibility tests for criterion 1 and criterion 2
92==========================================================================
93*/
94bool compareMonomials(int* m1, int** m2, int numberOfRules, int k) {
95    int i,j;
96    long sumM1  =   sumVector(m1,k);
97    //int k   =   sizeof(m1) / sizeof(int);
98    for(i=0; i<numberOfRules; i++) {
99        if(sumVector(m2[i],k) <= sumM1) {
100            for(j=1; j<=k; j++) {
101                if(m1[j]>m2[i][j]) {
102                    return true;
103                }
104            }   
105        }
106    }
107    return false;
108}
109
110/*
111==================================================
112computes incrementally gbs of subsets of the input
113gb{f_m} -> gb{f_m,f_(m-1)} -> gb{f_m,...,f_1}
114==================================================
115*/
116LList* F5inc(int i, poly f_i, LList* gPrev, LList* reducers, ideal gbPrev, poly ONE, LTagList* lTag, RList* rules, RTagList* rTag, int termination) {
117    //Print("in f5inc\n");           
118    //pWrite(rules->getFirst()->getRuleTerm());
119    int j;
120    //Print("%p\n",gPrev->getFirst());
121    //pWrite(gPrev->getFirst()->getPoly());
122    poly tempNF =   kNF(gbPrev,currQuotient,f_i);
123    f_i         =   tempNF;
124    //gPrev->insert(ONE,i,f_i);
125    gPrev->insert(ONE,gPrev->getLength()+1,f_i);
126    // tag the first element in gPrev of the current index for findReductor()
127    lTag->setFirstCurrentIdx(gPrev->getLast());
128    //Print("1st gPrev: ");
129    //pWrite(gPrev->getFirst()->getPoly());
130    //Print("2nd gPrev: ");
131    //pWrite(gPrev->getFirst()->getNext()->getPoly());
132    //pWrite(gPrev->getFirst()->getNext()->getPoly());   
133    CListOld* critPairs        =   new CListOld();
134    CNode* critPairsMinDeg  =   new CNode();   
135    // computation of critical pairs with checking of criterion 1 and criterion 2 and saving them
136    // in the list critPairs
137    criticalPair(gPrev, critPairs, lTag, rTag, rules);
138    static LList* sPolyList        =   new LList();
139    //sPolyList->print();
140    // labeled polynomials which have passed reduction() and have to be added to list gPrev
141    static LList* completed        =   new LList();
142    // the reduced labeled polynomials which are returned from subalgorithm reduction()
143    static LList* reducedLPolys     =   new LList();
144    // while there are critical pairs to be further checked and deleted/computed
145    while(NULL != critPairs->getFirst()) { 
146        // critPairs->getMinDeg() deletes the first elements of minimal degree from
147        // critPairs, thus the while loop is not infinite.
148        critPairsMinDeg =   critPairs->getMinDeg();
149        // adds all to be reduced S-polynomials in the list sPolyList and adds
150        // the corresponding rules to the list rules
151        // NOTE: inside there is a second check of criterion 2 if new rules are
152        // added
153        //int timer4  =   initTimer();
154        //startTimer();
155        //critPairs->print();
156        if(numberUsefulPairs > 0) {
157          Print("number of useful pairs:  %d\n",numberUsefulPairs);
158          Print("number of useless pairs: %d\n\n",numberUselessPairs);
159          computeSPols(critPairsMinDeg,rTag,rules,sPolyList);
160        }
161        else {
162          return gPrev;
163        }
164        //timer4  =   getTimer();
165        //Print("SPOLS TIMER: %d\n",timer4);
166        //spolsTime  =   spolsTime  +   timer4;
167        // DEBUG STUFF FOR SPOLYLIST
168        LNode* temp     =   sPolyList->getFirst();
169        //while(NULL != temp && NULL != temp->getLPoly()) {
170            //Print("Spolylist element: ");
171            //pWrite(temp->getPoly());
172            //temp    =   temp->getNext();
173        //}
174        // reduction process of new S-polynomials and also adds new critical pairs to critPairs
175        //int timer3  =   initTimer();
176        //startTimer();
177        //sPolyList->print();
178        //reduction(sPolyList, critPairs, gPrev, rules, lTag, rTag, gbPrev);
179        Print("BEFORE REDUCTION: \n");
180        Print("number of useful pairs:  %d\n",numberUsefulPairs);
181        Print("number of useless pairs: %d\n\n",numberUselessPairs);
182        newReduction(sPolyList, critPairs, gPrev, reducers, rules, lTag, rTag, gbPrev, termination);
183        //timer3      =  getTimer();
184        //reductionTime = reductionTime + timer3;
185        //Print("REDUCTION TIMER: %d\n",timer3);
186        // DEBUG STUFF FOR GPREV
187        //temp    =   gPrev->getFirst();
188        //int number  =   1;
189        //Print("\n\n");
190        //while(NULL != temp) {
191        //    Print("%d.  ",number);
192        //    pWrite(temp->getPoly());
193        //    temp    =   temp->getNext();
194        //    number++;
195        //    Print("\n");
196        //}
197        //sleep(5);
198   
199    }
200    //Print("REDUCTION DONE\n");
201    //Print("%p\n",rules->getFirst());
202    //Print("%p\n",rTag->getFirst());
203    //if(rules->getFirst() != rTag->getFirst()) {
204        //Print("+++++++++++++++++++++++++++++++++++++NEW RULES+++++++++++++++++++++++++++++++++++++\n");
205        //rTag->insert(rules->getFirst());
206    //}
207    //else {
208        //Print("+++++++++++++++++++++++++++++++++++NO NEW RULES++++++++++++++++++++++++++++++++++++\n");
209    //}
210    lTag->insert(lTag->getFirstCurrentIdx());
211    //Print("INDEX: %d\n",tempTag->getIndex());
212    //pWrite(tempTag->getPoly());
213    //Print("COMPLETED FIRST IN F5INC: \n");
214    //Print("1st gPrev: ");
215    //pWrite(gPrev->getFirst()->getPoly());
216    //Print("2nd gPrev: ");
217    //pWrite(gPrev->getFirst()->getNext()->getPoly());
218    //Print("3rd gPrev: ");
219    //pWrite(gPrev->getFirst()->getNext()->getNext()->getPoly());
220    //delete sPolyList;
221    //critPairs->print();
222    delete critPairs;
223    //Print("IN F5INC\n");
224    /*
225    Print("\n\n\nRULES: \n");
226        RNode* tempR    =   rules->getFirst();
227        Print("%p\n",tempR);
228        int t   = 1;
229        while(NULL != tempR) {
230            Print("ADDRESS OF %d RNODE: %p\n",t,tempR);
231            Print("ADDRESS OF RULE: %p\n",tempR->getRule());
232            pWrite(tempR->getRuleTerm());
233            Print("ADDRESS OF TERM: %p\n",tempR->getRuleTerm());
234            Print("%d\n\n",tempR->getRuleIndex());
235            tempR   =   tempR->getNext();
236            t++;
237        }
238    */
239    //gPrev->print();
240    //Print("COMPLETE REDUCTION TIME UNTIL NOW: %d\n",reductionTime);
241    //Print("COMPLETE SPOLS TIME UNTIL NOW:     %d\n",spolsTime);
242    degreeBound = 0;
243    return gPrev;
244}
245
246
247
248/*
249================================================================
250computes a list of critical pairs for the next reduction process
251the first element is always "useful" thus the critical pair
252computed is either "useful" or "useless" depending on the second
253element which generates the critical pair.
254first element in gPrev is always the newest element which must
255build critical pairs with all other elements in gPrev
256================================================================
257*/
258inline void criticalPair(LList* gPrev, CListOld* critPairs, LTagList* lTag, RTagList* rTag, RList* rules) {
259    //Print("IN CRITPAIRS\n");
260    // initialization for usage in pLcm()
261    number nOne         =   nInit(1);
262    LNode* newElement   =   gPrev->getLast();
263    LNode* temp         =   gPrev->getFirst();
264    poly u1             =   pOne();
265    poly u2             =   pOne();
266    poly lcm            =   pOne();
267    poly t              =   pHead(newElement->getPoly());
268    RuleOld* testedRuleOld    =   NULL;
269    if(NULL != rules->getFirst()) {
270        testedRuleOld  =   rules->getFirst()->getRuleOld();
271    }
272    // computation of critical pairs
273    while( gPrev->getLast() != temp) {
274        pLcm(newElement->getPoly(), temp->getPoly(), lcm);
275        pSetCoeff(lcm,nOne);
276        // computing factors u2 for new labels
277        u1 = pDivide(lcm,t);
278        if(NULL == u1) {
279            break;
280        }
281        pSetCoeff(u1,nOne);
282        u2 = pDivide(lcm,pHead(temp->getPoly()));
283        pSetCoeff(u2,nOne);
284        // testing both new labels by the F5 Criterion
285        if(!temp->getDel()) {
286          if(!criterion2(gPrev->getFirst()->getIndex(), u2, temp, rules, rTag)
287            && !criterion2(gPrev->getFirst()->getIndex(), u1, newElement, rules, rTag) 
288            && !criterion1(gPrev,u1,newElement,lTag) && !criterion1(gPrev,u2,temp,lTag)) {
289              // if they pass the test, add them to CListOld critPairs, having the LPolyOld with greater
290              // label as first element in the CPairOld
291              if(newElement->getIndex() == temp->getIndex() && 
292              -1 == pLmCmp(ppMult_qq(u1, newElement->getTerm()),ppMult_qq(u2, temp->getTerm()))) {
293                  CPairOld* cp   =   new CPairOld(pDeg(ppMult_qq(u2,pHead(temp->getPoly()))), u2, 
294                                  temp->getLPolyOld(), u1, newElement->getLPolyOld(), 0 , testedRuleOld);                   
295                  critPairs->insert(cp);
296                  // counting the number of useful pairs
297                  numberUsefulPairs++;
298              }
299              else {
300                  CPairOld* cp   =   new CPairOld(pDeg(ppMult_qq(u2,pHead(temp->getPoly()))), u1, 
301                                  newElement->getLPolyOld(), u2, temp->getLPolyOld(), 0, testedRuleOld);                   
302                  critPairs->insert(cp);
303                  // counting the number of useful pairs
304                  numberUsefulPairs++;
305              }
306          }
307        }
308        else {
309          if(!criterion2(gPrev->getFirst()->getIndex(), u2, temp, rules, rTag)
310            && !criterion2(gPrev->getFirst()->getIndex(), u1, newElement, rules, rTag) 
311            && !criterion1(gPrev,u1,newElement,lTag) && !criterion1(gPrev,u2,temp,lTag)) {
312              // if they pass the test, add them to CListOld critPairs, having the LPolyOld with greater
313              // label as first element in the CPairOld
314              if(newElement->getIndex() == temp->getIndex() && 
315              -1 == pLmCmp(ppMult_qq(u1, newElement->getTerm()),ppMult_qq(u2, temp->getTerm()))) {
316                  CPairOld* cp   =   new CPairOld(pDeg(ppMult_qq(u2,pHead(temp->getPoly()))), u2, 
317                                  temp->getLPolyOld(), u1, newElement->getLPolyOld(), 1 , testedRuleOld);                   
318                  critPairs->insert(cp);
319                  numberUselessPairs++;
320              }
321              else {
322                  CPairOld* cp   =   new CPairOld(pDeg(ppMult_qq(u2,pHead(temp->getPoly()))), u1, 
323                                  newElement->getLPolyOld(), u2, temp->getLPolyOld(), 1, testedRuleOld);                   
324                  critPairs->insert(cp);
325                  numberUselessPairs++;
326              }
327          }
328        }
329        temp    =   temp->getNext();
330    }
331}
332
333
334
335/*
336================================================================
337computes a list of critical pairs for the next reduction process
338the first element is always "useless" thus the critical pair
339computed is "useless".
340first element in gPrev is always the newest element which must
341build critical pairs with all other elements in gPrev
342================================================================
343*/
344inline void criticalPair2(LList* gPrev, CListOld* critPairs, LTagList* lTag, RTagList* rTag, RList* rules) {
345    //Print("IN CRITPAIRS\n");
346    // initialization for usage in pLcm()
347    number nOne         =   nInit(1);
348    LNode* newElement   =   gPrev->getLast();
349    LNode* temp         =   gPrev->getFirst();
350    poly u1             =   pOne();
351    poly u2             =   pOne();
352    poly lcm            =   pOne();
353    poly t              =   pHead(newElement->getPoly());
354    RuleOld* testedRuleOld    =   NULL;
355    if(NULL != rules->getFirst()) {
356        testedRuleOld  =   rules->getFirst()->getRuleOld();
357    }
358    // computation of critical pairs
359    while( gPrev->getLast() != temp) {
360        pLcm(newElement->getPoly(), temp->getPoly(), lcm);
361        pSetCoeff(lcm,nOne);
362        // computing factors u2 for new labels
363        u1 = pDivide(lcm,t);
364        if(NULL == u1) {
365            break;
366        }
367        pSetCoeff(u1,nOne);
368        u2 = pDivide(lcm,pHead(temp->getPoly()));
369        pSetCoeff(u2,nOne);
370        // testing both new labels by the F5 Criterion
371        if(!criterion2(gPrev->getFirst()->getIndex(), u2, temp, rules, rTag)
372           && !criterion2(gPrev->getFirst()->getIndex(), u1, newElement, rules, rTag) 
373           && !criterion1(gPrev,u1,newElement,lTag) && !criterion1(gPrev,u2,temp,lTag)) {
374            // if they pass the test, add them to CListOld critPairs, having the LPolyOld with greater
375            // label as first element in the CPairOld
376            if(newElement->getIndex() == temp->getIndex() && 
377            -1 == pLmCmp(ppMult_qq(u1, newElement->getTerm()),ppMult_qq(u2, temp->getTerm()))) {
378                CPairOld* cp   =   new CPairOld(pDeg(ppMult_qq(u2,pHead(temp->getPoly()))), u2, 
379                                temp->getLPolyOld(), u1, newElement->getLPolyOld(), 1 , testedRuleOld);                   
380                critPairs->insert(cp);
381                numberUselessPairs++;
382            }
383            else {
384                CPairOld* cp   =   new CPairOld(pDeg(ppMult_qq(u2,pHead(temp->getPoly()))), u1, 
385                                newElement->getLPolyOld(), u2, temp->getLPolyOld(), 1, testedRuleOld);                   
386                critPairs->insert(cp);
387                numberUselessPairs++;
388            }
389        }
390        temp    =   temp->getNext();
391    }
392}
393
394
395
396/*
397========================================
398Criterion 1, i.e. Faugere's F5 Criterion
399========================================
400*/
401inline bool criterion1(LList* gPrev, poly t, LNode* l, LTagList* lTag) {
402    // starts at the first element in gPrev with index = (index of l)-1, these tags are saved in lTag
403        int idx =   l->getIndex();
404    int i;
405    if(idx == 1) {
406        //Print("HIER\n");
407        return false;
408    }
409    else {
410        LNode* testNode =   gPrev->getFirst();
411        // save the monom t1*label_term(l) as it is tested various times in the following
412        poly u1 = ppMult_qq(t,l->getTerm());
413        //Print("------------------------------IN CRITERION 1-----------------------------------------\n");
414        //Print("TESTED ELEMENT: ");
415        //pWrite(l->getPoly());
416        //pWrite(l->getTerm());
417        //pWrite(ppMult_qq(t,l->getTerm()));
418        //Print("%d\n\n",l->getIndex());
419        while(testNode->getIndex() < idx) { // && NULL != testNode->getLPoly()) {
420            //pWrite(testNode->getPoly());
421            //Print("%d\n",testNode->getIndex());
422            if(pLmDivisibleByNoComp(testNode->getPoly(),u1)) {
423                //Print("Criterion 1 NOT passed!\n");
424                if(idx != gPrev->getLast()->getIndex()) {
425                    //Print("DOCH!\n");
426                }
427                return true;
428            }
429            //pWrite(testNode->getNext()->getPoly());
430            testNode    =   testNode->getNext();
431        }
432        /*
433        ideal testId    =   idInit(idx-1,1);
434        for(i=0;i<idx-1;i++) {
435            testId->m[i]  =   pHead(testNode->getPoly());
436            testNode        =   testNode->getNext();
437        }
438        poly temp   =   kNF(testId,currQuotient,u1);
439        //pWrite(temp);
440        for(i=0;i<IDELEMS(testId);i++) {
441            testId->m[i]    =   NULL;
442        }
443        idDelete(&testId);
444        if(NULL == temp) {
445            //if(l->getIndex() != gPrev->getFirst()->getIndex()) {
446            //    Print("----------------------------Criterion1 not passed----------------------------------\n");
447            //}
448            return true;
449        }
450        */
451        return false;
452    }
453}
454
455
456
457/*
458=====================================
459Criterion 2, i.e. Rewritten Criterion
460=====================================
461*/
462inline bool criterion2(int idx, poly t, LNode* l, RList* rules, RTagList* rTag) {
463    //Print("------------------------------IN CRITERION 2/1-----------------------------------------\n");
464    /* 
465    Print("RULES: \n");
466        RNode* tempR    =   rules->getFirst();
467        Print("%p\n",tempR);
468        int i   = 1;
469        while(NULL != tempR) {
470            Print("ADDRESS OF %d RNODE: %p\n",i,tempR);
471            Print("ADDRESS OF RULE: %p\n",tempR->getRule());
472            pWrite(tempR->getRuleTerm());
473            Print("ADDRESS OF TERM: %p\n",tempR->getRuleTerm());
474            Print("%d\n\n",tempR->getRuleIndex());
475            tempR   =   tempR->getNext();
476            i++;
477        }
478        //Print("TESTED ELEMENT: ");
479        //pWrite(l->getPoly());
480        //pWrite(l->getTerm());
481        //pWrite(ppMult_qq(t,l->getTerm()));
482        //Print("%d\n\n",l->getIndex());
483      */
484// start at the previously added element to gPrev, as all other elements will have the same index for sure
485    if(idx > l->getIndex()) {
486        return false;
487    }
488   
489    RNode* testNode; // =   new RNode();
490    testNode    =   rules->getFirst();
491    /*
492     if(NULL == rTag->getFirst()) {
493        if(NULL != rules->getFirst()) {
494            testNode    =   rules->getFirst();
495        }
496        else {
497            return false;
498        }
499    }
500   
501     else {
502
503        if(l->getIndex() > rTag->getFirst()->getRuleIndex()) {
504            testNode    =   rules->getFirst();
505        }
506        else {
507       //Print("HIER\n");
508            //Print("DEBUG\n");
509        //Print("L INDEX: %d\n",l->getIndex());
510            *-------------------------------------
511             * TODO: WHEN INTERREDUCING THE GB THE
512             *       INDEX OF THE PREVIOUS ELEMENTS
513             *       GETS HIGHER!
514             *-----------------------------------*
515            //testNode    =   rules->getFirst();
516            testNode    =   rTag->get(l->getIndex());
517            if(NULL == testNode) {
518                testNode    =   rules->getFirst();
519            }
520            //Print("TESTNODE ADDRESS: %p\n",testNode);
521        }
522    }
523    */
524    //testNode    =   rules->getFirst();
525        // save the monom t1*label_term(l) as it is tested various times in the following
526    poly u1 = ppMult_qq(t,l->getTerm());
527    // first element added to rTag was NULL, check for this
528    //Print("%p\n",testNode->getRule());
529    // NOTE: testNode is possibly NULL as rTag->get() returns NULL for elements of index <=1!
530    //Print("TESTNODE: %p\n",testNode);
531    //pWrite(testNode->getRuleTerm());
532    if(NULL != testNode ) {   
533        //pWrite(testNode->getRuleTerm());
534    }
535    if(NULL != testNode) {
536        if(testNode->getRuleOld() == l->getRuleOld()) {
537            //Print("%p\n%p\n",testNode->getRule(),l->getRule());
538            //Print("EQUAL\n");
539        }
540        else {
541            //Print("NOT EQUAL\n");
542        }
543    }
544    while(NULL != testNode && testNode->getRuleOld() != l->getRuleOld() 
545          && l->getIndex() == testNode->getRuleOldIndex()) {
546        //Print("%p\n",testNode);
547        //pWrite(testNode->getRuleTerm());
548        //pWrite(t);
549        //pWrite(l->getTerm());
550        //pWrite(u1);
551        //Print("%d\n",testNode->getRuleIndex());
552        if(pLmDivisibleByNoComp(testNode->getRuleOldTerm(),u1)) {
553            //Print("-----------------Criterion 2 NOT passed!-----------------------------------\n");
554            //Print("INDEX: %d\n",l->getIndex());
555            pDelete(&u1);
556    //Print("------------------------------IN CRITERION 2/1-----------------------------------------\n\n");
557            return true;
558        }
559                testNode    =   testNode->getNext();
560    }
561    //delete testNode;
562    pDelete(&u1);
563    //Print("------------------------------IN CRITERION 2/1-----------------------------------------\n\n");
564    return false;
565}
566
567
568
569/*
570=================================================================================================================
571Criterion 2, i.e. Rewritten Criterion, for its second call in computeSPols(), with added lastRuleTested parameter
572=================================================================================================================
573*/
574inline bool criterion2(poly t, LPolyOld* l, RList* rules, RuleOld* testedRuleOld) {
575    //Print("------------------------------IN CRITERION 2/2-----------------------------------------\n");
576    //Print("LAST RuleOld TESTED: %p",testedRuleOld);
577    /*
578    Print("RULES: \n");
579        RNode* tempR    =   rules->getFirst();
580        while(NULL != tempR) {
581            pWrite(tempR->getRuleTerm());
582            Print("%d\n\n",tempR->getRuleIndex());
583            tempR   =   tempR->getNext();
584        }
585        //Print("TESTED ELEMENT: ");
586        //pWrite(l->getPoly());
587        //pWrite(l->getTerm());
588        //pWrite(ppMult_qq(t,l->getTerm()));
589        //Print("%d\n\n",l->getIndex());
590    */
591// start at the previously added element to gPrev, as all other elements will have the same index for sure
592        RNode* testNode =   rules->getFirst();
593    // save the monom t1*label_term(l) as it is tested various times in the following
594    poly u1 = ppMult_qq(t,l->getTerm());
595        // first element added to rTag was NULL, check for this
596        while(NULL != testNode && testNode->getRuleOld() != testedRuleOld) {
597        //pWrite(testNode->getRuleTerm());
598        if(pLmDivisibleByNoComp(testNode->getRuleOldTerm(),u1)) {
599            //Print("--------------------------Criterion 2 NOT passed!------------------------------\n");
600            //Print("INDEX: %d\n",l->getIndex());
601            pDelete(&u1);
602    //Print("------------------------------IN CRITERION 2/2-----------------------------------------\n\n");
603            return true;
604        }
605                testNode    =   testNode->getNext();
606    }
607    pDelete(&u1);
608    //Print("------------------------------IN CRITERION 2/2-----------------------------------------\n\n");
609    return false;
610}
611
612
613
614/*
615==================================
616Computation of S-Polynomials in F5
617==================================
618*/
619void computeSPols(CNode* first, RTagList* rTag, RList* rules, LList* sPolyList) { 
620    CNode* temp         =   first;
621    poly sp     =   pInit();
622    number sign =   nInit(-1);   
623    //Print("###############################IN SPOLS##############################\n");
624    //first->print();
625
626    while(NULL != temp) {
627        // counting the number of useful pairs
628        if(!temp->getDel()) {
629          //Print("%d\n",numberUsefulPairs);
630          numberUsefulPairs--;
631        }
632        else {
633          numberUselessPairs--;
634        }
635        //Print("JA\n");
636        // only if a new RuleOld was added since the last test in subalgorithm criticalPair()
637        //if(rules->getFirst() != rTag->getFirst()) {
638        if(!criterion2(temp->getT1(),temp->getAdLp1(),rules,temp->getTestedRuleOld())) {
639                // the second component is tested only when it has the actual index, otherwise there is
640                // no new RuleOld to test since the last test in subalgorithm criticalPair()
641                if(highestDegree < pDeg(ppMult_qq(temp->getT1(),temp->getLp1Poly()))) { 
642                    highestDegree   = pDeg(ppMult_qq(temp->getT1(),temp->getLp1Poly()));
643                    //pWrite(pHead(ppMult_qq(temp->getT1(),temp->getLp1Poly())));
644                }   
645                if(temp->getLp2Index() == temp->getLp1Index()) {
646                    if(!criterion2(temp->getT2(),temp->getAdLp2(),rules,temp->getTestedRuleOld())) {
647                        // computation of S-polynomial
648                        //poly p1 =   temp->getLp1Poly();
649                        //poly p2 =   temp->getLp2Poly();
650                        //pIter(p1);
651                        //pIter(p2);
652                        //sp  =   pAdd(ppMult_qq(temp->getT1(),p1),pMult_nn(ppMult_qq(temp->getT2(),p2),sign)); 
653                        sp      =   ksOldSpolyRedNew(ppMult_qq(temp->getT1(),temp->getLp1Poly()),
654                                         ppMult_qq(temp->getT2(),temp->getLp2Poly()));
655                        //Print("BEGIN SPOLY1\n====================\n");
656                        pNorm(sp);
657                        //pWrite(sp);
658                        //Print("END SPOLY1\n====================\n");
659                        if(NULL == sp) {
660                            // as rules consist only of pointers we need to save the labeled
661                            // S-polynomial also of a zero S-polynomial
662                            //zeroList->insert(temp->getAdT1(),temp->getLp1Index(),&sp);
663                            // origin of RuleOld can be set NULL as the labeled polynomial
664                            // will never be used again as it is zero => no problems with
665                            // further criterion2() tests and termination conditions
666                            //Print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ZERO REDUCTION~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
667                                                        reductionsToZero++;
668                        //Print("IN SPOLS 1\n");
669                            //Rule* rNew  =  new Rule(temp->getLp1Index(),ppMult_qq(temp->getT1(),temp->getLp1Term()));
670                            //rules->insertOrdered(rNew);
671                            rules->insert(temp->getLp1Index(),ppMult_qq(temp->getT1(),temp->getLp1Term()));
672                            numberOfRules++;
673                            //Print("RuleOld ADDED: \n");
674                            //pWrite(rules->getFirst()->getRuleTerm());
675                            //rules->print();
676                            // as sp = NULL, delete it
677                            pDelete(&sp);
678                            //Print("HIER\n");
679                        }
680                        else {
681                        //Print("IN SPOLS 2\n");
682                            //Rule* rNew  =  new Rule(temp->getLp1Index(),ppMult_qq(temp->getT1(),temp->getLp1Term()));
683                            //rules->insertOrdered(rNew);
684                            rules->insert(temp->getLp1Index(),ppMult_qq(temp->getT1(),temp->getLp1Term()));
685                            numberOfRules++;
686                            //Print("RuleOld ADDED: \n");
687                            //pWrite(rules->getFirst()->getRuleTerm()); 
688                            //rules->print();
689                            sPolyList->insertByLabel(ppMult_qq(temp->getT1(),temp->getLp1Term()),temp->getLp1Index(),sp,rules->getFirst()->getRuleOld());
690                            //sPolyList->insertByLabel(ppMult_qq(temp->getT1(),temp->getLp1Term()),temp->getLp1Index(),sp,rNew);
691                        }
692                        // data is saved in sPolyList or zero => delete sp
693                    }
694                    else {
695                      Print("CRITERION 2 in SPOLS 2nd generator\n");
696                    }
697                }
698                else { // temp->getLp2Index() < temp->getLp1Index()
699                    // computation of S-polynomial
700                        //poly p1 =   temp->getLp1Poly();
701                        //poly p2 =   temp->getLp2Poly();
702                        //pIter(p1);
703                        //pIter(p2);
704                        //sp  =   pAdd(ppMult_qq(temp->getT1(),p1),pMult_nn(ppMult_qq(temp->getT2(),p2),sign)); 
705                    sp      =   ksOldSpolyRedNew(ppMult_qq(temp->getT1(),temp->getLp1Poly()),
706                                     ppMult_qq(temp->getT2(),temp->getLp2Poly()));
707                    //Print("BEGIN SPOLY2\n====================\n");
708                    pNorm(sp);
709                    //pWrite(sp);
710                    //Print("END SPOLY2\n====================\n");
711                    if(NULL == sp) {
712                        // zeroList->insert(temp->getAdT1(),temp->getLp1Index(),&sp);
713                        // origin of RuleOld can be set NULL as the labeled polynomial
714                        // will never be used again as it is zero => no problems with
715                        // further criterion2() tests and termination conditions
716                            //Print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ZERO REDUCTION~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
717                        reductionsToZero++;
718                        //Print("IN SPOLS 3\n");
719                        rules->insert(temp->getLp1Index(),ppMult_qq(temp->getT1(),temp->getLp1Term()));
720                        numberOfRules++;
721                        //Print("RuleOld ADDED: \n");
722                        //pWrite(rules->getFirst()->getRuleTerm());
723                        //rules->print();
724                        // as sp = NULL, delete it
725                        pDelete(&sp);
726                    }
727                    else {
728                        //Print("IN SPOLS 4\n");
729                       
730                        //////////////////////////////////////////////////////////
731                        //////////////////////////////////////////////////////////
732                        // TODO: Rules inserted ordered by their label monomial!//
733                        //////////////////////////////////////////////////////////
734                        //////////////////////////////////////////////////////////
735
736                        //Rule* rNew      =   new Rule(temp->getLp1Index(),ppMult_qq(temp->getT1(),temp->getLp1Term()));
737                        //RNode* rNodeNew =   new RNode(rNew);
738                        //rules->insertOrdered(rNew);
739                        rules->insert(temp->getLp1Index(),ppMult_qq(temp->getT1(),temp->getLp1Term()));
740                        numberOfRules++;
741                        //Print("RuleOld ADDED: \n");
742                        //pWrite(rules->getFirst()->getRuleTerm());
743                        //rules->print();
744                        //Print("%d\n",rules->getFirst()->getRuleIndex());
745                        //Print("%p\n",sPolyList->getFirst());
746                        sPolyList->insertByLabel(ppMult_qq(temp->getT1(),temp->getLp1Term()),temp->getLp1Index(),sp,rules->getFirst()->getRuleOld());
747                        //sPolyList->insertByLabel(ppMult_qq(temp->getT1(),temp->getLp1Term()),temp->getLp1Index(),sp,rNew);
748                    }
749                }
750            }
751            else {
752              Print("CRITERION 2 in SPOLS 1st generator\n");
753            }
754        //}
755        //Print("%p\n",temp);
756        temp    =   temp->getNext();
757        //Print("%p\n",temp);
758        //Print("%p\n",temp->getData());
759        //pWrite(temp->getLp1Poly());
760    }
761    // these critical pairs can be deleted now as they are either useless for further computations or
762    // already saved as an S-polynomial to be reduced in the following
763    delete first;   
764}
765
766
767
768/*
769========================================================================
770reduction including subalgorithm topReduction() using Faugere's criteria
771========================================================================
772*/
773void reduction(LList* sPolyList, CListOld* critPairs, LList* gPrev, RList* rules, LTagList* lTag, RTagList* rTag, 
774                 ideal gbPrev) { 
775    //Print("##########################################In REDUCTION!########################################\n");
776    // check if sPolyList has any elements
777    // NOTE: due to initialization sPolyList always has a default NULL element
778    LNode* temp = sPolyList->getFirst();
779    while(NULL != temp) {
780        // temp is the first element in the sPolyList which should be reduced
781        // due to earlier sorting this is the element of minimal degree AND
782        // minimal label
783        // delete the above first element from sPolyList, temp will be either reduced to
784        // zero or added to gPrev, but never come back to sPolyList
785        //pWrite(sPolyList->getFirst()->getPoly());
786        //Print("LIST OF SPOLYNOMIALS!\n");
787        //sPolyList->print();
788        sPolyList->setFirst(temp->getNext());
789        poly tempNF = kNF(gbPrev,currQuotient,temp->getPoly());
790        if(NULL != tempNF) {
791            pNorm(tempNF);
792            temp->setPoly(tempNF);
793            // try further reductions of temp with polynomials in gPrev
794            // with label index = current label index: this is done such that there
795            // is no label corruption during the reduction process
796            //Print("lower label reduction:  ");
797            //pWrite(tempNF);
798            topReduction(temp,sPolyList,gPrev,critPairs,rules,lTag,rTag,gbPrev);
799       
800        }
801        else {
802            reductionsToZero++;
803            delete temp;
804        }
805        //if(NULL != temp->getPoly()) {
806        //    criticalPair(gPrev,critPairs,lTag,rTag,rules);
807        //}
808        temp =   sPolyList->getFirst();
809    }
810    //sPolyList->print();
811    //delete sPolyList;
812}   
813
814/*
815========================================================================
816reduction including subalgorithm topReduction() using Faugere's criteria
817========================================================================
818*/
819void newReduction(LList* sPolyList, CListOld* critPairs, LList* gPrev, LList* reducers, RList* rules, LTagList* lTag, RTagList* rTag, 
820                 ideal gbPrev, int termination) { 
821    //Print("##########################################In REDUCTION!########################################\n");
822    // check if sPolyList has any elements
823    // NOTE: due to initialization sPolyList always has a default NULL element
824    //Print("--1--\n");
825    LNode* temp = sPolyList->getFirst();
826    while(NULL != temp) {
827        // temp is the first element in the sPolyList which should be reduced
828        // due to earlier sorting this is the element of minimal degree AND
829        // minimal label
830        // delete the above first element from sPolyList, temp will be either reduced to
831        // zero or added to gPrev, but never come back to sPolyList
832        //Print("LIST OF SPOLYNOMIALS!\n");
833        //sPolyList->print();
834        //pWrite(sPolyList->getFirst()->getPoly());
835        sPolyList->setFirst(temp->getNext());
836        //pWrite(temp->getPoly());
837        //poly tempNF = kNF(gbPrev,currQuotient,temp->getPoly());
838        //Print("!!!\n");
839        //if(NULL != tempNF) {
840            //pNorm(tempNF);
841            //temp->setPoly(tempNF);
842            //Print("lower label reduction:  ");
843            //pWrite(tempNF);
844            // try further reductions of temp with polynomials in gPrev
845            // with label index = current label index: this is done such that there
846            // is no label corruption during the reduction process
847            findReducers(temp,sPolyList,gbPrev,gPrev,reducers,critPairs,rules,lTag,rTag, termination); 
848        //}
849        //else {
850        //    reductionsToZero++;
851        //    delete temp;
852        //}
853        //if(NULL != temp->getPoly()) {
854        //    criticalPair(gPrev,critPairs,lTag,rTag,rules);
855        //}
856        //Print("HIER AUCH ?\n");
857        //Print("--2--\n");
858        //sPolyList->print();
859        //critPairs->print();
860        temp =   sPolyList->getFirst();
861        //Print("%p\n",temp);
862    }
863    //sPolyList->print();
864    //delete sPolyList;
865    //Print("REDUCTION FERTIG\n");
866}     
867
868
869/*!
870 * ================================================================================
871 * searches for reducers of temp similar to the symbolic preprocessing of F4  and
872 * divides them into a "good" and "bad" part:
873 *
874 * the "good" ones are the reducers which do not corrupt the label of temp, with
875 * these the normal form of temp is computed
876 *
877 * the "bad" ones are the reducers which corrupt the label of temp, they are tested
878 * later on for possible new rules and S-polynomials to be added to the algorithm
879 * ================================================================================
880*/
881void findReducers(LNode* l, LList* sPolyList, ideal gbPrev, LList* gPrev, LList* reducers, CListOld* critPairs, RList* rules, LTagList* lTag, RTagList* rTag, int termination) {
882    int canonicalize    =   0;
883    //int timerRed        =   0;
884    bool addToG         =   1;
885    number sign         =   nInit(-1);
886    LList* good         =   new LList();
887    LList* bad          =   new LList();
888    LList* monomials    =   new LList(l->getLPolyOld());
889    poly u              =   pOne();
890    number nOne         =   nInit(1);
891    LNode* tempRed      =   lTag->getFirstCurrentIdx();
892    LNode* tempMon      =   monomials->getFirst();
893    poly tempPoly       =   pInit();
894    poly redPoly        =   NULL;
895    int idx             =   l->getIndex();
896    //Print("IN FIND REDUCERS:  ");
897    //pWrite(l->getPoly());
898    tempPoly    =   pCopy(l->getPoly());
899    //tempMon->setPoly(tempPoly);
900    //while(NULL != tempMon) {
901        // iteration over all monomials in tempMon
902        kBucket* bucket  =   kBucketCreate();
903        kBucketInit(bucket,tempPoly,0);
904        tempPoly    =   kBucketGetLm(bucket);
905        //Print("\n\n\nTO BE REDUCED:  ");
906        //pWrite(l->getPoly());
907        //pWrite(l->getTerm());
908        //pWrite(tempPoly);
909        while(NULL != tempPoly) {
910            // iteration of all elements in gPrev of the current index
911            tempRed =   gPrev->getFirst();
912            while(NULL != tempRed) {
913                //Print("TEMPREDPOLY:  ");
914                //pWrite(tempRed->getPoly());
915                if(pLmDivisibleByNoComp(tempRed->getPoly(),tempPoly)) {
916                    u   =   pDivideM(pHead(tempPoly),pHead(tempRed->getPoly()));
917                    //Print("U:  ");
918                    //pWrite(u);
919                    if(tempRed->getIndex() != idx) {
920                            // passing criterion1 ?
921                            if(!criterion1(gPrev,u,tempRed,lTag)) {
922                                    poly tempRedPoly    =   tempRed->getPoly();
923                                    //Print("REDUCER: ");
924                                    //pWrite(ppMult_qq(u,tempRedPoly));
925                                    pIter(tempRedPoly);
926                                    int lTempRedPoly    =   pLength(tempRedPoly);
927                                    kBucketExtractLm(bucket);
928                                    kBucket_Minus_m_Mult_p(bucket,u,tempRedPoly,&lTempRedPoly);
929                                    canonicalize++;
930                                    //Print("Reduction\n");
931                                    if(!(canonicalize % 50)) {
932                                        kBucketCanonicalize(bucket);
933                                    }
934                                    tempPoly    =   kBucketGetLm(bucket);
935                                    //Print("TEMPPOLY:  ");
936                                    //pWrite(tempPoly);
937                                    if(NULL != tempPoly) {
938                                        tempRed     =   gPrev->getFirst();
939                                        continue;
940                                    }
941                                    else {
942                                        break;
943                                    }
944                             }   
945                   
946                    }
947                    else {
948                        if(pLmCmp(ppMult_qq(u,tempRed->getTerm()),l->getTerm()) == 0) {
949                         //Print("NOT ALLOWED REDUCER, EQUAL LABELS:\n");
950                                      //pWrite(u);
951                                      //pWrite(tempRed->getTerm());
952                                      //pWrite(pHead(tempRed->getPoly()));
953                                      addToG  = 0;
954                        }
955                        if(pLmCmp(ppMult_qq(u,tempRed->getTerm()),l->getTerm()) != 0) {
956                            // passing criterion2 ?
957                            if(!criterion2(gPrev->getFirst()->getIndex(), u,tempRed,rules,rTag)) {
958                                // passing criterion1 ?
959                                if(!criterion1(gPrev,u,tempRed,lTag)) {
960                                    if(pLmCmp(ppMult_qq(u,tempRed->getTerm()),l->getTerm()) == 1) {
961                                        if(NULL == redPoly) {
962                                            bad->insert(tempRed->getLPolyOld());
963                                            addToG  = 1;
964                                            //poly tempRedPoly    =   tempRed->getPoly();
965                                            //break;
966                                        }
967                                    }
968                                    else {
969                                        poly tempRedPoly    =   tempRed->getPoly();
970                                        //Print("REDUCER: ");
971                                        //pWrite(ppMult_qq(u,tempRedPoly));
972                                        pIter(tempRedPoly);
973                                        int lTempRedPoly    =   pLength(tempRedPoly);
974                                        //Print("HEAD MONOMIAL KBUCKET: ");
975                                        //pWrite(kBucketGetLm(bucket));
976                                        kBucketExtractLm(bucket);
977                                        kBucket_Minus_m_Mult_p(bucket,u,tempRedPoly,&lTempRedPoly);
978                                        canonicalize++;
979                                        //Print("REDUCTION\n");
980                                        addToG  = 1;
981                                        if(!(canonicalize % 50)) {
982                                            kBucketCanonicalize(bucket);
983                                        }
984                                        //Print("HEAD MONOMIAL KBUCKET: ");
985                                        //pWrite(kBucketGetLm(bucket));
986                                        tempPoly    =   kBucketGetLm(bucket);
987                                        //Print("TEMPPOLY:  ");
988                                        //pWrite(tempPoly);
989                                        if(NULL != tempPoly) {
990                                            tempRed     =   gPrev->getFirst();
991                                            continue;
992                                        }
993                                        else {
994                                            break;
995                                        }
996                                    }
997                                }   
998                            }
999                            else {
1000                              //Print("CRIT 1  ");
1001                                   
1002                                      if(pLmCmp(ppMult_qq(u,tempRed->getTerm()),l->getTerm()) == 1 ) {
1003                                      //Print("NOT ALLOWED REDUCER, CRIT 1:\n");
1004                                      //pWrite(u);
1005                                      //pWrite(tempRed->getTerm());
1006                                      //pWrite(tempRed->getPoly());
1007                                      if(pLmDivisibleByNoComp(tempRed->getTerm(),l->getTerm())) {
1008                                        //Print("REDUCER LABEL:  ");
1009                                        //pWrite(tempRed->getTerm());
1010addToG  = 0;
1011                                      }
1012                                    }
1013                            }
1014                        }
1015                        else {
1016                          //Print("CRIT 2  ");
1017                                    if(pLmCmp(ppMult_qq(u,tempRed->getTerm()),l->getTerm()) == 1) {
1018                                      //Print("NOT ALLOWED REDUCER, CRIT 2:\n");
1019                                      //pWrite(u);
1020                                      //pWrite(tempRed->getTerm());
1021                                      //pWrite(tempRed->getPoly());
1022                                      if(pLmDivisibleByNoComp(tempRed->getTerm(),l->getTerm())) {
1023                                        //Print("REDUCER LABEL:  ");
1024                                        //pWrite(tempRed->getTerm());
1025addToG  = 0;
1026                                      }
1027                                    }
1028                        }
1029                    }
1030                   
1031                }
1032                tempRed =   tempRed->getNext();
1033            }
1034            // reduction process with elements in LList* reducers
1035          if(NULL != tempPoly) {
1036            //Print("HERE\n");
1037            tempRed =   reducers->getFirst();
1038            while(NULL != tempRed) {
1039                //Print("TEMPREDPOLY:  ");
1040                //pWrite(tempRed->getPoly());
1041              //pWrite(tempPoly); 
1042              if(pLmDivisibleByNoComp(tempRed->getPoly(),tempPoly)) {
1043                    //Print("A\n");
1044                    u   =   pDivideM(pHead(tempPoly),pHead(tempRed->getPoly()));
1045                    //Print("U:  ");
1046                    //pWrite(u);
1047                    if(tempRed->getIndex() != idx) {
1048                            // passing criterion1 ?
1049                            if(!criterion1(gPrev,u,tempRed,lTag)) {
1050                                    poly tempRedPoly    =   tempRed->getPoly();
1051                                    //Print("REDUCER: ");
1052                                    //pWrite(ppMult_qq(u,tempRedPoly));
1053                                    pIter(tempRedPoly);
1054                                    int lTempRedPoly    =   pLength(tempRedPoly);
1055                                    kBucketExtractLm(bucket);
1056                                    kBucket_Minus_m_Mult_p(bucket,u,tempRedPoly,&lTempRedPoly);
1057                                    canonicalize++;
1058                                    //Print("Reduction\n");
1059                                    if(!(canonicalize % 50)) {
1060                                        kBucketCanonicalize(bucket);
1061                                    }
1062                                    tempPoly    =   kBucketGetLm(bucket);
1063                                    //Print("TEMPPOLY:  ");
1064                                    //pWrite(tempPoly);
1065                                    if(NULL != tempPoly) {
1066                                        tempRed     =   gPrev->getFirst();
1067                                        continue;
1068                                    }
1069                                    else {
1070                                        break;
1071                                    }
1072                             }   
1073                   
1074                    }
1075                    else {
1076                        if(pLmCmp(ppMult_qq(u,tempRed->getTerm()),l->getTerm()) == 0) {
1077                         //Print("NOT ALLOWED REDUCER, EQUAL LABELS:\n");
1078                                      //pWrite(u);
1079                                      //pWrite(tempRed->getTerm());
1080                                      //pWrite(pHead(tempRed->getPoly()));
1081                                      //addToG  = 0;
1082                        }
1083                        if(pLmCmp(ppMult_qq(u,tempRed->getTerm()),l->getTerm()) != 0) {
1084                            // passing criterion2 ?
1085                            if(!criterion2(gPrev->getFirst()->getIndex(), u,tempRed,rules,rTag)) {
1086                                // passing criterion1 ?
1087                                if(!criterion1(gPrev,u,tempRed,lTag)) {
1088                                    if(pLmCmp(ppMult_qq(u,tempRed->getTerm()),l->getTerm()) == 1) {
1089                                        if(NULL == redPoly) {
1090                                            bad->insert(tempRed->getLPolyOld());
1091                                            addToG  = 1;
1092                                            //poly tempRedPoly    =   tempRed->getPoly();
1093                                            //break;
1094                                        }
1095                                    }
1096                                    else {
1097                                        poly tempRedPoly    =   tempRed->getPoly();
1098                                        //Print("REDUCER: ");
1099                                        //pWrite(ppMult_qq(u,tempRedPoly));
1100                                        pIter(tempRedPoly);
1101                                        int lTempRedPoly    =   pLength(tempRedPoly);
1102                                        //Print("HEAD MONOMIAL KBUCKET: ");
1103                                        //pWrite(kBucketGetLm(bucket));
1104                                        kBucketExtractLm(bucket);
1105                                        kBucket_Minus_m_Mult_p(bucket,u,tempRedPoly,&lTempRedPoly);
1106                                        canonicalize++;
1107                                        //Print("REDUCTION\n");
1108                                        addToG  = 1;
1109                                        if(!(canonicalize % 50)) {
1110                                            kBucketCanonicalize(bucket);
1111                                        }
1112                                        //Print("HEAD MONOMIAL KBUCKET: ");
1113                                        //pWrite(kBucketGetLm(bucket));
1114                                        tempPoly    =   kBucketGetLm(bucket);
1115                                        //Print("TEMPPOLY:  ");
1116                                        //pWrite(tempPoly);
1117                                        if(NULL != tempPoly) {
1118                                            tempRed     =   gPrev->getFirst();
1119                                            continue;
1120                                        }
1121                                        else {
1122                                            break;
1123                                        }
1124                                    }
1125                                }   
1126                            }
1127                            else {
1128                              //Print("CRIT 1  ");
1129                                   
1130                                      if(pLmCmp(ppMult_qq(u,tempRed->getTerm()),l->getTerm()) == 1 ) {
1131                                      //Print("NOT ALLOWED REDUCER, CRIT 1:\n");
1132                                      //pWrite(u);
1133                                      //pWrite(tempRed->getTerm());
1134                                      //pWrite(tempRed->getPoly());
1135                                      if(pLmDivisibleByNoComp(tempRed->getTerm(),l->getTerm())) {
1136                                        //Print("REDUCER LABEL:  ");
1137                                        //pWrite(tempRed->getTerm());
1138                                        addToG  = 0;
1139                                      }
1140                                    }
1141                            }
1142                        }
1143                        else {
1144                          //Print("CRIT 2  ");
1145                                    if(pLmCmp(ppMult_qq(u,tempRed->getTerm()),l->getTerm()) == 1) {
1146                                      //Print("NOT ALLOWED REDUCER, CRIT 2:\n");
1147                                      //pWrite(u);
1148                                      //pWrite(tempRed->getTerm());
1149                                      //pWrite(tempRed->getPoly());
1150                                      if(pLmDivisibleByNoComp(tempRed->getTerm(),l->getTerm())) {
1151                                        //Print("REDUCER LABEL:  ");
1152                                        //pWrite(tempRed->getTerm());
1153addToG  = 0;
1154                                      }
1155                                    }
1156                        }
1157                    }
1158                   
1159                }
1160                tempRed =   tempRed->getNext();
1161            }
1162          }
1163            if(NULL != tempPoly) {
1164                if(NULL == redPoly) {
1165                    redPoly =   kBucketExtractLm(bucket);
1166                }
1167                else {
1168                    redPoly     =   p_Merge_q(redPoly,kBucketExtractLm(bucket),currRing);
1169                }
1170               // for top-reduction only
1171               redPoly  = p_Merge_q(redPoly,kBucketClear(bucket),currRing);
1172               break;
1173               // end for top-reduction only
1174               tempPoly    =   kBucketGetLm(bucket);
1175               
1176            }
1177        }
1178        if(NULL == redPoly) {
1179            reductionsToZero++;
1180            //pDelete(&redPoly);
1181        }
1182        else {
1183            Print("\nELEMENT ADDED TO GPREV: ");
1184            pNorm(redPoly);
1185            pWrite(pHead(redPoly));
1186            pWrite(l->getTerm());
1187            //Print("%d\n",canonicalize);
1188            l->setPoly(redPoly);
1189            // give "l" the label if it is "useful" (addToG = 0) or "useless"
1190            // (addToG = 1)
1191            l->setDel(!addToG);
1192            if(addToG == 0 && termination == 1) {
1193              reducers->insert(l->getLPolyOld());
1194            }
1195            else {
1196              gPrev->insert(l->getLPolyOld());
1197            }
1198            //Print("%d\n\n",termination);
1199            if(termination == 1) {
1200            if(addToG) {
1201              //Print("----------------HERE?-----------------\n");
1202              criticalPair(gPrev,critPairs,lTag,rTag,rules);
1203            }
1204            else {
1205              notInG++;
1206              //Print("\nNONONO");
1207              //pWrite(pHead(l->getPoly()));
1208              //pWrite(l->getTerm());
1209            }
1210            }
1211            // case in which all new elements are added to gPrev!
1212            // using boolean "addToG" to know if the element is "useful" (0) or
1213            // "useless" (1)
1214            else {
1215              if(!l->getDel()) {
1216                criticalPair(gPrev,critPairs,lTag,rTag,rules);
1217              }
1218              else {
1219                criticalPair2(gPrev,critPairs,lTag,rTag,rules);
1220              }
1221            }
1222        }
1223   
1224    // if there are "bad" reducers than try to compute new S-polynomials and rules
1225   
1226    if(NULL != bad->getFirst()) {
1227        //Print("BAD STUFF LIST:\n");
1228        //bad->print();
1229        LNode* tempBad  =   bad->getFirst();
1230        //pWrite(l->getPoly());
1231        while(NULL != tempBad) {
1232            if(pDivisibleBy(tempBad->getPoly(),l->getPoly())) {
1233                //Print("BAD STUFF\n");
1234                //pWrite(l->getPoly());
1235                //pWrite(tempBad->getPoly());
1236                u   =   pDivide(pHead(l->getPoly()),pHead(tempBad->getPoly()));
1237                //Print("MULTIPLIER:  ");
1238                //pWrite(u);
1239                pSetCoeff(u,nOne);
1240                if(pLmCmp(ppMult_qq(u,tempBad->getTerm()),l->getTerm()) != 0) {
1241                    // passing criterion2 ?
1242                    if(!criterion2(gPrev->getFirst()->getIndex(), u,tempBad,rules,rTag)) {
1243                        // passing criterion1 ?
1244                        if(!criterion1(gPrev,u,tempBad,lTag)) {
1245                            //Print("HIERHIERHIERHIERHIERHIER\n");
1246                            rules->insert(tempBad->getIndex(),ppMult_qq(u,tempBad->getTerm()));
1247                            numberOfRules++;
1248                            //gPrev->print();
1249                            //pWrite(l->getPoly());
1250                            poly temp   =   ksOldSpolyRedNew(ppMult_qq(u,tempBad->getPoly()),l->getPoly());
1251                            //pWrite(l->getPoly());
1252                            //Print("%p\n",temp);
1253                            //gPrev->print();
1254                            if(NULL != temp) {
1255                                pNorm(temp);
1256                                LNode* tempBadNew   =   new LNode(ppMult_qq(u,tempBad->getTerm()),tempBad->getIndex(),temp,rules->getFirst()->getRuleOld());
1257                                //pWrite(temp);
1258                                //pWrite(tempBadNew->getPoly());
1259                                //pWrite(tempBadNew->getTerm());
1260                                //pWrite(pHead(tempBadNew->getPoly()));
1261                                //Print("%p\n",tempBadNew->getPoly());
1262                                //tempRed->getLPoly()->setRule(rules->getFirst()->getRule());
1263                                tempBadNew->setDel(1);
1264                           
1265                                sPolyList->insertByLabel(tempBadNew);
1266                                //Print("BAD SPOLYLIST: \n");
1267                                //sPolyList->print();
1268                            }
1269                        }
1270                    }
1271                }
1272            }
1273        //Print("HIER\n");
1274            tempBad =   tempBad->getNext();
1275            //Print("%p\n",tempBad);
1276        }
1277       // Print("-------------------BAD STUFF LIST-----------------------------\n");
1278    }
1279        //Print("HIER AUCH\n");
1280        //Print("SPOLYLIST IN BAD: \n");
1281        //sPolyList->print();
1282    //Print("END FIND REDUCERS\n");
1283}
1284
1285/*
1286=======================================================================================
1287merging 2 polynomials p & q without requiring that all monomials of p & q are different
1288if there are equal monomials in p & q only one of these monomials (always that of p!)
1289is taken into account
1290=======================================================================================
1291
1292poly p_MergeEq_q(poly p, poly q, const ring r) {
1293  assume(p != NULL && q != NULL);
1294  p_Test(p, r);
1295  p_Test(q, r);
1296#if PDEBUG > 0
1297  int l = pLength(p) + pLength(q);
1298#endif
1299
1300  spolyrec rp;
1301  poly a = &rp;
1302  DECLARE_LENGTH(const unsigned long length = r->CmpL_Size);
1303  DECLARE_ORDSGN(const long* ordsgn = r->ordsgn);
1304
1305  Top:     // compare p and q w.r.t. monomial ordering
1306  p_MemCmp(p->exp, q->exp, length, ordsgn, goto Equal, goto Greater , goto Smaller);
1307
1308  Equal:
1309  a =   pNext(a)    =   p;
1310  pIter(p);
1311  pIter(q);
1312  if(NULL == p) {
1313      if(NULL == q) {
1314          goto Finish;
1315      }
1316      else {
1317          pNext(a)  =   q;
1318          goto Finish;
1319      }
1320  }
1321  goto Top;
1322
1323  Greater:
1324  a = pNext(a) = p;
1325  pIter(p);
1326  if (p==NULL) { pNext(a) = q; goto Finish;}
1327  goto Top;
1328
1329  Smaller:
1330  a = pNext(a) = q;
1331  pIter(q);
1332  if (q==NULL) { pNext(a) = p; goto Finish;}
1333  goto Top;
1334
1335  Finish:
1336
1337  p_Test(pNext(&rp), r);
1338#if PDEBUG > 0
1339  pAssume1(l - pLength(pNext(&rp)) == 0);
1340#endif
1341  return pNext(&rp);
1342}
1343*/
1344
1345/*
1346=====================================================================================
1347top reduction in F5, i.e. reduction of a given S-polynomial by labeled polynomials of
1348the same index whereas the labels are taken into account
1349=====================================================================================
1350*/
1351void topReduction(LNode* l, LList* sPolyList, LList* gPrev, CListOld* critPairs,  RList* rules, LTagList* lTag, RTagList* rTag, ideal gbPrev) {
1352    //Print("##########################################In topREDUCTION!########################################\n");
1353    // try l as long as there are reductors found by findReductor()
1354    LNode* gPrevRedCheck    =   lTag->getFirstCurrentIdx();
1355    LNode* tempRed;
1356    poly pOne               =   pOne();
1357    do {
1358        //int timer5  =   initTimer();
1359        //startTimer();
1360        //Print("TOP REDUCTION:  ");
1361        //pWrite(l->getPoly());
1362        tempRed  =   findReductor(l,sPolyList,gPrevRedCheck,gPrev,rules,lTag,rTag);
1363        //timer5  =   getTimer();
1364        //reductionTime   =   reductionTime   +   timer5;
1365        // if a reductor for l is found and saved in tempRed
1366        if(NULL != tempRed) {
1367            // if label of reductor is greater than the label of l we have to built a new element
1368            // and add it to sPolyList
1369           
1370            if(pLmCmp(tempRed->getTerm(),l->getTerm()) == 1) {
1371                // needed sinc pSub destroys the arguments!
1372                //poly temp_poly_l    =   pInit();
1373                //temp_poly_l         =   pCopy(l->getPoly());
1374                //Print("VORHER: ");
1375                //pWrite(tempRed->getPoly());
1376                //poly temp           =   pMinus_mm_Mult_qq(tempRed->getPoly(),pOne,l->getPoly());
1377                poly temp   =   ksOldSpolyRedNew(l->getPoly(),tempRed->getPoly());
1378                rules->insert(tempRed->getIndex(),tempRed->getTerm());
1379                //Print("NACHHER: ");
1380                //pWrite(tempRed->getPoly());
1381                //Print("TEMP: ");
1382                //pWrite(temp);
1383                if(NULL != temp) {
1384                    pNorm(temp);
1385                    //tempRed->setPoly(temp);
1386                    //tempRed->setDel(1);
1387                    //rules->insert(tempRed->getIndex(),tempRed->getTerm());
1388                    LNode* tempRedNew   =   new LNode(tempRed->getTerm(),tempRed->getIndex(),temp,rules->getFirst()->getRuleOld());
1389                    //tempRed->getLPoly()->setRule(rules->getFirst()->getRule());
1390                    tempRedNew->setDel(1);
1391                    sPolyList->insertByLabel(tempRedNew);
1392                }
1393                else {
1394                    pDelete(&temp);
1395                    reductionsToZero++;
1396                    //delete tempRed;
1397                }
1398            }
1399           
1400            // label of reductor is smaller than the label of l, subtract reductor from l and delete the
1401            // gPrevRedCheck pointer added to l during findReductor() as the head term of l changes
1402            // after subtraction
1403            else {
1404               
1405                //poly temp_poly_l    =   pInit();
1406                //temp_poly_l         =   pCopy(l->getPoly());
1407                //poly temp   =   pMinus_mm_Mult_qq(tempRed->getPoly(),pOne,l->getPoly());
1408                //Print("REDUCER: ");
1409                //pWrite(tempRed->getPoly());
1410                //pWrite(tempRed->getTerm());
1411                poly temp   =   ksOldSpolyRedNew(l->getPoly(),tempRed->getPoly());
1412                //Print("REDUCED ELEMENT:  ");
1413                if(NULL != temp) {
1414                    pNorm(temp);
1415                    //pWrite(temp);
1416                    poly tempNF =   kNF(gbPrev,currQuotient,temp); 
1417                    pNorm(tempNF);
1418                    if(NULL == tempNF) {
1419                        reductionsToZero++;
1420                        pDelete(&tempNF);
1421                        l->setPoly(NULL);
1422                        break;
1423                    }
1424                    l->setPoly(tempNF);
1425                   
1426                    gPrevRedCheck   =   lTag->getFirstCurrentIdx();
1427                }
1428                else {
1429                    reductionsToZero++;
1430                    pDelete(&temp);
1431                    l->setPoly(NULL);
1432                    break;
1433                }
1434            }   
1435        }
1436        else {
1437            if(NULL != l->getPoly()) {
1438                pNorm(l->getPoly());
1439                //Print("ELEMENT ADDED TO GPREV: ");
1440                //pWrite(l->getPoly());
1441                gPrev->insert(l->getLPolyOld());
1442                //Print("TEMP RED == 0  ");
1443                //pWrite(l->getPoly());
1444                //pWrite(l->getTerm());
1445                //rules->print();
1446                criticalPair(gPrev,critPairs,lTag,rTag,rules);
1447                //Print("LIST OF CRITICAL PAIRS:    \n");
1448                //critPairs->print();
1449            }
1450            break;
1451        }
1452    } while(1);
1453}
1454
1455
1456/*
1457=====================================================================
1458subalgorithm to find a possible reductor for the labeled polynomial l
1459=====================================================================
1460*/
1461LNode* findReductor(LNode* l, LList* sPolyList, LNode* gPrevRedCheck, LList* gPrev, RList* rules, LTagList* lTag,RTagList* rTag) {
1462    // allociation of memory for the possible reductor
1463    //Print("LPOLY:  ");
1464    //pWrite(l->getPoly());
1465    poly u      =   pOne();
1466    poly red;
1467    number nOne =   nInit(1);
1468    LNode* temp;
1469    // head term of actual element such that we do not have to call pHead at each new reductor test
1470    poly t      =   pHead(l->getPoly());
1471    // if l was already checked use the information in gPrevRedCheck such
1472    // that we can start searching for new reducers from this point and
1473    // not from the first element of gPrev with the current index
1474    temp    =   gPrevRedCheck;
1475    // search for reductors until we are at the end of gPrev resp. at the
1476    // end of the elements of the current index
1477    while(NULL != temp && temp->getIndex() == l->getIndex()) {
1478        // does the head of the element of gPrev divides the head of
1479        // the to be reduced element?
1480        if(pLmDivisibleByNoComp(pHead(temp->getPoly()),t)) {
1481            // get all the information needed for the following tests
1482            // of the criteria
1483            u   =   pDivide(t,pHead(temp->getPoly()));
1484            pSetCoeff(u,nOne);
1485            red =   ppMult_qq(u,temp->getPoly());
1486            pNorm(red);
1487            // check if both have the same label
1488            if(pLmCmp(ppMult_qq(u,temp->getTerm()),l->getTerm()) != 0) {
1489                // passing criterion2 ?
1490                if(!criterion2(gPrev->getFirst()->getIndex(), u,temp,rules,rTag)) {
1491                    // passing criterion1 ?
1492                    if(!criterion1(gPrev,u,temp,lTag)) {
1493                            gPrevRedCheck   =   temp->getNext();
1494                            LNode* redNode  =   new LNode(ppMult_qq(u,temp->getTerm()),temp->getIndex(),red,NULL,NULL);
1495                            return redNode;
1496                    }
1497                }
1498            }
1499            if(pLmCmp(ppMult_qq(u,temp->getTerm()),l->getTerm()) == 1) {
1500                // passing criterion2 ?
1501                if(!criterion2(gPrev->getFirst()->getIndex(), u,temp,rules,rTag)) {
1502                    // passing criterion1 ?
1503                    if(!criterion1(gPrev,u,temp,lTag)) {
1504                        poly tempSpoly  =   ksOldSpolyRedNew(red,l->getPoly());
1505                        rules->insert(temp->getIndex(),ppMult_qq(u,temp->getTerm()));
1506                        gPrevRedCheck   =   temp->getNext();
1507                        if(NULL != tempSpoly) {
1508                            pNorm(tempSpoly);
1509                            sPolyList->insertByLabel(ppMult_qq(u,temp->getTerm()),temp->getIndex(),tempSpoly,rules->getFirst()->getRuleOld());
1510                    //Print("NEW ONE: ");
1511                    //pWrite(tempSpoly);
1512                    //Print("HIER\n");
1513                            //sPolyList->print();
1514                            //sleep(5);
1515                        }
1516                    }
1517                }
1518            }
1519        }
1520        //Print("AUCH HIER\n");
1521        temp = temp->getNext();
1522    }
1523   
1524//    delete temp;
1525 return NULL;
1526}
1527
1528
1529
1530/*
1531==========================================================================
1532MAIN:computes a gb of the ideal i in the ring r with our F5 implementation
1533OPTIONS: INTEGER "opt" is to be set "0" for F5, "1" for F5R, "2" for F5C
1534==========================================================================
1535*/
1536ideal F5main(ideal id, ring r, int opt, int termination) {
1537  switch(opt) { 
1538    case 0:
1539      Print("\nComputations are done by the standard F5 Algorithm");
1540      break;
1541    case 1:
1542      Print("\nComputations are done by the variant F5R of the F5 Algorithm");
1543      break;
1544    case 2:
1545      Print("\nComputations are done by the variant F5C of the F5 Algorithm");
1546      break;
1547    default:
1548      WerrorS("\nThe option can only be set to \"0\", \"1\" or \"2\":\n\"0\": standard F5 Algorithm\n\"1\": variant F5R\n\"2\": variant F5C\nComputations are aborted!\n");
1549      return id;
1550  }
1551    int timer   =   initTimer();
1552    startTimer();
1553    int i,j,k,l;
1554    int gbLength;
1555    // 1 polynomial for defining initial labels & further tests
1556    poly ONE = pOne();
1557    poly pOne   =   pOne();
1558    number nOne =   nInit(1);
1559    // tag the first element of index i-1 for criterion 1
1560    //Print("LTAG BEGINNING: %p\n",lTag);
1561   
1562    // DEBUGGING STUFF START
1563    //Print("NUMBER: %d\n",r->N);
1564    /*
1565    int* ev = new int[r->N +1];
1566    for(i=0;i<IDELEMS(id);i++) {
1567        pGetExpV(id->m[i],ev);
1568        //ev2  =   pGetExp(id->m[i],1);
1569        pWrite(id->m[i]);
1570        Print("EXP1: %d\n",ev[1]);
1571        Print("EXP2: %d\n",ev[2]);
1572        Print("EXP3: %d\n\n",ev[3]);
1573        Print("SUM: %ld\n\n\n",sumVector(ev,r->N));
1574    }
1575    delete ev;
1576    */
1577    /*DEBUGGING STUFF END */
1578   
1579    // first element in rTag is first element of rules which is NULL RNode,
1580    // this must be done due to possible later improvements
1581    RList* rules    =   new RList();
1582    //Print("RULES FIRST: %p\n",rules->getFirst());
1583    //Print("RULES FIRST DATA: %p\n",rules->getFirst()->getRule());
1584    //RTagList* rTag  =   new RTagList(rules->getFirst());
1585    RTagList* rTag  =   NULL;
1586    i = 1;
1587    /*for(j=0; j<IDELEMS(id); j++) {
1588        if(NULL != id->m[j]) {
1589            if(pComparePolys(id->m[j],ONE)) {
1590                Print("One Polynomial in Input => Computations stopped\n");
1591                ideal idNew = idInit(1,1);
1592                idNew->m[0] = ONE;
1593                return(idNew);
1594            }   
1595        }
1596    }*/ 
1597    ideal idNew     =   kInterRed(id); 
1598    id              =   idNew;
1599    //qsortDegree(&id->m[0],&id->m[IDELEMS(id)-1]);
1600    //idShow(id);
1601    LList* gPrev    =   new LList(ONE, i, id->m[0]);
1602    LList* reducers =   new LList();
1603    //idShow(id);
1604    //Print("%p\n",id->m[0]);
1605    //pWrite(id->m[0]);
1606    //Print("%p\n",gPrev->getFirst()->getPoly());
1607    //pWrite(gPrev->getFirst()->getPoly());
1608
1609    LTagList* lTag  =   new LTagList(gPrev->getFirst());
1610    //lTag->insert(gPrev->getFirst());
1611    lTag->setFirstCurrentIdx(gPrev->getFirst());
1612    // computing the groebner basis of the elements of index < actual index
1613    gbLength    =   gPrev->getLength();
1614    //Print("Laenge der bisherigen Groebner Basis: %d\n",gPrev->getLength());
1615    ideal gbPrev    =   idInit(gbLength,1);
1616    // initializing the groebner basis of elements of index < actual index
1617    gbPrev->m[0]    =   gPrev->getFirst()->getPoly();
1618    //idShow(gbPrev);
1619    //idShow(currQuotient);
1620    for(i=2; i<=IDELEMS(id); i++) {
1621        LNode* gPrevTag =   gPrev->getLast();
1622        //Print("Last POlynomial in GPREV: ");
1623        //Print("%p\n",gPrevTag);   
1624        //pWrite(gPrevTag->getPoly());
1625        gPrev   =   F5inc(i, id->m[i-1], gPrev, reducers, gbPrev, ONE, lTag, rules, rTag, termination);
1626        //Print("%d\n",gPrev->count(gPrevTag->getNext()));
1627        //Print("%d\n",gPrev->getLength());
1628        //Print("____________________________________ITERATION STEP DONE________________________________________\n");
1629       
1630        // DEBUGGING STUFF
1631        LNode* temp    =   gPrev->getFirst();
1632   
1633
1634        /////////////////////////////////////////////////////////////////////////////////
1635        //                                                                             //
1636        // one needs to choose one of the following 3 implementations of the algorithm //
1637        // F5,F5R or F5C                                                               //
1638        //                                                                             //
1639        /////////////////////////////////////////////////////////////////////////////////                                                                           
1640       
1641       
1642        //   
1643        // standard "F5"
1644        //
1645        if(0 == opt) { 
1646          if(gPrev->getLength() > gbLength) {
1647            if(i < IDELEMS(id)) {
1648                ideal gbAdd =   idInit(gPrev->getLength()-gbLength,1);
1649                LNode*  temp =   gPrevTag;
1650                int counter =   0;
1651                for(j=0;j<=gPrev->getLength()-gbLength-1;j++) {
1652                    temp        =   temp->getNext();
1653                    if(0 == temp->getDel()) {
1654                        counter++;
1655                        gbAdd->m[j] =   temp->getPoly();
1656                    }
1657                }
1658                    gbPrev          =   idAdd(gbPrev,gbAdd);
1659            }
1660            else {
1661                ideal gbAdd =   idInit(gPrev->getLength()-gbLength,1);
1662                LNode*  temp =   gPrevTag;
1663                for(j=0;j<=gPrev->getLength()-gbLength-1;j++) {
1664                    temp        =   temp->getNext();
1665                    gbAdd->m[j] =   temp->getPoly();
1666                }
1667                gbPrev          =   idAdd(gbPrev,gbAdd);
1668            }
1669            if(i == IDELEMS(id)) {
1670                ideal tempId        =   kInterRed(gbPrev);
1671                gbPrev              =   tempId;
1672            }
1673        }
1674        gbLength    =   gPrev->getLength();
1675        }
1676       
1677
1678        //
1679        //  "F5R"
1680        //
1681        if(1 == opt) {
1682        if(gPrev->getLength() > gbLength) {
1683            if(i < IDELEMS(id)) {
1684                ideal gbAdd =   idInit(gPrev->getLength()-gbLength,1);
1685                LNode*  temp =   gPrevTag;
1686                int counter =   0;
1687                for(j=0;j<=gPrev->getLength()-gbLength-1;j++) {
1688                    temp        =   temp->getNext();
1689                    if(0 == temp->getDel()) {
1690                        counter++;
1691                        gbAdd->m[j] =   temp->getPoly();
1692                    }
1693                }
1694                    gbPrev          =   idAdd(gbPrev,gbAdd);
1695            }
1696            else {
1697                ideal gbAdd =   idInit(gPrev->getLength()-gbLength,1);
1698                LNode*  temp =   gPrevTag;
1699                for(j=0;j<=gPrev->getLength()-gbLength-1;j++) {
1700                    temp        =   temp->getNext();
1701                    gbAdd->m[j] =   temp->getPoly();
1702                }
1703                gbPrev          =   idAdd(gbPrev,gbAdd);
1704            }
1705            // interreduction stuff
1706            // comment this out if you want F5 instead of F5R
1707            //if(i<IDELEMS(id)) {
1708                ideal tempId    =   kInterRed(gbPrev);
1709                gbPrev          =   tempId;
1710            //}
1711        }
1712        gbLength    =   gPrev->getLength();
1713        }
1714       
1715
1716        //
1717        // "F5C"
1718        //
1719        if(2 == opt) { 
1720        if(gPrev->getLength() > gbLength) {
1721            if(i < IDELEMS(id)) {
1722                ideal gbAdd =   idInit(gPrev->getLength()-gbLength,1);
1723                LNode*  temp =   gPrevTag;
1724                for(j=0;j<=gPrev->getLength()-gbLength-1;j++) {
1725                    temp        =   temp->getNext();
1726                        gbAdd->m[j] =   temp->getPoly();
1727                }
1728                    gbPrev          =   idAdd(gbPrev,gbAdd);
1729            }
1730            else {
1731                ideal gbAdd =   idInit(gPrev->getLength()-gbLength,1);
1732                LNode*  temp =   gPrevTag;
1733                for(j=0;j<=gPrev->getLength()-gbLength-1;j++) {
1734                    temp        =   temp->getNext();
1735                    gbAdd->m[j] =   temp->getPoly();
1736                }
1737                gbPrev          =   idAdd(gbPrev,gbAdd);
1738            }
1739            if(i<IDELEMS(id)) {
1740                ideal tempId    =   kInterRed(gbPrev);
1741                gbPrev          =   tempId;
1742                delete gPrev;
1743                delete rules;
1744                gPrev    =   new LList(pOne,1,gbPrev->m[0]);
1745                gPrev->insert(pOne,1,gbPrev->m[1]);
1746                rules    =   new RList();
1747                //rTag     =   new RTagList(rules->getFirst());
1748                for(k=2; k<IDELEMS(gbPrev); k++) {
1749                    gPrev->insert(pOne,k+1,gbPrev->m[k]);
1750                    /*
1751                    for(l=0; l<k; l++) {
1752                    }
1753                    rTag->insert(rules->getFirst());
1754                    */
1755                }
1756            }
1757            gbLength    =   gPrev->getLength(); 
1758        } 
1759        }
1760
1761
1762    }
1763    timer   =   getTimer();
1764    //Print("\n\nADDING TIME IN REDUCTION: %d\n\n",reductionTime);
1765    Print("\n\nNumber of zero-reductions:           %d\n",reductionsToZero);
1766    Print("Number of rules:                     %d\n",numberOfRules); 
1767    Print("Elements not added to G:             %d\n",notInG); 
1768    Print("Highest Degree during computations:  %d\n",highestDegree);
1769    Print("Time for computations:               %d/1000 seconds\n",timer);
1770    Print("Number of elements in gb:            %d\n",IDELEMS(gbPrev));
1771    //LNode* temp    =   gPrev->getFirst();
1772    //while(NULL != temp) {
1773    //    pWrite(temp->getPoly());
1774    //    temp    =   temp->getNext();
1775    // }
1776    //gPrev->print();
1777    //delete lTag;
1778    delete rTag;
1779    delete gPrev;
1780    notInG              =   0;
1781    numberOfRules       =   0;
1782    reductionsToZero    =   0;
1783    highestDegree       =   0;
1784    reductionTime       =   0;
1785    spolsTime           =   0;
1786    numberUselessPairs  =   0;
1787    numberUsefulPairs   =   0;
1788    return(gbPrev);
1789
1790
1791}
1792
1793#endif
Note: See TracBrowser for help on using the repository browser.