Skip to content

Commit

Permalink
Merge branch 'main' into better-nambooripad
Browse files Browse the repository at this point in the history
  • Loading branch information
james-d-mitchell authored Nov 10, 2024
2 parents e0bb823 + 4f732b7 commit 0a68308
Show file tree
Hide file tree
Showing 11 changed files with 170 additions and 31 deletions.
28 changes: 28 additions & 0 deletions doc/attr.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1205,6 +1205,34 @@ gap> GeneratorsSmallest(T);
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="OneInverseOfSemigroupElement">
<ManSection>
<Attr Name="OneInverseOfSemigroupElement" Arg="S, x"/>
<Returns> One inverse of an element of a semigroup.</Returns>
<Description>
<C>OneInverseOfSemigroupElement</C> returns one inverse of the element
<C>x</C> in the semigroup <A>S</A> and returns fail if this
element has no inverse in <A>S</A>.
<A>x</A> in the semigroup <A>S</A>.
<Example><![CDATA[
gap> S := FullTransformationMonoid(4);
<full transformation monoid of degree 4>
gap> s := Transformation([2, 3, 1, 1]);
Transformation( [ 2, 3, 1, 1 ] )
gap> OneInverseOfSemigroupElement(S, s);
Transformation( [ 3, 1, 2, 2 ] )
gap> e := IdentityTransformation;
IdentityTransformation
gap> OneInverseOfSemigroupElement(S, e);
IdentityTransformation
gap> F := FreeSemigroup(1);
<free semigroup on the generators [ s1 ]>
gap> OneInverseOfSemigroupElement(F, F.1);
Error, the semigroup is not finite]]></Example>
</Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IndecomposableElements">
<ManSection>
<Attr Name="IndecomposableElements" Arg="S"/>
Expand Down
2 changes: 1 addition & 1 deletion doc/greens-generic.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1066,7 +1066,7 @@ gap> List(DClasses(S), SchutzenbergerGroup);
element <C>s</C> is of the same type as the elements of <A>S</A> but may
or may not be an element of <A>S</A>. In particular, if <A>S</A> is not a
monoid and <C><A>a</A> = <A>b</A></C>, then
<C>One(GeneratorsOfSemigroup(S))</C> may be returned. Even if <C><A>a</A> &lt;>
<C>One(GeneratorsOfSemigroup(S))</C> or an adjoined identity may be returned. Even if <C><A>a</A> &lt;>
<A>b</A></C>, then it is not guaranteed that the returned element <C>s</C>
will belong to <A>S</A>. It is guaranteed that the left action of <C>s</C> on
the elements of the &L;-class of <A>a</A> is the same as the left action of
Expand Down
11 changes: 11 additions & 0 deletions doc/z-chap11.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,17 @@
<!--**********************************************************************-->
<!--**********************************************************************-->

<Section>

<Heading>
Operations for elements in a semigroup
</Heading>
<#Include Label = "OneInverseOfSemigroupElement">
</Section>

<!--**********************************************************************-->
<!--**********************************************************************-->

<Section>

<Heading>
Expand Down
4 changes: 4 additions & 0 deletions gap/attributes/attr.gd
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ DeclareAttribute("UnderlyingSemigroupOfSemigroupWithAdjoinedZero",

DeclareOperation("InversesOfSemigroupElementNC",
[IsSemigroup, IsMultiplicativeElement]);
DeclareOperation("OneInverseOfSemigroupElementNC",
[IsSemigroup, IsMultiplicativeElement]);
DeclareOperation("OneInverseOfSemigroupElement",
[IsSemigroup, IsMultiplicativeElement]);

DeclareAttribute("IndecomposableElements", IsSemigroup);
DeclareAttribute("NambooripadLeqRegularSemigroup", IsSemigroup);
Expand Down
69 changes: 61 additions & 8 deletions gap/attributes/attr.gi
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ end);

