Skip to content

Commit

Permalink
Fix dual subsemigroups
Browse files Browse the repository at this point in the history
  • Loading branch information
MT-resource-bot committed Mar 29, 2018
1 parent c2270ea commit 3d85769
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 25 deletions.
46 changes: 25 additions & 21 deletions doc/dual.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#############################################################################
##
#W dual.xml
#Y Copyright (C) 2011-14 Finn Smith
#Y Copyright (C) 2018 Finn Smith
##
## Licensing information can be found in the README file of this package.
##
Expand All @@ -18,18 +18,19 @@
antisomorphic semigroup with the same underlying set as <A>S</A>,
where multiplication is reversed.
Note that the dual <A>D</A> of a semigroup <A>S</A> created using
<Ref Func="DualSemigroup"> has the opposite value of
<Ref Filt="IsDualSemigroup"> to <A>S</A>.
<Ref Func="DualSemigroup"/> has the opposite value of
<Ref Filt="IsDualSemigroup"/> to <A>S</A>.
<Example>
<![CDATA[
gap> S := Semigroup([Transformation([1, 4, 3, 2, 2]), Transformation([5, 4, 4, 1, 2])]);;
gap> S := Semigroup([Transformation([1, 4, 3, 2, 2]),
> Transformation([5, 4, 4, 1, 2])]);;
gap> D := DualSemigroup(S);
<dual semigroup of <transformation semigroup of degree 5 with 2 generators>>
<dual semigroup of <transformation semigroup of degree 5 with 2
generators>>
gap> Size(S) = Size(D);
true
gap> NrDClasses(S) = NrDClasses(D);
true
]]> </Example> </Description> </ManSection>
true]]></Example> </Description> </ManSection>
<#/GAPDoc>

