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