InstallMethod(InversesOfSemigroupElementNC,
"for a group as semigroup and a multiplicative element",
[IsGroupAsSemigroup, IsMultiplicativeElement],
[IsGroupAsSemigroup and CanUseFroidurePin, IsMultiplicativeElement],
function(G, x)
local i, iso, inv;
if IsMultiplicativeElementWithInverse(x) then
Expand All @@ -774,26 +774,79 @@ function(G, x)
end);

InstallMethod(InversesOfSemigroupElementNC,
"for a semigroup and a multiplicative element",
[IsSemigroup, IsMultiplicativeElement],
"for a semigroup that can use froidure-pin and a multiplicative element",
[CanUseFroidurePin, IsMultiplicativeElement],
function(S, a)
local R, L, inverses, e, f, s;
R := RClass(S, a);
L := LClass(S, a);
inverses := EmptyPlist(NrIdempotents(R) * NrIdempotents(L));

for e in Idempotents(R) do
s := RightGreensMultiplierNC(S, a, e) * e;
for f in Idempotents(L) do
Add(inverses, f * s);
od;
od;
return inverses;
end);

InstallMethod(InversesOfSemigroupElement,
"for a semigroup that can use froidure-pin and a multiplicative element",
[CanUseFroidurePin, IsMultiplicativeElement], # to beat the library method
function(S, x)
if not IsFinite(S) then
TryNextMethod();
elif not x in S then
ErrorNoReturn("the 2nd argument (a mult. element) must belong to the 1st ",
"argument (a semigroup)");
fi;
return Filtered(EnumeratorSorted(S), y -> x * y * x = x and y * x * y = y);
return InversesOfSemigroupElementNC(S, x);
end);

InstallMethod(InversesOfSemigroupElement,
InstallMethod(OneInverseOfSemigroupElementNC,
"for a semigroup and a multiplicative element",
[IsSemigroup, IsMultiplicativeElement], 1, # to beat the library method
[IsSemigroup, IsMultiplicativeElement],
function(S, x)
if not IsFinite(S) then
TryNextMethod();
fi;
return First(EnumeratorSorted(S),
y -> x * y * x = x and y * x * y = y);
end);

InstallMethod(OneInverseOfSemigroupElementNC,
"for CanUseFroidurePin and a multiplicative element",
[CanUseFroidurePin, IsMultiplicativeElement],
function(S, a)
local R, L, e, f, s;
R := RClass(S, a);
L := LClass(S, a);
e := Idempotents(R);
if IsEmpty(e) then
return fail;
fi;
e := e[1];
f := Idempotents(L);
if IsEmpty(f) then
return fail;
fi;
f := f[1];
s := RightGreensMultiplierNC(S, a, e);
return f * s * e;
end);

InstallMethod(OneInverseOfSemigroupElement,
"for a semigroup and a multiplicative element",
[IsSemigroup, IsMultiplicativeElement],
function(S, x)
if not IsFinite(S) then
TryNextMethod();
ErrorNoReturn("the semigroup is not finite");
elif not x in S then
ErrorNoReturn("the 2nd argument (a mult. element) must belong to the 1st ",
"argument (a semigroup)");
fi;
return InversesOfSemigroupElementNC(S, x);
return OneInverseOfSemigroupElementNC(S, x);
end);

InstallMethod(UnderlyingSemigroupOfSemigroupWithAdjoinedZero,
Expand Down
46 changes: 30 additions & 16 deletions gap/greens/froidure-pin.gi
Original file line number Diff line number Diff line change
Expand Up @@ -606,39 +606,53 @@ function(S)
end);

InstallMethod(LeftGreensMultiplierNC,
"for a semigroup that can use Froidure-Pin and L-related elements with one",
"for a semigroup that can use Froidure-Pin and L-related elements",
[IsSemigroup and CanUseFroidurePin,
IsMultiplicativeElementWithOne,
IsMultiplicativeElementWithOne],
IsMultiplicativeElement,
IsMultiplicativeElement],
function(S, a, b)
local gens, D, path;
local gens, D, path, a1, b1;
gens := GeneratorsOfSemigroup(S);
D := LeftCayleyDigraph(S);
a := PositionCanonical(S, a);
b := PositionCanonical(S, b);
path := NextIterator(IteratorOfPaths(D, a, b));
a1 := PositionCanonical(S, a);
b1 := PositionCanonical(S, b);
path := NextIterator(IteratorOfPaths(D, a1, b1));
if path = fail then
# This can occur when, for example, a = b and S is not a monoid.
return One(gens);
if IsMultiplicativeElementWithOne(a)
and IsMultiplicativeElementWithOne(b) then
return One(gens);
elif MultiplicativeNeutralElement(S) <> fail then
return MultiplicativeNeutralElement(S);
else
return SEMIGROUPS.UniversalFakeOne;
fi;
fi;
return EvaluateWord(gens, Reversed(path[2]));
end);

