Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement LeftSemigroupIdeal and RightSemigroupIdeal #1009

Open
wants to merge 45 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
335f388
Adding Free Semilattice constructor
Jun2M Feb 7, 2024
5fb0319
For Transformation and PartialPerm Semigroups
Jun2M Feb 7, 2024
4685a06
Lint
Jun2M Feb 8, 2024
721a464
Update semicons.gd
Jun2M Feb 10, 2024
c4f56d9
Merge branch 'main' into main
Jun2M Feb 10, 2024
1ec0a1a
Add docs and a whole lot of tests
Jun2M Feb 10, 2024
f35961a
Minor test fix
Jun2M Feb 11, 2024
9ae4fd9
Merge branch 'main' into main
Jun2M Feb 14, 2024
432322b
Dial back on the number of tests
Jun2M Feb 14, 2024
708e4c1
Merge branch 'main' into main
james-d-mitchell Mar 11, 2024
917be05
Apply suggestions from code review
james-d-mitchell Mar 11, 2024
7977c3b
Change tst to reflect the new error msg
Jun2M Mar 12, 2024
f7338a2
Merge branch 'main' into main
Jun2M Mar 12, 2024
b2463bb
Add Monoid constructors to FreeSemilatticeCons
Jun2M Mar 13, 2024
19266ad
Unbind _IsXMonoid in semicons.gi
Jun2M Mar 13, 2024
58013b4
Update semicons.xml and semicons.gi files
Jun2M Mar 13, 2024
f430c07
Adding Free Semilattice constructor
Jun2M Feb 7, 2024
6a6fcf9
For Transformation and PartialPerm Semigroups
Jun2M Feb 7, 2024
d952a4a
Lint
Jun2M Feb 8, 2024
a15a713
Update semicons.gd
Jun2M Feb 10, 2024
6bc9989
Add docs and a whole lot of tests
Jun2M Feb 10, 2024
d80fd74
Minor test fix
Jun2M Feb 11, 2024
2e4c7aa
Dial back on the number of tests
Jun2M Feb 14, 2024
1cc19e1
Apply suggestions from code review
james-d-mitchell Mar 11, 2024
c9c2062
Change tst to reflect the new error msg
Jun2M Mar 12, 2024
a36b834
Add Monoid constructors to FreeSemilatticeCons
Jun2M Mar 13, 2024
c583ad6
Unbind _IsXMonoid in semicons.gi
Jun2M Mar 13, 2024
fa9344f
Update semicons.xml and semicons.gi files
Jun2M Mar 13, 2024
0b2d4d4
Merge branch 'semigroups:main' into main
Jun2M Mar 20, 2024
cfda100
Add left and right semigroup ideal support
Jun2M Mar 20, 2024
df1cc98
Edit docs
Jun2M Mar 26, 2024
0880917
Don't destroy the whole thing
Jun2M Mar 26, 2024
61ac68f
bug fix
Jun2M Mar 26, 2024
4f1200b
Fix ideals.gd
Jun2M Mar 26, 2024
eb93dfc
doc update
Jun2M Mar 26, 2024
4aefac6
Linting
Jun2M Mar 26, 2024
1140492
Factor out the input parsing
Jun2M Mar 27, 2024
abdf215
Hide internal functions and make first edits on ideal.tst
Jun2M Mar 27, 2024
eb4bc56
Appearently not a duplicate
Jun2M Mar 27, 2024
6e76d9b
Linting
Jun2M Mar 27, 2024
c74ebcd
Linting for tst file
Jun2M Mar 28, 2024
a538cc8
Linting for tst
Jun2M Mar 28, 2024
0a39a7c
More tests
Jun2M Apr 2, 2024
97eb398
Linting
Jun2M Apr 2, 2024
2f825bd
Lint
Jun2M Apr 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions doc/ideals.xml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,56 @@ gap> I := SemigroupIdeal(S, I, Idempotents(S));
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="LeftSemigroupIdeal">
<ManSection>
<Func Name = "LeftSemigroupIdeal" Arg = "S, obj1, obj2, .. . "/>
<Returns>
A left ideal of a semigroup.
</Returns>
<Description>
If <A>obj1</A>, <A>obj2</A>, .. . are (any combination) of elements of the
semigroup <A>S</A> or collections of elements of <A>S</A> (including
subsemigroups and ideals of <A>S</A>), then <C>LeftSemigroupIdeal</C> returns the
left ideal of the semigroup <A>S</A> generated by the union of
<A>obj1</A>, <A>obj2</A>, .. .. <P/>

