Skip to content

Commit 1f46844

Browse files
committed
Initial version of AmalgamDigraphs and AmalgamDigraphsIsomorphic.
1 parent 1b7826e commit 1f46844

File tree

3 files changed

+123
-0
lines changed

3 files changed

+123
-0
lines changed

gap/oper.gd

+3
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ DeclareOperation("StrongProduct", [IsDigraph, IsDigraph]);
4646
DeclareOperation("ConormalProduct", [IsDigraph, IsDigraph]);
4747
DeclareOperation("HomomorphicProduct", [IsDigraph, IsDigraph]);
4848
DeclareOperation("LexicographicProduct", [IsDigraph, IsDigraph]);
49+
DeclareOperation("AmalgamDigraphs", [IsDigraph, IsDigraph, IsList, IsList]);
50+
DeclareOperation("AmalgamDigraphsIsomorphic",
51+
[IsDigraph, IsDigraph, IsList, IsList]);
4952

5053
DeclareSynonym("DigraphModularProduct", ModularProduct);
5154
DeclareSynonym("DigraphStrongProduct", StrongProduct);

gap/oper.gi

+85
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,91 @@ function(D1, D2, edge_function)
765765
return Digraph(edges);
766766
end);
767767

768+
InstallMethod(AmalgamDigraphsIsomorphic,
769+
"for a digraph, a digraph, a list, and a list",
770+
[IsDigraph, IsDigraph, IsList, IsList],
771+
function(D1, D2, subdigraphVertices1, subdigraphVertices2)
772+
local subdigraph1, subdigraph2, newSubdigraphVertices2, transformation, vertex;
773+
774+
subdigraph1 := InducedSubdigraph(D1, subdigraphVertices1);
775+
subdigraph2 := InducedSubdigraph(D2, subdigraphVertices2);
776+
777+
if not IsIsomorphicDigraph(subdigraph1, subdigraph2) then
778+
ErrorNoReturn(
779+
"the two subdigraphs must be isomorphic.");
780+
fi;
781+
782+
newSubdigraphVertices2 := [];
783+
transformation := DigraphEmbedding(subdigraph2, subdigraph1);
784+
for vertex in subdigraphVertices2 do
785+
newSubdigraphVertices2[
786+
Position(subdigraphVertices2, vertex) ^ transformation] := vertex;
787+
od;
788+
789+
return AmalgamDigraphs(D1, D2, subdigraphVertices1, newSubdigraphVertices2);
790+
end);
791+
792+
InstallMethod(AmalgamDigraphs,
793+
"for a digraph, a digraph, a list, and a list",
794+
[IsDigraph, IsDigraph, IsList, IsList],
795+
function(D1, D2, subdigraphVertices1, subdigraphVertices2)
796+
local D, map, vertex, vertexList, size, iterator, edgeList, subLength;
797+
798+
if not InducedSubdigraph(D1, subdigraphVertices1) =
799+
InducedSubdigraph(D2, subdigraphVertices2) then
800+
ErrorNoReturn(
801+
"the two subdigraphs must be equal.");
802+
fi;
803+
804+
# Create a mutable copy so that the function also works on
805+
# immutable input digraphs.
806+
D := DigraphMutableCopy(D1);
807+
subLength := Length(subdigraphVertices1);
808+
809+
# 'map' is a mapping from the vertices of D2 to the vertices of the
810+
# final output graph. The idea is to map the subdigraph vertices of D2
811+
# onto the subdigraph vertices of D1 and then map the rest of the vertices
812+
# of D2 to other (higher) values. The mapping from D1 to the output graph
813+
# can be understood as the identity mapping.
814+
map := rec();
815+
816+
for vertex in [1 .. subLength] do
817+
map.(subdigraphVertices2[vertex]) := subdigraphVertices1[vertex];
818+
od;
819+
820+
vertexList := Difference(DigraphVertices(D2), subdigraphVertices2);
821+
size := DigraphNrVertices(D1);
822+
iterator := 1;
823+
for vertex in vertexList do
824+
map.(vertex) := iterator + size;
825+
iterator := iterator + 1;
826+
od;
827+
828+
# The problem with adding edges to the output graph was that the
829+
# edges of of the subdigraph were added twice, creating multiple
830+
# edges between certain pairs of points. A quick and readable fix
831+
# would have been to use DigraphRemoveAllMultipleEdges, but I decided
832+
# to check each of the edges being added to see if they were already
833+
# in the subdigraph. This way the function does not end up adding edges
834+
# only to delete them later.
835+
edgeList := ShallowCopy(DigraphEdges(D2));
836+
iterator := 1;
837+
while iterator <= Length(edgeList) do
838+
if edgeList[iterator][1] in subdigraphVertices2 and
839+
edgeList[iterator][2] in subdigraphVertices2 then
840+
Remove(edgeList, iterator);
841+
else
842+
edgeList[iterator] := [
843+
map.(edgeList[iterator][1]), map.(edgeList[iterator][2])];
844+
iterator := iterator + 1;
845+
fi;
846+
od;
847+
848+
DigraphAddVertices(D, DigraphNrVertices(D2) - subLength);
849+
DigraphAddEdges(D, edgeList);
850+
return [MakeImmutable(D), map];
851+
end);
852+
768853
###############################################################################
769854
# 4. Actions
770855
###############################################################################

