############################################################################# ## ## This file is part of GAP, a system for computational discrete algebra. ## This file's authors include J. D. Mitchell. ## ## Copyright of GAP belongs to its developers, whose names are too numerous ## to list here. Please refer to the COPYRIGHT file for details. ## ## SPDX-License-Identifier: GPL-2.0-or-later ## ## This file contains the implementation of Rees matrix semigroups. ##
# Notes: there are essentially 3 types of semigroups here: # 1) the whole family Rees matrix semigroup (notice that the matrix used to # define the semigroup may contain rows or columns consisting entirely of 0s # so it is not guaranteed that the resulting semigroup is 0-simple) # 2) subsemigroups U of 1), which defined by a generating set and are Rees matrix # semigroups, i.e. U=I'xG'xJ' where the whole family if IxGxJ and I', J' subsets # of I, J and G' a subsemigroup of G. # 3) subsemigroups of 1) obtained by removing an index or element of the # underlying semigroup, and hence are also Rees matrix semigroups. # 4) subsemigroups of 1) defined by generating sets which are not # simple/0-simple.
# So, the methods with filters IsRees(Zero)MatrixSemigroup and # HasGeneratorsOfSemigroup only apply to subsemigroups of type 2). # Subsemigroups of type 3 already know the values of Rows, Columns, # UnderlyingSemigroup, and Matrix.
# a Rees matrix semigroup over a semigroup <S> is simple if and only if <S> is # simple.
InstallImmediateMethod(IsFinite, IsReesZeroMatrixSubsemigroup, 0, function(R) if IsBound(ElementsFamily(FamilyObj(R))!.IsFinite) then if HasIsWholeFamily(R) and IsWholeFamily(R) then
return ElementsFamily(FamilyObj(R))!.IsFinite; elif ElementsFamily(FamilyObj(R))!.IsFinite then
return true; fi; fi;
TryNextMethod(); end);
InstallImmediateMethod(IsFinite, IsReesMatrixSubsemigroup, 0, function(R) if IsBound(ElementsFamily(FamilyObj(R))!.IsFinite) then if HasIsWholeFamily(R) and IsWholeFamily(R) then
return ElementsFamily(FamilyObj(R))!.IsFinite; elif ElementsFamily(FamilyObj(R))!.IsFinite then
return true; fi; fi;
TryNextMethod(); end);
InstallMethod(IsFinite, "for a Rees 0-matrix subsemigroup",
[IsReesZeroMatrixSubsemigroup], function(R) if HasIsFinite(ParentAttr(R)) and IsFinite(ParentAttr(R))then
return true; fi;
TryNextMethod(); end);
InstallMethod(IsFinite, "for a Rees matrix subsemigroup",
[IsReesMatrixSubsemigroup], function(R) if HasIsFinite(ParentAttr(R)) and IsFinite(ParentAttr(R)) then
return true; fi;
TryNextMethod(); end);
#
InstallMethod(IsIdempotent, "for a Rees 0-matrix semigroup element",
[IsReesZeroMatrixSemigroupElement], function(x)
local matrix_entry, g;
if x![1] = 0then # <x> is the 0 element of the family
return true; fi;
matrix_entry := x![4][x![3]][x![1]];
if matrix_entry = 0then
return false; fi;
g := UnderlyingElementOfReesZeroMatrixSemigroupElement(x);
return g * matrix_entry * g = g; end);
#
InstallTrueMethod(IsRegularSemigroup,
IsReesMatrixSemigroup and IsSimpleSemigroup);
#
InstallMethod(IsRegularSemigroup, "for a Rees 0-matrix semigroup",
[IsReesZeroMatrixSemigroup], function(R)
local mat;
mat := Matrix(R); if HasIsGroupAsSemigroup(UnderlyingSemigroup(R))
and IsGroupAsSemigroup(UnderlyingSemigroup(R)) then
return ForAll(Rows(R), i -> ForAny(Columns(R), j -> mat[j,i]<>0))
and ForAll(Columns(R), j -> ForAny(Rows(R), i -> mat[j,i]<>0)); else
TryNextMethod(); fi; end);
#
InstallMethod(IsSimpleSemigroup, "for a subsemigroup of a Rees matrix semigroup with an underlying semigroup",
[IsReesMatrixSubsemigroup and HasUnderlyingSemigroup],
R-> IsSimpleSemigroup(UnderlyingSemigroup(R)));
# This next method for `IsSimpleSemigroup` additionally requires the filter # `IsFinite`, but is otherwise identical. In the Semigroups package, there are # some more general methods installed for `IsSimpleSemigroup` which include the # filter `IsFinite`. When the rank of `IsFinite` is sufficiently large, these # methods can beat the above method. The above method is a more specific method # and should always be the one chosen for Rees matrix subsemigroups with known # underlying semigroup, whether finite or infinite.
InstallMethod(IsSimpleSemigroup, "for finite subsemigroup of a Rees matrix semigroup with underlying semigroup",
[IsReesMatrixSubsemigroup and HasUnderlyingSemigroup and IsFinite],
R -> IsSimpleSemigroup(UnderlyingSemigroup(R)));
# check that the matrix has no rows or columns consisting entirely of 0s # and that the underlying semigroup is simple
InstallMethod(IsZeroSimpleSemigroup, "for a Rees 0-matrix semigroup",
[IsReesZeroMatrixSemigroup], function(R)
local i, mat;
mat := Matrix(R); if ForAny(Columns(R), j -> ForAll(Rows(R), i -> mat[j,i] = 0))
or ForAny(Rows(R), i -> ForAll(Columns(R), j -> mat[j,i] = 0)) then
return false; fi;
return IsSimpleSemigroup(UnderlyingSemigroup(R)); end);
#
InstallMethod(IsReesMatrixSemigroup, "for a semigroup", [IsSemigroup], ReturnFalse);
#
InstallMethod(IsReesMatrixSemigroup, "for a Rees matrix subsemigroup with generators",
[IsReesMatrixSubsemigroup and HasGeneratorsOfSemigroup], function(R)
local gens, I, J;
if IsWholeFamily(R) then
return true; fi;
# it is still possible that <R> is a Rees matrix semigroup, if, for example, # we have a subsemigroup specified by generators which equals a subsemigroup # obtained by removing a row, in the case that <R> is not simple.
gens:=GeneratorsOfSemigroup(R);
I:=Set(gens, x-> x![1]);
J:=Set(gens, x-> x![3]);
return ForAll(GeneratorsOfReesMatrixSemigroupNC(ParentAttr(R), I,
Semigroup(List(AsSSortedList(R), x-> x![2])), J), x-> x in R); end);
#
InstallMethod(IsReesZeroMatrixSemigroup, "for a semigroup", [IsSemigroup],
ReturnFalse);
#
InstallMethod(IsReesZeroMatrixSemigroup, "for a Rees 0-matrix subsemigroup with generators",
[IsReesZeroMatrixSubsemigroup and HasGeneratorsOfSemigroup], function(R)
local gens, pos, elts, I, J;
if IsWholeFamily(R) then
return true; fi;
# it is still possible that <R> is a Rees 0-matrix semigroup, if, for # example, we have a subsemigroup specified by generators which equals a # subsemigroup obtained by removing a row, in the case that <R> is not simple.
if MultiplicativeZero(R)<>MultiplicativeZero(ParentAttr(R)) then
return false; #Rees 0-matrix semigroups always contain the 0. fi;
gens := Unique(GeneratorsOfSemigroup(R));
pos:=Position(gens, MultiplicativeZero(R)); if pos<>fail then if Size(gens) = 1then
return false; fi;
gens:=ShallowCopy(gens);
Remove(gens, pos); fi;
return ForAll(GeneratorsOfReesZeroMatrixSemigroupNC(ParentAttr(R), I,
Semigroup(List(elts, x-> x![2])), J), x-> x in R); end);
#
InstallMethod(ReesMatrixSemigroup, "for a semigroup and a rectangular table",
[IsSemigroup, IsRectangularTable], function(S, mat)
local fam, R, type, x;
for x in mat do if ForAny(x, s-> not s in S) then
ErrorNoReturn("the entries of the second argument (a rectangular ", "table) must belong to the first argument (a semigroup)"); fi;
od;
InstallMethod(ReesZeroMatrixSemigroup, "for a semigroup and a dense list",
[IsSemigroup, IsDenseList], function(S, mat)
local fam, R, type, x;
if IsEmpty(mat) or not ForAll(mat, x -> IsDenseList(x) and not IsEmpty(x)
and Length(x) = Length(mat[1])) then
ErrorNoReturn("the second argument must be a non-empty list, whose ", "entries are non-empty lists of equal length"); fi;
for x in mat do if ForAny(x, s -> not (s = 0 or s in S)) then
ErrorNoReturn("the entries of the second argument must be 0 or belong ", "to the first argument (a semigroup)"); fi;
od;
if HasIsFinite(S) then
fam!.IsFinite := IsFinite(S); fi;
# create the Rees matrix semigroup
R := Objectify(NewType(CollectionsFamily(fam),
IsWholeFamily
and IsReesZeroMatrixSubsemigroup
and IsAttributeStoringRep), rec());
# store the type of the elements in the semigroup
type := NewType(fam, IsReesZeroMatrixSemigroupElement and IsPositionalObjectRep);
# cannot set IsZeroSimpleSemigroup to be <true> here since the matrix may # contain a row or column consisting entirely of 0s! # WW Also S might not be a simple semigroup (which is necessary)! if IsGroup(S) or (HasIsFinite(S) and IsFinite(S)) then
GeneratorsOfSemigroup(R); fi;
SetIsSimpleSemigroup(R, false);
return R; end);
InstallMethod(ViewObj, "for a Rees matrix semigroup",
[IsReesMatrixSemigroup], 3, #to beat the next method function(R)
Print("\>\><Rees matrix semigroup \>", Length(Rows(R)), "x",
Length(Columns(R)), "\< over \<");
View(UnderlyingSemigroup(R));
Print(">\<");
return; end);
#
InstallMethod(ViewObj, "for a subsemigroup of a Rees matrix semigroup",
[IsReesMatrixSubsemigroup], PrintObj);
#
InstallMethod(PrintObj, "for a subsemigroup of a Rees matrix semigroup",
[IsReesMatrixSubsemigroup and HasGeneratorsOfSemigroup], function(R)
Print("\><subsemigroup of \>",
Length(Rows(ParentAttr(R))), "x", Length(Columns(ParentAttr(R))), "\< Rees matrix semigroup \>with ",
Pluralize(Length(GeneratorsOfSemigroup(R)), "generator"), "\<>\<");
return; end);
#
InstallMethod(ViewObj, "for a Rees 0-matrix semigroup",
[IsReesZeroMatrixSemigroup], 3, #to beat the next method function(R)
Print("\>\><Rees 0-matrix semigroup \>", Length(Rows(R)), "x",
Length(Columns(R)), "\< over \<");
View(UnderlyingSemigroup(R));
Print(">\<");
return; end);
#
InstallMethod(ViewObj, "for a subsemigroup of a Rees 0-matrix semigroup",
[IsReesZeroMatrixSubsemigroup], PrintObj);
InstallMethod(PrintObj, "for a subsemigroup of a Rees 0-matrix semigroup",
[IsReesZeroMatrixSubsemigroup and HasGeneratorsOfSemigroup], function(R)
Print("\><subsemigroup of \>",
Length(Rows(ParentAttr(R))), "x", Length(Columns(ParentAttr(R))), "\< Rees 0-matrix semigroup \>with ",
Pluralize(Length(GeneratorsOfSemigroup(R)), "generator"), "\<>\<");
return; end);
#
InstallMethod(PrintObj, "for a Rees matrix semigroup",
[IsReesMatrixSemigroup and IsWholeFamily], 2, function(R)
Print("ReesMatrixSemigroup( ");
Print(UnderlyingSemigroup(R));
Print(", ");
Print(Matrix(R));
Print(" )"); end);
#
InstallMethod(PrintObj, "for a Rees 0-matrix semigroup",
[IsReesZeroMatrixSemigroup and IsWholeFamily], 2, function(R)
Print("ReesZeroMatrixSemigroup( ");
Print(UnderlyingSemigroup(R));
Print(", ");
Print(Matrix(R));
Print(" )"); end);
#
InstallMethod(Size, "for a Rees matrix semigroup",
[IsReesMatrixSemigroup], function(R) if Size(UnderlyingSemigroup(R))=infinity then
return infinity; fi;
InstallMethod(Size, "for a Rees 0-matrix semigroup",
[IsReesZeroMatrixSemigroup], function(R) if Size(UnderlyingSemigroup(R))=infinity then
return infinity; fi;
InstallMethod(Representative, "for a subsemigroup of Rees matrix semigroup with generators",
[IsReesMatrixSubsemigroup and HasGeneratorsOfSemigroup], 2, # to beat the other method function(R)
return GeneratorsOfSemigroup(R)[1]; end);
InstallMethod(Representative, "for a subsemigroup of Rees 0-matrix semigroup with generators",
[IsReesZeroMatrixSubsemigroup and HasGeneratorsOfSemigroup], 2, # to beat the other method function(R)
return GeneratorsOfSemigroup(R)[1]; end);
PrintObj:=function(enum)
Print("<enumerator of Rees 0-matrix semigroup>");
return; end)); end);
# these methods (Matrix, Rows, Columns, UnderlyingSemigroup) should only apply # to subsemigroups defined by a generating set, which happen to be # simple/0-simple.
InstallMethod(MatrixOfReesMatrixSemigroup, "for a Rees matrix semigroup with generators",
[IsReesMatrixSubsemigroup and HasGeneratorsOfSemigroup], function(R) if not IsReesMatrixSemigroup(R) then
return fail; fi;
return MatrixOfReesMatrixSemigroup(ParentAttr(R)); end);
InstallMethod(MatrixOfReesZeroMatrixSemigroup, "for a Rees 0-matrix semigroup with generators",
[IsReesZeroMatrixSubsemigroup and HasGeneratorsOfSemigroup], function(R) if not IsReesZeroMatrixSemigroup(R) then
return fail; fi;
return MatrixOfReesZeroMatrixSemigroup(ParentAttr(R)); end);
# for convenience and backwards compatibility
InstallOtherMethod(Matrix, [IsReesMatrixSubsemigroup], MatrixOfReesMatrixSemigroup);
InstallOtherMethod(Matrix, [IsReesZeroMatrixSubsemigroup], MatrixOfReesZeroMatrixSemigroup);
#
InstallMethod(RowsOfReesMatrixSemigroup, "for a Rees matrix semigroup with generators",
[IsReesMatrixSubsemigroup and HasGeneratorsOfSemigroup], function(R) if not IsReesMatrixSemigroup(R) then
return fail; fi;
return SetX(GeneratorsOfSemigroup(R), x-> x![1]); end);
InstallMethod(RowsOfReesZeroMatrixSemigroup, "for a Rees 0-matrix semigroup with generators",
[IsReesZeroMatrixSubsemigroup and HasGeneratorsOfSemigroup], function(R)
local out; if not IsReesZeroMatrixSemigroup(R) then
return fail; fi;
out:=SetX(GeneratorsOfSemigroup(R), x-> x![1]); if out[1]=0then
Remove(out, 1); fi;
return out; end);
#
InstallMethod(ColumnsOfReesMatrixSemigroup, "for a Rees matrix semigroup with generators",
[IsReesMatrixSubsemigroup and HasGeneratorsOfSemigroup], function(R) if not IsReesMatrixSemigroup(R) then
return fail; fi;
return SetX(GeneratorsOfSemigroup(R), x-> x![3]); end);
InstallMethod(ColumnsOfReesZeroMatrixSemigroup, "for a Rees 0-matrix semigroup with generators",
[IsReesZeroMatrixSubsemigroup and HasGeneratorsOfSemigroup], function(R)
local out, x;
if not IsReesZeroMatrixSemigroup(R) then
return fail; fi;
out:=[]; for x in GeneratorsOfSemigroup(R) do if x![1]<>0then
AddSet(out, x![3]); fi;
od;
return out; end);
# these methods only apply to subsemigroups which happen to be Rees matrix # semigroups
InstallMethod(UnderlyingSemigroup, "for a Rees matrix semigroup with generators",
[IsReesMatrixSubsemigroup and HasGeneratorsOfSemigroup], function(R)
local gens, i, S, U;
if not IsReesMatrixSemigroup(R) then
return fail; fi;
gens:=List(AsSSortedList(R), x-> x![2]);
if IsGeneratorsOfMagmaWithInverses(gens) then
i:=1;
S:=UnderlyingSemigroup(ParentAttr(R));
U:=Group(gens[1]); while Size(U)<Size(S) and i<Length(gens) do
i:=i+1;
U:=ClosureGroup(U, gens[i]);
od; else
U:=Semigroup(gens); fi;
SetIsSimpleSemigroup(U, true);
return U; end);
# these methods only apply to subsemigroups which happen to be Rees matrix # semigroups
InstallMethod(UnderlyingSemigroup, "for a Rees 0-matrix semigroup with generators",
[IsReesZeroMatrixSubsemigroup and HasGeneratorsOfSemigroup], function(R)
local gens, i, S, U;
if not IsReesZeroMatrixSemigroup(R) then
return fail; fi;
if IsGeneratorsOfMagmaWithInverses(gens) then
i:=1;
S:=UnderlyingSemigroup(ParentAttr(R));
U:=Group(gens[1]); while Size(U)<Size(S) and i<Length(gens) do
i:=i+1;
U:=ClosureGroup(U, gens[i]);
od; else
U:=Semigroup(gens); fi;
return U; end);
# again only for subsemigroups defined by generators...
InstallMethod(TypeReesMatrixSemigroupElements, "for a subsemigroup of Rees matrix semigroup",
[IsReesMatrixSubsemigroup],
R -> TypeReesMatrixSemigroupElements(ParentAttr(R)));
InstallMethod(TypeReesMatrixSemigroupElements, "for a subsemigroup of Rees 0-matrix semigroup",
[IsReesZeroMatrixSubsemigroup],
R -> TypeReesMatrixSemigroupElements(ParentAttr(R)));
# Elements...
InstallGlobalFunction(RMSElement, function(R, i, s, j)
local out;
if not (IsReesMatrixSubsemigroup(R)
or IsReesZeroMatrixSubsemigroup(R)) then
ErrorNoReturn("the first argument must be a Rees matrix semigroup", " or Rees 0-matrix semigroup"); fi;
if (HasIsReesMatrixSemigroup(R) and IsReesMatrixSemigroup(R)) or
(HasIsReesZeroMatrixSemigroup(R) and IsReesZeroMatrixSemigroup(R)) then if not i in Rows(R) then
ErrorNoReturn("the second argument (a positive integer) does not ", "belong to the rows of the first argument (a Rees ", "(0-)matrix semigroup)"); elif not j in Columns(R) then
ErrorNoReturn("the fourth argument (a positive integer) does not ", "belong to the columns of the first argument (a Rees ", "(0-)matrix semigroup)"); elif not s in UnderlyingSemigroup(R) then
ErrorNoReturn("the second argument does not belong to the", "underlying semigroup of the first argument (a Rees ", "(0-)matrix semgiroup)"); fi;
return Objectify(TypeReesMatrixSemigroupElements(R), [i, s, j, Matrix(R)]); fi;
if not out in R then# for the case R is defined by a generating set
ErrorNoReturn("the arguments do not describe an element of the first ", "argument (a Rees (0-)matrix semigroup)"); fi;
return out; end);
#
InstallMethod(RowOfReesMatrixSemigroupElement, "for a Rees matrix semigroup element", [IsReesMatrixSemigroupElement],
x-> x![1]);
#
InstallMethod(RowOfReesZeroMatrixSemigroupElement, "for a Rees 0-matrix semigroup element", [IsReesZeroMatrixSemigroupElement], function(x) if x![1] = 0then
return fail; fi;
return x![1]; end);
#
InstallMethod(UnderlyingElementOfReesMatrixSemigroupElement, "for a Rees matrix semigroup element", [IsReesMatrixSemigroupElement],
x-> x![2]);
#
InstallMethod(UnderlyingElementOfReesZeroMatrixSemigroupElement, "for a Rees 0-matrix semigroup element", [IsReesZeroMatrixSemigroupElement], function(x) if x![1] = 0then
return fail; fi;
return x![2]; end);
#
InstallMethod(ColumnOfReesMatrixSemigroupElement, "for a Rees matrix semigroup element", [IsReesMatrixSemigroupElement],
x-> x![3]);
#
InstallMethod(ColumnOfReesZeroMatrixSemigroupElement, "for a Rees 0-matrix semigroup element", [IsReesZeroMatrixSemigroupElement], function(x) if x![1] = 0then
return fail; fi;
return x![3]; end);
InstallMethod(ELM_LIST, "for a Rees matrix semigroup element",
[IsReesMatrixSemigroupElement, IsPosInt], function(x, i) if i > 3then
ErrorNoReturn("the second argument must be 1, 2, or 3"); fi;
return x![i]; end);
#
InstallMethod(ELM_LIST, "for a Rees 0-matrix semigroup element",
[IsReesZeroMatrixSemigroupElement, IsPosInt], function(x, i) if x![1] = 0then
ErrorNoReturn("the first argument (an element of a Rees 0-matrix ", "semigroup) must be non-zero"); elif i > 3then
ErrorNoReturn("the second argument must be 1, 2, or 3"); fi;
return x![i]; end);
#
InstallMethod(ZeroOp, "for a Rees matrix semigroup element",
[IsReesMatrixSemigroupElement], ReturnFail);
InstallMethod(MultiplicativeZeroOp, "for a Rees matrix semigroup",
[IsReesMatrixSemigroup], ReturnFail);
#
InstallMethod(\*, "for elements of a Rees matrix semigroup",
IsIdenticalObj,
[IsReesMatrixSemigroupElement, IsReesMatrixSemigroupElement], function(x, y)
return Objectify(FamilyObj(x)!.type,
[x![1], x![2]*x![4][x![3]][y![1]]*y![2], y![3], x![4]]); end);
#
InstallMethod(\*, "for elements of a Rees 0-matrix semigroup",
IsIdenticalObj,
[IsReesZeroMatrixSemigroupElement, IsReesZeroMatrixSemigroupElement], function(x, y)
local p;
if x![1]=0then
return x; elif y![1]=0then
return y; fi;
InstallMethod(\<, "for elements of a Rees matrix semigroup",
IsIdenticalObj,
[IsReesMatrixSemigroupElement, IsReesMatrixSemigroupElement], function(x, y)
return x![1]<y![1] or (x![1]=y![1] and x![2]<y![2])
or (x![1]=y![1] and x![2]=y![2] and x![3]<y![3]); end);
# 0 is less than everything!
InstallMethod(\<, "for elements of a Rees 0-matrix semigroup",
IsIdenticalObj,
[IsReesZeroMatrixSemigroupElement, IsReesZeroMatrixSemigroupElement], function(x, y) if x![1]=0then
return y![1]<>0; elif y![1]=0then
return false; fi;
return x![1]<y![1] or (x![1]=y![1] and x![2]<y![2])
or (x![1]=y![1] and x![2]=y![2] and x![3]<y![3]); end);
#
InstallMethod(\=, "for elements of a Rees matrix semigroup",
IsIdenticalObj,
[IsReesMatrixSemigroupElement, IsReesMatrixSemigroupElement], function(x, y)
return x![1]=y![1] and x![2]=y![2] and x![3]=y![3]; end);
#
InstallMethod(\=, "for elements of a Rees 0-matrix semigroup",
IsIdenticalObj,
[IsReesZeroMatrixSemigroupElement, IsReesZeroMatrixSemigroupElement], function(x, y) if x![1]=0then
return y![1]=0; fi;
return x![1]=y![1] and x![2]=y![2] and x![3]=y![3]; end);
#
InstallMethod(ParentAttr, "for a subsemigroup of a Rees matrix semigroup",
[IsReesMatrixSubsemigroup], function(R)
return ReesMatrixSemigroupOfFamily(FamilyObj(Representative(R))); end);
#
InstallMethod(ParentAttr, "for a subsemigroup of a Rees 0-matrix semigroup",
[IsReesZeroMatrixSubsemigroup], function(R)
return ReesMatrixSemigroupOfFamily(FamilyObj(Representative(R))); end);
#
InstallMethod(IsWholeFamily, "for a subsemigroup of a Rees matrix semigroup",
[IsReesMatrixSubsemigroup], function(R)
local S;
if Size(R)=Size(ReesMatrixSemigroupOfFamily(ElementsFamily(FamilyObj(R)))) then if not HasMatrixOfReesMatrixSemigroup(R) then# <R> is defined by generators
S:=ParentAttr(R);
SetMatrixOfReesMatrixSemigroup(R, Matrix(S));
SetUnderlyingSemigroup(R, UnderlyingSemigroup(S));
SetRowsOfReesMatrixSemigroup(R, Rows(S));
SetColumnsOfReesMatrixSemigroup(R, Columns(S)); fi;
return true; else
return false; fi; end);
#
InstallMethod(IsWholeFamily, "for a subsemigroup of a Rees 0-matrix semigroup",
[IsReesZeroMatrixSubsemigroup], function(R)
local S;
if Size(R)=Size(ReesMatrixSemigroupOfFamily(ElementsFamily(FamilyObj(R)))) then if not HasMatrixOfReesZeroMatrixSemigroup(R) then# <R> is defined by generators
S:=ParentAttr(R);
SetMatrixOfReesZeroMatrixSemigroup(R, Matrix(S));
SetUnderlyingSemigroup(R, UnderlyingSemigroup(S));
SetRowsOfReesZeroMatrixSemigroup(R, Rows(S));
SetColumnsOfReesZeroMatrixSemigroup(R, Columns(S)); fi;
return true; else
return false; fi; end);
# generators for the subsemigroup generated by <IxUxJ>, when <R> is a Rees # matrix semigroup (and not only a subsemigroup).
InstallGlobalFunction(GeneratorsOfReesMatrixSemigroupNC, function(R, I, U, J)
local P, type, i, j, gens, u;
if IsGroup(U) then
i:=I[1]; j:=J[1]; if IsTrivial(U) then
gens:=[Objectify(type, [i, P[j][i]^-1, j, P])]; else
gens:=List(GeneratorsOfGroup(U), x->
Objectify( type, [i, x*P[j][i]^-1, j, P])); fi;
if Length(I)>Length(J) then for i in [2..Length(J)] do
Add(gens, Objectify(type, [I[i], One(U), J[i], P]));
od; for i in [Length(J)+1..Length(I)] do
Add(gens, Objectify(type, [I[i], One(U), J[1], P]));
od; else for i in [2..Length(I)] do
Add(gens, Objectify(type, [I[i], One(U), J[i], P]));
od; for i in [Length(I)+1..Length(J)] do
Add(gens, Objectify(type, [I[1], One(U), J[i], P]));
od; fi; else
gens:=[]; for i in I do for u in U do for j in J do
Add(gens, Objectify(type, [i, u, j, P]));
od;
od;
od; fi;
return gens; end);
# generators for the subsemigroup generated by <IxUxJ>, when <R> is a Rees # matrix semigroup (and not only a subsemigroup).
InstallGlobalFunction(GeneratorsOfReesZeroMatrixSemigroupNC, function(R, I, U, J)
local P, type, i, j, gens, k, u;
if IsGroup(U) and IsRegularSemigroup(R) and not j=fail then if IsTrivial(U) then
gens:=[Objectify(type, [i, P[j][i]^-1, j, P])]; else
gens:=List(GeneratorsOfGroup(U), x->
Objectify(type, [i, x*P[j][i]^-1, j, P])); fi;
for k in J do if k<>j then
Add(gens, Objectify(type, [i, One(U), k, P])); fi;
od;
for k in I do if k<>i then
Add(gens, Objectify(type, [k, One(U), j, P])); fi;
od; else
gens:=[]; for i in I do for u in U do for j in J do
Add(gens, Objectify(type, [i, u, j, P]));
od;
od;
od; fi;
return gens; end);
# you can't do this operation on arbitrary subsemigroup of Rees matrix # semigroups since they don't have to be simple and so don't have to have rows, # columns etc.
# generators for the subsemigroup generated by <IxUxJ>, when <R> is a Rees # matrix semigroup (and not only a subsemigroup).
InstallMethod(GeneratorsOfReesMatrixSemigroup, "for a Rees matrix subsemigroup, rows, semigroup, columns",
[IsReesMatrixSubsemigroup, IsList, IsSemigroup, IsList], function(R, I, U, J)
if not IsReesMatrixSemigroup(R) then
ErrorNoReturn("the first argument must be a Rees matrix semigroup"); elif not IsSubset(Rows(R), I) or IsEmpty(I) then
ErrorNoReturn("the second argument must be a non-empty subset of the ", "rows of the first argument (a Rees matrix semigroup)"); elif not IsSubsemigroup(UnderlyingSemigroup(R), U) then
ErrorNoReturn("the third argument must be a subsemigroup of the ", "underlying semigroup of the first argument (a Rees matrix ", "semigroup)"); elif not IsSubset(Columns(R), J) or IsEmpty(J) then
ErrorNoReturn("the fourth argument must be a non-empty subset of the ", "columns of the first argument (a Rees matrix semigroup)"); fi;
return GeneratorsOfReesMatrixSemigroupNC(R, I, U, J); end);
# you can't do this operation on arbitrary subsemigroup of Rees matrix # semigroups since they don't have to be simple and so don't have to have rows, # columns etc.
# generators for the subsemigroup generated by <IxUxJ>, when <R> is a Rees # matrix semigroup (and not only a subsemigroup).
InstallMethod(GeneratorsOfReesZeroMatrixSemigroup, "for a Rees 0-matrix semigroup, rows, semigroup, columns",
[IsReesZeroMatrixSubsemigroup, IsList, IsSemigroup, IsList], function(R, I, U, J)
if not IsReesZeroMatrixSemigroup(R) then
ErrorNoReturn("the first argument must be a Rees 0-matrix semigroup"); elif not IsSubset(Rows(R), I) or IsEmpty(I) then
ErrorNoReturn("the second argument must be a non-empty subset of the ", "rows of the first argument (a Rees 0-matrix semigroup)"); elif not IsSubsemigroup(UnderlyingSemigroup(R), U) then
ErrorNoReturn("the third argument must be a subsemigroup of the ", "underlying semigroup of the first argument (a Rees ", "0-matrix semigroup)"); elif not IsSubset(Columns(R), J) or IsEmpty(J) then
ErrorNoReturn("the fourth argument must be a non-empty subset of the ", "columns of the first argument (a Rees 0-matrix semigroup)"); fi;
return GeneratorsOfReesZeroMatrixSemigroupNC(R, I, U, J); end);
InstallMethod(GeneratorsOfSemigroup, "for a Rees 0-matrix semigroup",
[IsReesZeroMatrixSemigroup], function(R)
local gens;
gens:=GeneratorsOfReesZeroMatrixSemigroupNC(R, Rows(R),
UnderlyingSemigroup(R), Columns(R)); if ForAll(Rows(R), i-> ForAll(Columns(R), j-> Matrix(R)[j][i]<>0)) then
Add(gens, MultiplicativeZero(R)); fi;
return gens; end);
# Note that it is possible that the rows and columns of the matrix only contain # the zero element, if the resulting semigroup were taken to be in # IsReesMatrixSemigroup then it would belong to IsReesMatrixSemigroup and # IsReesZeroMatrixSubsemigroup, so that its elements belong to # IsReesZeroMatrixSemigroupElement but not to IsReesMatrixSemigroupElement # (since this makes reference to the whole family used to create the # semigroups). On the other hand, if we simply exclude the 0, then every method # for IsReesZeroMatrixSemigroup is messed up because we assume that they always # contain the 0. # # Hence we always include the 0 element, even if all the matrix # entries corresponding to I and J are non-zero.
InstallMethod(ReesZeroMatrixSubsemigroup, "for a Rees 0-matrix semigroup, rows, semigroup, columns",
[IsReesZeroMatrixSubsemigroup, IsList, IsSemigroup, IsList], function(R, I, U, J)
if not IsReesZeroMatrixSemigroup(R) then
ErrorNoReturn("the first argument must be a Rees 0-matrix semigroup"); elif not IsSubset(Rows(R), I) or IsEmpty(I) then
ErrorNoReturn("the second argument must be a non-empty subset of the ", "rows of the first argument (a Rees 0-matrix semigroup)"); elif not IsSubsemigroup(UnderlyingSemigroup(R), U) then
ErrorNoReturn("the third argument must be a subsemigroup of the ", "underlying semigroup of the first argument (a Rees ", "0-matrix semigroup)"); elif not IsSubset(Columns(R), J) or IsEmpty(J) then
ErrorNoReturn("the fourth argument must be a non-empty subset of the ", "columns of the first argument (a Rees 0-matrix semigroup)"); fi;
return ReesZeroMatrixSubsemigroupNC(R, I, U, J); end);
InstallGlobalFunction(ReesZeroMatrixSubsemigroupNC, function(R, I, U, J)
local S;
if U=UnderlyingSemigroup(R) and ForAny(Matrix(R){J}{I}, x-> 0 in x) then
S:=Objectify( NewType( FamilyObj(R),
IsReesZeroMatrixSubsemigroup and IsAttributeStoringRep ), rec() );
SetTypeReesMatrixSemigroupElements(S, TypeReesMatrixSemigroupElements(R));
#it might be that all the matrix entries corresponding to I and J are zero #and so we can't set IsZeroSimpleSemigroup here.
SetMultiplicativeZero(S, MultiplicativeZero(R));
SetIsSimpleSemigroup(S, false);
SetIsReesZeroMatrixSemigroup(S, true);
return S; fi;
return Semigroup(GeneratorsOfReesZeroMatrixSemigroupNC(R, I, U, J)); end);
#
InstallMethod(ReesMatrixSubsemigroup, "for a Rees matrix semigroup, rows, semigroup, columns",
[IsReesMatrixSubsemigroup, IsList, IsSemigroup, IsList], function(R, I, U, J)
if not IsReesMatrixSemigroup(R) then
ErrorNoReturn("the first argument must be a Rees matrix semigroup"); elif not IsSubset(Rows(R), I) or IsEmpty(I) then
ErrorNoReturn("the second argument must be a non-empty subset of the ", "rows of the first argument (a Rees matrix semigroup)"); elif not IsSubsemigroup(UnderlyingSemigroup(R), U) then
ErrorNoReturn("the third argument must be a subsemigroup of the ", "underlying semigroup of the first argument (a Rees ", "matrix semigroup)"); elif not IsSubset(Columns(R), J) or IsEmpty(J) then
ErrorNoReturn("the fourth argument must be a non-empty subset of the ", "columns of the first argument (a Rees matrix semigroup)"); fi;
return ReesMatrixSubsemigroupNC(R, I, U, J); end);
#
InstallGlobalFunction(ReesMatrixSubsemigroupNC, function(R, I, U, J)
local S;
if U=UnderlyingSemigroup(R) then
S:=Objectify( NewType( FamilyObj(R),
IsReesMatrixSubsemigroup and IsAttributeStoringRep ), rec() );
SetTypeReesMatrixSemigroupElements(S, TypeReesMatrixSemigroupElements(R));
if HasIsSimpleSemigroup(R) and IsSimpleSemigroup(R) then
SetIsSimpleSemigroup(S, true); fi;
SetIsReesMatrixSemigroup(S, true);
SetIsZeroSimpleSemigroup(S, false);
return S; fi;
return Semigroup(GeneratorsOfReesMatrixSemigroupNC(R, I, U, J)); end);
#
BindGlobal("_InjectionPrincipalFactor", function(D, constructor)
local map, inv, G, mat, rep, R, L, x, RR, LL, rms, iso, hom, i, j;
rep := Representative(GroupHClassOfGreensDClass(D));
L := List(GreensHClasses(GreensRClassOfElement(Parent(D), rep)),
Representative);
R := List(GreensHClasses(GreensLClassOfElement(Parent(D), rep)),
Representative);
for i in [1 .. Length(L)] do
mat[i] := []; for j in [1 .. Length(R)] do
x := L[i] * R[j]; if x in D then
mat[i,j] := x ^ map; else
mat[i,j] := 0; fi;
od;
od;
for j in [1 .. Length(R)] do for i in [1 .. Length(L)] do if mat[i,j] <> 0then
RR[j] := ((mat[i,j] ^ -1) ^ inv) * L[i];
break; fi;
od;
od;
for i in [1 .. Length(L)] do for j in [1 .. Length(R)] do if mat[i,j] <> 0then
LL[i] := R[j] * (mat[i,j] ^ -1) ^ inv;
break; fi;
od;
od;
rms := constructor(G, mat);
iso := function(x)
i := PositionProperty(R, y -> y in GreensRClassOfElement(Parent(D), x));
j := PositionProperty(L, y -> y in GreensLClassOfElement(Parent(D), x));
if i = fail or j = fail then
return fail; fi;
return Objectify(TypeReesMatrixSemigroupElements(rms),
[i, (rep * RR[i] * x * LL[j]) ^ map, j, mat]); end;
InstallMethod(IsomorphismReesMatrixSemigroup, "for a D-class",
[IsGreensDClass], function(D) if Number(D, IsIdempotent) <> Length(GreensHClasses(D)) then
ErrorNoReturn("the argument (a Green's D-class) is not a subsemigroup"); fi;
return _InjectionPrincipalFactor(D, ReesMatrixSemigroup); end);
InstallMethod(IsomorphismReesMatrixSemigroup, "for a finite simple", [IsSemigroup], function(S)
local rep, inj;
if not (IsSimpleSemigroup(S) and IsFinite(S)) then
ErrorNoReturn("the argument must be a finite simple semigroup"); fi;
# the below is necessary since map is not defined on the zero of S
inj := function(x) if x = MultiplicativeZero(S) then
return MultiplicativeZero(Range(map)); fi;
return x ^ map; end;
inv := function(x) if x = MultiplicativeZero(Range(map)) then
return MultiplicativeZero(S); fi;
return x ^ InverseGeneralMapping(map); end;
InstallMethod(AssociatedReesMatrixSemigroupOfDClass, "for a Green's D-class of a semigroup",
[IsGreensDClass], function(D)
if not IsFinite(Parent(D)) then
TryNextMethod(); fi;
if not IsRegularDClass(D) then
ErrorNoReturn("the argument should be a regular D-class"); fi;
if Length(GreensHClasses(D)) = Number(D, IsIdempotent) then
return Range(IsomorphismReesMatrixSemigroup(D)); fi;
return Range(_InjectionPrincipalFactor(D, ReesZeroMatrixSemigroup)); end);
# so that we can find Green's relations etc
InstallMethod(MonoidByAdjoiningIdentity, [IsReesMatrixSubsemigroup], function(R)
local M;
M:=Monoid(List(GeneratorsOfSemigroup(R), MonoidByAdjoiningIdentityElt));
SetUnderlyingSemigroupOfMonoidByAdjoiningIdentity(M, R);
return M; end);
# so that we can find Green's relations etc
InstallMethod(MonoidByAdjoiningIdentity, [IsReesZeroMatrixSubsemigroup], function(R)
local M;
M:=Monoid(List(GeneratorsOfSemigroup(R), MonoidByAdjoiningIdentityElt));
SetUnderlyingSemigroupOfMonoidByAdjoiningIdentity(M, R);
return M; end);
# the next two methods by Michael Torpey and Thomas Bourne.
InstallMethod(IsomorphismReesZeroMatrixSemigroup, "for a Rees 0-matrix subsemigroup", [IsReesZeroMatrixSubsemigroup], function(U)
local V, iso, inv;
if not IsReesZeroMatrixSemigroup(U) then
TryNextMethod(); elif IsWholeFamily(U) then
return MagmaIsomorphismByFunctionsNC(U, U, IdFunc, IdFunc); fi;
iso := function(u) if u = MultiplicativeZero(U) then
return MultiplicativeZero(V); fi;
return RMSElement(V,
Position(Rows(U),u![1]),
u![2],
Position(Columns(U),u![3])); end;
inv := function(v) if v = MultiplicativeZero(V) then
return MultiplicativeZero(U); fi;
return RMSElement(U, Rows(U)[v![1]], v![2], Columns(U)[v![3]]); end;
InstallMethod(IsomorphismReesMatrixSemigroup, "for a Rees matrix subsemigroup",
[IsReesMatrixSubsemigroup], function(U)
local V, iso, inv;
if not IsReesMatrixSemigroup(U) then
TryNextMethod(); elif IsWholeFamily(U) then
return MagmaIsomorphismByFunctionsNC(U, U, IdFunc, IdFunc); fi;
V:=ReesMatrixSemigroup(UnderlyingSemigroup(U),
List(Matrix(U){Columns(U)}, x-> x{Rows(U)})); #JDM doing Matrix(U){Columns(U)}{Rows(U)} the resulting object does not know #IsRectangularTable, and doesn't store this after it is calculated.
iso := function(u)
return RMSElement(V, Position(Rows(U),u![1]), u![2],
Position(Columns(U),u![3])); end;
¤ 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.0.34Bemerkung:
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-10-13)
¤
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.