From a20be561271fc4aa838bdc3fbeeaa83dbeb73ea6 Mon Sep 17 00:00:00 2001 From: Finn Smith Date: Mon, 20 Jan 2020 15:22:29 +0100 Subject: [PATCH 1/5] allow specifying colours in IsDigraphHomomorphism etc. --- doc/grahom.xml | 36 +++++++- doc/isomorph.xml | 25 ++++++ gap/grahom.gd | 24 +++++ gap/grahom.gi | 117 ++++++++++++++++++++---- gap/isomorph.gd | 9 +- gap/isomorph.gi | 34 +++++++ tst/standard/grahom.tst | 191 ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 417 insertions(+), 19 deletions(-) diff --git a/doc/grahom.xml b/doc/grahom.xml index 1c8076008..ce36022c8 100644 --- a/doc/grahom.xml +++ b/doc/grahom.xml @@ -565,9 +565,13 @@ gap> EmbeddingsDigraphs(D1, D2); <#GAPDoc Label="IsDigraphHomomorphism"> + + + + true or false. IsDigraphHomomorphism returns true if the permutation @@ -603,6 +607,20 @@ gap> EmbeddingsDigraphs(D1, D2); See also .

+ If col1 and col2, or col, are given then they must + represent vertex colourings; see for details of the permissible values for + these argument. The homomorphism must then also have the property: + + + + col[i] = col[i ^ x] for all vertices i of digraph, + in the case of IsDigraphEndomorphism. + + col1[i] = col2[i ^ x] for all vertices i of src, + in the cases of the other operations. + + src := Digraph([[1], [1, 2], [1, 3]]); @@ -616,8 +634,18 @@ gap> IsDigraphHomomorphism(src, ran, Transformation([3, 3, 3])); false gap> IsDigraphHomomorphism(src, src, Transformation([3, 3, 3])); true +gap> IsDigraphHomomorphism(src, ran, Transformation([1, 2, 2]), +> [1, 2, 2], [1, 2]); +true +gap> IsDigraphHomomorphism(src, ran, Transformation([1, 2, 2]), +> [2, 1, 1], [1, 2]); +false gap> IsDigraphEndomorphism(src, Transformation([3, 3, 3])); true +gap> IsDigraphEndomorphism(src, Transformation([3, 3, 3]), [1, 1, 1]); +true +gap> IsDigraphEndomorphism(src, Transformation([3, 3, 3]), [1, 1, 2]); +false gap> IsDigraphEpimorphism(src, ran, Transformation([3, 3, 3])); false gap> IsDigraphMonomorphism(src, ran, Transformation([1, 2, 2])); @@ -633,11 +661,13 @@ true]]> <#GAPDoc Label="IsDigraphEmbedding"> + true or false. IsDigraphEmbedding returns true if the permutation or transformation x is a embedding of the digraph - src into the digraph ran. + src into the digraph ran, while respecting the colourings + col1 and col2 if given.

A permutation or transformation x is a embedding of a digraph @@ -657,6 +687,10 @@ gap> IsDigraphMonomorphism(src, ran, ()); true gap> IsDigraphEmbedding(src, ran, ()); true +gap> IsDigraphEmbedding(src, ran, (), [2, 1], [2, 1, 1]); +true +gap> IsDigraphEmbedding(src, ran, (), [2, 1], [1, 2, 1]); +false gap> ran := Digraph([[1, 2], [1, 2], [1, 3]]); gap> IsDigraphMonomorphism(src, ran, IdentityTransformation); diff --git a/doc/isomorph.xml b/doc/isomorph.xml index 96a5d4006..8d3796198 100644 --- a/doc/isomorph.xml +++ b/doc/isomorph.xml @@ -753,7 +753,9 @@ gap> OutNeighbours(canon); <#GAPDoc Label="IsDigraphAutomorphism"> + + true or false. IsDigraphIsomorphism returns true if the permutation or @@ -783,6 +785,21 @@ gap> OutNeighbours(canon); See also .

