diff --git a/doc/attr.xml b/doc/attr.xml index c2cba764d..d6c47fdc0 100644 --- a/doc/attr.xml +++ b/doc/attr.xml @@ -1535,29 +1535,29 @@ 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 symmetric 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 and loops.

Here are some examples for planar embeddings: D1 := CycleDigraph(4);; +gap> D1 := DigraphSymmetricClosure(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 ] ] -gap> D2 := CompleteMultipartiteDigraph([2, 2, 2]);; +[ [ 1, 2, 3, 4 ], [ 1, 4, 3, 2 ] ] +gap> D2 := DigraphSymmetricClosure( +> CompleteMultipartiteDigraph([2, 2, 2]));; gap> rotationSystem := PlanarEmbedding(D2); [ [ 3, 5, 4, 6 ], [ 6, 4, 5, 3 ], [ 6, 2, 5, 1 ], [ 1, 5, 2, 6 ], [ 1, 3, 2, 4 ], [ 1, 4, 2, 3 ] ] @@ -1567,7 +1567,8 @@ gap> FacialWalks(D2, rotationSystem); ]]> Here is an example of a non-planar digraph with a corresponding rotation system: D3 := CompleteMultipartiteDigraph([3, 3]);; +gap> D3 := DigraphSymmetricClosure( +> CompleteMultipartiteDigraph([3, 3]));; gap> rot := [[6, 5, 4], [6, 5, 4], [6, 5, 4], [1, 2, 3], > [1, 2, 3], [1, 2, 3]]; [ [ 6, 5, 4 ], [ 6, 5, 4 ], [ 6, 5, 4 ], [ 1, 2, 3 ], [ 1, 2, 3 ], diff --git a/doc/planar.xml b/doc/planar.xml index b59071067..c9f704134 100644 --- a/doc/planar.xml +++ b/doc/planar.xml @@ -239,13 +239,13 @@ gap> KuratowskiOuterPlanarSubdigraph(D); A list or fail. - If digraph is a planar digraph, then PlanarEmbedding returns - the immutable list of lists of out-neighbours of digraph (excluding - multiple edges and loops) such that each vertex's neighbours are given in - clockwise order. If digraph is not planar, then fail is - returned.

+ If digraph is a planar symmetric digraph, then PlanarEmbedding + returns the immutable list of lists of out-neighbours of digraph + (excluding multiple edges and loops) such that each vertex's neighbours are + given in clockwise order. If digraph is not planar, then fail + is returned.

- The directions and multiplicities of any edges in digraph are ignored + The multiplicities of any edges in digraph are ignored by PlanarEmbedding.

@@ -258,29 +258,32 @@ gap> KuratowskiOuterPlanarSubdigraph(D); in . 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> D := DigraphSymmetricClosure(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 ] ] -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]]); - + [ 7, 4 ], [ 5, 8, 6 ], [ 7, 2 ], [ 2, 11 ], [ 1, 2 ], [ 9, 5 ] ] +gap> D := DigraphSymmetricClosure(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]])); + gap> PlanarEmbedding(D); fail -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> D := DigraphSymmetricClosure(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 ] ] -gap> D := Digraph(IsMutableDigraph, [[2, 4, 7, 9, 10], -> [1, 3, 4, 6, 9, 10], [6, 10], [2, 5, 8, 9], +[ [ 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 := DigraphSymmetricClosure(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], -> [3, 4, 5, 6, 9, 10], [3, 4, 5, 7, 9], [2, 3, 5, 6, 7, 8], [3, 5]]); - +> [3, 4, 5, 6, 9, 10], [3, 4, 5, 7, 9], [2, 3, 5, 6, 7, 8], [3, 5]])); + gap> PlanarEmbedding(D); fail ]]> @@ -433,13 +436,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..5025a453f 100644 --- a/gap/attr.gi +++ b/gap/attr.gi @@ -1859,8 +1859,8 @@ 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"); + if not IsSymmetricDigraph(D) then + ErrorNoReturn("the argument must be a symmetric digraph,"); fi; if Length(rotationSystem) <> DigraphNrVertices(D) diff --git a/gap/planar.gi b/gap/planar.gi index dbcee889e..a7a732f1b 100644 --- a/gap/planar.gi +++ b/gap/planar.gi @@ -44,6 +44,10 @@ end); InstallMethod(PlanarEmbedding, "for a digraph", [IsDigraph], function(D) + if not IsSymmetricDigraph(D) then + ErrorNoReturn("the argument must be a symmetric digraph,"); + fi; + D := DigraphMutableCopyIfMutable(D); if DIGRAPHS_HasTrivialRotationSystem(D) then; return OutNeighbors(D); fi; diff --git a/tst/standard/attr.tst b/tst/standard/attr.tst index 6105bfae1..d1108e071 100644 --- a/tst/standard/attr.tst +++ b/tst/standard/attr.tst @@ -1097,18 +1097,20 @@ 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), []); +gap> g := DigraphSymmetricClosure(CycleDigraph(3));; +gap> FacialWalks(g, []); Error, the 2nd argument (dense list ) is not a rotation system\ for the 1st argument (digraph ), expected a list of 3 lists, -gap> FacialWalks(CycleDigraph(3), [1]); +gap> FacialWalks(g, [1]); Error, the 2nd argument (dense list ) is not a rotation system\ for the 1st argument (digraph ), expected a list of 3 lists, -gap> FacialWalks(CycleDigraph(3), [[4], [1], [3]]); +gap> FacialWalks(g, [[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 := DigraphSymmetricClosure(ChainDigraph(3));; +gap> FacialWalks(g, PlanarEmbedding(g)); +[ [ 1, 2, 3, 2 ] ] gap> g := Digraph([]);; gap> rotationSy := [];; gap> FacialWalks(g, rotationSy); @@ -1117,14 +1119,14 @@ gap> g := Digraph([[2], [1, 3], [2, 4], [3]]);;; gap> rotationSy := [[2], [1, 3], [2, 4], [3]];; gap> FacialWalks(g, rotationSy); [ [ 1, 2, 3, 4, 3, 2 ] ] -gap> g := CycleDigraph(4);; +gap> g := DigraphSymmetricClosure(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 ] ] +[ [ 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 ], diff --git a/tst/standard/planar.tst b/tst/standard/planar.tst index 9a8020a30..ab54f8330 100644 --- a/tst/standard/planar.tst +++ b/tst/standard/planar.tst @@ -88,16 +88,16 @@ true 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); +gap> PlanarEmbedding(DigraphSymmetricClosure(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]]); gap> IsPlanarDigraph(D); false -gap> PlanarEmbedding(D); +gap> PlanarEmbedding(DigraphSymmetricClosure(D)); fail gap> D := NullDigraph(0);