The <Ref Func = "Parent" BookName = "ref"/> of the ideal returned by this
function is <A>S</A>.

<Example><![CDATA[
gap> S := SymmetricInverseMonoid(10);
<symmetric inverse monoid of degree 10>
gap> I := LeftSemigroupIdeal(S, PartialPerm([1, 2]));
<LeftMagmaIdeal with 1 generator>]]></Example>
</Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="RightSemigroupIdeal">
<ManSection>
<Func Name = "RightSemigroupIdeal" Arg = "S, obj1, obj2, .. . "/>
<Returns>
A Right ideal of a semigroup.
</Returns>
<Description>
If <A>obj1</A>, <A>obj2</A>, .. . are (any combination) of elements of the
semigroup <A>S</A> or collections of elements of <A>S</A> (including
subsemigroups and ideals of <A>S</A>), then <C>RightSemigroupIdeal</C> returns the
Right ideal of the semigroup <A>S</A> generated by the union of
<A>obj1</A>, <A>obj2</A>, .. .. <P/>

The <Ref Func = "Parent" BookName = "ref"/> of the ideal returned by this
function is <A>S</A>.

<Example><![CDATA[
gap> S := SymmetricInverseMonoid(10);
<symmetric inverse monoid of degree 10>
gap> I := RightSemigroupIdeal(S, PartialPerm([1, 2]));
<RightMagmaIdeal with 1 generator>]]></Example>
</Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="SupersemigroupOfIdeal">
<ManSection>
<Attr Name = "SupersemigroupOfIdeal" Arg = "I"/>
Expand Down
55 changes: 55 additions & 0 deletions doc/semicons.xml
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,61 @@ true]]></Example>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="FreeSemilattice">
<ManSection>
<Func Name="FreeSemilattice" Arg="[filt, ] n"/>
<Returns>
A free semilattice with <A>n</A> generators.
</Returns>
<Description>
If <A>n</A> is a positive integer, then this function returns a free
semilattice with <A>n</A> generators in the representation given by the
filter <A>filt</A>.

The optional argument <A>filt</A> may be one of the following:
<List>
<Item><C>IsTransformationSemigroup</C>
(the default, if <A>filt</A> is not specified),</Item>
<Item><C>IsTransformationMonoid</C>,</Item>
<Item><C>IsPartialPermSemigroup</C>,</Item>
<Item><C>IsPartialPermMonoid</C>,</Item>
<Item><C>IsFpSemigroup</C>,</Item>
<Item><C>IsFpMonoid</C>,</Item>
<Item><C>IsBipartitionSemigroup</C>,</Item>
<Item><C>IsBipartitionMonoid</C>,</Item>
<Item><C>IsPBRSemigroup</C>,</Item>
<Item><C>IsPBRMonoid</C>,</Item>
<Item><C>IsBooleanMatSemigroup</C>,</Item>
<Item><C>IsBooleanMatMonoid</C>,</Item>
<Item><C>IsNTPMatrixSemigroup</C>,</Item>
<Item><C>IsNTPMatrixMonoid</C>,</Item>
<Item><C>IsMaxPlusMatrixSemigroup</C>,</Item>
<Item><C>IsMaxPlusMatrixMonoid</C>,</Item>
<Item><C>IsMinPlusMatrixSemigroup</C>,</Item>
<Item><C>IsMinPlusMatrixMonoid</C>,</Item>
<Item><C>IsTropicalMaxPlusMatrixSemigroup</C>,</Item>
<Item><C>IsTropicalMaxPlusMatrixMonoid</C>,</Item>
<Item><C>IsTropicalMinPlusMatrixSemigroup</C>,</Item>
<Item><C>IsTropicalMinPlusMatrixMonoid</C>,</Item>
<Item><C>IsProjectiveMaxPlusMatrixSemigroup</C>,</Item>
<Item><C>IsProjectiveMaxPlusMatrixMonoid</C>,</Item>
<Item><C>IsIntegerMatrixSemigroup.</C></Item>
<Item><C>IsIntegerMatrixMonoid.</C></Item>
</List>

