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);