From 575f1d0c6ec5773cc453a2eb792746d6635ae851 Mon Sep 17 00:00:00 2001 From: Meike Weiss Date: Fri, 8 May 2026 10:48:05 +0200 Subject: [PATCH 1/6] ignore directions for planar embedding --- gap/planar.gi | 1 + tst/standard/attr.tst | 2 +- tst/standard/planar.tst | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/gap/planar.gi b/gap/planar.gi index dbcee889e..1b858afeb 100644 --- a/gap/planar.gi +++ b/gap/planar.gi @@ -47,6 +47,7 @@ function(D) if DIGRAPHS_HasTrivialRotationSystem(D) then; return OutNeighbors(D); fi; + D := DigraphSymmetricClosure(DigraphMutableCopyIfMutable(D)); return PLANAR_EMBEDDING(D); end); diff --git a/tst/standard/attr.tst b/tst/standard/attr.tst index 6105bfae1..b6525aa82 100644 --- a/tst/standard/attr.tst +++ b/tst/standard/attr.tst @@ -1119,7 +1119,7 @@ gap> FacialWalks(g, rotationSy); [ [ 1, 2, 3, 4, 3, 2 ] ] gap> g := CycleDigraph(4);; gap> planar := PlanarEmbedding(g); -[ [ 2 ], [ 3 ], [ 4 ], [ 1 ] ] +[ [ 2, 4 ], [ 3, 1 ], [ 4, 2 ], [ 1, 3 ] ] gap> FacialWalks(g, planar); [ [ 1, 2, 3, 4 ] ] gap> nonPlanar := [[2, 4], [1, 3], [2, 4], [1, 3]];; diff --git a/tst/standard/planar.tst b/tst/standard/planar.tst index 9a8020a30..628c66fb0 100644 --- a/tst/standard/planar.tst +++ b/tst/standard/planar.tst @@ -90,7 +90,7 @@ gap> D := Digraph([[3, 5, 10], [8, 9, 10], [1, 4], [3, 6], [1, 7, 11], [4, 7], gap> PlanarEmbedding(D); [ [ 3, 10, 5 ], [ 10, 8, 9 ], [ 4, 1 ], [ 6, 3 ], [ 1, 11, 7 ], [ 7, 4 ], - [ 8, 6 ], [ 7, 2 ], [ 2, 11 ], [ 1, 2 ], [ 9, 5 ] ] + [ 5, 8, 6 ], [ 7, 2 ], [ 2, 11 ], [ 1, 2 ], [ 9, 5 ] ] gap> D := Digraph([[2, 4, 7, 9, 10], [1, 3, 4, 6, 9, 10], [6, 10], > [2, 5, 8, 9], [1, 2, 3, 4, 6, 7, 9, 10], [3, 4, 5, 7, 9, 10], > [3, 4, 5, 6, 9, 10], [3, 4, 5, 7, 9], [2, 3, 5, 6, 7, 8], [3, 5]]); From f1a8621404f1f9baec00f6c4303f30b3a4341fea Mon Sep 17 00:00:00 2001 From: Meike Weiss Date: Fri, 8 May 2026 11:11:02 +0200 Subject: [PATCH 2/6] more clarification --- doc/attr.xml | 11 +++++------ doc/planar.xml | 12 +++++++----- gap/attr.gi | 4 ++-- tst/standard/attr.tst | 4 ++-- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/doc/attr.xml b/doc/attr.xml index c2cba764d..36b0b6f94 100644 --- a/doc/attr.xml +++ b/doc/attr.xml @@ -1538,25 +1538,24 @@ gap> DigraphAllChordlessCycles(D); If digraph is an Eulerian digraph and list is a rotation system of digraph, then FacialWalks returns a list of the facial walks in digraph.

- A rotation system defines for each vertex the ordering of the out-neighbours. + A rotation system defines for each vertex of a symmetric digraph the ordering of the neighbours. For example, the method computes for a planar digraph D the rotation system of a planar embedding of D. The facial walks of digraph are closed walks and they are defined by the rotation system list. They describe the boundaries of the faces of the embedding of digraph given by the rotation system list. - The operation FacialWalks ignores - multiple edges and loops.

+ The operation FacialWalks ignores multiple edges, loops and the direction of the edges.

Here are some examples for planar embeddings: D1 := CycleDigraph(4);; gap> planar := PlanarEmbedding(D1); -[ [ 2 ], [ 3 ], [ 4 ], [ 1 ] ] +[ [ 2, 4 ], [ 3, 1 ], [ 4, 2 ], [ 1, 3 ] ] gap> FacialWalks(D1, planar); -[ [ 1, 2, 3, 4 ] ] +[ [ 1, 2, 3, 4 ], [ 1, 4, 3, 2 ] ] gap> nonPlanar := [[2, 4], [1, 3], [2, 4], [1, 3]];; gap> FacialWalks(D1, nonPlanar); -[ [ 1, 2, 3, 4 ] ] +[ [ 1, 2, 3, 4 ], [ 1, 4, 3, 2 ] ] gap> D2 := CompleteMultipartiteDigraph([2, 2, 2]);; gap> rotationSystem := PlanarEmbedding(D2); [ [ 3, 5, 4, 6 ], [ 6, 4, 5, 3 ], [ 6, 2, 5, 1 ], [ 1, 5, 2, 6 ], diff --git a/doc/planar.xml b/doc/planar.xml index b59071067..cdd86d49d 100644 --- a/doc/planar.xml +++ b/doc/planar.xml @@ -262,8 +262,8 @@ gap> D := Digraph([[3, 5, 10], [8, 9, 10], [1, 4], [3, 6], > [1, 7, 11], [4, 7], [6, 8], [2, 7], [2, 11], [1, 2], [5, 9]]); gap> PlanarEmbedding(D); -[ [ 3, 10, 5 ], [ 10, 8, 9 ], [ 4, 1 ], [ 6, 3 ], [ 1, 11, 7 ], - [ 7, 4 ], [ 8, 6 ], [ 7, 2 ], [ 2, 11 ], [ 1, 2 ], [ 9, 5 ] ] +[ [ 3, 10, 5 ], [ 10, 8, 9 ], [ 4, 1 ], [ 6, 3 ], [ 1, 11, 7 ], [ 7, 4 ], + [ 5, 8, 6 ], [ 7, 2 ], [ 2, 11 ], [ 1, 2 ], [ 9, 5 ] ] gap> D := Digraph([[2, 4, 7, 9, 10], [1, 3, 4, 6, 9, 10], [6, 10], > [2, 5, 8, 9], [1, 2, 3, 4, 6, 7, 9, 10], [3, 4, 5, 7, 9, 10], > [3, 4, 5, 6, 9, 10], [3, 4, 5, 7, 9], [2, 3, 5, 6, 7, 8], [3, 5]]); @@ -274,8 +274,8 @@ gap> D := Digraph(IsMutableDigraph, [[3, 5, 10], [8, 9, 10], [1, 4], > [3, 6], [1, 7, 11], [4, 7], [6, 8], [2, 7], [2, 11], [1, 2], [5, 9]]); gap> PlanarEmbedding(D); -[ [ 3, 10, 5 ], [ 10, 8, 9 ], [ 4, 1 ], [ 6, 3 ], [ 1, 11, 7 ], - [ 7, 4 ], [ 8, 6 ], [ 7, 2 ], [ 2, 11 ], [ 1, 2 ], [ 9, 5 ] ] +[ [ 3, 10, 5 ], [ 10, 8, 9 ], [ 4, 1 ], [ 6, 3 ], [ 1, 11, 7 ], + [ 7, 4 ], [ 5, 8, 6 ], [ 7, 2 ], [ 2, 11 ], [ 1, 2 ], [ 9, 5 ] ] gap> D := Digraph(IsMutableDigraph, [[2, 4, 7, 9, 10], > [1, 3, 4, 6, 9, 10], [6, 10], [2, 5, 8, 9], > [1, 2, 3, 4, 6, 7, 9, 10], [3, 4, 5, 7, 9, 10], @@ -433,13 +433,15 @@ fail A digraph or fail. - If digraph is a planar digraph, then returns the the dual graph of digraph. + If digraph is a planar digraph, then returns the symmetric dual graph + of digraph. If digraph is not planar, then fail is returned.

The dual graph of a planar digraph digraph has a vertex for each face of digraph and an edge for each pair of faces that are separated by an edge from each other. Vertex i of the dual graph corresponds to the facial walk at the i-th position calling of digraph with the rotation system returned by . + The directions and multiplicities of any edges in digraph are ignored by .

Note that , and therefore diff --git a/gap/attr.gi b/gap/attr.gi index ebaf86487..24c87cc5c 100644 --- a/gap/attr.gi +++ b/gap/attr.gi @@ -1911,8 +1911,8 @@ function(D, rotationSystem) return cycle; end; - D := DigraphRemoveLoops(DigraphRemoveAllMultipleEdges( - DigraphMutableCopyIfMutable(D))); + D := DigraphSymmetricClosure(DigraphRemoveLoops(DigraphRemoveAllMultipleEdges( + DigraphMutableCopyIfMutable(D)))); facialWalks := []; remEdges := ShallowCopy(DigraphEdges(D)); diff --git a/tst/standard/attr.tst b/tst/standard/attr.tst index b6525aa82..fa48d4ed2 100644 --- a/tst/standard/attr.tst +++ b/tst/standard/attr.tst @@ -1121,10 +1121,10 @@ gap> g := CycleDigraph(4);; gap> planar := PlanarEmbedding(g); [ [ 2, 4 ], [ 3, 1 ], [ 4, 2 ], [ 1, 3 ] ] gap> FacialWalks(g, planar); -[ [ 1, 2, 3, 4 ] ] +[ [ 1, 2, 3, 4 ], [ 1, 4, 3, 2 ] ] gap> nonPlanar := [[2, 4], [1, 3], [2, 4], [1, 3]];; gap> FacialWalks(g, nonPlanar); -[ [ 1, 2, 3, 4 ] ] +[ [ 1, 2, 3, 4 ], [ 1, 4, 3, 2 ] ] gap> g := CompleteMultipartiteDigraph([2, 2, 2]);; gap> rotationSystem := PlanarEmbedding(g); [ [ 3, 5, 4, 6 ], [ 6, 4, 5, 3 ], [ 6, 2, 5, 1 ], [ 1, 5, 2, 6 ], From 00b1a46602d2ea4111e153d1b75f6ce57260f865 Mon Sep 17 00:00:00 2001 From: Meike Weiss Date: Fri, 8 May 2026 11:13:19 +0200 Subject: [PATCH 3/6] fix FacialWalks --- doc/attr.xml | 2 +- gap/attr.gi | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/doc/attr.xml b/doc/attr.xml index 36b0b6f94..69df6ad92 100644 --- a/doc/attr.xml +++ b/doc/attr.xml @@ -1535,7 +1535,7 @@ gap> DigraphAllChordlessCycles(D); A list of lists of vertices. - If digraph is an Eulerian digraph and list is a rotation system of digraph, + If digraph is a digraph and list is a rotation system of digraph, then FacialWalks returns a list of the facial walks in digraph.

A rotation system defines for each vertex of a symmetric digraph the ordering of the neighbours. diff --git a/gap/attr.gi b/gap/attr.gi index 24c87cc5c..0770b3d8d 100644 --- a/gap/attr.gi +++ b/gap/attr.gi @@ -1859,10 +1859,6 @@ InstallMethod(FacialWalks, "for a digraph and a dense list", function(D, rotationSystem) local FacialWalk, facialWalks, remEdges, cycle; - if not IsEulerianDigraph(D) then - ErrorNoReturn("the 1st argument (digraph ) must be Eulerian"); - fi; - if Length(rotationSystem) <> DigraphNrVertices(D) or not ForAll(rotationSystem, IsList) then ErrorNoReturn("the 2nd argument (dense list ) is not a ", From f852ea671bfff39302d74fdfff17286ef7a22c56 Mon Sep 17 00:00:00 2001 From: Meike Weiss Date: Fri, 8 May 2026 11:33:10 +0200 Subject: [PATCH 4/6] trivial rotation system --- gap/planar.gi | 2 +- tst/standard/attr.tst | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/gap/planar.gi b/gap/planar.gi index 1b858afeb..b68e86a11 100644 --- a/gap/planar.gi +++ b/gap/planar.gi @@ -44,10 +44,10 @@ end); InstallMethod(PlanarEmbedding, "for a digraph", [IsDigraph], function(D) + D := DigraphSymmetricClosure(DigraphMutableCopyIfMutable(D)); if DIGRAPHS_HasTrivialRotationSystem(D) then; return OutNeighbors(D); fi; - D := DigraphSymmetricClosure(DigraphMutableCopyIfMutable(D)); return PLANAR_EMBEDDING(D); end); diff --git a/tst/standard/attr.tst b/tst/standard/attr.tst index fa48d4ed2..8d57c6901 100644 --- a/tst/standard/attr.tst +++ b/tst/standard/attr.tst @@ -1097,8 +1097,6 @@ gap> DigraphAllUndirectedSimpleCircuits(g); [ 9, 5, 6, 10 ], [ 9, 5, 7, 8, 6, 10 ] ] # FacialCycles -gap> FacialWalks(ChainDigraph(3), []); -Error, the 1st argument (digraph ) must be Eulerian gap> FacialWalks(CycleDigraph(3), []); Error, the 2nd argument (dense list ) is not a rotation system\ for the 1st argument (digraph ), expected a list of 3 lists, @@ -1109,6 +1107,9 @@ gap> FacialWalks(CycleDigraph(3), [[4], [1], [3]]); Error, the 2nd argument (dense list ) is not a rotation system\ for the 1st argument (digraph ), expected its union to be the vertices of \ , +gap> g:=ChainDigraph(3);; +gap> FacialWalks(g, PlanarEmbedding(g)); +[ [ 1, 2, 3, 2 ] ] gap> g := Digraph([]);; gap> rotationSy := [];; gap> FacialWalks(g, rotationSy); From c03dc13e800b8352cad69315be8e49093e04c413 Mon Sep 17 00:00:00 2001 From: Meike Weiss Date: Fri, 8 May 2026 11:37:52 +0200 Subject: [PATCH 5/6] fix lint --- tst/standard/attr.tst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tst/standard/attr.tst b/tst/standard/attr.tst index 8d57c6901..d517d0985 100644 --- a/tst/standard/attr.tst +++ b/tst/standard/attr.tst @@ -1107,7 +1107,7 @@ gap> FacialWalks(CycleDigraph(3), [[4], [1], [3]]); Error, the 2nd argument (dense list ) is not a rotation system\ for the 1st argument (digraph ), expected its union to be the vertices of \ , -gap> g:=ChainDigraph(3);; +gap> g := ChainDigraph(3);; gap> FacialWalks(g, PlanarEmbedding(g)); [ [ 1, 2, 3, 2 ] ] gap> g := Digraph([]);; From 417cdcc4836c67aee6a4b1d6357520b1393e84d0 Mon Sep 17 00:00:00 2001 From: Meike Weiss Date: Fri, 8 May 2026 11:43:50 +0200 Subject: [PATCH 6/6] fix long line --- doc/planar.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/planar.xml b/doc/planar.xml index cdd86d49d..070941dff 100644 --- a/doc/planar.xml +++ b/doc/planar.xml @@ -258,12 +258,12 @@ gap> KuratowskiOuterPlanarSubdigraph(D); in . D := Digraph([[3, 5, 10], [8, 9, 10], [1, 4], [3, 6], +gap> D := Digraph([[3, 5, 10], [8, 9, 10], [1, 4], [3, 6], > [1, 7, 11], [4, 7], [6, 8], [2, 7], [2, 11], [1, 2], [5, 9]]); gap> PlanarEmbedding(D); -[ [ 3, 10, 5 ], [ 10, 8, 9 ], [ 4, 1 ], [ 6, 3 ], [ 1, 11, 7 ], [ 7, 4 ], - [ 5, 8, 6 ], [ 7, 2 ], [ 2, 11 ], [ 1, 2 ], [ 9, 5 ] ] +[ [ 3, 10, 5 ], [ 10, 8, 9 ], [ 4, 1 ], [ 6, 3 ], [ 1, 11, 7 ], + [ 7, 4 ], [ 5, 8, 6 ], [ 7, 2 ], [ 2, 11 ], [ 1, 2 ], [ 9, 5 ] ] gap> D := Digraph([[2, 4, 7, 9, 10], [1, 3, 4, 6, 9, 10], [6, 10], > [2, 5, 8, 9], [1, 2, 3, 4, 6, 7, 9, 10], [3, 4, 5, 7, 9, 10], > [3, 4, 5, 6, 9, 10], [3, 4, 5, 7, 9], [2, 3, 5, 6, 7, 8], [3, 5]]);