Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
| Download
GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
Project: cocalc-sagemath-dev-slelievre
Views: 418346############################################################################# ## ## HomalgRing.gi MatricesForHomalg package Mohamed Barakat ## ## Copyright 2007-2009 Mohamed Barakat, RWTH Aachen ## ## Implementation stuff for homalg rings. ## ############################################################################# #################################### # # representations: # #################################### ## <#GAPDoc Label="IsHomalgInternalRingRep"> ## <ManSection> ## <Filt Type="Representation" Arg="R" Name="IsHomalgInternalRingRep"/> ## <Returns><C>true</C> or <C>false</C></Returns> ## <Description> ## The internal representation of &homalg; rings. <P/> ## (It is a representation of the &GAP; category <C>IsHomalgRing</C>.) ## </Description> ## </ManSection> ## <#/GAPDoc> ## DeclareRepresentation( "IsHomalgInternalRingRep", IsHomalgRing and IsHomalgRingOrFinitelyPresentedModuleRep, [ "ring", "homalgTable" ] ); ## DeclareRepresentation( "IsContainerForWeakPointersOnIdentityMatricesRep", IsContainerForWeakPointersRep, [ "weak_pointers" ] ); #################################### # # families and types: # #################################### # a new family: BindGlobal( "TheFamilyOfHomalgRingElements", NewFamily( "TheFamilyOfHomalgRingElements" ) ); # a new family: BindGlobal( "TheFamilyOfHomalgRings", CollectionsFamily( TheFamilyOfHomalgRingElements ) ); # a new type: BindGlobal( "TheTypeHomalgInternalRing", NewType( TheFamilyOfHomalgRings, IsHomalgInternalRingRep ) ); # a new family: BindGlobal( "TheFamilyOfContainersForWeakPointersOfIdentityMatrices", NewFamily( "TheFamilyOfContainersForWeakPointersOfIdentityMatrices" ) ); # a new type: BindGlobal( "TheTypeContainerForWeakPointersOnIdentityMatrices", NewType( TheFamilyOfContainersForWeakPointersOfIdentityMatrices, IsContainerForWeakPointersOnIdentityMatricesRep ) ); #################################### # # methods for attributes: # #################################### ## InstallMethod( Zero, "for homalg rings", [ IsHomalgInternalRingRep ], 10001, function( R ) return Zero( R!.ring ); end ); ## InstallMethod( Zero, "for homalg rings", [ IsHomalgInternalRingRep ], 10001, function( R ) local RP; RP := homalgTable( R ); if IsBound( RP!.Zero ) then return RP!.Zero; fi; TryNextMethod( ); end ); ## InstallMethod( One, "for homalg rings", [ IsHomalgInternalRingRep ], 1001, function( R ) return One( R!.ring ); end ); ## InstallMethod( One, "for homalg rings", [ IsHomalgInternalRingRep ], 1001, function( R ) local RP; RP := homalgTable( R ); if IsBound( RP!.One ) then return RP!.One; fi; TryNextMethod( ); end ); ## InstallMethod( MinusOne, "for homalg rings", [ IsHomalgInternalRingRep ], function( R ) return -One( R ); end ); ## InstallMethod( MinusOne, "for homalg rings", [ IsHomalgInternalRingRep ], function( R ) local RP; RP := homalgTable( R ); if IsBound( RP!.MinusOne ) then return RP!.MinusOne; fi; TryNextMethod( ); end ); ## InstallMethod( ZeroMutable, "for homalg ring elements", [ IsHomalgRingElement ], function( r ) return Zero( HomalgRing( r ) ); end ); ## InstallMethod( OneMutable, "for homalg ring elements", [ IsHomalgRingElement ], function( r ) return One( HomalgRing( r ) ); end ); ## InstallMethod( Inverse, "for homalg ring elements", [ IsHomalgRingElement ], function( r ) return One( r ) / r; end ); ## InstallMethod( MinusOneMutable, "for homalg ring elements", [ IsHomalgRingElement ], function( r ) return MinusOne( HomalgRing( r ) ); end ); ## InstallMethod( AssociatedPolynomialRing, "for homalg ring elements", [ IsHomalgRing and IsFieldForHomalg ], function( R ) local a, r; if not HasRationalParameters( R ) then Error( "the field has no rational parameters" ); elif not HasCoefficientsRing( R ) then Error( "the field has no subfield of coefficients" ); fi; r := CoefficientsRing( R ); a := RationalParameters( R ); return r * List( a, String ); end ); #################################### # # methods for operations: # #################################### ## InstallMethod( HomalgRing, "for homalg rings", [ IsHomalgRing ], function( R ) return R; end ); ## InstallMethod( HomalgRing, "for homalg ring elements", [ IsHomalgRingElement ], function( r ) return r!.ring; end ); ## InstallMethod( LT, "for homalg ring elements", [ IsHomalgRingElement, IsHomalgRingElement ], function( a, b ) return LT( String( a ), String( b ) ); end ); ## InstallMethod( INV, "for homalg ring elements", [ IsHomalgRingElement ], function( r ) return Inverse( r ); end ); ## InstallMethod( \*, "for homalg ring elements", [ IS_RAT, IsHomalgRingElement ], function( a, b ) if IS_INT( a ) then TryNextMethod( ); fi; return ( NUMERATOR_RAT( a ) * b ) / ( DENOMINATOR_RAT( a ) * One( b ) ); end ); ## InstallMethod( \*, "for homalg ring elements", [ IsHomalgRingElement, IS_RAT ], function( a, b ) if IS_INT( b ) then TryNextMethod( ); fi; return ( NUMERATOR_RAT( b ) * a ) / ( DENOMINATOR_RAT( b ) * One( a ) ); end ); ## InstallMethod( \+, "for homalg ring elements", [ IS_RAT, IsHomalgRingElement ], function( a, b ) return a * One( b ) + b; end ); ## InstallMethod( \+, "for homalg ring elements", [ IsHomalgRingElement, IS_RAT ], function( a, b ) return a + b * One( a ); end ); ## InstallMethod( Indeterminates, "for homalg rings", [ IsHomalgRing and HasIndeterminatesOfPolynomialRing ], function( R ) return IndeterminatesOfPolynomialRing( R ); end ); ## InstallMethod( Indeterminates, "for homalg rings", [ IsHomalgRing and HasIndeterminatesOfExteriorRing ], function( R ) return IndeterminatesOfExteriorRing( R ); end ); ## InstallMethod( Indeterminates, "for homalg rings", [ IsHomalgRing and HasIndeterminateCoordinatesOfRingOfDerivations ], function( R ) return Concatenation( IndeterminateCoordinatesOfRingOfDerivations( R ), IndeterminateDerivationsOfRingOfDerivations( R ) ); end ); ## InstallMethod( Indeterminates, "for homalg fields", [ IsHomalgRing and IsFieldForHomalg ], function( R ) return [ ]; end ); ## InstallMethod( AssignGeneratorVariables, "for homalg rings", [ IsHomalgRing ], function( R ) local indets; indets := Indeterminates( R ); DoAssignGenVars( indets ); return; end ); ## InstallMethod( ExportIndeterminates, "for homalg rings", [ IsHomalgRing ], function( R ) local indets, x_name, x; indets := Indeterminates( R ); for x in indets do x_name := String( x ); if IsBoundGlobal( x_name ) then if not IsHomalgRingElement( ValueGlobal( x_name ) ) then Error( "the name ", x_name, " is not bound to a homalg ring element\n" ); elif IsReadOnlyGlobal( x_name ) then MakeReadWriteGlobal( x_name ); fi; UnbindGlobal( x_name ); fi; BindGlobal( x_name, x ); od; return indets; end ); ## InstallMethod( ExportRationalParameters, "for homalg rings", [ IsHomalgRing and HasRationalParameters ], function( R ) local params, x_name, x; params := RationalParameters( R ); for x in params do x_name := String( x ); if IsBoundGlobal( x_name ) then if not IsHomalgRingElement( ValueGlobal( x_name ) ) then Error( "the name ", x_name, " is not bound to a homalg ring element\n" ); elif IsReadOnlyGlobal( x_name ) then MakeReadWriteGlobal( x_name ); fi; UnbindGlobal( x_name ); fi; BindGlobal( x_name, x ); od; return params; end ); ## InstallMethod( ExportVariables, "for homalg rings", [ IsHomalgRing ], function( R ) return ExportIndeterminates( R ); end ); ## InstallMethod( ExportVariables, "for homalg rings", [ IsHomalgRing and HasRationalParameters ], function( R ) return Concatenation( ExportIndeterminates( R ), ExportRationalParameters( R ) ); end ); ## InstallMethod( Indeterminate, "for homalg rings", [ IsHomalgRing, IsPosInt ], function( R, i ) return Indeterminates( R )[i]; end ); ## InstallMethod( ProductOfIndeterminates, "for homalg rings", [ IsHomalgRing ], function( R ) return Product( Indeterminates( R ) ); end ); ## InstallMethod( ProductOfIndeterminatesOverBaseRing, "for homalg rings", [ IsHomalgRing and HasIndeterminatesOfPolynomialRing ], function( R ) return Product( IndeterminatesOfPolynomialRing( R ) ); end ); ## InstallMethod( ProductOfIndeterminatesOverBaseRing, "for homalg rings", [ IsHomalgRing and HasRelativeIndeterminatesOfPolynomialRing ], 100, ## otherwise the above method is triggered :( function( R ) return Product( RelativeIndeterminatesOfPolynomialRing( R ) ); end ); ## provided to avoid branching in the code and always returns fail InstallMethod( PositionOfTheDefaultPresentation, "for ring elements", [ IsRingElement ], function( r ) return fail; end ); ## InstallMethod( \=, "for two homalg ring elements", [ IsHomalgRingElement, IsHomalgRingElement ], function( r1, r2 ) if IsIdenticalObj( HomalgRing( r1 ), HomalgRing( r2 ) ) then return IsZero( r1 - r2 ); fi; return false; end ); ## InstallMethod( \=, "for a rational and a homalg ring element", [ IS_RAT, IsHomalgRingElement ], function( r1, r2 ) return r1 / HomalgRing( r2 ) = r2; end ); ## InstallMethod( \=, "for a homalg ring element and a rational", [ IsHomalgRingElement, IS_RAT ], function( r1, r2 ) return r1 = r2 / HomalgRing( r1 ); end ); ## InstallMethod( StandardBasisRowVectors, "for homalg rings", [ IsInt, IsHomalgRing ], function( n, R ) local id; id := HomalgIdentityMatrix( n, R ); return List( [ 1 .. n ], r -> CertainRows( id, [ r ] ) ); end ); ## InstallMethod( StandardBasisColumnVectors, "for homalg rings", [ IsInt, IsHomalgRing ], function( n, R ) local id; id := HomalgIdentityMatrix( n, R ); return List( [ 1 .. n ], c -> CertainColumns( id, [ c ] ) ); end ); ## InstallMethod( RingName, "for homalg rings", [ IsHomalgRing ], function( R ) local RP, var, r, c; if HasName( R ) then return Name( R ); fi; ## ask the ring table RP := homalgTable( R ); if IsBound(RP!.RingName) then if IsFunction( RP!.RingName ) then r := RP!.RingName( R ); else r := RP!.RingName; fi; if r <> fail then return r; fi; fi; ## residue class rings/fields of the integers if HasIsResidueClassRingOfTheIntegers( R ) and IsResidueClassRingOfTheIntegers( R ) and HasCharacteristic( R ) then c := Characteristic( R ); if c = 0 then return "Z"; elif IsPrime( c ) then if HasDegreeOverPrimeField( R ) and DegreeOverPrimeField( R ) > 1 then r := [ "GF(", String( c ), "^", String( DegreeOverPrimeField( R ) ), ")" ]; else r := [ "GF(", String( c ), ")" ]; fi; else r := [ "Z/", String( c ), "Z" ]; fi; return String( Concatenation( r ) ); fi; ## the rationals if HasIsRationalsForHomalg( R ) and IsRationalsForHomalg( R ) then return "Q"; fi; return "(homalg ring)"; end ); ## InstallMethod( homalgRingStatistics, "for homalg rings", [ IsHomalgRing ], function( R ) return R!.statistics; end ); ## InstallMethod( IncreaseRingStatistics, "for homalg rings", [ IsHomalgRing, IsString ], function( R, s ) R!.statistics.(s) := R!.statistics.(s) + 1; end ); ## InstallMethod( DecreaseRingStatistics, "for homalg rings", [ IsHomalgRing, IsString ], function( R, s ) R!.statistics.(s) := R!.statistics.(s) - 1; end ); ## InstallOtherMethod( AsList, "for homalg internal rings", [ IsHomalgInternalRingRep ], function( r ) return AsList( r!.ring ); end ); ## InstallMethod( homalgSetName, "for homalg ring elements", [ IsHomalgRingElement, IsString ], SetName ); ## InstallMethod( Factors, "for homalg ring elements", [ IsHomalgRingElement ], function( r ) if not IsBound( r!.Factors ) then r!.Factors := Factors( EvalString( String( r ) ) ); fi; return r!.Factors; end ); ## InstallMethod( Roots, "for homalg ring elements", [ IsHomalgRingElement ], function( r ) local roots; if not IsBound( r!.Roots ) then roots := RootsOfUPol( EvalString( String( r ) ) ); Sort( roots ); r!.Roots := roots; fi; return r!.Roots; end ); ## InstallMethod( DecideZero, "for homalg ring elements", [ IsHomalgRingElement ], function( r ) IsZero( r ); return r; end ); ## InstallMethod( SetRingProperties, "for homalg rings", [ IsHomalgRing and IsFreePolynomialRing, IsHomalgRing, IsList ], function( S, R, var ) local param, paramS, d; d := Length( var ); if d > 0 then SetIsFinite( S, false ); fi; SetCoefficientsRing( S, R ); if HasRationalParameters( R ) then param := RationalParameters( R ); paramS := List( param, a -> a / S ); Perform( [ 1 .. Length( param ) ], function( i ) SetName( paramS[i], Name( param[i] ) ); end ); SetRationalParameters( S, paramS ); fi; if HasCharacteristic( R ) then SetCharacteristic( S, Characteristic( R ) ); fi; SetIsCommutative( S, true ); SetIndeterminatesOfPolynomialRing( S, var ); if HasContainsAField( R ) and ContainsAField( R ) then SetContainsAField( S, true ); fi; if d > 0 then SetIsLeftArtinian( S, false ); SetIsRightArtinian( S, false ); fi; if HasGlobalDimension( R ) then SetGlobalDimension( S, d + GlobalDimension( R ) ); fi; if HasKrullDimension( R ) then SetKrullDimension( S, d + KrullDimension( R ) ); fi; SetGeneralLinearRank( S, 1 ); ## Quillen-Suslin Theorem (see [McCRob, 11.5.5] if d = 1 then ## [McCRob, 11.5.7] SetElementaryRank( S, 1 ); elif d > 2 then SetElementaryRank( S, 2 ); fi; SetIsIntegralDomain( S, true ); SetBasisAlgorithmRespectsPrincipalIdeals( S, true ); end ); ## InstallMethod( SetRingProperties, "for homalg rings", [ IsHomalgRing and IsWeylRing, IsHomalgRing and IsFreePolynomialRing, IsList ], function( S, R, der ) local r, b, param, paramS, var, d; r := CoefficientsRing( R ); if HasBaseRing( R ) then b := BaseRing( R ); else b := r; fi; var := IndeterminatesOfPolynomialRing( R ); var := List( var, a -> a / S ); d := Length( var ); if d > 0 then SetIsFinite( S, false ); fi; SetCoefficientsRing( S, r ); if HasRationalParameters( r ) then param := RationalParameters( r ); paramS := List( param, a -> a / S ); Perform( [ 1 .. Length( param ) ], function( i ) SetName( paramS[i], Name( param[i] ) ); end ); SetRationalParameters( S, paramS ); fi; SetCharacteristic( S, Characteristic( R ) ); SetIsCommutative( S, der = [ ] ); SetCenter( S, Center( b ) ); SetIndeterminateCoordinatesOfRingOfDerivations( S, var ); if HasRelativeIndeterminatesOfPolynomialRing( R ) then SetRelativeIndeterminateCoordinatesOfRingOfDerivations( S, RelativeIndeterminatesOfPolynomialRing( R ) ); fi; SetIndeterminateDerivationsOfRingOfDerivations( S, der ); if d > 0 then SetIsLeftArtinian( S, false ); SetIsRightArtinian( S, false ); fi; SetIsLeftNoetherian( S, true ); SetIsRightNoetherian( S, true ); if HasGlobalDimension( r ) then SetGlobalDimension( S, d + GlobalDimension( r ) ); fi; if HasIsFieldForHomalg( b ) and IsFieldForHomalg( b ) and Characteristic( S ) = 0 then SetGeneralLinearRank( S, 2 ); ## [Stafford78], [McCRob, 11.2.15(i)] SetIsSimpleRing( S, true ); ## [Coutinho, Thm 2.2.1] fi; if HasIsIntegralDomain( r ) and IsIntegralDomain( r ) then SetIsIntegralDomain( S, true ); fi; if d > 0 then SetIsLeftPrincipalIdealRing( S, false ); SetIsRightPrincipalIdealRing( S, false ); SetIsPrincipalIdealRing( S, false ); fi; SetBasisAlgorithmRespectsPrincipalIdeals( S, true ); SetAreUnitsCentral( S, true ); end ); ## InstallMethod( SetRingProperties, "for homalg rings", [ IsHomalgRing and IsLocalizedWeylRing, IsString ], function( S, _var ) local var, d; var := SplitString( _var, ",", "[]" ); var := List( var, a -> a / S ); SetIndeterminateCoordinatesOfRingOfDerivations( S, var ); d := Length( var ); ## SetCoefficientsRing( S, r ); SetCharacteristic( S, 0 ); SetIsCommutative( S, false ); ## SetCenter( S, r ); SetIndeterminateCoordinatesOfRingOfDerivations( S, var ); ## SetIndeterminateDerivationsOfRingOfDerivations( S, der ); if d > 0 then SetIsLeftArtinian( S, false ); SetIsRightArtinian( S, false ); fi; SetIsLeftNoetherian( S, true ); SetIsRightNoetherian( S, true ); SetGlobalDimension( S, d + 0 ); ## Janet only knows Q as the coefficient ring ## SetGeneralLinearRank( S, 2 ); ## [Stafford78], [McCRob, 11.2.15(i)] SetIsSimpleRing( S, true ); ## [Coutinho, Thm 2.2.1] if d > 0 then SetIsPrincipalIdealRing( S, false ); fi; if d = 1 then SetIsLeftPrincipalIdealRing( S, true ); SetIsRightPrincipalIdealRing( S, true ); elif d > 0 then SetIsLeftPrincipalIdealRing( S, false ); SetIsRightPrincipalIdealRing( S, false ); fi; SetIsIntegralDomain( S, true ); SetBasisAlgorithmRespectsPrincipalIdeals( S, true ); SetAreUnitsCentral( S, false ); end ); ## InstallMethod( SetRingProperties, "for homalg rings", [ IsHomalgRing and IsExteriorRing, IsHomalgRing and IsFreePolynomialRing, IsList ], function( A, S, anti ) local r, d, param, paramA, comm, T; r := CoefficientsRing( S ); d := Length( anti ); SetCoefficientsRing( A, r ); if HasRationalParameters( r ) then param := RationalParameters( r ); paramA := List( param, a -> a / A ); Perform( [ 1 .. Length( param ) ], function( i ) SetName( paramA[i], Name( param[i] ) ); end ); SetRationalParameters( A, paramA ); fi; SetCharacteristic( A, Characteristic( S ) ); if d <= 1 or Characteristic( A ) = 2 then ## the Center is then automatically set to S SetIsCommutative( A, true ); else ## the center is the even part, which is ## bigger than the coefficients ring r SetIsCommutative( A, false ); fi; SetIsSuperCommutative( A, true ); SetIsIntegralDomain( A, d = 0 ); comm := [ ]; if HasBaseRing( S ) then T := BaseRing( S ); if HasIndeterminatesOfPolynomialRing( T ) then comm := IndeterminatesOfPolynomialRing( T ); fi; fi; SetIndeterminateAntiCommutingVariablesOfExteriorRing( A, anti ); SetIndeterminatesOfExteriorRing( A, Concatenation( comm, anti ) ); SetBasisAlgorithmRespectsPrincipalIdeals( A, true ); SetAreUnitsCentral( S, true ); end ); ## InstallMethod( SetRingProperties, "for homalg rings", [ IsHomalgRing and IsPrincipalIdealRing and IsCommutative, IsInt ], function( R, c ) local RP, powers; SetCharacteristic( R, c ); if HasIsFieldForHomalg( R ) and IsFieldForHomalg( R ) then TryNextMethod( ); elif HasIsResidueClassRingOfTheIntegers( R ) and IsResidueClassRingOfTheIntegers( R ) then TryNextMethod( ); fi; if c = 0 then SetContainsAField( R, false ); SetIsIntegralDomain( R, true ); SetIsArtinian( R, false ); SetKrullDimension( R, 1 ); ## FIXME: it is not set automatically although an immediate method is installed elif not IsPrime( c ) then SetIsSemiLocalRing( R, true ); SetIsIntegralDomain( R, false ); powers := List( Collected( FactorsInt( c ) ), a -> a[2] ); if Set( powers ) = [ 1 ] then SetIsSemiSimpleRing( R, true ); else SetIsRegular( R, false ); if Length( powers ) = 1 then SetIsLocal( R, true ); fi; fi; SetKrullDimension( R, 0 ); fi; RP := homalgTable( R ); if HasIsIntegralDomain( R ) and IsIntegralDomain( R ) then if IsBound( RP!.RowRankOfMatrixOverDomain ) then RP!.RowRankOfMatrix := RP!.RowRankOfMatrixOverDomain; fi; if IsBound( RP!.ColumnRankOfMatrixOverDomain ) then RP!.ColumnRankOfMatrix := RP!.ColumnRankOfMatrixOverDomain; fi; fi; SetBasisAlgorithmRespectsPrincipalIdeals( R, true ); end ); ## InstallMethod( SetRingProperties, "for homalg rings", [ IsHomalgRing and IsResidueClassRingOfTheIntegers, IsInt ], function( R, c ) local RP, powers; SetCharacteristic( R, c ); SetIsRationalsForHomalg( R, false ); if c = 0 then SetIsIntegersForHomalg( R, true ); SetContainsAField( R, false ); SetIsArtinian( R, false ); SetKrullDimension( R, 1 ); ## FIXME: it is not set automatically although an immediate method is installed elif IsPrime( c ) then SetIsFieldForHomalg( R, true ); SetRingProperties( R, c ); else SetIsSemiLocalRing( R, true ); SetIsIntegralDomain( R, false ); powers := List( Collected( FactorsInt( c ) ), a -> a[2] ); if Set( powers ) = [ 1 ] then SetIsSemiSimpleRing( R, true ); else SetIsRegular( R, false ); if Length( powers ) = 1 then SetIsLocal( R, true ); fi; fi; SetKrullDimension( R, 0 ); fi; RP := homalgTable( R ); if HasIsIntegralDomain( R ) and IsIntegralDomain( R ) then if IsBound( RP!.RowRankOfMatrixOverDomain ) then RP!.RowRankOfMatrix := RP!.RowRankOfMatrixOverDomain; fi; if IsBound( RP!.ColumnRankOfMatrixOverDomain ) then RP!.ColumnRankOfMatrix := RP!.ColumnRankOfMatrixOverDomain; fi; fi; SetBasisAlgorithmRespectsPrincipalIdeals( R, true ); end ); ## InstallMethod( SetRingProperties, "for homalg rings", [ IsHomalgRing and IsFieldForHomalg, IsInt ], function( R, c ) local RP; SetCharacteristic( R, c ); if HasRationalParameters( R ) and Length( RationalParameters( R ) ) > 0 then SetIsRationalsForHomalg( R, false ); SetIsResidueClassRingOfTheIntegers( R, false ); else SetDegreeOverPrimeField( R, 1 ); fi; RP := homalgTable( R ); if IsBound( RP!.RowRankOfMatrixOverDomain ) then RP!.RowRankOfMatrix := RP!.RowRankOfMatrixOverDomain; fi; if IsBound( RP!.ColumnRankOfMatrixOverDomain ) then RP!.ColumnRankOfMatrix := RP!.ColumnRankOfMatrixOverDomain; fi; SetFilterObj( R, IsField ); SetLeftActingDomain( R, R ); SetBasisAlgorithmRespectsPrincipalIdeals( R, true ); end ); ## InstallMethod( SetRingProperties, "for homalg rings", [ IsHomalgRing and IsFieldForHomalg, IsInt, IsInt ], function( R, c, d ) local RP; SetCharacteristic( R, c ); SetDegreeOverPrimeField( R, d ); if HasRationalParameters( R ) and Length( RationalParameters( R ) ) > 0 then SetIsRationalsForHomalg( R, false ); SetIsResidueClassRingOfTheIntegers( R, false ); fi; RP := homalgTable( R ); if IsBound( RP!.RowRankOfMatrixOverDomain ) then RP!.RowRankOfMatrix := RP!.RowRankOfMatrixOverDomain; fi; if IsBound( RP!.ColumnRankOfMatrixOverDomain ) then RP!.ColumnRankOfMatrix := RP!.ColumnRankOfMatrixOverDomain; fi; SetFilterObj( R, IsField ); SetLeftActingDomain( R, R ); SetBasisAlgorithmRespectsPrincipalIdeals( R, true ); end ); ## InstallMethod( UnusedVariableName, "for a homalg ring and a string", [ IsHomalgRing, IsString ], function( R, t ) local var; var := [ ]; if HasRationalParameters( R ) then Append( var, List( RationalParameters( R ), Name ) ); fi; if HasIndeterminatesOfPolynomialRing( R ) then Append( var, List( IndeterminatesOfPolynomialRing( R ), Name ) ); fi; while true do if not t in var then return t; fi; t := Concatenation( t, "_" ); od; end ); #################################### # # constructor functions and methods: # #################################### ## InstallGlobalFunction( CreateHomalgRing, function( arg ) local nargs, r, IdentityMatrices, statistics, asserts, homalg_ring, table, properties, ar, type, matrix_type, ring_element_constructor, finalizers, c, el; nargs := Length( arg ); if nargs = 0 then Error( "expecting a ring as the first argument\n" ); fi; r := arg[1]; IdentityMatrices := ContainerForWeakPointers( TheTypeContainerForWeakPointersOnIdentityMatrices ); Unbind( IdentityMatrices!.active ); Unbind( IdentityMatrices!.deleted ); Unbind( IdentityMatrices!.accessed ); Unbind( IdentityMatrices!.cache_misses ); statistics := rec( BasisOfRowModule := 0, BasisOfColumnModule := 0, BasisOfRowsCoeff := 0, BasisOfColumnsCoeff := 0, DecideZeroRows := 0, DecideZeroColumns := 0, DecideZeroRowsEffectively := 0, DecideZeroColumnsEffectively := 0, SyzygiesGeneratorsOfRows := 0, SyzygiesGeneratorsOfColumns := 0, RelativeSyzygiesGeneratorsOfRows := 0, RelativeSyzygiesGeneratorsOfColumns := 0, PartiallyReducedBasisOfRowModule := 0, PartiallyReducedBasisOfColumnModule := 0, ReducedBasisOfRowModule := 0, ReducedBasisOfColumnModule := 0, ReducedSyzygiesGeneratorsOfRows := 0, ReducedSyzygiesGeneratorsOfColumns := 0 ); ## <#GAPDoc Label="asserts"> ## Below you can find the record of the available level-4 assertions, ## which is a &GAP;-component of every &homalg; ring. Each assertion can ## thus be overwritten by package developers or even ordinary users. ## <Listing Type="Code"><![CDATA[ asserts := rec( BasisOfRowModule := function( B ) return ( NrRows( B ) = 0 ) = IsZero( B ); end, BasisOfColumnModule := function( B ) return ( NrColumns( B ) = 0 ) = IsZero( B ); end, BasisOfRowsCoeff := function( B, T, M ) return B = T * M; end, BasisOfColumnsCoeff := function( B, M, T ) return B = M * T; end, DecideZeroRows_Effectively := function( M, A, B ) return M = DecideZeroRows( A, B ); end, DecideZeroColumns_Effectively := function( M, A, B ) return M = DecideZeroColumns( A, B ); end, DecideZeroRowsEffectively := function( M, A, T, B ) return M = A + T * B; end, DecideZeroColumnsEffectively := function( M, A, B, T ) return M = A + B * T; end, DecideZeroRowsWRTNonBasis := function( B ) local R; R := HomalgRing( B ); if not ( HasIsBasisOfRowsMatrix( B ) and IsBasisOfRowsMatrix( B ) ) and IsBound( R!.DecideZeroWRTNonBasis ) then if R!.DecideZeroWRTNonBasis = "warn" then Info( InfoWarning, 1, "about to reduce with respect to a matrix", "with IsBasisOfRowsMatrix not set to true" ); elif R!.DecideZeroWRTNonBasis = "error" then Error( "about to reduce with respect to a matrix", "with IsBasisOfRowsMatrix not set to true\n" ); fi; fi; end, DecideZeroColumnsWRTNonBasis := function( B ) local R; R := HomalgRing( B ); if not ( HasIsBasisOfColumnsMatrix( B ) and IsBasisOfColumnsMatrix( B ) ) and IsBound( R!.DecideZeroWRTNonBasis ) then if R!.DecideZeroWRTNonBasis = "warn" then Info( InfoWarning, 1, "about to reduce with respect to a matrix", "with IsBasisOfColumnsMatrix not set to true" ); elif R!.DecideZeroWRTNonBasis = "error" then Error( "about to reduce with respect to a matrix", "with IsBasisOfColumnsMatrix not set to true\n" ); fi; fi; end, ReducedBasisOfRowModule := function( M, B ) return GenerateSameRowModule( B, BasisOfRowModule( M ) ); end, ReducedBasisOfColumnModule := function( M, B ) return GenerateSameColumnModule( B, BasisOfColumnModule( M ) ); end, ReducedSyzygiesGeneratorsOfRows := function( M, S ) return GenerateSameRowModule( S, SyzygiesGeneratorsOfRows( M ) ); end, ReducedSyzygiesGeneratorsOfColumns := function( M, S ) return GenerateSameColumnModule( S, SyzygiesGeneratorsOfColumns( M ) ); end, ); ## ]]></Listing> ## <#/GAPDoc> homalg_ring := rec( ring := r, IdentityMatrices := IdentityMatrices, statistics := statistics, asserts := asserts, DecideZeroWRTNonBasis := "warn/error" ); if nargs > 1 and IshomalgTable( arg[nargs] ) then table := arg[nargs]; else table := CreateHomalgTable( r ); fi; if not IsBound( table!.InitialMatrix ) and IsBound( table!.ZeroMatrix ) then table!.InitialMatrix := table!.ZeroMatrix; fi; if not IsBound( table!.InitialIdentityMatrix ) and IsBound( table!.IdentityMatrix ) then table!.InitialIdentityMatrix := table!.IdentityMatrix; fi; properties := [ ]; for ar in arg{[ 2 .. nargs ]} do if IsFilter( ar ) then Add( properties, ar ); elif not IsBound( type ) and IsList( ar ) and Length( ar ) = 2 and ForAll( ar, IsType ) then type := ar; elif not IsBound( ring_element_constructor ) and IsFunction( ar ) then ring_element_constructor := ar; elif not IsBound( finalizers ) and IsList( ar ) and ForAll( ar, IsFunction ) then finalizers := ar; fi; od; if IsBound( type ) then matrix_type := type[2]; type := type[1]; elif IsSemiringWithOneAndZero( r ) then matrix_type := ValueGlobal( "TheTypeHomalgInternalMatrix" ); ## will be defined later in HomalgMatrix.gi type := TheTypeHomalgInternalRing; else Error( "the types of the ring and matrices were not specified\n" ); fi; ## Objectify: ObjectifyWithAttributes( homalg_ring, type, homalgTable, table ); if IsBound( matrix_type ) then SetTypeOfHomalgMatrix( homalg_ring, matrix_type ); fi; if properties <> [ ] then for ar in properties do Setter( ar )( homalg_ring, true ); od; fi; if IsBound( HOMALG_MATRICES.RingCounter ) then HOMALG_MATRICES.RingCounter := HOMALG_MATRICES.RingCounter + 1; else HOMALG_MATRICES.RingCounter := 1; fi; ## this has to be done before we call ## ring_element_constructor below homalg_ring!.creation_number := HOMALG_MATRICES.RingCounter; ## do not invoke SetRingProperties here, since I might be ## the first step of creating a residue class ring! ## this has to be invoked before we set the distinguished ring elements below; ## these functions are used to finalize the construction of the ring if IsBound( finalizers ) then Perform( finalizers, function( f ) f( homalg_ring ); end ); fi; ## add distinguished ring elements like 0 and 1 ## (sometimes also -1) to the homalg table: if IsBound( ring_element_constructor ) then for c in NamesOfComponents( table ) do if IsRingElement( table!.(c) ) then table!.(c) := ring_element_constructor( table!.(c), homalg_ring ); fi; od; ## set the attribute SetRingElementConstructor( homalg_ring, ring_element_constructor ); fi; if IsBound( HOMALG_MATRICES.ByASmallerPresentation ) and HOMALG_MATRICES.ByASmallerPresentation = true then homalg_ring!.ByASmallerPresentation := true; fi; ## e.g. needed to construct residue class rings homalg_ring!.ConstructorArguments := arg; return homalg_ring; end ); ## <#GAPDoc Label="HomalgRingOfIntegers"> ## <ManSection> ## <Func Arg="" Name="HomalgRingOfIntegers" Label="constructor for the integers"/> ## <Returns>a &homalg; ring</Returns> ## <Func Arg="c" Name="HomalgRingOfIntegers" Label="constructor for the residue class rings of the integers"/> ## <Returns>a &homalg; ring</Returns> ## <Description> ## The no-argument form returns the ring of integers <M>&ZZ;</M> for &homalg;. <P/> ## The one-argument form accepts an integer <A>c</A> and returns ## the ring <M>&ZZ; / c </M> for &homalg;: ## <List> ## <Item><A>c</A><M> = 0</M> defaults to <M>&ZZ;</M></Item> ## <Item>if <A>c</A> is a prime power then the package &GaussForHomalg; is loaded (if it fails to load an error is issued)</Item> ## <Item>otherwise, the residue class ring constructor <C>/</C> ## (&see; <Ref Oper="\/" Label="constructor for residue class rings" Style="Number"/>) is invoked</Item> ## </List> ## The operation <C>SetRingProperties</C> is automatically invoked to set the ring properties. <P/> ## If for some reason you don't want to use the &GaussForHomalg; package (maybe because you didn't install it), then use<P/> ## <C>HomalgRingOfIntegers</C>( ) <C>/</C> <A>c</A>; <P/> ## but note that the computations will then be considerably slower. ## </Description> ## </ManSection> ## <#/GAPDoc> ## InstallGlobalFunction( HomalgRingOfIntegers, function( arg ) local nargs, R, c, d, rel; nargs := Length( arg ); if nargs = 0 or arg[1] = 0 then c := 0; R := CreateHomalgRing( Integers ); elif IsInt( arg[1] ) then c := arg[1]; if Length( Collected( FactorsInt( c ) ) ) = 1 then if LoadPackage( "GaussForHomalg" ) <> true then Error( "the package GaussForHomalg failed to load\n" ); fi; if IsPrime( c ) then if nargs > 1 and IsPosInt( arg[2] ) then d := arg[2]; else d := 1; fi; R := CreateHomalgRing( GF( c, d ) ); R!.NameOfPrimitiveElement := Concatenation( "Z", String( c ), "_", String( d ) ); SetIsFieldForHomalg( R, true ); SetRingProperties( R, c, d ); else R := CreateHomalgRing( ZmodnZ( c ) ); fi; else R := HomalgRingOfIntegers( ); rel := HomalgRingRelationsAsGeneratorsOfLeftIdeal( [ c ], R ); return R / rel; fi; else Error( "the first argument must be an integer\n" ); fi; SetIsResidueClassRingOfTheIntegers( R, true ); SetRingProperties( R, c ); return R; end ); ## <#GAPDoc Label="HomalgFieldOfRationals"> ## <ManSection> ## <Func Arg="" Name="HomalgFieldOfRationals" Label="constructor for the field of rationals"/> ## <Returns>a &homalg; ring</Returns> ## <Description> ## The package &GaussForHomalg; is loaded and the field of rationals <M>&QQ;</M> is returned. ## If &GaussForHomalg; fails to load an error is issued. <P/> ## The operation <C>SetRingProperties</C> is automatically invoked to set the ring properties. ## </Description> ## </ManSection> ## <#/GAPDoc> ## InstallGlobalFunction( HomalgFieldOfRationals, function( arg ) local R; if LoadPackage( "GaussForHomalg" ) <> true then Error( "the package GaussForHomalg failed to load\n" ); fi; R := CreateHomalgRing( Rationals ); SetIsRationalsForHomalg( R, true ); SetRingProperties( R, 0 ); return R; end ); ## InstallOtherMethod( \in, "for an integer and a homalg internal ring", [ IsObject, IsHomalgInternalRingRep ], 100001, function( z, R ) if not IsInt( Zero( R ) ) then TryNextMethod( ); fi; if IsInt( z ) then return true; fi; if not ( HasIsFieldForHomalg( R ) and IsFieldForHomalg( R ) ) then TryNextMethod( ); fi; if IsRat( z ) then return true; fi; TryNextMethod( ); end ); ## InstallMethod( ParseListOfIndeterminates, "for lists", [ IsList ], function( _indets ) local err, l, indets, i, v, l1, l2, p1, p2, c; if _indets = [ ] then return [ ]; fi; err := function( ) Error( "a list of variable strings or range strings is expected\n" ); end; if ForAll( _indets, IsRingElement and HasName ) then return ParseListOfIndeterminates( List( _indets, Name ) ); fi; if not ForAll( _indets, e -> IsStringRep( e ) or ( IsList( e ) and ForAll( e, IsInt ) ) ) then TryNextMethod( ); fi; l := Length( _indets ); indets := [ ]; for i in [ 1 .. l ] do v := _indets[i]; if Position( v, ',' ) <> fail then err( ); elif ForAll( v, IsInt ) then ## do nothing elif Position( v, '.' ) = fail then if i < l and ForAll( _indets[ i + 1 ], IsInt ) then Append( indets, List( _indets[ i + 1 ], i -> Concatenation( v, String( i ) ) ) ); else Add( indets, v ); fi; elif PositionSublist( v, ".." ) = fail then err( ); else v := SplitString( v, "." ); v := Filtered( v, s -> not IsEmpty( s ) ); if Length( v ) <> 2 then err( ); fi; # p1 := PositionProperty( v[1], c -> Position( "0123456789", c ) <> fail ); # p2 := PositionProperty( v[2], c -> Position( "0123456789", c ) <> fail ); l1 := Flat( List( "0123456789", c -> Positions( v[1], c ) ) ); Sort( l1 ); l2 := Flat( List( "0123456789", c -> Positions( v[2], c ) ) ); Sort( l2 ); if l1 = [] or l2 = [] then err( ); fi; p1 := l1[1]; p2 := l2[1]; for i in [ 2 .. Length( l1 ) ] do if l1[i-1] + 1 <> l1[i] then p1 := l1[i]; fi; od; for i in [ 2 .. Length( l2 ) ] do if l2[i-1] + 1 <> l2[i] then p2 := l2[i]; fi; od; if p1 = 1 then err( ); fi; c := v[1]{[ 1 .. p1 - 1 ]}; if p1 = p2 and c <> v[2]{[ 1 .. p2 - 1 ]} then err( ); fi; p1 := EvalString( v[1]{[ p1 .. Length( v[1] ) ]} ); p2 := EvalString( v[2]{[ p2 .. Length( v[2] ) ]} ); Append( indets, List( [ p1 .. p2 ], i -> Concatenation( c, String( i ) ) ) ); fi; od; return indets; end ); ## InstallMethod( \*, "for homalg rings", [ IsHomalgRing, IsList ], 1001, ## a high rank is necessary to overwrite the default behaviour of applying R to each list element function( R, indets ) return PolynomialRing( R, ParseListOfIndeterminates( indets ) ); end ); ## InstallMethod( \*, "for homalg rings", [ IsHomalgRing, IsString ], 1001, ## for this method to be triggered first it has to have at least the same rank as the above method function( R, indets ) if indets = "" then return R; else return R * SplitString( indets, "," ); fi; end ); ## InstallMethod( \*, "for homalg rings", [ IsHomalgRing and IsFreePolynomialRing and HasCoefficientsRing, IsHomalgRing and IsFreePolynomialRing and HasCoefficientsRing ], function( R1, R2 ) local r, var2; r := CoefficientsRing( R1 ); if not IsIdenticalObj( r, CoefficientsRing( R2 ) ) then TryNextMethod( ); fi; var2 := IndeterminatesOfPolynomialRing( R2 ); var2 := List( var2, Name ); var2 := JoinStringsWithSeparator( var2 ); return PolynomialRing( R1, var2 ); end ); ## InstallMethod( PolynomialRing, "for homalg rings", [ IsHomalgRing, IsString ], 1001, function( R, _var ) local var; if _var = "" then return R; fi; var := ParseListOfIndeterminates( SplitString( _var, "," ) ); return PolynomialRing( R, var ); end ); ## InstallMethod( RingOfDerivations, "for homalg rings", [ IsHomalgRing and IsCommutative, IsString ], 1001, function( S, _der ) local der, A; der := ParseListOfIndeterminates( SplitString( _der, "," ) ); A := RingOfDerivations( S, der ); S!.RingOfDerivations := A; return A; end ); ## InstallMethod( RingOfDerivations, "for homalg rings", [ IsHomalgRing ], function( R ) local var, A; if IsBound(R!.RingOfDerivations) then return R!.RingOfDerivations; fi; if HasRelativeIndeterminatesOfPolynomialRing( R ) then var := RelativeIndeterminatesOfPolynomialRing( R ); else var := IndeterminatesOfPolynomialRing( R ); fi; var := List( var, x -> Concatenation( "D", Name( x ) ) ); A := RingOfDerivations( R, var ); R!.RingOfDerivations := A; return A; end ); ## InstallMethod( ExteriorRing, "for homalg rings", [ IsHomalgRing and IsFreePolynomialRing, IsList ], function( S, _anti ) local anti, Base, A; if IsString( _anti ) then return ExteriorRing( S, SplitString( _anti, "," ) ); else anti := ParseListOfIndeterminates( _anti ); fi; if HasBaseRing( S ) then Base := BaseRing( S ); else Base := CoefficientsRing( S ); fi; A := ExteriorRing( S, CoefficientsRing( S ), Base, anti ); SetRingProperties( A, S, anti ); return A; end ); ## InstallMethod( KoszulDualRing, "for homalg rings", [ IsHomalgRing and IsFreePolynomialRing, IsList ], function( S, anti ) local A; if IsBound(S!.KoszulDualRing) then return S!.KoszulDualRing; fi; A := ExteriorRing( S, anti ); ## thanks GAP4 A!.KoszulDualRing := S; S!.KoszulDualRing := A; return A; end ); ## InstallMethod( KoszulDualRing, "for homalg rings", [ IsHomalgRing ], 10000, function( S ) if IsBound(S!.KoszulDualRing) then return S!.KoszulDualRing; fi; TryNextMethod( ); end ); ## InstallMethod( KoszulDualRing, "for homalg rings", [ IsHomalgRing and IsFreePolynomialRing ], function( S ) local l, Base, l_base, s1, s2, i; l := IndeterminatesOfPolynomialRing( S ); if HasBaseRing( S ) then Base := BaseRing( S ); else Base := CoefficientsRing( S ); fi; if HasIsFreePolynomialRing( Base ) and IsFreePolynomialRing( Base ) then l_base := List( Indeterminates( Base ), a -> a / S ); else l_base := []; fi; l := Difference( l, l_base ); s1 := List( l, String ); l := Length( l ); s2 := List( [ 0 .. l - 1 ], a -> Concatenation( "e", String( a ) ) ); for i in s1 do if not ( Position( s2, i ) = fail ) then Info( InfoWarning, 1, "KoszulDualRing: Variable name ", i, " already in use" ); fi; od; return KoszulDualRing( S, s2 ); end ); ## InstallGlobalFunction( HomalgRingElement, function( arg ) local nargs, R; nargs := Length( arg ); R := arg[nargs]; if HasRingElementConstructor( R ) then return CallFuncList( RingElementConstructor( R ), arg ); elif not IsHomalgInternalRingRep( R ) then Error( "the non-internal homalg ring must contain a ring element constructor as the attribute RingElementConstructor\n" ); elif IsString( arg[1] ) then return One( R ) * EvalString( arg[1] ); fi; return One( R ) * arg[1]; end ); ## InstallMethod( \/, "for ring elements", [ IsRingElement, IsHomalgRing ], function( r, R ) return HomalgRingElement( String( r ), R ); end ); ## InstallMethod( \/, "for strings", [ IsString, IsHomalgRing ], function( r, R ) return HomalgRingElement( r, R ); end ); ## InstallMethod( \/, "for homalg ring elements", [ IsHomalgRingElement, IsHomalgRing ], function( r, R ) if IsIdenticalObj( HomalgRing( r ), R ) then return r; fi; return HomalgRingElement( String( r ), R ); end ); ## InstallGlobalFunction( StringToElementStringList, function( arg ) return SplitString( arg[1], ",", "[ ]\n" ); end ); ## InstallGlobalFunction( _CreateHomalgRingToTestProperties, function( arg ) local homalg_ring, type; homalg_ring := rec( ); type := TheTypeHomalgInternalRing; ## Objectify: CallFuncList( ObjectifyWithAttributes, Concatenation([ homalg_ring, type ], arg ) ); return homalg_ring; end ); ## InstallMethod( UnivariatePolynomial, "for a list and a string", [ IsList, IsString ], function( coeffs, r ) local pol; pol := List( Reversed( [ 1 .. Length( coeffs ) ] ), i -> Concatenation( "(", String( coeffs[i] ), ")*", r, "^", String( i - 1 ) ) ); return JoinStringsWithSeparator( pol, "+" ); end ); ## InstallMethod( Homogenization, "for a homalg ring element and a homalg ring", [ IsHomalgRingElement, IsHomalgRing ], function( r, S ) local R, d, indetsR, indetsS, indR, indS, z, coeffs, monoms, diff; if IsZero( r ) then return Zero( S ); fi; R := HomalgRing( r ); if not HasIsFreePolynomialRing( R ) and IsFreePolynomialRing( R ) and not HasIsFreePolynomialRing( S ) and IsFreePolynomialRing( S ) then TryNextMethod( ); fi; d := Degree( r ); if d = 0 then return r / S; fi; indetsR := Indeterminates( R ); indetsS := Indeterminates( S ); indS := List( indetsS, String ); indR := List( indetsR, String ); if not IsSubset( indS, indR ) then Error( "the indeterminates of the second argument do not contain the indeterminates of the ring underlying the given ring element\n" ); fi; z := Difference( indS, indR ); if Length( z ) <> 1 then Error( "the indeterminates of the second argument are not exactly one more than the indeterminates of the ring underlying the given ring element\n" ); fi; z := Filtered( indetsS, a -> String( a ) = z[1] )[1]; coeffs := Coefficients( r ); monoms := coeffs!.monomials; coeffs := List( EntriesOfHomalgMatrix( coeffs ), c -> c / S ); monoms := List( monoms, m -> ( m / S ) * z^( d - Degree( m ) ) ); return Sum( ListN( coeffs, monoms, \* ) ); end ); ## InstallMethod( \*, "for an FFE and a homalg ring element", [ IsFFE, IsHomalgRingElement ], function( f, r ) local R, e; R := HomalgRing( r ); e := LogFFE( f, Z( Characteristic( R ), DegreeOverPrimeField( R ) ) ); return PrimitiveElement( R )^e * r; end ); ## InstallMethod( \*, "for a homalg ring element and an FFE", [ IsHomalgRingElement, IsFFE ], function( r, f ) return f * r; end ); ## the second argument is there for method selection InstallMethod( LcmOp, "for homalg objects", [ IsList, IsHomalgRingElement ], function( L, r ) return Iterated( L, LcmOp ); end ); ## InstallMethod( LcmOp, "for homalg ring elements", [ IsHomalgRingElement, IsHomalgRingElement ], function( p, q ) if IsZero( p ) or IsZero( q ) then return Zero( p ); fi; return p * q / GcdOp( p, q ); end ); #################################### # # View, Print, and Display methods: # #################################### ## InstallMethod( String, "for homalg rings", [ IsHomalgRing ], RingName ); ## InstallMethod( ViewObj, "for homalg rings", [ IsHomalgRing ], 100, function( o ) Print( RingName( o ) ); end ); ## InstallMethod( Display, "for homalg rings", [ IsHomalgRing ], function( o ) Print( "<A" ); if HasIsZero( o ) and IsZero( o ) then Print( " zero" ); fi; if IsBound( o!.description ) then Print( o!.description ); elif IsHomalgInternalRingRep( o ) then Print( "n internal" ); fi; if IsPreHomalgRing( o ) then Print( " pre-homalg" ); fi; Print( " ring>", "\n" ); end ); ## InstallMethod( DisplayRing, "for homalg rings", [ IsHomalgRing ], function( o ) Display( o ); end ); ## InstallMethod( ViewObj, "for homalg ring elements", [ IsHomalgRingElement ], function( o ) Print( Name( o ) ); ## this sets the attribute Name and the view method is never triggered again (as long as Name is set) end ); ## InstallMethod( Display, "for homalg ring elements", [ IsHomalgRingElement ], function( o ) Print( Name( o ), "\n" ); ## this sets the attribute Name and the display method is never triggered again (as long as Name is set) end ); ## InstallMethod( Display, "for weak pointer containers of identity matrices", [ IsContainerForWeakPointersOnIdentityMatricesRep ], function( o ) local weak_pointers; weak_pointers := o!.weak_pointers; Print( Filtered( [ 1 .. LengthWPObj( weak_pointers ) ], i -> IsBoundElmWPObj( weak_pointers, i ) ), "\n" ); end );