diff --git a/PackageInfo.g b/PackageInfo.g
index f17c1777a..bdbc29628 100644
--- a/PackageInfo.g
+++ b/PackageInfo.g
@@ -11,7 +11,7 @@
## <#GAPDoc Label="PKGVERSIONDATA">
##
##
-##
+##
##
##
##
@@ -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"]],
diff --git a/README.md b/README.md
index bc59bc905..7e5af98ac 100644
--- a/README.md
+++ b/README.md
@@ -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
diff --git a/doc/display.xml b/doc/display.xml
index eb0e40e07..4138f54b9 100644
--- a/doc/display.xml
+++ b/doc/display.xml
@@ -127,8 +127,23 @@
pbrs
-
- If obj is a PBR, then TikzString returns a graphical
- representation obj; see Section
.
+ If obj is a , then TikzString returns a
+ graphical representation obj; see Chapter .
+
+ Cayley graphs
+ -
+ If obj is a
in the
+ category , then
+ TikzString returns a picture of obj. No attempt is made
+ whatsoever to produce a sensible picture of the digraph obj,
+ 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 if you want an automatically laid out diagram of
+ the digraph obj.
@@ -288,6 +303,29 @@ gap> FileString("t3.dot", DotString(S));
<#/GAPDoc>
+<#GAPDoc Label="DotStringDigraph">
+
+
+ A string.
+
+ If digraph is a in the
+ category , then
+ DotString returns a graphical representation of digraph.
+ The output is in dot format (also known
+ as GraphViz) format. For details about this file format, and
+ information about how to display or edit this format see
+ http://www.graphviz.org.
+
+
+ The string returned by DotString can be written to a file using
+ the command .
+
+ See also and .
+
+
+<#/GAPDoc>
+
<#GAPDoc Label="DotSemilatticeOfIdempotents">
@@ -341,3 +379,69 @@ d{pmatrix}"]]>
<#/GAPDoc>
+
+<#GAPDoc Label="TikzLeftCayleyDigraph">
+
+
+
+ A string.
+
+ If S is a semigroup in the representation
+ , then TikzLeftCayleyDigraph
+ is simply short for TikzString(LeftCayleyDigraph(S)).
+
+ TikzRightCayleyDigraph can be used to produce a tikz string for
+ the right Cayley graph of S.
+
+ See for more details, and see also
+ .
+
+ 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}"]]>
+
+
+<#/GAPDoc>
+
+<#GAPDoc Label="DotLeftCayleyDigraph">
+
+
+
+ A string.
+
+ If S is a semigroup in the representation , then DotLeftCayleyDigraph is
+ simply short for DotString(LeftCayleyDigraph(S)).
+
+ DotRightCayleyDigraph can be used to produce a dot string for
+ the right Cayley graph of S.
+
+ See for more details, and see also
+ .
+
+ 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"]]>
+
+
+<#/GAPDoc>
diff --git a/doc/fropin.xml b/doc/fropin.xml
index 2a4f23295..1cecdbdc8 100644
--- a/doc/fropin.xml
+++ b/doc/fropin.xml
@@ -50,8 +50,8 @@ false
returns a list of the elements of S in the order they are
enumerated by the Froidure-Pin Algorithm. This is the same as the order
used to index the elements of S in and .
+ Attr="RightCayleyDigraph"/> and .
EnumeratorCanonical and IteratorCanonical return an
enumerator and an iterator where the elements are
@@ -67,8 +67,8 @@ false
AsList may not equal the value returned by AsListCanonical.
AsListCanonical exists so that there is a method for obtaining the
elements of S in the particular order used by
- and
- .
+ and
+ .
See also .
@@ -183,27 +183,34 @@ true]]>
<#/GAPDoc>
-<#GAPDoc Label="RightCayleyGraphSemigroup">
+<#GAPDoc Label="RightCayleyDigraph">
-
-
+
+
A list of lists of positive integers.
When the argument S is a semigroup in the representation
,
- RightCayleyGraphSemigroup returns the right
- Cayley graphs of S, as a list graph where
- graph[i][j] is equal to
+ RightCayleyDigraph returns the right
+ Cayley graphs of S, as a
+ digraph where vertex OutNeighbours(digraph)[i][j] is
PositionCanonical(S, AsListCanonical(S)[i] *
GeneratorsOfSemigroup(S)[j]).
- The list returned by LeftCayleyGraphSemigroup is defined analogously.
+ The digraph returned by LeftCayleyDigraph is defined analogously.
+
+ The digraph returned by this attribute belongs to the category
+ , the semigroup S
+ and the generators used to create the digraph can be recovered from the
+ digraph using
+ and .
+
S := FullTransformationMonoid(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 ] ]]]>
+gap> RightCayleyDigraph(S);
+
+gap> LeftCayleyDigraph(S);
+]]>
<#/GAPDoc>
diff --git a/doc/z-chap13.xml b/doc/z-chap13.xml
index 845f0ddfa..b26612332 100644
--- a/doc/z-chap13.xml
+++ b/doc/z-chap13.xml
@@ -27,7 +27,7 @@
Cayley graphs
- <#Include Label = "RightCayleyGraphSemigroup">
+ <#Include Label = "RightCayleyDigraph">
diff --git a/doc/z-chap18.xml b/doc/z-chap18.xml
index 888d48680..d14e6eac0 100644
--- a/doc/z-chap18.xml
+++ b/doc/z-chap18.xml
@@ -46,7 +46,9 @@
BookName = "GAPDoc"/> or viewed using .
<#Include Label = "DotString"/>
+ <#Include Label = "DotStringDigraph"/>
<#Include Label = "DotSemilatticeOfIdempotents"/>
+ <#Include Label = "DotLeftCayleyDigraph">
@@ -81,6 +83,7 @@
BookName = "GAPDoc"/> or viewed using .
<#Include Label = "TikzString">
+ <#Include Label = "TikzLeftCayleyDigraph">
diff --git a/gap/congruences/conginv.gi b/gap/congruences/conginv.gi
index ed6673f0e..97b62be44 100644
--- a/gap/congruences/conginv.gi
+++ b/gap/congruences/conginv.gi
@@ -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])];
#
diff --git a/gap/greens/gree.gi b/gap/greens/gree.gi
index c9670f115..e2e758da9 100644
--- a/gap/greens/gree.gi
+++ b/gap/greens/gree.gi
@@ -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);
diff --git a/gap/greens/gren.gi b/gap/greens/gren.gi
index c9043cedc..e3f6f1c29 100644
--- a/gap/greens/gren.gi
+++ b/gap/greens/gren.gi
@@ -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);
@@ -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);
@@ -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);
diff --git a/gap/ideals/idealenum.gi b/gap/ideals/idealenum.gi
index 6c44c6f55..9d0423ca9 100644
--- a/gap/ideals/idealenum.gi
+++ b/gap/ideals/idealenum.gi
@@ -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,
diff --git a/gap/main/fropin.gd b/gap/main/fropin.gd
index 652fbc604..50efb4a4e 100644
--- a/gap/main/fropin.gd
+++ b/gap/main/fropin.gd
@@ -48,3 +48,6 @@ DeclareOperation("Enumerate", [IsEnumerableSemigroupRep]);
DeclareOperation("IsFullyEnumerated", [IsEnumerableSemigroupRep]);
DeclareProperty("IsSemigroupEnumerator", IsEnumeratorByFunctions);
+
+DeclareAttribute("LeftCayleyDigraph", IsEnumerableSemigroupRep);
+DeclareAttribute("RightCayleyDigraph", IsEnumerableSemigroupRep);
diff --git a/gap/main/fropin.gi b/gap/main/fropin.gi
index 1ea7a73ec..2f34fc836 100644
--- a/gap/main/fropin.gi
+++ b/gap/main/fropin.gi
@@ -565,11 +565,23 @@ end);
InstallMethod(RightCayleyGraphSemigroup, "for an enumerable semigroup rep",
[IsEnumerableSemigroupRep], 3,
function(S)
+ return OutNeighbours(RightCayleyDigraph(S));
+end);
+
+InstallMethod(RightCayleyDigraph,
+"for an enumerable semigroup rep",
+[IsEnumerableSemigroupRep],
+function(S)
+ local digraph;
if not IsFinite(S) then
- ErrorNoReturn("Semigroups: RightCayleyGraphSemigroup: usage,\n",
+ ErrorNoReturn("Semigroups: RightCayleyDigraph: usage,\n",
"the first argument (a semigroup) must be finite,");
fi;
- return EN_SEMI_RIGHT_CAYLEY_GRAPH(S);
+ digraph := Digraph(EN_SEMI_RIGHT_CAYLEY_GRAPH(S));
+ SetFilterObj(digraph, IsCayleyDigraph);
+ SetSemigroupOfCayleyDigraph(digraph, S);
+ SetGeneratorsOfCayleyDigraph(digraph, GeneratorsOfSemigroup(S));
+ return digraph;
end);
# same method for ideals
@@ -578,11 +590,23 @@ InstallMethod(LeftCayleyGraphSemigroup,
"for an enumerable semigroup rep",
[IsEnumerableSemigroupRep], 3,
function(S)
+ return OutNeighbours(LeftCayleyDigraph(S));
+end);
+
+InstallMethod(LeftCayleyDigraph,
+"for an enumerable semigroup rep",
+[IsEnumerableSemigroupRep],
+function(S)
+ local digraph;
if not IsFinite(S) then
- ErrorNoReturn("Semigroups: LeftCayleyGraphSemigroup: usage,\n",
+ ErrorNoReturn("Semigroups: LeftCayleyDigraph: usage,\n",
"the first argument (a semigroup) must be finite,");
fi;
- return EN_SEMI_LEFT_CAYLEY_GRAPH(S);
+ digraph := Digraph(EN_SEMI_LEFT_CAYLEY_GRAPH(S));
+ SetFilterObj(digraph, IsCayleyDigraph);
+ SetSemigroupOfCayleyDigraph(digraph, S);
+ SetGeneratorsOfCayleyDigraph(digraph, GeneratorsOfSemigroup(S));
+ return digraph;
end);
InstallMethod(MultiplicationTable, "for an enumerable semigroup",
diff --git a/gap/semigroups/grpperm.gi b/gap/semigroups/grpperm.gi
index a1d4a4389..e18a101e9 100644
--- a/gap/semigroups/grpperm.gi
+++ b/gap/semigroups/grpperm.gi
@@ -156,7 +156,7 @@ function(S)
"IsGroupAsSemigroup,");
fi;
- cay := RightCayleyGraphSemigroup(S);
+ cay := OutNeighbours(RightCayleyDigraph(S));
deg := Size(S);
gen := [];
diff --git a/gap/semigroups/semifp.gi b/gap/semigroups/semifp.gi
index 19c1ad0bb..73338d299 100644
--- a/gap/semigroups/semifp.gi
+++ b/gap/semigroups/semifp.gi
@@ -92,7 +92,7 @@ function(x1, x2)
return x1 ^ map < x2 ^ map;
end);
-#TODO AsSSortedList, RightCayleyGraph, any more?
+#TODO AsSSortedList, RightCayleyDigraph, any more?
InstallMethod(ViewString, "for an f.p. semigroup element",
[IsElementOfFpSemigroup], String);
diff --git a/gap/semigroups/semitrans.gi b/gap/semigroups/semitrans.gi
index 540bfebc0..3852acfbe 100644
--- a/gap/semigroups/semitrans.gi
+++ b/gap/semigroups/semitrans.gi
@@ -853,12 +853,12 @@ function(S)
local cay, deg, gen, next, T, iso, inv, i;
if not IsFinite(S) then
- # This is unreachable in tests, since there is not other method that
+ # This is unreachable in tests, since there is no other method that
# terminates
TryNextMethod();
fi;
- cay := RightCayleyGraphSemigroup(S);
+ cay := OutNeighbours(RightCayleyDigraph(S));
deg := Size(S);
gen := [];
@@ -897,7 +897,7 @@ function(S)
TryNextMethod();
fi;
- cay := RightCayleyGraphSemigroup(S);
+ cay := OutNeighbours(RightCayleyDigraph(S));
deg := Size(S);
gen := EmptyPlist(Length(cay[1]));
diff --git a/gap/tools/display.gd b/gap/tools/display.gd
index 6052fc503..d66478b1c 100644
--- a/gap/tools/display.gd
+++ b/gap/tools/display.gd
@@ -15,4 +15,10 @@ DeclareOperation("DotString", [IsObject, IsRecord]);
DeclareOperation("TexString", [IsObject]);
DeclareOperation("TexString", [IsObject, IsObject]);
+DeclareOperation("TikzLeftCayleyDigraph", [IsSemigroup]);
+DeclareOperation("TikzRightCayleyDigraph", [IsSemigroup]);
+
+DeclareOperation("DotLeftCayleyDigraph", [IsSemigroup]);
+DeclareOperation("DotRightCayleyDigraph", [IsSemigroup]);
+
DeclareAttribute("DotSemilatticeOfIdempotents", IsInverseSemigroup);
diff --git a/gap/tools/display.gi b/gap/tools/display.gi
index 4b61d2c1e..50eda6112 100644
--- a/gap/tools/display.gi
+++ b/gap/tools/display.gi
@@ -735,3 +735,101 @@ function(coll)
deg := DegreeOfTransformationCollection(coll);
return JoinStringsWithSeparator(List(coll, x -> TexString(x, deg)), "\n");
end);
+
+InstallMethod(TikzLeftCayleyDigraph, "for a semigroup", [IsSemigroup],
+function(S)
+ return TikzString(LeftCayleyDigraph(S));
+end);
+
+InstallMethod(TikzRightCayleyDigraph, "for a semigroup", [IsSemigroup],
+function(S)
+ return TikzString(RightCayleyDigraph(S));
+end);
+
+InstallMethod(TikzString, "for a Cayley digraph", [IsCayleyDigraph],
+function(digraph)
+ local S, vertex, edge, str, nbs, x, from, gen;
+
+ S := SemigroupOfCayleyDigraph(digraph);
+ if not IsEnumerableSemigroupRep(S) or Size(S) > 26 then
+ TryNextMethod();
+ fi;
+
+ vertex := function(x)
+ local word, name, label;
+ word := MinimalFactorization(S, x);
+ name := SEMIGROUPS.WordToString(word);
+ label := SEMIGROUPS.ExtRepObjToString(SEMIGROUPS.WordToExtRepObj(word));
+ return Concatenation(" \\node [vertex] (", name, ") at (0, 0) {};\n",
+ " \\node at (0, 0) {$", label, "$};\n\n");
+ end;
+
+ edge := function(from, to, gen)
+ local word;
+ word := MinimalFactorization(S, AsListCanonical(S)[from]);
+ from := SEMIGROUPS.WordToString(word);
+ word := MinimalFactorization(S, AsListCanonical(S)[to]);
+ to := SEMIGROUPS.WordToString(word);
+ gen := SEMIGROUPS.WordToString([gen]);
+ if from <> to then
+ return Concatenation(" \\path[->] (", from,
+ ") edge [edge] node {$", gen, "$} (",
+ to, ");\n");
+ else
+ return Concatenation(" \\path[->] (", from,
+ ") edge [loop]\n",
+ " node {$", gen, "$} (", to, ");\n");
+ fi;
+ end;
+
+ str := "";
+
+ Append(str, "\\begin{tikzpicture}[scale=1, auto, \n");
+ Append(str, " vertex/.style={circle, draw, thick, fill=white, minimum");
+ Append(str, " size=0.65cm},\n");
+ Append(str, " edge/.style={arrows={-angle 90}, thick},\n");
+ Append(str, " loop/.style={min distance=5mm,looseness=5,");
+ Append(str, "arrows={-angle 90},thick}]\n\n");
+
+ Append(str, " % Vertices . . .\n");
+ for x in AsListCanonical(S) do
+ Append(str, vertex(x));
+ od;
+
+ Append(str, " % Edges . . .\n");
+ nbs := OutNeighbours(digraph);
+ for from in [1 .. Size(S)] do
+ for gen in [1 .. Size(nbs[from])] do
+ Append(str, edge(from, nbs[from][gen], gen));
+ od;
+ od;
+
+ Append(str, "\\end{tikzpicture}");
+ return str;
+end);
+
+InstallMethod(DotString, "for a Cayley digraph", [IsCayleyDigraph],
+function(digraph)
+ local S, li, label, i;
+ S := SemigroupOfCayleyDigraph(digraph);
+ if not IsEnumerableSemigroupRep(S) or Size(S) > 26 then
+ TryNextMethod();
+ fi;
+ li := AsListCanonical(S);
+ for i in [1 .. Size(S)] do
+ label := SEMIGROUPS.WordToExtRepObj(MinimalFactorization(S, li[i]));
+ label := SEMIGROUPS.ExtRepObjToString(label);
+ SetDigraphVertexLabel(digraph, i, label);
+ od;
+ return DotVertexLabelledDigraph(digraph);
+end);
+
+InstallMethod(DotLeftCayleyDigraph, "for a semigroup", [IsSemigroup],
+function(S)
+ return DotString(LeftCayleyDigraph(S));
+end);
+
+InstallMethod(DotRightCayleyDigraph, "for a semigroup", [IsSemigroup],
+function(S)
+ return DotString(RightCayleyDigraph(S));
+end);
diff --git a/src/fropin.cc b/src/fropin.cc
index a93902c23..730ffe440 100644
--- a/src/fropin.cc
+++ b/src/fropin.cc
@@ -338,9 +338,9 @@ Obj fropin(Obj obj, Obj limit, Obj lookfunc, Obj looking) {
return data;
}
-// Using the output of GABOW_SCC on the right and left Cayley graphs of a
-// semigroup, the following function calculates the strongly connected
-// components of the union of these two graphs.
+// Using the output of DigraphStronglyConnectedComponents on the right and left
+// Cayley graphs of a semigroup, the following function calculates the strongly
+// connected components of the union of these two graphs.
Obj SCC_UNION_LEFT_RIGHT_CAYLEY_GRAPHS(Obj self, Obj scc1, Obj scc2) {
UInt* ptr;
@@ -416,9 +416,9 @@ Obj SCC_UNION_LEFT_RIGHT_CAYLEY_GRAPHS(Obj self, Obj scc1, Obj scc2) {
}
// and should be scc data structures for the right and left
-// Cayley graphs of a semigroup, as produced by GABOW_SCC. This function find
-// the H-classes of the semigroup from and . The method used is
-// that described in:
+// Cayley graphs of a semigroup, as produced by
+// DigraphStronglyConnectedComponents. This function find the H-classes of the
+// semigroup from and . The method used is that described in:
// http://www.liafa.jussieu.fr/~jep/PDF/Exposes/StAndrews.pdf
Obj FIND_HCLASSES(Obj self, Obj right, Obj left) {
diff --git a/tst/standard/attr.tst b/tst/standard/attr.tst
index 56a452a3f..49c0378ee 100644
--- a/tst/standard/attr.tst
+++ b/tst/standard/attr.tst
@@ -342,22 +342,23 @@ gap> Size(MinimalDClass(s));
gap> MultiplicativeZero(s);
Transformation( [ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ] )
-#T# attr: RightCayleyGraphSemigroup
+#T# attr: RightCayleyDigraph
gap> S := Semigroup(PartialPerm([1, 2, 3], [1, 3, 4]),
> PartialPerm([1, 2, 3], [2, 5, 3]),
> PartialPerm([1, 2, 3], [4, 1, 2]),
> PartialPerm([1, 2, 3, 4], [2, 4, 1, 5]),
> PartialPerm([1, 3, 5], [5, 1, 3]));;
-gap> RightCayleyGraphSemigroup(S);;
-gap> Length(STRONGLY_CONNECTED_COMPONENTS_DIGRAPH(last)) = NrRClasses(S);
+gap> digraph := RightCayleyDigraph(S);;
+gap> Length(DigraphStronglyConnectedComponents(digraph).comps)
+> = NrRClasses(S);
true
-#T# attr: RightCayleyGraphSemigroup, infinite
-gap> RightCayleyGraphSemigroup(FreeSemigroup(2));
+#T# attr: RightCayleyDigraph, infinite
+gap> RightCayleyDigraph(FreeSemigroup(2));
Error, no method found! For debugging hints type ?Recovery from NoMethodFound
-Error, no 2nd choice method found for `CayleyGraphSemigroup' on 1 arguments
+Error, no 1st choice method found for `RightCayleyDigraph' on 1 arguments
-#T# attr: LeftCayleyGraphSemigroup
+#T# attr: LeftCayleyDigraph
gap> S := Monoid(BooleanMat([[1, 1, 1, 1, 1], [1, 0, 1, 0, 0],
> [1, 1, 0, 1, 0], [1, 1, 1, 1, 1],
> [1, 1, 0, 0, 0]]),
@@ -373,15 +374,15 @@ gap> S := Monoid(BooleanMat([[1, 1, 1, 1, 1], [1, 0, 1, 0, 0],
> BooleanMat([[1, 0, 0, 0, 1], [1, 0, 0, 0, 1],
> [0, 0, 0, 0, 1], [0, 1, 1, 0, 1],
> [1, 1, 1, 0, 1]]));;
-gap> LeftCayleyGraphSemigroup(S);;
-gap> Length(STRONGLY_CONNECTED_COMPONENTS_DIGRAPH(last)) = NrLClasses(S);
+gap> digraph := LeftCayleyDigraph(S);;
+gap> Length(DigraphStronglyConnectedComponents(digraph).comps)
+> = NrLClasses(S);
true
-#T# attr: RightCayleyGraphSemigroup, infinite
-gap> LeftCayleyGraphSemigroup(FreeInverseSemigroup(2));
+#T# attr: RightCayleyDigraph, infinite
+gap> LeftCayleyDigraph(FreeInverseSemigroup(2));
Error, no method found! For debugging hints type ?Recovery from NoMethodFound
-Error, no 2nd choice method found for `CayleyGraphDualSemigroup' on 1 argument\
-s
+Error, no 1st choice method found for `LeftCayleyDigraph' on 1 arguments
#T# attr: IsomorphismReesMatrixSemigroup
gap> D := GreensDClassOfElement(Semigroup(
diff --git a/tst/standard/display.tst b/tst/standard/display.tst
index dd6bf3a2a..e291c1193 100644
--- a/tst/standard/display.tst
+++ b/tst/standard/display.tst
@@ -724,6 +724,62 @@ Error, Semigroups: TexString: usage,
the second argument (the degree) should be at least the degree of the first ar\
gument (a transformation),
+# Tikz/DotLeft/RightCayleyDigraph
+gap> TikzLeftCayleyDigraph(FullTransformationMonoid(2));
+"\\begin{tikzpicture}[scale=1, auto, \n vertex/.style={circle, draw, thick, f\
+ill=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 \\node [vertex] (b) at (0, 0) {};\n \\node at (0, 0) {$b$};\n\n \\node\
+ [vertex] (c) at (0, 0) {};\n \\node at (0, 0) {$c$};\n\n \\node [vertex] (c\
+b) at (0, 0) {};\n \\node at (0, 0) {$cb$};\n\n % Edges . . .\n \\path[->] \
+(a) edge [loop]\n node {$a$} (a);\n \\path[->] (a) edge [edge] node\
+ {$b$} (b);\n \\path[->] (a) edge [edge] node {$c$} (c);\n \\path[->] (b) ed\
+ge [loop]\n node {$a$} (b);\n \\path[->] (b) edge [edge] node {$b$}\
+ (a);\n \\path[->] (b) edge [edge] node {$c$} (cb);\n \\path[->] (c) edge [l\
+oop]\n node {$a$} (c);\n \\path[->] (c) edge [loop]\n nod\
+e {$b$} (c);\n \\path[->] (c) edge [loop]\n node {$c$} (c);\n \\pa\
+th[->] (cb) edge [loop]\n node {$a$} (cb);\n \\path[->] (cb) edge [\
+loop]\n node {$b$} (cb);\n \\path[->] (cb) edge [loop]\n \
+node {$c$} (cb);\n\\end{tikzpicture}"
+gap> TikzRightCayleyDigraph(FullTransformationMonoid(2));
+"\\begin{tikzpicture}[scale=1, auto, \n vertex/.style={circle, draw, thick, f\
+ill=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 \\node [vertex] (b) at (0, 0) {};\n \\node at (0, 0) {$b$};\n\n \\node\
+ [vertex] (c) at (0, 0) {};\n \\node at (0, 0) {$c$};\n\n \\node [vertex] (c\
+b) at (0, 0) {};\n \\node at (0, 0) {$cb$};\n\n % Edges . . .\n \\path[->] \
+(a) edge [loop]\n node {$a$} (a);\n \\path[->] (a) edge [edge] node\
+ {$b$} (b);\n \\path[->] (a) edge [edge] node {$c$} (c);\n \\path[->] (b) ed\
+ge [loop]\n node {$a$} (b);\n \\path[->] (b) edge [edge] node {$b$}\
+ (a);\n \\path[->] (b) edge [edge] node {$c$} (c);\n \\path[->] (c) edge [lo\
+op]\n node {$a$} (c);\n \\path[->] (c) edge [edge] node {$b$} (cb);\
+\n \\path[->] (c) edge [loop]\n node {$c$} (c);\n \\path[->] (cb) \
+edge [loop]\n node {$a$} (cb);\n \\path[->] (cb) edge [edge] node {\
+$b$} (c);\n \\path[->] (cb) edge [edge] node {$c$} (c);\n\\end{tikzpicture}"
+gap> DotRightCayleyDigraph(FullTransformationMonoid(2));
+"//dot\ndigraph hgn{\nnode [shape=circle]\n1 [label=\"a\"]\n2 [label=\"b\"]\n3\
+ [label=\"c\"]\n4 [label=\"cb\"]\n1 -> 1\n1 -> 2\n1 -> 3\n2 -> 2\n2 -> 1\n2 ->\
+ 3\n3 -> 3\n3 -> 4\n3 -> 3\n4 -> 4\n4 -> 3\n4 -> 3\n}\n"
+gap> DotLeftCayleyDigraph(FullTransformationMonoid(2));
+"//dot\ndigraph hgn{\nnode [shape=circle]\n1 [label=\"a\"]\n2 [label=\"b\"]\n3\
+ [label=\"c\"]\n4 [label=\"cb\"]\n1 -> 1\n1 -> 2\n1 -> 3\n2 -> 2\n2 -> 1\n2 ->\
+ 4\n3 -> 3\n3 -> 3\n3 -> 3\n4 -> 4\n4 -> 4\n4 -> 4\n}\n"
+gap> S := LeftZeroSemigroup(27);;
+gap> DotLeftCayleyDigraph(S);
+Error, no method found! For debugging hints type ?Recovery from NoMethodFound
+Error, no 2nd choice method found for `DotString' on 1 arguments
+gap> TikzLeftCayleyDigraph(S);
+Error, no method found! For debugging hints type ?Recovery from NoMethodFound
+Error, no 2nd choice method found for `TikzString' on 1 arguments
+gap> DotRightCayleyDigraph(S);
+Error, no method found! For debugging hints type ?Recovery from NoMethodFound
+Error, no 2nd choice method found for `DotString' on 1 arguments
+gap> TikzRightCayleyDigraph(S);
+Error, no method found! For debugging hints type ?Recovery from NoMethodFound
+Error, no 2nd choice method found for `TikzString' on 1 arguments
+
#
gap> SEMIGROUPS.StopTest();
gap> STOP_TEST("Semigroups package: standard/display.tst");
diff --git a/tst/standard/fropin.tst b/tst/standard/fropin.tst
index 67c0e43d2..4faa8c9c4 100644
--- a/tst/standard/fropin.tst
+++ b/tst/standard/fropin.tst
@@ -416,15 +416,36 @@ gap> PositionSorted(S, S.1);
Error, Semigroups: PositionSortedOp: usage,
the first argument (a semigroup) must be finite,
-# Left/RightCayleyGraphSemigroup, for an infinite enumerable semigroup
+# Left/RightCayleyDigraph, for an infinite enumerable semigroup
gap> S := Semigroup(Matrix(IsMaxPlusMatrix, [[-2, 2], [0, -1]]));;
-gap> RightCayleyGraphSemigroup(S);
-Error, Semigroups: RightCayleyGraphSemigroup: usage,
+gap> RightCayleyDigraph(S);
+Error, Semigroups: RightCayleyDigraph: usage,
the first argument (a semigroup) must be finite,
-gap> LeftCayleyGraphSemigroup(S);
-Error, Semigroups: LeftCayleyGraphSemigroup: usage,
+gap> LeftCayleyDigraph(S);
+Error, Semigroups: LeftCayleyDigraph: usage,
the first argument (a semigroup) must be finite,
+# Left/RightCayleyGraphSemigroup
+gap> S := Semigroup(FullTransformationMonoid(3));;
+gap> LeftCayleyGraphSemigroup(S);
+[ [ 1, 2, 3, 4 ], [ 2, 5, 8, 9 ], [ 3, 6, 1, 10 ], [ 4, 7, 7, 4 ],
+ [ 5, 1, 6, 14 ], [ 6, 8, 5, 15 ], [ 7, 11, 4, 10 ], [ 8, 3, 2, 16 ],
+ [ 9, 12, 12, 9 ], [ 10, 13, 13, 10 ], [ 11, 4, 11, 22 ], [ 12, 17, 9, 16 ],
+ [ 13, 18, 10, 4 ], [ 14, 19, 19, 14 ], [ 15, 20, 20, 15 ],
+ [ 16, 21, 21, 16 ], [ 17, 9, 17, 26 ], [ 18, 10, 18, 26 ],
+ [ 19, 23, 14, 15 ], [ 20, 24, 15, 14 ], [ 21, 25, 16, 9 ],
+ [ 22, 22, 22, 22 ], [ 23, 14, 23, 27 ], [ 24, 15, 24, 22 ],
+ [ 25, 16, 25, 27 ], [ 26, 26, 26, 26 ], [ 27, 27, 27, 27 ] ]
+gap> RightCayleyGraphSemigroup(S);
+[ [ 1, 2, 3, 4 ], [ 2, 5, 6, 7 ], [ 3, 8, 1, 7 ], [ 4, 9, 10, 4 ],
+ [ 5, 1, 8, 11 ], [ 6, 3, 2, 11 ], [ 7, 12, 13, 7 ], [ 8, 6, 5, 4 ],
+ [ 9, 14, 15, 10 ], [ 10, 16, 4, 10 ], [ 11, 17, 18, 11 ],
+ [ 12, 19, 20, 13 ], [ 13, 21, 7, 13 ], [ 14, 4, 16, 22 ], [ 15, 10, 9, 22 ],
+ [ 16, 15, 14, 4 ], [ 17, 23, 24, 18 ], [ 18, 25, 11, 18 ],
+ [ 19, 7, 21, 22 ], [ 20, 13, 12, 22 ], [ 21, 20, 19, 7 ],
+ [ 22, 26, 26, 22 ], [ 23, 11, 25, 22 ], [ 24, 18, 17, 22 ],
+ [ 25, 24, 23, 11 ], [ 26, 27, 22, 26 ], [ 27, 22, 27, 22 ] ]
+
# AsSet, for an infinite enumerable semigroup
gap> S := Semigroup(Matrix(IsMaxPlusMatrix, [[-2, 2], [0, -1]]));;
gap> AsSet(S);
diff --git a/tst/standard/gren.tst b/tst/standard/gren.tst
index 6b070547c..81525e3da 100644
--- a/tst/standard/gren.tst
+++ b/tst/standard/gren.tst
@@ -1670,16 +1670,16 @@ gap> GreensLClasses(D);
# Test GreensXClasses for an infinite enumerable semigroup
gap> S := Semigroup(Matrix(IsMaxPlusMatrix, [[0, 2], [-1, 0]]));;
gap> GreensLClasses(S);
-Error, Semigroups: LeftCayleyGraphSemigroup: usage,
+Error, Semigroups: LeftCayleyDigraph: usage,
the first argument (a semigroup) must be finite,
gap> GreensRClasses(S);
-Error, Semigroups: RightCayleyGraphSemigroup: usage,
+Error, Semigroups: RightCayleyDigraph: usage,
the first argument (a semigroup) must be finite,
gap> GreensHClasses(S);
-Error, Semigroups: LeftCayleyGraphSemigroup: usage,
+Error, Semigroups: LeftCayleyDigraph: usage,
the first argument (a semigroup) must be finite,
gap> GreensDClasses(S);
-Error, Semigroups: LeftCayleyGraphSemigroup: usage,
+Error, Semigroups: LeftCayleyDigraph: usage,
the first argument (a semigroup) must be finite,
gap> GreensJClasses(S);
Error, no method found! For debugging hints type ?Recovery from NoMethodFound