Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue 704 #709

Merged
merged 4 commits into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/config_options.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
- name: Output g++ version . . .
run: g++ --version
- name: Install micromamba environment from environment.yml . . .
uses: mamba-org/setup-micromamba@v1
uses: mamba-org/setup-micromamba@v2
with:
environment-name: digraphs
cache-environment: true
Expand Down
4 changes: 2 additions & 2 deletions doc/grahom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -321,8 +321,8 @@ gap> MonomorphismsDigraphsRepresentatives(gr1, CompleteDigraph(3));
the vertices and the edges of <A>digraph1</A>, and are therefore possibly
strictly contained in the induced subdigraph on the same vertex set.
<Example><![CDATA[
gap> SubdigraphsMonomorphisms(CompleteBipartiteDigraph(2, 2),
> CompleteDigraph(4));
gap> Set(SubdigraphsMonomorphisms(CompleteBipartiteDigraph(2, 2),
> CompleteDigraph(4)));
[ Transformation( [ 1, 3, 2 ] ), Transformation( [ 2, 3, 1 ] ),
Transformation( [ 3, 4, 2, 1 ] ) ]
gap> SubdigraphsMonomorphismsRepresentatives(
Expand Down
8 changes: 5 additions & 3 deletions gap/attr.gi
Original file line number Diff line number Diff line change
Expand Up @@ -1630,11 +1630,13 @@ function(D)
return [C, blocked];
end;

digraph := DigraphSymmetricClosure(DigraphRemoveLoops(
DigraphRemoveAllMultipleEdges(DigraphMutableCopyIfMutable(D))));

digraph := DigraphMutableCopy(D);
DigraphSymmetricClosure(DigraphRemoveLoops(
DigraphRemoveAllMultipleEdges(digraph)));
MakeImmutable(digraph);
SetDigraphVertexLabels(digraph,
Reversed(DigraphDegeneracyOrdering(digraph)));

temp := Triplets(digraph);
T := temp[1];
C := temp[2];
Expand Down
7 changes: 4 additions & 3 deletions gap/cliques.gi
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ function(arg...)
orbits := HashMap();
for c in cliques do
if not c in orbits then
DIGRAPHS_AddOrbitToHashMap(G, c, orbits);
DIGRAPHS_AddOrbitToHashMap(G, c, OnSets, orbits);
fi;
od;
out := Keys(orbits);
Expand Down Expand Up @@ -709,7 +709,8 @@ function(digraph, hook, user_param, limit, include, exclude, max, size, reps)

new_found := 0;
if not clique in found_orbits then
orbit := DIGRAPHS_AddOrbitToHashMap(group, clique, found_orbits);
orbit :=
DIGRAPHS_AddOrbitToHashMap(group, clique, OnSets, found_orbits);
n := Length(orbit);

if invariant_include and invariant_exclude then
Expand Down Expand Up @@ -895,7 +896,7 @@ function(D, hook, param, lim, inc, exc, max, size, reps, inc_var, exc_var)
num := num + 1;
return;
elif not c in found_orbits then
orb := DIGRAPHS_AddOrbitToHashMap(grp, c, found_orbits);
orb := DIGRAPHS_AddOrbitToHashMap(grp, c, OnSets, found_orbits);
n := Length(orb);

if invariant then # we're not just looking for orbit reps, but inc and
Expand Down
88 changes: 36 additions & 52 deletions gap/grahom.gi
Original file line number Diff line number Diff line change
Expand Up @@ -333,75 +333,59 @@ end);
InstallMethod(SubdigraphsMonomorphismsRepresentatives,
"for a digraph and a digraph", [IsDigraph, IsDigraph],
function(H, G)
local GV, HN, map, reps, result, set, rep;

GV := DigraphVertices(G);
HN := DigraphNrVertices(H);
local AG, map, result, K, rep;

AG := AutomorphismGroup(G);
map := HashMap();
reps := [];
result := [];

for set in Combinations(GV, HN) do
if not set in map then
Add(reps, set);
DIGRAPHS_AddOrbitToHashMap(AutomorphismGroup(G), set, map);
for rep in MonomorphismsDigraphsRepresentatives(H, G) do
K := OnSetsTuples(DigraphEdges(H), rep);
if not K in map then
Add(result, rep);
DIGRAPHS_AddOrbitToHashMap(AG, K, OnSetsTuples, map);
fi;
od;

result := [];
for rep in reps do
map :=
HomomorphismDigraphsFinder(H, # domain
G, # range
fail, # hook
[], # user_param
1, # max_results
HN, # hint (i.e. rank)
true, # injective
rep, # image
[], # partial_map
fail, # colors1
fail, # colors2
DigraphWelshPowellOrder(H),
Group(()));
if Length(map) <> 0 then
Add(result, map[1]);
fi;
od;
return result;
end);

InstallMethod(SubdigraphsMonomorphisms, "for a digraph and a digraph",
[IsDigraph, IsDigraph],
function(H, G)
local ApplyHomomorphismNC, reps, AG, result, sub, o, x, rep, i;

ApplyHomomorphismNC := function(D1, D2, t)
local old, new, v, im;
old := OutNeighbours(D1);
new := List([1 .. DigraphNrVertices(D2)], x -> []);
for v in DigraphVertices(D1) do
im := v ^ t;
if not IsBound(new[im]) then
new[im] := [];
fi;
Append(new[im], OnTuples(old[v], t));
local AddOrbitToHashMap, AG, map, K, rep;

AddOrbitToHashMap := function(G, set, act, hashmap, rep)
local gens, o, im, pt, g;

gens := GeneratorsOfGroup(G);
o := [set];
Assert(1, not set in hashmap);
hashmap[set] := rep;
for pt in o do
for g in gens do
im := act(pt, g);
if not im in hashmap then
hashmap[im] := hashmap[pt] * g;
# Assert(0, OnSetsTuples(set, hashmap[im]) = im);
Add(o, im);
fi;
od;
od;
return DigraphNC(new);
return o;
end;

reps := SubdigraphsMonomorphismsRepresentatives(H, G);
AG := AutomorphismGroup(G);
result := [];
for rep in reps do
sub := ApplyHomomorphismNC(H, G, rep);
o := Enumerate(Orb(AG, sub, OnDigraphs, rec(schreier := true)));
for i in [1 .. Length(o)] do
x := EvaluateWord(GeneratorsOfGroup(AG), TraceSchreierTreeForward(o, i));
Add(result, rep * x);
od;
map := HashMap();

for rep in MonomorphismsDigraphsRepresentatives(H, G) do
K := OnSetsTuples(DigraphEdges(H), rep);
if not K in map then
AddOrbitToHashMap(AG, K, OnSetsTuples, map, rep);
fi;
od;
return result;

return Values(map);
end);

################################################################################
Expand Down
4 changes: 2 additions & 2 deletions gap/orbits.gi
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ function(G, domain)
end);

InstallGlobalFunction(DIGRAPHS_AddOrbitToHashMap,
function(G, set, hashmap)
function(G, set, act, hashmap)
local gens, o, im, pt, g;

gens := GeneratorsOfGroup(G);
Expand All @@ -78,7 +78,7 @@ function(G, set, hashmap)
hashmap[set] := true;
for pt in o do
for g in gens do
im := OnSets(pt, g);
im := act(pt, g);
if not im in hashmap then
hashmap[im] := true;
Add(o, im);
Expand Down
35 changes: 35 additions & 0 deletions tst/standard/attr.tst
Original file line number Diff line number Diff line change
Expand Up @@ -1036,6 +1036,41 @@ gap> DigraphAllChordlessCycles(D);
[ 1, 4, 8, 7, 6, 2 ], [ 1, 4, 3, 2 ], [ 1, 4, 3, 7, 6, 5 ], [ 3, 2, 6, 7 ],
[ 2, 1, 5, 6 ], [ 2, 1, 5, 8, 7, 3 ] ]

# check that DigraphAllChordlessCycles do not change the input graph
gap> g := Digraph([[2, 3, 7], [1, 4, 8], [1, 4, 9], [2, 3, 10], [6, 7, 9], [5, 8, 10],
> [8, 5, 1], [7, 6, 2], [5, 10, 3], [6, 9, 4]]);;
gap> DigraphAllChordlessCycles(g);
[ [ 7, 8, 6, 5 ], [ 6, 5, 9, 10 ], [ 3, 4, 10, 6, 5, 7, 1 ],
[ 3, 4, 10, 6, 8, 7, 1 ], [ 3, 4, 10, 9 ], [ 2, 4, 10, 6, 5, 7, 1 ],
[ 2, 4, 10, 6, 8 ], [ 2, 4, 10, 9, 5, 7, 8 ], [ 2, 4, 10, 9, 5, 7, 1 ],
[ 3, 4, 2, 1 ], [ 3, 4, 2, 8, 7, 5, 9 ], [ 3, 4, 2, 8, 6, 5, 9 ],
[ 3, 1, 7, 8, 6, 10, 9 ], [ 3, 1, 7, 5, 9 ], [ 2, 1, 7, 8 ],
[ 3, 1, 2, 8, 6, 5, 9 ], [ 3, 1, 2, 8, 6, 10, 9 ] ]
gap> DigraphAllUndirectedSimpleCircuits(g);
[ [ 1, 2, 4, 3 ], [ 1, 2, 4, 3, 9, 5, 6, 8, 7 ], [ 1, 2, 4, 3, 9, 5, 7 ],
[ 1, 2, 4, 3, 9, 10, 6, 5, 7 ], [ 1, 2, 4, 3, 9, 10, 6, 8, 7 ],
[ 1, 2, 4, 10, 6, 5, 7 ], [ 1, 2, 4, 10, 6, 5, 9, 3 ],
[ 1, 2, 4, 10, 6, 8, 7 ], [ 1, 2, 4, 10, 6, 8, 7, 5, 9, 3 ],
[ 1, 2, 4, 10, 9, 3 ], [ 1, 2, 4, 10, 9, 5, 6, 8, 7 ],
[ 1, 2, 4, 10, 9, 5, 7 ], [ 1, 2, 8, 6, 5, 7 ], [ 1, 2, 8, 6, 5, 9, 3 ],
[ 1, 2, 8, 6, 5, 9, 10, 4, 3 ], [ 1, 2, 8, 6, 10, 4, 3 ],
[ 1, 2, 8, 6, 10, 4, 3, 9, 5, 7 ], [ 1, 2, 8, 6, 10, 9, 3 ],
[ 1, 2, 8, 6, 10, 9, 5, 7 ], [ 1, 2, 8, 7 ], [ 1, 2, 8, 7, 5, 6, 10, 4, 3 ],
[ 1, 2, 8, 7, 5, 6, 10, 9, 3 ], [ 1, 2, 8, 7, 5, 9, 3 ],
[ 1, 2, 8, 7, 5, 9, 10, 4, 3 ], [ 1, 3, 4, 2, 8, 6, 5, 7 ],
[ 1, 3, 4, 2, 8, 6, 10, 9, 5, 7 ], [ 1, 3, 4, 2, 8, 7 ],
[ 1, 3, 4, 10, 6, 5, 7 ], [ 1, 3, 4, 10, 6, 8, 7 ],
[ 1, 3, 4, 10, 9, 5, 6, 8, 7 ], [ 1, 3, 4, 10, 9, 5, 7 ],
[ 1, 3, 9, 5, 6, 8, 7 ], [ 1, 3, 9, 5, 6, 10, 4, 2, 8, 7 ],
[ 1, 3, 9, 5, 7 ], [ 1, 3, 9, 10, 4, 2, 8, 6, 5, 7 ],
[ 1, 3, 9, 10, 4, 2, 8, 7 ], [ 1, 3, 9, 10, 6, 5, 7 ],
[ 1, 3, 9, 10, 6, 8, 7 ], [ 2, 4, 3, 9, 5, 6, 8 ], [ 2, 4, 3, 9, 5, 7, 8 ],
[ 2, 4, 3, 9, 10, 6, 5, 7, 8 ], [ 2, 4, 3, 9, 10, 6, 8 ],
[ 2, 4, 10, 6, 5, 7, 8 ], [ 2, 4, 10, 6, 8 ], [ 2, 4, 10, 9, 5, 6, 8 ],
[ 2, 4, 10, 9, 5, 7, 8 ], [ 4, 3, 9, 5, 6, 10 ],
[ 4, 3, 9, 5, 7, 8, 6, 10 ], [ 4, 3, 9, 10 ], [ 5, 6, 8, 7 ],
[ 9, 5, 6, 10 ], [ 9, 5, 7, 8, 6, 10 ] ]

# Issue #676
gap> D := Digraph([[], [3], []]);;
gap> SetDigraphVertexLabels(D, ["one", "two", "three"]);
Expand Down
16 changes: 9 additions & 7 deletions tst/standard/grahom.tst
Original file line number Diff line number Diff line change
Expand Up @@ -2762,24 +2762,26 @@ gap> IsLatticeEpimorphism(D, D, (2, 3));
true

# SubdigraphsMonomorphisms
gap> SubdigraphsMonomorphisms(CompleteBipartiteDigraph(2, 2),
> CompleteDigraph(4));
gap> Set(SubdigraphsMonomorphisms(CompleteBipartiteDigraph(2, 2),
> CompleteDigraph(4)));
[ Transformation( [ 1, 3, 2 ] ), Transformation( [ 2, 3, 1 ] ),
Transformation( [ 3, 4, 2, 1 ] ) ]
gap> D := DigraphFromGraph6String("D^{");
<immutable symmetric digraph with 5 vertices, 18 edges>
gap> SubdigraphsMonomorphisms(CompleteDigraph(4), D);
gap> Set(SubdigraphsMonomorphisms(CompleteDigraph(4), D));
[ Transformation( [ 1, 3, 4, 5, 5 ] ), Transformation( [ 2, 3, 4, 5, 5 ] ) ]
gap> Length(SubdigraphsMonomorphisms(CompleteDigraph(4), CompleteDigraph(12)));
495
gap> D := DigraphFromGraph6String("K^vMMF@oM?{@");
<immutable symmetric digraph with 12 vertices, 60 edges>
gap> Length(SubdigraphsMonomorphisms(CompleteMultipartiteDigraph([2, 5]), D));
252
gap> D := DigraphFromGraph6String("O^vMMF@oM?w@o@o?w?N?@");
<immutable symmetric digraph with 16 vertices, 84 edges>
gap> Length(SubdigraphsMonomorphisms(CompleteMultipartiteDigraph([2, 7]), D));
3432

# The next test is a bit slow
# gap> D := DigraphFromGraph6String("O^vMMF@oM?w@o@o?w?N?@");
# <immutable symmetric digraph with 16 vertices, 84 edges>
# gap> Length(SubdigraphsMonomorphisms(CompleteMultipartiteDigraph([2, 7]), D));
# 3432

#
gap> H := DigraphFromGraph6String("F~CWw");
Expand Down
6 changes: 6 additions & 0 deletions tst/testinstall.tst
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,12 @@ gap> C := DigraphContractEdge(D, 2, 1);
gap> DigraphEdges(C);
[ [ 2, 1 ] ]

# Issue #704 SubdigraphsMonomorphisms bug
gap> d := Digraph([[2, 3, 4, 5], [1, 3, 4], [1, 2, 4, 5], [1, 2, 3, 5],
> [1, 3, 4]]);;
gap> Length(SubdigraphsMonomorphisms(CompleteMultipartiteDigraph([2, 3]), d));
4

# DIGRAPHS_UnbindVariables
gap> Unbind(C);
gap> Unbind(D);
Expand Down
Loading