<Example><![CDATA[
gap> S := FreeSemilattice(IsTransformationSemigroup, 5);
<inverse transformation semigroup of size 31, degree 6 with 5
generators>
gap> T := FreeSemilattice(IsPartialPermSemigroup, 3);
<inverse partial perm semigroup of size 7, rank 3 with 3 generators>
gap> U := FreeSemilattice(IsBooleanMatSemigroup, 4);
<inverse semigroup of size 15, 5x5 boolean matrices with 4 generators>
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="ZeroSemigroup">
<ManSection>
<Func Name="ZeroSemigroup" Arg="[filt, ]n"/>
Expand Down
1 change: 1 addition & 0 deletions doc/z-chap07.xml
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@
<#Include Label = "TrivialSemigroup">
<#Include Label = "MonogenicSemigroup">
<#Include Label = "RectangularBand">
<#Include Label = "FreeSemilattice">
<#Include Label = "ZeroSemigroup">
<#Include Label = "LeftZeroSemigroup">
<#Include Label = "BrandtSemigroup">
Expand Down
2 changes: 2 additions & 0 deletions doc/z-chap09.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
</Heading>

<#Include Label = "SemigroupIdeal">
<#Include Label = "LeftSemigroupIdeal">
<#Include Label = "RightSemigroupIdeal">
<#Include Label = "Ideals">
</Section>

Expand Down
2 changes: 2 additions & 0 deletions gap/ideals/froidure-pin.gd
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@
##

DeclareAttribute("PositionsInSupersemigroup", IsSemigroupIdeal);
DeclareAttribute("PositionsInSupersemigroup", IsLeftSemigroupIdeal);
DeclareAttribute("PositionsInSupersemigroup", IsRightSemigroupIdeal);
42 changes: 42 additions & 0 deletions gap/ideals/froidure-pin.gi
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,48 @@ function(I)
return result;
end);

InstallMethod(PositionsInSupersemigroup,
"for a left semigroup ideal with known generators",
[IsLeftSemigroupIdeal and HasGeneratorsOfSemigroupIdeal and
CanUseFroidurePin],
function(I)
local S, L, result, pos, x;
S := SupersemigroupOfIdeal(I);
L := LeftCayleyDigraph(S);

result := [];
for x in GeneratorsOfSemigroupIdeal(I) do
pos := PositionCanonical(S, x);
if not pos in result then
AddSet(result, pos);
UniteSet(result, VerticesReachableFrom(L, pos));
fi;
od;

return result;
end);

InstallMethod(PositionsInSupersemigroup,
"for a right semigroup ideal with known generators",
[IsRightSemigroupIdeal and HasGeneratorsOfSemigroupIdeal and
CanUseFroidurePin],
function(I)
local S, R, result, pos, x;
S := SupersemigroupOfIdeal(I);
R := RightCayleyDigraph(S);

result := [];
for x in GeneratorsOfSemigroupIdeal(I) do
pos := PositionCanonical(S, x);
if not pos in result then
AddSet(result, pos);
UniteSet(result, VerticesReachableFrom(R, pos));
fi;
od;

return result;
end);

InstallMethod(GeneratorsOfInverseSemigroup,
"for an inverse semigroup ideal with inverse op and generators",
[IsSemigroupIdeal and IsInverseSemigroup
Expand Down
12 changes: 9 additions & 3 deletions gap/ideals/ideals.gd
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,21 @@
##
#############################################################################

DeclareSynonymAttr("GeneratorsOfSemigroupIdeal", GeneratorsOfMagmaIdeal);
DeclareSynonymAttr("GeneratorsOfSemigroupIdeal",
GeneratorsOfMagmaIdeal);
DeclareSynonymAttr("GeneratorsOfLeftSemigroupIdeal",
GeneratorsOfLeftMagmaIdeal);
DeclareSynonymAttr("GeneratorsOfRightSemigroupIdeal",
GeneratorsOfRightMagmaIdeal);

DeclareGlobalFunction("SemigroupIdeal");
DeclareGlobalFunction("LeftSemigroupIdeal");
DeclareGlobalFunction("RightSemigroupIdeal");

DeclareOperation("SemigroupIdealByGenerators",
[IsSemigroup, IsListOrCollection]);

DeclareOperation("SemigroupIdealByGenerators",
[IsSemigroup, IsListOrCollection, IsRecord]);

DeclareOperation("SemigroupIdealByGeneratorsNC",
[IsSemigroup, IsListOrCollection, IsRecord]);

Expand Down
104 changes: 82 additions & 22 deletions gap/ideals/ideals.gi
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,7 @@ InstallMethod(Representative, "for a semigroup ideal",

# a convenience, similar to the functions <Semigroup>, <Monoid>, etc

InstallGlobalFunction(SemigroupIdeal,
function(arg...)
SEMIGROUPS.AnySemigroupIdealInputParsing := function(arg...)
local out, i;

if Length(arg) <= 1 then
Expand All @@ -197,11 +196,11 @@ function(arg...)
ErrorNoReturn("the 1st argument is not a semigroup");
elif Length(arg) = 2 and IsMatrix(arg[2]) then
# special case for matrices, because they may look like lists
return SemigroupIdealByGenerators(arg[1], [arg[2]]);
return [arg[1], [arg[2]]];

elif Length(arg) = 2 and IsList(arg[2]) and 0 < Length(arg[2]) then
# list of generators
return SemigroupIdealByGenerators(arg[1], arg[2]);
return [arg[1], arg[2]];
elif (IsMultiplicativeElement(arg[2])
and IsGeneratorsOfSemigroup([arg[2]]))
or (IsListOrCollection(arg[2])
Expand All @@ -212,7 +211,7 @@ function(arg...)
for i in [2 .. Length(arg)] do
# so that we can pass the options record
if i = Length(arg) and IsRecord(arg[i]) then
return SemigroupIdealByGenerators(arg[1], out, arg[i]);
return [arg[1], out, arg[i]];
elif IsMultiplicativeElement(arg[i]) and
IsGeneratorsOfSemigroup([arg[i]]) then
Add(out, arg[i]);
Expand All @@ -232,36 +231,68 @@ function(arg...)
"nor semigroups");
fi;
od;
return SemigroupIdealByGenerators(arg[1], out);
return [arg[1], out];
fi;
ErrorNoReturn("invalid arguments");
end;

InstallGlobalFunction(SemigroupIdeal,
function(arg...)
local parsed;
parsed := CallFuncList(SEMIGROUPS.AnySemigroupIdealInputParsing, arg);
if Length(parsed) = 3 then
return SEMIGROUPS.AnySemigroupIdealByGenerators4(parsed[1],
IsMagmaIdeal, parsed[2], parsed[3]);
else
return SEMIGROUPS.AnySemigroupIdealByGenerators3(parsed[1],
IsMagmaIdeal, parsed[2]);
fi;
end);

InstallMethod(SemigroupIdealByGenerators,
"for a semigroup and list or collections",
[IsSemigroup, IsListOrCollection],
{S, gens} -> SemigroupIdealByGenerators(S, gens, SEMIGROUPS.OptionsRec(S)));
InstallGlobalFunction(LeftSemigroupIdeal,
function(arg...)
local parsed;
parsed := CallFuncList(SEMIGROUPS.AnySemigroupIdealInputParsing, arg);
if Length(parsed) = 3 then
return SEMIGROUPS.AnySemigroupIdealByGenerators4(parsed[1],
IsLeftMagmaIdeal, parsed[2], parsed[3]);
else
return SEMIGROUPS.AnySemigroupIdealByGenerators3(parsed[1],
IsLeftMagmaIdeal, parsed[2]);
fi;
end);

InstallMethod(SemigroupIdealByGenerators,
"for semigroup, list or collection, and record",
[IsSemigroup, IsListOrCollection, IsRecord],
function(S, gens, opts)
InstallGlobalFunction(RightSemigroupIdeal,
function(arg...)
local parsed;
parsed := CallFuncList(SEMIGROUPS.AnySemigroupIdealInputParsing, arg);
if Length(parsed) = 3 then
return SEMIGROUPS.AnySemigroupIdealByGenerators4(parsed[1],
IsRightMagmaIdeal, parsed[2], parsed[3]);
else
return SEMIGROUPS.AnySemigroupIdealByGenerators3(parsed[1],
IsRightMagmaIdeal, parsed[2]);
fi;
end);

SEMIGROUPS.AnySemigroupIdealByGenerators3 := {S, filter, gens} ->
SEMIGROUPS.AnySemigroupIdealByGenerators4(S,
filter, gens, SEMIGROUPS.OptionsRec(S));

SEMIGROUPS.AnySemigroupIdealByGenerators4 := function(S, filter, gens, opts)
if not ForAll(gens, x -> x in S) then
ErrorNoReturn("the 2nd argument (a mult. elt. coll.) do not all ",
"belong to the semigroup");
fi;
return SemigroupIdealByGeneratorsNC(S, gens, opts);
end);
return SEMIGROUPS.AnySemigroupIdealByGeneratorsNC(S, filter, gens, opts);
end;

InstallMethod(SemigroupIdealByGeneratorsNC,
"for a semigroup, list or collections, and record",
[IsSemigroup, IsListOrCollection, IsRecord],
function(S, gens, opts)
SEMIGROUPS.AnySemigroupIdealByGeneratorsNC := function(S, filter, gens, opts)
local filts, I;
opts := SEMIGROUPS.ProcessOptionsRec(SEMIGROUPS.DefaultOptionsRec, opts);
gens := AsList(gens);

filts := IsMagmaIdeal and IsAttributeStoringRep;
filts := filter and IsAttributeStoringRep;

if opts.acting
and (IsActingSemigroup(S) or IsGeneratorsOfActingSemigroup(gens)) then
Expand Down Expand Up @@ -313,7 +344,16 @@ function(S, gens, opts)
fi;

SetParent(I, S);
SetGeneratorsOfMagmaIdeal(I, gens);
if "IsLeftActedOnBySuperset" in NamesFilter(filter) and
"IsRightActedOnBySuperset" in NamesFilter(filter) then
SetGeneratorsOfMagmaIdeal(I, gens);
elif "IsLeftActedOnBySuperset" in NamesFilter(filter) then
SetGeneratorsOfLeftMagmaIdeal(I, gens);
elif "IsRightActedOnBySuperset" in NamesFilter(filter) then
SetGeneratorsOfRightMagmaIdeal(I, gens);
else
# PANIC
fi;

if not IsActingSemigroup(I) then
# to keep the craziness in the library happy!
Expand All @@ -326,6 +366,26 @@ function(S, gens, opts)
fi;

return I;
end;

InstallMethod(SemigroupIdealByGenerators,
"for a semigroup and list or collections",
[IsSemigroup, IsListOrCollection],
{S, gens} -> SemigroupIdealByGenerators(S, gens, SEMIGROUPS.OptionsRec(S)));

InstallMethod(SemigroupIdealByGenerators,
"for semigroup, list or collection, and record",
[IsSemigroup, IsListOrCollection, IsRecord],
function(S, gens, opts)
return SEMIGROUPS.AnySemigroupIdealByGenerators4(S, IsMagmaIdeal, gens, opts);
end);

InstallMethod(SemigroupIdealByGeneratorsNC,
"for a semigroup, list or collections, and record",
[IsSemigroup, IsListOrCollection, IsRecord],
function(S, gens, opts)
return SEMIGROUPS.AnySemigroupIdealByGeneratorsNC(S,
IsMagmaIdeal, gens, opts);
end);

InstallMethod(MinimalIdealGeneratingSet,
Expand Down
2 changes: 2 additions & 0 deletions gap/semigroups/semicons.gd
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ DeclareGlobalFunction("TrivialSemigroup");
DeclareConstructor("TrivialSemigroupCons", [IsSemigroup, IsInt]);
DeclareGlobalFunction("RectangularBand");
DeclareConstructor("RectangularBandCons", [IsSemigroup, IsPosInt, IsPosInt]);
DeclareGlobalFunction("FreeSemilattice");
DeclareConstructor("FreeSemilatticeCons", [IsSemigroup, IsPosInt]);
DeclareGlobalFunction("MonogenicSemigroup");
DeclareConstructor("MonogenicSemigroupCons", [IsSemigroup, IsPosInt, IsPosInt]);
DeclareGlobalFunction("ZeroSemigroup");
Expand Down
Loading
Loading