diff --git a/doc/examples.xml b/doc/examples.xml
index 835475b14..909d7b8b8 100644
--- a/doc/examples.xml
+++ b/doc/examples.xml
@@ -309,3 +309,47 @@ gap> GeneralisedPetersenGraph(IsMutableDigraph, 9, 4);
<#/GAPDoc>
+
+<#GAPDoc Label="PancakeGraph">
+
+
+ A digraph.
+
+ If n is a positive integer, then this operation returns
+ the Pancake graph with n! vertices and n!(n - 1)
+ directed edges. The nth Pancake graph is the Cayley graph of the
+ symmetric group acting on [1 .. n] with respect to the
+ generating set consisting of the prefix reversals
. This generating
+ set has consists of the permutations p2, p3, ...,
+ pn where ListPerm(pi, n) is the concatenation
+ of [i, i -1 .. 1] and [i + 1 .. n].
+
+
+ If the optional first argument filt is present, then this should
+ specify the category or representation the digraph being created will
+ belong to. For example, if filt is ,
+ then the digraph being created will be mutable, if filt is , then the digraph will be immutable.
+ If the optional first argument filt is not present, then is used by default.
+
+ See https://en.wikipedia.org/wiki/Pancake_graph for further
+ details.
+
+ D := PancakeGraph(5);
+
+gap> DigraphUndirectedGirth(D);
+6
+gap> ChromaticNumber(D);
+3
+gap> IsHamiltonianDigraph(D);
+true
+gap> IsCayleyDigraph(D);
+true
+gap> IsVertexTransitive(D);
+true]]>
+
+
+<#/GAPDoc>
diff --git a/doc/z-chap2.xml b/doc/z-chap2.xml
index 733e3c92c..5cded20a3 100644
--- a/doc/z-chap2.xml
+++ b/doc/z-chap2.xml
@@ -87,6 +87,7 @@
<#Include Label="JohnsonDigraph">
<#Include Label="PetersenGraph">
<#Include Label="GeneralisedPetersenGraph">
+ <#Include Label="PancakeGraph">
diff --git a/gap/examples.gd b/gap/examples.gd
index 4a08fdf79..7368a519a 100644
--- a/gap/examples.gd
+++ b/gap/examples.gd
@@ -48,3 +48,8 @@ DeclareOperation("PetersenGraph", [IsFunction]);
DeclareConstructor("GeneralisedPetersenGraphCons", [IsDigraph, IsInt, IsInt]);
DeclareOperation("GeneralisedPetersenGraph", [IsInt, IsInt]);
DeclareOperation("GeneralisedPetersenGraph", [IsFunction, IsInt, IsInt]);
+
+DeclareConstructor("PancakeGraphCons", [IsDigraph, IsPosInt]);
+DeclareOperation("PancakeGraph", [IsPosInt]);
+DeclareOperation("PancakeGraph", [IsFunction, IsPosInt]);
+
diff --git a/gap/examples.gi b/gap/examples.gi
index 402ef6456..e0cbbb78a 100644
--- a/gap/examples.gi
+++ b/gap/examples.gi
@@ -370,3 +370,39 @@ GeneralisedPetersenGraphCons);
InstallMethod(GeneralisedPetersenGraph, "for integer, integer", [IsInt, IsInt],
{n, k} -> GeneralisedPetersenGraphCons(IsImmutableDigraph, n, k));
+
+BindGlobal("DIGRAPHS_PrefixReversalGroup",
+function(n)
+ local id, A, i;
+ if n = 1 then
+ return Group(());
+ fi;
+ id := [1 .. n];
+ A := [];
+ for i in [2 .. n] do
+ id{[1 .. i]} := [i, i - 1 .. 1];
+ Add(A, PermList(id));
+ od;
+ return Group(A);
+end);
+
+InstallMethod(PancakeGraphCons, "for IsMutableDigraph and pos int",
+[IsMutableDigraph, IsPosInt],
+{filt, n} -> CayleyDigraph(IsMutableDigraph, DIGRAPHS_PrefixReversalGroup(n)));
+
+InstallMethod(PancakeGraphCons, "for IsImmutableDigraph and pos int",
+[IsImmutableDigraph, IsPosInt],
+function(filt, n)
+ local D;
+ D := CayleyDigraph(IsImmutableDigraph, DIGRAPHS_PrefixReversalGroup(n));
+ SetIsMultiDigraph(D, false);
+ SetIsSymmetricDigraph(D, true);
+ SetIsHamiltonianDigraph(D, true);
+ return D;
+end);
+
+InstallMethod(PancakeGraph, "for a function and pos int",
+[IsFunction, IsPosInt], PancakeGraphCons);
+
+InstallMethod(PancakeGraph, "for a pos int",
+[IsPosInt], n -> PancakeGraphCons(IsImmutableDigraph, n));
diff --git a/gap/grape.gd b/gap/grape.gd
index 9eab49d94..205a931c0 100644
--- a/gap/grape.gd
+++ b/gap/grape.gd
@@ -11,8 +11,13 @@
DeclareOperation("Graph", [IsDigraph]);
# Cayley digraphs
+DeclareConstructor("CayleyDigraphCons", [IsDigraph, IsGroup, IsList]);
+
DeclareOperation("CayleyDigraph", [IsGroup]);
DeclareOperation("CayleyDigraph", [IsGroup, IsList]);
+DeclareOperation("CayleyDigraph", [IsFunction, IsGroup]);
+DeclareOperation("CayleyDigraph", [IsFunction, IsGroup, IsList]);
+
DeclareAttribute("GroupOfCayleyDigraph", IsCayleyDigraph);
DeclareAttribute("SemigroupOfCayleyDigraph", IsCayleyDigraph);
DeclareAttribute("GeneratorsOfCayleyDigraph", IsCayleyDigraph);
diff --git a/gap/grape.gi b/gap/grape.gi
index d550a6546..0cfd838ff 100644
--- a/gap/grape.gi
+++ b/gap/grape.gi
@@ -91,33 +91,65 @@ function(imm, G, obj, act, adj)
return D;
end);
-InstallMethod(CayleyDigraph, "for a group with generators",
-[IsGroup, IsHomogeneousList],
-function(G, gens)
- local adj, D;
-
+InstallMethod(CayleyDigraphCons,
+"for IsMutableDigraph, group, and list of elements",
+[IsMutableDigraph, IsGroup, IsHomogeneousList],
+function(filt, G, gens)
if not IsFinite(G) then
ErrorNoReturn("the 1st argument must be a finite group,");
elif not ForAll(gens, x -> x in G) then
ErrorNoReturn("the 2nd argument must consist of elements of the ",
"1st argument,");
fi;
+ return Digraph(IsMutableDigraph,
+ G,
+ AsList(G),
+ OnLeftInverse,
+ {x, y} -> x ^ -1 * y in gens);
+end);
- adj := function(x, y)
- return x ^ -1 * y in gens;
- end;
+InstallMethod(CayleyDigraphCons,
+"for IsImmutableDigraph, group, and list of elements",
+[IsImmutableDigraph, IsGroup, IsHomogeneousList],
+function(filt, G, gens)
+ # This method is a duplicate of the one above because the method for Digraph
+ # sets some additional attributes if IsImmutableDigraph is passed as 1st
+ # argument, and so we don't want to make a mutable version of the returned
+ # graph, and then make it immutable, because then those attributes won't be
+ # set.
+ local D;
+ if not IsFinite(G) then
+ ErrorNoReturn("the 1st argument must be a finite group,");
+ elif not ForAll(gens, x -> x in G) then
+ ErrorNoReturn("the 2nd argument must consist of elements of the ",
+ "1st argument,");
+ fi;
+ D := Digraph(IsImmutableDigraph,
+ G,
+ AsList(G),
+ OnLeftInverse,
+ {x, y} -> x ^ -1 * y in gens);
- D := Digraph(G, AsList(G), OnLeftInverse, adj);
SetFilterObj(D, IsCayleyDigraph);
SetGroupOfCayleyDigraph(D, G);
SetGeneratorsOfCayleyDigraph(D, gens);
-
return D;
end);
+InstallMethod(CayleyDigraph, "for a group and list of elements",
+[IsGroup, IsHomogeneousList],
+{G, gens} -> CayleyDigraphCons(IsImmutableDigraph, G, gens));
+
+InstallMethod(CayleyDigraph, "for a filter and group with generators",
+[IsFunction, IsGroup, IsHomogeneousList], CayleyDigraphCons);
+
InstallMethod(CayleyDigraph, "for a group with generators",
[IsGroup and HasGeneratorsOfGroup],
-G -> CayleyDigraph(G, GeneratorsOfGroup(G)));
+G -> CayleyDigraphCons(IsImmutableDigraph, G, GeneratorsOfGroup(G)));
+
+InstallMethod(CayleyDigraph, "for a filter and group with generators",
+[IsFunction, IsGroup and HasGeneratorsOfGroup],
+{filt, G} -> CayleyDigraphCons(filt, G, GeneratorsOfGroup(G)));
InstallMethod(Graph, "for a digraph", [IsDigraph],
function(D)
diff --git a/tst/standard/examples.tst b/tst/standard/examples.tst
index d06db41e4..47a8fd6bb 100644
--- a/tst/standard/examples.tst
+++ b/tst/standard/examples.tst
@@ -226,6 +226,18 @@ Error, the arguments and must be non-negative integers,
gap> JohnsonDigraph(IsMutableDigraph, 4, 2);
+# PancakeGraph
+gap> D := PancakeGraph(3);
+
+gap> ChromaticNumber(D);
+2
+gap> IsVertexTransitive(D);
+true
+gap> DigraphUndirectedGirth(D);
+6
+gap> IsHamiltonianDigraph(D);
+true
+
#
gap> DIGRAPHS_StopTest();
gap> STOP_TEST("Digraphs package: standard/examples.tst", 0);