1 #ifndef CoCoA_PPMonoid_H
2 #define CoCoA_PPMonoid_H
3 
4 //   Copyright (c)  2001-2017  John Abbott and Anna M. Bigatti
5 //   Author:  2001-2010  John Abbott
6 
7 //   This file is part of the source of CoCoALib, the CoCoA Library.
8 
9 //   CoCoALib is free software: you can redistribute it and/or modify
10 //   it under the terms of the GNU General Public License as published by
11 //   the Free Software Foundation, either version 3 of the License, or
12 //   (at your option) any later version.
13 
14 //   CoCoALib is distributed in the hope that it will be useful,
15 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
16 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 //   GNU General Public License for more details.
18 
19 //   You should have received a copy of the GNU General Public License
20 //   along with CoCoALib.  If not, see <http://www.gnu.org/licenses/>.
21 
22 
23 #include "CoCoA/PPOrdering.H"
24 #include "CoCoA/symbol.H"
25 #include "CoCoA/utils.H"
26 // #include "CoCoA/SmartPtrIRC.H" --- already included in PPOrdering.H
27 
28 // #include <iosfwd> --- already included in PPOrdering.H
29 // using std::ostream;
30 #include <vector>
31 // using std::vector;
32 
33 
34 namespace CoCoA
35 {
36 
37   class BigInt;         // fwd decl -- defined in BigInt.H
38   class DivMask;        // fwd decl -- defined in DivMask.H
39   class DivMaskRule;    // fwd decl -- defined in DivMask.H
40   class MachineInt;     // fwd decl -- defined in MachineInt.H
41   class OpenMathOutput; // fwd decl -- defined in OpenMath.H
42   class degree;         // fwd decl -- defined in degree.H
43   class matrix;         // fwd decl -- defined in matrix.H
44 
45   class PPMonoidBase; // forward declaration for SmartPtrIRC
46 
47   class PPMonoid
48   {
49   public:
PPMonoid(const PPMonoidBase * ptr)50     explicit PPMonoid(const PPMonoidBase* ptr): mySmartPtr(ptr) {}
51     // assignment disabled because SmartPtrIRC has no assignment
52     const PPMonoidBase* operator->() const { return mySmartPtr.operator->(); }  ///< Allow const member fns to be called.
53     bool operator==(const PPMonoid& PPM) const { return mySmartPtr==PPM.mySmartPtr; }
54   private: // data members
55     SmartPtrIRC<const PPMonoidBase> mySmartPtr;
56   };
57 
58 
59   // These two classes are simply wrapped void*
60 
61   class PPMonoidElemConstRawPtr
62   {
63   public:
PPMonoidElemConstRawPtr(void const * ptr)64     explicit PPMonoidElemConstRawPtr(void const* ptr): myPtr(const_cast<void*>(ptr)) {}
65     // default copy ctor, assignment, and dtor are fine
66     bool operator==(const PPMonoidElemConstRawPtr& pp) const;
67     bool operator!=(const PPMonoidElemConstRawPtr& pp) const;
myRawPtr()68     void const* myRawPtr() const { return myPtr; }
69   protected: // data member
70     void* myPtr;
71   };
72 
73   class PPMonoidElemRawPtr: public PPMonoidElemConstRawPtr
74   {
75     // NB data members are inherited from PPMonoidElemConstRawPtr
76   public:
PPMonoidElemRawPtr(void * ptr)77     explicit PPMonoidElemRawPtr(void* ptr): PPMonoidElemConstRawPtr(ptr) {}
78     // default copy ctor, assignment, and dtor are fine
myRawPtr()79     void* myRawPtr() { return myPtr; }
80   };
81 
82 
83   //---------------------------------------------------------------------------
84   // The next three classes mimic the trio of PPMonoidElem classes.
85   class ConstRefPPMonoidElem
86   {
87   protected: // data members
88     const PPMonoid myPPM;
89     PPMonoidElemRawPtr const myPPPtr;  ///< VALUE NOT OWNED BY ME, deliberately NOT PPMonoidElemConstRawPtr
90 
91     // friend accessor functions (with non-member-fn syntax)
92     friend PPMonoidElemConstRawPtr raw(const ConstRefPPMonoidElem& pp);
93     friend const PPMonoid& owner(const ConstRefPPMonoidElem& pp);
94 
95   public:
96     ConstRefPPMonoidElem(const PPMonoid& PPM, PPMonoidElemConstRawPtr rawpp);
97     // default copy ctor works OK
98     // default dtor works OK -- deliberately NOT virtual (see documentation)
99   private: // disable assignment
100     ConstRefPPMonoidElem& operator=(const ConstRefPPMonoidElem& rhs); ///< NEVER DEFINED -- assignment disabled
101   };
102 
103 
104   class RefPPMonoidElem: public ConstRefPPMonoidElem
105   {
106   protected: // data members inherited from ConstRefPPMonoidElem
107     // friend accessor functions (with non-member-fn syntax)
108     friend PPMonoidElemRawPtr raw(RefPPMonoidElem& pp);
109 
110   public:
111     RefPPMonoidElem(const PPMonoid& PPM, PPMonoidElemRawPtr rawpp);
112     // default copy ctor works OK
113     // default dtor works OK  -- deliberately NOT virtual (see documentation)
114     RefPPMonoidElem& operator=(const RefPPMonoidElem& rhs);
115     RefPPMonoidElem& operator=(const ConstRefPPMonoidElem& rhs);
116   };
117 
118 
119 
120 //   class PPMonoidElem; // fwd decl for friend decl.
121 //   class PPMonoidElemCheckVecSize
122 //   {
123 //     friend class PPMonoidElem;
124 //     PPMonoidElemCheckVecSize() {};
125 //     PPMonoidElemCheckVecSize(long NumIndets, long VecSize) { if (VecSize != NumIndets) CoCoA_THROW_ERROR(ERR::BadArraySize, "PPMonoidElem(PPM,ExpVec)"); };
126 //   };
127 
128   class PPMonoidElem: public RefPPMonoidElem
129   {
130     // NB data members inherited from ConstRefPPMonoidElem via RefPPMonoidElem
131   public:
132     explicit PPMonoidElem(const PPMonoid& Gamma);
133     PPMonoidElem(const PPMonoid& Gamma, const std::vector<long>& v);
134     PPMonoidElem(const PPMonoid& Gamma, const std::vector<BigInt>& v);
135     PPMonoidElem(const PPMonoid& Gamma, PPMonoidElemRawPtr rawToBeOwned);
136     PPMonoidElem(const PPMonoidElem& copy);
137     PPMonoidElem(const ConstRefPPMonoidElem& copy);
138     PPMonoidElem& operator=(const PPMonoidElem& rhs);
139     PPMonoidElem& operator=(const ConstRefPPMonoidElem& rhs);
140     ~PPMonoidElem();  ///< deliberately NOT virtual (see documentation)
141   };
142 
143 
144   //---------------------------------------------------------------------------
145   //  class PPMonoidBase /* ABSTRACT CLASS */
146   class PPMonoidBase: protected IntrusiveReferenceCount  /* ABSTRACT CLASS */
147   {
148     friend class SmartPtrIRC<const PPMonoidBase>; ///< morally "friend PPMonoid", so it can alter reference count
149 
150   protected:
151     PPMonoidBase(const PPOrdering& ord, const std::vector<symbol>& IndetNames);
~PPMonoidBase()152     virtual ~PPMonoidBase() {};
153   private: // disable copy ctor and assignment
154     PPMonoidBase(const PPMonoidBase& copy);       ///< NEVER DEFINED -- disable default copy ctor
155     PPMonoidBase& operator=(const PPMonoidBase&); ///< NEVER DEFINED -- disable assignment
156 
157   public:
158     typedef PPMonoidElemRawPtr RawPtr;           ///< just to save typing
159     typedef PPMonoidElemConstRawPtr ConstRawPtr; ///< just to save typing
160 
myOrdering()161     const PPOrdering& myOrdering() const { return myOrd; };
162     virtual const std::vector<PPMonoidElem>& myIndets() const = 0;                ///< std::vector whose n-th entry is n-th indet as PPMonoidElem
mySymbols()163     const std::vector<symbol>& mySymbols() const { return myIndetSymbols; }
164     virtual const symbol& myIndetSymbol(long i) const;                            ///< the symbol of the i-th indet
165     ConstRefPPMonoidElem mySymbolValue(const symbol& s) const;                    ///< returns the PPMonoidElem corresponding to sym
166 
167     virtual const PPMonoidElem& myOne() const = 0;
168     virtual PPMonoidElemRawPtr myNew() const = 0;                                 ///< ctor from nothing
169     virtual PPMonoidElemRawPtr myNew(PPMonoidElemConstRawPtr rawpp) const = 0;    ///< ctor from another pp
170     virtual PPMonoidElemRawPtr myNew(const std::vector<long>& v) const = 0;       ///< ctor from exp vector
171     PPMonoidElemRawPtr myNewCheckVecSize(const std::vector<long>& v) const;       ///< ctor (with check) from exp vector
172     virtual PPMonoidElemRawPtr myNew(const std::vector<BigInt>& v) const;         ///< ctor from exp vector (default goes via vector<long>)
173     PPMonoidElemRawPtr myNewCheckVecSize(const std::vector<BigInt>& v) const;     ///< ctor (with check) from exp vector
174 
175     virtual void myDelete(RawPtr rawpp) const = 0;                                ///< dtor, frees pp
176     virtual void mySwap(RawPtr rawpp1, RawPtr rawpp2) const = 0;                  ///< swap(pp1, pp2)
177     virtual void myAssignOne(RawPtr rawpp) const = 0;                             ///< pp = 1
178     virtual void myAssign(RawPtr rawpp, ConstRawPtr rawpp1) const = 0;            ///< pp = pp1
179     virtual void myAssign(RawPtr rawpp, const std::vector<long>& v) const = 0;    ///< pp = v (assign from exp vector)
180     virtual void myMul(RawPtr rawpp, ConstRawPtr rawpp1, ConstRawPtr rawpp2) const = 0; ///< pp = pp1*pp2
181     virtual void myMulIndetPower(RawPtr rawpp, long var, long exp) const = 0;     ///< pp *= indet(var)^exp, assumes exp >= 0
182     virtual void myMulIndetPower(RawPtr rawpp, long var, const BigInt& EXP) const;    ///< pp *= indet(var)^EXP, NOT PURE
183     virtual void myDiv(RawPtr rawpp, ConstRawPtr rawpp1, ConstRawPtr rawpp2) const = 0; ///< pp = pp1/pp2, assumes the quotient exists
184     virtual void myColon(RawPtr rawpp, ConstRawPtr rawpp1, ConstRawPtr rawpp2) const = 0;///< pp = pp1/gcd(pp1,pp2)
185     virtual void myGcd(RawPtr rawpp, ConstRawPtr rawpp1, ConstRawPtr rawpp2) const = 0; ///< pp = gcd(pp1,pp2)
186     virtual void myLcm(RawPtr rawpp, ConstRawPtr rawpp1, ConstRawPtr rawpp2) const = 0; ///< pp = lcm(pp1,pp2)
187     virtual void myRadical(RawPtr rawpp, ConstRawPtr rawpp1) const = 0;           ///< pp = radical(pp1)
188     void myPower(RawPtr rawpp, ConstRawPtr rawpp1, long exp) const;               ///< pp = pp1^exp, assumes exp >= 0
189     void myPower(RawPtr rawpp, ConstRawPtr rawpp1, const BigInt& EXP) const;          ///< pp = pp1^EXP, assumes EXP >= 0
190     virtual void myPowerSmallExp(RawPtr rawpp, ConstRawPtr rawpp1, long exp) const = 0;// pp = pp1^exp (non-trivial), assumes exp >= 0
191     virtual void myPowerBigExp(RawPtr rawpp, ConstRawPtr rawpp1, const BigInt& EXP) const; ///< pp = pp1^EXP (non-triv, EXP large); default gives error
192     virtual void myPowerOverflowCheck(ConstRawPtr rawpp1, long exp) const = 0;    ///< throw if pp1^exp would overflow, assumes exp >= 0
193 
194     virtual bool myIsOne(ConstRawPtr rawpp) const = 0;                            ///< is pp = 1?
195     virtual bool myIsIndet(long& index, ConstRawPtr rawpp) const = 0;             ///< true iff pp is an indet
196     virtual bool myIsIndetPosPower(long& index, BigInt& EXP, ConstRawPtr rawpp) const; ///< true iff pp is a positive power of an indet
197     virtual bool myIsIndetPosPower(long& index, long& pow, ConstRawPtr rawpp) const; ///< true iff pp is a positive power of an indet and the exponent fits into a long (no checks!)
198     virtual bool myIsIndetPosPower(ConstRawPtr rawpp) const; ///< true iff pp is a positive power of an indet (no checks!)
199     virtual bool myIsCoprime(ConstRawPtr rawpp1, ConstRawPtr rawpp2) const = 0;   ///< are pp1, pp2 coprime?
200     virtual bool myIsEqual(ConstRawPtr rawpp1, ConstRawPtr rawpp2) const;         ///< is pp1 equal to pp2?
201     virtual bool myIsDivisible(ConstRawPtr rawpp1, ConstRawPtr rawpp2) const = 0; ///< is pp1 divisible by pp2?
202     virtual bool myIsSqFree(ConstRawPtr rawpp) const = 0;                         ///< is pp equal to its radical?
203 
204     virtual int myCmp(ConstRawPtr rawpp1, ConstRawPtr rawpp2) const = 0;          ///< <0, =0, >0 as pp1 < = > pp2
205     //    virtual int myHomogCmp(ConstRawPtr rawt1, ConstRawPtr rawt2) const = 0;   ///< <0, =0, >0 as t1 < = > t2 assuming t1 and t2 have same multi-degree
206     //    virtual int myHomogDegRevLex(ConstRawPtr rawt1, ConstRawPtr rawt2) const = 0; ///< <0, =0, >0 as t1 < = > t2 ??? degrevlex assuming t1 and t2 have same multi-degree TO BE REMOVED
207 
208     virtual long myStdDeg(ConstRawPtr rawpp) const = 0;                           ///< standard degree of pp
209     virtual void myWDeg(degree& d, ConstRawPtr rawpp) const = 0;                  ///< d = grading(pp)
210     virtual int myCmpWDeg(ConstRawPtr rawpp1, ConstRawPtr rawpp2) const = 0;      ///< <0, =0, >0 as wdeg(pp1) < = > wdeg(pp2)
211     virtual int myCmpWDegPartial(ConstRawPtr rawpp1, ConstRawPtr rawpp2, long n) const = 0;      ///< <0, =0, >0 as wdeg(pp1) < = > wdeg(pp2) wrt the first n rows of weights
212     virtual long myExponent(ConstRawPtr rawpp, long i) const = 0;                 ///< exponent of ith indet in pp
213     virtual void myBigExponent(BigInt& EXP, ConstRawPtr rawpp, long i) const = 0; ///< EXP = degree of ith indet in pp
214 
215     virtual void myExponents(std::vector<long>& v, ConstRawPtr rawpp) const = 0;  ///< get exponents, SHOULD BE vector<BigInt> ????
216     virtual void myBigExponents(std::vector<BigInt>& v, ConstRawPtr rawpp) const = 0;  ///< get exponents, SHOULD BE myExponents ???
217     virtual void myIndetsIn(std::vector<bool>& v, ConstRawPtr rawpp) const = 0;   ///< v[i] = true if i-th indet has exponent != 0
218     virtual void myComputeDivMask(DivMask& dm, const DivMaskRule& DivMaskImpl, ConstRawPtr rawpp) const = 0; ///< computes the DivMask for pp according to DivMaskImpl
219     virtual void myOutputSelf(std::ostream& out) const = 0;                       ///< print value of PPMonoid
220 //???    virtual void myOutputSelf(OpenMathOutput& OMOut) const = 0;              ///< print OpenMath value of PPMonoid
221     virtual void myOutput(std::ostream& out, ConstRawPtr rawpp) const;            ///< NOT PURE!!
222     virtual void myOutput(OpenMathOutput& OMOut, ConstRawPtr rawpp) const;        ///< NOT PURE!!
223 
224   protected: // data members (common to all PPOrdering implementations)
225     const PPOrdering myOrd;
226     const std::vector<symbol> myIndetSymbols;
227     const long myNumIndets;
228     friend long NumIndets(const PPMonoid& M);
229   };
230 
231   const std::vector<PPMonoidElem>& indets(const PPMonoid& PPM);      ///< std::vector whose n-th entry is n-th indet as PPMonoidElem
232   const symbol& IndetSymbol(const PPMonoid& PPM, long idx);
233   const std::vector<symbol>& symbols(const PPMonoid& PPM);                  ///< std::vector of the symbols in PPM
234   ConstMatrixView OrdMat(const PPMonoid& M);
235   ConstMatrixView GradingMat(const PPMonoid& M);
236 
237   long StdDeg(ConstRefPPMonoidElem pp);                              ///< standard degree of pp
238   long deg(ConstRefPPMonoidElem pp);                                 ///< standard degree of pp
239   degree wdeg(ConstRefPPMonoidElem pp);                              ///< degree according to grading
240   int CmpWDeg(ConstRefPPMonoidElem pp1, ConstRefPPMonoidElem pp2);   ///< <0 =0 >0 according as wdeg(t1) < = > wdeg(t2)
241   int CmpWDegPartial(ConstRefPPMonoidElem pp1, ConstRefPPMonoidElem pp2, long n);   ///< <0 =0 >0 according as wdeg(t1) < = > wdeg(t2) wrt the first n rows of weights
242   long exponent(ConstRefPPMonoidElem pp, long var);                  ///< exponent in pp of indet of index var
243   BigInt BigExponent(ConstRefPPMonoidElem pp, long var);                  ///< exponent in pp of indet of index var
244   void exponents(std::vector<long>& v, ConstRefPPMonoidElem pp);     ///< SHOULD BE vector<BigInt> ????
245   void BigExponents(std::vector<BigInt>& v, ConstRefPPMonoidElem pp);     ///< SHOULD BE exponents? should return the vector ????
246   void swap(RefPPMonoidElem pp1, RefPPMonoidElem pp2);               ///< swap(t1, t2);
247 
248   // comparisons
249   bool IsOne(ConstRefPPMonoidElem pp);
250   bool IsIndet(long& index, ConstRefPPMonoidElem pp);
251   bool IsIndet(ConstRefPPMonoidElem pp);
252   bool IsIndetPosPower(long& index, BigInt& exp, ConstRefPPMonoidElem pp);
253   bool IsIndetPosPower(long& index, long& exp, ConstRefPPMonoidElem pp);
254   bool IsIndetPosPower(ConstRefPPMonoidElem pp);
255   int cmp(ConstRefPPMonoidElem pp1, ConstRefPPMonoidElem pp2);         ///< <0, =0, >0 as pp1 < = > pp2
256   bool operator==(ConstRefPPMonoidElem pp1, ConstRefPPMonoidElem pp2); ///< pp1 == pp2;
257   bool operator!=(ConstRefPPMonoidElem pp1, ConstRefPPMonoidElem pp2); ///< pp1 != pp2;
258   bool operator<(ConstRefPPMonoidElem pp1, ConstRefPPMonoidElem pp2);  ///< pp1 < pp2;
259   bool operator<=(ConstRefPPMonoidElem pp1, ConstRefPPMonoidElem pp2); ///< pp1 <= pp2;
260   bool operator>(ConstRefPPMonoidElem pp1, ConstRefPPMonoidElem pp2);  ///< pp1 > pp2;
261   bool operator>=(ConstRefPPMonoidElem pp1, ConstRefPPMonoidElem pp2); ///< pp1 => pp2;
262 
263   std::ostream& operator<<(std::ostream& out, const PPMonoid& PPM);
264   std::ostream& operator<<(std::ostream& out, ConstRefPPMonoidElem pp);
265   OpenMathOutput& operator<<(OpenMathOutput& OMOut, ConstRefPPMonoidElem t);
266 
267 
268   // arithmetic
269   PPMonoidElem operator*(ConstRefPPMonoidElem pp1, ConstRefPPMonoidElem pp2); ///< pp1*pp2;
270   PPMonoidElem operator/(ConstRefPPMonoidElem pp1, ConstRefPPMonoidElem pp2); ///< pp1/pp2;
271   PPMonoidElem colon(ConstRefPPMonoidElem pp1, ConstRefPPMonoidElem pp2);     ///< pp1:pp2
272 ///??? saturation???
273   PPMonoidElem gcd(ConstRefPPMonoidElem pp1, ConstRefPPMonoidElem pp2);       ///< gcd(pp1, pp2)
274   PPMonoidElem lcm(ConstRefPPMonoidElem pp1, ConstRefPPMonoidElem pp2);       ///< lcm(pp1, pp2)
275   PPMonoidElem radical(ConstRefPPMonoidElem pp);                              ///< radical(pp)
276   std::vector<long> IndetsIn(ConstRefPPMonoidElem pp);                        ///< list of indices of indets actually in pp
277   PPMonoidElem power(ConstRefPPMonoidElem pp, long exp);                      ///< pp^exp
278   PPMonoidElem power(ConstRefPPMonoidElem pp, const BigInt& EXP);             ///< pp^EXP
279   void PowerOverflowCheck(ConstRefPPMonoidElem pp, long exp);                 ///< pp^exp
280   PPMonoidElem root(ConstRefPPMonoidElem pp, const MachineInt& exp);          ///< pp^(1/exp)
281   bool IsPower(ConstRefPPMonoidElem pp, const MachineInt& exp);               /// true iff pp = t^exp for some t
282   bool IsCoprime(ConstRefPPMonoidElem pp1, ConstRefPPMonoidElem pp2);         ///< is gcd(pp1, pp2)=1?
283   bool IsDivisible(ConstRefPPMonoidElem pp1, ConstRefPPMonoidElem pp2);       ///< is pp1 divisible by pp2?
284   bool IsSqFree(ConstRefPPMonoidElem pp);                                     ///< is pp = radical(pp)?
285 
286   bool IsFactorClosed(const std::vector<PPMonoidElem>& S);
287 
288   void AssignOne(RefPPMonoidElem dest);
289   RefPPMonoidElem operator*=(RefPPMonoidElem dest, ConstRefPPMonoidElem t);
290   RefPPMonoidElem operator/=(RefPPMonoidElem dest, ConstRefPPMonoidElem t);
291 
292   const PPMonoidElem& indet(const PPMonoid& M, long i); ///< x[i]
293   const PPMonoidElem& indet(const PPMonoid& M, const BigInt& i); ///< x[i]
294   PPMonoidElem IndetPower(const PPMonoid& M, long var, long exp);
295   PPMonoidElem IndetPower(const PPMonoid& M, long var, const BigInt& EXP);
296 
297   PPMonoid NewPPMonoid(const std::vector<symbol>& IndetNames, const PPOrdering& ord);
298   PPMonoid NewPPMonoid(const std::vector<symbol>& IndetNames, const PPOrderingCtor& ord);
299 
300 
301   //---------------------------------------------------------------------------
302   // INLINE FUNCTIONS
303 
304   inline bool PPMonoidElemConstRawPtr::operator==(const PPMonoidElemConstRawPtr& pp) const
305   { return myPtr == pp.myPtr; }
306 
307 
308   inline bool PPMonoidElemConstRawPtr::operator!=(const PPMonoidElemConstRawPtr& pp) const
309   { return !operator==(pp); } // weird syntax
310 
311 
312   //---------------------------------------------------------------------------
313   // inline functions on PPMonoids -- the order of appearance might be important!
314 
315   inline bool operator!=(const PPMonoid& M1, const PPMonoid& M2)
316   { return !(M1 == M2); }
317 
318 
319   //----------------------------------------------------------------------
320 
one(const PPMonoid & PPM)321   inline ConstRefPPMonoidElem one(const PPMonoid& PPM)
322   { return PPM->myOne(); }
323 
324 
NumIndets(const PPMonoid & M)325   inline long NumIndets(const PPMonoid& M)
326   { return M->myNumIndets; }
327 
328 
ordering(const PPMonoid & M)329   inline const PPOrdering& ordering(const PPMonoid& M)
330   { return M->myOrdering(); }
331 
332 
GradingDim(const PPMonoid & M)333   inline long GradingDim(const PPMonoid& M)
334   { return GradingDim(ordering(M)); }
335 
336 
IsStdGraded(const PPMonoid & M)337   inline bool IsStdGraded(const PPMonoid& M)
338   { return IsStdGraded(ordering(M)); }
339 
340 
indets(const PPMonoid & PPM)341   inline const std::vector<PPMonoidElem>& indets(const PPMonoid& PPM)
342   { return PPM->myIndets(); }
343 
344 
myIndetSymbol(long var)345   inline const symbol& PPMonoidBase::myIndetSymbol(long var) const
346   {
347     CoCoA_ASSERT(0 <= var && var < len(myIndetSymbols));
348     return myIndetSymbols[var];
349   }
350 
351 
ConstRefPPMonoidElem(const PPMonoid & PPM,PPMonoidElemConstRawPtr rawpp)352   inline ConstRefPPMonoidElem::ConstRefPPMonoidElem(const PPMonoid& PPM, PPMonoidElemConstRawPtr rawpp):
353       myPPM(PPM), myPPPtr(const_cast<void*>(rawpp.myRawPtr()))
354   {}
355 
356 
RefPPMonoidElem(const PPMonoid & PPM,PPMonoidElemRawPtr rawpp)357   inline RefPPMonoidElem::RefPPMonoidElem(const PPMonoid& PPM, PPMonoidElemRawPtr rawpp):
358       ConstRefPPMonoidElem(PPM, rawpp)
359   {}
360 
361 
owner(const ConstRefPPMonoidElem & rawpp)362   inline const PPMonoid& owner(const ConstRefPPMonoidElem& rawpp)
363   { return rawpp.myPPM; }
364 
365 
raw(RefPPMonoidElem & rawpp)366   inline PPMonoidElemRawPtr raw(RefPPMonoidElem& rawpp)
367   { return rawpp.myPPPtr; }
368 
369 
raw(const ConstRefPPMonoidElem & rawpp)370   inline PPMonoidElemConstRawPtr raw(const ConstRefPPMonoidElem& rawpp)
371   { return rawpp.myPPPtr; }
372 
373 
374 } // end of namespace CoCoA
375 
376 
377 
378 // RCS header/log in the next few lines
379 // $Header: /Volumes/Home_1/cocoa/cvs-repository/CoCoALib-0.99/include/CoCoA/PPMonoid.H,v 1.35 2020/06/17 15:49:20 abbott Exp $
380 // $Log: PPMonoid.H,v $
381 // Revision 1.35  2020/06/17 15:49:20  abbott
382 // Summary: Changed CoCoA_ERROR into CoCoA_THROW_ERROR
383 //
384 // Revision 1.34  2020/02/14 12:20:43  abbott
385 // Summary: Renamed indets(PP) to IndetsIn(PP)
386 //
387 // Revision 1.33  2017/12/01 17:13:38  bigatti
388 // -- myOrdering inline code is now within the class definition
389 //
390 // Revision 1.32  2016/11/03 12:25:24  abbott
391 // Summary: Changed IsRadical (for PPMonoidElem) into IsSqFree
392 //
393 // Revision 1.31  2015/11/30 21:53:55  abbott
394 // Summary: Major update to matrices for orderings (not yet complete, some tests fail)
395 //
396 // Revision 1.30  2015/06/30 12:52:13  abbott
397 // Summary: Added new fns myPowerOverflowCheck and myIndetsIn
398 // Author: JAA
399 //
400 // Revision 1.29  2015/04/13 14:42:07  abbott
401 // Summary: Added myPowerOverflowCheck (1st version)
402 // Author: JAA
403 //
404 // Revision 1.28  2014/07/31 13:10:46  bigatti
405 // -- GetMatrix(PPO) --> OrdMat(PPO)
406 // -- added OrdMat and GradingMat to PPOrdering, PPMonoid, SparsePolyRing
407 //
408 // Revision 1.27  2014/07/03 15:36:35  abbott
409 // Summary: Cleaned up impl of PPMonoids: moved myIndetSymbols & myNumIndets to base class
410 // Author: JAA
411 //
412 // Revision 1.26  2014/02/25 16:27:57  abbott
413 // Summary: Added new fn IsFactorClosed
414 // Author: JAA
415 //
416 // Revision 1.25  2013/07/30 14:57:19  bigatti
417 // -- reduced empty lines
418 // -- added IsStdGraded
419 //
420 // Revision 1.24  2013/05/31 09:15:43  abbott
421 // Improved a comment.
422 //
423 // Revision 1.23  2012/04/17 19:55:40  abbott
424 // Added 2 new fns: root and IsPower.
425 //
426 // Revision 1.22  2012/02/10 17:07:28  abbott
427 // Added pseudo-ctor mem fn myNew(vector<BigInt>), and some related fns.
428 // Added new fn indets.
429 //
430 // Revision 1.21  2011/08/14 15:52:18  abbott
431 // Changed ZZ into BigInt (phase 1: just the library sources).
432 //
433 // Revision 1.20  2011/06/23 16:05:55  abbott
434 // Improved a comment.
435 //
436 // Revision 1.19  2011/03/22 15:26:46  bigatti
437 // -- added myIsIndetPosPower/IsIndetPosPower
438 //
439 // Revision 1.18  2011/03/16 15:18:48  bigatti
440 // -- added IsIndet(pp), IsIndetPosPower(pp)
441 //
442 // Revision 1.17  2011/03/10 16:39:35  abbott
443 // Replaced (very many) size_t by long in function interfaces (for rings,
444 // PPMonoids and modules).  Also replaced most size_t inside fn defns.
445 //
446 // Revision 1.16  2010/11/30 11:18:11  bigatti
447 // -- renamed IndetName --> IndetSymbol
448 //
449 // Revision 1.15  2010/11/25 09:31:01  bigatti
450 // -- forward declaration --> fwd decl
451 //
452 // Revision 1.14  2010/11/05 16:21:08  bigatti
453 // -- added ZZExponents
454 //
455 // Revision 1.13  2010/11/02 16:03:12  bigatti
456 // -- added indet(*, ZZ) [for CoCoA-5]
457 // -- indet(PPM, i) now returns "const PPMonoidElem&"
458 //
459 // Revision 1.12  2010/10/01 15:20:33  bigatti
460 // -- added mySymbolValue
461 // -- added RingElem(R, sym)
462 //
463 // Revision 1.11  2010/02/03 16:13:52  abbott
464 // Added new single word tags for specifying the ordering in PPMonoid
465 // pseudo-ctors.
466 //
467 // Revision 1.10  2010/02/03 12:11:08  bigatti
468 // -- added myIsIndetPosPower with exponent variable of type long
469 //    (no checks for overflow)
470 //
471 // Revision 1.9  2010/02/02 16:44:31  abbott
472 // Added radical & IsRadical (via mem fns myRadical & myIsRadical)
473 // for PPMonoidElems.
474 //
475 // Revision 1.8  2009/11/26 16:12:29  bigatti
476 // -- commented out some includes
477 //
478 // Revision 1.7  2009/09/22 14:01:33  bigatti
479 // -- added myCmpWDegPartial (ugly name, I know....)
480 // -- cleaned up and realigned code in PPMonoid*.C files
481 //
482 // Revision 1.6  2008/10/07 12:18:29  abbott
483 // Added deg function, same as StdDeg.
484 //
485 // Revision 1.5  2007/12/05 11:06:24  bigatti
486 // -- changed "size_t StdDeg/myStdDeg(f)" into "long"  (and related functions)
487 // -- changed "log/myLog(f, i)" into "MaxExponent/myMaxExponent(f, i)"
488 // -- fixed bug in "IsOne(ideal)" in SparsePolyRing.C
489 //
490 // Revision 1.4  2007/12/04 14:27:07  bigatti
491 // -- changed "log(pp, i)" into "exponent(pp, i)"
492 //
493 // Revision 1.3  2007/10/30 17:14:12  abbott
494 // Changed licence from GPL-2 only to GPL-3 or later.
495 // New version for such an important change.
496 //
497 // Revision 1.2  2007/09/24 14:15:16  abbott
498 // Renamed IsIndetPower to IsIndetPosPower.
499 // Changed layout of some comments.
500 //
501 // Revision 1.1.1.1  2007/03/09 15:16:11  abbott
502 // Imported files
503 //
504 // Revision 1.14  2007/03/08 18:42:06  cocoa
505 // Cleaned up whitespace.
506 //
507 // Revision 1.13  2007/03/08 17:43:11  cocoa
508 // Swapped order of args to the NewPPMonoid pseudo ctors.
509 //
510 // Revision 1.12  2007/01/11 14:06:15  cocoa
511 // -- added prefix "raw" to RawPtr arguments names
512 //
513 // Revision 1.11  2006/12/06 17:32:24  cocoa
514 // -- removed #include "config.H"
515 //
516 // Revision 1.10  2006/11/24 17:26:22  cocoa
517 // -- reorganized includes of header files
518 // -- doxygen style comments
519 //
520 // Revision 1.9  2006/11/23 17:35:48  cocoa
521 // -- changed: PPMonoid is now a class (instead of typedef)
522 //
523 // Revision 1.8  2006/11/22 14:53:46  cocoa
524 // -- changed: PPMonoid defined as class (instead of typedef)
525 //
526 // Revision 1.7  2006/11/03 15:37:47  cocoa
527 // -- cleaned up code after testing on usage of SmartPtrIRC
528 //
529 // Revision 1.6  2006/11/03 14:01:46  cocoa
530 // -- changed: reference counting in ring, PPMonoids and OrdvArith now
531 //    uses SmartPtrIRC
532 //
533 // Revision 1.5  2006/11/02 13:25:44  cocoa
534 // Simplification of header files: the OpenMath classes have been renamed.
535 // Many minor consequential changes.
536 //
537 // Revision 1.4  2006/10/06 14:04:15  cocoa
538 // Corrected position of #ifndef in header files.
539 // Separated CoCoA_ASSERT into assert.H from config.H;
540 // many minor consequential changes (have to #include assert.H).
541 // A little tidying of #include directives (esp. in Max's code).
542 //
543 // Revision 1.3  2006/10/06 10:08:58  cocoa
544 // Corrected a comment.
545 //
546 // Revision 1.2  2006/08/07 21:23:25  cocoa
547 // Removed almost all publicly visible references to SmallExponent_t;
548 // changed to long in all PPMonoid functions and SparsePolyRing functions.
549 // DivMask remains to sorted out.
550 //
551 // Revision 1.1.1.1  2006/05/30 11:39:37  cocoa
552 // Imported files
553 //
554 // Revision 1.11  2006/05/12 16:10:58  cocoa
555 // Added OpenMathFwd.H, and tidied OpenMath.H.
556 // Many consequential but trivial changes.
557 //
558 // Revision 1.10  2006/04/21 14:59:22  cocoa
559 // Changed return type of indet(PPM, i) to ConstRefPPMonoidElem
560 // instead of PPMonoidElem (which made a copy).
561 //
562 // Revision 1.9  2006/03/27 12:21:26  cocoa
563 // Minor silly changes to reduce number of complaints from some compiler or other.
564 //
565 // Revision 1.8  2006/03/15 18:09:31  cocoa
566 // Changed names of member functions which print out their object
567 // into myOutputSelf -- hope this will appease the Intel C++ compiler.
568 //
569 // Revision 1.7  2006/03/12 21:28:34  cocoa
570 // Major check in after many changes
571 //
572 // Revision 1.6  2006/03/07 10:08:48  cocoa
573 // -- fixed: PPMonoidElem(const ConstRefPPMonoidElem& copy);  [added const]
574 //
575 // Revision 1.5  2006/02/20 22:41:20  cocoa
576 // All forms of the log function for power products now return SmallExponent_t
577 // (instead of int).  exponents now resizes the vector rather than requiring
578 // the user to pass in the correct size.
579 //
580 // Revision 1.4  2006/02/01 16:56:13  cocoa
581 // Added some missing assignment operators for (Ref)PPMonoidElems.
582 //
583 // Revision 1.3  2006/01/17 10:23:08  cocoa
584 // Updated DivMask; many consequential changes.
585 // A few other minor fixes.
586 //
587 // Revision 1.2  2005/11/17 15:43:04  cocoa
588 // -- added ctor PPMonoidElem(ConstRefPPMonoidElem& copy);
589 //
590 // Revision 1.1.1.1  2005/10/17 10:46:54  cocoa
591 // Imported files
592 //
593 // Revision 1.7  2005/08/08 16:36:33  cocoa
594 // Just checking in before going on holiday.
595 // Don't really recall what changes have been made.
596 // Added IsIndet function for RingElem, PPMonoidElem,
597 // and a member function of OrdvArith.
598 // Improved the way failed assertions are handled.
599 //
600 // Revision 1.6  2005/07/19 15:30:20  cocoa
601 // A first attempt at iterators over sparse polynomials.
602 // Main additions are to SparsePolyRing, DistrMPoly*.
603 // Some consequential changes to PPMonoid*.
604 //
605 // Revision 1.5  2005/07/08 15:09:29  cocoa
606 // Added new symbol class (to represent names of indets).
607 // Integrated the new class into concrete polynomial rings
608 // and PPMonoid -- many consequential changes.
609 // Change ctors for the "inline" sparse poly rings: they no
610 // longer expect a PPMonoid, but build their own instead
611 // (has to be a PPMonoidOv).
612 //
613 // Revision 1.4  2005/07/01 16:08:16  cocoa
614 // Friday check-in.  Major change to structure under PolyRing:
615 // now SparsePolyRing and DUPolyRing are separated (in preparation
616 // for implementing iterators).
617 //
618 // A number of other relatively minor changes had to be chased through
619 // (e.g. IndetPower).
620 //
621 // Revision 1.3  2005/06/23 15:42:41  cocoa
622 // Fixed typo in GNU fdl -- all doc/*.txt files affected.
623 // Minor corrections to PPMonoid (discovered while writing doc).
624 //
625 // Revision 1.2  2005/06/22 14:47:56  cocoa
626 // PPMonoids and PPMonoidElems updated to mirror the structure
627 // used for rings and RingElems.  Many consequential changes.
628 //
629 // Revision 1.1.1.1  2005/05/03 15:47:30  cocoa
630 // Imported files
631 //
632 // Revision 1.3  2005/04/29 15:42:02  cocoa
633 // Improved documentation for GMPAllocator.
634 // Added example program for GMPAllocator.
635 // Added example program for simple ops on polynomials.
636 // Added two new ctors for (principal) ideals (from long, and from ZZ).
637 // Added (crude) printing for PPMonoids.
638 // Updated library.H (#included GMPAllocator.H).
639 //
640 // Revision 1.2  2005/04/19 14:06:04  cocoa
641 // Added GPL and GFDL licence stuff.
642 //
643 // Revision 1.1.1.1  2005/01/27 15:12:13  cocoa
644 // Imported files
645 //
646 // Revision 1.14  2004/11/25 16:14:21  cocoa
647 // (1) Fixed definition of specialization of std::swap template function
648 //     so that it compiles with gcc 3.4.3
649 // (2) Implemented monomial function for polynomial rings.
650 // (3) Added one(PPM) and PPM->myOne() functions.
651 //
652 // Revision 1.13  2004/11/11 13:41:14  cocoa
653 // -- moved CoCoA includes to the top
654 //
655 // Revision 1.12  2004/11/08 14:03:32  cocoa
656 // -- small changes for doxygen support
657 //
658 // Revision 1.11  2004/11/02 14:56:33  cocoa
659 // -- changed *Print* into *Output* (myPrint --> myOutput)
660 // -- changed *Var* into *Indet* (myPrintVarName --> myOutputIndetName)
661 // -- removed suffix "IgnoreDivMask"
662 // -- added myComputeDivMask
663 // -- improved storing of IndetNames
664 // -- changed ExpvElem into SmallExponent_t
665 //
666 // Revision 1.10  2004/10/29 16:11:10  cocoa
667 // -- new type   PPMonoidEvOv_entry;
668 // -- function IsDivisible had wrong semantics --> swapped arguments everywhere
669 //
670 // Revision 1.9  2004/10/21 17:16:37  cocoa
671 // Fairly major change: new OrdvArith namspace with various members,
672 //   new global typedef  SmallExponent_t (defined in config.H).
673 //
674 // Revision 1.8  2004/06/30 16:46:06  cocoa
675 // End of day check-in: mostly tidying up, and correcting some
676 // overly lax access permissions.
677 //
678 // Revision 1.7  2004/06/29 17:10:22  cocoa
679 // Partially tidied use of "protected" and "private" in various
680 // base classes.  Checking in at the end of the day -- it works,
681 // and I wouldn't want it to be lost next time point's disk
682 // misbehaves.
683 //
684 // Revision 1.6  2004/05/27 16:14:02  cocoa
685 // Minor revision for new coding conventions.
686 //
687 // Revision 1.5  2004/05/24 15:52:14  cocoa
688 // Major update:
689 //   new error mechanism
690 //   many fixes
691 //   RingHoms almost work now
692 //   RingFloat much improved
693 //
694 // Revision 1.4  2004/03/20 17:46:10  cocoa
695 // Check in prior to departure to RWCA
696 //
697 // Revision 1.3  2004/01/28 15:20:36  cocoa
698 // Added CmpDeg function and myCmpDeg member function.
699 // Aligned name of data member of PPMonoid with the convention used
700 // for the data member of ring.
701 //
702 // Revision 1.2  2003/10/01 10:35:31  cocoa
703 // - applied "my" coding convention to PPMonoid and PPOrdering
704 //
705 // Revision 1.1.1.1  2003/09/24 12:55:43  cocoa
706 // Imported files
707 //
708 // Revision 1.22  2003/09/23 16:59:33  bigatti
709 // - added PPMonoidDiv_entry* in RawPP
710 //
711 // Revision 1.21  2003/06/23 16:56:59  abbott
712 // Minor cleaning prior to public release.
713 //
714 // Revision 1.20  2003/05/14 16:38:54  abbott
715 // Changed name of assign1 to AssignOne.
716 // Added new member functions PPMonoidBase::IsOne, IsOneIgnoreDivMask,
717 // IsEqual, and IsEqualIgnoreDivMask (following the pattern of
718 // IsDivisible).
719 // Added PPMonoidBase::ZeroRefCount.
720 // Added inline definitions of IsOne and IsEqual.
721 //
722 // Revision 1.19  2003/04/29 13:59:29  abbott
723 // Uh oh.  Lots of changes.  Checking in prior to restructuring
724 // to align with new PPOrdering code.
725 //
726 // Revision 1.18  2003/01/15 15:58:39  abbott
727 // Checking in prior to major change.
728 // Minor changes:
729 //   coprime has become AreCoprime,
730 //   divides has become IsDivisible,
731 //   new member fn IsDivisibleIgnoreDivMask,
732 //   signature of deg has changed (now produces values of type degree)
733 //
734 // Revision 1.17  2002/11/15 16:24:50  abbott
735 // MAJOR CHANGE reflecting a new "philosophy".
736 // The new philosophy is that PPMonoid::elems will be "slow and safe" since
737 // they are now higly decoupled from the internal representation of
738 // polynomials (which use "order vectors").
739 // Eliminated HalfPP, alias and temp subclasses.
740 // Every RawPP now contains its own "divisibility mask" because Anna needs
741 // the DivMask check to be inline.
742 //
743 // Revision 1.16  2002/06/22 17:15:14  abbott
744 // Numerous changes to accommodate the new idea of PPOrdering.
745 //
746 // Revision 1.15  2002/03/06 11:22:38  abbott
747 // Added stubs for two new comparison functions (implemented via
748 // member functions) to allow comparison between a RawPP and a
749 // HalfPP, and between two HalfPPs.
750 //
751 // Revision 1.14  2002/02/08 12:07:22  abbott
752 // MAJOR CHANGE: added two new proxy classes "alias" and "temp" (see PP.txt)
753 // Numerous consequential changes.  Changed order of some declarations.
754 //
755 // Revision 1.13  2002/01/30 14:18:19  abbott
756 // Replaced VarName function by PrintVarName; simplifies maintaining backward
757 // compatibility with gcc 2.95, and may even be slightly easier to use.
758 // Added owner(...) and raw(..) functions for PPMonoid::elem objects.
759 //
760 // Revision 1.12  2002/01/10 17:04:39  abbott
761 // Revised names of two of the members of the RawPP union to
762 // concord with their implementations.  The new names also
763 // make more sense than the old ones.
764 //
765 // Revision 1.11  2002/01/09 14:32:40  abbott
766 // Added/corrected HalfPP type and operations.
767 //
768 // Revision 1.10  2001/12/12 18:32:23  bigatti
769 // - HalfMul and OtherHalfMul
770 //
771 // Revision 1.9  2001/12/07 18:17:46  abbott
772 // Added field cpctexp in RawPP for PP_compact values.
773 // The field needs a better name.
774 //
775 // Revision 1.8  2001/12/05 15:18:40  abbott
776 // Act first, think later...  Fixed another copy of the name of struct PPMonoid_DenseUniq.
777 //
778 // Revision 1.7  2001/12/05 15:17:46  abbott
779 // Corrected name of struct PPmonoid_DenseUniq_entry.
780 //
781 // Revision 1.6  2001/12/04 19:53:08  abbott
782 // Names changed in accordance with new coding standards.
783 // (public) Function NumVars is now a non-member (but calls a private member
784 // function to allow inheritance to work as desired).
785 //
786 // Revision 1.5  2001/11/19 15:27:24  abbott
787 // Added support for "compact_uniq" PP implementation:
788 //   one forward declaration of a struct,
789 //   a new field to the PPmonoid::raw_elem union.
790 //
791 // Revision 1.4  2001/11/16 18:40:00  bigatti
792 // added: <iostream> and std::
793 // for compatibility with gcc-3
794 //
795 // Revision 1.3  2001/11/05 18:13:29  abbott
796 // Added homogeneous PP comparison functions: i.e. assuming two PPs have the
797 // same (multi)degree it compares the PPs using the monoid's ordering.
798 //
799 // Anna also wanted an explicit homog_degrevlex; JAA hopes this function will
800 // eventually disappear, though it may be needed for efficiency reasons.
801 //
802 // The names homog_cmp and homog_degrevlex are too cumbersome.
803 //
804 // Revision 1.2  2001/10/31 20:25:56  abbott
805 // MAIN CHANGE:
806 //   PPmonoid::raw_elem is now a union of the different types it can hold
807 //   rather than a void*.  JAA is not sure if it is really cleaner to use
808 //   a union than a void* (with casting), but the compiler gave enough
809 //   problems to make the change worthwhile.  Furthermore, a union does
810 //   give some extra checks/restrictions on what can be done to raw_elem.
811 //   One significant difficulty was producing an l-value when using a
812 //   (reinterpret) cast hidden inside a file static inline function.
813 //   Also it is easier to debug with unions since the debugger will allow
814 //   field selection in unions -- reinterpret_casts were a headache.
815 //
816 // The "copy constructor" for a PPmonoid::elem was altered to require a const
817 // copy (previously the const was missing).
818 //
819 // Revision 1.1  2001/10/25 17:53:53  abbott
820 // Initial revision
821 //
822 
823 #endif
824