/**************************************** * Computer Algebra System SINGULAR * ****************************************/ <<<<<<< f5gb.cc /* $Id: f5gb.cc,v 1.48 2009-03-16 19:28:07 ederc Exp $ */ ======= /* $Id: f5gb.cc,v 1.48 2009-03-16 19:28:07 ederc Exp $ */ >>>>>>> 1.47 /* * ABSTRACT: f5gb interface */ #include "mod2.h" #ifdef HAVE_F5 #include #include "structs.h" #include "kutil.h" #include "omalloc.h" #include "polys.h" #include "p_polys.h" #include "ideals.h" #include "febase.h" #include "kstd1.h" #include "khstd.h" #include "kbuckets.h" #include "weight.h" #include "intvec.h" #include "pInline1.h" #include "f5gb.h" #include "f5data.h" #include "f5lists.h" int reductionsToZero = 0; /* ==================================================================== sorting ideals by decreasing total degree "left" and "right" are the pointer of the first and last polynomial in the considered ideal ==================================================================== */ void qsortDegree(poly* left, poly* right) { poly* ptr1 = left; poly* ptr2 = right; poly p1,p2; p2 = *(left + (right - left >> 1)); do { while(pTotaldegree(*ptr1, currRing) < pTotaldegree(p2, currRing)) { ptr1++; } while(pTotaldegree(*ptr2, currRing) > pTotaldegree(p2,currRing)) { ptr2--; } if(ptr1 > ptr2) { break; } p1 = *ptr1; *ptr1 = *ptr2; *ptr2 = p1; } while(++ptr1 <= --ptr2); if(left < ptr2) { qsortDegree(left,ptr2); } if(ptr1 < right) { qsortDegree(ptr1,right); } } /* ================================================== computes incrementally gbs of subsets of the input gb{f_m} -> gb{f_m,f_(m-1)} -> gb{f_m,...,f_1} ================================================== */ LList* F5inc(int i, poly f_i, LList* gPrev, ideal gbPrev, poly ONE, LTagList* lTag, RList* rules, RTagList* rTag) { //Print("in f5inc\n"); //pWrite(rules->getFirst()->getRuleTerm()); int j; //Print("%p\n",gPrev->getFirst()); //pWrite(gPrev->getFirst()->getPoly()); poly tempNF = kNF(gbPrev,currQuotient,f_i); f_i = tempNF; //gPrev->insert(ONE,i,f_i); gPrev->insert(ONE,gPrev->getLength()+1,f_i); // tag the first element in gPrev of the current index for findReductor() lTag->setFirstCurrentIdx(gPrev->getLast()); //Print("1st gPrev: "); //pWrite(gPrev->getFirst()->getPoly()); //Print("2nd gPrev: "); //pWrite(gPrev->getFirst()->getNext()->getPoly()); //pWrite(gPrev->getFirst()->getNext()->getPoly()); CList* critPairs = new CList(); CNode* critPairsMinDeg = new CNode(); // computation of critical pairs with checking of criterion 1 and criterion 2 and saving them // in the list critPairs criticalPair(gPrev, critPairs, lTag, rTag, rules); static LList* sPolyList = new LList(); //sPolyList->print(); // labeled polynomials which have passed reduction() and have to be added to list gPrev static LList* completed = new LList(); // the reduced labeled polynomials which are returned from subalgorithm reduction() static LList* reducedLPolys = new LList(); // while there are critical pairs to be further checked and deleted/computed while(NULL != critPairs->getFirst()) { // critPairs->getMinDeg() deletes the first elements of minimal degree from // critPairs, thus the while loop is not infinite. critPairsMinDeg = critPairs->getMinDeg(); // adds all to be reduced S-polynomials in the list sPolyList and adds // the corresponding rules to the list rules // NOTE: inside there is a second check of criterion 2 if new rules are // added computeSPols(critPairsMinDeg,rTag,rules,sPolyList); // DEBUG STUFF FOR SPOLYLIST LNode* temp = sPolyList->getFirst(); //while(NULL != temp && NULL != temp->getLPoly()) { //Print("Spolylist element: "); //pWrite(temp->getPoly()); //temp = temp->getNext(); //} // reduction process of new S-polynomials and also adds new critical pairs to critPairs reduction(sPolyList, critPairs, gPrev, rules, lTag, rTag, gbPrev); // DEBUG STUFF FOR GPREV //temp = gPrev->getFirst(); //int number = 1; //Print("\n\n"); //while(NULL != temp) { // Print("%d. ",number); // pWrite(temp->getPoly()); // temp = temp->getNext(); // number++; // Print("\n"); //} //sleep(5); } //Print("REDUCTION DONE\n"); //Print("%p\n",rules->getFirst()); //Print("%p\n",rTag->getFirst()); //if(rules->getFirst() != rTag->getFirst()) { //Print("+++++++++++++++++++++++++++++++++++++NEW RULES+++++++++++++++++++++++++++++++++++++\n"); //rTag->insert(rules->getFirst()); //} //else { //Print("+++++++++++++++++++++++++++++++++++NO NEW RULES++++++++++++++++++++++++++++++++++++\n"); //} lTag->insert(lTag->getFirstCurrentIdx()); //Print("INDEX: %d\n",tempTag->getIndex()); //pWrite(tempTag->getPoly()); //Print("COMPLETED FIRST IN F5INC: \n"); //Print("1st gPrev: "); //pWrite(gPrev->getFirst()->getPoly()); //Print("2nd gPrev: "); //pWrite(gPrev->getFirst()->getNext()->getPoly()); //Print("3rd gPrev: "); //pWrite(gPrev->getFirst()->getNext()->getNext()->getPoly()); //delete sPolyList; //critPairs->print(); delete critPairs; //Print("IN F5INC\n"); Print("\n\n\nRULES: \n"); RNode* tempR = rules->getFirst(); Print("%p\n",tempR); int t = 1; while(NULL != tempR) { Print("ADDRESS OF %d RNODE: %p\n",t,tempR); Print("ADDRESS OF RULE: %p\n",tempR->getRule()); pWrite(tempR->getRuleTerm()); Print("ADDRESS OF TERM: %p\n",tempR->getRuleTerm()); Print("%d\n\n",tempR->getRuleIndex()); tempR = tempR->getNext(); t++; } //gPrev->print(); return gPrev; } /* ================================================================ computes a list of critical pairs for the next reduction process first element in gPrev is always the newest element which must build critical pairs with all other elements in gPrev ================================================================ */ inline void criticalPair(LList* gPrev, CList* critPairs, LTagList* lTag, RTagList* rTag, RList* rules) { //Print("IN CRITPAIRS\n"); // initialization for usage in pLcm() number nOne = nInit(1); LNode* newElement = gPrev->getLast(); LNode* temp = gPrev->getFirst(); poly u1 = pOne(); poly u2 = pOne(); poly lcm = pOne(); poly t = pHead(newElement->getPoly()); Rule* testedRule = NULL; if(NULL != rules->getFirst()) { testedRule = rules->getFirst()->getRule(); } // computation of critical pairs //critPairs->print(); while( gPrev->getLast() != temp) { //pWrite( *(gPrev->getFirst()->getPoly()) ); // pWrite( *(l->getPoly()) ); //pWrite(newElement->getPoly()); //pWrite(temp->getPoly()); pLcm(newElement->getPoly(), temp->getPoly(), lcm); pSetCoeff(lcm,nOne); // computing factors u2 for new labels //pExpVectorDiff(u1,lcm,t); //Print("U1: "); //pWrite(u1); u1 = pDivide(lcm,t); //pWrite(u1); pSetCoeff(u1,nOne); //Print("%p\n",u1); //critPairs->print(); //pExpVectorDiff(u2,lcm,temp->getPoly()); //Print("U2: "); //pWrite(u2); u2 = pDivide(lcm, pHead(temp->getPoly())); //pWrite(u2); //Print("%p\n",u2); pSetCoeff(u2,nOne); //if(gPrev->getLast()->getIndex()==5) { //Print("IN CRITPAIRS\n"); // pWrite(u1); // Print("1st ELEMENT: "); // pWrite(newElement->getPoly()); // Print("2nd ELEMENT: "); // pWrite(temp->getPoly()); //} // testing both new labels by the F5 Criterion //critPairs->print(); if(!criterion2(u1, newElement, rules, rTag) && !criterion2(u2, temp, rules, rTag) && !criterion1(gPrev,u1,newElement,lTag) && !criterion1(gPrev,u2,temp,lTag)) { // if they pass the test, add them to CList critPairs, having the LPoly with greater // label as first element in the CPair if(newElement->getIndex() == temp->getIndex() && -1 == pLmCmp(ppMult_qq(u1, newElement->getTerm()),ppMult_qq(u2, temp->getTerm()))) { //Print("zweites groesser\n"); CPair* cp = new CPair(pDeg(ppMult_qq(u2,pHead(temp->getPoly()))), u2, temp->getLPoly(), u1, newElement->getLPoly(), testedRule); critPairs->insert(cp); //Print("LALA %p\n",critPairs->getFirst()); //sleep(5); } else { CPair* cp = new CPair(pDeg(ppMult_qq(u2,pHead(temp->getPoly()))), u1, newElement->getLPoly(), u2, temp->getLPoly(), testedRule); //Print("erstes groesser\n"); critPairs->insert(cp); //Print("LALA %p\n",critPairs->getFirst()); //sleep(5); } } else { } //Print("\n\n"); temp = temp->getNext(); } // for debugging //if(NULL != critPairs) { //critPairs->print(); //sleep(5); //} //Print("END CRITPAIRS\n"); } /* ======================================== Criterion 1, i.e. Faugere's F5 Criterion ======================================== */ inline bool criterion1(LList* gPrev, poly t, LNode* l, LTagList* lTag) { // starts at the first element in gPrev with index = (index of l)-1, these tags are saved in lTag int idx = l->getIndex(); int i; if(idx == 1) { //Print("HIER\n"); return false; } else { LNode* testNode = gPrev->getFirst(); // save the monom t1*label_term(l) as it is tested various times in the following poly u1 = ppMult_qq(t,l->getTerm()); //Print("------------------------------IN CRITERION 1-----------------------------------------\n"); //Print("TESTED ELEMENT: "); //pWrite(l->getPoly()); //pWrite(l->getTerm()); //pWrite(ppMult_qq(t,l->getTerm())); //Print("%d\n\n",l->getIndex()); /* while(testNode->getIndex() < idx) { // && NULL != testNode->getLPoly()) { //pWrite(testNode->getPoly()); //Print("%d\n",testNode->getIndex()); if(pLmDivisibleByNoComp(testNode->getPoly(),u1)) { //Print("Criterion 1 NOT passed!\n"); return true; } //pWrite(testNode->getNext()->getPoly()); testNode = testNode->getNext(); } */ ideal testId = idInit(idx-1,1); for(i=0;im[i] = pHead(testNode->getPoly()); testNode = testNode->getNext(); } poly temp = kNF(testId,currQuotient,u1); //pWrite(temp); for(i=0;im[i] = NULL; } idDelete(&testId); if(NULL == temp) { return true; } return false; } } /* ===================================== Criterion 2, i.e. Rewritten Criterion ===================================== */ inline bool criterion2(poly t, LNode* l, RList* rules, RTagList* rTag) { //Print("------------------------------IN CRITERION 2/1-----------------------------------------\n"); /* Print("RULES: \n"); RNode* tempR = rules->getFirst(); Print("%p\n",tempR); int i = 1; while(NULL != tempR) { Print("ADDRESS OF %d RNODE: %p\n",i,tempR); Print("ADDRESS OF RULE: %p\n",tempR->getRule()); pWrite(tempR->getRuleTerm()); Print("ADDRESS OF TERM: %p\n",tempR->getRuleTerm()); Print("%d\n\n",tempR->getRuleIndex()); tempR = tempR->getNext(); i++; } //Print("TESTED ELEMENT: "); //pWrite(l->getPoly()); //pWrite(l->getTerm()); //pWrite(ppMult_qq(t,l->getTerm())); //Print("%d\n\n",l->getIndex()); */ // start at the previously added element to gPrev, as all other elements will have the same index for sure RNode* testNode; // = new RNode(); if(NULL == rTag->getFirst()) { if(NULL != rules->getFirst()) { testNode = rules->getFirst(); } else { return false; } } else { if(l->getIndex() > rTag->getFirst()->getRuleIndex()) { testNode = rules->getFirst(); } else { //Print("HIER\n"); //Print("DEBUG\n"); //Print("L INDEX: %d\n",l->getIndex()); /*------------------------------------- * TODO: WHEN INTERREDUCING THE GB THE * INDEX OF THE PREVIOUS ELEMENTS * GETS HIGHER! *-----------------------------------*/ //testNode = rules->getFirst(); testNode = rTag->get(l->getIndex()); if(NULL == testNode) { testNode = rules->getFirst(); } //Print("TESTNODE ADDRESS: %p\n",testNode); } } //testNode = rules->getFirst(); // save the monom t1*label_term(l) as it is tested various times in the following poly u1 = ppMult_qq(t,l->getTerm()); // first element added to rTag was NULL, check for this //Print("%p\n",testNode->getRule()); // NOTE: testNode is possibly NULL as rTag->get() returns NULL for elements of index <=1! //Print("TESTNODE: %p\n",testNode); //pWrite(testNode->getRuleTerm()); if(NULL != testNode ) { //pWrite(testNode->getRuleTerm()); } if(NULL != testNode) { if(testNode->getRule() == l->getRule()) { //Print("%p\n%p\n",testNode->getRule(),l->getRule()); //Print("EQUAL\n"); } else { //Print("NOT EQUAL\n"); } } while(NULL != testNode && testNode->getRule() != l->getRule() && l->getIndex() == testNode->getRuleIndex()) { //Print("%p\n",testNode); //pWrite(testNode->getRuleTerm()); //pWrite(t); //pWrite(l->getTerm()); //pWrite(u1); //Print("%d\n",testNode->getRuleIndex()); if(pLmDivisibleByNoComp(testNode->getRuleTerm(),u1)) { //Print("Criterion 2 NOT passed!\n"); pDelete(&u1); //Print("------------------------------IN CRITERION 2/1-----------------------------------------\n\n"); return true; } testNode = testNode->getNext(); } //delete testNode; pDelete(&u1); //Print("------------------------------IN CRITERION 2/1-----------------------------------------\n\n"); return false; } /* ================================================================================================================= Criterion 2, i.e. Rewritten Criterion, for its second call in computeSPols(), with added lastRuleTested parameter ================================================================================================================= */ inline bool criterion2(poly t, LPoly* l, RList* rules, Rule* testedRule) { //Print("------------------------------IN CRITERION 2/2-----------------------------------------\n"); //Print("LAST RULE TESTED: %p",testedRule); /* Print("RULES: \n"); RNode* tempR = rules->getFirst(); while(NULL != tempR) { pWrite(tempR->getRuleTerm()); Print("%d\n\n",tempR->getRuleIndex()); tempR = tempR->getNext(); } //Print("TESTED ELEMENT: "); //pWrite(l->getPoly()); //pWrite(l->getTerm()); //pWrite(ppMult_qq(t,l->getTerm())); //Print("%d\n\n",l->getIndex()); */ // start at the previously added element to gPrev, as all other elements will have the same index for sure RNode* testNode = rules->getFirst(); // save the monom t1*label_term(l) as it is tested various times in the following poly u1 = ppMult_qq(t,l->getTerm()); // first element added to rTag was NULL, check for this while(NULL != testNode && testNode->getRule() != testedRule) { //pWrite(testNode->getRuleTerm()); if(pLmDivisibleByNoComp(testNode->getRuleTerm(),u1)) { //Print("Criterion 2 NOT passed!\n"); pDelete(&u1); //Print("------------------------------IN CRITERION 2/2-----------------------------------------\n\n"); return true; } testNode = testNode->getNext(); } pDelete(&u1); //Print("------------------------------IN CRITERION 2/2-----------------------------------------\n\n"); return false; } /* ================================== Computation of S-Polynomials in F5 ================================== */ void computeSPols(CNode* first, RTagList* rTag, RList* rules, LList* sPolyList) { CNode* temp = first; poly sp = pInit(); //Print("###############################IN SPOLS##############################\n"); //first->print(); while(NULL != temp) { //Print("JA\n"); // only if a new rule was added since the last test in subalgorithm criticalPair() //if(rules->getFirst() != rTag->getFirst()) { if(!criterion2(temp->getT1(),temp->getAdLp1(),rules,temp->getTestedRule())) { // the second component is tested only when it has the actual index, otherwise there is // no new rule to test since the last test in subalgorithm criticalPair() if(temp->getLp2Index() == temp->getLp1Index()) { if(!criterion2(temp->getT2(),temp->getAdLp2(),rules,temp->getTestedRule())) { // computation of S-polynomial sp = pSub(ppMult_qq(temp->getT1(),temp->getLp1Poly()), ppMult_qq(temp->getT2(),temp->getLp2Poly())); //Print("BEGIN SPOLY1\n====================\n"); pNorm(sp); //pWrite(sp); //Print("END SPOLY1\n====================\n"); if(NULL == sp) { // as rules consist only of pointers we need to save the labeled // S-polynomial also of a zero S-polynomial //zeroList->insert(temp->getAdT1(),temp->getLp1Index(),&sp); // origin of rule can be set NULL as the labeled polynomial // will never be used again as it is zero => no problems with // further criterion2() tests and termination conditions //Print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ZERO REDUCTION~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); reductionsToZero++; //Print("IN SPOLS 1\n"); rules->insert(temp->getLp1Index(),ppMult_qq(temp->getT1(),temp->getLp1Term())); //Print("RULE ADDED: \n"); //pWrite(rules->getFirst()->getRuleTerm()); // as sp = NULL, delete it pDelete(&sp); //Print("HIER\n"); } else { //Print("IN SPOLS 2\n"); rules->insert(temp->getLp1Index(),ppMult_qq(temp->getT1(),temp->getLp1Term())); //Print("RULE ADDED: \n"); //pWrite(rules->getFirst()->getRuleTerm()); sPolyList->insertByLabel(ppMult_qq(temp->getT1(),temp->getLp1Term()),temp->getLp1Index(),sp,rules->getFirst()->getRule()); } // data is saved in sPolyList or zero => delete sp } } else { // temp->getLp2Index() < temp->getLp1Index() // computation of S-polynomial sp = pSub(ppMult_qq(temp->getT1(),temp->getLp1Poly()), ppMult_qq(temp->getT2(),temp->getLp2Poly())); //Print("BEGIN SPOLY2\n====================\n"); pNorm(sp); //pWrite(sp); //Print("END SPOLY2\n====================\n"); if(NULL == sp) { // zeroList->insert(temp->getAdT1(),temp->getLp1Index(),&sp); // origin of rule can be set NULL as the labeled polynomial // will never be used again as it is zero => no problems with // further criterion2() tests and termination conditions //Print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ZERO REDUCTION~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); reductionsToZero++; //Print("IN SPOLS 3\n"); rules->insert(temp->getLp1Index(),ppMult_qq(temp->getT1(),temp->getLp1Term())); //Print("RULE ADDED: \n"); //pWrite(rules->getFirst()->getRuleTerm()); // as sp = NULL, delete it pDelete(&sp); } else { //Print("IN SPOLS 4\n"); rules->insert(temp->getLp1Index(),ppMult_qq(temp->getT1(),temp->getLp1Term())); //Print("RULE ADDED: \n"); //pWrite(rules->getFirst()->getRuleTerm()); //Print("%d\n",rules->getFirst()->getRuleIndex()); //Print("%p\n",sPolyList->getFirst()); sPolyList->insertByLabel(ppMult_qq(temp->getT1(),temp->getLp1Term()),temp->getLp1Index(),sp,rules->getFirst()->getRule()); } } } //} //Print("%p\n",temp); temp = temp->getNext(); //Print("%p\n",temp); //Print("%p\n",temp->getData()); //pWrite(temp->getLp1Poly()); } // these critical pairs can be deleted now as they are either useless for further computations or // already saved as an S-polynomial to be reduced in the following delete first; } /* ======================================================================== reduction including subalgorithm topReduction() using Faugere's criteria ======================================================================== */ void reduction(LList* sPolyList, CList* critPairs, LList* gPrev, RList* rules, LTagList* lTag, RTagList* rTag, ideal gbPrev) { //Print("##########################################In REDUCTION!########################################\n"); // check if sPolyList has any elements // NOTE: due to initialization sPolyList always has a default NULL element while(sPolyList->getLength() > 0) { //Print("SPOLYLIST LENGTH: %d\n",sPolyList->getLength()); if(sPolyList->getLength() > 1) { //Print("%p\n",sPolyList->getFirst()); //Print("%p\n",sPolyList->getFirst()->getLPoly()); //Print("%p\n",sPolyList->getFirst()->getNext()); //Print("%p\n",sPolyList->getFirst()->getNext()->getLPoly()); //Print("%p\n",sPolyList->getFirst()); } //if(gPrev->getLast()->getIndex() == 5) { //sPolyList->print(); //sleep(5); //} // temp is the first element in the sPolyList which should be reduced // due to earlier sorting this is the element of minimal degree AND // minimal label LNode* temp = sPolyList->getFirst(); //pWrite(temp->getPoly()); // delete the above first element from sPolyList, temp will be either reduced to // zero or added to gPrev, but never come back to sPolyList if(NULL != temp) { sPolyList->setFirst(temp->getNext()); //Print("HIER\n"); } else { break; } //Print("HALLO %p\n",temp->getPoly()); //Print("%p\n",temp->getPoly()); //pWrite(temp->getPoly()); //idShow(gbPrev); poly tempNF = kNF(gbPrev,currQuotient,temp->getPoly()); //Print("LENGTH: %d\n",sPolyList->getLength()); //pWrite(tempNF); //pWrite(temp->getPoly()); if(NULL != tempNF) { pNorm(tempNF); // write the reduced polynomial in temp temp->setPoly(tempNF); // try further reductions of temp with polynomials in gPrev // with label index = current label index: this is done such that there // is no label corruption during the reduction process topReduction(temp,sPolyList,gPrev,rules,lTag,rTag,gbPrev); } if(NULL != temp->getPoly()) { //CList* newCritPairs = new CList; //Print("##################IN CRITPAIRS IN REDUCTION#####################\n"); criticalPair(gPrev,critPairs,lTag,rTag,rules); //Print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++H I E R++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); } else { //delete temp; LNode* tempLoop = gPrev->getFirst(); //Print("AUSGABE IN REDUCTION:\n"); //while(NULL != tempLoop) { //pWrite(tempLoop->getPoly()); //tempLoop = tempLoop->getNext(); //} //sleep(10); } } } /* ===================================================================================== top reduction in F5, i.e. reduction of a given S-polynomial by labeled polynomials of the same index whereas the labels are taken into account ===================================================================================== */ void topReduction(LNode* l, LList* sPolyList, LList* gPrev, RList* rules, LTagList* lTag, RTagList* rTag, ideal gbPrev) { //Print("##########################################In topREDUCTION!########################################\n"); // try l as long as there are reductors found by findReductor() do { LNode* gPrevRedCheck = new LNode(lTag->getFirstCurrentIdx()); //Print("gPrevCheckPOLY: "); //pWrite(gPrevRedCheck->getPoly()); LNode* tempRed = new LNode(); //Print("TESTED POLYNOMIAL IN THE FOLLOWING: "); //pWrite(l->getPoly()); //Print("HIER\n"); tempRed = findReductor(l,gPrevRedCheck,gPrev,rules,lTag,rTag); //Print("TEMPRED NEXT: %p\n",tempRed->getNext()); //Print("--------------------------------HIER DEBUG 2----------------------------------\n"); // if a reductor for l is found and saved in tempRed if(NULL != tempRed) { // if label of reductor is greater than the label of l we have to built a new element // and add it to sPolyList //Print("REDUCTOR POLYNOMIAL: "); //pWrite(tempRed->getPoly()); //Print("TEMPRED: %p\n",tempRed); //Print("TERM: "); //pWrite(tempRed->getTerm()); if(pLmCmp(tempRed->getTerm(),l->getTerm()) == 1) { // needed sinc pSub destroys the arguments! //Print("H----------I------------E--------------R\n"); poly temp_poly_l = pInit(); temp_poly_l = pCopy(l->getPoly()); //Print("POLYNOMIAL L: "); //pWrite(l->getPoly()); //pWrite(temp_poly_l); poly temp = pSub(tempRed->getPoly(),temp_poly_l); //Print("POLYNOMIAL L: "); //pWrite(l->getPoly()); //pWrite(temp_poly_l); //Print("AFTER REDUCTION STEP: "); //pWrite(temp); //sleep(20); //pWrite(temp); if(NULL != temp) { pNorm(temp); tempRed->setPoly(temp); //pWrite(tempRed->getPoly()); // for debugging //pWrite(tempRed->getPoly()); //Print("RULE ADDED\n"); rules->insert(tempRed->getIndex(),tempRed->getTerm()); tempRed->getLPoly()->setRule(rules->getFirst()->getRule()); //Print("%p\n",sPolyList->getFirst()); //Print("%p\n",sPolyList->getFirst()->getLPoly()); //Print("SPOLYLIST LENGTH: %d\n",sPolyList->getLength()); //sPolyList->print(); sPolyList->insertByLabel(tempRed); //sPolyList->print(); //Print("SPOLYLIST LENGTH: %d\n",sPolyList->getLength()); //Print("OH JE\n"); } else { pDelete(&temp); reductionsToZero++; //Print("RULE ADDED\n"); //rules->insert(tempRed->getIndex(),tempRed->getTerm()); //pWrite(rules->getFirst()->getRuleTerm()); //Print("DELETE TEMPRED\n"); delete tempRed; } } // label of reductor is smaller than the label of l, subtract reductor from l and delete the // gPrevRedCheck pointer added to l during findReductor() as the head term of l changes // after subtraction else { poly temp_poly_l = pInit(); temp_poly_l = pCopy(l->getPoly()); poly temp = pSub(temp_poly_l,tempRed->getPoly()); //Print("AFTER REDUCTION STEP: "); //pWrite(temp); if(NULL != temp) { pNorm(temp); poly tempNF = kNF(gbPrev,currQuotient,temp); pNorm(tempNF); //pWrite(tempNF); if(NULL == tempNF) { reductionsToZero++; pDelete(&tempNF); l->setPoly(NULL); break; } l->setPoly(tempNF); //pWrite(l->getPoly()); gPrevRedCheck = lTag->getFirstCurrentIdx(); } else { //Print("ZERO REDUCTION!\n"); reductionsToZero++; pDelete(&temp); l->setPoly(NULL); //pWrite(gPrev->getLast()->getPoly()); break; } } } else { if(NULL != l->getPoly()) { pNorm(l->getPoly()); //Print("----------------------------------ADDED TO GPREV IN TOPREDUCTION:-------------------------------------- "); //pWrite(l->getPoly()); //pWrite(l->getTerm()); //Print("INDEX: %d\n\n\n", l->getIndex()); //sleep(20); gPrev->insert(l->getLPoly()); //Print("GPREV: \n"); LNode* tempLoop = gPrev->getFirst(); //while(NULL != tempLoop) { //Print("HERE\n"); //pWrite(tempLoop->getPoly()); //tempLoop = tempLoop->getNext(); //} } break; } } while(1); } /* ===================================================================== subalgorithm to find a possible reductor for the labeled polynomial l ===================================================================== */ LNode* findReductor(LNode* l, LNode* gPrevRedCheck, LList* gPrev, RList* rules, LTagList* lTag,RTagList* rTag) { // allociation of memory for the possible reductor //Print("IN FIND REDUCTOR\n"); poly u = pOne(); poly red = pOne(); number nOne = nInit(1); LNode* temp = new LNode(); // head term of actual element such that we do not have to call pHead at each new reductor test poly t = pHead(l->getPoly()); // if l was already checked use the information in gPrevRedCheck such // that we can start searching for new reducers from this point and // not from the first element of gPrev with the current index temp = gPrevRedCheck; //temp = lTag->getFirstCurrentIdx(); //Print("GPREVREDCHECK: %p\n",gPrevRedCheck); //pWrite(gPrevRedCheck->getPoly()); // search for reductors until we are at the end of gPrev resp. at the // end of the elements of the current index while(NULL != temp && temp->getIndex() == l->getIndex()) { //pWrite(temp->getPoly()); //Print("INDEX: %d\n",temp->getIndex()); // does the head of the element of gPrev divides the head of // the to be reduced element? //Print("-------------FOUND REDUCTORS----------------------\n"); //Print("\n"); //pWrite(temp->getPoly()); //pWrite(temp->getTerm()); //pWrite(t); //Print("HALLO\n"); if(pLmDivisibleByNoComp(pHead(temp->getPoly()),t)) { //Print("HALLO\n"); // get all the information needed for the following tests // of the criteria u = pDivide(t,pHead(temp->getPoly())); pSetCoeff(u,nOne); //Print("HIER FINDRED\n"); //pWrite(u); //Print("\n"); red = ppMult_qq(u,temp->getPoly()); pNorm(red); //u = ppMult_qq(u,temp->getTerm()); //pSetCoeff(u,nOne); // check if both have the same label //Print("HALLO\n"); if(pLmCmp(u,l->getTerm()) != 0) { //Print("HALLO\n"); // passing criterion2 ? if(!criterion2(u,temp,rules,rTag)) { // passing criterion1 ? if(!criterion1(gPrev,u,temp,lTag)) { //Print("HIER DEBUG\n"); gPrevRedCheck = temp->getNext(); LNode* redNode = new LNode(ppMult_qq(u,temp->getTerm()),temp->getIndex(),red,NULL,NULL); return redNode; } } } } //Print("%p\n",temp->getNext()); //pWrite(temp->getPoly()); //Print("HALLO\n"); temp = temp->getNext(); } // delete temp; //Print("1st gPrev: "); //pWrite(gPrev->getFirst()->getPoly()); //Print("2nd gPrev: "); //pWrite(gPrev->getFirst()->getNext()->getPoly()); return NULL; } /* ========================================================================== MAIN:computes a gb of the ideal i in the ring r with our F5 implementation ========================================================================== */ ideal F5main(ideal id, ring r) { int i,j,k,l; int gbLength; // 1 polynomial for defining initial labels & further tests poly ONE = pOne(); poly pOne = pOne(); number nOne = nInit(1); // tag the first element of index i-1 for criterion 1 LTagList* lTag = new LTagList(); //Print("LTAG BEGINNING: %p\n",lTag); // first element in rTag is first element of rules which is NULL RNode, // this must be done due to possible later improvements RList* rules = new RList(); Print("RULES FIRST: %p\n",rules->getFirst()); //Print("RULES FIRST DATA: %p\n",rules->getFirst()->getRule()); RTagList* rTag = new RTagList(rules->getFirst()); i = 1; for(j=0; jm[j]) { if(pComparePolys(id->m[j],ONE)) { Print("One Polynomial in Input => Computations stopped\n"); ideal idNew = idInit(1,1); idNew->m[0] = ONE; return(idNew); } } } ideal idNew = kInterRed(id); id = idNew; //qsortDegree(&id->m[0],&id->m[IDELEMS(id)-1]); idShow(id); LList* gPrev = new LList(ONE, i, id->m[0]); //idShow(id); //Print("%p\n",id->m[0]); //pWrite(id->m[0]); //Print("%p\n",gPrev->getFirst()->getPoly()); //pWrite(gPrev->getFirst()->getPoly()); lTag->insert(gPrev->getFirst()); lTag->setFirstCurrentIdx(gPrev->getFirst()); // computing the groebner basis of the elements of index < actual index gbLength = gPrev->getLength(); //Print("Laenge der bisherigen Groebner Basis: %d\n",gPrev->getLength()); ideal gbPrev = idInit(gbLength,1); // initializing the groebner basis of elements of index < actual index gbPrev->m[0] = gPrev->getFirst()->getPoly(); //idShow(gbPrev); //idShow(currQuotient); for(i=2; i<=IDELEMS(id); i++) { LNode* gPrevTag = gPrev->getLast(); //Print("Last POlynomial in GPREV: "); //Print("%p\n",gPrevTag); //pWrite(gPrevTag->getPoly()); gPrev = F5inc(i, id->m[i-1], gPrev, gbPrev, ONE, lTag, rules, rTag); //Print("____________________________________ITERATION STEP DONE________________________________________\n"); // DEBUGGING STUFF LNode* temp = gPrev->getFirst(); // computing new groebner basis gbPrev if(gPrev->getLength() > gbLength) { ideal gbAdd = idInit(gPrev->getLength()-gbLength,1); LNode* temp = gPrevTag; //Print("%p\n",gPrevTag); //Print("%p\n",gPrev->getLast()); //pWrite(temp->getPoly()); //Print("LENGTH OF GPREV LIST: %d\n",gPrev->getLength()); //Print("%d\n",gbLength); //Print("%d\n",gPrev->getLength()-gbLength-1); for(j=0;j<=gPrev->getLength()-gbLength-1;j++) { //Print("YES\n"); temp = temp->getNext(); if(temp) { //Print("%p\n",temp); //pWrite(temp->getPoly()); //Print("%p\n",temp->getNext()); } gbAdd->m[j] = temp->getPoly(); //pWrite(temp->getPoly()); } //Print("HIER AUCH\n"); gbPrev = idAdd(gbPrev,gbAdd); // interreduction stuff if(im[0],&gbPrev->m[IDELEMS(gbPrev)-1]); delete gPrev; //sleep(5); //Print("RULES FIRST NOW1: %p\n",rules->getFirst()); //Print("HIER\n"); delete rules; //delete rTag; //Print("HIER AUCH\n"); //Print("%p\n",rules->getFirst()); gPrev = new LList(pOne,1,gbPrev->m[0]); gPrev->insert(pOne,1,gbPrev->m[1]); poly tempPoly = pInit(); pSetCoeff(tempPoly,nOne); pLcm(pHead(gbPrev->m[0]),pHead(gbPrev->m[1]),tempPoly); rules = new RList(); rTag = new RTagList(rules->getFirst()); //Print("%p\n",rules->getFirst()); pWrite(tempPoly); rules->insert(2,tempPoly); rTag->insert(rules->getFirst()); //Print("%p\n",rules->getFirst()); //Print("%p\n",rTag->getFirst()); //Print("%p\n",rules->getFirst()); //Print("%p\n",rules->getFirst()->getNext()->getNext()); //Print("HIERLALA\n"); //pWrite(rules->getFirst()->getRuleTerm()); // Print("RULES FIRST NOW2: %p\n",rules->getFirst()); for(k=2; kinsert(pOne,k+1,gbPrev->m[k]); for(l=0; lm[k]); //pWrite(gbPrev->m[l]); poly tempPoly2 = pOne(); pLcm(pHead(gbPrev->m[k]),pHead(gbPrev->m[l]),tempPoly2); pSetCoeff(tempPoly2,nOne); pWrite(tempPoly2); rules->insert(k+1,tempPoly2); } rTag->insert(rules->getFirst()); } } gbLength = gPrev->getLength(); //Print("HIER\n"); } //gPrev->print(); //int anzahl = 1; //while(NULL != temp) { // Print("%d. Element: ",anzahl); // pWrite(temp->getPoly()); // Print("\n"); // temp = temp->getNext(); // anzahl++; //} //sleep(5); //Print("GROEBNER BASIS:\n====================================================\n"); //idShow(gbPrev); //Print("===================================================\n"); //Print("JA\n"); } //idShow(gbPrev); Print("\n\nNumber of zero-reductions: %d\n",reductionsToZero); //LNode* temp = gPrev->getFirst(); //while(NULL != temp) { // pWrite(temp->getPoly()); // temp = temp->getNext(); // } //gPrev->print(); //delete lTag; //delete rTag; //delete gPrev; return(gbPrev); } #endif