-
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
930b5ef
commit 524257e
Showing
8 changed files
with
653 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,129 @@ | ||
############################################################################# | ||
## | ||
#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> | ||
A mapping from <A>S</A> to corresponding elements in the 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 true 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 dual elements to elements that already | ||
lie in the category. | ||
<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 true 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 dual | ||
semigroups to semigroups that already have this representation. | ||
<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 @@ | ||
############################################################################# | ||
## | ||
#W dual.gd | ||
#Y Copyright (C) 2017 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,214 @@ | ||
############################################################################# | ||
## | ||
#W dual.gi | ||
#Y 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, 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; | ||
|
||
dual!.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 | ||
SetAntiIsomorphismTransformationSemigroup(dual, | ||
AntiIsomorphismDualSemigroup(dual)); | ||
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; | ||
S := DualSemigroupOfFamily(FamilyObj(s)); | ||
return SEMIGROUPS.DualSemigroupElementNC(S, | ||
OneMutable( | ||
SEMIGROUPS.DualSemigroupElementNC( | ||
DualSemigroup(S), s))); | ||
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); |
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
Oops, something went wrong.