CoCoALib-0.9905 date: 23 May 2007


ring.H

Go to the documentation of this file.
00001 #ifndef CoCoA_ring_H
00002 #define CoCoA_ring_H
00003 
00004 //   Copyright (c)  2005  John Abbott
00005 
00006 //   This file is part of the source of CoCoALib, the CoCoA Library.
00007 
00008 //   CoCoALib is free software; you can redistribute it and/or modify
00009 //   it under the terms of the GNU General Public License (version 2)
00010 //   as published by the Free Software Foundation.  A copy of the full
00011 //   licence may be found in the file COPYING in this directory.
00012 
00013 //   CoCoALib is distributed in the hope that it will be useful,
00014 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 //   GNU General Public License for more details.
00017 
00018 //   You should have received a copy of the GNU General Public License
00019 //   along with CoCoA; if not, write to the Free Software
00020 //   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021 
00022 
00023 #include "CoCoA/assert.H"
00024 #include "CoCoA/error.H"
00025 #include "CoCoA/SmartPtrIRC.H"
00026 #include "CoCoA/ZZ.H"  // for inline ZZ characteristic(ring)
00027 
00028 #include <cstddef>
00029 // using std::size_t;
00030 #include <iosfwd>
00031 // using std::ostream;
00032 #include <vector>
00033 // using std::vector;
00034 
00035 
00036 //#include <boost/shared_ptr.hpp>
00037 //#include "boost/shared_ptr.hpp"
00038 //using boost::shared_ptr;
00039 
00040 namespace CoCoA
00041 {
00042 
00043   class OpenMathOutput; // forward declaration -- defined in OpenMath.H
00044   class OpenMathInput;  // forward declaration -- defined in OpenMath.H
00045   class symbol;         // forward declaration -- defined in symbol.H
00046   class ideal;          // forward declaration -- defined in ideal.H
00047   class RingHom;        // forward declaration -- defined in RingHom.H
00048 
00049 
00050   class RingBase; // forward decl for SmartPtrIRC
00051   /*-----------------------------------------------------------------*/
00052   /** \include ring.txt  */
00053   /*-----------------------------------------------------------------*/
00054   class ring
00055   {
00056   public:
00057     explicit ring(const RingBase* RingPtr): mySmartPtr(RingPtr) {}
00058     // Default copy ctor works fine.
00059     // Assignment disabled because SmartPtrIRC has no assignment.
00060     const RingBase* operator->() const { return mySmartPtr.operator->(); }  ///< Allow const member fns to be called.
00061     const RingBase* myRawPtr() const { return mySmartPtr.myRawPtr(); } ///< Used by "downcasting" functions IsRingFp, AsRingFp, etc.
00062   private: // data members
00063     SmartPtrIRC<const RingBase> mySmartPtr;
00064   };
00065 
00066 
00067   class RingElemConstRawPtr
00068   {
00069   public:
00070     explicit RingElemConstRawPtr(void const* ptr): myPtr(ptr) {}
00071     // default copy ctor, assignment, and dtor are fine
00072     void const* myRawPtr() const { return myPtr; }
00073   private: // data members
00074     void const* myPtr;
00075   };
00076 
00077   class RingElemRawPtr: public RingElemConstRawPtr
00078   {
00079     // data members are inherited from RingElemConstRawPtr
00080   public:
00081     explicit RingElemRawPtr(void* ptr): RingElemConstRawPtr(ptr) {}
00082     // default copy ctor, assignment, and dtor are fine
00083     void* myRawPtr() { return const_cast<void*>(RingElemConstRawPtr::myRawPtr()); }
00084   };
00085 
00086 
00087   class ConstRefRingElem
00088   {
00089   private: // data members
00090     const ring myR;
00091   protected:
00092     RingElemRawPtr myValuePtr;  // VALUE NOT OWNED BY ME -- deliberately not RingElemConstRawPtr (see doc)
00093 
00094   public:
00095     ConstRefRingElem(const ring& R, RingElemConstRawPtr rawx);
00096     // default copy ctor works OK
00097     // default dtor works OK  -- deliberately NOT virtual (see documentation)
00098   private: // disable assignment
00099     ConstRefRingElem& operator=(const ConstRefRingElem& rhs); // NEVER DEFINED -- assignment disabled
00100   protected:
00101     const ring& myOwner() const { return myR; }
00102     const RingElemConstRawPtr& myRawPtr() const { return myValuePtr; } // NB implicit conversion to RingElemConstRawPtr
00103     // friend accessor functions (with non-member-fn syntax)
00104     friend const RingElemConstRawPtr& raw(const ConstRefRingElem& x);
00105     friend const ring& owner(const ConstRefRingElem& x);
00106   };
00107 
00108   class RefRingElem: public ConstRefRingElem
00109   {
00110     // data members inherited from ConstRefRingElem
00111   protected:
00112     RingElemRawPtr& myRawPtr() { return myValuePtr; }
00113     // friend accessor functions (with non-member-fn syntax)
00114     friend RingElemRawPtr& raw(RefRingElem& x);
00115 
00116   public:
00117     RefRingElem(const ring& R, RingElemRawPtr rawx): ConstRefRingElem(R, rawx) {}
00118     // default copy ctor works OK
00119     // default dtor works OK -- deliberately NOT virtual (see documentation)
00120     RefRingElem& operator=(const RefRingElem& rhs);
00121     RefRingElem& operator=(const ConstRefRingElem& rhs);
00122     RefRingElem& operator=(long n);
00123     RefRingElem& operator=(const ZZ& N);
00124   };
00125 
00126 
00127   class RingElem: public RefRingElem
00128   {
00129     // Data members inherited from RefRingElem, as are accessors.
00130     // Sole difference is that the value pointed to by myValuePtr
00131     // is OWNED by the RingElem object.
00132 
00133   public:
00134     explicit RingElem(const ring& R);
00135     RingElem(const ring& R, long n);
00136     RingElem(const ring& R, const ZZ& N);
00137     RingElem(const ring& R, const RingElemRawPtr rawx);
00138     RingElem(const RingElem& copy); // have to define this, default version is unsuitable, cannot be explicit as it is needed in function return
00139     RingElem(const ConstRefRingElem& copy); // becomes rather a hassle if made explicit
00140     ~RingElem();  ///< -- deliberately NOT virtual (see documentation)
00141     RingElem& operator=(const RingElem& rhs);
00142     RingElem& operator=(const ConstRefRingElem& rhs); // also caters for rhs being RefRingElem
00143     RingElem& operator=(long n);
00144     RingElem& operator=(const ZZ& N);
00145   };
00146 
00147 
00148   // This is a bit like an auto_ptr to a RingElem; it can surrender ownership.
00149   class AutoRingElem
00150   {
00151   private: // data members
00152     const ring myR;
00153     RingElemRawPtr myValuePtr;  // either NULL or VALUE IS OWNED BY ME
00154   public:
00155     AutoRingElem(const ring& R, RingElemRawPtr rawx);
00156     friend RingElemRawPtr raw(AutoRingElem& x);
00157     friend RingElemRawPtr release(AutoRingElem& x);
00158   private: // disable assignment and copy ctor
00159     AutoRingElem(const AutoRingElem&);            // NEVER DEFINED -- disable copy ctor
00160     AutoRingElem& operator=(const AutoRingElem&); // NEVER DEFINED -- disable assigment
00161   };
00162 
00163 
00164   class RingBase: protected IntrusiveReferenceCount   // abstract class
00165   {
00166     friend class SmartPtrIRC<const RingBase>; // Morally "friend ring", so it can alter reference count.
00167 
00168   protected: // data member
00169     friend std::size_t ID(const ring& R);
00170     static std::size_t NewRingID();
00171     const std::size_t myID; // Every concrete ring has a fixed distinct (numerical) ID.
00172 
00173   protected:
00174     RingBase();             // See inline functions below.
00175     virtual ~RingBase();    // Destructor of a base class must be virtual.
00176   private: // Disable assignment and copy ctor.
00177     RingBase(const RingBase&);            // NEVER DEFINED -- copy ctor disabled
00178     RingBase& operator=(const RingBase&); // NEVER DEFINED -- assignment disabled
00179   public:
00180     typedef RingElemConstRawPtr ConstRawPtr;  // for brevity
00181     typedef RingElemRawPtr RawPtr;            // for brevity
00182 
00183     // Functions which every ring must implement.
00184     virtual void myCharacteristic(ZZ& p) const = 0;
00185     virtual bool IamCommutative() const = 0;
00186     virtual bool IamIntegralDomain() const = 0;
00187     virtual bool IamGCDDomain() const;                              ///< Defaults to true.
00188     virtual bool IamOrderedDomain() const;                          ///< Defaults to false.
00189     virtual bool IamField() const = 0;
00190     virtual ConstRefRingElem myZero() const = 0;
00191     virtual ConstRefRingElem myOne() const = 0;
00192     virtual RingElemRawPtr myNew() const = 0;
00193     virtual RingElemRawPtr myNew(long int n) const = 0;
00194     virtual RingElemRawPtr myNew(const ZZ& N) const = 0;
00195     virtual RingElemRawPtr myNew(ConstRawPtr rawx) const = 0;
00196     virtual void myDelete(RawPtr rawx) const = 0;                      ///< destroys x (incl all resources)
00197     virtual void mySwap(RawPtr rawx, RawPtr rawy) const = 0;           ///< swap(x, y)
00198     virtual void myAssign(RawPtr rawlhs, ConstRawPtr rawx) const = 0;  ///< lhs = x
00199     virtual void myAssign(RawPtr rawlhs, long n) const = 0;            ///< lhs = n
00200     virtual void myAssign(RawPtr rawlhs, const ZZ& N) const = 0;       ///< lhs = N
00201     virtual void myAssignZero(RawPtr rawlhs) const = 0;                ///< lhs = 0
00202     virtual void myNegate(RawPtr rawlhs, ConstRawPtr rawx) const = 0;  ///< lhs = -x
00203     virtual void myAdd(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const = 0; ///< lhs = x+y
00204     virtual void mySub(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const = 0; ///< lhs = x-y
00205     virtual void myMul(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const = 0; ///< lhs = x*y
00206     virtual void myDiv(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const = 0; ///< lhs = x/y
00207     virtual bool myIsDivisible(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const = 0;///< lhs = x/y, if divisible
00208     virtual bool myIsInvertible(ConstRawPtr rawx) const;                             ///< true iff x is invertible
00209     virtual void myGcd(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const;     ///< lhs = gcd(x,y) if GCDDomain;
00210     virtual void myGcdQuot(RawPtr rawlhs, RawPtr rawxquot, RawPtr rawyquot, ConstRawPtr rawx, ConstRawPtr rawy) const; ///< lhs = gcd(x,y)  xquot = x/gcd, yquot = y/gcd  if GCDDomain;
00211     virtual void myExgcd(RawPtr rawlhs, RawPtr rawxcofac, RawPtr rawycofac, ConstRawPtr rawx, ConstRawPtr rawy) const; ///< lhs = gcd(x,y) = xcofac*x + ycofac*y  if GCDDomain;
00212     void myPower(RawPtr rawlhs, ConstRawPtr rawx, unsigned long n) const;          ///< lhs = x^n, n>=0
00213     void myPower(RawPtr rawlhs, ConstRawPtr rawx, const ZZ& N) const;              ///< lhs = x^N, N>=0
00214     virtual void mySymbols(std::vector<symbol>& SymList) const;                    ///< append symbols in ring to SymList
00215     virtual void myOutput(std::ostream& out, ConstRawPtr rawx) const = 0;          ///< out << x
00216     virtual bool myIsPrintAtom(ConstRawPtr rawx) const;                            ///< x^n may be printed without parentheses
00217     virtual bool myIsPrintedWithMinus(ConstRawPtr rawx) const;                     ///< first character of x printed is a minus sign
00218     virtual void myOutputSelf(std::ostream& out) const = 0;                        ///< out << R
00219     virtual void myOutputSelf(OpenMathOutput& OMOut) const = 0;                    ///< OMOut << R
00220     virtual void myOutput(OpenMathOutput& OMOut, ConstRawPtr rawx) const = 0;      ///< OMOut << x
00221     virtual bool myIsZero(ConstRawPtr rawx) const = 0;                             ///< x == 0
00222     virtual bool myIsOne(ConstRawPtr rawx) const = 0;                              ///< x == 1
00223     virtual bool myIsMinusOne(ConstRawPtr rawx) const;                             ///< x == -1
00224     virtual bool myIsInteger(ZZ& N, ConstRawPtr rawx) const = 0;                   ///< true iff x is integer
00225     virtual bool myIsRational(ZZ& N, ZZ& D, ConstRawPtr rawx) const = 0;           ///< true iff x is rational
00226     virtual bool myIsZeroAddMul(RawPtr rawlhs, ConstRawPtr rawy, ConstRawPtr rawz) const;   ///< lhs += y*z, result says whether lhs == 0.
00227     virtual bool myIsEqual(ConstRawPtr rawx, ConstRawPtr rawy) const = 0;          ///< x == y
00228     virtual int myCmp(ConstRawPtr rawx, ConstRawPtr rawy) const;                   ///< result is <0, =0, >0 according as x<y, x=y, x>y
00229     virtual int mySign(ConstRawPtr rawx) const;                                    ///< -1,0,+1 according as x <0,=0,>0
00230 
00231     virtual ideal myIdealCtor(const std::vector<RingElem>& gens) const = 0;
00232 
00233     virtual RingHom myCompose(const RingHom& phi, const RingHom& theta) const = 0;  ///< phi(theta(...))
00234 
00235   protected: // These are almost an implementation detail
00236     virtual void myPowerSmallExp(RawPtr rawlhs, ConstRawPtr rawx, unsigned long n) const = 0;///< lhs = x^n (non-trivial)
00237     virtual void myPowerBigExp(RawPtr rawlhs, ConstRawPtr rawx, const ZZ& N) const; ///< lhs = x^N (non-triv, N large); default gives error
00238     void mySequentialPower(RawPtr rawlhs, ConstRawPtr rawx, unsigned long n) const; ///< lhs = x^n
00239     void myBinaryPower(RawPtr rawlhs, ConstRawPtr rawx, unsigned long n) const;     ///< lhs = x^n
00240     void myBinaryPower(RawPtr rawlhs, ConstRawPtr rawx, const ZZ& N) const;         ///< lhs = x^N
00241     void myGcdInField(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const;     ///< lhs = gcd(x, y) in a field
00242   private:   // This is an implementation detail
00243     void myBinaryPowerLoop(RawPtr rawlhs, ConstRawPtr rawx, unsigned long n) const;
00244   };
00245 
00246 
00247   std::vector<symbol> symbols(const ring& R);
00248   // Some syntactic sugar for arithmetic on RingElems
00249   bool operator==(ConstRefRingElem, ConstRefRingElem);
00250   bool operator!=(ConstRefRingElem, ConstRefRingElem);
00251   RingElem operator-(ConstRefRingElem);
00252   RingElem operator+(ConstRefRingElem, ConstRefRingElem);
00253   RingElem operator-(ConstRefRingElem, ConstRefRingElem);
00254   RingElem operator*(ConstRefRingElem, ConstRefRingElem);
00255   RingElem operator/(ConstRefRingElem, ConstRefRingElem);
00256   RingElem gcd(ConstRefRingElem, ConstRefRingElem);
00257   void GcdQuot(RefRingElem gcd, RefRingElem xquot, RefRingElem yquot, ConstRefRingElem x, ConstRefRingElem y);
00258   RefRingElem operator+=(RefRingElem, ConstRefRingElem);
00259   RefRingElem operator-=(RefRingElem, ConstRefRingElem);
00260   RefRingElem operator*=(RefRingElem, ConstRefRingElem);
00261   RefRingElem operator/=(RefRingElem, ConstRefRingElem);
00262   std::ostream& operator<<(std::ostream&, ConstRefRingElem);
00263 //??? see io.H  std::ostream& operator<<(std::ostream&, const std::vector<RingElem>&);
00264   OpenMathOutput& operator<<(OpenMathOutput& OMOut, ConstRefRingElem);
00265   bool IsZero(ConstRefRingElem);
00266   bool IsOne(ConstRefRingElem);
00267   bool IsMinusOne(ConstRefRingElem);
00268   bool IsInteger(ZZ& N, ConstRefRingElem x);
00269   bool IsRational(ZZ& N, ZZ& D, ConstRefRingElem x);
00270   bool IsInvertible(ConstRefRingElem);
00271   bool IsDivisible(ConstRefRingElem, ConstRefRingElem);
00272   bool IsDivisible(long, ConstRefRingElem);
00273   bool IsDivisible(ConstRefRingElem, long);
00274   bool IsDivisible(const ZZ& N, ConstRefRingElem);
00275   bool IsDivisible(ConstRefRingElem, const ZZ& N);
00276   RingElem power(ConstRefRingElem x, long n);      ///< NB exponent may be negative
00277   RingElem power(ConstRefRingElem x, const ZZ& N); ///< NB exponent may be negative
00278   ConstRefRingElem zero(const ring& R);
00279   ConstRefRingElem one(const ring& R);
00280   std::ostream& operator<<(std::ostream& out, const ring& R);
00281   OpenMathOutput& operator<<(OpenMathOutput& OMOut, const ring& R);
00282 
00283   int sign(ConstRefRingElem x);
00284   RingElem abs(ConstRefRingElem x);
00285   int cmp(ConstRefRingElem x, ConstRefRingElem y);
00286   int cmp(ConstRefRingElem x, long n);
00287   int cmp(long n, ConstRefRingElem y);
00288   int cmp(ConstRefRingElem x, const ZZ& N);
00289   int cmp(const ZZ& N, ConstRefRingElem y);
00290   bool operator<(ConstRefRingElem x, ConstRefRingElem y);
00291   bool operator<=(ConstRefRingElem x, ConstRefRingElem y);
00292   bool operator>(ConstRefRingElem x, ConstRefRingElem y);
00293   bool operator>=(ConstRefRingElem x, ConstRefRingElem y);
00294   bool operator<(ConstRefRingElem x, long y);
00295   bool operator<=(ConstRefRingElem x, long y);
00296   bool operator>(ConstRefRingElem x, long y);
00297   bool operator>=(ConstRefRingElem x, long y);
00298   bool operator<(long x, ConstRefRingElem y);
00299   bool operator<=(long x, ConstRefRingElem y);
00300   bool operator>(long x, ConstRefRingElem y);
00301   bool operator>=(long x, ConstRefRingElem y);
00302   bool operator<(ConstRefRingElem x, const ZZ& y);
00303   bool operator<=(ConstRefRingElem x, const ZZ& y);
00304   bool operator>(ConstRefRingElem x, const ZZ& y);
00305   bool operator>=(ConstRefRingElem x, const ZZ& y);
00306   bool operator<(const ZZ& x, ConstRefRingElem y);
00307   bool operator<=(const ZZ& x, ConstRefRingElem y);
00308   bool operator>(const ZZ& x, ConstRefRingElem y);
00309   bool operator>=(const ZZ& x, ConstRefRingElem y);
00310 
00311   // More syntactic sugar: arithmetic between RingElems and longs
00312   bool operator==(ConstRefRingElem, long);
00313   bool operator!=(ConstRefRingElem, long);
00314   RingElem operator+(ConstRefRingElem, long);
00315   RingElem operator-(ConstRefRingElem, long);
00316   RingElem operator*(ConstRefRingElem, long);
00317   RingElem operator/(ConstRefRingElem, long);
00318   RingElem gcd(ConstRefRingElem, long);
00319   bool operator==(long, ConstRefRingElem);
00320   bool operator!=(long, ConstRefRingElem);
00321   RingElem operator+(long, ConstRefRingElem);
00322   RingElem operator-(long, ConstRefRingElem);
00323   RingElem operator*(long, ConstRefRingElem);
00324   RingElem operator/(long, ConstRefRingElem);
00325   RingElem gcd(long, ConstRefRingElem);
00326   RefRingElem operator+=(RefRingElem, long);
00327   RefRingElem operator-=(RefRingElem, long);
00328   RefRingElem operator*=(RefRingElem, long);
00329   RefRingElem operator/=(RefRingElem, long);
00330 
00331 
00332   // More syntactic sugar: arithmetic between RingElems and ZZs
00333   bool operator==(ConstRefRingElem, const ZZ&);
00334   bool operator!=(ConstRefRingElem, const ZZ&);
00335   RingElem operator+(ConstRefRingElem, const ZZ&);
00336   RingElem operator-(ConstRefRingElem, const ZZ&);
00337   RingElem operator*(ConstRefRingElem, const ZZ&);
00338   RingElem operator/(ConstRefRingElem, const ZZ&);
00339   RingElem gcd(ConstRefRingElem, const ZZ&);
00340   bool operator==(const ZZ&, ConstRefRingElem);
00341   bool operator!=(const ZZ&, ConstRefRingElem);
00342   RingElem operator+(const ZZ&, ConstRefRingElem);
00343   RingElem operator-(const ZZ&, ConstRefRingElem);
00344   RingElem operator*(const ZZ&, ConstRefRingElem);
00345   RingElem operator/(const ZZ&, ConstRefRingElem);
00346   RingElem gcd(const ZZ&, ConstRefRingElem);
00347   RefRingElem operator+=(RefRingElem, const ZZ&);
00348   RefRingElem operator-=(RefRingElem, const ZZ&);
00349   RefRingElem operator*=(RefRingElem, const ZZ&);
00350   RefRingElem operator/=(RefRingElem, const ZZ&);
00351 
00352 
00353   //---------------------------------------------------------------------------
00354   // inline functions on rings -- the order of appearance might be important!
00355 
00356 
00357   inline bool operator==(const ring& R1, const ring& R2)
00358   {
00359     return R1.myRawPtr() == R2.myRawPtr();
00360 //    return R1.mySmartPtr == R2.mySmartPtr;  // equivalent formulation
00361   }
00362 
00363   inline bool operator!=(const ring& R1, const ring& R2)
00364   {
00365     return !(R1 == R2);
00366   }
00367 
00368 
00369   //----------------------------------------------------------------------
00370   // Inline functions.  The "owner" and "raw" accessor functions must come first.
00371 
00372 
00373   inline AutoRingElem::AutoRingElem(const ring& R, RingElemRawPtr rawx):
00374       myR(R),
00375       myValuePtr(rawx)
00376   {}
00377 
00378 
00379   inline RingElemRawPtr raw(AutoRingElem& x)
00380   {
00381     CoCoA_ASSERT(x.myValuePtr.myRawPtr() != 0);
00382     return x.myValuePtr;
00383   }
00384 
00385   inline RingElemRawPtr release(AutoRingElem& x)
00386   {
00387     CoCoA_ASSERT(x.myValuePtr.myRawPtr() != 0);
00388     RingElemRawPtr rawans = x.myValuePtr;
00389     x.myValuePtr = RingElemRawPtr(0);
00390     return rawans;
00391   }
00392 
00393 
00394   inline ConstRefRingElem::ConstRefRingElem(const ring& R, RingElemConstRawPtr rawx):
00395       myR(R),
00396       myValuePtr(const_cast<void*>(rawx.myRawPtr()))
00397   {}
00398 
00399 
00400 //??? BEWARE reference to temporary???? e.g. const ring& R = owner(a+b);
00401   inline const ring& owner(const ConstRefRingElem& x)
00402   {
00403     return x.myOwner();
00404   }
00405 
00406 
00407   inline const RingElemConstRawPtr& raw(const ConstRefRingElem& x)
00408   {
00409     return x.myRawPtr();
00410   }
00411 
00412   inline RingElemRawPtr& raw(RefRingElem& x)
00413   {
00414     return x.myRawPtr();
00415   }
00416 
00417 
00418 
00419   inline std::size_t ID(const ring& R)
00420   {
00421     return R->myID;
00422   }
00423 
00424 
00425   inline RingBase::RingBase():
00426     IntrusiveReferenceCount(),
00427     myID(NewRingID())
00428   {}
00429 
00430 
00431   inline RingBase::~RingBase()
00432   {}
00433 
00434 
00435   inline RingElem::RingElem(const ring& R):
00436       RefRingElem(R, R->myNew())
00437   {}
00438 
00439 
00440   inline RingElem::RingElem(const ring& R, RingElemRawPtr rawx):
00441       RefRingElem(R, rawx)
00442   {}
00443 
00444 
00445   inline RingElem::RingElem(const RingElem& copy):
00446       RefRingElem(owner(copy), owner(copy)->myNew(raw(copy)))
00447   {}
00448 
00449 
00450   inline RingElem::RingElem(const ConstRefRingElem& copy):
00451       RefRingElem(owner(copy), owner(copy)->myNew(raw(copy)))
00452   {}
00453 
00454 
00455 
00456   inline ConstRefRingElem zero(const ring& R)
00457   {
00458     return R->myZero();
00459   }
00460 
00461 
00462   inline ConstRefRingElem one(const ring& R)
00463   {
00464     return R->myOne();
00465   }
00466 
00467 
00468   inline ZZ characteristic(const ring& R)
00469   {
00470     ZZ p;
00471     R->myCharacteristic(p);
00472     return p;
00473   }
00474 
00475 
00476   inline bool IsGCDDomain(const ring& R)
00477   {
00478     return R->IamGCDDomain();
00479   }
00480 
00481 
00482   inline bool IsCommutative(const ring& R)
00483   {
00484     return R->IamCommutative();
00485   }
00486 
00487 
00488   inline bool IsIntegralDomain(const ring& R)
00489   {
00490     return R->IamIntegralDomain();
00491   }
00492 
00493 
00494   inline bool IsField(const ring& R)
00495   {
00496     return R->IamField();
00497   }
00498 
00499 
00500   inline bool IsOrderedDomain(const ring& R)
00501   {
00502     return R->IamOrderedDomain();
00503   }
00504 
00505   //??? bool contains(const RingBase& big_ring, const RingBase& little_ring);
00506 
00507 
00508   // Define the not-equals functions here:
00509 
00510   inline bool operator!=(ConstRefRingElem x, ConstRefRingElem y)
00511   {
00512     return !(x == y);
00513   }
00514 
00515   inline bool operator!=(ConstRefRingElem r, long n)
00516   {
00517     return !(r == n);
00518   }
00519 
00520   inline bool operator!=(long n, ConstRefRingElem r)
00521   {
00522     return !(r == n);
00523   }
00524 
00525   inline bool operator!=(ConstRefRingElem r, const ZZ& N)
00526   {
00527     return !(r == N);
00528   }
00529 
00530   inline bool operator!=(const ZZ& N, ConstRefRingElem r)
00531   {
00532     return !(r == N);
00533   }
00534 
00535 
00536   inline void swap(RefRingElem f, RefRingElem g)
00537   {
00538     if (owner(f) != owner(g))
00539       CoCoA_ERROR(ERR::MixedRings, "swap(RingElem, RingElem)");
00540     owner(f)->mySwap(raw(f), raw(g));
00541   }
00542 
00543 } // end of namespace CoCoA
00544 
00545 
00546 // RCS header/log in the next few lines
00547 // $Header: /Volumes/Home/cocoa/cvs-repository/CoCoALib-0.99/include/CoCoA/ring.H,v 1.3 2007/05/22 22:45:14 abbott Exp $
00548 // $Log: ring.H,v $
00549 // Revision 1.3  2007/05/22 22:45:14  abbott
00550 // Changed fn name IsUnit to IsInvertible.
00551 //
00552 // Revision 1.2  2007/05/18 10:46:06  bigatti
00553 // -- added comment: #include "CoCoA/ZZ.H"  // for inline ZZ characteristic(ring)
00554 //
00555 // Revision 1.1.1.1  2007/03/09 15:16:11  abbott
00556 // Imported files
00557 //
00558 // Revision 1.17  2007/01/15 16:16:14  cocoa
00559 // -- added prefix "raw" to RawPtr arguments names
00560 // -- changed rhs into rawx, n, or N
00561 //
00562 // Revision 1.16  2007/01/13 14:14:34  cocoa
00563 // Overhaul of RingHom code: it nows uses SmartPtrIRC, and printing is more logical.
00564 // Have not yet updated the documentation.
00565 //
00566 // Revision 1.15  2007/01/08 16:39:22  cocoa
00567 // -- changed comment about operator<<
00568 //
00569 // Revision 1.14  2006/12/06 17:18:40  cocoa
00570 // -- removed #include "config.H"
00571 //
00572 // Revision 1.13  2006/11/27 13:06:23  cocoa
00573 // Anna and Michael made me check without writing a proper message.
00574 //
00575 // Revision 1.12  2006/11/23 17:45:46  cocoa
00576 // -- updated #include and forward declarations
00577 //
00578 // Revision 1.11  2006/11/22 17:49:33  cocoa
00579 // -- doxygen style comments
00580 //
00581 // Revision 1.10  2006/11/21 17:08:02  cocoa
00582 // added explicit call to IntrusiveReferenceCount ctor in RingBase ctor
00583 //
00584 // Revision 1.9  2006/11/20 15:55:02  cocoa
00585 // ring is now a class again.  Improved definitions of operator-> in derived classes.
00586 //
00587 // Revision 1.8  2006/11/03 15:37:47  cocoa
00588 // -- cleaned up code after testing on usage of SmartPtrIRC
00589 //
00590 // Revision 1.7  2006/11/03 14:01:46  cocoa
00591 // -- changed: reference counting in ring, PPMonoids and OrdvArith now
00592 //    uses SmartPtrIRC
00593 //
00594 // Revision 1.6  2006/11/02 13:25:44  cocoa
00595 // Simplification of header files: the OpenMath classes have been renamed.
00596 // Many minor consequential changes.
00597 //
00598 // Revision 1.5  2006/10/27 19:09:45  cocoa
00599 // Replaced some member functions of CoCoA::symbol by friend functions.
00600 // Removed some include dependency on symbol.H
00601 //
00602 // Revision 1.4  2006/10/16 23:18:59  cocoa
00603 // Corrected use of std::swap and various special swap functions.
00604 // Improved myApply memfn for homs of RingDistrMPolyInlPP.
00605 //
00606 // Revision 1.3  2006/10/06 14:04:15  cocoa
00607 // Corrected position of #ifndef in header files.
00608 // Separated CoCoA_ASSERT into assert.H from config.H;
00609 // many minor consequential changes (have to #include assert.H).
00610 // A little tidying of #include directives (esp. in Max's code).
00611 //
00612 // Revision 1.2  2006/08/07 21:23:25  cocoa
00613 // Removed almost all publicly visible references to SmallExponent_t;
00614 // changed to long in all PPMonoid functions and SparsePolyRing functions.
00615 // DivMask remains to sorted out.
00616 //
00617 // Revision 1.1.1.1  2006/05/30 11:39:37  cocoa
00618 // Imported files
00619 //
00620 // Revision 1.10  2006/05/29 16:22:37  cocoa
00621 // Third time lucky???
00622 // Added myIsInteger member function to all rings (NYI for RingFloat).
00623 //
00624 // Revision 1.9  2006/05/12 16:10:58  cocoa
00625 // Added OpenMathFwd.H, and tidied OpenMath.H.
00626 // Many consequential but trivial changes.
00627 //
00628 // Revision 1.8  2006/04/27 13:43:35  cocoa
00629 // Added abs function (only for arithmetically ordered rings).
00630 //
00631 // Revision 1.7  2006/04/21 15:01:36  cocoa
00632 // Changed default implementation of RingBase::myGcd -- it now gives a SERIOUS
00633 // error.  All fields must now handle a call to gcd explicitly: they can use
00634 // the new myGcdInField function.  It's now cleaner than it was.
00635 //
00636 // Revision 1.6  2006/03/27 12:21:25  cocoa
00637 // Minor silly changes to reduce number of complaints from some compiler or other.
00638 //
00639 // Revision 1.5  2006/03/15 18:09:31  cocoa
00640 // Changed names of member functions which print out their object
00641 // into myOutputSelf -- hope this will appease the Intel C++ compiler.
00642 //
00643 // Revision 1.4  2006/03/14 15:01:49  cocoa
00644 // Improved the implementation of ring member fns for computing powers.
00645 // Should keep Intel C++ compiler quieter too.
00646 //
00647 // Revision 1.3  2006/03/12 21:28:34  cocoa
00648 // Major check in after many changes
00649 //
00650 // Revision 1.2  2006/02/14 16:22:20  cocoa
00651 // -- defined "operator<<" for vector<RingElem>&  in ring.H/C
00652 //
00653 // Revision 1.1.1.1  2005/10/17 10:46:54  cocoa
00654 // Imported files
00655 //
00656 // Revision 1.4  2005/09/22 18:04:17  cocoa
00657 // It compiles; the tests run OK.  The examples compile.
00658 // No documentation -- the mindless eurocrats have rendered
00659 // me mindless too.
00660 //
00661 // Revision 1.3  2005/07/08 15:09:29  cocoa
00662 // Added new symbol class (to represent names of indets).
00663 // Integrated the new class into concrete polynomial rings
00664 // and PPMonoid -- many consequential changes.
00665 // Change ctors for the "inline" sparse poly rings: they no
00666 // longer expect a PPMonoid, but build their own instead
00667 // (has to be a PPMonoidOv).
00668 //
00669 // Revision 1.2  2005/06/22 14:47:56  cocoa
00670 // PPMonoids and PPMonoidElems updated to mirror the structure
00671 // used for rings and RingElems.  Many consequential changes.
00672 //
00673 // Revision 1.1.1.1  2005/05/03 15:47:30  cocoa
00674 // Imported files
00675 //
00676 // Revision 1.5  2005/04/20 15:40:48  cocoa
00677 // Major change: modified the standard way errors are to be signalled
00678 // (now via a macro which records filename and line number).  Updated
00679 // documentation in error.txt accordingly.
00680 //
00681 // Improved the documentation in matrix.txt (still more work to be done).
00682 //
00683 // Revision 1.4  2005/04/19 14:06:04  cocoa
00684 // Added GPL and GFDL licence stuff.
00685 //
00686 // Revision 1.3  2005/02/11 16:45:24  cocoa
00687 // Removed the useless and misleading functions myInit and myKill
00688 // from the SmallFp*Impl classes; various consequential changes.
00689 //
00690 // Revision 1.2  2005/02/11 14:15:20  cocoa
00691 // New style ring elements and references to ring elements;
00692 // I hope I have finally got it right!
00693 //
00694 // Revision 1.1.1.1  2005/01/27 15:12:13  cocoa
00695 // Imported files
00696 //
00697 // Revision 1.23  2004/11/25 16:14:21  cocoa
00698 // (1) Fixed definition of specialization of std::swap template function
00699 //     so that it compiles with gcc 3.4.3
00700 // (2) Implemented monomial function for polynomial rings.
00701 // (3) Added one(PPM) and PPM->myOne() functions.
00702 //
00703 // Revision 1.22  2004/11/18 18:33:40  cocoa
00704 // Now every ring know its own "one" element (as well as "zero").
00705 // Several consequential changes.
00706 //
00707 // Revision 1.21  2004/11/11 14:05:02  cocoa
00708 // -- minor changes for doxygen
00709 //
00710 // Revision 1.20  2004/11/09 15:57:01  cocoa
00711 // -- minor changes for doxygen
00712 //
00713 // Revision 1.19  2004/11/04 18:47:42  cocoa
00714 // (1) Ring member functions which previously expected mpz_t args
00715 //     now expect ZZ args.  Numerous minor consequential changes.
00716 // (2) Renamed function which gives access to the mpz_t value inside
00717 //     a ZZ object: previously was raw(...), now is mpzref(...).
00718 //     Plenty of calls had to be altered.
00719 //
00720 // Revision 1.18  2004/07/27 16:03:38  cocoa
00721 // Added IsCommutative test and IamCommutative member function
00722 // to all rings.  Tidied geobuckets a little.
00723 //
00724 // Revision 1.17  2004/07/20 15:04:05  cocoa
00725 // The next step in the new "ring element" conversion process:
00726 // handling the case of creating a "const RefRingElem" object
00727 // (since C++ refuses to do this properly itself).
00728 //
00729 // Revision 1.16  2004/07/16 15:45:12  cocoa
00730 // First stage of new RingElem implementation completed.
00731 //
00732 // Revision 1.15  2004/07/13 16:32:26  cocoa
00733 // First stage of major revamp of ring elements.
00734 // Implementation of RingFp has been split into "ring interface"
00735 // and "algorithms plus data structures".
00736 //
00737 // Revision 1.14  2004/06/29 17:10:22  cocoa
00738 // Partially tidied use of "protected" and "private" in various
00739 // base classes.  Checking in at the end of the day -- it works,
00740 // and I wouldn't want it to be lost next time point's disk
00741 // misbehaves.
00742 //
00743 // Revision 1.13  2004/05/27 16:14:02  cocoa
00744 // Minor revision for new coding conventions.
00745 //
00746 // Revision 1.12  2004/05/24 15:52:13  cocoa
00747 // Major update:
00748 //   new error mechanism
00749 //   many fixes
00750 //   RingHoms almost work now
00751 //   RingFloat much improved
00752 //
00753 // Revision 1.11  2004/04/08 15:33:34  cocoa
00754 // Added function IsInteger, and the related RingBase::myIsInteger
00755 // virtual function, plus all necessary implementations.
00756 //
00757 // Revision 1.10  2004/03/20 17:46:10  cocoa
00758 // Check in prior to departure to RWCA
00759 //
00760 // Revision 1.9  2004/02/03 16:16:20  cocoa
00761 // Removed pointless IamGCDDomain functions from several concrete rings.
00762 // Added IamOrderedDomain functions where appropriate.
00763 // Tidied ctors for the small finite fields.
00764 //
00765 // Revision 1.8  2004/01/30 14:08:16  cocoa
00766 // Tidied RingRawValue union -- forgot to check this in with all the other
00767 // files.
00768 //
00769 // Revision 1.7  2004/01/28 16:03:27  cocoa
00770 // Sundry minor changes.
00771 //
00772 // Revision 1.6  2003/11/21 14:32:17  cocoa
00773 // -- added fields for DistrMPoly
00774 //
00775 // Revision 1.5  2003/11/14 13:06:04  cocoa
00776 // -- New function "myIsPrintAtom" for printing polynomials and fractions
00777 //
00778 // Revision 1.4  2003/10/17 10:51:06  cocoa
00779 // Major cleaning, and new naming convention.
00780 //
00781 // Revision 1.3  2003/10/09 14:55:19  cocoa
00782 // - minor debugging after merge
00783 //
00784 // Revision 1.2  2003/10/09 12:12:26  cocoa
00785 // New coding convention for rings.
00786 //
00787 // Revision 1.1.1.1  2003/09/24 12:55:43  cocoa
00788 // Imported files
00789 //
00790 // Revision 1.24  2003/06/23 16:35:06  abbott
00791 // Updates prior to public release:
00792 //   changed characteristic to yield a big integer
00793 //   added IsIntegralDomain function
00794 //
00795 // Revision 1.23  2003/05/30 11:57:47  abbott
00796 // Minor revisions to some comments (for compatibility with "doxygen".
00797 //
00798 // Revision 1.22  2003/04/16 14:14:26  abbott
00799 // Main changes:
00800 //   added functions for ideals and homomorphisms
00801 //     RingBase::NewIdeal  -- to create new ideals
00802 //     RingBase::ReduceMod -- to reduce a value modulo an ideal
00803 //
00804 //   added a function to compute the composition of two ring homomorphisms
00805 //     RingBase::compose
00806 //
00807 //   added IsDivisible top level function
00808 //   added RingBase::ZeroRefCount  (a slightly "dirty" function).
00809 //
00810 // Revision 1.21  2003/01/21 15:33:01  abbott
00811 // Major restructuring (and some renaming):
00812 //   RingBase is now the base class for all rings, and
00813 //   it includes an intrusive reference count;
00814 //   ring is a reference counted pointer class (to RingBase);
00815 //   RingElem, ConstRefRingElem are now at top level;
00816 //   RingRawValue is also at top level (unhappy about this).
00817 // Commented out the "zero" function.
00818 //
00819 // Revision 1.20  2002/12/13 15:14:05  abbott
00820 // Added functions IsOne and IsMinusOne (both at global level and
00821 // as member functions of an AbstractRing).  Commented out the
00822 // member function for testing equality between a RingElem and a
00823 // machine integer.  Added member functions for initializing or
00824 // assigning from a big integer (of type ZZ).  Added syntactic
00825 // sugar operators for arithmetic between RingElems and ZZs.
00826 //
00827 // Revision 1.19  2002/12/11 11:49:09  abbott
00828 // Checking in for safety -- this code does at least compile and work.
00829 // Exponents in power functions must now be non-negative (unsigned int).
00830 // Added functions between RingElems and ZZs (big integers).
00831 // Added two member functions for initialising/assigning from big integers.
00832 //
00833 // Made op == and != inline because Anna wanted them so; probably revoke
00834 // this after IsOne has been invented.
00835 //
00836 // Revision 1.18  2002/11/14 16:24:04  abbott
00837 // Extensive changes.  ring renamed to AbstractRing.
00838 // New typedef RingElem for AbstractRing::elem.
00839 // New typedef ConstRawValue to be used as arg type in ring member functions.
00840 // Old alias subclass has been removed -- its semantics were unclear.
00841 // New ConstRefElem subclass replaces old alias -- clearer semantics than alias.
00842 // New typedef ConstRefRingElem to be used as arg type for read only RingElems :-(
00843 // New specialization of std::swap template fn for RingElems.
00844 //
00845 // Revision 1.17  2002/07/05 15:15:04  abbott
00846 // Added IsDivisible pure virtual member function.
00847 // Added SequentialPower member function, and made power pure virtual.
00848 //
00849 // Revision 1.16  2002/06/27 16:05:53  abbott
00850 // Added two missing equality/not-equality operators.
00851 // Added BinaryPower member function (and BinaryPowerLoop).
00852 //
00853 // Revision 1.15  2002/06/21 14:36:35  abbott
00854 // Changed name of "equal" member function to "IsEqual".
00855 // Added field to ring::elem to support FractionField.
00856 // Added "syntactic sugar" to allow arithmetic between ring::elems
00857 // and machine integers.
00858 //
00859 // Revision 1.14  2002/05/30 16:19:21  abbott
00860 // Removed an apparently bogus init member function: its second arg was a ring::elem
00861 // rather than a RawValue.
00862 //
00863 // Revision 1.13  2002/05/30 13:33:12  abbott
00864 // Added IsField and IsGCDDomain functions (also as member functions).
00865 // Added zero function (and member function).
00866 // Added equals and not-equals operators.
00867 //
00868 // Revision 1.12  2002/05/15 14:50:29  abbott
00869 // Extensive revisions.
00870 //   Added new member functions for ring: characteristic, negate, power.
00871 //   Reordered various blocks of code.
00872 //   Class elem is now class ring::elem.
00873 //   Enlarged ring::elem objects so that they can be aliases.
00874 //   Changed "const RawValue&" arguments into simple "RawValue" arguments.
00875 //
00876 // Revision 1.11  2002/03/28 15:56:25  abbott
00877 // Added field to ring::RawValue for ring_DMP.
00878 //
00879 // Revision 1.10  2002/02/15 11:53:59  bigatti
00880 // - added IsGCDDomain, gcd, "=", "==", "!="
00881 //
00882 // Revision 1.9  2002/02/08 11:09:54  bigatti
00883 // - changed syntax to IsZeroAddMul
00884 //
00885 // Revision 1.8  2002/01/30 14:55:33  abbott
00886 // Apparently the destructor should not have been pure virtual, so I fixed that.
00887 // Added ring member function IsZeroAddMul -- Anna says it improves performance
00888 // noticeably.
00889 // Changed "raw" from being a member function of elem, to being a normal
00890 // function (following a brief discussion with Anna and Max).  Also it no
00891 // longer requires the ring as argument -- any such checks must be explicit!
00892 // The "raw" functions are inline.
00893 //
00894 // Revision 1.7  2001/12/07 18:19:43  abbott
00895 // Changed names in accordance with new coding conventions;
00896 // in particular ring::raw_elem became ring::RawValue.
00897 // Added a few assertions.
00898 //
00899 // Revision 1.6  2001/11/23 20:50:31  abbott
00900 // Added assignment to an elem from a machine integer (long).
00901 // Had to make DMP a friend of class elem -- UNHAPPY!
00902 //
00903 // Revision 1.5  2001/11/16 18:44:15  bigatti
00904 // added: std::
00905 // for compatibility with gcc-3
00906 //
00907 // Revision 1.4  2001/11/07 20:51:22  abbott
00908 // Changed ring::raw_elem to a union (from a void*) analogously to the change
00909 // to PPmonoid::raw_elem.  Note that care will be needed to keep the field
00910 // types synchronized with the types required by each concrete ring!
00911 //
00912 // Added an accessor function which allows access to the value field of
00913 // an elem (but the caller must supply the ring, as a safety check).
00914 // Not sure about how dirty this is.  Used in DMP.C (DMP::mul and DMP::div).
00915 //
00916 // Revision 1.3  2001/11/05 18:03:13  abbott
00917 // Added a "copy constructor" which allows a raw_elem to be initialized
00918 // from an elem (after checking that the rings are the same).
00919 // Question: should this constuctor automatically apply homomorphisms?
00920 //
00921 // Revision 1.2  2001/10/31 20:40:45  abbott
00922 // Some minor changes: biggest was declaration of +=, -=, *=, /=
00923 // for elems.
00924 //
00925 // Revision 1.1  2001/10/05 12:44:13  abbott
00926 // Initial revision
00927 //
00928 
00929 #endif

Generated on Wed May 23 13:43:36 2007 for CoCoALib by  doxygen 1.4.6