tst/standard/oper.tst

+35
Original file line numberDiff line numberDiff line change
@@ -2757,6 +2757,41 @@ gap> path := DigraphPath(D, 5, 5);;
27572757
gap> IsDigraphPath(D, path);
27582758
true
27592759

2760+
# AmalgamDigraphs
2761+
gap> D1 := Digraph([[2, 3], [1, 3], [1, 2], [2], [3, 4]]);;
2762+
gap> D2 := Digraph([[2, 6], [1, 3, 5], [4], [3], [4, 6], [1, 5]]);;
2763+
gap> U := AmalgamDigraphs(D1, D2, [2, 3, 4, 5], [4, 3, 5, 2]);
2764+
[ <immutable digraph with 7 vertices, 15 edges>,
2765+
rec( 1 := 6, 2 := 5, 3 := 3, 4 := 2, 5 := 4, 6 := 7 ) ]
2766+
gap> D1 := Digraph([
2767+
> [2, 3], [1, 3, 4, 6], [1, 2, 5, 7], [2, 6], [3, 7], [2, 4, 7, 8],
2768+
> [3, 5, 6, 8], [6, 7]]);;
2769+
gap> D2 := Digraph([
2770+
> [2, 3], [1, 4], [1, 5], [2, 5, 6], [3, 4, 7], [4, 7], [5, 6]]);;
2771+
gap> U := AmalgamDigraphs(D1, D2, [2, 3, 6, 7], [4, 5, 6, 7]);
2772+
[ <immutable digraph with 11 vertices, 32 edges>,
2773+
rec( 1 := 9, 2 := 10, 3 := 11, 4 := 2, 5 := 3, 6 := 6, 7 := 7 ) ]
2774+
gap> AmalgamDigraphs(D1, D2, [3, 6, 2, 7], [4, 5, 7, 6]);
2775+
Error, the two subdigraphs must be equal.
2776+
gap> D1 := PetersenGraph();;
2777+
gap> U := AmalgamDigraphs(D1, D1, [3, 4, 6, 8, 9], [3, 4, 6, 8, 9]);
2778+
[ <immutable digraph with 15 vertices, 50 edges>,
2779+
rec( 1 := 11, 10 := 15, 2 := 12, 3 := 3, 4 := 4, 5 := 13, 6 := 6, 7 := 14,
2780+
8 := 8, 9 := 9 ) ]
2781+
2782+
# AmalgamDigraphsIsomorphic
2783+
gap> D1 := PetersenGraph();;
2784+
gap> D2 := Digraph([
2785+
> [2, 4], [1, 3, 4, 5], [2, 5], [1, 2, 6], [2, 3, 7], [4, 7, 8],
2786+
> [5, 6, 8], [6, 7]]);;
2787+
gap> U := AmalgamDigraphsIsomorphic(D1, D2, [3, 4, 6, 8, 9],
2788+
> [2, 4, 5, 6, 7]);
2789+
[ <immutable digraph with 13 vertices, 42 edges>,
2790+
rec( 1 := 11, 2 := 3, 3 := 12, 4 := 4, 5 := 8, 6 := 9, 7 := 6, 8 := 13 ) ]
2791+
gap> U := AmalgamDigraphsIsomorphic(D1, D2, [3, 4, 10, 8, 9],
2792+
> [2, 4, 5, 6, 7]);
2793+
Error, the two subdigraphs must be isomorphic.
2794+
27602795
#DIGRAPHS_UnbindVariables
27612796
gap> Unbind(a);
27622797
gap> Unbind(adj);

0 commit comments

Comments
 (0)