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

/magnus/back_end/Group/include/Group.h

Go to the documentation of this file.
00001 /*
00002  *   $Id: Group.h,v 1.4 2000/03/03 02:44:14 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 Group class.
00009 //
00010 // Principal Authors: Stephane Collart, Roger Needham
00011 //
00012 // Status: in progress
00013 //
00014 // Revision History:
00015 //
00016 // Special Remarks:
00017 //
00018 // * As a general principle, the (conditional) error-checking takes
00019 //   place as close to the root of the class hierarchy and at the
00020 //   location where the construction actually takes place;
00021 //   for instance checking for a negative number of generators is done
00022 //   if FGGroup but not higher. This has the slight
00023 //   inconvenience that the user does not immediately see where the
00024 //   origin of the error is, but saves placing error traps.
00025 //
00026 // * Tentatively, operator == and != are not delegated to virtual functions.
00027 //   Instead, every group will be compared according to the type by which
00028 //   it is referenced, and these operators must be defined in every class
00029 //   of the hierarchy which adds representation information. (@rn huh?)
00030 //   The meaning of comparison is thus equality of representation as
00031 //   referenced.
00032 //
00033 // Bugs:
00034 //
00035 // * A bug in g++ 2.5.8 and less forces to derive Group publicly from
00036 //   ObjectOf<GroupRep> although there is no reason to do this.
00037 //   The difficulty may be due to a confusion in the assignment of
00038 //   objects of derived classes
00039 //
00040 // * 07/96 Alexey M. implemented IPC tools.
00041 //
00042 
00043 #ifndef _GROUP_H_
00044 #define _GROUP_H_
00045 
00046 
00047 #include "Type.h"
00048 #include "IStreamPoll.h"
00049 #include "GroupRep.h"
00050 
00051 
00052 class Group : public GenericObject {
00053   
00054 public:
00055 
00056   ///////////////////////////////////////////////////////
00057   //                                                   //
00058   //  Constructors                                     //
00059   //                                                   //
00060   ///////////////////////////////////////////////////////
00061 
00062   // No default constructor for pseudo-abstract class.
00063   // Copy constructor and destructor supplied by compiler.
00064   
00065   ///////////////////////////////////////////////////////
00066   //                                                   //
00067   //  Operators                                        //
00068   //                                                   //
00069   ///////////////////////////////////////////////////////
00070 
00071   // Operator= supplied by compiler.
00072 
00073   int operator == ( const Group& G ) const 
00074   { 
00075     if( actualType() != G.actualType() )
00076       return false;
00077     if( look() == G.look() ) 
00078       return true; 
00079     return look()->compare( G.look() );
00080   }
00081   // @rn:stc Can we do better than this?
00082   // @dp made some enhancements.
00083   
00084   int operator != ( const Group& G ) const { return !(*this == G); }
00085 
00086   ///////////////////////////////////////////////////////
00087   //                                                   //
00088   //  Accessors                                        //
00089   //                                                   //
00090   ///////////////////////////////////////////////////////
00091 
00092   static Type type( ) { return GroupRep::type(); }
00093 
00094   Type actualType( ) const { return look()->actualType(); }
00095 
00096   ///////////////////////////////////////////////////////
00097   //                                                   //
00098   //  Group structure methods                          //
00099   //                                                   //
00100   ///////////////////////////////////////////////////////
00101 
00102   int order( ) const; // pseudo-virtual
00103   // Returns the order of this group, or 0 if this is infinite,
00104   // or -1 if no answer can be determined.
00105 
00106   Trichotomy isTrivial( ) const { return enhance()->isTrivial(); }
00107   // pseudo-virtual
00108 
00109   Trichotomy isFinite( ) const { return enhance()->isFinite(); }
00110   // pseudo-virtual
00111 
00112   Trichotomy isInfinite( ) const { return enhance()->isInfinite(); }
00113   // pseudo-virtual
00114 
00115   Trichotomy isAbelian( ) const { return enhance()->isAbelian(); }
00116   // pseudo-virtual
00117 
00118 
00119   ///////////////////////////////////////////////////////
00120   //                                                   //
00121   //  Methods which deal with group elements           //
00122   //                                                   //
00123   ///////////////////////////////////////////////////////
00124 
00125 
00126   Elt makeIdentity( ) const { return look()->makeIdentity(); }
00127   // Returns an object which this group treats as a
00128   // syntactic representation of its identity element.
00129 
00130   Bool isSyntacticIdentity(const Elt& e) const {
00131          return look()->isSyntacticIdentity(e);
00132   }
00133   // Says whether this group considers e to be a syntactic representation
00134   // of its identity element. This does not try to solve the word problem,
00135   // or apply such a solution if it exists.
00136 
00137   Trichotomy isTrivialElt( const Elt& e ) const
00138         { return look()->isTrivialElt(e); }
00139   // Attempts to determine whether e is or represents the identity in
00140   // this group
00141 
00142   Trichotomy areEqual(const Elt& e1, const Elt& e2) const {
00143          return enhance()->areEqual(e1, e2);
00144   }
00145   // Tries to decide whether e1 and e2 represent the same element
00146   // of this group.
00147 
00148   Elt firstElt( ) const { return look()->firstElt(); }
00149   // Returns the first Elt in a fixed, pre-determined sequence of Elts
00150   // which maps onto, but not necessarily 1-1, the set of this group's
00151   // elements.
00152 
00153   Elt nextElt(const Elt& e) const { return look()->nextElt(e); }
00154   // Returns the element which comes after e in the sequence described
00155   // above. Guaranteed defined only on Elts returned by firstElt or
00156   // nextElt, since the sequence may not contain all Elts.
00157 
00158   Elt multiply(const Elt& e1, const Elt& e2) const {
00159          return look()->multiply(e1, e2);
00160   }
00161   // Returns a representation of the product of e1 and e2 in this group.
00162 
00163   Elt inverseOf(const Elt& e) const { return look()->inverseOf(e); }
00164   // Returns a representation of the inverse of e in this group.
00165 
00166   Elt raiseToPower(const Elt& e, int n) const {
00167          return look()->raiseToPower(e, n);
00168   }
00169   // Returns a representation of e^n in this group, for any int n.
00170 
00171   Elt conjugateBy(const Elt& e1, const Elt& e2) const {
00172          return look()->conjugateBy(e1, e2);
00173   }
00174   // Returns a representation of e2^-1 e1 e2 in this group.
00175 
00176   Elt commutator(const Elt& e1, const Elt& e2) const {
00177          return look()->commutator(e1, e2);
00178   }
00179   // Returns a representation of e1^-1 e2^-1 e1 e2 in this group.
00180 
00181 
00182   ///////////////////////////////////////////////////////
00183   //                                                   //
00184   //  Methods which deal with sets of group elements   //
00185   //                                                   //
00186   ///////////////////////////////////////////////////////
00187 
00188 
00189   SetOf<Elt> setMultiply(const SetOf<Elt>& S1, const SetOf<Elt>& S2) const;
00190   SetOf<Elt> setMultiply(const Elt& e, const SetOf<Elt>& S) const;
00191   SetOf<Elt> setMultiply(const SetOf<Elt>& S, const Elt& e) const;
00192   // These return elementwise products, multiplying in the order of the args.
00193 
00194   SetOf<Elt> conjugateBy(const SetOf<Elt>& S1, const SetOf<Elt>& S2) const;
00195   SetOf<Elt> conjugateBy(const Elt& e, const SetOf<Elt>& S) const;
00196   SetOf<Elt> conjugateBy(const SetOf<Elt>& S, const Elt& e) const;
00197   // By convention, conjugateBy(S1, S2) = { s2^-1 s1 s2 : s_i in S_i }.
00198 
00199   void closeUnderInverses(SetOf<Elt>& S) const;
00200   // Alters S so that it is closed under (group element) inverses.
00201    
00202 
00203   ///////////////////////////////////////////////////////
00204   //                                                   //
00205   //  I/O                                              //
00206   //                                                   //
00207   ///////////////////////////////////////////////////////
00208 
00209 
00210   // @stc outdated: (valid only for ostream & istream)
00211   // The paradigm for I/O:
00212   //
00213   // The Rep of the root of a hierarchy H defines
00214   //
00215   // virtual void printOn(ostream&) const;
00216   // virtual Rep* readFrom(istream&, Chars&) const;
00217   //
00218   // The root defines
00219   //
00220   // friend ostream& operator << ( ostream&, const H& );
00221   // friend IStreamPoll operator >> ( istream&, H& );
00222   //
00223   // which delegate to printOn and readFrom, resp.
00224   // Subclasses of Rep override printOn/readFrom.
00225   // readFrom returns NULL when there is a parse error;
00226   // in this case, >> does not change H.
00227 
00228   // the old i/o way :
00229 
00230   friend ostream& operator << ( ostream&, const Group& );
00231   
00232   friend IStreamPoll operator >> ( istream&, Group& );
00233  /////////////////////////////////////////////////////////////////////////
00234   //                                                                     //
00235   // IPC tools:                                                          //
00236   //                                                                     //
00237   /////////////////////////////////////////////////////////////////////////
00238 
00239   friend ostream& operator < ( ostream& ostr, const Group& G )
00240   {
00241     G.look()->write(ostr);
00242     return ostr;
00243   }
00244   
00245   friend istream& operator > ( istream& istr, Group& G )
00246   {
00247     G.change()->read(istr);
00248     return istr;
00249   }
00250 
00251 
00252 
00253   ///////////////////////////////////////////////////////
00254   //                                                   //
00255   //  Representation access methods                    //
00256   //                                                   //
00257   ///////////////////////////////////////////////////////
00258 
00259 
00260 protected:
00261 
00262   // Shadow representation accessors to get representations of the
00263   // right type in the members of this class:
00264 
00265   const GroupRep* look( ) const {
00266          return (const GroupRep*)GenericObject::look();
00267   }
00268   GroupRep* enhance( ) const {
00269          return (GroupRep*)GenericObject::enhance();
00270   }
00271   GroupRep* change( ) {
00272          return (GroupRep*)GenericObject::change();
00273   }
00274 
00275   // Special wrapping constructor to wrap new representations (returned
00276   // by eg. delegated methods) and for base initialisation by derived
00277   // classes:
00278 
00279   Group( GroupRep* newrep ) : GenericObject(newrep) { }
00280 
00281 
00282   ///////////////////////////////////////////////////////
00283   //                                                   //
00284   //  Debugging stuff                                  //
00285   //                                                   //
00286   ///////////////////////////////////////////////////////
00287 
00288 #ifdef DEBUG
00289 
00290 private:
00291   
00292   //friend int main( );
00293   friend void debugPrint(ostream&, const Group& g);
00294 
00295 public:
00296 
00297   bool consistent( ) const { return look()->consistent(); } // pseudo-virtual
00298 
00299 #endif
00300   
00301 };
00302 
00303 
00304 //--------------------------- Group -----------------------------------//
00305 //------------------- top level i/o functions -------------------------//
00306  
00307 
00308 /*@rn
00309 // @stc Ostream& operator << ( Ostream&, const Group& );
00310 // @stc provisional bypass:
00311 inline Ostream& operator << ( Ostream& o, const Group& g ) {
00312         ostream(o) << g;
00313         return o;
00314 }
00315 */
00316 
00317 #endif

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