1 //   Copyright (c)  2005-2007  Massimo Caboara
2 
3 //   This file is part of the source of CoCoALib, the CoCoA Library.
4 
5 //   CoCoALib is free software: you can redistribute it and/or modify
6 //   it under the terms of the GNU General Public License as published by
7 //   the Free Software Foundation, either version 3 of the License, or
8 //   (at your option) any later version.
9 
10 //   CoCoALib is distributed in the hope that it will be useful,
11 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //   GNU General Public License for more details.
14 
15 //   You should have received a copy of the GNU General Public License
16 //   along with CoCoALib.  If not, see <http://www.gnu.org/licenses/>.
17 
18 #include "CoCoA/TmpGPoly.H"
19 
20 #include "CoCoA/BigIntOps.H"
21 #include "CoCoA/DenseMatrix.H"
22 #include "CoCoA/FreeModule.H"
23 #include "CoCoA/ModuleOrdering.H"
24 #include "CoCoA/PPMonoidEv.H"
25 #include "CoCoA/RingZZ.H"
26 #include "CoCoA/SparsePolyOps-RingElem.H"
27 #include "CoCoA/TmpGPair.H"
28 #include "CoCoA/VectorOps.H" // just for debugging and statistics
29 #include "CoCoA/assert.H"
30 #include "CoCoA/matrix.H"
31 #include "CoCoA/symbol.H"
32 
33 #include <algorithm>
34 using std::min;
35 using std::max;
36 #include <iostream>
37 using std::ostream;
38 using std::endl;
39 //using std::swap;
40 #include <iterator>
41 #include <limits>
42 using std::numeric_limits;
43 //#include <vector>
44 using std::vector;
45 
46 namespace CoCoA
47 {
48 
49 
50   //---------class GPoly-------------------------------
51 
52   // WARNING: is not possible to build the zero GPoly here.
53   // change the ctors to allow this possibility
GPoly(ConstRefRingElem the_p,const GRingInfo & theGRI,long age)54   GPoly::GPoly(ConstRefRingElem the_p,
55                const GRingInfo& theGRI,
56                long age):  // default age=0
57     myLPPForDivwMask(theGRI.myPPM(), theGRI.myDivMaskRule()),
58     myLPPForOrd(LPP(the_p)),
59     myLCValue(LC(the_p)),
60     myPolyValue(the_p),
61     myGRingInfoValue(theGRI),
62     myWDeg(wdeg(LPP(the_p))),
63     mySugar(uninitialized)
64   {
65     vector<long> expv;
66     exponents(expv, myLPPForOrd);
67     myLPPForDivwMask = expv;
68     IamActive = true;
69     //    IamMinimalGen = false;
70     myMinimalGenLevel = -1;
71     myAge = age;
72     myNumTerms = NumTerms(the_p);
73     myComponent = theGRI.myComponent(myLPPForDiv());
74    }//ctor
75 
76 
77  // for DYN use, the LPP and LC are given to the GPoly
GPoly(ConstRefRingElem the_p,ConstRefPPMonoidElem theLPP,ConstRefRingElem theLC,const GRingInfo & theGRI,long age)78  GPoly::GPoly(ConstRefRingElem the_p,
79               ConstRefPPMonoidElem theLPP,
80               ConstRefRingElem theLC,
81               const GRingInfo& theGRI,
82               long age):  // default age=0
83     myLPPForDivwMask(theGRI.myPPM(), theGRI.myDivMaskRule()),
84     myLPPForOrd(theLPP),
85     myLCValue(theLC),
86     myPolyValue(the_p),
87     myGRingInfoValue(theGRI),
88     myWDeg(wdeg(theLPP)),
89     mySugar(uninitialized)
90   {
91     vector<long> expv;
92     exponents(expv, myLPPForOrd);
93     myLPPForDivwMask = expv;
94     IamActive = true;
95     //    IamMinimalGen = false;
96     myMinimalGenLevel = -1;
97     myAge = age;
98     myNumTerms = NumTerms(the_p);
99     myComponent = theGRI.myComponent(myLPPForDiv());
100    }//ctor
101 
102   // This ctor destroys the_p
GPoly(RingElem & the_p,ConstRefPPMonoidElem theLPP,ConstRefRingElem theLC,const GRingInfo & theGRI,const ClearMarker,long age)103   GPoly::GPoly(RingElem& the_p,
104                ConstRefPPMonoidElem theLPP,
105                ConstRefRingElem theLC,
106                const GRingInfo& theGRI,
107                const ClearMarker,//just for operator ariety
108                long age):  // default age=0
109     myLPPForDivwMask(theGRI.myPPM(), theGRI.myDivMaskRule()),
110     myLPPForOrd(theLPP),
111     myLCValue(theLC),
112     myPolyValue(theGRI.myNewSPR()),
113     myGRingInfoValue(theGRI),
114     myWDeg(wdeg(theLPP)),
115     mySugar(uninitialized)
116   {
117     vector<long> expv;
118     exponents(expv, myLPPForOrd);
119     myLPPForDivwMask = expv;
120     swap(the_p,myPolyValue);
121     IamActive = true;
122     //    IamMinimalGen = false;
123     myMinimalGenLevel = -1;
124     myAge = age;
125     myNumTerms = NumTerms(myPolyValue);
126     myComponent = theGRI.myComponent(myLPPForDiv());
127   }//ctor
128 
129 // This ctor destroys the_p
GPoly(RingElem & the_p,const GRingInfo & theGRI,const ClearMarker,long age)130   GPoly::GPoly(RingElem& the_p,
131                const GRingInfo& theGRI,
132                const ClearMarker,// just for operator ariety
133                long age):  // default age=0
134     myLPPForDivwMask(theGRI.myPPM(), theGRI.myDivMaskRule()),
135     myLPPForOrd(LPP(the_p)),
136     myLCValue(LC(the_p)),
137     myPolyValue(theGRI.myNewSPR()),
138     myGRingInfoValue(theGRI),
139     myWDeg(wdeg(LPP(the_p))),
140     mySugar(uninitialized)
141   {
142     vector<long> expv;
143     exponents(expv, myLPPForOrd);
144     myLPPForDivwMask = expv;
145     swap(the_p,myPolyValue);
146     IamActive = true;
147     //    IamMinimalGen = false;
148     myMinimalGenLevel = -1;
149     myAge = age;
150     myNumTerms = NumTerms(myPolyValue);
151     myComponent = theGRI.myComponent(myLPPForDiv());
152   }//ctor
153 
154 
GPoly(const GRingInfo & theGRI)155   GPoly::GPoly(const GRingInfo& theGRI):
156     myLPPForDivwMask(theGRI.myPPM(), theGRI.myDivMaskRule()),
157     myLPPForOrd(PPM(theGRI.myNewSPR())),
158     myLCValue(CoeffRing(theGRI.myNewSPR())),
159     myPolyValue(theGRI.myNewSPR()),
160     myGRingInfoValue(theGRI),
161     myWDeg(GradingDim(theGRI.myNewSPR())),
162     mySugar(uninitialized)
163   {
164     IamActive = true;
165     //    IamMinimalGen = false;
166     myMinimalGenLevel = -1;
167     myNumTerms = 0;
168     myComponent = 0;
169     myAge = 0;//-1?
170   }//ctor
171 
172 
GPoly(const GPoly & the_gp)173   GPoly::GPoly(const GPoly& the_gp):
174       myLPPForDivwMask(the_gp.myLPPForDivwMask),
175       myLPPForOrd(the_gp.myLPPForOrd),
176       myLCValue(LC(the_gp)),
177       myPolyValue(the_gp.myPolyValue),
178       myGRingInfoValue(the_gp.myGRingInfoValue),
179       myWDeg(the_gp.myWDeg),
180       mySugar(the_gp.mySugar)
181   {
182     IamActive = the_gp.IamActive;
183     myMinimalGenLevel = the_gp.myMinimalGenLevel;
184     myNumTerms = the_gp.myNumTerms;
185     myAge = the_gp.myAge;
186     myComponent = the_gp.myComponent;
187  }//ctor
188 
189 
190   GPoly& GPoly::operator=(const GPoly& the_gp) // ANNA: should it throw if not compatible???
191   {
192     CoCoA_ASSERT( AreCompatible(myGRingInfoValue,the_gp.myGRingInfoValue));
193     myLPPForDivwMask = the_gp.myLPPForDivwMask;
194     myLPPForOrd = the_gp.myLPPForOrd;
195     myLCValue = the_gp.myLCValue;
196     myPolyValue = the_gp.myPolyValue;
197     myWDeg = the_gp.myWDeg;
198     IamActive = the_gp.IamActive;
199     myNumTerms = the_gp.myNumTerms;
200     myWDeg = the_gp.myWDeg;
201     myAge = the_gp.myAge;
202     myComponent = the_gp.myComponent;
203     mySugar = the_gp.mySugar;
204     return *this;
205   }//operator=
206 
AssignClear(GPoly & the_gp)207   void GPoly::AssignClear(GPoly& the_gp) // ANNA: should it throw if not compatible???
208   {
209     CoCoA_ASSERT( AreCompatible(myGRingInfoValue,the_gp.myGRingInfoValue));
210     //    swap(myLPPForDivwMask, the_gp.myLPPForDivwMask);
211     myLPPForDivwMask = the_gp.myLPPForDivwMask;
212     swap(myLPPForOrd, the_gp.myLPPForOrd);
213     myLCValue = the_gp.myLCValue;
214     swap(myPolyValue,the_gp.myPolyValue);
215     myWDeg = the_gp.myWDeg;
216     IamActive = the_gp.IamActive;
217     myNumTerms = the_gp.myNumTerms;
218     myAge = the_gp.myAge;
219     myComponent = the_gp.myComponent;
220     mySugar = the_gp.mySugar;
221     the_gp=GPoly(myGRingInfoValue);
222   }//AssignClear
223 
224 
225   bool GPoly::operator==(const GPoly& f)const
226   {
227     CoCoA_ASSERT(AreCompatible(myGRingInfoValue, f.myGRingInfoValue) );
228     if (myPolyValue == f.myPolyValue) return true;
229     return true;
230   }//operator==
231 
232 
233   bool GPoly::operator!=(const GPoly& f)const
234   {
235     CoCoA_ASSERT( AreCompatible(myGRingInfoValue, f.myGRingInfoValue) );
236     if (myPolyValue == f.myPolyValue) return false;
237     return true;
238   }//operator!=
239 
240 
IsZero(const GPoly & f)241   bool IsZero(const GPoly& f) { return CoCoA::IsZero(f.myPolyValue); }
242 
243 
244   ostream& operator<<(ostream& out, const GPoly& f)
245   {
246     if (!out) return out;  // short-cut for bad ostreams
247 
248     out<<"["<<f.myPolyValue
249        <<", record["
250        <<"IsActive="<<f.IamActive
251        <<", NumTerms="<<f.myNumTerms
252        <<", Deg="<<f.myWDeg
253        <<", Sugar="<<f.mySugar
254        <<", Age="<<f.myAge<<" "
255        <<", LPP_Comp="<<f.myComponent
256        <<", LPPForDiv="<<f.myLPPForDiv()
257        <<", LPPForOrd="<<f.myLPPForOrd
258        <<", LC="<<f.myLCValue
259        <<"]]";
260     return out;
261   }
262 
263 // here a GPoly is updated. used in reduction and SPoly production.
myUpdateLenLPPLCDegComp()264 void GPoly::myUpdateLenLPPLCDegComp()
265 {
266   myNumTerms = NumTerms(myPolyValue);
267   if (IsZero(*this)) // the following things are effectively undefined
268   {
269     myLPPForDivwMask.myAssign(one(owner(myLPPForDiv())));
270     AssignOne(myLPPForOrd);
271     myLCValue = 0;
272 /// JAA BUG???    myWDeg = 0;      // ANNA delete???
273     myComponent = 0; // ANNA delete ???
274   }
275   else
276   {
277     myLPPForOrd = LPP(myPoly());//DYN here the new LPP will be computed
278     vector<long> expv;
279     exponents(expv, myLPPForOrd);
280     myLPPForDivwMask = expv;
281     myLCValue=LC(myPoly());//DYN here the new LC will be computed
282     myWDeg = wdeg(myLPPForOrd);
283     myComponent = myGRingInfoValue.myComponent(myLPPForDiv());
284   }
285 }//myUpdateLenLPPLCDegComp
286 
287 
myInitializeSugar(const SugarDegree & s)288   void GPoly::myInitializeSugar(const SugarDegree& s)
289   {
290     CoCoA_ASSERT(!IsInitialized(mySugar));
291     mySugar = s;
292   }
293 
294 
myAssignSPoly(const GPair & the_gp,const long the_age)295   void GPoly::myAssignSPoly(const GPair& the_gp, const long the_age)
296   {
297     IamActive = true;
298     //    IamMinimalGen = false;
299     myMinimalGenLevel = -1;
300     if (the_gp.IsInputPoly())
301       myPolyValue = poly(the_gp.myFirstGPoly());
302     else
303       myPolySetSPoly(the_gp.myFirstGPoly(), the_gp.mySecondGPoly());
304     myUpdateLenLPPLCDegComp();
305     myAge = the_age;
306     // MAX: do these things only if necessary.
307     mySugar = sugar(the_gp);
308    }//myAssignSPoly
309 
310  /*
311 //???  This does not work, I don't understand why.
312  void GPoly::myAppendClear(RingElem& p)
313  {
314    SparsePolyRing P=owner(*this);
315 clog << "operator+=: myPoly " <<myPoly<< endl;
316 clog << "operator+=: p " <<p<< endl;
317    P->myAppendClear(raw(myPoly), raw(p));
318 clog << "operator+=: result " <<myPoly<< endl;
319    myNumTerms = NumTerms(myPoly);
320  }//_myAppendClear
321  */
322 
323 // TEMPORARY - Dangerous, does not adjust all the fields of *this
myAppendClear(RingElem & p)324  void GPoly::myAppendClear(RingElem& p)
325  {
326    SparsePolyRingPtr(owner(*this))->myAppendClear(raw(myPolyValue), raw(p));
327    myNumTerms = NumTerms(myPolyValue);
328  }//myAppendClear
329 
330 // TEMPORARY - Dangerous, does not adjust all the fields of *this
myAppendClear(GPoly & p)331  void GPoly::myAppendClear(GPoly& p)
332  {
333    SparsePolyRingPtr(owner(*this))->myAppendClear(raw(myPolyValue), raw(p.myPolyValue));
334    myNumTerms = NumTerms(myPolyValue);
335  }//myAppendClear
336 
337 
MultiplyByPP(ConstRefPPMonoidElem MultPP)338   void  GPoly::MultiplyByPP(ConstRefPPMonoidElem MultPP)
339   {
340     // MultPP is in PPM(owner(GPoly))
341     myLPPForOrd *= MultPP; // should we make it more efficient?
342     vector<long> expv;
343     exponents(expv, myLPPForOrd);
344     myLPPForDivwMask = expv;
345     SparsePolyRingPtr(owner(*this))->myMulByPP(raw(myPolyValue), raw(MultPP)); // (..) because of g++ parser bug
346     myWDeg = wdeg(myLPPForOrd); // should we make it more efficient?
347     mySugar->myMul(MultPP);
348     // The other fields stay the same.
349   }//MultiplyByPP
350 
351 
352 // This procedure should rely on the procedure for polys.
353 // When there are orderings, it should know if
354 // Ord=DRL, Var=last var, in which case may just return
355 // exponent(LPP(*this),DH_var_index)
max_common_wdeg(GPoly & f,long Var)356   long max_common_wdeg(GPoly& f,long Var)
357   {
358     const SparsePolyRing P = owner(f);
359     RingElem tmp(f.myPolyValue);
360     long result=numeric_limits<long>::max();
361     for (;!IsZero(tmp);)
362     {
363       result=min<long>(result,exponent(LPP(tmp),Var));
364       P->myDeleteLM(raw(tmp));
365     }
366     return result;
367   }//max_common_wdeg
368 
369 //   void GRingInfo::WDegLessSVar(degree& res,ConstRefPPMonoidElem T)const// wdeg(T)-wdeg(saturating to the power it has in T)
370 //   {
371 //     PPMonoid TmpPPM=owner(T);
372 //     long LastVarIndex=NumIndets(TmpPPM)-1;
373 //     PPMonoidElem T1(TmpPPM->myOne());
374 //     vector<long> exps(TmpPPM->myNumIndets());
375 //     TmpPPM->myExponents(exps,raw(T));
376 //     TmpPPM->myMulIndetPower(raw(T1),LastVarIndex,exps[LastVarIndex]);
377 //     PPMonoidElem T2(TmpPPM);
378 //     TmpPPM->myDiv(raw(T2),raw(T),raw(T1));
379 //     res=wdeg(T2);
380 //   }//WDegLessSVar
381 
382 //   degree GRingInfo::WDegLessSVarA(ConstRefPPMonoidElem T)const// wdeg(T)-wdeg(saturating to the power it has in T)
383 //   {
384 //     PPMonoid TmpPPM=owner(T);
385 //     long LastVarIndex=NumIndets(TmpPPM)-1;
386 //     PPMonoidElem T1(TmpPPM->myOne());
387 //     vector<long> exps(TmpPPM->myNumIndets());
388 //     TmpPPM->myExponents(exps,raw(T));
389 //     TmpPPM->myMulIndetPower(raw(T1),LastVarIndex,exps[LastVarIndex]);
390 //     PPMonoidElem T2(TmpPPM);
391 //     TmpPPM->myDiv(raw(T2),raw(T),raw(T1));
392 //     return wdeg(T2);
393 //   }//WDegLessSVar
394 
395 //  degree GRingInfo::WDegLessSVarB(ConstRefPPMonoidElem T01,ConstRefPPMonoidElem T02)const// wdeg(T)-wdeg(saturating to the power it has in T)
396 //   {
397 //     PPMonoid TmpPPM=owner(T01);
398 //     PPMonoidElem T(TmpPPM);
399 //     TmpPPM->myDiv(raw(T),raw(T01),raw(T02));
400 //     long LastVarIndex=NumIndets(TmpPPM)-1;
401 //     PPMonoidElem T1(TmpPPM->myOne());
402 //     vector<long> exps(TmpPPM->myNumIndets());
403 //     TmpPPM->myExponents(exps,raw(T));
404 //     TmpPPM->myMulIndetPower(raw(T1),LastVarIndex,exps[LastVarIndex]);
405 //     PPMonoidElem T2(TmpPPM);
406 //     TmpPPM->myDiv(raw(T2),raw(T),raw(T1));
407 //     return wdeg(T2);
408 //   }//WDegLessSVar
409 
410 // void GRingInfo::WDegLessSVarSmart(degree& res,
411 //                                   ConstRefPPMonoidElem T1,
412 //                                   ConstRefPPMonoidElem T2)const
413 // {
414 //    PPMonoid TmpPPM=owner(T1);
415 //    long LastVarIndex=NumIndets(TmpPPM)-1;
416 //    res.mySetComponent(0,exponent(T1,LastVarIndex)-exponent(T2,LastVarIndex));//WARNING: this works only for st deg
417 // }//WDegLessSVarSmart
418 
419 // void GRingInfo::WDegLessSVarFake(degree& res,
420 //                                  ConstRefPPMonoidElem T1,
421 //                                  ConstRefPPMonoidElem T2)const
422 // {
423 //    PPMonoid TmpPPM=owner(T1);
424 //    long LastVarIndex=NumIndets(TmpPPM)-1;
425 //    res.mySetComponent(0,exponent(T1,LastVarIndex)-exponent(T2,LastVarIndex));//WARNING: this works only for st deg
426 // }//WDegLessSVarFake
427 
428 
429 // WARN : this function should rely on smart_dehomog for polys.
430 // Using that, smart_dehomog_DRL and smart_dehomog are few lines and equal.
smart_dehomog_DRL(long DH_var_index)431   void GPoly::smart_dehomog_DRL(long DH_var_index)
432   {
433     long mc_deg=exponent(LPPForDiv(*this),DH_var_index);
434     const SparsePolyRing P = owner(*this);
435     RingElem result(P);
436     RingElem tmp(P);
437     RingElem H2Deg = P->myMonomial(raw(one(CoeffRing(P))),
438                                    raw(IndetPower(PPM(P), DH_var_index, mc_deg)));
439     if (mc_deg!=0)
440     {
441       for (;!IsZero(myPolyValue);)
442       {
443         P->myDivLM(raw(tmp),raw(myPolyValue),raw(H2Deg));
444         P->myDeleteLM(raw(myPolyValue));
445         P->myAppendClear(raw(result),raw(tmp));
446       }
447       swap(myPolyValue, result);
448       myLPPForOrd /= IndetPower(PPM(P), DH_var_index, mc_deg);
449       vector<long> expv;
450       exponents(expv, myLPPForOrd);
451       myLPPForDivwMask = expv;
452       myWDeg = wdeg(myLPPForOrd);
453     }
454     // myComponent and myLC... stay the same
455   }//smart_dehomog_DRL
456 
457 
smart_dehomog(long DH_var_index)458   void GPoly::smart_dehomog(long DH_var_index)
459   {
460     long mc_deg=max_common_wdeg(*this,DH_var_index);
461     const SparsePolyRing P = owner(myPolyValue);
462     RingElem result(P);
463     RingElem tmp(P);
464     RingElem H2Deg = P->myMonomial(raw(one(CoeffRing(P))),
465                                    raw(IndetPower(PPM(P), DH_var_index, mc_deg)));
466 
467     if (mc_deg!=0)
468     {
469       for (;!IsZero(myPolyValue);)
470       {
471         P->myDivLM(raw(tmp),raw(myPolyValue),raw(H2Deg));
472         P->myDeleteLM(raw(myPolyValue));
473         P->myAppendClear(raw(result),raw(tmp));
474       }
475       swap(myPolyValue, result);
476       myLPPForOrd /= IndetPower(PPM(P), DH_var_index, mc_deg);
477       vector<long> expv;
478       exponents(expv, myLPPForOrd);
479       myLPPForDivwMask = expv;
480       myWDeg = wdeg(myLPPForOrd);
481     }
482     // myComponent and myRing... stay the same
483   }//smart_dehomog
484 
485 
486 //******** ReductorData ******************************************************
487 
ReductorData(GPoly * p,const long p_component,const long count)488   ReductorData::ReductorData(GPoly* p, const long p_component,  const long count):
489       myLPPForDivwMask(LPPForDivwMask(*p))
490   {
491     myGPolyPtr=p;
492     myKey=MakeKey(*p);
493     myComponent=p_component;
494     myCount = count;
495     IamBorelUpdated = true;
496     myIamNotToBeUsedValue=false;
497   }
498 
499 
ReductorData(const ReductorData & RD)500   ReductorData::ReductorData(const ReductorData& RD):
501       myLPPForDivwMask(RD.myLPPForDivwMask)
502   {
503     myGPolyPtr=RD.myGPolyPtr;
504     myKey=RD.myKey;
505     myComponent=RD.myComponent;
506     myCount = RD.myCount;
507     IamBorelUpdated = RD.IamBorelUpdated;
508     myIamNotToBeUsedValue=RD.myIamNotToBeUsedValue;
509   }
510 
511 
512   ostream& operator<<(ostream& out, const ReductorData& RD)
513   {
514     if (!out) return out;  // short-cut for bad ostreams
515 
516     out<<"Record[ Key=" << RD.myKey
517        <<", age=" << age(*(RD.myGPolyPtr))
518        <<", LPPForDiv=" << PP(RD.myLPPForDivwMask)
519        <<", LPPForOrd=" << LPPForOrd(*(RD.myGPolyPtr))
520        <<", MdCmp=" << RD.myComponent
521        //<<", Used = " << RD.myCount  //TMP SAT
522        <<", Upd = " << RD.IamBorelUpdated
523        <<", ToBeUsd = " << RD.myIamNotToBeUsedValue
524        <<", Wdeg=" << wdeg(*(RD.myGPolyPtr))
525        <<", Sugar=" << sugar(*(RD.myGPolyPtr))
526        <<", PtrPoly="<<*(RD.myGPolyPtr)
527        <<"]";
528     return out;
529   }
530 
531   // The Key field controls the reductors ordering
MakeKey(const GPoly & gp)532   long MakeKey(const GPoly& gp)
533   {
534     //if (Len(gp)<255) return Len(gp);
535     // return gp.myAge+255;
536     return gp.myAge;
537   }
538 
539 
540 
541 
542 //********* Reductors *****************************************************
543 
544 
Reductors(const GRingInfo & P,const UseBorelFlag UBR)545   Reductors::Reductors(const GRingInfo& P, const UseBorelFlag UBR):
546       myGRingInfoValue(P)
547   {
548     myReductors.reserve(10000);
549     if (UBR == DontUseBorel)
550       IhaveBorelReductorsFlag = false;
551     else
552     {
553       IhaveBorelReductorsFlag = true;
554       myBorelReductors.reserve(10000);
555     }
556   }
557 
558 
Reductors(const GRingInfo & P)559   Reductors::Reductors(const GRingInfo& P):
560       myGRingInfoValue(P)
561   {
562     myReductors.reserve(10000);
563     IhaveBorelReductorsFlag = false;
564   }
565 
566 
PPM(const Reductors & red)567   const PPMonoid& PPM(const Reductors& red)
568   {
569     return PPM(owner(red));
570   }
571 
572 
owner(const Reductors & red)573   const SparsePolyRing& owner(const Reductors& red)
574   {
575     return red.myGRingInfo().myNewSPR();
576   }
577 
Insert(GPoly * p,const long count)578   void Reductors::Insert(GPoly* p, const long count)
579   {
580     myReductors.push_back(ReductorData(p,Component(*p), count));
581     //This is useless if  myKey is  Age.
582     long N = len(myReductors)-1;
583     for (long i=0;i!=N;++i)
584       if (myReductors[N]<myReductors[i]) std::swap(myReductors[i],myReductors[N]);
585     // ANNA : Borel algorithm
586     if (IhaveBorelReductorsFlag)
587     {
588       myBorelGPolys.push_back(*p); // ANNA
589       GPoly* f = &myBorelGPolys.back();
590       myBorelReductors.push_back(ReductorData(f,Component(*f), count));
591     }
592   }
593 
594 
myStampaReductors(ostream & out)595   void Reductors::myStampaReductors(ostream& out) const
596   {
597     if (!out) return;  // short-cut for bad ostreams
598 
599     out << "TheREDUCTORS := " << myReductors << endl;
600 
601     if (IhaveBorelReductorsFlag)
602       out << "The_BOREL_REDUCTORS := " << myBorelReductors << endl;
603   }
604 
605 
606    // Find the (unique and exisitng) ReductorData which ptr is equal to GPolyPtr.
607    // Existence is guaranteed by the fact that this procedure is used ONLY for
608    // the final interreduction.
find(GPoly * GPolyPtr)609    vector<ReductorData>::iterator Reductors::find(GPoly* GPolyPtr)
610    {
611      for (vector<ReductorData>::iterator it=myReductors.begin();
612 	                                 it!=myReductors.end();
613 					 ++it)
614        if (it->myGetGPolyPtr()==GPolyPtr)
615          return it;
616 
617      CoCoA_ASSERT(true);// This instruction should never be executed
618      return myReductors.end();// for compilator's sake.
619    }//find
620 
621 
622 /*Reduces the polys in G of degree Deg(f) with the poly f */
interreduce(const GPoly & f)623   void Reductors::interreduce(const GPoly& f)
624   {
625     for (std::vector<ReductorData>::reverse_iterator it=myReductors.rbegin();
626          it!=myReductors.rend();
627          ++it )
628       //  if (wdeg(*(it->myGPolyPtr))>d)
629      (it->myGPolyPtr)->myReduceTail(f);
630   }//interreduce
631 
632 
633 /*Reduces the polys in G of degree Deg(f) with the poly f
634   WARN G is supposed to be ordered by Deg                */
OrderedInterreduce(const GPoly & f)635   void Reductors::OrderedInterreduce(const GPoly& f)
636   {
637     degree d(wdeg(f));
638 
639     for (std::vector<ReductorData>::reverse_iterator it=myReductors.rbegin();
640          it!=myReductors.rend()&&(wdeg(*(it->myGPolyPtr))==d);
641          ++it )
642       (it->myGPolyPtr)->myReduceTail(f);
643   }//OrderedInterreduce
644 
645 
646 /*Reduces the polys in G with the poly f*/
SuperInterreduce(const GPoly & f)647   void Reductors::SuperInterreduce(const GPoly& f)
648   {
649     //  unsigned  int d = deg(f);
650     for (std::vector<ReductorData>::reverse_iterator it=myReductors.rbegin();
651          it!=myReductors.rend();
652          ++it )
653       (it->myGPolyPtr)->myReduceTail(f);
654   }//SuperInterreduce
655 
656   // clean the reductors keeping the same GRI
myClear()657   void Reductors::myClear()
658   {
659     myReductors.clear();
660     myBorelReductors.clear();
661     myBorelGPolys.clear();
662   }//clean
663 
664 //   void swap(Reductors& R1,Reductors& R2)
665 //   {
666 //     // TODO NEW if (R1.myPolyRing!=R2.myPolyRing) return;
667 //     swap(R1.myReductors,R2.myReductors);
668 //   }
669 
670 
671 // This function prepares the Borel Reductors for the next degree
myBorelReductorsUpdateInNextDegree()672   void Reductors::myBorelReductorsUpdateInNextDegree()
673   {
674     for (vector<ReductorData>::const_iterator it = myBorelReductors.begin();
675          it != myBorelReductors.end();
676          ++it)
677       it->IamBorelUpdated = false;
678   }
679 
680 
681   // forward declaration of class GPoly needed.
monic(std::list<GPoly> & GPL)682   void monic(std::list<GPoly>& GPL)
683   {
684     if (GPL.empty())
685       return;
686     const SparsePolyRing P(owner(GPL));
687     for (std::list<GPoly>::iterator it=GPL.begin();it!=GPL.end();++it)
688     {
689       it->myPolyValue/=LC(it->myPolyValue);
690       it->myLCValue=one(P);
691     }
692   }//monic
693 
694 
owner(const PolyList & thePL)695   SparsePolyRing owner(const PolyList& thePL)
696   {
697     CoCoA_ASSERT(!thePL.empty());
698     return owner(*thePL.begin());
699   }//owner
700 
owner(const GPolyList & theGPL)701   SparsePolyRing owner(const GPolyList& theGPL)
702   {
703     CoCoA_ASSERT(!theGPL.empty());
704     return owner(*theGPL.begin());
705   }//owner
706 
707 //  SparsePolyRing owner(const  std::vector<RingElem>& thePV)
708 //   {
709 //     CoCoA_ASSERT(!thePV.empty());
710 //     return owner(*thePV.begin());
711 //   }//owner
712 
PolyList2PolyVectorClear(PolyList & thePL,std::vector<RingElem> & thePV)713   void PolyList2PolyVectorClear(PolyList& thePL,std::vector<RingElem>& thePV)
714   {
715     thePV.clear();
716     if (thePL.empty())
717       return;
718     const SparsePolyRing P(owner(thePL));
719     for (PolyList::iterator it=thePL.begin();it!=thePL.end();++it)
720     {
721       thePV.push_back(one(P));
722       swap(thePV.back(),*it);
723     }
724   }//PolyList2PolyVector
725 
PolyVector2PolyListClear(std::vector<RingElem> & thePV,PolyList & thePL)726   void PolyVector2PolyListClear(std::vector<RingElem>& thePV,PolyList& thePL)
727   {
728     thePL.clear();
729     if (thePV.empty())
730       return;
731     const SparsePolyRing P(owner(thePV));
732     for (std::vector<RingElem>::iterator it=thePV.begin();it!=thePV.end();++it)
733     {
734       thePL.push_back(one(P));
735       swap(thePL.back(),*it);
736     }
737   }//PolyVector2PolyList
738 
739   // power(y_1y_2..y_k,d_1d_2..d_k)=y_1^d_1y_2^d_2..y_k^d_k
power(RingElem & theResult,const std::vector<RingElem> & theV,const degree & the_d)740   void power(RingElem& theResult,
741              const std::vector<RingElem>& theV,
742              const degree& the_d)
743   {
744     CoCoA_ASSERT(len(theV)==GradingDim(the_d));
745      CoCoA_ASSERT(GradingDim(owner(theResult))==GradingDim(the_d));
746      const SparsePolyRing SPR=owner(theResult);
747      theResult=one(SPR);
748      if (theV.empty())
749        return;
750      for (long j=0; j < GradingDim(SPR); ++j)
751        theResult*=power(theV[j],the_d[j]);
752   }//power
753 
754 
755 }// end namespace cocoa
756 
757 // $Header: /Volumes/Home_1/cocoa/cvs-repository/CoCoALib-0.99/src/AlgebraicCore/TmpGPoly.C,v 1.41 2020/02/11 16:56:42 abbott Exp $
758 // $Log: TmpGPoly.C,v $
759 // Revision 1.41  2020/02/11 16:56:42  abbott
760 // Summary: Corrected last update (see redmine 969)
761 //
762 // Revision 1.40  2020/02/11 16:12:19  abbott
763 // Summary: Added some checks for bad ostream (even to mem fns myOutput); see redmine 969
764 //
765 // Revision 1.39  2019/11/14 17:59:31  abbott
766 // Summary: Removed a little cruft
767 //
768 // Revision 1.38  2018/05/18 16:38:51  bigatti
769 // -- added include SparsePolyOps-RingElem.H
770 //
771 // Revision 1.37  2018/05/18 12:24:47  bigatti
772 // -- renamed IntOperations --> BigIntOps
773 //
774 // Revision 1.36  2018/05/17 15:52:29  bigatti
775 // -- renamed VectorOperations --> VectorOps
776 //
777 // Revision 1.35  2017/11/29 17:42:08  bigatti
778 // -- just spaces
779 //
780 // Revision 1.34  2017/11/27 08:47:13  bigatti
781 // -- just spaces in a comment
782 //
783 // Revision 1.33  2017/04/26 12:53:54  bigatti
784 // -- some cleaning: len --> NumTerms, f.IsActive() --> IsActive(f), ..
785 //
786 // Revision 1.32  2017/04/18 09:33:32  bigatti
787 // -- "age" now lower-case
788 //
789 // Revision 1.31  2016/11/11 14:15:33  abbott
790 // Summary: Added short-cut to operator<< when ostream is in bad state
791 //
792 // Revision 1.30  2014/07/31 14:45:18  abbott
793 // Summary: Merged io.H and UtilsTemplate.H into new header VectorOperations.H
794 // Author: JAA
795 //
796 // Revision 1.29  2014/07/07 13:05:25  abbott
797 // Summary: Removed AsSparsePolyRing
798 // Author: JAA
799 //
800 // Revision 1.28  2013/10/28 13:22:33  bigatti
801 // -- myMinimalGenLevel, IsInputPoly
802 //
803 // Revision 1.27  2013/06/12 08:50:03  bigatti
804 // -- added IamMinimalGen
805 //
806 // Revision 1.26  2013/06/03 09:11:50  bigatti
807 // renamed ModuleTermOrdering into ModuleOrdering
808 //
809 // Revision 1.25  2012/10/16 09:51:53  abbott
810 // Replaced  RefRingElem  by  RingElem&
811 //
812 // Revision 1.24  2012/05/28 09:18:20  abbott
813 // Created IntOperations which gathers together all operations on
814 // integers (both big and small).  Many consequential changes.
815 //
816 // Revision 1.23  2012/02/10 10:29:07  bigatti
817 // -- changed RingZ.H, RingQ.H --> RingZZ.H, RingQQ.H
818 //
819 // Revision 1.22  2011/03/11 17:38:55  bigatti
820 // -- changed  unsigned int --> long
821 //
822 // Revision 1.21  2011/03/11 15:33:30  bigatti
823 // -- changed size_t into long
824 //
825 // Revision 1.20  2011/03/11 12:09:57  bigatti
826 // -- changed size --> len
827 //
828 // Revision 1.19  2011/03/10 16:39:33  abbott
829 // Replaced (very many) size_t by long in function interfaces (for rings,
830 // PPMonoids and modules).  Also replaced most size_t inside fn defns.
831 //
832 // Revision 1.18  2010/12/26 13:04:37  abbott
833 // Changed "GlobalXXXput" into corresponding std C++ stream
834 // (even in commented out code).
835 //
836 // Revision 1.17  2010/07/16 09:29:58  bigatti
837 // -- minor cleaning and coding conventions
838 //
839 // Revision 1.16  2010/05/14 09:53:09  bigatti
840 // -- removed empty ctor for SugarDegree
841 // -- added marker for SugarDegree(uninitialized)
842 // -- SugarDegree for GBasis input is initialized by myPrepareGBasis
843 //
844 // Revision 1.15  2010/03/23 14:43:07  bigatti
845 // -- class GRingInfo estracted from TmpGPoly
846 //
847 // Revision 1.14  2009/12/03 17:41:01  abbott
848 // Removed useless include of FGModule.H
849 //
850 // Revision 1.13  2009/10/27 17:15:14  bigatti
851 // -- fixed: using sugar(g)->myWSugar() insted of wsugar(g)
852 //
853 // Revision 1.12  2009/05/14 12:27:39  abbott
854 // Fixed typo (changed "ESS:" into "ERR::")
855 //
856 // Revision 1.11  2009/04/27 13:38:17  bigatti
857 // -- changed DetermineComputationType
858 // -- added temporary functions (DegLess..)
859 //
860 // Revision 1.10  2009/04/27 12:31:32  bigatti
861 // -- added   case SaturatingAlgNoDRL
862 //
863 // Revision 1.9  2009/02/09 14:22:36  bigatti
864 // -- changed std::swap(RingElem, RingElem) --> swap(RingElem, RingElem)
865 //
866 // Revision 1.8  2009/01/08 06:57:57  bigatti
867 // -- fixed smart_dehomog (myLPPForOrd was not updated)
868 //
869 // Revision 1.7  2008/09/19 13:33:42  bigatti
870 // -- added: Sat algorithm (M.Caboara)
871 //
872 // Revision 1.6  2008/09/16 15:03:42  bigatti
873 // -- added LPPForDiv
874 // -- changed LPP into LPPForOrd
875 //
876 // Revision 1.5  2008/04/18 15:35:57  abbott
877 // (long overdue) Major revision to matrices
878 //
879 // Revision 1.4  2007/12/05 11:06:24  bigatti
880 // -- changed "size_t StdDeg/myStdDeg(f)" into "long"  (and related functions)
881 // -- changed "log/myLog(f, i)" into "MaxExponent/myMaxExponent(f, i)"
882 // -- fixed bug in "IsOne(ideal)" in SparsePolyRing.C
883 //
884 // Revision 1.3  2007/12/04 14:27:06  bigatti
885 // -- changed "log(pp, i)" into "exponent(pp, i)"
886 //
887 // Revision 1.2  2007/10/30 17:14:07  abbott
888 // Changed licence from GPL-2 only to GPL-3 or later.
889 // New version for such an important change.
890 //
891 // Revision 1.1  2007/03/09 18:56:56  bigatti
892 // -- added Tmp prefix to Groebner related files
893 //
894 // Revision 1.1.1.1  2007/03/09 15:16:11  abbott
895 // Imported files
896 //
897 // Revision 1.18  2007/03/08 18:50:05  bigatti
898 // -- disabled function  bool GRingInfo::DetermineIfMyGradingIsPosPlus(const SparsePolyRing& theSPR)
899 //
900 // Revision 1.17  2007/03/08 18:22:29  cocoa
901 // Just whitespace cleaning.
902 //
903 // Revision 1.16  2007/03/07 17:04:31  cocoa
904 // -- several changes by M.Caboara: more operations on ideals,
905 //    exception cleaner, coding conventions, WSugar, dynamic
906 //
907 // Revision 1.15  2007/03/05 21:06:07  cocoa
908 // New names for homomorphism pseudo-ctors: removed the "New" prefix.
909 //
910 // Revision 1.14  2007/02/10 18:44:03  cocoa
911 // Added "const" twice to each test and example.
912 // Eliminated dependency on io.H in several files.
913 // Improved BuildInfo, and added an example about how to use it.
914 // Some other minor cleaning.
915 //
916 // Revision 1.13  2006/12/22 11:37:40  cocoa
917 // Removed operator<< for PolyList and GPolyList.  A few consequential changes.
918 //
919 // Revision 1.12  2006/12/21 13:48:33  cocoa
920 // Made all increment/decrement calls prefix (except where the must be postfix).
921 //
922 // Revision 1.11  2006/12/04 13:55:54  cocoa
923 // -- added: sugar for GradingDim > 0  (called wsugar)
924 //
925 // Revision 1.10  2006/11/27 14:24:02  cocoa
926 // -- removed ";" in debugging printing function
927 //
928 // Revision 1.9  2006/11/20 14:57:17  cocoa
929 // -- added: (standard) sugar for modules
930 // -- fixed: non-homogeneous sysygies
931 // -- minor fixes     [M.Caboara]
932 //
933 // Revision 1.8  2006/11/09 17:46:58  cocoa
934 // -- version 0.9712:
935 // --   IdealImpl moved to SparsePolyRing from concrete rings
936 // -- PolyList in GTypes is now vector<RingElem> (was list)
937 // -- "my" coding convention applied to DistrMPoly
938 //
939 // Revision 1.7  2006/10/16 23:18:59  cocoa
940 // Corrected use of std::swap and various special swap functions.
941 // Improved myApply memfn for homs of RingDistrMPolyInlPP.
942 //
943 // Revision 1.6  2006/10/06 16:32:06  cocoa
944 // -- changed: GPoly::SPoly --> GPoly::myAssignSPoly
945 // -- changed: Len(const GPoly&) --> len(const GPoly&)
946 // -- added:   poly(const GPoly&)
947 // -- added:   GPoly::myUpdateLenLPPDegComp()
948 // -- in reduce.C added functions for computing sugar during reduction
949 //
950 // Revision 1.5  2006/10/06 14:04:15  cocoa
951 // Corrected position of #ifndef in header files.
952 // Separated CoCoA_ASSERT into assert.H from config.H;
953 // many minor consequential changes (have to #include assert.H).
954 // A little tidying of #include directives (esp. in Max's code).
955 //
956 // Revision 1.4  2006/10/06 10:48:34  cocoa
957 // Removed #include references to GradedFreeModule.H
958 //
959 // Revision 1.3  2006/08/17 09:28:56  cocoa
960 // -- added: sugar
961 // -- added: controls on homogeneity
962 //
963 // Revision 1.2  2006/07/20 14:15:42  cocoa
964 // -- removed unused "wdeg"
965 //
966 // Revision 1.1.1.1  2006/05/30 11:39:37  cocoa
967 // Imported files
968 //
969 // Revision 1.20  2006/05/04 14:25:16  cocoa
970 // -- major cleaning of FreeModule: created GradedFreeModule and moved
971 //    some code around
972 //
973 // Revision 1.19  2006/04/27 15:06:58  cocoa
974 // -- removed (wrong) check on the degree in Reductors::interreduce(const GPoly& f)
975 //
976 // Revision 1.18  2006/04/27 13:45:30  cocoa
977 // Changed name of NewIdentityRingHom to NewIdentityHom.
978 // Changed name of member functions which print out their own object
979 // into myOutputSelf (to distinguish from "transitive" myOutput fns).
980 //
981 // Revision 1.17  2006/04/21 16:46:14  cocoa
982 // -- minor changes by Max
983 //
984 // Revision 1.16  2006/04/11 14:29:48  cocoa
985 // -- minor cleaning
986 //
987 // Revision 1.15  2006/04/11 14:16:29  cocoa
988 // -- reorganization of fns between reduce,SparsePolyRing,GPoly
989 // -- added optional "len" argument to myAssignReset in ReductionCog
990 //
991 // Revision 1.14  2006/04/10 16:24:38  cocoa
992 // -- changed implementation of reduce by a single GPoly
993 //    (I didn't really do it last time..)
994 //
995 // Revision 1.13  2006/03/22 17:58:45  cocoa
996 // -- changed implementation of reduce by a single GPoly
997 //
998 // Revision 1.12  2006/03/17 18:17:16  cocoa
999 // -- changed: use of ReductionCog for reduction (major cleanup)
1000 //
1001 // Revision 1.11  2006/03/16 14:34:43  cocoa
1002 // -- moved GlobalLogput out of my way
1003 //
1004 // Revision 1.10  2006/03/07 17:01:21  cocoa
1005 // -- changed: operations on coefficients are now decided by
1006 //    "myCoeffRingType" (need a better name for it!)
1007 //
1008 // Revision 1.9  2006/03/02 13:43:26  cocoa
1009 // -- changed: myPoly --> myPolyValue
1010 //
1011 // Revision 1.8  2006/02/14 16:23:58  cocoa
1012 // -- defined "operator<<" for vector<RingElem>& in ring.C/H
1013 //
1014 // Revision 1.7  2006/02/13 14:46:45  cocoa
1015 // -- changes by Max
1016 //
1017 // Revision 1.6  2006/02/13 13:50:20  cocoa
1018 // -- changes by Max (GRingInfo)
1019 //
1020 // Revision 1.5  2006/01/20 15:43:30  cocoa
1021 // -- fixed: use of RefPPMonoidElem and ConstRefPPMonoidElem
1022 //
1023 // Revision 1.4  2006/01/18 15:58:20  cocoa
1024 // -- new changes by Max
1025 //
1026 // Revision 1.3  2006/01/17 15:44:56  cocoa
1027 // -- chamges by Max for operations with modules
1028 //
1029 // Revision 1.2  2006/01/17 10:23:08  cocoa
1030 // Updated DivMask; many consequential changes.
1031 // A few other minor fixes.
1032 //
1033 // Revision 1.1.1.1  2005/10/17 10:46:54  cocoa
1034 // Imported files
1035 //
1036 // Revision 1.3  2005/09/28 11:50:34  cocoa
1037 // -- new code for graded modules
1038 //
1039 // Revision 1.2  2005/07/01 16:08:15  cocoa
1040 // Friday check-in.  Major change to structure under PolyRing:
1041 // now SparsePolyRing and DUPolyRing are separated (in preparation
1042 // for implementing iterators).
1043 //
1044 // A number of other relatively minor changes had to be chased through
1045 // (e.g. IndetPower).
1046 //
1047 // Revision 1.1.1.1  2005/05/03 15:47:31  cocoa
1048 // Imported files
1049 //
1050 // Revision 1.3  2005/04/19 14:06:04  cocoa
1051 // Added GPL and GFDL licence stuff.
1052 //
1053 // Revision 1.2  2005/02/11 14:15:20  cocoa
1054 // New style ring elements and references to ring elements;
1055 // I hope I have finally got it right!
1056 //
1057 // Revision 1.1.1.1  2005/01/27 15:12:13  cocoa
1058 // Imported files
1059 //
1060 // Revision 1.12  2004/11/19 15:44:27  cocoa
1061 // Changed names of "casting" functions which convert a ring into
1062 // one with a more special structure (e.g. FractionField).  These
1063 // functions now have names starting with "As".  There were several
1064 // consequential changes.
1065 //
1066 // Revision 1.11  2004/11/18 18:33:41  cocoa
1067 // Now every ring know its own "one" element (as well as "zero").
1068 // Several consequential changes.
1069 //
1070 // Revision 1.10  2004/11/11 13:37:33  cocoa
1071 // -- change: cout --> GlobalLogput()
1072 //
1073 // Revision 1.9  2004/10/29 15:55:54  cocoa
1074 // -- changed myLPP into myLPPwMask (PPMonoidElem --> PPWithMask)
1075 // -- added DivMask::base arguments in GPoly constructors
1076 //
1077 // Revision 1.8  2004/06/29 17:10:22  cocoa
1078 // Partially tidied use of "protected" and "private" in various
1079 // base classes.  Checking in at the end of the day -- it works,
1080 // and I wouldn't want it to be lost next time point's disk
1081 // misbehaves.
1082 //
1083 // Revision 1.7  2004/06/16 16:13:41  cocoa
1084 // Improved I/O facilities with knock-on changes
1085 //
1086 // Revision 1.6  2004/05/27 16:27:21  cocoa
1087 // -- removed ";" at the end of function bodies (g++ gives error on them)
1088 //
1089 // Revision 1.5  2004/05/27 16:14:02  cocoa
1090 // Minor revision for new coding conventions.
1091 //
1092 // Revision 1.4  2004/03/04 11:37:18  cocoa
1093 // -- updated code for Borel reductors:
1094 //    ReductorData fields: myGPoly->myGPolyPtr;  new: myCount, IamBorelUpdated
1095 //    myBorelReductors is now in Reductors (was in GReductor)
1096 //    Reductors: field: IhaveBorelReductors;  type: enum UseBorelMarker
1097 //
1098 // Revision 1.3  2003/10/08 14:27:33  cocoa
1099 // New naming convention for ring member functions.
1100 //
1101 // Revision 1.2  2003/10/01 10:35:32  cocoa
1102 // - applied "my" coding convention to PPMonoid and PPOrdering
1103 //
1104 // Revision 1.1.1.1  2003/09/24 12:55:43  cocoa
1105 // Imported files
1106 //
1107 // Revision 1.14  2003/09/22 17:00:04  bigatti
1108 // - myDeg is now defined as deg(myPoly) instead of deg(myLPP)
1109 //
1110 // Revision 1.13  2003/06/23 17:10:23  abbott
1111 // Minor cleaning prior to public release.
1112 // Improved the include directives,
1113 //
1114 // Revision 1.12  2003/05/29 16:31:02  bigatti
1115 // - change: RingSpecialIndex is now int
1116 // - change: order of SPoly arguments
1117 //
1118 // Revision 1.11  2003/05/28 14:14:59  bigatti
1119 // - new code for modules
1120 //
1121 // Revision 1.10  2003/05/14 16:52:37  bigatti
1122 // - new ring/PPMonoid syntax
1123 // - new functions for "BorelReductorsPolys" and saturating algorithm
1124 // - added myPolyRing field
1125 // - myDeg is now of type degree
1126 //
1127 // Revision 1.9  2002/11/15 17:29:56  bigatti
1128 // - ASSERT --> CoCoA_ASSERT
1129 //
1130 // Revision 1.8  2002/09/19 17:17:44  bigatti
1131 // - More general structure using PolyRing
1132 //
1133 // Revision 1.7  2002/05/13 11:45:42  bigatti
1134 // - new data structure for "Reductors"
1135 //
1136 // Revision 1.6  2002/04/17 10:46:14  bigatti
1137 // - new function: SPoly moved here from DMP
1138 // - new field: myLPP
1139 //
1140 // Revision 1.5  2002/04/15 17:26:44  bigatti
1141 // - Max's new code
1142 //
1143 // Revision 1.4  2002/04/09 14:06:20  bigatti
1144 // - SPoly now takes a GPair as argument
1145 //
1146 // Revision 1.3  2002/01/31 17:19:55  bigatti
1147 // - new function: ReduceTail
1148 //
1149 // Revision 1.2  2001/12/12 17:56:33  bigatti
1150 // - new structure of reduction
1151 //
1152 // Revision 1.1  2001/12/05 12:56:02  bigatti
1153 // Initial revision
1154 //
1155