InstallMethod(RightGreensMultiplierNC,
"for a semigroup that can use Froidure-Pin and R-related elements with one",
"for a semigroup that can use Froidure-Pin and R-related elements",
[IsSemigroup and CanUseFroidurePin,
IsMultiplicativeElementWithOne,
IsMultiplicativeElementWithOne],
IsMultiplicativeElement,
IsMultiplicativeElement],
function(S, a, b)
local gens, D, path;
local gens, D, path, a1, b1;
gens := GeneratorsOfSemigroup(S);
D := RightCayleyDigraph(S);
a := PositionCanonical(S, a);
b := PositionCanonical(S, b);
path := NextIterator(IteratorOfPaths(D, a, b));
a1 := PositionCanonical(S, a);
b1 := PositionCanonical(S, b);
path := NextIterator(IteratorOfPaths(D, a1, b1));
if path = fail then
# This can occur when, for example, a = b and S is not a monoid.
return One(gens);
if IsMultiplicativeElementWithOne(a)
and IsMultiplicativeElementWithOne(b) then
return One(gens);
elif MultiplicativeNeutralElement(S) <> fail then
return MultiplicativeNeutralElement(S);
else
return SEMIGROUPS.UniversalFakeOne;
fi;
fi;
return EvaluateWord(gens, path[2]);
end);
Expand Down
2 changes: 1 addition & 1 deletion gap/semigroups/grpperm.gi
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ end);

# fall back method, same method for ideals