+ + + If col1 and col2, or col, are given then they must + represent vertex colourings; see for details of the permissible values for + these argument. The homomorphism must then also have the property: + + + + col1[i] = col2[i ^ x] for all vertices i of src, + for IsDigraphIsomorphism. + + col[i] = col[i ^ x] for all vertices i of digraph, + for IsDigraphAutomorphism. + For some digraphs, it can be faster to use IsDigraphAutomorphism than to test membership in the automorphism group of digraph. @@ -794,6 +811,10 @@ gap> IsDigraphAutomorphism(src, (1, 2, 3)); false gap> IsDigraphAutomorphism(src, (2, 3)); true +gap> IsDigraphAutomorphism(src, (2, 3), [2, 1, 1]); +true +gap> IsDigraphAutomorphism(src, (2, 3), [2, 2, 1]); +false gap> IsDigraphAutomorphism(src, (2, 3)(4, 5)); false gap> IsDigraphAutomorphism(src, (1, 4)); @@ -810,6 +831,10 @@ gap> IsDigraphIsomorphism(ran, src, (1, 2)); true gap> IsDigraphIsomorphism(src, Digraph([[3], [1, 3], [2]]), (1, 2, 3)); false +gap> IsDigraphIsomorphism(src, ran, (1, 2), [1, 2, 3], [2, 1, 3]); +true +gap> IsDigraphIsomorphism(src, ran, (1, 2), [1, 2, 2], [2, 1, 3]); +false ]]> diff --git a/gap/grahom.gd b/gap/grahom.gd index 82e0634f1..7bfd16d20 100644 --- a/gap/grahom.gd +++ b/gap/grahom.gd @@ -43,10 +43,20 @@ DeclareOperation("IsDigraphEndomorphism", [IsDigraph, IsTransformation]); DeclareOperation("IsDigraphHomomorphism", [IsDigraph, IsDigraph, IsTransformation]); +DeclareOperation("IsDigraphEndomorphism", + [IsDigraph, IsTransformation, IsList]); +DeclareOperation("IsDigraphHomomorphism", + [IsDigraph, IsDigraph, IsTransformation, IsList, IsList]); + DeclareOperation("IsDigraphEndomorphism", [IsDigraph, IsPerm]); DeclareOperation("IsDigraphHomomorphism", [IsDigraph, IsDigraph, IsPerm]); +DeclareOperation("IsDigraphEndomorphism", + [IsDigraph, IsPerm, IsList]); +DeclareOperation("IsDigraphHomomorphism", + [IsDigraph, IsDigraph, IsPerm, IsList, IsList]); + DeclareOperation("IsDigraphEpimorphism", [IsDigraph, IsDigraph, IsTransformation]); DeclareOperation("IsDigraphMonomorphism", @@ -54,6 +64,13 @@ DeclareOperation("IsDigraphMonomorphism", DeclareOperation("IsDigraphEmbedding", [IsDigraph, IsDigraph, IsTransformation]); +DeclareOperation("IsDigraphEpimorphism", + [IsDigraph, IsDigraph, IsTransformation, IsList, IsList]); +DeclareOperation("IsDigraphMonomorphism", + [IsDigraph, IsDigraph, IsTransformation, IsList, IsList]); +DeclareOperation("IsDigraphEmbedding", + [IsDigraph, IsDigraph, IsTransformation, IsList, IsList]); + DeclareOperation("IsDigraphEpimorphism", [IsDigraph, IsDigraph, IsPerm]); DeclareOperation("IsDigraphMonomorphism", @@ -61,5 +78,12 @@ DeclareOperation("IsDigraphMonomorphism", DeclareOperation("IsDigraphEmbedding", [IsDigraph, IsDigraph, IsPerm]); +DeclareOperation("IsDigraphEpimorphism", + [IsDigraph, IsDigraph, IsPerm, IsList, IsList]); +DeclareOperation("IsDigraphMonomorphism", + [IsDigraph, IsDigraph, IsPerm, IsList, IsList]); +DeclareOperation("IsDigraphEmbedding", + [IsDigraph, IsDigraph, IsPerm, IsList, IsList]); + DeclareOperation("IsDigraphColouring", [IsDigraph, IsList]); DeclareOperation("IsDigraphColouring", [IsDigraph, IsTransformation]); diff --git a/gap/grahom.gi b/gap/grahom.gi index 44f4ed08c..3d2fbdacd 100644 --- a/gap/grahom.gi +++ b/gap/grahom.gi @@ -454,27 +454,20 @@ end); InstallMethod(IsDigraphHomomorphism, "for a digraph by out-neighbours, a digraph, and a perm", [IsDigraphByOutNeighboursRep, IsDigraph, IsPerm], -function(src, ran, x) - local i, j; - if IsMultiDigraph(src) or IsMultiDigraph(ran) then - ErrorNoReturn("the 1st and 2nd arguments and must be digraphs", - " with no multiple edges,"); - elif LargestMovedPoint(x) > DigraphNrVertices(src) then - return false; - fi; - for i in DigraphVertices(src) do - for j in OutNeighbours(src)[i] do - if not IsDigraphEdge(ran, i ^ x, j ^ x) then - return false; - fi; - od; - od; - return true; -end); +{src, ran, x} -> IsDigraphHomomorphism(src, ran, AsTransformation(x))); + +InstallMethod(IsDigraphHomomorphism, +"for a digraph by out-neighbours, a digraph, a perm, and two lists", +[IsDigraphByOutNeighboursRep, IsDigraph, IsPerm, IsList, IsList], +{src, ran, x, c1, c2} -> +IsDigraphHomomorphism(src, ran, AsTransformation(x), c1, c2)); InstallMethod(IsDigraphEndomorphism, "for a digraph and a perm", [IsDigraph, IsPerm], IsDigraphAutomorphism); +InstallMethod(IsDigraphEndomorphism, "for a digraph and a perm", +[IsDigraph, IsPerm, IsList], IsDigraphAutomorphism); + InstallMethod(IsDigraphHomomorphism, "for a digraph by out-neighbours, digraph, and transformation", [IsDigraphByOutNeighboursRep, IsDigraph, IsTransformation], @@ -496,10 +489,29 @@ function(src, ran, x) return true; end); +InstallMethod(IsDigraphHomomorphism, +"for a digraph by out-neighbours, a digraph, a transformation, and two lists", +[IsDigraphByOutNeighboursRep, IsDigraph, IsTransformation, IsList, IsList], +function(src, ran, x, colours1, colours2) + if not IsDigraphHomomorphism(src, ran, x) then + return false; + fi; + + DIGRAPHS_ValidateVertexColouring(DigraphNrVertices(src), colours1); + DIGRAPHS_ValidateVertexColouring(DigraphNrVertices(ran), colours2); + + return ForAll(DigraphVertices(src), i -> colours1[i] = colours2[i ^ x]); +end); + InstallMethod(IsDigraphEndomorphism, "for a digraph and a transformation", [IsDigraph, IsTransformation], {D, x} -> IsDigraphHomomorphism(D, D, x)); +InstallMethod(IsDigraphEndomorphism, +"for a digraph, transformation, and a list", +[IsDigraph, IsTransformation, IsList], +{D, x, c} -> IsDigraphHomomorphism(D, D, x, c, c)); + InstallMethod(IsDigraphEpimorphism, "for digraph, digraph, and transformation", [IsDigraph, IsDigraph, IsTransformation], function(src, ran, x) @@ -507,6 +519,13 @@ function(src, ran, x) and OnSets(DigraphVertices(src), x) = DigraphVertices(ran); end); +InstallMethod(IsDigraphEpimorphism, "for digraph, digraph, and transformation", +[IsDigraph, IsDigraph, IsTransformation, IsList, IsList], +function(src, ran, x, c1, c2) + return IsDigraphHomomorphism(src, ran, x, c1, c2) + and OnSets(DigraphVertices(src), x) = DigraphVertices(ran); +end); + InstallMethod(IsDigraphEpimorphism, "for digraph, digraph, and perm", [IsDigraph, IsDigraph, IsPerm], function(src, ran, x) @@ -514,6 +533,14 @@ function(src, ran, x) and OnSets(DigraphVertices(src), x) = DigraphVertices(ran); end); +InstallMethod(IsDigraphEpimorphism, +"for digraph, digraph, perm, list, and list", +[IsDigraph, IsDigraph, IsPerm, IsList, IsList], +function(src, ran, x, c1, c2) + return IsDigraphHomomorphism(src, ran, x, c1, c2) + and OnSets(DigraphVertices(src), x) = DigraphVertices(ran); +end); + InstallMethod(IsDigraphMonomorphism, "for digraph, digraph, and transformation", [IsDigraph, IsDigraph, IsTransformation], @@ -522,9 +549,43 @@ function(src, ran, x) and IsInjectiveListTrans(DigraphVertices(src), x); end); +InstallMethod(IsDigraphMonomorphism, +"for digraph, digraph, transformation, list, list", +[IsDigraph, IsDigraph, IsTransformation, IsList, IsList], +function(src, ran, x, c1, c2) + return IsDigraphHomomorphism(src, ran, x, c1, c2) + and IsInjectiveListTrans(DigraphVertices(src), x); +end); + InstallMethod(IsDigraphMonomorphism, "for digraph, digraph, and perm", [IsDigraph, IsDigraph, IsPerm], IsDigraphHomomorphism); +InstallMethod(IsDigraphMonomorphism, "for digraph, digraph, perm, list, list", +[IsDigraph, IsDigraph, IsPerm, IsList, IsList], IsDigraphHomomorphism); + +InstallMethod(IsDigraphEmbedding, +"for digraph, digraph by out-neighbours, transformation, list, and list", +[IsDigraph, IsDigraphByOutNeighboursRep, IsTransformation, IsList, IsList], +function(src, ran, x, c1, c2) + local y, induced, i, j; + if not IsDigraphMonomorphism(src, ran, x, c1, c2) then + return false; + fi; + y := MappingPermListList(OnTuples(DigraphVertices(src), x), + DigraphVertices(src)); + induced := BlistList(DigraphVertices(ran), OnSets(DigraphVertices(src), x)); + for i in DigraphVertices(ran) do + if induced[i] then + for j in OutNeighbours(ran)[i] do + if induced[j] and not IsDigraphEdge(src, i ^ y, j ^ y) then + return false; + fi; + od; + fi; + od; + return true; +end); + InstallMethod(IsDigraphEmbedding, "for digraph, digraph by out-neighbours, and transformation", [IsDigraph, IsDigraphByOutNeighboursRep, IsTransformation], @@ -570,6 +631,28 @@ function(src, ran, x) return true; end); +InstallMethod(IsDigraphEmbedding, +"for a digraph, a digraph by out-neighbours, a perm, a list, and a list", +[IsDigraph, IsDigraphByOutNeighboursRep, IsPerm, IsList, IsList], +function(src, ran, x, c1, c2) + local y, induced, i, j; + if not IsDigraphHomomorphism(src, ran, x, c1, c2) then + return false; + fi; + y := x ^ -1; + induced := BlistList(DigraphVertices(ran), OnSets(DigraphVertices(src), x)); + for i in DigraphVertices(ran) do + if induced[i] then + for j in OutNeighbours(ran)[i] do + if induced[j] and not IsDigraphEdge(src, i ^ y, j ^ y) then + return false; + fi; + od; + fi; + od; + return true; +end); + InstallMethod(IsDigraphColouring, "for a digraph by out-neighbours and a list", [IsDigraphByOutNeighboursRep, IsHomogeneousList], function(D, colours) diff --git a/gap/isomorph.gd b/gap/isomorph.gd index aa21a04dc..30301bbe7 100644 --- a/gap/isomorph.gd +++ b/gap/isomorph.gd @@ -57,7 +57,14 @@ DeclareGlobalFunction("DIGRAPHS_ValidateEdgeColouring"); DeclareGlobalFunction("DIGRAPHS_CollapseMultiColouredEdges"); DeclareOperation("IsDigraphAutomorphism", [IsDigraph, IsPerm]); -DeclareOperation("IsDigraphIsomorphism", [IsDigraph, IsDigraph, IsPerm]); +DeclareOperation("IsDigraphAutomorphism", [IsDigraph, IsPerm, IsList]); DeclareOperation("IsDigraphAutomorphism", [IsDigraph, IsTransformation]); +DeclareOperation("IsDigraphAutomorphism", [IsDigraph, IsTransformation, IsList]); + +DeclareOperation("IsDigraphIsomorphism", [IsDigraph, IsDigraph, IsPerm]); +DeclareOperation("IsDigraphIsomorphism", + [IsDigraph, IsDigraph, IsPerm, IsList, IsList]); DeclareOperation("IsDigraphIsomorphism", [IsDigraph, IsDigraph, IsTransformation]); +DeclareOperation("IsDigraphIsomorphism", + [IsDigraph, IsDigraph, IsTransformation, IsList, IsList]); diff --git a/gap/isomorph.gi b/gap/isomorph.gi index a5e811719..bc817e1a0 100644 --- a/gap/isomorph.gi +++ b/gap/isomorph.gi @@ -718,10 +718,27 @@ function(src, ran, x) and IsDigraphHomomorphism(ran, src, x ^ -1); end); +InstallMethod(IsDigraphIsomorphism, +"for digraph, digraph, permutation, list, and list", +[IsDigraph, IsDigraph, IsPerm, IsList, IsList], +function(src, ran, x, c1, c2) + if IsMultiDigraph(src) or IsMultiDigraph(ran) then + ErrorNoReturn("the 1st and 2nd arguments and must not have ", + "multiple edges,"); + fi; + return IsDigraphHomomorphism(src, ran, x, c1, c2) + and IsDigraphHomomorphism(ran, src, x ^ -1, c1, c2); +end); + InstallMethod(IsDigraphAutomorphism, "for a digraph and a permutation", [IsDigraph, IsPerm], {D, x} -> IsDigraphIsomorphism(D, D, x)); +InstallMethod(IsDigraphAutomorphism, +"for a digraph, a permutation, and a list", +[IsDigraph, IsPerm, IsList], +{D, x, c} -> IsDigraphIsomorphism(D, D, x, c, c)); + InstallMethod(IsDigraphIsomorphism, "for digraph, digraph, and transformation", [IsDigraph, IsDigraph, IsTransformation], function(src, ran, x) @@ -733,6 +750,23 @@ function(src, ran, x) return IsDigraphIsomorphism(src, ran, y); end); +InstallMethod(IsDigraphIsomorphism, +"for digraph, digraph, transformation, list, and list", +[IsDigraph, IsDigraph, IsTransformation, IsList, IsList], +function(src, ran, x, c1, c2) + local y; + y := AsPermutation(RestrictedTransformation(x, DigraphVertices(src))); + if y = fail then + return false; + fi; + return IsDigraphIsomorphism(src, ran, y, c1, c2); +end); + InstallMethod(IsDigraphAutomorphism, "for a digraph and a transformation", [IsDigraph, IsTransformation], {D, x} -> IsDigraphIsomorphism(D, D, x)); + +InstallMethod(IsDigraphAutomorphism, +"for a digraph, a transformation, and a list", +[IsDigraph, IsTransformation, IsList], +{D, x, c} -> IsDigraphIsomorphism(D, D, x, c, c)); diff --git a/tst/standard/grahom.tst b/tst/standard/grahom.tst index d7db0fef2..f7dba5582 100644 --- a/tst/standard/grahom.tst +++ b/tst/standard/grahom.tst @@ -2140,6 +2140,197 @@ gap> GeneratorsOfEndomorphismMonoid(gr); [ Transformation( [ 2, 3, 4, 5, 1 ] ), Transformation( [ 2, 1 ] ), IdentityTransformation ] +# IsHomomorphism etc. for vertex-coloured digraphs +gap> gr1 := Digraph([[], []]); + +gap> gr2 := Digraph([[], [1]]); + +gap> IsDigraphAutomorphism(gr1, Transformation([1, 2])); +true +gap> IsDigraphAutomorphism(gr1, Transformation([1, 2]), [1, 2]); +true +gap> IsDigraphAutomorphism(gr2, Transformation([1, 2]), [1, 1]); +true +gap> IsDigraphHomomorphism(gr1, gr2, Transformation([1, 2])); +true +gap> IsDigraphHomomorphism(gr1, gr2, Transformation([1, 2]), [1, 2], [1, 1]); +false +gap> IsDigraphHomomorphism(gr1, gr2, Transformation([1, 2]), [1, 1], [1, 1]); +true +gap> IsDigraphHomomorphism(gr1, gr2, Transformation([1, 2]), [1, 1], [1, 2]); +false +gap> gr1 := Digraph([[], []]); + +gap> gr1 := ChainDigraph(3); + +gap> gr2 := ChainDigraph(6); + +gap> IsDigraphHomomorphism(gr1, gr2, Transformation([1, 2, 3]), [1 .. 3], [1 .. 6]); +true +gap> IsDigraphHomomorphism(gr1, gr2, Transformation([1, 2, 3]), [1 .. 3], [1, 1, 2, 3, 4, 5]); +false +gap> IsDigraphHomomorphism(gr1, gr2, Transformation([1, 2, 3]), +> [2, 2, 1], [2, 2, 1, 3, 4, 5]); +true +gap> IsDigraphHomomorphism(gr1, gr2, Transformation([1, 2, 3]), +> [2, 2, 1], [1, 1, 2, 3, 4, 5]); +false +gap> IsDigraphAutomorphism(gr1, Transformation([3, 2, 1]), [1, 2, 3]); +false +gap> gr1 := CycleDigraph(6); + +gap> x := (1, 2, 3, 4, 5, 6); +(1,2,3,4,5,6) +gap> t := AsTransformation(x); +Transformation( [ 2, 3, 4, 5, 6, 1 ] ) +gap> IsDigraphAutomorphism(gr1, x, [1 .. 6]); +false +gap> IsDigraphAutomorphism(gr1, x, [1, 1, 2, 2, 3, 3]); +false +gap> IsDigraphAutomorphism(gr1, x, [1, 1, 1, 1, 1, 1]); +true +gap> IsDigraphAutomorphism(gr1, x, [1, 1, 2, 2, 3, 3]); +false +gap> IsDigraphAutomorphism(gr1, x^2, [1, 1, 2, 2, 3, 3]); +false +gap> IsDigraphAutomorphism(gr1, x^2, [1, 2, 2, 3, 4, 4]); +false +gap> IsDigraphAutomorphism(gr1, x^2, [1, 1, 1, 1, 1, 1]); +true +gap> IsDigraphAutomorphism(gr1, x^3, [1, 2, 2, 3, 4, 4]); +false +gap> IsDigraphAutomorphism(gr1, x^3, [1, 1, 1, 1, 1, 1]); +true +gap> IsDigraphAutomorphism(gr1, t, [1 .. 6]); +false +gap> IsDigraphAutomorphism(gr1, t, [1, 1, 2, 2, 3, 3]); +false +gap> IsDigraphAutomorphism(gr1, t^2, [1, 1, 2, 2, 3, 3]); +false +gap> IsDigraphAutomorphism(gr1, t^2, [1, 2, 2, 3, 4, 4]); +false +gap> IsDigraphAutomorphism(gr1, t^3, [1, 2, 2, 3, 4, 4]); +false +gap> gr1 := DigraphFromDigraph6String("&D~~~~_"); + +gap> ForAll(AutomorphismGroup(gr1), +> x -> x = () or not IsDigraphAutomorphism(gr1, x, [1 .. 5])); +true +gap> ForAll(AutomorphismGroup(gr1), +> x -> IsDigraphAutomorphism(gr1, x, [1, 1, 1, 1, 1])); +true + +# IsDigraphEndomorphism, for vertex-coloured digraphs +gap> gr1 := DigraphTransitiveClosure(CompleteDigraph(2)); + +gap> IsDigraphEndomorphism(gr1, (1, 2), [1, 2]); +false +gap> IsDigraphEndomorphism(gr1, (1, 2), [1, 1]); +true +gap> IsDigraphEndomorphism(gr1, Transformation([1, 1]), [1, 2]); +false +gap> IsDigraphEndomorphism(gr1, Transformation([1, 1]), [1, 1]); +true +gap> ForAll(GeneratorsOfEndomorphismMonoid(gr1), +> x -> IsDigraphEndomorphism(gr1, x, [1, 1])); +true +gap> gr2 := Digraph([[3, 4], [1, 3], [4], [1, 2, 3, 5], [2]]); + +gap> ForAll(GeneratorsOfEndomorphismMonoid(gr2), +> x -> IsDigraphEndomorphism(gr2, x, [1, 1, 1, 1, 1])); +true +gap> gr1 := DigraphFromDigraph6String("&D~~~~_"); + +gap> ForAll(GeneratorsOfEndomorphismMonoid(gr1), +> x -> IsDigraphEndomorphism(gr1, x, [1, 1, 1, 1, 1])); +true +gap> ForAll(AutomorphismGroup(gr1), +> x -> IsDigraphEndomorphism(gr1, x, [1, 1, 1, 1, 1])); +true + +# IsDigraphEpimorphism, for vertex-coloured digraphs +gap> src := Digraph([[1], [1, 2], [1, 3]]); + +gap> ran := Digraph([[1], [1, 2]]); + +gap> IsDigraphEpimorphism(src, ran, Transformation([1, 2, 2]), [1, 2, 2], [1, 2]); +true +gap> IsDigraphEpimorphism(src, ran, Transformation([1, 2, 2]), [1, 2, 3], [1, 2]); +false +gap> IsDigraphEpimorphism(src, src, Transformation([1, 2, 3]), +> [1, 1, 2], [1, 1,2]); +true +gap> IsDigraphEpimorphism(src, src, Transformation([1, 2, 3]), +> [1, 2, 3], [1, 1,2]); +false +gap> IsDigraphEpimorphism(src, src, (), [1, 2, 2], [1, 2, 2]); +true +gap> IsDigraphEpimorphism(src, src, (2, 3), [1, 2, 3], [2, 3, 1]); +false +gap> IsDigraphEpimorphism(src, src, (2, 3), [2, 1, 3], [2, 3, 1]); +true + +# IsDigraphMonomorphism, for vertex-coloured digraphs +gap> src := Digraph([[1], [1, 2], [1, 3]]); + +gap> ran := Digraph([[1], [1, 2]]); + +gap> IsDigraphMonomorphism(src, src, Transformation([1, 3, 2]), +> [2, 3, 1], [2, 1, 3]); +true +gap> IsDigraphMonomorphism(src, src, Transformation([1, 3, 2]), +> [2, 3, 1], [2, 3, 1]); +false +gap> IsDigraphMonomorphism(src, src, Transformation([1, 2, 3]), +> [2, 1, 1], [1, 2, 2]); +false +gap> IsDigraphMonomorphism(src, src, Transformation([1, 2, 3]), +> [1, 2, 2], [1, 2, 2]); +true +gap> IsDigraphMonomorphism(ran, src, Transformation([1, 2]), +> [2, 1], [1, 2, 1]); +false +gap> IsDigraphMonomorphism(ran, src, Transformation([1, 2]), +> [2, 1], [1, 1, 1]); +false +gap> IsDigraphMonomorphism(ran, src, Transformation([1, 2]), +> [1, 1], [1, 1, 2]); +true +gap> IsDigraphMonomorphism(src, src, (), [1, 2, 2], [1, 2, 2]); +true +gap> IsDigraphMonomorphism(src, src, (), [1, 1, 2], [1, 2, 2]); +false +gap> IsDigraphMonomorphism(ran, src, (), [1, 1], [1, 1, 2]); +true +gap> IsDigraphMonomorphism(ran, src, (), [1, 1], [2, 2, 1]); +false +gap> IsDigraphMonomorphism(ran, src, (), [1, 2], [1, 2, 1]); +true + +# IsDigraphEmbedding, for vertex-coloured digraphs +gap> src := Digraph([[1], [1, 2], [1, 3]]); + +gap> ran := Digraph([[1], [1, 2]]); + +gap> IsDigraphEmbedding(src, src, Transformation([1, 2, 3]), +> [1, 1, 1], [1, 1, 1]); +true +gap> IsDigraphEmbedding(src, src, Transformation([1, 2, 3]), +> [1, 1, 2], [1, 1, 2]); +true +gap> IsDigraphEmbedding(ran, src, Transformation([1, 2])); +true +gap> IsDigraphEmbedding(src, src, (), [1, 1, 1], [1, 1, 1]); +true +gap> IsDigraphEmbedding(src, src, (), [2, 1, 1], [1, 1, 1]); +false +gap> IsDigraphEmbedding(ran, src, (), [1, 1], [1, 1, 2]); +true +gap> IsDigraphEmbedding(ran, src, (), [2, 1], [1, 2, 2]); +false +gap> IsDigraphEmbedding(ran, src, (), [2, 1], [1, 1, 2]); +false + # DIGRAPHS_UnbindVariables gap> Unbind(edges); gap> Unbind(epis); From 6b94e2e850e92879eb7abefdc7d6be306dd9044f Mon Sep 17 00:00:00 2001 From: Finn Smith Date: Tue, 21 Jan 2020 16:09:53 +0000 Subject: [PATCH 2/5] linting and coverage --- tst/standard/grahom.tst | 20 ++++++++--------- tst/standard/isomorph.tst | 47 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 10 deletions(-) diff --git a/tst/standard/grahom.tst b/tst/standard/grahom.tst index f7dba5582..ea69f77d8 100644 --- a/tst/standard/grahom.tst +++ b/tst/standard/grahom.tst @@ -2191,25 +2191,25 @@ gap> IsDigraphAutomorphism(gr1, x, [1, 1, 1, 1, 1, 1]); true gap> IsDigraphAutomorphism(gr1, x, [1, 1, 2, 2, 3, 3]); false -gap> IsDigraphAutomorphism(gr1, x^2, [1, 1, 2, 2, 3, 3]); +gap> IsDigraphAutomorphism(gr1, x ^ 2, [1, 1, 2, 2, 3, 3]); false -gap> IsDigraphAutomorphism(gr1, x^2, [1, 2, 2, 3, 4, 4]); +gap> IsDigraphAutomorphism(gr1, x ^ 2, [1, 2, 2, 3, 4, 4]); false -gap> IsDigraphAutomorphism(gr1, x^2, [1, 1, 1, 1, 1, 1]); +gap> IsDigraphAutomorphism(gr1, x ^ 2, [1, 1, 1, 1, 1, 1]); true -gap> IsDigraphAutomorphism(gr1, x^3, [1, 2, 2, 3, 4, 4]); +gap> IsDigraphAutomorphism(gr1, x ^ 3, [1, 2, 2, 3, 4, 4]); false -gap> IsDigraphAutomorphism(gr1, x^3, [1, 1, 1, 1, 1, 1]); +gap> IsDigraphAutomorphism(gr1, x ^ 3, [1, 1, 1, 1, 1, 1]); true gap> IsDigraphAutomorphism(gr1, t, [1 .. 6]); false gap> IsDigraphAutomorphism(gr1, t, [1, 1, 2, 2, 3, 3]); false -gap> IsDigraphAutomorphism(gr1, t^2, [1, 1, 2, 2, 3, 3]); +gap> IsDigraphAutomorphism(gr1, t ^ 2, [1, 1, 2, 2, 3, 3]); false -gap> IsDigraphAutomorphism(gr1, t^2, [1, 2, 2, 3, 4, 4]); +gap> IsDigraphAutomorphism(gr1, t ^ 2, [1, 2, 2, 3, 4, 4]); false -gap> IsDigraphAutomorphism(gr1, t^3, [1, 2, 2, 3, 4, 4]); +gap> IsDigraphAutomorphism(gr1, t ^ 3, [1, 2, 2, 3, 4, 4]); false gap> gr1 := DigraphFromDigraph6String("&D~~~~_"); @@ -2258,10 +2258,10 @@ true gap> IsDigraphEpimorphism(src, ran, Transformation([1, 2, 2]), [1, 2, 3], [1, 2]); false gap> IsDigraphEpimorphism(src, src, Transformation([1, 2, 3]), -> [1, 1, 2], [1, 1,2]); +> [1, 1, 2], [1, 1, 2]); true gap> IsDigraphEpimorphism(src, src, Transformation([1, 2, 3]), -> [1, 2, 3], [1, 1,2]); +> [1, 2, 3], [1, 1, 2]); false gap> IsDigraphEpimorphism(src, src, (), [1, 2, 2], [1, 2, 2]); true diff --git a/tst/standard/isomorph.tst b/tst/standard/isomorph.tst index 4b4a4af25..5cc08a2d6 100644 --- a/tst/standard/isomorph.tst +++ b/tst/standard/isomorph.tst @@ -950,6 +950,53 @@ h), where graph is the 1st argument, gap> BlissAutomorphismGroup(gr, fail, [[1], [1, 1], [1]]) = Group([(1, 3)]); true +# IsDigraphIsomorphism +gap> gr1 := Digraph([[2, 3, 4], [1, 3, 4], [1, 2], [1, 2]]); + +gap> IsDigraphIsomorphism(gr1, gr1, (1, 2)); +true +gap> IsDigraphIsomorphism(gr1, gr1, (1, 2)(3, 4)); +true +gap> gr2 := Digraph([[2, 3, 4, 4], [1, 3, 4], [1, 2], [1, 2]]); + +gap> IsDigraphIsomorphism(gr1, gr2, (1, 2)); +Error, the 1st and 2nd arguments and must not have multiple edges, +gap> IsDigraphIsomorphism(gr2, gr1, (1, 2)); +Error, the 1st and 2nd arguments and must not have multiple edges, +gap> IsDigraphIsomorphism(gr1, gr1, Transformation([2, 1, 4, 3, 6, 5])); +true +gap> IsDigraphIsomorphism(gr1, gr1, Transformation([2, 1, 3, 5, 4, 6])); +false +gap> gr := NullDigraph(5);; +gap> ForAll(AutomorphismGroup(gr), +> x -> IsDigraphAutomorphism(gr, x, [1, 1, 1, 1, 1])); +true +gap> Number(AutomorphismGroup(gr), +> x -> IsDigraphAutomorphism(gr, x, [1, 2, 3, 4, 5])); +1 +gap> gr2 := CycleDigraph(6); + +gap> t := Transformation([2, 3, 4, 5, 6, 1, 8, 7]); +Transformation( [ 2, 3, 4, 5, 6, 1, 8, 7 ] ) +gap> ForAll([1 .. 6], +> i -> IsDigraphAutomorphism(gr2, +> t ^ i, +> [1, 1, 1, 1, 1, 1])); +true +gap> ForAll([2, 4, 6], +> i -> IsDigraphAutomorphism(gr2, +> t ^ i, +> [1, 2, 1, 2, 1, 2])); +true +gap> IsDigraphAutomorphism(gr2, t ^ 3, [1, 2, 3, 1, 2, 3]); +true +gap> gr3 := CycleDigraph(5);; +gap> Number(FullTransformationMonoid(5), +> t -> IsDigraphAutomorphism(gr3, +> t, +> [1, 1, 1, 1, 1])); +5 + # DIGRAPHS_UnbindVariables gap> Unbind(canon); gap> Unbind(D); From 3b52ce203687d7ac4a64b93b70f68c610e5162e0 Mon Sep 17 00:00:00 2001 From: Finn Smith Date: Thu, 23 Jan 2020 14:18:35 +0000 Subject: [PATCH 3/5] refactor --- doc/grahom.xml | 28 ++++++++++++ doc/isomorph.xml | 4 +- doc/z-chap6.xml | 1 + gap/grahom.gd | 5 +++ gap/grahom.gi | 114 +++++++++++++++++++++++------------------------ gap/isomorph.gi | 20 +++------ 6 files changed, 98 insertions(+), 74 deletions(-) diff --git a/doc/grahom.xml b/doc/grahom.xml index ce36022c8..b4cf042d4 100644 --- a/doc/grahom.xml +++ b/doc/grahom.xml @@ -621,6 +621,8 @@ gap> EmbeddingsDigraphs(D1, D2); in the cases of the other operations. + See also . + src := Digraph([[1], [1, 2], [1, 3]]); @@ -744,3 +746,29 @@ true <#/GAPDoc> + +<#GAPDoc Label="DigraphsRespectsColouring"> + + + true or false. + + The operation DigraphsRespectsColouring verifies whether or not + the permutation or transformation x respects the vertex colourings + col1 and col2 of the digraphs src and range. + That is, DigraphsRespectsColouring returns true if and only if for + all vertices i of src, col1[i] = col2[i ^ x]. +

+ + src := Digraph([[1], [1, 2]]); + +gap> ran := Digraph([[1], [1, 2], [1, 3]]); + +gap> DigraphsRespectsColouring(src, ran, (1, 2), [2, 1], [1, 2, 1]); +true +gap> DigraphsRespectsColouring(src, ran, (1, 2), [2, 1], [2, 1, 1]); +false +]]> + + +<#/GAPDoc> diff --git a/doc/isomorph.xml b/doc/isomorph.xml index 8d3796198..d7e136265 100644 --- a/doc/isomorph.xml +++ b/doc/isomorph.xml @@ -787,10 +787,10 @@ gap> OutNeighbours(canon); />.

