Spracherkennung für: .gi vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]
#############################################################################
##
## congruences/conguniv.gi
## Copyright (C) 2015-2022 Michael C. Young
##
## Licensing information can be found in the README file of this package.
##
#############################################################################
##
## This file contains methods for the unique universal congruence on a
## semigroup, that is the relation SxS on a semigroup S.
##
InstallMethod(UniversalSemigroupCongruence, "for a semigroup",
[IsSemigroup],
function(S)
local fam, C;
fam := GeneralMappingsFamily(ElementsFamily(FamilyObj(S)),
ElementsFamily(FamilyObj(S)));
C := Objectify(NewType(fam,
IsSemigroupCongruence
and IsMagmaCongruence
and CanComputeEquivalenceRelationPartition
and IsAttributeStoringRep),
rec());
SetSource(C, S);
SetRange(C, S);
SetIsUniversalSemigroupCongruence(C, true);
return C;
end);
InstallMethod(IsUniversalSemigroupCongruence, "for a semigroup congruence",
[IsSemigroupCongruence],
C -> NrEquivalenceClasses(C) = 1);
InstallImmediateMethod(IsUniversalSemigroupCongruence,
IsSemigroupCongruence and HasNrEquivalenceClasses, 0,
C -> NrEquivalenceClasses(C) = 1);
InstallMethod(EquivalenceRelationCanonicalLookup,
"for a universal semigroup congruence",
[IsUniversalSemigroupCongruence],
C -> ListWithIdenticalEntries(Size(Range(C)), 1));
InstallMethod(EquivalenceRelationPartition,
"for a universal semigroup congruence",
[IsUniversalSemigroupCongruence],
C -> [AsList(Range(C))]);
InstallMethod(ViewObj, "for universal semigroup congruence",
[IsUniversalSemigroupCongruence],
function(C)
Print("<universal semigroup congruence over ");
ViewObj(Range(C));
Print(">");
end);
InstallMethod(\=,
"for two universal semigroup congruences",
[IsUniversalSemigroupCongruence, IsUniversalSemigroupCongruence],
{lhop, rhop} -> Range(lhop) = Range(rhop));
InstallMethod(\=,
"for universal congruence and RZMS congruence by linked triple",
[IsUniversalSemigroupCongruence, IsRZMSCongruenceByLinkedTriple],
ReturnFalse);
InstallMethod(\=,
"for RZMS congruence by linked triple and universal congruence",
[IsRZMSCongruenceByLinkedTriple, IsUniversalSemigroupCongruence],
ReturnFalse);
InstallMethod(\=,
"for universal congruence and semigroup congruence with generating pairs",
[IsUniversalSemigroupCongruence,
IsSemigroupCongruence and HasGeneratingPairsOfMagmaCongruence],
{U, C} -> Range(U) = Range(C) and NrEquivalenceClasses(C) = 1);
InstallMethod(\=,
"for universal congruence and semigroup congruence with generating pairs",
[IsSemigroupCongruence and HasGeneratingPairsOfMagmaCongruence,
IsUniversalSemigroupCongruence],
{C, U} -> U = C);
InstallMethod(CongruenceTestMembershipNC,
"for universal semigroup congruence and two multiplicative elements",
[IsUniversalSemigroupCongruence,
IsMultiplicativeElement, IsMultiplicativeElement],
ReturnTrue);
InstallMethod(IsSubrelation,
"for a universal semigroup congruence and a semigroup congruence",
[IsUniversalSemigroupCongruence, IsSemigroupCongruence],
function(U, C)
if Range(U) <> Range(C) then
Error("the 1st and 2nd arguments are congruences over different",
" semigroups");
fi;
return true;
end);
InstallMethod(IsSubrelation,
"for a semigroup congruence and a universal semigroup congruence",
[IsSemigroupCongruence, IsUniversalSemigroupCongruence],
function(C, U)
if Range(U) <> Range(C) then
Error("the 1st and 2nd arguments are congruences over different",
" semigroups");
fi;
return C = U;
end);
InstallMethod(ImagesElm,
"for universal semigroup congruence and element",
[IsUniversalSemigroupCongruence, IsMultiplicativeElement],
function(C, x)
if not x in Range(C) then
ErrorNoReturn("the 2nd argument (a mult. elt.) does not belong to ",
"the range of the 1st argument (a congruence)");
fi;
return AsList(Range(C));
end);
InstallMethod(NrEquivalenceClasses,
"for universal semigroup congruence",
[IsUniversalSemigroupCongruence], C -> 1);
InstallMethod(JoinSemigroupCongruences,
"for semigroup congruence and universal congruence",
[IsSemigroupCongruence, IsUniversalSemigroupCongruence],
function(C, U)
if Range(C) <> Range(U) then
ErrorNoReturn("cannot form the join of congruences over different",
" semigroups");
fi;
return U;
end);
InstallMethod(JoinSemigroupCongruences,
"for universal congruence and semigroup congruence",
[IsUniversalSemigroupCongruence, IsSemigroupCongruence],
function(U, C)
if Range(C) <> Range(U) then
ErrorNoReturn("cannot form the join of congruences over different",
" semigroups");
fi;
return U;
end);
InstallMethod(MeetSemigroupCongruences,
"for semigroup congruence and universal congruence",
[IsSemigroupCongruence, IsUniversalSemigroupCongruence],
function(C, U)
if Range(C) <> Range(U) then
ErrorNoReturn("cannot form the meet of congruences over different",
" semigroups");
fi;
return C;
end);
InstallMethod(MeetSemigroupCongruences,
"for universal congruence and semigroup congruence",
[IsUniversalSemigroupCongruence, IsSemigroupCongruence],
function(U, C)
if Range(C) <> Range(U) then
ErrorNoReturn("cannot form the meet of congruences over different",
" semigroups");
fi;
return C;
end);
InstallMethod(EquivalenceClasses,
"for universal semigroup congruence",
[IsUniversalSemigroupCongruence],
C -> [EquivalenceClassOfElement(C, Representative(Range(C)))]);
InstallMethod(EquivalenceClassOfElementNC,
"for universal semigroup congruence and associative element",
[IsUniversalSemigroupCongruence, IsMultiplicativeElement],
function(C, x)
local fam, class;
fam := CollectionsFamily(FamilyObj(x));
class := Objectify(NewType(fam,
IsUniversalSemigroupCongruenceClass
and IsLeftRightOrTwoSidedCongruenceClass),
rec());
SetParentAttr(class, Range(C));
SetEquivalenceClassRelation(class, C);
SetRepresentative(class, x);
return class;
end);
InstallMethod(\in,
"for associative element and universal semigroup congruence class",
[IsMultiplicativeElement, IsUniversalSemigroupCongruenceClass],
{x, class} -> x in Parent(class));
# TODO(later) more \* methods for universal and non-universal congruences??
InstallMethod(\*,
"for two universal semigroup congruence classes",
[IsUniversalSemigroupCongruenceClass, IsUniversalSemigroupCongruenceClass],
function(lhop, rhop)
if EquivalenceClassRelation(lhop) <> EquivalenceClassRelation(rhop) then
ErrorNoReturn("the arguments (cong. classes) are not classes of the same ",
"congruence");
fi;
return lhop;
end);
InstallMethod(Size,
"for universal semigroup congruence class",
[IsUniversalSemigroupCongruenceClass],
C -> Size(Range(EquivalenceClassRelation(C))));
InstallMethod(\=,
"for two universal semigroup congruence classes",
[IsUniversalSemigroupCongruenceClass, IsUniversalSemigroupCongruenceClass],
{lhop, rhop}
-> EquivalenceClassRelation(lhop) = EquivalenceClassRelation(rhop));
InstallMethod(GeneratingPairsOfMagmaCongruence,
"for universal semigroup congruence",
[IsUniversalSemigroupCongruence],
function(C)
local S, it, z, x, m, iso, r, n, colBlocks, rowBlocks, rmscong, pairs, d;
S := Range(C);
if Size(S) = 1 then
return [];
fi;
it := Iterator(S);
z := MultiplicativeZero(S);
if z <> fail then
if IsZeroSimpleSemigroup(S) then
# Just link zero to any non-zero element
x := NextIterator(it);
if x = z then
return [[z, NextIterator(it)]];
else
return [[x, z]];
fi;
else
# Link zero to a representative of each maximal D-class
return List(MaximalDClasses(S), cl -> [z, Representative(cl)]);
fi;
fi;
# Otherwise we have no zero: use the minimal ideal
m := MinimalIdeal(S);
# Use the linked triple
iso := IsomorphismReesMatrixSemigroup(m);
r := Range(iso);
n := UnderlyingSemigroup(r);
colBlocks := [[1 .. Size(Matrix(r)[1])]];
rowBlocks := [[1 .. Size(Matrix(r))]];
rmscong := RMSCongruenceByLinkedTriple(r, n, colBlocks, rowBlocks);
C := CongruenceByIsomorphism(iso, rmscong);
pairs := ShallowCopy(GeneratingPairsOfSemigroupCongruence(C));
if IsSimpleSemigroup(S) then
return pairs;
fi;
# We must relate each maximal D-class to the minimal ideal
z := GeneratorsOfSemigroupIdeal(m)[1];
for d in MaximalDClasses(S) do
Add(pairs, [z, Representative(d)]);
od;
return pairs;
end);