<#GAPDoc Label="DualSemigroupElement">
Expand All @@ -41,25 +42,29 @@ true
dual semigroup of <A>sgrp</A>.
<Example>
<![CDATA[
gap> S := Semigroup([Transformation([1, 4, 3, 2, 2]), Transformation([5, 4, 4, 1, 2])]);;
gap> S := Semigroup([Transformation([1, 4, 3, 2, 2]),
> Transformation([5, 4, 4, 1, 2])]);;
gap> D := DualSemigroup(S);
<dual semigroup of <transformation semigroup of degree 5 with 2 generators>>
gap> x := Representative(DClasses(S)[1]);; y := Representative(DClasses(S)[2]);;
gap> dx := DualSemigroupElement(D, x);; dy := DualSemigroupElement(D, y);;
<dual semigroup of <transformation semigroup of degree 5 with 2
generators>>
gap> x := Representative(DClasses(S)[1]);;
gap> y := Representative(DClasses(S)[2]);;
gap> dx := DualSemigroupElement(D, x);;
gap> dy := DualSemigroupElement(D, y);;
gap> dx * dy = DualSemigroupElement(D, y * x);
true
gap> dx * dy = DualSemigroupElement(D, x * y);
false
]]> </Example> </Description> </ManSection>
false]]></Example> </Description> </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsDualSemigroupElement">
<ManSection>
<Filt Name = "IsDualSemigroupElement" Type = "Category" Arg="elt"/>
<Returns>Returns true if <A>elt</A> has the representation of a dual semigroup element.</Returns>
<Returns>Returns true if <A>elt</A> has the representation of a dual
semigroup element.</Returns>
<Description>
Elements of a dual semigroup created using
<Ref Func = "DualSemigroupElement"> normally lie in this
<Ref Func = "DualSemigroupElement"/> normally lie in this
category. The exception is dual elements to elements that already
lie in the category.
<Example>
Expand All @@ -75,8 +80,7 @@ true
gap> x := DualSemigroupElement(S, t);
<block bijection: [ 1, 2, -1, -2 ], [ 3, -3 ], [ 4, -4 ]>
gap> IsDualSemigroupElement(x);
false
]]> </Example> </Description> </ManSection>
false]]></Example> </Description> </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsDualSemigroup">
Expand All @@ -85,7 +89,7 @@ false
<Returns>Returns true if <A>sgrp</A> is represented as
a dual semigroup.</Returns>
<Description>
Semigroups created using <Ref Func="DualSemigroup">
Semigroups created using <Ref Func="DualSemigroup"/>
normally lie in this category. The exception is dual
semigroups to semigroups that already lie in the category.
<Example>
Expand All @@ -94,7 +98,8 @@ gap> S := Semigroup([Transformation([3, 5, 1, 1, 2]),
> Transformation([1, 2, 4, 4, 3])]);
<transformation semigroup of degree 5 with 2 generators>
gap> D := DualSemigroup(S);
<dual semigroup of <transformation semigroup of degree 5 with 2 generators>>
<dual semigroup of <transformation semigroup of degree 5 with 2
generators>>
gap> IsDualSemigroup(D);
true
gap> R := DualSemigroup(D);
Expand All @@ -106,6 +111,5 @@ true
gap> T := Range(IsomorphismTransformationSemigroup(D));
<transformation semigroup of size 16, degree 17 with 2 generators>
gap> IsDualSemigroup(T);
false
]]> </Example> </Description> </ManSection>
false]]></Example> </Description> </ManSection>
<#/GAPDoc>
2 changes: 2 additions & 0 deletions gap/attributes/dual.gd
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ DeclareSynonym("IsDualSemigroup", IsSemigroup and
DeclareAttribute("TypeDualSemigroupElements", IsDualSemigroup);

DeclareAttribute("DualSemigroupOfFamily", IsFamily);
DeclareAttribute("ParentAttr", IsDualSemigroup);

DeclareGlobalFunction("DualSemigroupElement");
DeclareGlobalFunction("DualSemigroupElementNC");
DeclareGlobalFunction("UnderlyingElementOfDualSemigroupElement");

DeclareAttribute("AntiIsomorphismDualSemigroup", IsSemigroup);
35 changes: 35 additions & 0 deletions gap/attributes/dual.gi
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ InstallMethod(DualSemigroup, "for a semigroup",
function(S)
local dual, fam, filts, type;

if IsDualSemigroup(S) then
if HasGeneratorsOfSemigroup(S) then
return Semigroup(List(GeneratorsOfSemigroup(S),
x -> UnderlyingElementOfDualSemigroupElement(x)));
fi;
# FS: need to work out what to do if not
fi;

fam := NewFamily("DualSemigroupElementsFamily", IsDualSemigroupElement);
dual := Objectify(NewType(CollectionsFamily(fam),
IsWholeFamily and
Expand Down Expand Up @@ -101,6 +109,17 @@ function(S)
return MappingByFunction(S, dual, iso, inv);
end);

InstallGlobalFunction(UnderlyingElementOfDualSemigroupElement,
"for a dual semigroup element",
function(s)
if not IsDualSemigroupElement(s) then
ErrorNoReturn("Semigroups: UnderlyingElementOfDualSemigroupElement: \n",
"the argument must be an element represented as a dual ",
"semigroup element,");
fi;
return s![1];
end);

################################################################################
## Technical methods
################################################################################
Expand Down Expand Up @@ -130,6 +149,9 @@ end);
InstallMethod(Representative, "for a dual semigroup",
[IsDualSemigroup],
function(S)
if HasGeneratorsOfSemigroup(S) then
return GeneratorsOfSemigroup(S)[1];
fi;
return DualSemigroupElementNC(S, Representative(DualSemigroup(S)));
end);

Expand Down Expand Up @@ -198,3 +220,16 @@ function(x, data)
end;
return rec(func := hashfunc, data := H.data);
end);

InstallMethod(ParentAttr, "for a subsemigroup of a dual semigroup",
[IsDualSemigroup],
function(S)
return DualSemigroupOfFamily(FamilyObj(Representative(S)));
end);

InstallMethod(TypeDualSemigroupElements,
"for a subsemigroup of a dual semigroup",
[IsDualSemigroup],
function(S)
return TypeDualSemigroupElements(ParentAttr(S));
end);
1 change: 1 addition & 0 deletions gap/tools/utils.gi
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ SEMIGROUPS.DocXMLFiles := ["../PackageInfo.g",
"congrees.xml",
"congrms.xml",
"conguniv.xml",
"dual.xml",
"display.xml",
"elements.xml",
"factor.xml",
Expand Down
1 change: 0 additions & 1 deletion read.g
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ ReadPackage("semigroups", "gap/attributes/maximal.gi");
ReadPackage("semigroups", "gap/attributes/normalizer.gi");
ReadPackage("semigroups", "gap/attributes/properties.gi");


ReadPackage("semigroups", "gap/congruences/congpairs.gi");
ReadPackage("semigroups", "gap/congruences/congrms.gi");
ReadPackage("semigroups", "gap/congruences/conguniv.gi");
Expand Down
93 changes: 90 additions & 3 deletions tst/standard/dual.tst
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ gap> S := Semigroup([Transformation([2, 6, 3, 2, 4, 2]),
gap> T := DualSemigroup(S);;
gap> ForAll(DClasses(T),
> x -> AsSortedList(List(x, y -> DualSemigroupElement(S, y))) =
> AsSortedList(GreensDClassOfElement(S,
> AsSortedList(GreensDClassOfElement(S,
> DualSemigroupElement(S, Representative(x)))));
true
gap> ForAll(DClasses(T),
Expand All @@ -121,8 +121,7 @@ true
gap> S := FullTransformationMonoid(20);;
gap> T := DualSemigroup(S);;
gap> Representative(T);
<Transformation( [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 1 ] ) in the dual semigroup>
<IdentityTransformation in the dual semigroup>

#T# Size
gap> S := FullTransformationMonoid(20);;
Expand Down Expand Up @@ -179,12 +178,100 @@ x ) ... end )
gap> ForAll(S, x -> (x ^ antiso) ^ invantiso = x);
true

#T# Subsemigroups of a dual semigroup
gap> S := FullBooleanMatMonoid(4);
<monoid of 4x4 boolean matrices with 7 generators>
gap> T := DualSemigroup(S);
<dual semigroup of <monoid of 4x4 boolean matrices with 7 generators>>
gap> U := Semigroup(GeneratorsOfSemigroup(T){[3 .. 5]});
<dual semigroup of <semigroup of 4x4 boolean matrices with 3 generators>>
gap> AsList(U);
[ <Matrix(IsBooleanMat, [[1, 1, 0, 0], [1, 0, 1, 0], [0, 1, 1, 0],
[0, 0, 0, 1]]) in the dual semigroup>,
<Matrix(IsBooleanMat, [[1, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1],
[0, 0, 1, 1]]) in the dual semigroup>,
<Matrix(IsBooleanMat, [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0],
[1, 0, 0, 1]]) in the dual semigroup>,
<Matrix(IsBooleanMat, [[1, 1, 1, 0], [1, 1, 1, 0], [1, 1, 1, 0],
[0, 0, 0, 1]]) in the dual semigroup>,
<Matrix(IsBooleanMat, [[1, 1, 1, 0], [1, 1, 0, 1], [1, 1, 1, 1],
[0, 0, 1, 1]]) in the dual semigroup>,
<Matrix(IsBooleanMat, [[1, 1, 0, 0], [1, 0, 1, 0], [0, 1, 1, 0],
[1, 0, 0, 1]]) in the dual semigroup>,
<Matrix(IsBooleanMat, [[1, 1, 1, 0], [1, 1, 1, 0], [1, 0, 1, 1],
[0, 1, 1, 1]]) in the dual semigroup>,
<Matrix(IsBooleanMat, [[1, 1, 1, 0], [1, 1, 0, 1], [1, 0, 1, 1],
[0, 1, 1, 1]]) in the dual semigroup>,
<Matrix(IsBooleanMat, [[1, 1, 0, 0], [1, 0, 1, 0], [1, 1, 0, 1],
[1, 0, 1, 1]]) in the dual semigroup>,
<Matrix(IsBooleanMat, [[1, 1, 0, 0], [1, 0, 1, 0], [0, 1, 1, 0],
[1, 1, 0, 1]]) in the dual semigroup>,
<Matrix(IsBooleanMat, [[1, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1],
[1, 1, 1, 1]]) in the dual semigroup>,
<Matrix(IsBooleanMat, [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1],
[0, 0, 1, 1]]) in the dual semigroup>,
<Matrix(IsBooleanMat, [[1, 1, 1, 0], [1, 1, 1, 0], [1, 1, 1, 0],
[1, 0, 0, 1]]) in the dual semigroup>,
<Matrix(IsBooleanMat, [[1, 1, 1, 0], [1, 1, 1, 1], [1, 1, 1, 1],
[0, 1, 1, 1]]) in the dual semigroup>,
<Matrix(IsBooleanMat, [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1],
[0, 1, 1, 1]]) in the dual semigroup>,
<Matrix(IsBooleanMat, [[1, 1, 1, 0], [1, 1, 0, 1], [1, 1, 1, 1],
[1, 0, 1, 1]]) in the dual semigroup>,
<Matrix(IsBooleanMat, [[1, 1, 1, 0], [1, 1, 1, 0], [1, 1, 1, 0],
[1, 1, 0, 1]]) in the dual semigroup>,
<Matrix(IsBooleanMat, [[1, 1, 1, 0], [1, 1, 0, 1], [1, 1, 1, 1],
[1, 1, 1, 1]]) in the dual semigroup>,
<Matrix(IsBooleanMat, [[1, 1, 1, 0], [1, 1, 1, 0], [1, 1, 1, 1],
[1, 1, 1, 1]]) in the dual semigroup>,
<Matrix(IsBooleanMat, [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1],
[1, 1, 1, 1]]) in the dual semigroup>,
<Matrix(IsBooleanMat, [[1, 1, 1, 0], [1, 1, 1, 0], [1, 0, 1, 1],
[1, 1, 1, 1]]) in the dual semigroup>,
<Matrix(IsBooleanMat, [[1, 1, 1, 0], [1, 1, 1, 1], [1, 1, 1, 1],
[1, 1, 1, 1]]) in the dual semigroup>,
<Matrix(IsBooleanMat, [[1, 1, 1, 0], [1, 1, 0, 1], [1, 0, 1, 1],
[1, 1, 1, 1]]) in the dual semigroup>,
<Matrix(IsBooleanMat, [[1, 1, 1, 0], [1, 1, 1, 0], [1, 1, 1, 0],
[1, 1, 1, 1]]) in the dual semigroup>,
<Matrix(IsBooleanMat, [[1, 1, 0, 0], [1, 0, 1, 0], [1, 1, 0, 1],
[1, 1, 1, 1]]) in the dual semigroup>,
<Matrix(IsBooleanMat, [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1],
[1, 0, 1, 1]]) in the dual semigroup> ]
gap> Size(last);
26
gap> Size(DualSemigroup(U));
26
gap> V := DualSemigroup(U);
<semigroup of size 26, 4x4 boolean matrices with 3 generators>
gap> V = Semigroup(GeneratorsOfSemigroup(S){[3 .. 5]});
true

