#################################### # # 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 ) );
#################################### # # global variables: # ####################################
##
InstallValue( CommonHomalgTableForRings,
rec(
RingName := function( R )
local minimal_polynomial, var, brackets, r;
if IsBound( R!.MinimalPolynomialOfPrimitiveElement ) then
minimal_polynomial := R!.MinimalPolynomialOfPrimitiveElement; fi;
## the Weyl algebra (relative version): if HasRelativeIndeterminateDerivationsOfRingOfDerivations( R ) then
var := RelativeIndeterminateDerivationsOfRingOfDerivations( R );
brackets := [ "<", ">" ];
## the Weyl algebra: elif HasIndeterminateDerivationsOfRingOfDerivations( R ) then
var := IndeterminateDerivationsOfRingOfDerivations( R );
brackets := [ "<", ">" ];
## the exterior algebra (relative version): elif HasRelativeIndeterminateAntiCommutingVariablesOfExteriorRing( R ) then
var := RelativeIndeterminateAntiCommutingVariablesOfExteriorRing( R );
brackets := [ "{", "}" ];
## the exterior algebra: elif HasIndeterminateAntiCommutingVariablesOfExteriorRing( R ) then
var := IndeterminateAntiCommutingVariablesOfExteriorRing( R );
brackets := [ "{", "}" ];
## the pseudo shift algebra: elif HasIndeterminateShiftsOfShiftAlgebra( R ) then
var := IndeterminateShiftsOfShiftAlgebra( R );
brackets := [ "<", ">" ];
## the pseudo shift algebra: elif HasIndeterminateShiftsOfRationalShiftAlgebra( R ) then
var := IndeterminateShiftsOfRationalShiftAlgebra( R );
brackets := [ "<", ">" ];
## the pseudo double-shift algebra: elif HasIndeterminateShiftsOfPseudoDoubleShiftAlgebra( R ) then
var := IndeterminateShiftsOfPseudoDoubleShiftAlgebra( R );
brackets := [ "<", ">" ];
## the pseudo double-shift algebra: elif HasIndeterminateShiftsOfRationalPseudoDoubleShiftAlgebra( R ) then
var := IndeterminateShiftsOfRationalPseudoDoubleShiftAlgebra( R );
brackets := [ "<", ">" ];
## the biased double-shift algebra: elif HasIndeterminateShiftsOfBiasedDoubleShiftAlgebra( R ) then
var := IndeterminateShiftsOfBiasedDoubleShiftAlgebra( R );
brackets := [ "<", ">" ];
## the (free) polynomial ring (relative version): elif HasBaseRing( R ) and HasRelativeIndeterminatesOfPolynomialRing( R ) and
not IsIdenticalObj( R, BaseRing( R ) ) then
var := RelativeIndeterminatesOfPolynomialRing( R );
brackets := [ "[", "]" ];
## the (free) polynomial ring: elif HasIndeterminatesOfPolynomialRing( R ) then
var := IndeterminatesOfPolynomialRing( R );
brackets := [ "[", "]" ];
elif HasRationalParameters( R ) then
var := RationalParameters( R );
if IsBound( minimal_polynomial ) then
brackets := [ "[", "]" ]; else
brackets := [ "(", ")" ]; fi;
fi;
if not IsBound( var ) then
return fail; fi;
var := JoinStringsWithSeparator( List( var, String ) );
var := Concatenation( brackets[1], var, brackets[2] );
if HasBaseRing( R ) and HasCoefficientsRing( R ) and
not IsIdenticalObj( BaseRing( R ), CoefficientsRing( R ) ) then
r := RingName( BaseRing( R ) ); elif HasCoefficientsRing( R ) then
r := CoefficientsRing( R ); if IsBound( r!.MinimalPolynomialOfPrimitiveElement ) and IsSubset( RingName( r ), "/" ) then
r := Concatenation( "(", RingName( r ), ")" ); else
r := RingName( r ); fi; else
r := "(some ring)"; fi;
r := Concatenation( r, var );
if IsBound( minimal_polynomial ) then
r := Concatenation( r, "/(", minimal_polynomial, ")" ); fi;
return String( r );
end,
)
);
#################################### # # methods for attributes: # ####################################
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;
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;
for x in params do
x_name := ShallowCopy( String( x ) );
RemoveCharacters( x_name, "()" ); 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 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 ],
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 = 0then
return "Z"; elif IsPrime( c ) then if HasDegreeOverPrimeField( R ) and DegreeOverPrimeField( R ) > 1then
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;
##
InstallMethod( IrreducibleFactors, "for ring elements",
[ IsRingElement ],
PrimeDivisors );
##
InstallMethod( IrreducibleFactors, "for homalg ring elements",
[ IsHomalgRingElement ],
function( r )
local R, factors;
R := HomalgRing( r );
if IsHomalgInternalRingRep( R ) then if not IsBound( r!.IrreducibleFactors ) then
r!.IrreducibleFactors := PrimeDivisors( EvalString( String( r ) ) ); fi; fi;
factors := RadicalDecompositionOp( HomalgMatrix( [ r ], 1, 1, R ) );
r!.Factors := List( factors, a -> a[ 1, 1 ] );
return r!.Factors;
end );
##
InstallMethod( Factors, "for homalg ring elements",
[ IsHomalgRingElement ],
function( r )
local R, factors, primary, prime, one, divide;
R := HomalgRing( r );
if IsHomalgInternalRingRep( R ) then if not IsBound( r!.Factors ) then
r!.Factors := Factors( EvalString( String( r ) ) ); fi; fi;
factors := PrimaryDecompositionOp( HomalgMatrix( [ r ], 1, 1, R ) );
primary := List( factors, a -> a[1][ 1, 1 ] );
prime := List( factors, a -> a[2][ 1, 1 ] );
one := One( R );
divide := function( q, p )
local list;
list := [ ];
repeat
q := q / p;
Add( list, p );
until IsZero( DecideZero( one, q ) );
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 > 0then
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 = 1then## [McCRob, 11.5.7]
SetElementaryRank( S, 1 ); elif d > 2then
SetElementaryRank( S, 2 ); fi;
##
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 > 0then
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 > 0then
SetIsLeftArtinian( S, false );
SetIsRightArtinian( S, false ); fi;
##
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 ) = 2then
## 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;
if not HasIndeterminateAntiCommutingVariablesOfExteriorRing( A ) then
SetIndeterminateAntiCommutingVariablesOfExteriorRing( A, anti );
fi;
if not HasIndeterminatesOfExteriorRing( A ) then
SetIndeterminatesOfExteriorRing( A, Concatenation( comm, anti ) );
fi;
SetBasisAlgorithmRespectsPrincipalIdeals( A, true );
SetAreUnitsCentral( S, true );
end );
##
InstallMethod( SetRingProperties, "for homalg rings",
[ IsHomalgRing and IsShiftAlgebra, IsHomalgRing and IsFreePolynomialRing, IsList ],
function( S, R, shift )
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 > 0then
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, shift = [ ] );
SetIndeterminateCoordinatesOfShiftAlgebra( S, var );
if HasRelativeIndeterminatesOfPolynomialRing( R ) then
SetRelativeIndeterminateCoordinatesOfShiftAlgebra(
S, RelativeIndeterminatesOfPolynomialRing( R ) ); fi;
SetIndeterminateShiftsOfShiftAlgebra( S, shift );
if d > 0then
SetIsLeftArtinian( S, false );
SetIsRightArtinian( S, false ); fi;
##
InstallMethod( SetRingProperties, "for homalg rings",
[ IsHomalgRing and IsRationalShiftAlgebra, IsHomalgRing and IsFreePolynomialRing, IsList ],
function( S, R, shift )
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 > 0then
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, shift = [ ] );
SetParametersOfRationalShiftAlgebra( S, var );
if HasRelativeIndeterminatesOfPolynomialRing( R ) then
SetRelativeParametersOfRationalShiftAlgebra(
S, RelativeIndeterminatesOfPolynomialRing( R ) ); fi;
##
InstallMethod( SetRingProperties, "for homalg rings",
[ IsHomalgRing and IsPseudoDoubleShiftAlgebra, IsHomalgRing and IsFreePolynomialRing, IsList ],
function( S, R, shift )
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 > 0then
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, shift = [ ] );
SetIndeterminateCoordinatesOfPseudoDoubleShiftAlgebra( S, var );
if HasRelativeIndeterminatesOfPolynomialRing( R ) then
SetRelativeIndeterminateCoordinatesOfPseudoDoubleShiftAlgebra(
S, RelativeIndeterminatesOfPolynomialRing( R ) ); fi;
##
InstallMethod( SetRingProperties, "for homalg rings",
[ IsHomalgRing and IsRationalPseudoDoubleShiftAlgebra, IsHomalgRing and IsFreePolynomialRing, IsList ],
function( S, R, shift )
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 > 0then
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, shift = [ ] );
SetParametersOfRationalPseudoDoubleShiftAlgebra( S, var );
if HasRelativeIndeterminatesOfPolynomialRing( R ) then
SetRelativeParametersOfRationalPseudoDoubleShiftAlgebra(
S, RelativeIndeterminatesOfPolynomialRing( R ) ); fi;
##
InstallMethod( SetRingProperties, "for homalg rings",
[ IsHomalgRing and IsBiasedDoubleShiftAlgebra, IsHomalgRing and IsFreePolynomialRing, IsList ],
function( S, R, shift )
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 > 0then
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, shift = [ ] );
SetIndeterminateCoordinatesOfBiasedDoubleShiftAlgebra( S, var );
if HasRelativeIndeterminatesOfPolynomialRing( R ) then
SetRelativeIndeterminateCoordinatesOfBiasedDoubleShiftAlgebra(
S, RelativeIndeterminatesOfPolynomialRing( R ) ); fi;
##
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 = 0then
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 ) = 1then
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;
if c = 0then
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 ) = 1then
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;
##
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 );
##
InstallMethod( EuclideanQuotient, "for a homalg ring and two homalg ring elements",
[ IsHomalgInternalRingRep and IsPrincipalIdealRing and IsCommutative, IsRingElement, IsRingElement ],
function( R, a, b )
return EuclideanQuotient( R!.ring, a, b );
end );
##
InstallMethod( EuclideanRemainder, "for a homalg ring and two homalg ring elements",
[ IsHomalgInternalRingRep and IsPrincipalIdealRing and IsCommutative, IsRingElement, IsRingElement ],
function( R, a, b )
return EuclideanRemainder( R!.ring, a, b );
end );
##
InstallMethod( QuotientRemainder, "for a homalg ring and two homalg ring elements",
[ IsHomalgInternalRingRep and IsPrincipalIdealRing and IsCommutative, IsRingElement, IsRingElement ],
function( R, a, b )
return QuotientRemainder( R!.ring, a, b );
end );
#################################### # # constructor functions and methods: # ####################################
## <#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 ( NumberRows( B ) = 0 ) = IsZero( B ); end,
BasisOfColumnModule := function( B ) return ( NumberColumns( 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,
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;
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;
homalg_ring!.interpret_rationals_func := function( r )
local d;
d := DenominatorRat( r ) / homalg_ring; if IsZero( d ) or not IsUnit( homalg_ring, d ) then
return fail; fi;
return r / homalg_ring; end;
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] = 0then
c := 0;
R := CreateHomalgRing( Integers );
SetRingFilter( R, IsHomalgRing );
SetRingElementFilter( R, IsInt ); elif IsInt( arg[1] ) then
c := arg[1]; if Length( Collected( FactorsInt( c ) ) ) = 1 and IsPackageMarkedForLoading( "GaussForHomalg", ">= 2018.09.20") then
R := HOMALG_RING_OF_INTEGERS_PRIME_POWER_HELPER( arg, c ); 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 );
##
InstallMethod( HomalgRingOfIntegersInUnderlyingCAS, "for an integer and homalg internal ring",
[ IsInt, IsHomalgInternalRingRep ],
HomalgRingOfIntegers );
##
InstallOtherMethod( \in, "for an object and a homalg internal ring",
[ IsObject, IsHomalgInternalRingRep ], 100001,
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 ) <> 2then
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 = 1then
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 );
##
InstallGlobalFunction( _PrepareInputForPolynomialRing, function( R, indets )
local var, nr_var, properties, r, var_of_base_ring, param;
if HasRingRelations( R ) then
Error( "polynomial rings over homalg residue class rings are not supported yet\nUse the generic residue class ring constructor '/' provided by homalg after defining the ambient ring\nfor help type: ?homalg: constructor for residue class rings\n" ); fi;
## get the new indeterminates for the ring and save them in var if IsString( indets ) and indets <> ""then
var := SplitString( indets, "," ); elif indets <> [ ] and ForAll( indets, i -> IsString( i ) and i <> "" ) then
var := indets; else
Error( "either a non-empty list of indeterminates or a comma separated string of them must be provided as the second argument\n" ); fi;
if not IsDuplicateFree( var ) then
Error( "your list of indeterminates is not duplicate free: ", var, "\n" ); fi;
nr_var := Length( var );
properties := [ IsCommutative ];
## K[x] is a principal ideal ring for a field K if Length( var ) = 1 and HasIsFieldForHomalg( R ) and IsFieldForHomalg( R ) then
Add( properties, IsPrincipalIdealRing ); fi;
## r is set to the ring of coefficients ## further a check is done, whether the old indeterminates (if exist) and the new ## ones are disjoint if HasIndeterminatesOfPolynomialRing( R ) then
r := CoefficientsRing( R );
var_of_base_ring := IndeterminatesOfPolynomialRing( R );
var_of_base_ring := List( var_of_base_ring, Name ); if Intersection2( var_of_base_ring, var ) <> [ ] then
Error( "the following indeterminates are already elements of the base ring: ", Intersection2( var_of_base_ring, var ), "\n" ); fi; else
r := R;
var_of_base_ring := [ ]; fi;
var := Concatenation( var_of_base_ring, var );
if HasRationalParameters( r ) then
param := Concatenation( ",", JoinStringsWithSeparator( RationalParameters( r ) ) ); else
param := ""; fi;
Error( "given coefficients rings R = ", StringView( R ), " and list of indeterminates = ", indets, ", ", "but only univariate polynomial rings over internal homalg fields are supported, ", "for multivariate polynomial rings or more general coefficients rings R ", "construct the coefficients ring in an external CAS which support the desired construction\n" );
function( R, indets )
local ar, r, var, nr_var, properties, S, l;
ar := _PrepareInputForPolynomialRing( R, indets );
r := ar[1];
var := ar[2]; ## all indeterminates, relative and base
nr_var := ar[3]; ## the number of relative indeterminates
properties := ar[4];
## create the new ring
S := PolynomialRing( r!.ring, var );
var := IndeterminatesOfPolynomialRing( S );
if not ( HasIsFieldForHomalg( R ) and IsFieldForHomalg( R ) and Length( var ) <= 1 ) then
TryNextMethod( ); fi;
S := CallFuncList( CreateHomalgRing, Concatenation( [ S ], properties ) );
SetIsFreePolynomialRing( S, true );
if HasIndeterminatesOfPolynomialRing( R ) and IndeterminatesOfPolynomialRing( R ) <> [ ] then
SetBaseRing( S, R );
l := Length( var );
SetRelativeIndeterminatesOfPolynomialRing( S, var{[ l - nr_var + 1 .. l ]} ); fi;
SetRingProperties( S, r, var );
SetFilterObj( S, IsUnivariatePolynomialRing );
S!.pre_matrix_constructor := a -> One( S ) * a;
return S;
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
##
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 );
##
InstallOtherMethod( \[\], "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 )
return R * indets;
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;
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 ) ) );
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 );
## this is a technical method which should not be called by the user ## as its mathematical assumptions are not checked here: ## the relations must only involve the base ring
InstallMethod( KoszulDualRing, "for homalg rings",
[ IsHomalgRing and HasAmbientRing ],
function( S )
local R, A, E;
R := AmbientRing( S );
A := KoszulDualRing( R );
if HasBaseRing( R ) then
SetBaseRing( A, BaseRing( R ) ); fi;
SetIsExteriorRing( A, true );
E := A / MatrixOfRelations( S );
SetIsExteriorRing( E, true );
SetIndeterminatesOfExteriorRing( E,
List( IndeterminatesOfExteriorRing( A ), e -> e / E ) );
SetIndeterminateAntiCommutingVariablesOfExteriorRing( E,
List( IndeterminateAntiCommutingVariablesOfExteriorRing( A ), e -> e / E ) );
if HasBaseRing( S ) then
SetBaseRing( E, BaseRing( S ) ); fi;
S!.KoszulDualRing := E;
return E;
end );
## this is a technical method which should not be called by the user ## as its mathematical assumptions are not checked here: ## the relations must only involve the base ring
InstallMethod( BaseRing, "for homalg rings",
[ IsExteriorRing and HasAmbientRing ],
function( A )
return BaseRing( AmbientRing( A ) );
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 ],
##
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 = 0then
return r / S; fi;
indetsR := Indeterminates( R );
indetsS := Indeterminates( S );
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 ) <> 1then
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 ],
if HasIsRationalsForHomalg( k ) and IsRationalsForHomalg( k ) then
return "\\mathbb{Q}"; elif HasCharacteristic( k ) and IsPrime( Characteristic( k ) ) then
return Concatenation( "\\mathbb{F}_{", String( Characteristic( k ) ), "}" ); else
TryNextMethod( ); fi;
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)
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.