- If col1 and col2, or col, are given then they must + If col1 and col2, or col, are given, then they must represent vertex colourings; see for details of the permissible values for - these argument. The homomorphism must then also have the property: + these arguments. The homomorphism must then also have the property: diff --git a/doc/z-chap6.xml b/doc/z-chap6.xml index 637ff97d3..c8931052c 100644 --- a/doc/z-chap6.xml +++ b/doc/z-chap6.xml @@ -62,6 +62,7 @@ from} $E_a$ \emph{to} $E_b$. In this case we say that $E_a$ and $E_b$ are <#Include Label="EmbeddingsDigraphs"> <#Include Label="IsDigraphHomomorphism"> <#Include Label="IsDigraphEmbedding"> + <#Include Label="DigraphsRespectsColouring"> <#Include Label="GeneratorsOfEndomorphismMonoid"> <#Include Label="DigraphColouring"> <#Include Label="DigraphGreedyColouring"> diff --git a/gap/grahom.gd b/gap/grahom.gd index 7bfd16d20..1817be489 100644 --- a/gap/grahom.gd +++ b/gap/grahom.gd @@ -87,3 +87,8 @@ DeclareOperation("IsDigraphEmbedding", DeclareOperation("IsDigraphColouring", [IsDigraph, IsList]); DeclareOperation("IsDigraphColouring", [IsDigraph, IsTransformation]); + +DeclareOperation("DigraphsRespectsColouring", + [IsDigraph, IsDigraph, IsTransformation, IsList, IsList]); +DeclareOperation("DigraphsRespectsColouring", + [IsDigraph, IsDigraph, IsPerm, IsList, IsList]); diff --git a/gap/grahom.gi b/gap/grahom.gi index 3d2fbdacd..d3d3afd40 100644 --- a/gap/grahom.gi +++ b/gap/grahom.gi @@ -451,6 +451,35 @@ end); # IsDigraph{Homo/Epi/...}morphism ######################################################################## +# Given: +# +# 1) two digraphs and , +# 2) a transformation mapping the vertices of to , and +# 3) two lists and of positive integers defining vertex +# colourings of and , +# +# this operation tests whether respects the colouring, i.e. whether for all +# vertices i in , cols[i] = cols[i ^ x]. +InstallMethod(DigraphsRespectsColouring, +[IsDigraph, IsDigraph, IsTransformation, IsList, IsList], +function(src, ran, x, cols1, cols2) + if Maximum(OnTuples(DigraphVertices(src), x)) > DigraphNrVertices(ran) then + ErrorNoReturn("the third argument must map the vertices of the first ", + "argument into the vertices of the second argument ", + ","); + fi; + DIGRAPHS_ValidateVertexColouring(DigraphNrVertices(src), cols1); + DIGRAPHS_ValidateVertexColouring(DigraphNrVertices(ran), cols2); + + return ForAll(DigraphVertices(src), i -> cols1[i] = cols2[i ^ x]); +end); + +InstallMethod(DigraphsRespectsColouring, +[IsDigraph, IsDigraph, IsPerm, IsList, IsList], +function(src, ran, x, cols1, cols2) + return DigraphsRespectsColouring(src, ran, AsTransformation(x), cols1, cols2); +end); + InstallMethod(IsDigraphHomomorphism, "for a digraph by out-neighbours, a digraph, and a perm", [IsDigraphByOutNeighboursRep, IsDigraph, IsPerm], @@ -492,15 +521,9 @@ end); InstallMethod(IsDigraphHomomorphism, "for a digraph by out-neighbours, a digraph, a transformation, and two lists", [IsDigraphByOutNeighboursRep, IsDigraph, IsTransformation, IsList, IsList], -function(src, ran, x, colours1, colours2) - if not IsDigraphHomomorphism(src, ran, x) then - return false; - fi; - - DIGRAPHS_ValidateVertexColouring(DigraphNrVertices(src), colours1); - DIGRAPHS_ValidateVertexColouring(DigraphNrVertices(ran), colours2); - - return ForAll(DigraphVertices(src), i -> colours1[i] = colours2[i ^ x]); +function(src, ran, x, cols1, cols2) + return IsDigraphHomomorphism(src, ran, x) and + DigraphsRespectsColouring(src, ran, x, cols1, cols2); end); InstallMethod(IsDigraphEndomorphism, "for a digraph and a transformation", @@ -521,9 +544,9 @@ end); InstallMethod(IsDigraphEpimorphism, "for digraph, digraph, and transformation", [IsDigraph, IsDigraph, IsTransformation, IsList, IsList], -function(src, ran, x, c1, c2) - return IsDigraphHomomorphism(src, ran, x, c1, c2) - and OnSets(DigraphVertices(src), x) = DigraphVertices(ran); +function(src, ran, x, cols1, cols2) + return IsDigraphEpimorphism(src, ran, x) and + DigraphsRespectsColouring(src, ran, x, cols1, cols2); end); InstallMethod(IsDigraphEpimorphism, "for digraph, digraph, and perm", @@ -536,9 +559,9 @@ end); InstallMethod(IsDigraphEpimorphism, "for digraph, digraph, perm, list, and list", [IsDigraph, IsDigraph, IsPerm, IsList, IsList], -function(src, ran, x, c1, c2) - return IsDigraphHomomorphism(src, ran, x, c1, c2) - and OnSets(DigraphVertices(src), x) = DigraphVertices(ran); +function(src, ran, x, cols1, cols2) + return IsDigraphEpimorphism(src, ran, x) + and DigraphsRespectsColouring(src, ran, x, cols1, cols2); end); InstallMethod(IsDigraphMonomorphism, @@ -552,38 +575,19 @@ end); InstallMethod(IsDigraphMonomorphism, "for digraph, digraph, transformation, list, list", [IsDigraph, IsDigraph, IsTransformation, IsList, IsList], -function(src, ran, x, c1, c2) - return IsDigraphHomomorphism(src, ran, x, c1, c2) - and IsInjectiveListTrans(DigraphVertices(src), x); +function(src, ran, x, cols1, cols2) + return IsDigraphMonomorphism(src, ran, x) + and DigraphsRespectsColouring(src, ran, x, cols1, cols2); end); InstallMethod(IsDigraphMonomorphism, "for digraph, digraph, and perm", [IsDigraph, IsDigraph, IsPerm], IsDigraphHomomorphism); InstallMethod(IsDigraphMonomorphism, "for digraph, digraph, perm, list, list", -[IsDigraph, IsDigraph, IsPerm, IsList, IsList], IsDigraphHomomorphism); - -InstallMethod(IsDigraphEmbedding, -"for digraph, digraph by out-neighbours, transformation, list, and list", -[IsDigraph, IsDigraphByOutNeighboursRep, IsTransformation, IsList, IsList], -function(src, ran, x, c1, c2) - local y, induced, i, j; - if not IsDigraphMonomorphism(src, ran, x, c1, c2) then - return false; - fi; - y := MappingPermListList(OnTuples(DigraphVertices(src), x), - DigraphVertices(src)); - induced := BlistList(DigraphVertices(ran), OnSets(DigraphVertices(src), x)); - for i in DigraphVertices(ran) do - if induced[i] then - for j in OutNeighbours(ran)[i] do - if induced[j] and not IsDigraphEdge(src, i ^ y, j ^ y) then - return false; - fi; - od; - fi; - od; - return true; +[IsDigraph, IsDigraph, IsPerm, IsList, IsList], +function(src, ran, x, cols1, cols2) + return IsDigraphMonomorphism(src, ran, x) + and DigraphsRespectsColouring(src, ran, x, cols1, cols2); end); InstallMethod(IsDigraphEmbedding, @@ -609,6 +613,14 @@ function(src, ran, x) return true; end); +InstallMethod(IsDigraphEmbedding, +"for digraph, digraph by out-neighbours, transformation, list, and list", +[IsDigraph, IsDigraphByOutNeighboursRep, IsTransformation, IsList, IsList], +function(src, ran, x, cols1, cols2) + return IsDigraphEmbedding(src, ran, x) + and DigraphsRespectsColouring(src, ran, x, cols1, cols2); +end); + InstallMethod(IsDigraphEmbedding, "for a digraph, a digraph by out-neighbours, and a perm", [IsDigraph, IsDigraphByOutNeighboursRep, IsPerm], @@ -634,23 +646,9 @@ end); InstallMethod(IsDigraphEmbedding, "for a digraph, a digraph by out-neighbours, a perm, a list, and a list", [IsDigraph, IsDigraphByOutNeighboursRep, IsPerm, IsList, IsList], -function(src, ran, x, c1, c2) - local y, induced, i, j; - if not IsDigraphHomomorphism(src, ran, x, c1, c2) then - return false; - fi; - y := x ^ -1; - induced := BlistList(DigraphVertices(ran), OnSets(DigraphVertices(src), x)); - for i in DigraphVertices(ran) do - if induced[i] then - for j in OutNeighbours(ran)[i] do - if induced[j] and not IsDigraphEdge(src, i ^ y, j ^ y) then - return false; - fi; - od; - fi; - od; - return true; +function(src, ran, x, cols1, cols2) + return IsDigraphEmbedding(src, ran, x) + and DigraphsRespectsColouring(src, ran, x, cols1, cols2); end); InstallMethod(IsDigraphColouring, "for a digraph by out-neighbours and a list", diff --git a/gap/isomorph.gi b/gap/isomorph.gi index bc817e1a0..a4fd3adf4 100644 --- a/gap/isomorph.gi +++ b/gap/isomorph.gi @@ -721,13 +721,9 @@ end); InstallMethod(IsDigraphIsomorphism, "for digraph, digraph, permutation, list, and list", [IsDigraph, IsDigraph, IsPerm, IsList, IsList], -function(src, ran, x, c1, c2) - if IsMultiDigraph(src) or IsMultiDigraph(ran) then - ErrorNoReturn("the 1st and 2nd arguments and must not have ", - "multiple edges,"); - fi; - return IsDigraphHomomorphism(src, ran, x, c1, c2) - and IsDigraphHomomorphism(ran, src, x ^ -1, c1, c2); +function(src, ran, x, cols1, cols2) + return IsDigraphIsomorphism(src, ran, x) + and DigraphsRespectsColouring(src, ran, x, cols1, cols2); end); InstallMethod(IsDigraphAutomorphism, "for a digraph and a permutation", @@ -753,13 +749,9 @@ end); InstallMethod(IsDigraphIsomorphism, "for digraph, digraph, transformation, list, and list", [IsDigraph, IsDigraph, IsTransformation, IsList, IsList], -function(src, ran, x, c1, c2) - local y; - y := AsPermutation(RestrictedTransformation(x, DigraphVertices(src))); - if y = fail then - return false; - fi; - return IsDigraphIsomorphism(src, ran, y, c1, c2); +function(src, ran, x, cols1, cols2) + return IsDigraphIsomorphism(src, ran, x) + and DigraphsRespectsColouring(src, ran, x, cols1, cols2); end); InstallMethod(IsDigraphAutomorphism, "for a digraph and a transformation", From 7b7ec18e06581d2deeaf3a6cf63c55dacbb5fdd0 Mon Sep 17 00:00:00 2001 From: James Mitchell Date: Thu, 23 Jan 2020 17:46:46 +0000 Subject: [PATCH 4/5] Add K tags to true. --- doc/grahom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/grahom.xml b/doc/grahom.xml index b4cf042d4..1534cf6ea 100644 --- a/doc/grahom.xml +++ b/doc/grahom.xml @@ -755,7 +755,7 @@ true The operation DigraphsRespectsColouring verifies whether or not the permutation or transformation x respects the vertex colourings col1 and col2 of the digraphs src and range. - That is, DigraphsRespectsColouring returns true if and only if for + That is, DigraphsRespectsColouring returns true if and only if for all vertices i of src, col1[i] = col2[i ^ x].

From 0db5724e536fba4744a68b48cfa57e446561e4a5 Mon Sep 17 00:00:00 2001 From: James Mitchell Date: Fri, 24 Jan 2020 12:35:08 +0000 Subject: [PATCH 5/5] Update isomorph.xml --- doc/isomorph.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/isomorph.xml b/doc/isomorph.xml index e824005cb..ea1be7076 100644 --- a/doc/isomorph.xml +++ b/doc/isomorph.xml @@ -790,7 +790,7 @@ gap> OutNeighbours(canon); represent vertex colourings; see for details of the permissible values for - these argument. The homomorphism must then also have the property: + these arguments. The homomorphism must then also have the property: