Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

/magnus/back_end/Elt/include/Elt.h

Go to the documentation of this file.
00001 /*
00002  *   $Id: Elt.h,v 1.5 1999/11/23 20:22:42 bormotov Exp $
00003  */
00004 
00005 // Copyright (C) 1994 The New York Group Theory Cooperative
00006 // See magnus/doc/COPYRIGHT for the full notice.
00007 
00008 // Contents: Definition of the Elt class.
00009 //
00010 // Principal Author: Stephane Collart
00011 //
00012 // Status: Useable.
00013 //
00014 // Revision History:
00015 //
00016 // * 4.6.94 @stc added default constructor to Elt
00017 //
00018 // * 01/96 Dmitry B. implemented IPC tools.
00019 //
00020 // Fundamental Questions:
00021 //
00022 // * What does one do about functions and operators taking two or more
00023 //   arguments, when it is important to correctly resolve the actual
00024 //   type of both arguments? As a special case, see the Q about op ==
00025 //   below. Some type mismatches would be allowed (e.g. EltIdentityRep
00026 //   with anything else) and others not (e.g. WordRep and MatrixRep).
00027 //
00028 // * Where should equality be resolved (as expressed through operator ==)?
00029 //   - at the object level, via the accessors?
00030 //   - via delegation to the representation level?
00031 //   Note the ramifications: you have two objects a,b, ostensibly of
00032 //   type T; should they be compared as T's, or as their *actual* types?
00033 //   If the latter is preferred, what does one do about type mismatches?
00034 //   Simple minded delegation to a virtual function of one of the
00035 //   arguments does not resolve the type of the second argument.
00036 //
00037 // * In a tentative revision of the practice of not giving
00038 //   pseudo-abstract classes a default constructor, Elt now gets a
00039 //   default constructor which gives it an actual EltIdentityRep* as a rep
00040 //   This makes an object-level (ie wrapped-pointer) class behave more
00041 //   closely like a real pointer. A default initialised Elt may be
00042 //   assigned to and even from in perfect consistency. Eventually,
00043 //   it is intended to make such a default initialised Elt behave like
00044 //   the identity; note that this is not implemented fully yet (see
00045 //   restrictions).
00046 //
00047 // * Does Elt need a global operator * taking two Elt arguments? in 
00048 //   every case when one expects a conversion from some type T which has
00049 //   a conversion to Elt on the left hand side of `a * b',
00050 //   the only alternative is to give T itself an operator * ( Elt ),
00051 //   since the ARM will not consider a conversion to apply a method.
00052 //
00053 // * The same question occurs much more frequently and generally with
00054 //   operator ==; for this reason Elt has tentatively been given a global
00055 //   == inlined below.
00056 //
00057 // Restrictions:
00058 //
00059 // * If you try applying methods to a default initialised Elt, you
00060 //   will likely get grief (as if you tried dereferencing the null pointer.)
00061 //   
00062 
00063 #ifndef _ELT_H_
00064 #define _ELT_H_
00065 
00066 #include "EltRep.h"
00067 #include "Integer.h"
00068 #include "Rational.h"
00069 
00070 
00071 class Elt : public GenericObject {
00072 
00073 public:
00074 
00075 ///////////////////////////////////////////////////////////////////////
00076 //                                                                   //
00077 // Constructors:                                                     //
00078 //                                                                   //
00079 ///////////////////////////////////////////////////////////////////////
00080 
00081   // copy constructor provided by compiler
00082 
00083   Elt( ) : GenericObject( new EltIdentityRep ) { }
00084   // @stc this is a tentative way of giving Elt a default constructor
00085 
00086   // destructor provided by compiler
00087 
00088 ///////////////////////////////////////////////////////////////////////
00089 //                                                                   //
00090 // Basic operators:                                                  //
00091 //                                                                   //
00092 ///////////////////////////////////////////////////////////////////////
00093 
00094   int operator == ( const Elt& e ) const {
00095          return ((look() == e.look()) || (*look() == *e.look()));
00096   }
00097 
00098   int operator != ( const Elt& e ) const { return !( *this == e ); }
00099 
00100 ///////////////////////////////////////////////////////////////////////
00101 //                                                                   //
00102 // Representation and type stuff:                                    //
00103 //                                                                   //
00104 ///////////////////////////////////////////////////////////////////////
00105 
00106   static Type type( ) { return EltRep::type(); }
00107 
00108   Type actualType( ) const { return look()->actualType(); }
00109 
00110   int hash( ) const { return look()->hash(); }
00111 
00112 ///////////////////////////////////////////////////////////////////////
00113 //                                                                   //
00114 // Mathematical methods:                                             //
00115 //                                                                   //
00116 ///////////////////////////////////////////////////////////////////////
00117 
00118   Elt operator * ( const Elt& e ) const {
00119          return Elt( *look() * *e.look() );
00120   }
00121 
00122   Elt operator *= ( const Elt& e ) {
00123          return *this = Elt( *look() * *e.look() );
00124   }
00125 
00126   Elt raiseToPower( Integer power ) const;
00127 
00128   Elt inverse() const {
00129          return Elt( look()->inverse() );
00130   }
00131 
00132   friend Elt inverse( const Elt& e ) { return e.inverse(); }
00133   // to make it more convenient to take the inverse of something which
00134   // can be converted to an Elt
00135 
00136   Elt conjugateBy( const Elt& e ) const {
00137          return Elt( look()->conjugateBy(e.look()) );
00138   }
00139 
00140   friend Elt commutator( const Elt&, const Elt& );
00141 
00142   // The paradigm for output:
00143   // The Rep of the root of a hierarchy defines
00144   // virtual void printOn(ostream&) const;
00145   // The root defines a friend << which
00146   // calls printOn. Subclasses of Rep override printOn.
00147   // No other << or printOn's are needed.
00148 
00149   friend ostream& operator << ( ostream&, const Elt& );
00150 
00151   void debugPrint( ostream& o ) const; // mixed pseudo-virtual
00152 
00153   
00154   /////////////////////////////////////////////////////////////////////////
00155   //                                                                     //
00156   // IPC tools:                                                          //
00157   //                                                                     //
00158   /////////////////////////////////////////////////////////////////////////
00159 
00160   friend ostream& operator < ( ostream& ostr, const Elt& e )
00161   {
00162     e.look()->write(ostr);
00163     return ostr;
00164   }
00165   
00166   friend istream& operator > ( istream& istr, Elt& e )
00167   {
00168     e.change()->read(istr);
00169     return istr;
00170   }
00171 
00172 
00173 protected:
00174 
00175   // Shadow representation accessors to get representations of the
00176   // right type in the members of this class:
00177 
00178   const EltRep* look( ) const {
00179          return (const EltRep*)GenericObject::look();
00180   }
00181   EltRep* enhance( ) const {
00182          return (EltRep*)GenericObject::enhance();
00183   }
00184   EltRep* change( ) {
00185          return (EltRep*)GenericObject::change();
00186   }
00187 
00188   Elt( EltRep* p ) : GenericObject(p) { }
00189 
00190 };
00191 
00192 
00193 //----------------------- Associated Global ------------------------//
00194 //------------------------- Functions ------------------------------//
00195 
00196 /*@db porting
00197 inline bool operator == ( const Elt& e1, const Elt& e2 ) {
00198 
00199         return e1.operator == (e2);
00200 }
00201 */
00202 
00203 #endif

Generated at Tue Jun 19 09:49:34 2001 for Magnus Classes by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001