Skip to content

Commit

Permalink
Merge pull request #348 from james-d-mitchell/cayley
Browse files Browse the repository at this point in the history
Cayley digraphs
  • Loading branch information
wilfwilson committed Aug 1, 2017
2 parents 3cf9f97 + 0a0adc9 commit ede1124
Show file tree
Hide file tree
Showing 22 changed files with 398 additions and 76 deletions.
4 changes: 2 additions & 2 deletions PackageInfo.g
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
## <#GAPDoc Label="PKGVERSIONDATA">
## <!ENTITY VERSION "3.0.4">
## <!ENTITY GAPVERS "4.9.0">
## <!ENTITY DIGRAPHSVERS "0.7.1">
## <!ENTITY DIGRAPHSVERS "0.10.0">
## <!ENTITY ORBVERS "4.7.5">
## <!ENTITY IOVERS "4.4.4">
## <!ENTITY GENSSVERS "1.5">
Expand Down Expand Up @@ -236,7 +236,7 @@ Dependencies := rec(
GAP := ">=4.9.0",
NeededOtherPackages := [["orb", ">=4.7.5"],
["io", ">=4.4.4"],
["digraphs", ">=0.7.1"],
["digraphs", ">=0.10.0"],
["genss", ">=1.5"]],
SuggestedOtherPackages := [["gapdoc", ">=1.5.1"]],

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ The following is a summary of the steps that should lead to a successful ins
* get the [Orb](http://gap-system.github.io/orb/) package version 4.7.5 or higher.
Both [Orb](http://gap-system.github.io/orb/) and [Semigroups](https://gap-packages.github.io/Semigroups) perform better if [Orb](http://gap-system.github.io/orb/) is compiled, so compile [Orb](http://gap-system.github.io/orb/)!

* ensure that the [Digraphs](http://gap-system.github.io/digraphs/) package version 0.7.1 or higher is available. [Digraphs](http://gap-system.github.io/digraphs/) must be compiled before [Semigroups](https://gap-packages.github.io/Semigroups) can be
* ensure that the [Digraphs](http://gap-system.github.io/digraphs/) package version 0.10.0 or higher is available. [Digraphs](http://gap-system.github.io/digraphs/) must be compiled before [Semigroups](https://gap-packages.github.io/Semigroups) can be
loaded.

* get the [genss](http://gap-system.github.io/genss/) package version 1.5 or higher
Expand Down
108 changes: 106 additions & 2 deletions doc/display.xml
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,23 @@
</Item>
<Mark>pbrs</Mark>
<Item>
If <A>obj</A> is a PBR, then <C>TikzString</C> returns a graphical
representation <A>obj</A>; see Section <Ref Sect = "section-blocks"/>.
If <A>obj</A> is a <Ref Oper="PBR"/>, then <C>TikzString</C> returns a
graphical representation <A>obj</A>; see Chapter <Ref Sect =
"Partitioned binary relations (PBRs)"/>.
</Item>
<Mark>Cayley graphs</Mark>
<Item>
If <A>obj</A> is a <Ref Oper="Digraph" BookName="digraphs"/> in the
category <Ref Filt="IsCayleyDigraph" BookName="digraphs"/>, then
<C>TikzString</C> returns a picture of <A>obj</A>. No attempt is made
whatsoever to produce a sensible picture of the digraph <A>obj</A>,
in fact, the vertices are all given the same coordinates. Human
intervention is required to produce a meaningful picture from the
value returned by this method. It is intended to make the task of
drawing such a Cayley graph more straightforward by providing
everything except the final layout of the graph. Please use <Ref
Oper="DotString"/> if you want an automatically laid out diagram of
the digraph <A>obj</A>.
</Item>
</List>

Expand Down Expand Up @@ -288,6 +303,29 @@ gap> FileString("t3.dot", DotString(S));
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="DotStringDigraph">
<ManSection>
<Oper Name="DotString" Arg="digraph" Label="for a Cayley digraph"/>
<Returns>A string.</Returns>
<Description>
If <A>digraph</A> is a <Ref Oper="Digraph" BookName="digraphs"/> in the
category <Ref Filt="IsCayleyDigraph" BookName="digraphs"/>, then
<C>DotString</C> returns a graphical representation of <A>digraph</A>.
The output is in <C>dot</C> format (also known
as <C>GraphViz</C>) format. For details about this file format, and
information about how to display or edit this format see
<URL>http://www.graphviz.org</URL>.
<P/>

The string returned by <C>DotString</C> can be written to a file using
the command <Ref Func="FileString" BookName="GAPDoc"/>.<P/>

See also <Ref Oper="DotLeftCayleyDigraph"/> and <Ref
Oper="TikzLeftCayleyDigraph"/>.
</Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="DotSemilatticeOfIdempotents">
<ManSection>
<Attr Name="DotSemilatticeOfIdempotents" Arg="S"/>
Expand Down Expand Up @@ -341,3 +379,69 @@ d{pmatrix}"]]></Example>
</Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="TikzLeftCayleyDigraph">
<ManSection>
<Oper Name="TikzLeftCayleyDigraph" Arg="S"/>
<Oper Name="TikzRightCayleyDigraph" Arg="S"/>
<Returns>A string.</Returns>
<Description>
If <A>S</A> is a semigroup in the representation
<Ref Filt="IsEnumerableSemigroupRep"/>, then <C>TikzLeftCayleyDigraph</C>
is simply short for <C>TikzString(LeftCayleyDigraph(<A>S</A>))</C>.<P/>

<C>TikzRightCayleyDigraph</C> can be used to produce a tikz string for
the right Cayley graph of <A>S</A>.<P/>

See <Ref Oper="TikzString"/> for more details, and see also
<Ref Oper="DotLeftCayleyDigraph"/>.

<Log><![CDATA[
gap> TikzLeftCayleyDigraph(Semigroup(IdentityTransformation));
"\\begin{tikzpicture}[scale=1, auto, \n vertex/.style={c\
ircle, draw, thick, fill=white, minimum size=0.65cm},\n \
edge/.style={arrows={-angle 90}, thick},\n loop/.style={\
min distance=5mm,looseness=5,arrows={-angle 90},thick}]\n\
\n % Vertices . . .\n \\node [vertex] (a) at (0, 0) {};\
\n \\node at (0, 0) {$a$};\n\n % Edges . . .\n \\path[\
->] (a) edge [loop]\n node {$a$} (a);\n\\end{ti\
kzpicture}"
gap> TikzRightCayleyDigraph(Semigroup(IdentityTransformation));
"\\begin{tikzpicture}[scale=1, auto, \n vertex/.style={c\
ircle, draw, thick, fill=white, minimum size=0.65cm},\n \
edge/.style={arrows={-angle 90}, thick},\n loop/.style={\
min distance=5mm,looseness=5,arrows={-angle 90},thick}]\n\
\n % Vertices . . .\n \\node [vertex] (a) at (0, 0) {};\
\n \\node at (0, 0) {$a$};\n\n % Edges . . .\n \\path[\
->] (a) edge [loop]\n node {$a$} (a);\n\\end{ti\
kzpicture}"]]></Log>
</Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="DotLeftCayleyDigraph">
<ManSection>
<Oper Name="DotLeftCayleyDigraph" Arg="S"/>
<Oper Name="DotRightCayleyDigraph" Arg="S"/>
<Returns>A string.</Returns>
<Description>
If <A>S</A> is a semigroup in the representation <Ref
Filt="IsEnumerableSemigroupRep"/>, then <C>DotLeftCayleyDigraph</C> is
simply short for <C>DotString(LeftCayleyDigraph(<A>S</A>))</C>.<P/>

<C>DotRightCayleyDigraph</C> can be used to produce a dot string for
the right Cayley graph of <A>S</A>.<P/>

See <Ref Oper="DotString"/> for more details, and see also
<Ref Oper="TikzLeftCayleyDigraph"/>.

<Log><![CDATA[
gap> DotLeftCayleyDigraph(Semigroup(IdentityTransformation));
"//dot\ndigraph hgn{\nnode [shape=circle]\n1 [label=\"a\"]\n1 -> 1\n}\
\n"
gap> DotRightCayleyDigraph(Semigroup(IdentityTransformation));
"//dot\ndigraph hgn{\nnode [shape=circle]\n1 [label=\"a\"]\n1 -> 1\n}\
\n"]]></Log>
</Description>
</ManSection>
<#/GAPDoc>
37 changes: 22 additions & 15 deletions doc/fropin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ false
returns a list of the elements of <A>S</A> in the order they are
enumerated by the Froidure-Pin Algorithm. This is the same as the order
used to index the elements of <A>S</A> in <Ref
Attr="RightCayleyGraphSemigroup"/> and <Ref
Attr="LeftCayleyGraphSemigroup"/>. <P/>
Attr="RightCayleyDigraph"/> and <Ref
Attr="LeftCayleyDigraph"/>. <P/>

<C>EnumeratorCanonical</C> and <C>IteratorCanonical</C> return an
enumerator and an iterator where the elements are
Expand All @@ -67,8 +67,8 @@ false
<C>AsList</C> may not equal the value returned by <C>AsListCanonical</C>.
<C>AsListCanonical</C> exists so that there is a method for obtaining the
elements of <A>S</A> in the particular order used by
<Ref Attr="RightCayleyGraphSemigroup"/> and
<Ref Attr="LeftCayleyGraphSemigroup"/>.<P/>
<Ref Attr="RightCayleyDigraph"/> and
<Ref Attr="LeftCayleyDigraph"/>.<P/>

See also <Ref Oper="PositionCanonical"/>.

Expand Down Expand Up @@ -183,27 +183,34 @@ true]]></Example>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="RightCayleyGraphSemigroup">
<#GAPDoc Label="RightCayleyDigraph">
<ManSection>
<Attr Name="RightCayleyGraphSemigroup" Arg="S"/>
<Attr Name="LeftCayleyGraphSemigroup" Arg="S"/>
<Attr Name="RightCayleyDigraph" Arg="S"/>
<Attr Name="LeftCayleyDigraph" Arg="S"/>
<Returns>A list of lists of positive integers.</Returns>
<Description>
When the argument <A>S</A> is a semigroup in the representation
<Ref Filt="IsEnumerableSemigroupRep"/>,
<C>RightCayleyGraphSemigroup</C> returns the right
Cayley graphs of <A>S</A>, as a list <C>graph</C> where
<C>graph[i][j]</C> is equal to
<C>RightCayleyDigraph</C> returns the right
Cayley graphs of <A>S</A>, as a <Ref Oper="Digraph" BookName="digraphs"/>
<C>digraph</C> where vertex <C>OutNeighbours(digraph)[i][j]</C> is
<C>PositionCanonical(<A>S</A>, AsListCanonical(<A>S</A>)[i] *
GeneratorsOfSemigroup(<A>S</A>)[j])</C>.
The list returned by <C>LeftCayleyGraphSemigroup</C> is defined analogously.
The digraph returned by <C>LeftCayleyDigraph</C> is defined analogously.<P/>

The digraph returned by this attribute belongs to the category
<Ref Filt="IsCayleyDigraph" BookName="digraphs"/>, the semigroup <A>S</A>
and the generators used to create the digraph can be recovered from the
digraph using <Ref Attr="SemigroupOfCayleyDigraph" BookName="digraphs"/>
and <Ref Attr="GeneratorsOfCayleyDigraph" BookName="digraphs"/>.

<Example><![CDATA[
gap> S := FullTransformationMonoid(2);
<full transformation monoid of degree 2>
gap> RightCayleyGraphSemigroup(S);
[ [ 1, 2, 3 ], [ 2, 1, 3 ], [ 3, 4, 3 ], [ 4, 3, 3 ] ]
gap> LeftCayleyGraphSemigroup(S);
[ [ 1, 2, 3 ], [ 2, 1, 4 ], [ 3, 3, 3 ], [ 4, 4, 4 ] ]]]></Example>
gap> RightCayleyDigraph(S);
<multidigraph with 4 vertices, 12 edges>
gap> LeftCayleyDigraph(S);
<multidigraph with 4 vertices, 12 edges>]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
2 changes: 1 addition & 1 deletion doc/z-chap13.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<Heading>
Cayley graphs
</Heading>
<#Include Label = "RightCayleyGraphSemigroup">
<#Include Label = "RightCayleyDigraph">
</Section>

<!--**********************************************************************-->
Expand Down
3 changes: 3 additions & 0 deletions doc/z-chap18.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@
BookName = "GAPDoc"/> or viewed using <Ref Func = "Splash"/>.

<#Include Label = "DotString"/>
<#Include Label = "DotStringDigraph"/>
<#Include Label = "DotSemilatticeOfIdempotents"/>
<#Include Label = "DotLeftCayleyDigraph">

</Section>

Expand Down Expand Up @@ -81,6 +83,7 @@
BookName = "GAPDoc"/> or viewed using <Ref Func = "Splash"/>.

<#Include Label = "TikzString">
<#Include Label = "TikzLeftCayleyDigraph">

</Section>

Expand Down
2 changes: 1 addition & 1 deletion gap/congruences/conginv.gi
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ SEMIGROUPS.KernelTraceClosure := function(S, kernel, traceBlocks, pairstoapply)
hashlen := SEMIGROUPS.OptionsRec(S).hashlen.L;
ht := HTCreate([1, 1], rec(forflatplainlists := true,
treehashsize := hashlen));
right := RightCayleyGraphSemigroup(idsmgp);
right := OutNeighbours(RightCayleyDigraph(idsmgp));
genstoapply := [1 .. Length(right[1])];

#
Expand Down
2 changes: 0 additions & 2 deletions gap/greens/gree.gi
Original file line number Diff line number Diff line change
Expand Up @@ -391,8 +391,6 @@ function(S)

l := LeftCayleyGraphSemigroup(S);
r := RightCayleyGraphSemigroup(S);
# WW: in the future, when l and r are digraphs, gr can be created
# by using DigraphEdgeUnion(l, r)
gr := Digraph(List([1 .. Length(l)], i -> Concatenation(l[i], r[i])));
gr := QuotientDigraph(gr, DigraphStronglyConnectedComponents(gr).comps);
return List(OutNeighbours(gr), Set);
Expand Down
27 changes: 14 additions & 13 deletions gap/greens/gren.gi
Original file line number Diff line number Diff line change
Expand Up @@ -225,19 +225,19 @@ end);
InstallMethod(GreensRRelation, "for an enumerable semigroup",
[IsEnumerableSemigroupRep],
function(S)
local fam, rel;
local fam, data, rel;
if IsActingSemigroup(S) then
TryNextMethod();
fi;
fam := GeneralMappingsFamily(ElementsFamily(FamilyObj(S)),
ElementsFamily(FamilyObj(S)));

data := DigraphStronglyConnectedComponents(RightCayleyDigraph(S));
rel := Objectify(NewType(fam,
IsEquivalenceRelation
and IsEquivalenceRelationDefaultRep
and IsGreensRRelation
and IsEnumerableSemigroupGreensRelationRep),
rec(data := GABOW_SCC(RightCayleyGraphSemigroup(S))));
rec(data := data));
SetSource(rel, S);
SetRange(rel, S);
SetIsLeftSemigroupCongruence(rel, true);
Expand All @@ -250,19 +250,19 @@ end);
InstallMethod(GreensLRelation, "for an enumerable semigroup",
[IsEnumerableSemigroupRep],
function(S)
local fam, rel;
local fam, data, rel;
if IsActingSemigroup(S) then
TryNextMethod();
fi;
fam := GeneralMappingsFamily(ElementsFamily(FamilyObj(S)),
ElementsFamily(FamilyObj(S)));

data := DigraphStronglyConnectedComponents(LeftCayleyDigraph(S));
rel := Objectify(NewType(fam,
IsEquivalenceRelation
and IsEquivalenceRelationDefaultRep
and IsGreensLRelation
and IsEnumerableSemigroupGreensRelationRep),
rec(data := GABOW_SCC(LeftCayleyGraphSemigroup(S))));
rec(data := data));
SetSource(rel, S);
SetRange(rel, S);
SetIsRightSemigroupCongruence(rel, true);
Expand Down Expand Up @@ -514,19 +514,20 @@ InstallMethod(HClassReps, "for a Green's class of an enumerable semigroup",
[IsGreensClass and IsEnumerableSemigroupGreensClassRep],
C -> SEMIGROUPS.XClassRepsOfClass(C, GreensHRelation));

## Partial order of D-classes
# There is duplicate code in here and in maximal D-classes
# There is duplicate code in here and in maximal D-classes.
#
# This cannot be replaced with the method for IsSemigroup and IsFinite since
# the value of GreensDRelation(S)!.data.comps is not the same as the output of
# DigraphStronglyConnectedComponents.

InstallMethod(PartialOrderOfDClasses, "for a finite enumerable semigroup",
[IsEnumerableSemigroupRep and IsFinite],
function(S)
local l, r, gr;

l := LeftCayleyGraphSemigroup(S);
r := RightCayleyGraphSemigroup(S);
gr := Digraph(List([1 .. Length(l)], i -> Concatenation(l[i], r[i])));
l := LeftCayleyDigraph(S);
r := RightCayleyDigraph(S);
gr := DigraphEdgeUnion(l, r);
gr := QuotientDigraph(gr, GreensDRelation(S)!.data.comps);

return List(OutNeighbours(gr), Set);
end);

Expand Down
4 changes: 2 additions & 2 deletions gap/ideals/idealenum.gi
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ SEMIGROUPS.EnumerateIdeal := function(enum, limit, lookfunc)
indices := enum!.indices;

S := SupersemigroupOfIdeal(UnderlyingCollection(enum));
left := LeftCayleyGraphSemigroup(S);
right := RightCayleyGraphSemigroup(S);
left := OutNeighbours(LeftCayleyDigraph(S));
right := OutNeighbours(RightCayleyDigraph(S));
# FIXME Once the left and right Cayley graphs have been calculated, the
# entire data structure of S is known and from this it is relatively easy to
# find the entire data structure for I, so there is no point to what follows,
Expand Down
3 changes: 3 additions & 0 deletions gap/main/fropin.gd
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,6 @@ DeclareOperation("Enumerate", [IsEnumerableSemigroupRep]);
DeclareOperation("IsFullyEnumerated", [IsEnumerableSemigroupRep]);

DeclareProperty("IsSemigroupEnumerator", IsEnumeratorByFunctions);

DeclareAttribute("LeftCayleyDigraph", IsEnumerableSemigroupRep);
DeclareAttribute("RightCayleyDigraph", IsEnumerableSemigroupRep);
Loading

0 comments on commit ede1124

Please sign in to comment.