Skip to content

Commit

Permalink
Initial version of AmalgamDigraphs and AmalgamDigraphsIsomorphic.
Browse files Browse the repository at this point in the history
  • Loading branch information
finnbuck committed Mar 17, 2022
1 parent 1b7826e commit 1f46844
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 0 deletions.
3 changes: 3 additions & 0 deletions gap/oper.gd
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ DeclareOperation("StrongProduct", [IsDigraph, IsDigraph]);
DeclareOperation("ConormalProduct", [IsDigraph, IsDigraph]);
DeclareOperation("HomomorphicProduct", [IsDigraph, IsDigraph]);
DeclareOperation("LexicographicProduct", [IsDigraph, IsDigraph]);
DeclareOperation("AmalgamDigraphs", [IsDigraph, IsDigraph, IsList, IsList]);
DeclareOperation("AmalgamDigraphsIsomorphic",
[IsDigraph, IsDigraph, IsList, IsList]);

DeclareSynonym("DigraphModularProduct", ModularProduct);
DeclareSynonym("DigraphStrongProduct", StrongProduct);
Expand Down
85 changes: 85 additions & 0 deletions gap/oper.gi
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,91 @@ function(D1, D2, edge_function)
return Digraph(edges);
end);

InstallMethod(AmalgamDigraphsIsomorphic,
"for a digraph, a digraph, a list, and a list",
[IsDigraph, IsDigraph, IsList, IsList],
function(D1, D2, subdigraphVertices1, subdigraphVertices2)
local subdigraph1, subdigraph2, newSubdigraphVertices2, transformation, vertex;

subdigraph1 := InducedSubdigraph(D1, subdigraphVertices1);
subdigraph2 := InducedSubdigraph(D2, subdigraphVertices2);

if not IsIsomorphicDigraph(subdigraph1, subdigraph2) then
ErrorNoReturn(
"the two subdigraphs must be isomorphic.");
fi;

newSubdigraphVertices2 := [];
transformation := DigraphEmbedding(subdigraph2, subdigraph1);
for vertex in subdigraphVertices2 do
newSubdigraphVertices2[
Position(subdigraphVertices2, vertex) ^ transformation] := vertex;
od;

return AmalgamDigraphs(D1, D2, subdigraphVertices1, newSubdigraphVertices2);
end);

InstallMethod(AmalgamDigraphs,
"for a digraph, a digraph, a list, and a list",
[IsDigraph, IsDigraph, IsList, IsList],
function(D1, D2, subdigraphVertices1, subdigraphVertices2)
local D, map, vertex, vertexList, size, iterator, edgeList, subLength;

if not InducedSubdigraph(D1, subdigraphVertices1) =
InducedSubdigraph(D2, subdigraphVertices2) then
ErrorNoReturn(
"the two subdigraphs must be equal.");
fi;

# Create a mutable copy so that the function also works on
# immutable input digraphs.
D := DigraphMutableCopy(D1);
subLength := Length(subdigraphVertices1);

# 'map' is a mapping from the vertices of D2 to the vertices of the
# final output graph. The idea is to map the subdigraph vertices of D2
# onto the subdigraph vertices of D1 and then map the rest of the vertices
# of D2 to other (higher) values. The mapping from D1 to the output graph
# can be understood as the identity mapping.
map := rec();

for vertex in [1 .. subLength] do
map.(subdigraphVertices2[vertex]) := subdigraphVertices1[vertex];
od;

vertexList := Difference(DigraphVertices(D2), subdigraphVertices2);
size := DigraphNrVertices(D1);
iterator := 1;
for vertex in vertexList do
map.(vertex) := iterator + size;
iterator := iterator + 1;
od;

# The problem with adding edges to the output graph was that the
# edges of of the subdigraph were added twice, creating multiple
# edges between certain pairs of points. A quick and readable fix
# would have been to use DigraphRemoveAllMultipleEdges, but I decided
# to check each of the edges being added to see if they were already
# in the subdigraph. This way the function does not end up adding edges
# only to delete them later.
edgeList := ShallowCopy(DigraphEdges(D2));
iterator := 1;
while iterator <= Length(edgeList) do
if edgeList[iterator][1] in subdigraphVertices2 and
edgeList[iterator][2] in subdigraphVertices2 then
Remove(edgeList, iterator);
else
edgeList[iterator] := [
map.(edgeList[iterator][1]), map.(edgeList[iterator][2])];
iterator := iterator + 1;
fi;
od;

DigraphAddVertices(D, DigraphNrVertices(D2) - subLength);
DigraphAddEdges(D, edgeList);
return [MakeImmutable(D), map];
end);

