diff --git a/gap/attr.gi b/gap/attr.gi index 2bababd12..c28b0aaa4 100644 --- a/gap/attr.gi +++ b/gap/attr.gi @@ -292,11 +292,16 @@ end); InstallMethod(ReducedDigraph, "for an immutable digraph", [IsImmutableDigraph], function(D) + local C; if IsConnectedDigraph(D) then return D; fi; - D := ReducedDigraph(DigraphMutableCopy(D)); - return MakeImmutableDigraph(D); + C := MakeImmutableDigraph(ReducedDigraph(DigraphMutableCopy(D))); + if IsVertexColoredDigraph(D) then + MakeVertexColoredDigraph(C, + DigraphVertexColors(D){DigraphVertexLabels(C)}); + fi; + return C; end); InstallMethod(ReducedDigraphAttr, "for an immutable digraph", @@ -332,6 +337,9 @@ function(D) if HasDigraphGroup(D) then SetDigraphGroup(C, DigraphGroup(D)); fi; + if IsVertexColoredDigraph(D) then + MakeVertexColoredDigraph(C, DigraphVertexColors(D)); + fi; SetDigraphDualAttr(D, C); return C; end); @@ -1472,6 +1480,9 @@ function(D) fi; C := DigraphMutableCopy(D); C := MakeImmutableDigraph(MaximalSymmetricSubdigraph(C)); + if IsVertexColoredDigraph(D) then + MakeVertexColoredDigraph(C, DigraphVertexColors(D)); + fi; SetDigraphVertexLabels(C, DigraphVertexLabels(D)); SetMaximalSymmetricSubdigraphAttr(D, C); return C; diff --git a/gap/digraph.gd b/gap/digraph.gd index d319d87d0..d548add34 100644 --- a/gap/digraph.gd +++ b/gap/digraph.gd @@ -15,6 +15,9 @@ DeclareCategory("IsDigraphWithAdjacencyFunction", IsDigraph); DeclareSynonym("IsMutableDigraph", IsDigraph and IsMutable); DeclareCategory("IsImmutableDigraph", IsDigraph); +DeclareCategory("IsVertexColoredDigraph", IsImmutableDigraph); +DeclareAttribute("DigraphVertexColors", IsVertexColoredDigraph); + DeclareGlobalFunction("IsValidDigraph"); # Family @@ -34,12 +37,10 @@ DeclareOperation("ConvertToImmutableDigraphNC", [IsList]); DeclareConstructor("DigraphConsNC", [IsDigraph, IsRecord]); DeclareConstructor("DigraphConsNC", [IsDigraph, IsDenseList]); +DeclareConstructor("DigraphConsNC", + [IsVertexColoredDigraph, IsObject, IsDenseList]); -DeclareOperation("DigraphNC", [IsFunction, IsRecord]); -DeclareOperation("DigraphNC", [IsFunction, IsDenseList]); - -DeclareOperation("DigraphNC", [IsRecord]); -DeclareOperation("DigraphNC", [IsDenseList]); +DeclareGlobalFunction("DigraphNC"); # Copies DeclareOperation("DigraphMutableCopy", [IsDigraph]); @@ -50,6 +51,7 @@ DeclareOperation("DigraphCopyIfImmutable", [IsDigraph]); # Converter DeclareOperation("MakeImmutableDigraph", [IsDigraph]); +DeclareOperation("MakeVertexColoredDigraph", [IsImmutableDigraph, IsDenseList]); # Constructors DeclareConstructor("DigraphCons", [IsDigraph, IsRecord]); @@ -57,18 +59,18 @@ DeclareConstructor("DigraphCons", [IsDigraph, IsDenseList]); DeclareConstructor("DigraphCons", [IsDigraph, IsList, IsFunction]); DeclareConstructor("DigraphCons", [IsDigraph, IsInt, IsList, IsList]); DeclareConstructor("DigraphCons", [IsDigraph, IsList, IsList, IsList]); - -DeclareOperation("Digraph", [IsFunction, IsRecord]); -DeclareOperation("Digraph", [IsFunction, IsList]); -DeclareOperation("Digraph", [IsFunction, IsList, IsFunction]); -DeclareOperation("Digraph", [IsFunction, IsInt, IsList, IsList]); -DeclareOperation("Digraph", [IsFunction, IsList, IsList, IsList]); - -DeclareOperation("Digraph", [IsRecord]); -DeclareOperation("Digraph", [IsList]); -DeclareOperation("Digraph", [IsList, IsFunction]); -DeclareOperation("Digraph", [IsInt, IsList, IsList]); -DeclareOperation("Digraph", [IsList, IsList, IsList]); +DeclareConstructor("DigraphCons", + [IsVertexColoredDigraph, IsObject, IsDenseList]); +DeclareConstructor("DigraphCons", + [IsVertexColoredDigraph, IsList, IsFunction, IsDenseList]); +DeclareConstructor("DigraphCons", + [IsVertexColoredDigraph, IsInt, IsList, IsList, + IsDenseList]); +DeclareConstructor("DigraphCons", + [IsVertexColoredDigraph, IsList, IsList, IsList, + IsDenseList]); + +DeclareGlobalFunction("Digraph"); # Constructors "by" something . . . DeclareConstructor("DigraphByAdjacencyMatrixCons", diff --git a/gap/digraph.gi b/gap/digraph.gi index 5f15a4e21..4e6f4a614 100644 --- a/gap/digraph.gi +++ b/gap/digraph.gi @@ -136,26 +136,26 @@ function(filt, list) return MakeImmutableDigraph(DigraphConsNC(IsMutableDigraph, list)); end); -InstallMethod(DigraphNC, "for a function and a dense list", -[IsFunction, IsDenseList], -function(func, list) - return DigraphConsNC(func, list); -end); - -InstallMethod(DigraphNC, "for a dense list", [IsDenseList], -function(list) - return DigraphConsNC(IsImmutableDigraph, list); -end); - -InstallMethod(DigraphNC, "for a function and a record", -[IsFunction, IsRecord], -function(func, record) - return DigraphConsNC(func, record); +InstallMethod(DigraphConsNC, +"for IsVertexColoredDigraph, object, and dense list of colours", +[IsVertexColoredDigraph, IsObject, IsDenseList], +function(filt, obj, colors) + local D; + D := DigraphConsNC(IsImmutableDigraph, obj); + SetFilterObj(D, IsVertexColoredDigraph); + SetDigraphVertexColors(D, colors); + return D; end); -InstallMethod(DigraphNC, "for a record", [IsRecord], -function(record) - return DigraphConsNC(IsImmutableDigraph, record); +InstallGlobalFunction(DigraphNC, +function(arg) + if Length(arg) = 0 then + ErrorNoReturn("there must be at least 1 argument,"); + elif not IsFilter(arg[1]) then + CopyListEntries(arg, 1, 1, arg, 2, 1, Length(arg)); + arg[1] := IsImmutableDigraph; + fi; + return CallFuncList(DigraphConsNC, arg); end); ######################################################################## @@ -182,6 +182,19 @@ function(D) return copy; end); +InstallMethod(DigraphCopy, "for a dense vertex-colored digraph", +[IsDenseDigraphRep and IsVertexColoredDigraph], +function(D) + local copy; + IsValidDigraph(D); + copy := ConvertToImmutableDigraphNC(OutNeighboursMutableCopy(D)); + SetDigraphVertexLabels(copy, StructuralCopy(DigraphVertexLabels(D))); + SetDigraphEdgeLabelsNC(copy, StructuralCopy(DigraphEdgeLabelsNC(D))); + SetFilterObj(copy, IsVertexColoredDigraph); + SetDigraphVertexColors(copy, DigraphVertexColors(D)); + return copy; +end); + InstallMethod(DigraphCopyIfMutable, "for a mutable digraph", [IsMutableDigraph], DigraphMutableCopy); @@ -208,6 +221,16 @@ function(D) return D; end); +InstallMethod(MakeVertexColoredDigraph, +"for an immutable digraph and a dense list", +[IsImmutableDigraph, IsDenseList], +function(D, colors) + colors := DIGRAPHS_ValidateVertexColouring(colors); + SetDigraphVertexColors(D, colors); + SetFilterObj(D, IsVertexColoredDigraph); + return D; +end); + ######################################################################## # 5. Digraph constructors ######################################################################## @@ -369,6 +392,9 @@ function(filt, record) SetDigraphGroup(D, record.group); SetDigraphSchreierVector(D, record.schreierVector); SetRepresentativeOutNeighbours(D, record.adjacencies); + if IsBound(record.colourClasses) then + MakeVertexColoredDigraph(D, record.colourClasses); + fi; fi; else SetDigraphNrEdges(D, Length(record.DigraphSource)); @@ -408,58 +434,50 @@ function(filt, domain, src, ran) return MakeImmutableDigraph(DigraphCons(IsMutableDigraph, domain, src, ran)); end); -InstallMethod(Digraph, "for a filter and a record", [IsFunction, IsRecord], -function(filt, record) - return DigraphCons(filt, record); -end); - -InstallMethod(Digraph, "for a record", [IsRecord], -function(record) - return DigraphCons(IsImmutableDigraph, record); -end); - -InstallMethod(Digraph, "for a filter and a list", [IsFunction, IsList], -function(func, list) - return DigraphCons(func, list); -end); - -InstallMethod(Digraph, "for a list", [IsList], -function(list) - return DigraphCons(IsImmutableDigraph, list); -end); - -InstallMethod(Digraph, "for a filter, a list, and a function", -[IsFunction, IsList, IsFunction], -function(filt, list, func) - return DigraphCons(filt, list, func); -end); - -InstallMethod(Digraph, "for a list and a function", [IsList, IsFunction], -function(list, func) - return DigraphCons(IsImmutableDigraph, list, func); +InstallMethod(DigraphCons, +"for IsVertexColoredDigraph, an object, and a dense list", +[IsVertexColoredDigraph, IsObject, IsDenseList], +function(filt, obj, colors) + return MakeVertexColoredDigraph(DigraphCons(IsImmutableDigraph, obj), + colors); end); -InstallMethod(Digraph, "for a filter, integer, list, and list", -[IsFunction, IsInt, IsList, IsList], -function(filt, n, src, ran) - return DigraphCons(filt, n, src, ran); +InstallMethod(DigraphCons, +"for IsVertexColoredDigraph, a list, a function, and a dense list", +[IsVertexColoredDigraph, IsList, IsFunction, IsDenseList], +function(filt, list, func, colors) + return MakeVertexColoredDigraph(DigraphCons(IsImmutableDigraph, list, func), + colors); end); -InstallMethod(Digraph, "for an integer, list, and list", -[IsInt, IsList, IsList], -function(n, src, ran) - return DigraphCons(IsImmutableDigraph, n, src, ran); +InstallMethod(DigraphCons, +"for IsVertexColoredDigraph, an integer, a list, a list, and a dense list", +[IsVertexColoredDigraph, IsInt, IsList, IsList, IsDenseList], +function(filt, n, src, ran, colors) + return MakeVertexColoredDigraph(DigraphCons(IsImmutableDigraph, n, src, ran), + colors); end); -InstallMethod(Digraph, "for a filter, list, list, and list", -[IsFunction, IsList, IsList, IsList], -function(filt, dom, src, ran) - return DigraphCons(filt, dom, src, ran); +InstallMethod(DigraphCons, +"for IsVertexColoredDigraph, a list, a list, a list, and a dense list", +[IsVertexColoredDigraph, IsInt, IsList, IsList, IsDenseList], +function(filt, dom, src, ran, colors) + return MakeVertexColoredDigraph(DigraphCons(IsImmutableDigraph, + dom, + src, + ran), + colors); end); -InstallMethod(Digraph, "for a list, list, and list", [IsList, IsList, IsList], -function(dom, src, ran) - return DigraphCons(IsImmutableDigraph, dom, src, ran); +InstallGlobalFunction(Digraph, +function(arg) + if Length(arg) = 0 then + ErrorNoReturn("there must be at least 1 argument,"); + elif not IsFilter(arg[1]) then + CopyListEntries(arg, 1, 1, arg, 2, 1, Length(arg)); + arg[1] := IsImmutableDigraph; + fi; + return CallFuncList(DigraphCons, arg); end); ######################################################################## @@ -476,7 +494,9 @@ function(D) elif IsImmutableDigraph(D) then Append(str, "immutable "); fi; - + if IsVertexColoredDigraph(D) then + Append(str, "vertex colored "); + fi; if IsMultiDigraph(D) then Append(str, "multi"); fi; @@ -516,7 +536,18 @@ function(D) " )"); end); +InstallMethod(PrintString, "for a vertex colored dense digraph", +[IsVertexColoredDigraph and IsDenseDigraphRep], +function(D) + return Concatenation("Digraph( IsVertexColoredDigraph,", + PrintString(OutNeighbours(D)), + ", ", + PrintString(DigraphVertexColors(D)), + " )"); +end); + InstallMethod(String, "for a dense immutable digraph", + [IsImmutableDigraph and IsDenseDigraphRep], function(D) return Concatenation("Digraph( IsImmutableDigraph, ", @@ -532,6 +563,16 @@ function(D) " )"); end); +InstallMethod(String, "for a vertex colored dense digraph", +[IsVertexColoredDigraph and IsDenseDigraphRep], +function(D) + return Concatenation("Digraph( IsVertexColoredDigraph, ", + String(OutNeighbours(D)), + ", ", + String(DigraphVertexColors(D)), + " )"); +end); + ######################################################################## # 7. Operators ######################################################################## @@ -550,6 +591,33 @@ function(C, D) return DIGRAPH_LT(C, D); end); +InstallMethod(\=, "for a digraph and vertex colored digraph", +[IsDigraph, IsVertexColoredDigraph], ReturnFalse); + +InstallMethod(\=, "for vertex colored digraph and digraph", +[IsVertexColoredDigraph, IsDigraph], ReturnFalse); + +InstallMethod(\=, "for vertex colored digraphs", +[IsVertexColoredDigraph, IsVertexColoredDigraph], +function(C, D) + return DIGRAPH_EQUALS(C, D) + and DigraphVertexColors(C) = DigraphVertexColors(D); +end); + +InstallMethod(\<, "for a digraph and vertex colored digraph", +[IsDigraph, IsVertexColoredDigraph], ReturnTrue); + +InstallMethod(\<, "for a vertex colored digraph and digraph", +[IsVertexColoredDigraph, IsDigraph], ReturnFalse); + +InstallMethod(\<, "for vertex colored digraphs", +[IsVertexColoredDigraph, IsVertexColoredDigraph], +function(C, D) + return DIGRAPH_LT(C, D) or (DIGRAPH_EQUALS(C, D) + and DigraphVertexColors(C) < + DigraphVertexColors(D)); +end); + ######################################################################## # 8. Digraph by-something constructors ######################################################################## diff --git a/gap/grahom.gi b/gap/grahom.gi index be6dc028b..5086683ae 100644 --- a/gap/grahom.gi +++ b/gap/grahom.gi @@ -29,7 +29,11 @@ function(arg) elif not IsBound(arg[3]) and (IsPosInt(arg[2]) or arg[2] = infinity) then # arg[2] is arg[3] := arg[2]; - colours := fail; + if IsVertexColoredDigraph(D) then + colours := DigraphVertexColors(D); + else + colours := fail; + fi; G := AutomorphismGroup(DigraphRemoveAllMultipleEdges(D)); else ErrorNoReturn("the 2nd argument must be a homogenous list,"); @@ -38,7 +42,11 @@ function(arg) if HasGeneratorsOfEndomorphismMonoidAttr(D) then return GeneratorsOfEndomorphismMonoidAttr(D); fi; - colours := fail; + if IsVertexColoredDigraph(D) then + colours := DigraphVertexColors(D); + else + colours := fail; + fi; G := AutomorphismGroup(DigraphRemoveAllMultipleEdges(D)); fi; @@ -282,6 +290,73 @@ function(D1, D2) return Union(List(aut, x -> hom * x)); end); +InstallMethod(DigraphHomomorphism, +"for a vertex colored digraph and a vertex colored digraph", +[IsVertexColoredDigraph, IsVertexColoredDigraph], +function(C, D) + local out; + out := HomomorphismDigraphsFinder(C, + D, + fail, + [], + 1, + fail, + false, + DigraphVertices(D), + [], + DigraphVertexColors(C), + DigraphVertexColors(D), + DigraphWelshPowellOrder(C)); + if IsEmpty(out) then + return fail; + fi; + return out[1]; +end); + +InstallMethod(DigraphHomomorphism, +"for a vertex colored digraph and a digraph", +[IsVertexColoredDigraph, IsDigraph], ReturnFail); + +InstallMethod(DigraphHomomorphism, +"for a digraph and a vertex colored digraph", +[IsDigraph, IsVertexColoredDigraph], ReturnFail); + +InstallMethod(HomomorphismsDigraphsRepresentatives, +"for a vertex colored digraph and a vertex colored digraph", +[IsVertexColoredDigraph, IsVertexColoredDigraph], +function(C, D) + if IsIsomorphicDigraph(C, D) then + return AsTransformation(IsomorphismDigraphs(C, D)); + fi; + return HomomorphismDigraphsFinder(C, + D, + fail, + [], + infinity, + fail, + false, + DigraphVertices(D), + [], + DigraphVertexColors(C), + DigraphVertexColors(D)); +end); + +InstallMethod(HomomorphismsDigraphsRepresentatives, +"for a vertex colored digraph and a digraph", +[IsVertexColoredDigraph, IsDigraph], ReturnFail); + +InstallMethod(HomomorphismsDigraphsRepresentatives, +"for a digraph and a vertex colored digraph", +[IsDigraph, IsVertexColoredDigraph], ReturnFail); + +InstallMethod(HomomorphismsDigraphs, +"for a vertex colored digraph and a digraph", +[IsVertexColoredDigraph, IsDigraph], ReturnFail); + +InstallMethod(HomomorphismsDigraphs, +"for a digraph and a vertex colored digraph", +[IsDigraph, IsVertexColoredDigraph], ReturnFail); + ################################################################################ # INJECTIVE HOMOMORPHISMS @@ -345,6 +420,69 @@ function(D1, D2) return Union(List(aut, x -> hom * x)); end); +InstallMethod(DigraphMonomorphism, +"for a vertex colored digraph and a vertex colored digraph", +[IsVertexColoredDigraph, IsVertexColoredDigraph], +function(gr1, gr2) + local out; + if IsIsomorphicDigraph(gr1, gr2) then + return AsTransformation(IsomorphismDigraphs(gr1, gr2)); + fi; + out := HomomorphismDigraphsFinder(gr1, gr2, fail, [], 1, + DigraphNrVertices(gr1), true, + DigraphVertices(gr2), [], + DigraphVertexColors(gr1), + DigraphVertexColors(gr2)); + if IsEmpty(out) then + return fail; + fi; + return out[1]; +end); + +InstallMethod(DigraphMonomorphism, +"for a vertex colored digraph and a digraph", +[IsVertexColoredDigraph, IsDigraph], ReturnFail); + +InstallMethod(DigraphMonomorphism, +"for a digraph and a vertex colored digraph", +[IsDigraph, IsVertexColoredDigraph], ReturnFail); + +InstallMethod(MonomorphismsDigraphsRepresentatives, +"for a vertex colored digraph and a vertex colored digraph", +[IsVertexColoredDigraph, IsVertexColoredDigraph], +function(C, D) + if IsIsomorphicDigraph(C, D) then + return AsTransformation(IsomorphismDigraphs(C, D)); + fi; + return HomomorphismDigraphsFinder(C, + D, + fail, + [], + infinity, + DigraphNrVertices(C), + true, + DigraphVertices(D), + [], + DigraphVertexColors(C), + DigraphVertexColors(D)); +end); + +InstallMethod(MonomorphismsDigraphsRepresentatives, +"for a vertex colored digraph and a digraph", +[IsVertexColoredDigraph, IsDigraph], ReturnFail); + +InstallMethod(MonomorphismsDigraphsRepresentatives, +"for a digraph and a vertex colored digraph", +[IsDigraph, IsVertexColoredDigraph], ReturnFail); + +InstallMethod(MonomorphismsDigraphs, +"for a vertex colored digraph and a digraph", +[IsVertexColoredDigraph, IsDigraph], ReturnFail); + +InstallMethod(MonomorphismsDigraphs, +"for a digraph and a vertex colored digraph", +[IsDigraph, IsVertexColoredDigraph], ReturnFail); + ################################################################################ # SURJECTIVE HOMOMORPHISMS @@ -407,6 +545,76 @@ function(D1, D2) return Union(List(aut, x -> hom * x)); end); +InstallMethod(DigraphEpimorphism, +"for a vertex colored digraph and a vertex colored digraph", +[IsVertexColoredDigraph, IsVertexColoredDigraph], +function(C, D) + local out; + if IsIsomorphicDigraph(C, D) then + return AsTransformation(IsomorphismDigraphs(C, D)); + fi; + out := HomomorphismDigraphsFinder(C, + D, + fail, + [], + 1, + DigraphNrVertices(D), + false, + DigraphVertices(D), + [], + DigraphVertexColors(C), + DigraphVertexColors(D)); + + if IsEmpty(out) then + return fail; + fi; + return out[1]; +end); + +InstallMethod(DigraphEpimorphism, +"for a vertex colored digraph and a digraph", +[IsVertexColoredDigraph, IsDigraph], ReturnFail); + +InstallMethod(DigraphEpimorphism, +"for a digraph and a vertex colored digraph", +[IsDigraph, IsVertexColoredDigraph], ReturnFail); + +InstallMethod(EpimorphismsDigraphsRepresentatives, +"for a vertex colored digraph and a vertex colored digraph", +[IsVertexColoredDigraph, IsVertexColoredDigraph], +function(C, D) + if IsIsomorphicDigraph(C, D) then + return AsTransformation(IsomorphismDigraphs(C, D)); + fi; + return HomomorphismDigraphsFinder(C, + D, + fail, + [], + infinity, + DigraphNrVertices(D), + false, + DigraphVertices(D), + [], + DigraphVertexColors(C), + DigraphVertexColors(D)); +end); + +InstallMethod(EpimorphismsDigraphsRepresentatives, +"for a vertex colored digraph and a digraph", +[IsVertexColoredDigraph, IsDigraph], ReturnFail); + +InstallMethod(EpimorphismsDigraphsRepresentatives, +"for a digraph and a vertex colored digraph", +[IsDigraph, IsVertexColoredDigraph], ReturnFail); + +InstallMethod(EpimorphismsDigraphs, +"for a vertex colored digraph and a digraph", +[IsVertexColoredDigraph, IsDigraph], ReturnFail); + +InstallMethod(EpimorphismsDigraphs, +"for a digraph and a vertex colored digraph", +[IsDigraph, IsVertexColoredDigraph], ReturnFail); + ################################################################################ # Embeddings ################################################################################ @@ -467,6 +675,14 @@ function(D1, D2) return Union(List(aut, x -> hom * x)); end); +InstallMethod(DigraphEmbedding, +"for a vertex colored digraph and a digraph", +[IsVertexColoredDigraph, IsDigraph], ReturnFail); + +InstallMethod(DigraphEmbedding, +"for a digraph and a vertex colored digraph", +[IsDigraph, IsVertexColoredDigraph], ReturnFail); + ######################################################################## # IsDigraphHomo/Epi/.../morphism ######################################################################## diff --git a/gap/grape.gd b/gap/grape.gd index d975cfc69..828f58bcb 100644 --- a/gap/grape.gd +++ b/gap/grape.gd @@ -16,10 +16,11 @@ DeclareAttribute("GroupOfCayleyDigraph", IsCayleyDigraph); DeclareAttribute("SemigroupOfCayleyDigraph", IsCayleyDigraph); DeclareAttribute("GeneratorsOfCayleyDigraph", IsCayleyDigraph); -DeclareOperation("Digraph", [IsGroup, - IsListOrCollection, - IsFunction, - IsFunction]); +DeclareConstructor("DigraphCons", [IsImmutableDigraph, + IsGroup, + IsListOrCollection, + IsFunction, + IsFunction]); DeclareOperation("CayleyDigraph", [IsGroup]); DeclareOperation("CayleyDigraph", [IsGroup, IsList]); diff --git a/gap/grape.gi b/gap/grape.gi index 80ae14270..8c052a787 100644 --- a/gap/grape.gi +++ b/gap/grape.gi @@ -17,10 +17,10 @@ InstallImmediateMethod(SemigroupOfCayleyDigraph, IsCayleyDigraph and HasGroupOfCayleyDigraph, 0, GroupOfCayleyDigraph); -InstallMethod(Digraph, -"for a group, list or collection, function, and function", -[IsGroup, IsListOrCollection, IsFunction, IsFunction], -function(G, obj, act, adj) +InstallMethod(DigraphCons, +"for IsImmutableDigraph, a group, list or collection, function, and function", +[IsImmutableDigraph, IsGroup, IsListOrCollection, IsFunction, IsFunction], +function(filt, G, obj, act, adj) local hom, dom, sch, orbits, reps, stabs, rep_out, out, gens, trace, word, D, adj_func, i, o, w; @@ -114,7 +114,7 @@ end); InstallMethod(Graph, "for a digraph", [IsDigraph], function(D) - local gamma, i, n; + local n, gamma, c, i; IsValidDigraph(D); if IsMultiDigraph(D) then @@ -149,6 +149,16 @@ function(D) fi; gamma.names := Immutable(DigraphVertexLabels(D)); + if IsVertexColoredDigraph(D) then + gamma.colourClasses := []; + for i in DigraphVertices(D) do + c := DigraphVertexColors(D)[i]; + if not IsBound(gamma.colourClasses[c]) then + gamma.colourClasses[c] := []; + fi; + Add(gamma.colourClasses[c], i); + od; + fi; return gamma; end); diff --git a/gap/isomorph.gi b/gap/isomorph.gi index 5d6879458..2a9dc466a 100644 --- a/gap/isomorph.gi +++ b/gap/isomorph.gi @@ -147,6 +147,15 @@ function(D, colors) return BLISS_DATA(D, colors)[2]; end); +InstallMethod(BlissCanonicalLabelling, "for a vertex colored digraph", +[IsVertexColoredDigraph], +function(D) + local data; + data := BLISS_DATA(D, DigraphVertexColors(D)); + SetBlissAutomorphismGroup(D, data[1]); + return data[2]; +end); + InstallMethod(NautyCanonicalLabelling, "for a digraph", [IsDigraph], function(D) @@ -173,6 +182,19 @@ function(D, colors) return NAUTY_DATA(D, colors)[2]; end); +InstallMethod(NautyCanonicalLabelling, "for a vertex colored digraph", +[IsVertexColoredDigraph], +function(D) + local data; + if not DIGRAPHS_NautyAvailable or IsMultiDigraph(D) then + Info(InfoWarning, 1, "NautyTracesInterface is not available"); + return fail; + fi; + data := NAUTY_DATA(D, DigraphVertexColors(D)); + SetNautyAutomorphismGroup(D, data[1]); + return data[2]; +end); + # Canonical digraphs InstallMethod(BlissCanonicalDigraph, "for a digraph", [IsDigraph], @@ -231,6 +253,22 @@ function(D) return data[1]; end); +InstallMethod(BlissAutomorphismGroup, "for a vertex colored digraph", +[IsVertexColoredDigraph], +function(D) + local data; + data := BLISS_DATA(D, DigraphVertexColors(D)); + SetBlissCanonicalLabelling(D, data[2]); + if not HasDigraphGroup(D) then + if IsMultiDigraph(D) then + SetDigraphGroup(D, Range(Projection(data[1], 1))); + else + SetDigraphGroup(D, data[1]); + fi; + fi; + return data[1]; +end); + InstallMethod(NautyAutomorphismGroup, "for a digraph", [IsDigraph], function(D) local data; @@ -249,6 +287,23 @@ function(D) return data[1]; end); +InstallMethod(NautyAutomorphismGroup, "for a vertex colored digraph", +[IsVertexColoredDigraph], +function(D) + local data; + if not DIGRAPHS_NautyAvailable or IsMultiDigraph(D) then + Info(InfoWarning, 1, "NautyTracesInterface is not available"); + return fail; + fi; + data := NAUTY_DATA(D, DigraphVertexColors(D)); + SetNautyCanonicalLabelling(D, data[2]); + if not HasDigraphGroup(D) then + # Multidigraphs not allowed + SetDigraphGroup(D, data[1]); + fi; + return data[1]; +end); + InstallMethod(BlissAutomorphismGroup, "for a digraph and vertex coloring", [IsDigraph, IsHomogeneousList], function(D, colors) @@ -363,6 +418,31 @@ function(C, D, c1, c2) fi; end); +InstallMethod(IsIsomorphicDigraph, "for vertex colored digraphs", +[IsVertexColoredDigraph, IsVertexColoredDigraph], +function(C, D) + return IsIsomorphicDigraph(C, + D, + DigraphVertexColors(C), + DigraphVertexColors(D)); +end); + +InstallMethod(IsIsomorphicDigraph, "for a vertex colored digraph and digraph", +[IsVertexColoredDigraph, IsDigraph], +function(C, D) + return IsIsomorphicDigraph(C, + D, + DigraphVertexColors(C), + ListWithIdenticalEntries(DigraphNrVertices(D), + 1)); +end); + +InstallMethod(IsIsomorphicDigraph, "for a digraph and vertex colored digraph", +[IsDigraph, IsVertexColoredDigraph], +function(C, D) + return IsomorphismDigraphs(D, C); +end); + # Isomorphisms between digraphs InstallMethod(IsomorphismDigraphs, "for digraphs", [IsDigraph, IsDigraph], @@ -454,6 +534,30 @@ function(C, D, c1, c2) return label1 / label2; end); +InstallMethod(IsomorphismDigraphs, "for vertex colored digraphs", +[IsVertexColoredDigraph, IsVertexColoredDigraph], +function(C, D) + return IsomorphismDigraphs(C, + D, + DigraphVertexColors(C), + DigraphVertexColors(D)); +end); + +InstallMethod(IsomorphismDigraphs, "for a vertex colored digraph and digraph", +[IsVertexColoredDigraph, IsDigraph], +function(C, D) + return IsomorphismDigraphs(C, + D, + DigraphVertexColors(C), + ListWithIdenticalEntries(DigraphNrVertices(D), + 1)); +end); + +InstallMethod(IsomorphismDigraphs, "for digraph and a vertex colored digraph", +[IsDigraph, IsVertexColoredDigraph], +function(C, D) + return IsomorphismDigraphs(D, C); +end); # Given a non-negative integer and a homogeneous list , # this global function tests whether is a valid partition # of the list [1 .. n]. A valid partition of [1 .. n] is either: diff --git a/gap/oper.gi b/gap/oper.gi index 3e2bdb74c..2f9c88ab2 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -365,10 +365,14 @@ end); InstallMethod(DigraphRemoveAllMultipleEdges, "for an immutable digraph", [IsImmutableDigraph], function(D) - D := DigraphMutableCopy(D); - D := MakeImmutableDigraph(DigraphRemoveAllMultipleEdges(D)); - SetIsMultiDigraph(D, false); - return D; + local C; + C := DigraphMutableCopy(D); + C := MakeImmutableDigraph(DigraphRemoveAllMultipleEdges(C)); + SetIsMultiDigraph(C, false); + if IsVertexColoredDigraph(D) then + MakeVertexColoredDigraph(C, DigraphVertexColors(D)); + fi; + return C; end); InstallMethod(DigraphClosure, diff --git a/tst/standard/digraph.tst b/tst/standard/digraph.tst index 624c54f7d..56dc51237 100644 --- a/tst/standard/digraph.tst +++ b/tst/standard/digraph.tst @@ -92,7 +92,7 @@ Error, the record component 'DigraphVertices' must be duplicate-free, # Digraph (by nrvertices, source, and range) gap> Digraph(Group(()), [], []); Error, no method found! For debugging hints type ?Recovery from NoMethodFound -Error, no 1st choice method found for `Digraph' on 3 arguments +Error, no 1st choice method found for `DigraphCons' on 4 arguments gap> Digraph(2, [1, "a"], [2, 1]); Error, the record component 'DigraphSource' is invalid, gap> Digraph(2, [1, 1], [1, Group(())]); @@ -128,13 +128,13 @@ gap> Digraph(IsMutableDigraph, 4, [3, 1, 2, 3], [4, 1, 2, 4]); # Digraph (by vertices, source, and range) gap> Digraph(Group(()), [], []); Error, no method found! For debugging hints type ?Recovery from NoMethodFound -Error, no 1st choice method found for `Digraph' on 3 arguments +Error, no 1st choice method found for `DigraphCons' on 4 arguments gap> Digraph([], Group(()), []); Error, no method found! For debugging hints type ?Recovery from NoMethodFound -Error, no 1st choice method found for `Digraph' on 3 arguments +Error, no 1st choice method found for `DigraphCons' on 4 arguments gap> Digraph([], [], Group(())); Error, no method found! For debugging hints type ?Recovery from NoMethodFound -Error, no 1st choice method found for `Digraph' on 3 arguments +Error, no 1st choice method found for `DigraphCons' on 4 arguments gap> Digraph([1], [2], [3, 4]); Error, the record components 'DigraphSource' and 'DigraphRange' must have equa\ l length, @@ -974,7 +974,7 @@ gap> G := DihedralGroup(8); gap> digraph := Digraph(G, ReturnTrue); Error, no method found! For debugging hints type ?Recovery from NoMethodFound -Error, no 1st choice method found for `Digraph' on 2 arguments +Error, no 1st choice method found for `DigraphCons' on 3 arguments gap> digraph := Digraph(AsSet(G), ReturnTrue); gap> HasDigraphAdjacencyFunction(digraph);