1 //   Copyright (c)  2005-2007,2010  John Abbott and Anna M. Bigatti
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 
19 // Source code for RingDistrMPolyInlFpPPImpl
20 
21 #include "CoCoA/RingDistrMPolyInlFpPP.H"
22 
23 #include "CoCoA/BigIntOps.H"
24 #include "CoCoA/DistrMPolyInlFpPP.H"
25 #include "CoCoA/MemPool.H"
26 #include "CoCoA/OpenMath.H"
27 #include "CoCoA/PPMonoidOv.H" // includes "CoCoA/symbol.H"
28 #include "CoCoA/RingFp.H" // for IsRingFp
29 #include "CoCoA/RingHom.H"
30 #include "CoCoA/SparsePolyRing.H"
31 #include "CoCoA/assert.H"
32 #include "CoCoA/convert.H"
33 #include "CoCoA/symbol.H"
34 #include "CoCoA/utils.H"
35 
36 #include <algorithm>
37 using std::sort;
38 using std::copy;
39 #include <iostream>
40 using std::ostream;
41 #include <memory>
42 using std::unique_ptr;
43 #include <new>
44 //for placement new
45 //#include <vector> // included in RingDistrMPolyInlFpPP.H
46 using std::vector;
47 
48 
49 namespace CoCoA
50 {
51 
52   class RingDistrMPolyInlFpPPImpl: public SparsePolyRingBase
53   {
54   private:
55     typedef DistrMPolyInlFpPP value_t; // DistrMPolyInlFpPP is the actual type of the values in a RingDistrMPolyInlFpPP
56     static value_t& import(RingElemRawPtr rawf);
57     static const value_t& import(RingElemConstRawPtr rawf);
58 
59   public:
60     RingDistrMPolyInlFpPPImpl(const ring& R, const std::vector<symbol>& IndetNames, const PPOrdering& ord);
61     ~RingDistrMPolyInlFpPPImpl();
62 
63   private: // Data members of RingDistrMPolyInlFpPPImpl
64     const ring myCoeffRingValue;  ///< the coefficient ring (used for input and output)
65     const DistrMPolyInlFpPP::InlineFpImpl myInlineCoeffImplValue;  ///< to be used instead of ring for inlining operations on coefficients
66     const PPMonoid myPPMValue; ///< the monoid of the power-products
67     const OrdvArith::reference myOrdvArith;
68     mutable MemPool myDMPPool; ///< memory manager for polynomials
69     long myNumIndetsValue; ///< number of indeteminates
70     mutable MemPool mySummandPool; ///< memory manager for summands; MemPool MUST COME BEFORE myZeroPtr, myOnePtr, and myIndetVector!
71     std::unique_ptr<RingElem> myZeroPtr;  ///< Every ring stores its own zero.
72     std::unique_ptr<RingElem> myOnePtr;   ///< Every ring stores its own one.
73     std::vector<RingElem> myIndetVector;
74 
75   public:  // functions which every ring must implement
myZero()76     virtual ConstRefRingElem myZero() const {return *myZeroPtr;}
myOne()77     virtual ConstRefRingElem myOne() const {return *myOnePtr;}
78     using RingBase::myNew;    // disable warnings of overloading
79     using RingBase::myAssign; // disable warnings of overloading
80     using PolyRingBase::myIndets; // disable warnings of overloading
81     virtual RingElemRawPtr myNew() const;
82     virtual RingElemRawPtr myNew(const MachineInt& n) const;
83     virtual RingElemRawPtr myNew(const BigInt& N) const;
84     virtual RingElemRawPtr myNew(ConstRawPtr rawcopy) const;
85     virtual void myDelete(RawPtr rawx) const;                             // destroys x (incl all resources)
86     virtual void mySwap(RawPtr rawx, RawPtr rawy) const;                  // swap(x, y)
87     virtual void myAssign(RawPtr rawlhs, ConstRawPtr rawx) const;         // lhs = x
88     virtual void myAssign(RawPtr rawlhs, const MachineInt& n) const;  // lhs = n
89     virtual void myAssign(RawPtr rawlhs, const BigInt& N) const;          // lhs = N
90     virtual void myAssignZero(RawPtr rawlhs) const;                       // lhs = 0
91     virtual void myRecvTwinFloat(RawPtr rawlhs, ConstRawPtr rawx) const;
92     virtual void myNegate(RawPtr rawlhs, ConstRawPtr rawx) const;         // lhs = -x
93     virtual void myAdd(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const;        // lhs = x+y
94     virtual void mySub(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const;        // lhs = x-y
myImplDetails()95     virtual std::string myImplDetails() const {return "RingDistrMPolyInlFpPP";}
96     virtual bool myIsZero(ConstRawPtr rawx) const;                                // x == 0
97     virtual bool myIsEqual(ConstRawPtr rawx, ConstRawPtr rawy) const;                // x == y
98 
99     // functions which every PolyRing must implement
100 
myNumIndets()101     virtual long myNumIndets() const {return myNumIndetsValue;}
myCoeffRing()102     virtual const ring& myCoeffRing() const {return myCoeffRingValue;}
myIndets()103     virtual const std::vector<RingElem>& myIndets() const {return myIndetVector;}
104     virtual void myIndetPower(RawPtr rawf, long var, long exp) const;
105 
106     ///@name Simple functions on polynomials
107     //@{
108     virtual long myNumTerms(ConstRawPtr rawf) const;
109     virtual bool myIsMonomial(ConstRawPtr rawf) const;
110     virtual RingElemAlias myLC(ConstRawPtr rawf) const;
111     virtual void myMulByCoeff(RawPtr rawf, ConstRawPtr rawc) const; ///< WEAK EXCEPTION GUARANTEE
112     virtual bool myDivByCoeff(RawPtr rawf, ConstRawPtr rawc) const; ///< WEAK EXCEPTION GUARANTEE
113     //@}
114 
115     //----------------------------------------------------------------------
116     // Functions which every SparsePolyRing must implement:
117     //----------------------------------------------------------------------
118 
myPPM()119     virtual const PPMonoid& myPPM() const {return myPPMValue;}
120 
121     ///@name   Functions for creating/building polynomials
122     //@{
123     virtual RingElem myMonomial(ConstRawPtr rawc, PPMonoidElemConstRawPtr rawpp) const;
124     virtual SparsePolyIter myBeginIter(ConstRawPtr rawf) const;
125     virtual SparsePolyIter myEndIter(ConstRawPtr rawf) const;
126 
127     virtual void myPushFront(RawPtr rawf, ConstRawPtr rawc, const std::vector<long>& expv) const;
128     virtual void myPushBack(RawPtr rawf, ConstRawPtr rawc, const std::vector<long>& expv) const;
129     virtual void myPushFront(RawPtr rawf, ConstRawPtr rawc, PPMonoidElemConstRawPtr rawpp) const;
130     virtual void myPushBack(RawPtr rawf, ConstRawPtr rawc, PPMonoidElemConstRawPtr rawpp) const;
131     //@}
132 
133     ///@name Special functions on polynomials needed for implementing Buchberger's Algorithm
134     //@{
135     virtual ConstRefPPMonoidElem myLPP(ConstRawPtr rawf) const;
136     virtual void myMulByPP(RawPtr rawf, PPMonoidElemConstRawPtr rawpp) const;
137     virtual bool myIsZeroAddLCs(RawPtr rawf, RawPtr rawg) const; ///< f+=LM(g); g-=LM(g); assumes LPP(f)==LPP(g); returns LC(f)+LC(g)==0
138     virtual void myMoveLMToFront(RawPtr rawf, RawPtr rawg) const;
139     virtual void myMoveLMToBack(RawPtr rawf, RawPtr rawg) const;
140     virtual void myDeleteLM(RawPtr rawf) const; // ????? right interface
141     virtual void myDivLM(RawPtr rawlhs, ConstRawPtr rawf, ConstRawPtr rawg) const; ///< lhs=div(LM(f),LM(g)); assumes f!=0,g!=0
142     virtual int  myCmpLPP(ConstRawPtr rawf, ConstRawPtr rawg) const; ///< cmp(LPP(f),LPP(g)); assumes f!=0,g!=0
143     virtual void myAddClear(RawPtr rawf, RawPtr rawg) const; ///< f+=g; g=0;
144     virtual void myAppendClear(RawPtr rawf, RawPtr rawg) const; ///< f+=g; g=0; appends g to f with no checks
145 
146     virtual void myAddMulLM(RawPtr rawf, ConstRawPtr rawh, ConstRawPtr rawg) const; ///<  f += LM(h)*g
147     virtual void myAddMulLM(RawPtr rawf, ConstRawPtr rawh, ConstRawPtr rawg, SkipLMFlag) const; ///<  f += LM(h)*g
148     virtual void myReductionStep(RawPtr rawf, ConstRawPtr rawg) const;
149     // ??? aggiungere coefficiente
150     virtual void myReductionStepGCD(RawPtr rawf, ConstRawPtr rawg, RingElem& FScale) const;
151     // should it all be in ReductionStep ??? ANNA
152     //@}
153 
154 
155 // ***ATTENTION*** [20140726] is it worth having this special case code???
156   // private: // Special homomorphism class for this type of ring.
157   //   class CoeffEmbeddingHomImpl: public SparsePolyRingBase::CoeffEmbeddingHomImpl
158   //   {
159   //   public:
160   //     CoeffEmbeddingHomImpl(const SparsePolyRing& P);
161   //     virtual void myApply(RingElemRawPtr rawimage, RingElemConstRawPtr rawarg) const;
162   //   };
163 
164   };
165 
166   //----------------------------------------------------------------------
167 
168   typedef DistrMPolyInlFpPP::InlineFpElem_t InlineFpElem_t; // to save some typing
169 
170 
import(RingElemRawPtr rawf)171   inline RingDistrMPolyInlFpPPImpl::value_t& RingDistrMPolyInlFpPPImpl::import(RingElemRawPtr rawf)
172   {
173     return *static_cast<value_t*>(rawf.myRawPtr());
174   }
175 
import(RingElemConstRawPtr rawf)176   inline const RingDistrMPolyInlFpPPImpl::value_t& RingDistrMPolyInlFpPPImpl::import(RingElemConstRawPtr rawf)
177   {
178     return *static_cast<const value_t*>(rawf.myRawPtr());
179   }
180 
181 
RingDistrMPolyInlFpPPImpl(const ring & R,const std::vector<symbol> & IndetNames,const PPOrdering & ord)182   RingDistrMPolyInlFpPPImpl::RingDistrMPolyInlFpPPImpl(const ring& R, const std::vector<symbol>& IndetNames, const PPOrdering& ord):
183     myCoeffRingValue(R),
184     myInlineCoeffImplValue(ConvertTo<long>(characteristic(R))),
185     myPPMValue(NewPPMonoidOv(IndetNames, ord)),
186     myOrdvArith(NewOrdvArith(ord)),
187     myDMPPool(sizeof(DistrMPolyInlFpPP), "RingDistrMPolyInlFpPPImpl::myDMPPool"),
188     myNumIndetsValue(NumIndets(ord)),
189     mySummandPool(DistrMPolyInlFpPP::SummandSize(R, myOrdvArith), "RingDistrMPolyInlFpPPImpl::mySummandPool")
190   {
191     //    std::cout << "------RingDistrMPolyInlFpPPImpl:NewOrdvArith-called" << std::endl;
192     CoCoA_ASSERT(IsCommutative(myCoeffRingValue));
193     CoCoA_ASSERT(len(IndetNames) == myNumIndetsValue);
194     myRefCountInc();  // this is needed for exception cleanliness, in case one of the lines below throws
195     myZeroPtr.reset(new RingElem(ring(this)));
196     myOnePtr.reset(new RingElem(ring(this), 1));
197     myIndetVector.resize(myNumIndetsValue, *myZeroPtr);
198     vector<long> expv(myNumIndetsValue);
199     for (long i=0; i < myNumIndetsValue; ++i)
200     {
201       expv[i] = 1;
202       myPushFront(raw(myIndetVector[i]), raw(one(R)), expv);
203       expv[i] = 0;
204     }
205     myRefCountZero(); // otherwise it is 2 + NumIndets and won't be destroyed
206   }
207 
208 
~RingDistrMPolyInlFpPPImpl()209   RingDistrMPolyInlFpPPImpl::~RingDistrMPolyInlFpPPImpl()
210   {}
211 
212 
213   //----------------------------------------------------------------------
214   // Functions which every ring must implement:
215   //----------------------------------------------------------------------
216 
myNew()217   RingElemRawPtr RingDistrMPolyInlFpPPImpl::myNew() const
218   {
219     void* ptr = myDMPPool.alloc();
220     new(ptr) DistrMPolyInlFpPP(myInlineCoeffImplValue, myCoeffRingValue, myPPMValue, myOrdvArith, mySummandPool); // placement new
221     return RingElemRawPtr(ptr);
222   }
223 
224 
myNew(const MachineInt & n)225   RingElemRawPtr RingDistrMPolyInlFpPPImpl::myNew(const MachineInt& n) const
226   {
227     if (IsZero(n)) return myNew();
228     unique_ptr<DistrMPolyInlFpPP> ans(new(myDMPPool.alloc()) DistrMPolyInlFpPP(myInlineCoeffImplValue, myCoeffRingValue, myPPMValue, myOrdvArith, mySummandPool)); // placement new
229     *ans = n;
230     return RingElemRawPtr(ans.release());
231   }
232 
233 
myNew(const BigInt & N)234   RingElemRawPtr RingDistrMPolyInlFpPPImpl::myNew(const BigInt& N) const
235   {
236     if (N == 0) return myNew();
237     unique_ptr<DistrMPolyInlFpPP> ans(new(myDMPPool.alloc()) DistrMPolyInlFpPP(myInlineCoeffImplValue, myCoeffRingValue, myPPMValue, myOrdvArith, mySummandPool)); // placement new
238     *ans = N;
239     return RingElemRawPtr(ans.release());
240   }
241 
242 
myNew(ConstRawPtr rawcopy)243   RingElemRawPtr RingDistrMPolyInlFpPPImpl::myNew(ConstRawPtr rawcopy) const
244   {
245     unique_ptr<DistrMPolyInlFpPP> ans(new(myDMPPool.alloc()) DistrMPolyInlFpPP(myInlineCoeffImplValue, myCoeffRingValue, myPPMValue, myOrdvArith, mySummandPool)); // placement new
246     *ans = import(rawcopy);
247     return RingElemRawPtr(ans.release());
248   }
249 
250 
myDelete(RawPtr rawx)251   void RingDistrMPolyInlFpPPImpl::myDelete(RawPtr rawx) const
252   {
253     import(rawx).~DistrMPolyInlFpPP();
254     myDMPPool.free(rawx.myRawPtr());
255   }
256 
257 
mySwap(RawPtr rawx,RawPtr rawy)258   void RingDistrMPolyInlFpPPImpl::mySwap(RawPtr rawx, RawPtr rawy) const
259   {
260     swap(import(rawx), import(rawy));
261   }
262 
263 
myAssign(RawPtr rawlhs,ConstRawPtr rawx)264   void RingDistrMPolyInlFpPPImpl::myAssign(RawPtr rawlhs, ConstRawPtr rawx) const
265   {
266     import(rawlhs) = import(rawx);
267   }
268 
269 
myAssign(RawPtr rawlhs,const MachineInt & n)270   void RingDistrMPolyInlFpPPImpl::myAssign(RawPtr rawlhs, const MachineInt& n) const
271   {
272     import(rawlhs) = n;
273   }
274 
275 
myAssign(RawPtr rawlhs,const BigInt & N)276   void RingDistrMPolyInlFpPPImpl::myAssign(RawPtr rawlhs, const BigInt& N) const
277   {
278     import(rawlhs) = N;
279   }
280 
281 
myAssignZero(RawPtr rawlhs)282   void RingDistrMPolyInlFpPPImpl::myAssignZero(RawPtr rawlhs) const
283   {
284     import(rawlhs).myAssignZero();
285   }
286 
287 
myRecvTwinFloat(RawPtr,ConstRawPtr)288   void RingDistrMPolyInlFpPPImpl::myRecvTwinFloat(RawPtr /*rawlhs*/, ConstRawPtr /*rawx*/) const
289   {
290     CoCoA_THROW_ERROR(ERR::ShouldNeverGetHere, "RingDistrMPolyInlFpPPImpl::myRecvTwinFloat");
291   }
292 
293 
myNegate(RawPtr rawlhs,ConstRawPtr rawx)294   void RingDistrMPolyInlFpPPImpl::myNegate(RawPtr rawlhs, ConstRawPtr rawx) const
295   {
296     import(rawlhs) = import(rawx);
297     import(rawlhs).myNegate();
298   }
299 
300 
myAdd(RawPtr rawlhs,ConstRawPtr rawx,ConstRawPtr rawy)301   void RingDistrMPolyInlFpPPImpl::myAdd(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const
302   {
303     add(import(rawlhs), import(rawx), import(rawy));
304   }
305 
306 
mySub(RawPtr rawlhs,ConstRawPtr rawx,ConstRawPtr rawy)307   void RingDistrMPolyInlFpPPImpl::mySub(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const
308   {
309     sub(import(rawlhs), import(rawx), import(rawy));
310   }
311 
312 
myIsZero(ConstRawPtr rawx)313   bool RingDistrMPolyInlFpPPImpl::myIsZero(ConstRawPtr rawx) const
314   {
315     return IsZero(import(rawx));
316   }
317 
318 
myIsEqual(ConstRawPtr rawx,ConstRawPtr rawy)319   bool RingDistrMPolyInlFpPPImpl::myIsEqual(ConstRawPtr rawx, ConstRawPtr rawy) const
320   {
321     return IsEqual(import(rawx), import(rawy));
322   }
323 
324 
325   //----------------------------------------------------------------------
326   // Functions which every PolyRing must implement
327   //----------------------------------------------------------------------
328 
myIndetPower(RawPtr rawf,long var,long exp)329   void RingDistrMPolyInlFpPPImpl::myIndetPower(RawPtr rawf, long var, long exp) const
330   {
331     CoCoA_ASSERT(var < myNumIndets());
332     CoCoA_ASSERT(exp >= 0);
333     RingElem ans(ring(this));
334     vector<long> expv(myNumIndets()); // wasteful new/delete
335     expv[var] = NumericCast<long>(exp);
336     import(raw(ans)).myPushFront(one(SmallFp), expv);
337     mySwap(raw(ans), rawf); // do it this way to be exception clean
338   }
339 
340 
myNumTerms(ConstRawPtr rawx)341   long RingDistrMPolyInlFpPPImpl::myNumTerms(ConstRawPtr rawx) const
342   { return NumTerms(import(rawx)); }
343 
myIsMonomial(ConstRawPtr rawf)344   bool RingDistrMPolyInlFpPPImpl::myIsMonomial(ConstRawPtr rawf) const
345   { return IsMonomial(import(rawf)); }
346 
347 
myLC(ConstRawPtr rawf)348   RingElemAlias RingDistrMPolyInlFpPPImpl::myLC(ConstRawPtr rawf) const
349   {
350     CoCoA_ASSERT(!myIsZero(rawf));
351     return RingElemAlias(myCoeffRing(), RingElemRawPtr(const_cast<InlineFpElem_t*>(&LC(import(rawf)))));
352   }
353 
354 
myMulByCoeff(RawPtr rawf,ConstRawPtr rawc)355   void RingDistrMPolyInlFpPPImpl::myMulByCoeff(RawPtr rawf, ConstRawPtr rawc) const // EXCEPTION SAFE
356   {
357     BigInt N;
358     myCoeffRingValue->myIsInteger(N, rawc);  // must return true
359     InlineFpElem_t c = myInlineCoeffImplValue.myReduce(N);
360     import(rawf).myMulByCoeff(c);
361   }
362 
363 
myDivByCoeff(RawPtr rawf,ConstRawPtr rawc)364   bool RingDistrMPolyInlFpPPImpl::myDivByCoeff(RawPtr rawf, ConstRawPtr rawc) const // EXCEPTION SAFE
365   {
366     BigInt N;
367     myCoeffRingValue->myIsInteger(N, rawc);  // must return true
368     InlineFpElem_t c = myInlineCoeffImplValue.myReduce(N);
369     return import(rawf).myDivByCoeff(c);
370   }
371 
372 
373   //----------------------------------------------------------------------
374   // Functions which every SparsePolyRing must implement:
375   //----------------------------------------------------------------------
376 
377 
myMonomial(ConstRawPtr rawc,PPMonoidElemConstRawPtr rawpp)378   RingElem RingDistrMPolyInlFpPPImpl::myMonomial(ConstRawPtr rawc, PPMonoidElemConstRawPtr rawpp) const
379   {
380     CoCoA_ASSERT(!myCoeffRing()->myIsZero(rawc));
381     RingElem ans(ring(this));
382     myPushFront(raw(ans), rawc, rawpp);
383     return ans;
384   }
385 
386 
myBeginIter(ConstRawPtr rawf)387   SparsePolyIter RingDistrMPolyInlFpPPImpl::myBeginIter(ConstRawPtr rawf) const
388   { return SparsePolyIter(new DistrMPolyInlFpPP::iter(import(rawf))); }
389 
myEndIter(ConstRawPtr rawf)390   SparsePolyIter RingDistrMPolyInlFpPPImpl::myEndIter(ConstRawPtr rawf) const
391   { return SparsePolyIter(new DistrMPolyInlFpPP::iter(import(rawf), 0)); }
392 
393 
myPushFront(RawPtr rawf,ConstRawPtr rawc,const std::vector<long> & expv)394   void RingDistrMPolyInlFpPPImpl::myPushFront(RawPtr rawf, ConstRawPtr rawc, const std::vector<long>& expv) const
395   {
396     BigInt N;
397     myCoeffRingValue->myIsInteger(N, rawc);  // Necessarily returns true.
398     InlineFpElem_t c = myInlineCoeffImplValue.myReduce(N);
399     import(rawf).myPushFront(c, expv);
400     CoCoA_ASSERT(myIsValid(rawf));
401   }
402 
403 
myPushBack(RawPtr rawf,ConstRawPtr rawc,const std::vector<long> & expv)404   void RingDistrMPolyInlFpPPImpl::myPushBack(RawPtr rawf, ConstRawPtr rawc, const std::vector<long>& expv) const
405   {
406     BigInt N;
407     myCoeffRingValue->myIsInteger(N, rawc);  // Necessarily returns true.
408     InlineFpElem_t c = myInlineCoeffImplValue.myReduce(N);
409     import(rawf).myPushBack(c, expv);
410     CoCoA_ASSERT(myIsValid(rawf));
411   }
412 
413 
myPushFront(RawPtr rawf,ConstRawPtr rawc,PPMonoidElemConstRawPtr rawpp)414   void RingDistrMPolyInlFpPPImpl::myPushFront(RawPtr rawf, ConstRawPtr rawc, PPMonoidElemConstRawPtr rawpp) const
415   {
416     BigInt N;
417     myCoeffRingValue->myIsInteger(N, rawc);  // Necessarily returns true.
418     InlineFpElem_t c = myInlineCoeffImplValue.myReduce(N);
419     import(rawf).myPushFront(c, rawpp);
420     CoCoA_ASSERT(myIsValid(rawf));
421   }
422 
423 
myPushBack(RawPtr rawf,ConstRawPtr rawc,PPMonoidElemConstRawPtr rawpp)424   void RingDistrMPolyInlFpPPImpl::myPushBack(RawPtr rawf, ConstRawPtr rawc, PPMonoidElemConstRawPtr rawpp) const
425   {
426     BigInt N;
427     myCoeffRingValue->myIsInteger(N, rawc);  // Necessarily returns true.
428     InlineFpElem_t c = myInlineCoeffImplValue.myReduce(N);
429     import(rawf).myPushBack(c, rawpp);
430     CoCoA_ASSERT(myIsValid(rawf));
431   }
432 
433 
myLPP(ConstRawPtr rawf)434   ConstRefPPMonoidElem RingDistrMPolyInlFpPPImpl::myLPP(ConstRawPtr rawf) const
435   {
436     CoCoA_ASSERT(!myIsZero(rawf));
437     return LPP(import(rawf));
438   }
439 
440 
myMulByPP(RawPtr rawf,PPMonoidElemConstRawPtr rawpp)441   void RingDistrMPolyInlFpPPImpl::myMulByPP(RawPtr rawf, PPMonoidElemConstRawPtr rawpp) const
442   { import(rawf).myMulByPP(rawpp); }
443 
myIsZeroAddLCs(RawPtr rawf,RawPtr rawg)444   bool RingDistrMPolyInlFpPPImpl::myIsZeroAddLCs(RawPtr rawf, RawPtr rawg) const
445   { return IsZeroAddLCs(import(rawf), import(rawg)); }
446 
447 
myMoveLMToFront(RawPtr rawf,RawPtr rawg)448   void RingDistrMPolyInlFpPPImpl::myMoveLMToFront(RawPtr rawf, RawPtr rawg) const
449   {
450     CoCoA_ASSERT(!myIsZero(rawg));
451     MoveLMToFront(import(rawf), import(rawg));
452   }
453 
454 
myMoveLMToBack(RawPtr rawf,RawPtr rawg)455   void RingDistrMPolyInlFpPPImpl::myMoveLMToBack(RawPtr rawf, RawPtr rawg) const
456   {
457     CoCoA_ASSERT(!myIsZero(rawg));
458     MoveLMToBack(import(rawf), import(rawg));
459   }
460 
461 
myDeleteLM(RawPtr rawf)462   void RingDistrMPolyInlFpPPImpl::myDeleteLM(RawPtr rawf) const
463   {
464     CoCoA_ASSERT(!myIsZero(rawf));
465     import(rawf).myDeleteLM();
466   }
467 
468 
myDivLM(RawPtr rawlhs,ConstRawPtr rawf,ConstRawPtr rawg)469   void RingDistrMPolyInlFpPPImpl::myDivLM(RawPtr rawlhs, ConstRawPtr rawf, ConstRawPtr rawg) const
470   {
471     CoCoA_ASSERT(!myIsZero(rawf) && !myIsZero(rawg));
472     DivLM(import(rawlhs), import(rawf), import(rawg));
473   }
474 
475 
myCmpLPP(ConstRawPtr rawf,ConstRawPtr rawg)476   int  RingDistrMPolyInlFpPPImpl::myCmpLPP(ConstRawPtr rawf, ConstRawPtr rawg) const
477   {
478     CoCoA_ASSERT(!myIsZero(rawf) && !myIsZero(rawg));
479     return CmpLPP(import(rawf), import(rawg));
480   }
481 
482 
myAddClear(RawPtr rawf,RawPtr rawg)483   void RingDistrMPolyInlFpPPImpl::myAddClear(RawPtr rawf, RawPtr rawg) const
484   { import(rawf).myAddClear(import(rawg)); }
485 
486 
myAppendClear(RawPtr rawf,RawPtr rawg)487   void RingDistrMPolyInlFpPPImpl::myAppendClear(RawPtr rawf, RawPtr rawg) const
488   {
489 #ifdef CoCoA_DEBUG
490     if (!myIsZero(rawf) && !myIsZero(rawg))
491     {
492       for (SparsePolyIter it=myBeginIter(rawf); !IsEnded(it); ++it)  // INEFFICIENT   SLUG????
493         CoCoA_ASSERT(PP(it) > myLPP(rawg));
494     }
495 #endif
496     import(rawf).myAppendClear(import(rawg));
497   }
498 
499 
myAddMulLM(RawPtr rawf,ConstRawPtr rawh,ConstRawPtr rawg)500   void RingDistrMPolyInlFpPPImpl::myAddMulLM(RawPtr rawf, ConstRawPtr rawh, ConstRawPtr rawg) const //???? delete me???
501   { import(rawf).myAddMulLM(import(rawh), import(rawg), /* SkipLMg = */ false); }
502 
myAddMulLM(RawPtr rawf,ConstRawPtr rawh,ConstRawPtr rawg,SkipLMFlag skip)503   void RingDistrMPolyInlFpPPImpl::myAddMulLM(RawPtr rawf, ConstRawPtr rawh, ConstRawPtr rawg, SkipLMFlag skip) const //???? delete me???
504   { import(rawf).myAddMulLM(import(rawh), import(rawg), skip==SkipLMg); }
505 
myReductionStep(RawPtr rawf,ConstRawPtr rawg)506   void RingDistrMPolyInlFpPPImpl::myReductionStep(RawPtr rawf, ConstRawPtr rawg) const
507   { import(rawf).myReductionStep(import(rawg)); }
508 
myReductionStepGCD(RawPtr rawf,ConstRawPtr rawg,RingElem & fscale)509   void RingDistrMPolyInlFpPPImpl::myReductionStepGCD(RawPtr rawf, ConstRawPtr rawg, RingElem& fscale) const
510   { import(rawf).myReductionStepGCD(import(rawg), fscale); }
511 
512 
513 // ***ATTENTION*** CoeffEmbeddingHomImpl
514 // Special case code; should be a bit more efficient that general case -- is it really worth it???
515   // //---------------------------------------------------------------------------
516   // // Functions for the class RingDistrMPolyInlFpPPImpl::CoeffEmbeddingHom
517 
518   // RingDistrMPolyInlFpPPImpl::CoeffEmbeddingHomImpl::CoeffEmbeddingHomImpl(const SparsePolyRing& P):
519   //   SparsePolyRingBase::CoeffEmbeddingHomImpl(P)
520   // {}
521 
522 
523   // void RingDistrMPolyInlFpPPImpl::CoeffEmbeddingHomImpl::myApply(RingElemRawPtr rawimage, RingElemConstRawPtr rawarg) const
524   // {
525   //   BigInt x;   //??? wasteful ctor/dtor???
526   //   myDomain->myIsInteger(x, rawarg);  // must return true
527   //   myCodomain->myAssign(rawimage, x);  // I think this is "no throw" in this case ???
528   // }
529 
530 
531   //----------------------------------------------------------------------
532   // Pseudo-ctors for (sparse) polynomial rings.
533 
534   namespace  {  // anonymous
CheckCoeffRing(const ring & K)535     void CheckCoeffRing(const ring& K)
536     {
537       if (!IsRingFp(K)) // check that CoeffRing is really a SmallFpImpl
538         CoCoA_THROW_ERROR(ERR::NotQuotientRing, "NewPolyRing_DMPII pseudo ctor");
539     }
540 
541 
CheckIndets(const ring & K,const std::vector<symbol> & IndetNames)542     void CheckIndets(const ring& K, const std::vector<symbol>& IndetNames)
543     {
544       if (IndetNames.empty())
545         CoCoA_THROW_ERROR(ERR::Empty, "NewPolyRing_DMPII pseudo ctor");
546       if (!AreGoodIndetNames(K, IndetNames))
547         CoCoA_THROW_ERROR(ERR::BadIndetNames, "NewPolyRing_DMPII pseudo ctor");
548     }
549 
550 
CheckNumIndets(long n)551     void CheckNumIndets(long n)
552     {
553       if (n <=0 )
554         CoCoA_THROW_ERROR(ERR::BadNumIndets, "NewPolyRing_DMPII pseudo ctor");
555     }
556 
557 
CheckNumIndets(long n,const std::vector<symbol> & IndetNames)558     void CheckNumIndets(long n, const std::vector<symbol>& IndetNames)
559     {
560       CheckNumIndets(n);
561       if (n != len(IndetNames))
562         CoCoA_THROW_ERROR(ERR::BadNumIndets, "NewPolyRing_DMPII pseudo ctor");
563     }
564 
565   }  // anonymous namespace
566 
567 
NewPolyRing_DMPII(const ring & CoeffRing,const std::vector<symbol> & IndetNames,const PPOrdering & ord)568   SparsePolyRing NewPolyRing_DMPII(const ring& CoeffRing, const std::vector<symbol>& IndetNames, const PPOrdering& ord)
569   {
570     CheckCoeffRing(CoeffRing);
571     CheckIndets(CoeffRing, IndetNames);
572     return SparsePolyRing(new RingDistrMPolyInlFpPPImpl(CoeffRing, IndetNames, ord));
573   }
574 
575 
NewPolyRing_DMPII(const ring & CoeffRing,const std::vector<symbol> & IndetNames,const PPOrderingCtor & OrdCtor)576   SparsePolyRing NewPolyRing_DMPII(const ring& CoeffRing, const std::vector<symbol>& IndetNames, const PPOrderingCtor& OrdCtor)
577   {
578     CheckCoeffRing(CoeffRing);
579     CheckIndets(CoeffRing, IndetNames);
580     return SparsePolyRing(new RingDistrMPolyInlFpPPImpl(CoeffRing, IndetNames, OrdCtor(len(IndetNames))));
581   }
582 
583 
NewPolyRing_DMPII(const ring & CoeffRing,const std::vector<symbol> & IndetNames)584   SparsePolyRing NewPolyRing_DMPII(const ring& CoeffRing, const std::vector<symbol>& IndetNames)
585   {
586     return NewPolyRing_DMPII(CoeffRing, IndetNames, StdDegRevLex(len(IndetNames)));
587   }
588 
589 
NewPolyRing_DMPII(const ring & CoeffRing,long NumIndets)590   SparsePolyRing NewPolyRing_DMPII(const ring& CoeffRing, long NumIndets)
591   {
592     CheckNumIndets(NumIndets);
593     return NewPolyRing_DMPII(CoeffRing, SymbolRange("x",0,NumIndets-1), StdDegRevLex(NumIndets));
594   }
595 
596 
NewPolyRing_DMPII(const ring & CoeffRing,long NumIndets,const PPOrderingCtor & OrdCtor)597   SparsePolyRing NewPolyRing_DMPII(const ring& CoeffRing, long NumIndets, const PPOrderingCtor& OrdCtor)
598   {
599     CheckNumIndets(NumIndets);
600     return NewPolyRing_DMPII(CoeffRing, SymbolRange("x",0,NumIndets-1), OrdCtor(NumIndets));
601   }
602 
603 
604 } // end of namespace CoCoA
605 
606 
607 // RCS header/log in the next few lines
608 // $Header: /Volumes/Home_1/cocoa/cvs-repository/CoCoALib-0.99/src/AlgebraicCore/RingDistrMPolyInlFpPP.C,v 1.50 2020/06/17 15:49:26 abbott Exp $
609 // $Log: RingDistrMPolyInlFpPP.C,v $
610 // Revision 1.50  2020/06/17 15:49:26  abbott
611 // Summary: Changed CoCoA_ERROR into CoCoA_THROW_ERROR
612 //
613 // Revision 1.49  2020/01/09 16:41:10  bigatti
614 // -- improved error message for empty list of IndetNames in pseudo ctor
615 //
616 // Revision 1.48  2019/03/04 10:38:11  abbott
617 // Summary: Changed auto_ptr into unique_ptr
618 //
619 // Revision 1.47  2018/06/13 15:07:07  abbott
620 // Summary: Added check for empty list of symbols in pseudo-cto for DMPI and DMPII
621 //
622 // Revision 1.46  2018/05/18 12:15:56  bigatti
623 // -- renamed IntOperations --> BigIntOps
624 //
625 // Revision 1.45  2017/12/01 17:28:21  bigatti
626 // -- a commented out line (debugging info)
627 //
628 // Revision 1.44  2017/11/10 16:02:27  abbott
629 // Summary: Removed NewLexOrdering, NewStdDegLexOrdering, NewStdDegRevLexOrdering; consequential changes
630 //
631 // Revision 1.43  2017/09/06 11:56:29  abbott
632 // Summary: Changed ERR::SERIOUS into ERR::ShouldNeverGetHere
633 //
634 // Revision 1.42  2015/12/01 13:11:01  abbott
635 // Summary: Changed mem fn PPOrderingCtor::myCtor into operator(); also for ModuleOrderingCtor; see issue 829
636 //
637 // Revision 1.41  2015/11/04 10:46:04  abbott
638 // Summary: Consequential change (after revising SmallFpImpl)
639 //
640 // Revision 1.40  2015/04/24 15:40:58  bigatti
641 // -- renamed: myAddMul --> myAddMulLM
642 // -- renamed: myMoveLM --> myMoveLMToFront
643 // -- new myMoveLMToBack (used in ReductionCog --> bug in test-TmpMorseGraph??)
644 //
645 // Revision 1.39  2014/12/11 13:34:42  bigatti
646 // -- removed all input for doxygen
647 //
648 // Revision 1.38  2014/07/28 15:47:55  abbott
649 // Summary: Redesign: ringhoms no longer cached in rings (caused ref count trouble); removed lots of cruft
650 // Author: JAA
651 //
652 // Revision 1.37  2014/07/11 15:46:00  bigatti
653 // -- removed myOutputSelf (default impl) and added myImplDetails
654 //
655 // Revision 1.36  2014/07/04 13:35:42  bigatti
656 // -- in printing of ring, indeterminates are now more compact
657 //
658 // Revision 1.35  2014/07/04 13:08:08  bigatti
659 // -- RingID into RingWithID
660 //
661 // Revision 1.34  2014/07/02 16:33:14  bigatti
662 // -- new way of printing rings with ID
663 //
664 // Revision 1.33  2014/05/14 15:57:15  bigatti
665 // -- added "using" for clang with superpedantic flag
666 //
667 // Revision 1.32  2014/04/15 14:25:02  abbott
668 // Summary: Removed cruft (commented out code which is impl'd in PolyRing)
669 // Author: JAA
670 //
671 // Revision 1.31  2013/05/27 14:08:47  abbott
672 // Replaced SmallFpElem_t by SmallFpImpl::value_t.
673 //
674 // Revision 1.30  2012/10/24 12:19:38  abbott
675 // Changed return type of myLC.
676 //
677 // Revision 1.29  2012/10/17 09:40:16  abbott
678 // Replaced  RefRingElem  by  RingElem&
679 // (plus a few consequential changes)
680 //
681 // Revision 1.28  2012/09/26 12:29:33  abbott
682 // Updated to new SmallFpImpl interface.
683 //
684 // Revision 1.27  2012/05/28 09:18:21  abbott
685 // Created IntOperations which gathers together all operations on
686 // integers (both big and small).  Many consequential changes.
687 //
688 // Revision 1.26  2012/05/22 10:02:37  abbott
689 // Removed IsGCDDomain; substituted by IsTrueGCDDomain.
690 // Added IsFractionFieldOfGCDDomain.
691 //
692 // Revision 1.25  2011/11/09 14:10:49  bigatti
693 // -- renamed MachineInteger --> MachineInt
694 //
695 // Revision 1.24  2011/08/14 15:52:17  abbott
696 // Changed ZZ into BigInt (phase 1: just the library sources).
697 //
698 // Revision 1.23  2011/06/23 16:04:47  abbott
699 // Added IamExact mem fn for rings.
700 // Added myRecvTwinFloat mem fn for rings.
701 // Added first imple of RingHom from RingTwinFloat to other rings.
702 //
703 // Revision 1.22  2011/05/19 14:43:49  abbott
704 // Added include of ZZ.H (previously was already included in some header file).
705 //
706 // Revision 1.21  2011/03/10 16:39:34  abbott
707 // Replaced (very many) size_t by long in function interfaces (for rings,
708 // PPMonoids and modules).  Also replaced most size_t inside fn defns.
709 //
710 // Revision 1.20  2010/10/08 14:18:58  bigatti
711 // -- changed printing style: RingDistrMPolyXXImpl(..) -->  RingDistrMPolyXX(..)
712 //
713 // Revision 1.19  2010/10/06 14:10:24  abbott
714 // Added increments to the ref count in ring and PPMonoid ctors to make
715 // them exception safe.
716 //
717 // Revision 1.18  2010/03/05 18:43:48  abbott
718 // Added pseudo-ctors allowing polynomial rings to be created specifying
719 // the ordering using a PPOrderingCtor object.
720 //
721 // Revision 1.17  2009/12/23 18:53:52  abbott
722 // Major change to conversion functions:
723 //   convert(..) is now a procedure instead of a function
724 //   IsConvertible(..) replaces the former convert(..) function
725 //   Added new NumericCast conversion function (placeholder for BOOST feature)
726 //   Consequent changes in code which uses these features.
727 //
728 // Revision 1.16  2009/12/11 11:46:32  abbott
729 // Changed fn  convert  into  IsConvertible.
730 // Added template procedure  convert.
731 // New version because change is not backward compatible.
732 //
733 // Revision 1.15  2009/10/02 13:47:07  bigatti
734 // -- myDivByCoeff now returns bool
735 // -- unique implementation of myDiv in PolyRing.C
736 //
737 // Revision 1.14  2009/09/28 16:19:43  bigatti
738 // -- unique implementation for myDeriv
739 //
740 // Revision 1.13  2009/09/25 13:02:09  bigatti
741 // -- myDiv with one implementation in SparsePolyRing
742 //
743 // Revision 1.12  2008/12/17 12:11:52  abbott
744 // Changed type from long to MachineInt in operations which use a machine integer
745 // in place of a RingElem.  The change is "superficial" but affects many files.
746 //
747 // Revision 1.11  2008/04/10 15:12:59  bigatti
748 // -- added myPushBack/Front(RawPtr, ConstRawPtr, PPMonoidElemConstRawPtr)
749 // -- minor tidying
750 //
751 // Revision 1.10  2007/10/30 17:14:07  abbott
752 // Changed licence from GPL-2 only to GPL-3 or later.
753 // New version for such an important change.
754 //
755 // Revision 1.9  2007/10/11 16:31:42  bigatti
756 // -- changed  #ifdef CoCoA_ASSERT  into  CoCoA_DEBUG
757 //
758 // Revision 1.8  2007/05/31 16:34:37  bigatti
759 // -- Changed IsValid (now returns true of false and does not throw an error)
760 // -- using IsValid for sanity check in PushBack
761 //
762 // Revision 1.7  2007/05/31 15:56:33  bigatti
763 // -- default implementation for IamCommutative, IamIntegralDomain,
764 //    IamGCDDomain, IamField, myCharacteristic  in PolyRing
765 // -- default implementation for mySymbols  in SparsePolyRing
766 // -- cleaned up pseudo-ctors
767 //
768 // Revision 1.5  2007/05/21 14:50:56  bigatti
769 // -- myPushFront and myPushBack now accept zero coefficient
770 //
771 // Revision 1.4  2007/03/23 18:38:42  abbott
772 // Separated the "convert" functions (and CheckedCast) into their own files.
773 // Many consequential changes.  Also corrected conversion to doubles.
774 //
775 // Revision 1.3  2007/03/12 16:00:29  bigatti
776 // -- moved myLog(F, index) into unique implementation in SparsePolyRing
777 //
778 // Revision 1.2  2007/03/09 18:56:56  bigatti
779 // -- added Tmp prefix to Groebner related files
780 //
781 // Revision 1.1.1.1  2007/03/09 15:16:11  abbott
782 // Imported files
783 //
784 // Revision 1.28  2007/03/08 17:43:10  cocoa
785 // Swapped order of args to the NewPPMonoid pseudo ctors.
786 //
787 // Revision 1.27  2007/03/08 16:55:06  cocoa
788 // Changed name of "range" function to "SymbolRange".
789 //
790 // Revision 1.26  2007/03/08 11:07:12  cocoa
791 // Made pseudo ctors for polynomial rings more uniform.  This allowed me to
792 // remove an include of CoCoA/symbol.H  from the RingDistrM*.H files, but then
793 // I had to put the include in several .C files.
794 //
795 // Revision 1.25  2007/03/05 21:06:07  cocoa
796 // New names for homomorphism pseudo-ctors: removed the "New" prefix.
797 //
798 // Revision 1.24  2007/01/20 14:07:25  bigatti
799 // -- moved code for homomorphism into common implementation in SparsePolyRing
800 //
801 // Revision 1.23  2007/01/15 15:47:57  cocoa
802 // -- added prefix "raw" to RawPtr arguments names
803 // -- changed rhs into rawx, n, or N
804 //
805 // Revision 1.22  2007/01/13 14:14:34  cocoa
806 // Overhaul of RingHom code: it nows uses SmartPtrIRC, and printing is more logical.
807 // Have not yet updated the documentation.
808 //
809 // Revision 1.21  2006/12/07 17:36:19  cocoa
810 // -- migrated  myRemoveBigContent myContent myPowerSmallExp  into
811 //    single implementation in SparsePolyRing
812 // -- removed  content  from DistrMPoly(..)
813 //
814 // Revision 1.20  2006/12/06 16:19:11  cocoa
815 // Minor corrections to comments.
816 //
817 // Revision 1.19  2006/11/23 18:01:53  cocoa
818 // -- moved printing functions in unified implementation in SparsePolyRing
819 // -- simplified "output(f)" for debugging only
820 //
821 // Revision 1.18  2006/11/22 17:51:31  cocoa
822 // -- moved printing functions into unified implementation in SparsePolyRing
823 //
824 // Revision 1.17  2006/11/22 15:01:20  cocoa
825 // -- sorted #include
826 //
827 // Revision 1.16  2006/11/22 14:55:50  cocoa
828 // -- added #include "CoCoA/SparsePolyRing.H"
829 //
830 // Revision 1.15  2006/11/21 18:09:23  cocoa
831 // -- added myIsMonomial
832 // -- implemented myIsOne, myIsMinusOne, myIsConstant, myIsIndet in SparsePolyRing
833 // -- removed the 4 functions from DistrMPoly(..) and RingDistrMPoly(..)
834 // -- changed all names of RawPtr arguments into "raw(..)"
835 //
836 // Revision 1.14  2006/11/14 17:18:35  cocoa
837 // -- added comment about myRefCountZero()
838 //
839 // Revision 1.13  2006/11/09 17:46:58  cocoa
840 // -- version 0.9712:
841 // --   IdealImpl moved to SparsePolyRing from concrete rings
842 // -- PolyList in GTypes is now vector<RingElem> (was list)
843 // -- "my" coding convention applied to DistrMPoly
844 //
845 // Revision 1.12  2006/11/08 16:21:59  cocoa
846 // Structural cleaning of RingHom; many consequential changes.
847 //
848 // Revision 1.11  2006/11/02 13:25:44  cocoa
849 // Simplification of header files: the OpenMath classes have been renamed.
850 // Many minor consequential changes.
851 //
852 // Revision 1.10  2006/10/19 13:56:24  cocoa
853 // Added #include<new> whenever needed (i.e. for placement new).
854 //
855 // Revision 1.9  2006/10/16 23:18:59  cocoa
856 // Corrected use of std::swap and various special swap functions.
857 // Improved myApply memfn for homs of RingDistrMPolyInlPP.
858 //
859 // Revision 1.8  2006/10/06 14:04:14  cocoa
860 // Corrected position of #ifndef in header files.
861 // Separated CoCoA_ASSERT into assert.H from config.H;
862 // many minor consequential changes (have to #include assert.H).
863 // A little tidying of #include directives (esp. in Max's code).
864 //
865 // Revision 1.7  2006/10/06 10:15:52  cocoa
866 // In response to Susan's bug: a fiasco when compiling with CoCoA_MEMPOOL_DEBUG
867 // set wrongly.  Moved several implementation classes out of their header files
868 // into the implementation files.  Several functions had to be uninlined.
869 // Also corrected position of #include, etc.
870 //
871 // Revision 1.6  2006/09/27 14:31:59  cocoa
872 // -- improved checks for CoeffRing in contructor (must be RingFp)
873 //
874 // Revision 1.5  2006/08/07 21:23:25  cocoa
875 // Removed almost all publicly visible references to SmallExponent_t;
876 // changed to long in all PPMonoid functions and SparsePolyRing functions.
877 // DivMask remains to sorted out.
878 //
879 // Revision 1.4  2006/07/20 17:06:08  cocoa
880 // -- moved myStdDeg into SparsePolyRing
881 //
882 // Revision 1.3  2006/07/17 19:49:34  cocoa
883 // Added some stronger arg checks (to myPushFront and myPushBack).
884 //
885 // Revision 1.2  2006/06/08 16:45:28  cocoa
886 // -- RingDistrMPoly*.H  have been "moved" into RingDistrMPoly*.C
887 // -- some coding conventions fixed in DistrMPoly*
888 // -- functions wdeg and CmpWDeg have a common implementation in SparsePolyRing
889 //
890 // Revision 1.1.1.1  2006/05/30 11:39:37  cocoa
891 // Imported files
892 //
893 // Revision 1.25  2006/05/29 16:22:37  cocoa
894 // Third time lucky???
895 // Added myIsInteger member function to all rings (NYI for RingFloat).
896 //
897 // Revision 1.24  2006/05/29 13:20:33  cocoa
898 // -- added implementation of "intersect" for SparsePolyRing
899 //
900 // Revision 1.23  2006/05/12 17:06:09  cocoa
901 // -- moved myIsUnit, myGcd into SparsePolyRing (common implementation)
902 //
903 // Revision 1.22  2006/05/12 16:10:58  cocoa
904 // Added OpenMathFwd.H, and tidied OpenMath.H.
905 // Many consequential but trivial changes.
906 //
907 // Revision 1.21  2006/04/27 13:45:30  cocoa
908 // Changed name of NewIdentityRingHom to NewIdentityHom.
909 // Changed name of member functions which print out their own object
910 // into myOutputSelf (to distinguish from "transitive" myOutput fns).
911 //
912 // Revision 1.20  2006/04/26 16:44:53  cocoa
913 // -- myMul has now a single implementation in SparsePolyRing
914 // -- myMul and mul in RingDistrMPoly* and DistrMPoly* have been disabled
915 //
916 // Revision 1.19  2006/04/21 16:47:06  cocoa
917 // -- new syntax for ComputeGBasis by Max
918 //
919 // Revision 1.18  2006/04/05 12:43:13  cocoa
920 // -- fixed: RingDistrMPolyInlFpPPImpl::HomImpl::myApply
921 //
922 // Revision 1.17  2006/03/30 17:19:48  cocoa
923 // -- removed "static" before typedef InlineFpElem_t
924 //
925 // Revision 1.16  2006/03/30 16:59:27  cocoa
926 // -- changed misleading name: InlineCoeffRing --> InlineCoeffImpl
927 // -- new: implementation for homomorphisms
928 // -- rearrangement of code to mimic RingDistrMPolyInlPP
929 //
930 // Revision 1.15  2006/03/21 09:43:13  cocoa
931 // Changed names of some member fns of ideals (dealing with setting and testing
932 // the flags for primeness and maximality).  Hope icc will complain less now.
933 //
934 // Revision 1.14  2006/03/20 17:27:42  cocoa
935 // -- changed in DistrMPolyInlFpPP: myMul, myDiv --> myMulByCoeff, myMulByPP, myDivByCoeff
936 //
937 // Revision 1.13  2006/03/17 18:10:27  cocoa
938 // -- changed: myMul --> myMulByPP
939 //
940 // Revision 1.12  2006/03/15 18:09:31  cocoa
941 // Changed names of member functions which print out their object
942 // into myOutputSelf -- hope this will appease the Intel C++ compiler.
943 //
944 // Revision 1.11  2006/03/14 15:01:49  cocoa
945 // Improved the implementation of ring member fns for computing powers.
946 // Should keep Intel C++ compiler quieter too.
947 //
948 // Revision 1.10  2006/03/12 21:28:33  cocoa
949 // Major check in after many changes
950 //
951 // Revision 1.9  2006/03/07 10:06:12  cocoa
952 // -- fixed: PPMonoidElem LPP(rawf) now returns ConstRefPPMonoidElem
953 //
954 // Revision 1.8  2006/03/07 09:57:10  cocoa
955 // -- changed only some commented out code in myApply (to be implemented)
956 //
957 // Revision 1.7  2006/02/20 22:41:19  cocoa
958 // All forms of the log function for power products now return SmallExponent_t
959 // (instead of int).  exponents now resizes the vector rather than requiring
960 // the user to pass in the correct size.
961 //
962 // Revision 1.6  2006/02/14 16:19:37  cocoa
963 // -- defined "IdealImpl::contains"
964 //
965 // Revision 1.5  2006/02/13 13:56:50  cocoa
966 // -- changed: "GReductor" --> "ComputeGBasis"
967 //
968 // Revision 1.4  2006/01/19 18:03:53  cocoa
969 // -- fixed coding conventions for myGBasis, myGBasisValue
970 // -- fixed myReduceMod (NF - tested)
971 //
972 // Revision 1.3  2006/01/19 16:34:42  cocoa
973 // -- added NF, myReduceMod functions (not yet tested)
974 //
975 // Revision 1.2  2006/01/17 15:44:56  cocoa
976 // -- chamges by Max for operations with modules
977 //
978 // Revision 1.1.1.1  2005/10/17 10:46:54  cocoa
979 // Imported files
980 //
981 // Revision 1.8  2005/09/22 18:04:17  cocoa
982 // It compiles; the tests run OK.  The examples compile.
983 // No documentation -- the mindless eurocrats have rendered
984 // me mindless too.
985 //
986 // Revision 1.7  2005/08/08 16:36:32  cocoa
987 // Just checking in before going on holiday.
988 // Don't really recall what changes have been made.
989 // Added IsIndet function for RingElem, PPMonoidElem,
990 // and a member function of OrdvArith.
991 // Improved the way failed assertions are handled.
992 //
993 // Revision 1.6  2005/07/15 16:34:33  cocoa
994 // Added iterators for sparse polynomials.
995 // The code compiles (and the old tests still run).
996 // It'd Friday evening -- I'm going home before
997 // getting any ideas about making the iterator code run.
998 //
999 // Revision 1.5  2005/07/08 15:09:28  cocoa
1000 // Added new symbol class (to represent names of indets).
1001 // Integrated the new class into concrete polynomial rings
1002 // and PPMonoid -- many consequential changes.
1003 // Change ctors for the "inline" sparse poly rings: they no
1004 // longer expect a PPMonoid, but build their own instead
1005 // (has to be a PPMonoidOv).
1006 //
1007 // Revision 1.4  2005/07/07 16:40:24  cocoa
1008 // -- added: ASSERT for gcd(0,0)
1009 //
1010 // Revision 1.3  2005/07/01 16:08:15  cocoa
1011 // Friday check-in.  Major change to structure under PolyRing:
1012 // now SparsePolyRing and DUPolyRing are separated (in preparation
1013 // for implementing iterators).
1014 //
1015 // A number of other relatively minor changes had to be chased through
1016 // (e.g. IndetPower).
1017 //
1018 // Revision 1.2  2005/06/22 14:47:56  cocoa
1019 // PPMonoids and PPMonoidElems updated to mirror the structure
1020 // used for rings and RingElems.  Many consequential changes.
1021 //
1022 // Revision 1.1.1.1  2005/05/03 15:47:31  cocoa
1023 // Imported files
1024 //
1025 // Revision 1.5  2005/04/20 15:40:48  cocoa
1026 // Major change: modified the standard way errors are to be signalled
1027 // (now via a macro which records filename and line number).  Updated
1028 // documentation in error.txt accordingly.
1029 //
1030 // Improved the documentation in matrix.txt (still more work to be done).
1031 //
1032 // Revision 1.4  2005/04/19 14:06:03  cocoa
1033 // Added GPL and GFDL licence stuff.
1034 //
1035 // Revision 1.3  2005/02/11 16:45:24  cocoa
1036 // Removed the useless and misleading functions myInit and myKill
1037 // from the SmallFp*Impl classes; various consequential changes.
1038 //
1039 // Revision 1.2  2005/02/11 14:15:20  cocoa
1040 // New style ring elements and references to ring elements;
1041 // I hope I have finally got it right!
1042 //
1043 // Revision 1.1.1.1  2005/01/27 15:12:13  cocoa
1044 // Imported files
1045 //
1046 // Revision 1.13  2004/11/25 16:14:21  cocoa
1047 // (1) Fixed definition of specialization of std::swap template function
1048 //     so that it compiles with gcc 3.4.3
1049 // (2) Implemented monomial function for polynomial rings.
1050 // (3) Added one(PPM) and PPM->myOne() functions.
1051 //
1052 // Revision 1.12  2004/11/18 18:33:41  cocoa
1053 // Now every ring know its own "one" element (as well as "zero").
1054 // Several consequential changes.
1055 //
1056 // Revision 1.11  2004/11/11 14:32:01  cocoa
1057 // -- minor changes for doxygen
1058 // -- change: cout --> GlobalLogput()
1059 //
1060 // Revision 1.10  2004/11/11 11:56:09  cocoa
1061 // (1) Tidied makefiles, and introduced common.mki
1062 // (2) Improved several tests, and cleaned them so that they
1063 //     handle sanely any otherwise unhandled exceptions.
1064 //
1065 // Revision 1.9  2004/11/08 13:54:48  cocoa
1066 // -- changed calls to ZZ (after changes to ZZ.H)
1067 //
1068 // Revision 1.8  2004/11/04 18:47:43  cocoa
1069 // (1) Ring member functions which previously expected mpz_t args
1070 //     now expect ZZ args.  Numerous minor consequential changes.
1071 // (2) Renamed function which gives access to the mpz_t value inside
1072 //     a ZZ object: previously was raw(...), now is mpzref(...).
1073 //     Plenty of calls had to be altered.
1074 //
1075 // Revision 1.7  2004/10/29 16:14:42  cocoa
1076 // -- changed PPOrdering calls to OrdvArith
1077 // -- new default monoid: NewPPMonoidSafe with NewStdDegRevLexOrdering
1078 //
1079 // Revision 1.5  2004/07/27 16:03:39  cocoa
1080 // Added IsCommutative test and IamCommutative member function
1081 // to all rings.  Tidied geobuckets a little.
1082 //
1083 // Revision 1.4  2004/07/20 15:37:08  cocoa
1084 // Minor fix for some errors which slipped through the net...
1085 //
1086 // Revision 1.3  2004/07/20 15:04:06  cocoa
1087 // The next step in the new "ring element" conversion process:
1088 // handling the case of creating a "const RefRingElem" object
1089 // (since C++ refuses to do this properly itself).
1090 //
1091 // Revision 1.2  2004/07/16 10:11:34  cocoa
1092 // -- now using the new class SmallFpImpl (or SmallFpLogImpl)
1093 // -- updated with "my" coding convenctions
1094 // -- NYI: LC and LCRaw
1095 //
1096 // Revision 1.1  2004/06/25 16:03:06  cocoa
1097 // -- first import
1098 //
1099