#T# UnderlyingElementOfDualSemigroupElement
gap> S := SingularPartitionMonoid(4);;
gap> D := DualSemigroup(S);;
gap> d := Representative(D);
<<block bijection: [ 1, 2, -1, -2 ], [ 3, -3 ], [ 4, -4 ]>
in the dual semigroup>
gap> UnderlyingElementOfDualSemigroupElement(d);
<block bijection: [ 1, 2, -1, -2 ], [ 3, -3 ], [ 4, -4 ]>
gap> Representative(S);
<block bijection: [ 1, 2, -1, -2 ], [ 3, -3 ], [ 4, -4 ]>
gap> UnderlyingElementOfDualSemigroupElement(S);
Error, Semigroups: UnderlyingElementOfDualSemigroupElement:
the argument must be an element represented as a dual semigroup element,
gap> T := Semigroup(GeneratorsOfSemigroup(D){[1000 .. 2000]});
<dual semigroup of <bipartition semigroup of degree 4 with 1001 generators>>
gap> UnderlyingElementOfDualSemigroupElement(Representative(T));
<bipartition: [ 1, 2, -1 ], [ 3, -2 ], [ 4 ], [ -3, -4 ]>

#T# UnbindVariables
gap> Unbind(antiso);
gap> Unbind(inv);
gap> Unbind(invantiso);
gap> Unbind(i);
gap> Unbind(U);
gap> Unbind(V);
gap> Unbind(S);
gap> Unbind(T);

Expand Down

0 comments on commit 3d85769

Please sign in to comment.