###############################################################################
# 4. Actions
###############################################################################
Expand Down
35 changes: 35 additions & 0 deletions tst/standard/oper.tst
Original file line number Diff line number Diff line change
Expand Up @@ -2757,6 +2757,41 @@ gap> path := DigraphPath(D, 5, 5);;
gap> IsDigraphPath(D, path);
true

# AmalgamDigraphs
gap> D1 := Digraph([[2, 3], [1, 3], [1, 2], [2], [3, 4]]);;
gap> D2 := Digraph([[2, 6], [1, 3, 5], [4], [3], [4, 6], [1, 5]]);;
gap> U := AmalgamDigraphs(D1, D2, [2, 3, 4, 5], [4, 3, 5, 2]);
[ <immutable digraph with 7 vertices, 15 edges>,
rec( 1 := 6, 2 := 5, 3 := 3, 4 := 2, 5 := 4, 6 := 7 ) ]
gap> D1 := Digraph([
> [2, 3], [1, 3, 4, 6], [1, 2, 5, 7], [2, 6], [3, 7], [2, 4, 7, 8],
> [3, 5, 6, 8], [6, 7]]);;
gap> D2 := Digraph([
> [2, 3], [1, 4], [1, 5], [2, 5, 6], [3, 4, 7], [4, 7], [5, 6]]);;
gap> U := AmalgamDigraphs(D1, D2, [2, 3, 6, 7], [4, 5, 6, 7]);
[ <immutable digraph with 11 vertices, 32 edges>,
rec( 1 := 9, 2 := 10, 3 := 11, 4 := 2, 5 := 3, 6 := 6, 7 := 7 ) ]
gap> AmalgamDigraphs(D1, D2, [3, 6, 2, 7], [4, 5, 7, 6]);
Error, the two subdigraphs must be equal.
gap> D1 := PetersenGraph();;
gap> U := AmalgamDigraphs(D1, D1, [3, 4, 6, 8, 9], [3, 4, 6, 8, 9]);
[ <immutable digraph with 15 vertices, 50 edges>,
rec( 1 := 11, 10 := 15, 2 := 12, 3 := 3, 4 := 4, 5 := 13, 6 := 6, 7 := 14,
8 := 8, 9 := 9 ) ]

# AmalgamDigraphsIsomorphic
gap> D1 := PetersenGraph();;
gap> D2 := Digraph([
> [2, 4], [1, 3, 4, 5], [2, 5], [1, 2, 6], [2, 3, 7], [4, 7, 8],
> [5, 6, 8], [6, 7]]);;
gap> U := AmalgamDigraphsIsomorphic(D1, D2, [3, 4, 6, 8, 9],
> [2, 4, 5, 6, 7]);
[ <immutable digraph with 13 vertices, 42 edges>,
rec( 1 := 11, 2 := 3, 3 := 12, 4 := 4, 5 := 8, 6 := 9, 7 := 6, 8 := 13 ) ]
gap> U := AmalgamDigraphsIsomorphic(D1, D2, [3, 4, 10, 8, 9],
> [2, 4, 5, 6, 7]);
Error, the two subdigraphs must be isomorphic.

#DIGRAPHS_UnbindVariables
gap> Unbind(a);
gap> Unbind(adj);
Expand Down

0 comments on commit 1f46844

Please sign in to comment.