C Logic Subpackages C.1 LIRNG: Logical Implications for Rings C.2 LIMAP: Logical Implications for Ring Maps C.3 LIMAT: Logical Implications for Matrices C.4 COLEM: Clever Operations for Lazy Evaluated Matrices Most of the matrix tool operations listed in Appendix B.1 which return a new matrix are lazy evaluated. The value of a homalg matrix is stored in the attribute Eval. Below is the list of the installed methods for the attribute Eval. C.4-1 Eval Eval( C )  method Returns: the Eval value of a homalg matrix C In case the matrix C was created using HomalgInitialMatrix (5.2-1) then the filter IsInitialMatrix for C is set to true and the homalgTable function (--> InitialMatrix (B.1-1)) will be used to set the attribute Eval and resets the filter IsInitialMatrix.  Code  InstallMethod( Eval,  "for homalg matrices (IsInitialMatrix)",  [ IsHomalgMatrix and IsInitialMatrix and  HasNrRows and HasNrColumns ],    function( C )  local R, RP, z, zz;    R := HomalgRing( C );    RP := homalgTable( R );    if IsBound( RP!.InitialMatrix ) then  ResetFilterObj( C, IsInitialMatrix );  return RP!.InitialMatrix( C );  fi;    if not IsHomalgInternalMatrixRep( C ) then  Error( "could not find a procedure called InitialMatrix in the ",  "homalgTable to evaluate a non-internal initial matrix\n" );  fi;    #=====# can only work for homalg internal matrices #=====#    z := Zero( HomalgRing( C ) );    ResetFilterObj( C, IsInitialMatrix );    zz := ListWithIdenticalEntries( NrColumns( C ), z );    return homalgInternalMatrixHull(  List( [ 1 .. NrRows( C ) ], i -> ShallowCopy( zz ) ) );   end );  C.4-2 Eval Eval( C )  method Returns: the Eval value of a homalg matrix C In case the matrix C was created using HomalgInitialIdentityMatrix (5.2-2) then the filter IsInitialIdentityMatrix for C is set to true and the homalgTable function (--> InitialIdentityMatrix (B.1-2)) will be used to set the attribute Eval and resets the filter IsInitialIdentityMatrix.  Code  InstallMethod( Eval,  "for homalg matrices (IsInitialIdentityMatrix)",  [ IsHomalgMatrix and IsInitialIdentityMatrix and  HasNrRows and HasNrColumns ],    function( C )  local R, RP, o, z, zz, id;    R := HomalgRing( C );    RP := homalgTable( R );    if IsBound( RP!.InitialIdentityMatrix ) then  ResetFilterObj( C, IsInitialIdentityMatrix );  return RP!.InitialIdentityMatrix( C );  fi;    if not IsHomalgInternalMatrixRep( C ) then  Error( "could not find a procedure called InitialIdentityMatrix in the ",  "homalgTable to evaluate a non-internal initial identity matrix\n" );  fi;    #=====# can only work for homalg internal matrices #=====#    z := Zero( HomalgRing( C ) );  o := One( HomalgRing( C ) );    ResetFilterObj( C, IsInitialIdentityMatrix );    zz := ListWithIdenticalEntries( NrColumns( C ), z );    id := List( [ 1 .. NrRows( C ) ],  function(i)  local z;  z := ShallowCopy( zz ); z[i] := o; return z;  end );    return homalgInternalMatrixHull( id );   end );  C.4-3 Eval Eval( C )  method Returns: the Eval value of a homalg matrix C In case the matrix C was created using HomalgZeroMatrix (5.2-3) then the filter IsZeroMatrix for C is set to true and the homalgTable function (--> ZeroMatrix (B.1-3)) will be used to set the attribute Eval.  Code  InstallMethod( Eval,  "for homalg matrices (IsZero)",  [ IsHomalgMatrix and IsZero and HasNrRows and HasNrColumns ], 20,    function( C )  local R, RP, z;    R := HomalgRing( C );    RP := homalgTable( R );    if ( NrRows( C ) = 0 or NrColumns( C ) = 0 ) and  not ( IsBound( R!.SafeToEvaluateEmptyMatrices ) and  R!.SafeToEvaluateEmptyMatrices = true ) then  Info( InfoWarning, 1, "\033[01m\033[5;31;47m",  "an empty matrix is about to get evaluated!",  "\033[0m" );  fi;    if IsBound( RP!.ZeroMatrix ) then  return RP!.ZeroMatrix( C );  fi;    if not IsHomalgInternalMatrixRep( C ) then  Error( "could not find a procedure called ZeroMatrix ",  "homalgTable to evaluate a non-internal zero matrix\n" );  fi;    #=====# can only work for homalg internal matrices #=====#    z := Zero( HomalgRing( C ) );    ## copying the rows saves memory;  ## we assume that the entries are never modified!!!  return homalgInternalMatrixHull(  ListWithIdenticalEntries( NrRows( C ),  ListWithIdenticalEntries( NrColumns( C ), z ) ) );   end );  C.4-4 Eval Eval( C )  method Returns: the Eval value of a homalg matrix C In case the matrix C was created using HomalgIdentityMatrix (5.2-4) then the filter IsOne for C is set to true and the homalgTable function (--> IdentityMatrix (B.1-4)) will be used to set the attribute Eval.  Code  InstallMethod( Eval,  "for homalg matrices (IsOne)",  [ IsHomalgMatrix and IsOne and HasNrRows and HasNrColumns ], 10,    function( C )  local R, id, RP, o, z, zz;    R := HomalgRing( C );    if IsBound( R!.IdentityMatrices ) then  id := ElmWPObj( R!.IdentityMatrices!.weak_pointers, NrColumns( C ) );  if id <> fail then  R!.IdentityMatrices!.cache_hits := R!.IdentityMatrices!.cache_hits + 1;  return id;  fi;  ## we do not count cache_misses as it is equivalent to counter  fi;    RP := homalgTable( R );    if IsBound( RP!.IdentityMatrix ) then  id := RP!.IdentityMatrix( C );  SetElmWPObj( R!.IdentityMatrices!.weak_pointers, NrColumns( C ), id );  R!.IdentityMatrices!.counter := R!.IdentityMatrices!.counter + 1;  return id;  fi;    if not IsHomalgInternalMatrixRep( C ) then  Error( "could not find a procedure called IdentityMatrix ",  "homalgTable to evaluate a non-internal identity matrix\n" );  fi;    #=====# can only work for homalg internal matrices #=====#    z := Zero( HomalgRing( C ) );  o := One( HomalgRing( C ) );    zz := ListWithIdenticalEntries( NrColumns( C ), z );    id := List( [ 1 .. NrRows( C ) ],  function(i)  local z;  z := ShallowCopy( zz ); z[i] := o; return z;  end );    id := homalgInternalMatrixHull( id );    SetElmWPObj( R!.IdentityMatrices!.weak_pointers, NrColumns( C ), id );    return id;   end );  C.4-5 Eval Eval( LI )  method Returns: see below In case the matrix LI was created using LeftInverseLazy (5.5-4) then the filter HasEvalLeftInverse for LI is set to true and the method listed below will be used to set the attribute Eval. (--> LeftInverse (5.5-2))  Code  InstallMethod( Eval,  "for homalg matrices",  [ IsHomalgMatrix and HasEvalLeftInverse ],    function( LI )  local left_inv;    left_inv := LeftInverse( EvalLeftInverse( LI ) );    if IsBool( left_inv ) then  return false;  fi;    return Eval( left_inv );   end );  C.4-6 Eval Eval( RI )  method Returns: see below In case the matrix RI was created using RightInverseLazy (5.5-5) then the filter HasEvalRightInverse for RI is set to true and the method listed below will be used to set the attribute Eval. (--> RightInverse (5.5-3))  Code  InstallMethod( Eval,  "for homalg matrices",  [ IsHomalgMatrix and HasEvalRightInverse ],    function( RI )  local right_inv;    right_inv := RightInverse( EvalRightInverse( RI ) );    if IsBool( right_inv ) then  return false;  fi;    return Eval( right_inv );   end );  C.4-7 Eval Eval( C )  method Returns: the Eval value of a homalg matrix C In case the matrix was created using Involution (5.5-6) then the filter HasEvalInvolution for C is set to true and the homalgTable function Involution (B.1-5) will be used to set the attribute Eval.  Code  InstallMethod( Eval,  "for homalg matrices (HasEvalInvolution)",  [ IsHomalgMatrix and HasEvalInvolution ],    function( C )  local R, RP, M;    R := HomalgRing( C );    RP := homalgTable( R );    M := EvalInvolution( C );    if IsBound(RP!.Involution) then  return RP!.Involution( M );  fi;    if not IsHomalgInternalMatrixRep( C ) then  Error( "could not find a procedure called Involution ",  "in the homalgTable of the non-internal ring\n" );  fi;    #=====# can only work for homalg internal matrices #=====#    return homalgInternalMatrixHull( TransposedMat( Eval( M )!.matrix ) );   end );  C.4-8 Eval Eval( C )  method Returns: the Eval value of a homalg matrix C In case the matrix was created using CertainRows (5.5-7) then the filter HasEvalCertainRows for C is set to true and the homalgTable function CertainRows (B.1-6) will be used to set the attribute Eval.  Code  InstallMethod( Eval,  "for homalg matrices (HasEvalCertainRows)",  [ IsHomalgMatrix and HasEvalCertainRows ],    function( C )  local R, RP, e, M, plist;    R := HomalgRing( C );    RP := homalgTable( R );    e := EvalCertainRows( C );    M := e[1];  plist := e[2];    if IsBound(RP!.CertainRows) then  return RP!.CertainRows( M, plist );  fi;    if not IsHomalgInternalMatrixRep( C ) then  Error( "could not find a procedure called CertainRows ",  "in the homalgTable of the non-internal ring\n" );  fi;    #=====# can only work for homalg internal matrices #=====#    return homalgInternalMatrixHull( Eval( M )!.matrix{ plist } );   end );  C.4-9 Eval Eval( C )  method Returns: the Eval value of a homalg matrix C In case the matrix was created using CertainColumns (5.5-8) then the filter HasEvalCertainColumns for C is set to true and the homalgTable function CertainColumns (B.1-7) will be used to set the attribute Eval.  Code  InstallMethod( Eval,  "for homalg matrices (HasEvalCertainColumns)",  [ IsHomalgMatrix and HasEvalCertainColumns ],    function( C )  local R, RP, e, M, plist;    R := HomalgRing( C );    RP := homalgTable( R );    e := EvalCertainColumns( C );    M := e[1];  plist := e[2];    if IsBound(RP!.CertainColumns) then  return RP!.CertainColumns( M, plist );  fi;    if not IsHomalgInternalMatrixRep( C ) then  Error( "could not find a procedure called CertainColumns ",  "in the homalgTable of the non-internal ring\n" );  fi;    #=====# can only work for homalg internal matrices #=====#    return homalgInternalMatrixHull(  Eval( M )!.matrix{[ 1 .. NrRows( M ) ]}{plist} );   end );  C.4-10 Eval Eval( C )  method Returns: the Eval value of a homalg matrix C In case the matrix was created using UnionOfRows (5.5-9) then the filter HasEvalUnionOfRows for C is set to true and the homalgTable function UnionOfRows (B.1-8) will be used to set the attribute Eval.  Code  InstallMethod( Eval,  "for homalg matrices (HasEvalUnionOfRows)",  [ IsHomalgMatrix and HasEvalUnionOfRows ],    function( C )  local R, RP, e, A, B, U;    R := HomalgRing( C );    RP := homalgTable( R );    e := EvalUnionOfRows( C );    A := e[1];  B := e[2];    if IsBound(RP!.UnionOfRows) then  return RP!.UnionOfRows( A, B );  fi;    if not IsHomalgInternalMatrixRep( C ) then  Error( "could not find a procedure called UnionOfRows ",  "in the homalgTable of the non-internal ring\n" );  fi;    #=====# can only work for homalg internal matrices #=====#    U := ShallowCopy( Eval( A )!.matrix );    U{ [ NrRows( A ) + 1 .. NrRows( A ) + NrRows( B ) ] } := Eval( B )!.matrix;    return homalgInternalMatrixHull( U );   end );  C.4-11 Eval Eval( C )  method Returns: the Eval value of a homalg matrix C In case the matrix was created using UnionOfColumns (5.5-10) then the filter HasEvalUnionOfColumns for C is set to true and the homalgTable function UnionOfColumns (B.1-9) will be used to set the attribute Eval.  Code  InstallMethod( Eval,  "for homalg matrices (HasEvalUnionOfColumns)",  [ IsHomalgMatrix and HasEvalUnionOfColumns ],    function( C )  local R, RP, e, A, B, U;    R := HomalgRing( C );    RP := homalgTable( R );    e := EvalUnionOfColumns( C );    A := e[1];  B := e[2];    if IsBound(RP!.UnionOfColumns) then  return RP!.UnionOfColumns( A, B );  fi;    if not IsHomalgInternalMatrixRep( C ) then  Error( "could not find a procedure called UnionOfColumns ",  "in the homalgTable of the non-internal ring\n" );  fi;    #=====# can only work for homalg internal matrices #=====#    U := List( Eval( A )!.matrix, ShallowCopy );    U{ [ 1 .. NrRows( A ) ] }  { [ NrColumns( A ) + 1 .. NrColumns( A ) + NrColumns( B ) ] }  := Eval( B )!.matrix;    return homalgInternalMatrixHull( U );   end );  C.4-12 Eval Eval( C )  method Returns: the Eval value of a homalg matrix C In case the matrix was created using DiagMat (5.5-11) then the filter HasEvalDiagMat for C is set to true and the homalgTable function DiagMat (B.1-10) will be used to set the attribute Eval.  Code  InstallMethod( Eval,  "for homalg matrices (HasEvalDiagMat)",  [ IsHomalgMatrix and HasEvalDiagMat ],    function( C )  local R, RP, e, z, m, n, diag, mat;    R := HomalgRing( C );    RP := homalgTable( R );    e := EvalDiagMat( C );    if IsBound(RP!.DiagMat) then  return RP!.DiagMat( e );  fi;    if not IsHomalgInternalMatrixRep( C ) then  Error( "could not find a procedure called DiagMat ",  "in the homalgTable of the non-internal ring\n" );  fi;    #=====# can only work for homalg internal matrices #=====#    z := Zero( R );    m := Sum( List( e, NrRows ) );  n := Sum( List( e, NrColumns ) );    diag := List( [ 1 .. m ], a -> List( [ 1 .. n ], b -> z ) );    m := 0;  n := 0;    for mat in e do  diag{ [ m + 1 .. m + NrRows( mat ) ] }{ [ n + 1 .. n + NrColumns( mat ) ] }  := Eval( mat )!.matrix;    m := m + NrRows( mat );  n := n + NrColumns( mat );  od;    return homalgInternalMatrixHull( diag );   end );  C.4-13 Eval Eval( C )  method Returns: the Eval value of a homalg matrix C In case the matrix was created using KroneckerMat (5.5-12) then the filter HasEvalKroneckerMat for C is set to true and the homalgTable function KroneckerMat (B.1-11) will be used to set the attribute Eval.  Code  InstallMethod( Eval,  "for homalg matrices (HasEvalKroneckerMat)",  [ IsHomalgMatrix and HasEvalKroneckerMat ],    function( C )  local R, RP, A, B;    R := HomalgRing( C );    if ( HasIsCommutative( R ) and not IsCommutative( R ) ) and  ( HasIsSuperCommutative( R ) and not IsSuperCommutative( R ) ) then  Info( InfoWarning, 1, "\033[01m\033[5;31;47m",  "the Kronecker product is only defined for (super) commutative rings!",  "\033[0m" );  fi;    RP := homalgTable( R );    A := EvalKroneckerMat( C )[1];  B := EvalKroneckerMat( C )[2];    if IsBound(RP!.KroneckerMat) then  return RP!.KroneckerMat( A, B );  fi;    if not IsHomalgInternalMatrixRep( C ) then  Error( "could not find a procedure called KroneckerMat ",  "in the homalgTable of the non-internal ring\n" );  fi;    #=====# can only work for homalg internal matrices #=====#    return homalgInternalMatrixHull(  KroneckerProduct( Eval( A )!.matrix, Eval( B )!.matrix ) );  ## this was easy, thanks GAP :)   end );  C.4-14 Eval Eval( C )  method Returns: the Eval value of a homalg matrix C In case the matrix was created using \* (5.5-13) then the filter HasEvalMulMat for C is set to true and the homalgTable function MulMat (B.1-12) will be used to set the attribute Eval.  Code  InstallMethod( Eval,  "for homalg matrices (HasEvalMulMat)",  [ IsHomalgMatrix and HasEvalMulMat ],    function( C )  local R, RP, e, a, A;    R := HomalgRing( C );    RP := homalgTable( R );    e := EvalMulMat( C );    a := e[1];  A := e[2];    if IsBound(RP!.MulMat) then  return RP!.MulMat( a, A );  fi;    if not IsHomalgInternalMatrixRep( C ) then  Error( "could not find a procedure called MulMat ",  "in the homalgTable of the non-internal ring\n" );  fi;    #=====# can only work for homalg internal matrices #=====#    return a * Eval( A );   end );  InstallMethod( Eval,  "for homalg matrices (HasEvalMulMatRight)",  [ IsHomalgMatrix and HasEvalMulMatRight ],    function( C )  local R, RP, e, A, a;    R := HomalgRing( C );    RP := homalgTable( R );    e := EvalMulMatRight( C );    A := e[1];  a := e[2];    if IsBound(RP!.MulMatRight) then  return RP!.MulMatRight( A, a );  fi;    if not IsHomalgInternalMatrixRep( C ) then  Error( "could not find a procedure called MulMatRight ",  "in the homalgTable of the non-internal ring\n" );  fi;    #=====# can only work for homalg internal matrices #=====#    return Eval( A ) * a;   end );  C.4-15 Eval Eval( C )  method Returns: the Eval value of a homalg matrix C In case the matrix was created using \+ (5.5-14) then the filter HasEvalAddMat for C is set to true and the homalgTable function AddMat (B.1-13) will be used to set the attribute Eval.  Code  InstallMethod( Eval,  "for homalg matrices (HasEvalAddMat)",  [ IsHomalgMatrix and HasEvalAddMat ],    function( C )  local R, RP, e, A, B;    R := HomalgRing( C );    RP := homalgTable( R );    e := EvalAddMat( C );    A := e[1];  B := e[2];    if IsBound(RP!.AddMat) then  return RP!.AddMat( A, B );  fi;    if not IsHomalgInternalMatrixRep( C ) then  Error( "could not find a procedure called AddMat ",  "in the homalgTable of the non-internal ring\n" );  fi;    #=====# can only work for homalg internal matrices #=====#    return Eval( A ) + Eval( B );   end );  C.4-16 Eval Eval( C )  method Returns: the Eval value of a homalg matrix C In case the matrix was created using \- (5.5-15) then the filter HasEvalSubMat for C is set to true and the homalgTable function SubMat (B.1-14) will be used to set the attribute Eval.  Code  InstallMethod( Eval,  "for homalg matrices (HasEvalSubMat)",  [ IsHomalgMatrix and HasEvalSubMat ],    function( C )  local R, RP, e, A, B;    R := HomalgRing( C );    RP := homalgTable( R );    e := EvalSubMat( C );    A := e[1];  B := e[2];    if IsBound(RP!.SubMat) then  return RP!.SubMat( A, B );  fi;    if not IsHomalgInternalMatrixRep( C ) then  Error( "could not find a procedure called SubMat ",  "in the homalgTable of the non-internal ring\n" );  fi;    #=====# can only work for homalg internal matrices #=====#    return Eval( A ) - Eval( B );   end );  C.4-17 Eval Eval( C )  method Returns: the Eval value of a homalg matrix C In case the matrix was created using \* (5.5-16) then the filter HasEvalCompose for C is set to true and the homalgTable function Compose (B.1-15) will be used to set the attribute Eval.  Code  InstallMethod( Eval,  "for homalg matrices (HasEvalCompose)",  [ IsHomalgMatrix and HasEvalCompose ],    function( C )  local R, RP, e, A, B;    R := HomalgRing( C );    RP := homalgTable( R );    e := EvalCompose( C );    A := e[1];  B := e[2];    if IsBound(RP!.Compose) then  return RP!.Compose( A, B );  fi;    if not IsHomalgInternalMatrixRep( C ) then  Error( "could not find a procedure called Compose ",  "in the homalgTable of the non-internal ring\n" );  fi;    #=====# can only work for homalg internal matrices #=====#    return Eval( A ) * Eval( B );   end );