-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
cf9ec37
commit 9105017
Showing
8 changed files
with
708 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
############################################################################# | ||
## | ||
#W dual.xml | ||
#Y Copyright (C) 2018 Finn Smith | ||
## | ||
## Licensing information can be found in the README file of this package. | ||
## | ||
############################################################################# | ||
## | ||
|
||
<#GAPDoc Label="DualSemigroup"> | ||
<ManSection> | ||
<Attr Name = "DualSemigroup" Arg = "S"/> | ||
<Returns>The dual semigroup of the given semigroup.</Returns> | ||
<Description> | ||
The dual semigroup of a semigroup <A>S</A> is the | ||
anti-isomorphic semigroup with the same underlying set as <A>S</A>, | ||
where multiplication is reversed. This attribute returns a semigroup | ||
isomorphic to the dual semigroup of <A>S</A>. | ||
<Example> | ||
<![CDATA[ | ||
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> Size(S) = Size(D); | ||
true | ||
gap> NrDClasses(S) = NrDClasses(D); | ||
true]]></Example> </Description> </ManSection> | ||
<#/GAPDoc> | ||
|
||
<#GAPDoc Label="AntiIsomorphismDualSemigroup"> | ||
<ManSection> | ||
<Attr Name= "AntiIsomorphismDualSemigroup" Arg = "S"/> | ||
<Returns> | ||
An anti-isomorphism from <A>S</A> to the corresponding dual semigroup. | ||
</Returns> | ||
<Description> | ||
The dual semigroup of <A>S</A> mathematically has the same underlying | ||
set as <A>S</A>, but is represented with a different set of elements in | ||
&Semigroups;. This function returns a mapping which is an anti-isomorphism from | ||
<A>S</A> to its dual. | ||
<Example> | ||
<![CDATA[ | ||
gap> S := PartitionMonoid(3); | ||
<regular bipartition *-monoid of size 203, degree 3 with 4 generators> | ||
gap> map := AntiIsomorphismDualSemigroup(S); | ||
MappingByFunction( <regular bipartition *-monoid of size 203, | ||
degree 3 with 4 generators>, <dual semigroup of | ||
<regular bipartition *-monoid of size 203, degree 3 with 4 generators> | ||
>, function( x ) ... end, function( x ) ... end ) | ||
gap> inv := InverseGeneralMapping(map);; | ||
gap> x := Bipartition([[1, -2], [2, -3], [3, -1]]); | ||
<block bijection: [ 1, -2 ], [ 2, -3 ], [ 3, -1 ]> | ||
gap> y := Bipartition([[1], [2, -2], [3, -3], [-1]]); | ||
<bipartition: [ 1 ], [ 2, -2 ], [ 3, -3 ], [ -1 ]> | ||
gap> (x ^ map) * (y ^ map) = (y * x) ^ map; | ||
true | ||
gap> x ^ map; | ||
<<block bijection: [ 1, -2 ], [ 2, -3 ], [ 3, -1 ]> | ||
in the dual semigroup>]]></Example> </Description> </ManSection> | ||
<#/GAPDoc> | ||
|
||
<#GAPDoc Label="IsDualSemigroupElement"> | ||
<ManSection> | ||
<Filt Name = "IsDualSemigroupElement" Type = "Category" Arg="elt"/> | ||
<Returns>Returns <K>true</K> if <A>elt</A> has the representation of a dual | ||
semigroup element.</Returns> | ||
<Description> | ||
Elements of a dual semigroup obtained using | ||
<Ref Attr = "AntiIsomorphismDualSemigroup"/> normally lie in this | ||
category. The exception is elements obtained by applying | ||
the map <Ref Attr = "AntiIsomorphismDualSemigroup"/> to elements already | ||
in this category. That is, the elements of a semigroup lie in the | ||
category <Ref Filt="IsDualSemigroupElement"/> if and only if the | ||
elements of the corresponding dual semigroup do not. | ||
<Example> | ||
<![CDATA[ | ||
gap> S := SingularPartitionMonoid(4);; | ||
gap> D := DualSemigroup(S);; | ||
gap> s := GeneratorsOfSemigroup(S)[1];; | ||
gap> map := AntiIsomorphismDualSemigroup(S);; | ||
gap> t := s ^ map; | ||
<<block bijection: [ 1, 2, -1, -2 ], [ 3, -3 ], [ 4, -4 ]> | ||
in the dual semigroup> | ||
gap> IsDualSemigroupElement(t); | ||
true | ||
gap> inv := InverseGeneralMapping(map);; | ||
gap> x := t ^ inv; | ||
<block bijection: [ 1, 2, -1, -2 ], [ 3, -3 ], [ 4, -4 ]> | ||
gap> IsDualSemigroupElement(x); | ||
false]]></Example> </Description> </ManSection> | ||
<#/GAPDoc> | ||
|
||
<#GAPDoc Label="IsDualSemigroupRep"> | ||
<ManSection> | ||
<Filt Name = "IsDualSemigroupRep" Type = "Category" Arg="sgrp"/> | ||
<Returns>Returns <K>true</K> if <A>sgrp</A> is represented as | ||
a dual semigroup.</Returns> | ||
<Description> | ||
Semigroups created using <Ref Func="DualSemigroup"/> | ||
normally have this representation. The exception is semigroups | ||
which are the dual of semigroups already lying in this category. | ||
That is, a semigroup has the representation | ||
<Ref Filt="IsDualSemigroupRep"/> if and only if the corresponding | ||
dual semigroup does not. | ||
<Example> | ||
<![CDATA[ | ||
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>> | ||
gap> IsDualSemigroupRep(D); | ||
true | ||
gap> R := DualSemigroup(D); | ||
<transformation semigroup of degree 5 with 2 generators> | ||
gap> IsDualSemigroupRep(R); | ||
false | ||
gap> R = S; | ||
true | ||
gap> T := Range(IsomorphismTransformationSemigroup(D)); | ||
<transformation semigroup of size 16, degree 17 with 2 generators> | ||
gap> IsDualSemigroupRep(T); | ||
false | ||
gap> x := Representative(D); | ||
<Transformation( [ 3, 5, 1, 1, 2 ] ) in the dual semigroup> | ||
gap> V := Semigroup(x); | ||
<dual semigroup of <commutative transformation semigroup of degree 5 | ||
with 1 generator>> | ||
gap> IsDualSemigroupRep(V); | ||
true]]></Example> </Description> </ManSection> | ||
<#/GAPDoc> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
############################################################################# | ||
## | ||
## dual.gd | ||
## Copyright (C) 2018 James D. Mitchell | ||
## Finn Smith | ||
## | ||
## Licensing information can be found in the README file of this package. | ||
## | ||
############################################################################# | ||
## | ||
|
||
DeclareCategory("IsDualSemigroupElement", IsAssociativeElement); | ||
DeclareCategoryCollections("IsDualSemigroupElement"); | ||
DeclareAttribute("DualSemigroup", IsSemigroup); | ||
|
||
# Every semigroup is mathematically a dual semigroup | ||
# What we care about is whether it is represented as one | ||
DeclareRepresentation("IsDualSemigroupRep", | ||
IsEnumerableSemigroupRep and | ||
IsDualSemigroupElementCollection, | ||
[]); | ||
|
||
DeclareAttribute("DualSemigroupOfFamily", IsFamily); | ||
DeclareAttribute("AntiIsomorphismDualSemigroup", IsSemigroup); | ||
DeclareGlobalFunction("UnderlyingElementOfDualSemigroupElement"); | ||
|
||
InstallTrueMethod(IsDualSemigroupRep, | ||
IsSemigroup and IsDualSemigroupElementCollection); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,210 @@ | ||
############################################################################# | ||
## | ||
## dual.gi | ||
## Copyright (C) 2018 James D. Mitchell | ||
## Finn Smith | ||
## | ||
## Licensing information can be found in the README file of this package. | ||
## | ||
############################################################################# | ||
## | ||
## This file contains an implementation of dual semigroups. We only provide | ||
## enough functionality to allow dual semigroups to work as enumerable | ||
## semigroups. This is to avoid having to install versions of every function | ||
## in Semigroups specially for dual semigroup representations. In some cases | ||
## special functions would be faster. | ||
|
||
InstallMethod(DualSemigroup, "for a semigroup", | ||
[IsSemigroup], | ||
function(S) | ||
local dual, fam, filts, map, type; | ||
|
||
if IsDualSemigroupRep(S) then | ||
if HasGeneratorsOfSemigroup(S) then | ||
return Semigroup(List(GeneratorsOfSemigroup(S), | ||
x -> UnderlyingElementOfDualSemigroupElement(x))); | ||
fi; | ||
ErrorNoReturn("Semigroups: DualSemigroup: \n", | ||
"this dual semigroup cannot be constructed ", | ||
"without knowing generators,"); | ||
fi; | ||
|
||
fam := NewFamily("DualSemigroupElementsFamily", IsDualSemigroupElement); | ||
dual := Objectify(NewType(CollectionsFamily(fam), | ||
IsWholeFamily and | ||
IsDualSemigroupRep and | ||
IsAttributeStoringRep), | ||
rec()); | ||
|
||
filts := IsDualSemigroupElement; | ||
if IsMultiplicativeElementWithOne(Representative(S)) then | ||
filts := filts and IsMultiplicativeElementWithOne; | ||
fi; | ||
|
||
type := NewType(fam, filts); | ||
fam!.type := type; | ||
|
||
SetDualSemigroupOfFamily(fam, dual); | ||
|
||
SetElementsFamily(FamilyObj(dual), fam); | ||
SetDualSemigroup(dual, S); | ||
|
||
if HasIsFinite(S) then | ||
SetIsFinite(dual, IsFinite(S)); | ||
fi; | ||
|
||
if IsTransformationSemigroup(S) then | ||
map := AntiIsomorphismDualSemigroup(dual); | ||
SetAntiIsomorphismTransformationSemigroup(dual, map); | ||
fi; | ||
|
||
if HasGeneratorsOfSemigroup(S) then | ||
SetGeneratorsOfSemigroup(dual, | ||
List(GeneratorsOfSemigroup(S), | ||
x -> SEMIGROUPS.DualSemigroupElementNC(dual, | ||
x))); | ||
fi; | ||
|
||
if HasGeneratorsOfMonoid(S) then | ||
SetGeneratorsOfMonoid(dual, | ||
List(GeneratorsOfMonoid(S), | ||
x -> SEMIGROUPS.DualSemigroupElementNC(dual, | ||
x))); | ||
fi; | ||
return dual; | ||
end); | ||
|
||
SEMIGROUPS.DualSemigroupElementNC := function(S, s) | ||
if not IsDualSemigroupElement(s) then | ||
return Objectify(ElementsFamily(FamilyObj(S))!.type, [s]); | ||
fi; | ||
return s![1]; | ||
end; | ||
|
||
InstallMethod(AntiIsomorphismDualSemigroup, "for a semigroup", | ||
[IsSemigroup], | ||
function(S) | ||
local dual, inv, iso; | ||
|
||
dual := DualSemigroup(S); | ||
iso := function(x) | ||
return SEMIGROUPS.DualSemigroupElementNC(dual, x); | ||
end; | ||
|
||
inv := function(x) | ||
return SEMIGROUPS.DualSemigroupElementNC(S, x); | ||
end; | ||
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 | ||
################################################################################ | ||
|
||
InstallMethod(OneMutable, "for a dual semigroup element", | ||
[IsDualSemigroupElement and IsMultiplicativeElementWithOne], | ||
function(s) | ||
local S, x; | ||
S := DualSemigroupOfFamily(FamilyObj(s)); | ||
x := SEMIGROUPS.DualSemigroupElementNC(DualSemigroup(S), s); | ||
return SEMIGROUPS.DualSemigroupElementNC(S, OneMutable(x)); | ||
end); | ||
|
||
InstallMethod(MultiplicativeNeutralElement, "for a dual semigroup", | ||
[IsDualSemigroupRep], | ||
10, # add rank to beat enumeration methods | ||
function(S) | ||
local m; | ||
m := MultiplicativeNeutralElement(DualSemigroup(S)); | ||
if m <> fail then | ||
return SEMIGROUPS.DualSemigroupElementNC(S, m); | ||
fi; | ||
return fail; | ||
end); | ||
|
||
InstallMethod(Representative, "for a dual semigroup", | ||
[IsDualSemigroupRep], | ||
function(S) | ||
if HasGeneratorsOfSemigroup(S) then | ||
return GeneratorsOfSemigroup(S)[1]; | ||
fi; | ||
return SEMIGROUPS.DualSemigroupElementNC(S, Representative(DualSemigroup(S))); | ||
end); | ||
|
||
InstallMethod(Size, "for a dual semigroup", | ||
[IsDualSemigroupRep], | ||
10, # add rank to beat enumeration methods | ||
function(S) | ||
return Size(DualSemigroup(S)); | ||
end); | ||
|
||
InstallMethod(AsList, "for a dual semigroup", | ||
[IsDualSemigroupRep], | ||
10, # add rank to beat enumeration methods | ||
function(S) | ||
return List(DualSemigroup(S), s -> SEMIGROUPS.DualSemigroupElementNC(S, s)); | ||
end); | ||
|
||
InstallMethod(\*, "for dual semigroup elements", | ||
IsIdenticalObj, | ||
[IsDualSemigroupElement, IsDualSemigroupElement], | ||
function(x, y) | ||
return Objectify(FamilyObj(x)!.type, [y![1] * x![1]]); | ||
end); | ||
|
||
InstallMethod(\=, "for dual semigroup elements", | ||
IsIdenticalObj, | ||
[IsDualSemigroupElement, IsDualSemigroupElement], | ||
function(x, y) | ||
return x![1] = y![1]; | ||
end); | ||
|
||
InstallMethod(\<, "for dual semigroup elements", | ||
IsIdenticalObj, | ||
[IsDualSemigroupElement, IsDualSemigroupElement], | ||
function(x, y) | ||
return x![1] < y![1]; | ||
end); | ||
|
||
InstallMethod(ViewObj, "for dual semigroup elements", | ||
[IsDualSemigroupElement], PrintObj); | ||
|
||
InstallMethod(PrintObj, "for dual semigroup elements", | ||
[IsDualSemigroupElement], | ||
function(x) | ||
Print("<", ViewString(x![1]), " in the dual semigroup>"); | ||
end); | ||
|
||
InstallMethod(ViewObj, "for a dual semigroup", | ||
[IsDualSemigroupRep], PrintObj); | ||
|
||
InstallMethod(PrintObj, "for a dual semigroup", | ||
[IsDualSemigroupRep], | ||
function(S) | ||
Print("<dual semigroup of ", | ||
ViewString(DualSemigroup(S)), | ||
">"); | ||
end); | ||
|
||
InstallMethod(ChooseHashFunction, "for a dual semigroup element and int", | ||
[IsDualSemigroupElement, IsInt], | ||
function(x, data) | ||
local H, hashfunc; | ||
|
||
H := ChooseHashFunction(x![1], data); | ||
hashfunc := function(a, b) | ||
return H.func(a![1], b); | ||
end; | ||
return rec(func := hashfunc, data := H.data); | ||
end); |
Oops, something went wrong.