InstallMethod(IsomorphismPermGroup, "for a semigroup", [IsSemigroup],
InstallMethod(IsomorphismPermGroup, "for a semigroup", [CanUseFroidurePin],
function(S)
local cay, deg, G, gen1, gen2, next, pos, iso, inv, i;
if not IsFinite(S) then
Expand Down
32 changes: 31 additions & 1 deletion tst/standard/attributes/attr.tst
Original file line number Diff line number Diff line change
Expand Up @@ -1474,9 +1474,39 @@ gap> InversesOfSemigroupElement(S, IdentityTransformation);
Error, usage: the 2nd argument must be an element of the 1st,
gap> InversesOfSemigroupElementNC(S, S.1);
Error, no method found! For debugging hints type ?Recovery from NoMethodFound
Error, no 2nd choice method found for `InversesOfSemigroupElementNC' on 2 argu\
Error, no 1st choice method found for `InversesOfSemigroupElementNC' on 2 argu\
ments

# attr: OneInverseOfSemigroupElement, for a semigroup
gap> S := Semigroup([
> Matrix(IsMaxPlusMatrix, [[-2, 2, 0], [-1, 0, 0], [1, -3, 1]]),
> Matrix(IsMaxPlusMatrix, [[- infinity, 0, 0], [0, 1, 0], [1, -1, 0]])]);;
gap> OneInverseOfSemigroupElement(S, S.1);
Error, the semigroup is not finite
gap> S := Semigroup(Transformation([2, 3, 1, 3, 3]));;
gap> OneInverseOfSemigroupElement(S, Transformation([1, 3, 2]));
Error, the 2nd argument (a mult. element) must belong to the 1st argument (a s\
emigroup)
gap> S := Semigroup([Matrix(IsBooleanMat, [[0, 0, 1], [0, 1, 1], [1, 0, 0]]),
> Matrix(IsBooleanMat, [[1, 0, 0], [1, 0, 1], [1, 1, 1]])]);;
gap> OneInverseOfSemigroupElement(S, S.1);
fail
gap> OneInverseOfSemigroupElement(S, S.1 * S.2 * S.1);
Matrix(IsBooleanMat, [[1, 1, 1], [1, 1, 1], [0, 0, 1]])

# OneInverseOfSemigroupElement, for a semigroup that cannot use Froidure-Pin
gap> S := Semigroup(SEMIGROUPS.UniversalFakeOne);;
gap> OneInverseOfSemigroupElement(S, S.1);
<universal fake one>

# OneInverseOfSemigroupElement, for an infinite semigroup, 1
gap> S := FreeSemigroup(1);
<free semigroup on the generators [ s1 ]>
gap> OneInverseOfSemigroupElementNC(S, S.1);
Error, no method found! For debugging hints type ?Recovery from NoMethodFound
Error, no 2nd choice method found for `OneInverseOfSemigroupElementNC' on 2 ar\
guments
# attr: IdempotentGeneratedSubsemigroup, 2
gap> S := FullTransformationMonoid(3);;
gap> I := IdempotentGeneratedSubsemigroup(S);;
Expand Down
2 changes: 1 addition & 1 deletion tst/standard/ideals/ideals.tst
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ gap> I := SemigroupIdeal(S,
> Matrix(IsBooleanMat, [[1, 0, 1], [0, 0, 0], [0, 1, 0]]),
> Matrix(IsBooleanMat, [[0, 1, 1], [0, 1, 1], [1, 0, 1]]));;
gap> x := Matrix(IsBooleanMat, [[1, 0, 1], [0, 1, 0], [1, 0, 1]]);;
gap> InversesOfSemigroupElement(I, x);
gap> AsSet(InversesOfSemigroupElement(I, x));
[ Matrix(IsBooleanMat, [[0, 0, 0], [0, 1, 0], [0, 0, 1]]),
Matrix(IsBooleanMat, [[0, 0, 0], [0, 1, 0], [1, 0, 0]]),
Matrix(IsBooleanMat, [[0, 0, 0], [0, 1, 0], [1, 0, 1]]),
Expand Down
2 changes: 1 addition & 1 deletion tst/standard/semigroups/grpperm.tst
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ Group([ (1,3)(2,5)(4,6), (1,4,5)(2,6,3) ])
# IsomorphismPermGroup, infinite 1 / 1
gap> IsomorphismPermGroup(FreeMonoid(3));
Error, no method found! For debugging hints type ?Recovery from NoMethodFound
Error, no 3rd choice method found for `IsomorphismPermGroup' on 1 arguments
Error, no 2nd choice method found for `IsomorphismPermGroup' on 1 arguments
# IsomorphismPermGroup, for a block bijection semigroup
gap> S := Semigroup(Bipartition([[1, 2, -3, -4], [3, 4, -1, -2]]));;
Expand Down
3 changes: 1 addition & 2 deletions tst/standard/semigroups/semirms.tst
Original file line number Diff line number Diff line change
Expand Up @@ -2629,8 +2629,7 @@ gap> R := ReesZeroMatrixSemigroup(SymmetricGroup(4),
> [(), (2, 4, 3), (1, 2)]]);
<Rees 0-matrix semigroup 3x4 over Sym( [ 1 .. 4 ] )>
gap> IsomorphismPermGroup(R);
Error, the underlying semigroup of the argument (a subsemigroup of a Rees 0-m\
atrix semigroup) does not satisfy IsGroupAsSemigroup
Error, the argument (a semigroup) does not satisfy IsGroupAsSemigroup
gap> S := Semigroup(MultiplicativeZero(R));;
gap> IsomorphismPermGroup(S);
<subsemigroup of 3x4 Rees 0-matrix semigroup with 1 generator> -> Group(())
Expand Down

0 comments on commit 0a68308

Please sign in to comment.