Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
9d1c20d
Change to GAP stable-4.14 in CI
frankiegillis Feb 5, 2025
1ff11a2
Merge branch 'digraphs:main' into main
frankiegillis Feb 25, 2025
00fe48c
Merge branch 'digraphs:main' into main
frankiegillis Feb 26, 2025
7932db5
Merge branch 'main' of github.com:digraphs/Digraphs into HEAD
frankiegillis Feb 26, 2025
4cc0df5
Add HasPseudoSimilarVertices no docs
frankiegillis Mar 2, 2025
f05eaf3
Fixed syntax
frankiegillis Mar 2, 2025
5c5f5e8
fixed syntax
frankiegillis Mar 2, 2025
81a7065
Add HasPSVs
frankiegillis Mar 26, 2025
d3dac89
Is2EdgeTransitive overhaul using Orbit-Stabiliser Theorem
frankiegillis Mar 26, 2025
51a3664
Added support for digraphs with loops
frankiegillis Mar 26, 2025
c9f28ef
Linting
frankiegillis Mar 26, 2025
35033ec
More linting
frankiegillis Mar 26, 2025
02a088c
Edited Documentation
frankiegillis Mar 26, 2025
e1eb03e
Edited Documentation again
frankiegillis Mar 26, 2025
b088fa8
Merge branch 'main' of github.com:digraphs/Digraphs into Is2EdgeTrans…
frankiegillis Apr 7, 2025
4415aa0
Merge branch 'main' of github.com:digraphs/Digraphs into Is2EdgeTrans…
frankiegillis Apr 21, 2025
bc3d557
Once more rewritten Is2EdgeTransitive, this time to avoid looping thr…
frankiegillis Apr 26, 2025
e62fc7e
lint
frankiegillis Apr 26, 2025
1414081
Added more comments to prop.gi
frankiegillis Apr 26, 2025
733cc5f
Fix trailing whitespace
frankiegillis Apr 26, 2025
5ef192f
Added IsTwoEdgeTransitive as synonym for Is2EdgeTransitive
frankiegillis Sep 24, 2025
2964fab
Merge branch 'main' of github.com:digraphs/Digraphs into Is2EdgeTrans…
frankiegillis Sep 24, 2025
851b036
lint
frankiegillis Sep 24, 2025
d3dfdcd
Removed spurious files and added what happens when the argument of Is…
frankiegillis Sep 25, 2025
73afcc5
fixed typo in doc
frankiegillis Sep 25, 2025
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
24 changes: 12 additions & 12 deletions doc/prop.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1589,31 +1589,31 @@ false]]></Example>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsTwoEdgeTransitive">
<#GAPDoc Label="Is2EdgeTransitive">
<ManSection>
<Prop Name="IsTwoEdgeTransitive" Arg="digraph"/>
<Prop Name="Is2EdgeTransitive" Arg="digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
If <A>digraph</A> is a digraph without multiple edges, then <C>IsTwoEdgeTransitive</C>
If <A>digraph</A> is a digraph without multiple edges, then <C>Is2EdgeTransitive</C>
returns <K>true</K> if <A>digraph</A> is 2-edge transitive, and <K>false</K>
otherwise. A digraph is <E>2-edge transitive</E> if its automorphism group
acts transitively on its 2-edges via the action
<Ref Func="OnTuplesTuples" BookName="ref"/>.
otherwise. If <A>digraph</A> has multiple edges, then <C>Is2EdgeTransitive</C> returns an error.

A <E>2-edge</E> of a digraph is a pair of its edges, such that the range of the
first edge is equal to the source of the second edge.
A digraph is <E>2-edge transitive</E> if its automorphism group
acts transitively on 2-edges via the action
<Ref Func="OnTuples" BookName="ref"/>. A <E>2-edge</E> in a digraph is a triple (u, v, w) of distinct vertices
such that (u, v) and (v, w) are edges.
<P/>

&MUTABLE_RECOMPUTED_PROP;

<Example><![CDATA[
gap> IsTwoEdgeTransitive(CompleteDigraph(4));
gap> Is2EdgeTransitive(CompleteDigraph(4));
true
gap> IsTwoEdgeTransitive(DigraphByEdges([[1, 2], [2, 3], [3, 1], [3, 4]]))
gap> Is2EdgeTransitive(DigraphByEdges([[1, 2], [2, 3], [3, 4]]));
false
gap> IsTwoEdgeTransitive(CycleDigraph(5));
gap> Is2EdgeTransitive(CycleDigraph(5));
true
gap> IsTwoEdgeTransitive(Digraph([[2], [3, 3, 3], []]));
gap> Is2EdgeTransitive(Digraph([[2], [3, 3, 3], []]));
Error, the argument <D> must be a digraph with no multiple edges,
]]></Example>
</Description>
Expand Down
1 change: 1 addition & 0 deletions doc/z-chap5.xml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
<#Include Label="IsDigraphCore">
<#Include Label="IsEdgeTransitive">
<#Include Label="IsVertexTransitive">
<#Include Label="Is2EdgeTransitive">
</Section>


Expand Down
3 changes: 2 additions & 1 deletion gap/prop.gd
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ DeclareProperty("IsMeetSemilatticeDigraph", IsDigraph);
DeclareProperty("IsPermutationDigraph", IsDigraph);
DeclareProperty("IsDistributiveLatticeDigraph", IsDigraph);
DeclareProperty("IsModularLatticeDigraph", IsDigraph);
DeclareProperty("IsTwoEdgeTransitive", IsDigraph);
DeclareProperty("Is2EdgeTransitive", IsDigraph);
DeclareSynonymAttr("IsLatticeDigraph",
IsMeetSemilatticeDigraph and IsJoinSemilatticeDigraph);
DeclareSynonymAttr("IsPreorderDigraph",
Expand All @@ -70,6 +70,7 @@ DeclareSynonymAttr("IsEquivalenceDigraph",
DeclareSynonymAttr("IsAntiSymmetricDigraph", IsAntisymmetricDigraph);
DeclareSynonymAttr("IsNullDigraph", IsEmptyDigraph);
DeclareSynonymAttr("IsQuasiorderDigraph", IsPreorderDigraph);
DeclareSynonymAttr("IsTwoEdgeTransitive", Is2EdgeTransitive);

DeclareOperation("DIGRAPHS_IsJoinSemilatticeAndJoinTable", [IsDigraph]);
DeclareOperation("DIGRAPHS_IsMeetSemilatticeAndMeetTable", [IsDigraph]);
Expand Down
89 changes: 79 additions & 10 deletions gap/prop.gi
Original file line number Diff line number Diff line change
Expand Up @@ -693,25 +693,94 @@ function(D)
return LatticeDigraphEmbedding(N5, D) = fail;
end);

InstallMethod(IsTwoEdgeTransitive,
InstallMethod(Is2EdgeTransitive,
"for a digraph without multiple edges",
[IsDigraph],
function(D)
local twoEdges;

local Aut, O, I, Centers, Count, In, Out, u;
if IsMultiDigraph(D) then
ErrorNoReturn("the argument <D> must be a digraph with no multiple",
" edges,");
fi;

twoEdges := Filtered(Cartesian(DigraphEdges(D), DigraphEdges(D)),
pair -> pair[1][2] = pair[2][1]
and pair[1][1] <> pair[2][2]);
Aut := AutomorphismGroup(D);
D := DigraphRemoveLoops(D);
O := D!.OutNeighbours;
I := InNeighbours(D);
# The list Centers will store all those vertices which lie at the
# center of a 2-edge.

Centers := [];

for u in [1 .. Length(O)] do
if Length(O[u]) > 0 and Length(I[u]) > 0 then
# If u has precisely one in neighbour and out neighbour,
# we must check these are not the same vertex as then there
# would be no 2-edge centered at u.

if Length(O[u]) = 1 and Length(I[u]) = 1 then
if O[u][1] = I[u][1] then
continue;
fi;
fi;
if not IsBound(Out) then
Out := Length(O[u]);
In := Length(I[u]);
fi;
# For D to be 2-edge transitive, it must be transitive
# on 2-edge centers, so all 2-edge centers must have the
# same in-degree and same out-degree.

if Length(twoEdges) = 0 then
if Out <> Length(O[u]) or In <> Length(I[u]) then
return false;
fi;
Add(Centers, u);
fi;
od;
# If Centers is empty, D has no 2-edges so is vacuously 2-edge
# transtive.

if Length(Centers) = 0 then
return true;
else
return OrbitLength(AutomorphismGroup(D), twoEdges[1], OnTuplesTuples)
= Length(twoEdges);
fi;
# Find the number of 2-cycles at any center. We will have to subtract
# these from the total number of 2-edges as 2-cycles are not classed
# as 2-edges.

Count := 0;
for u in O[Centers[1]] do
if Centers[1] in O[u] then
Count := Count + 1;
fi;
od;

# Find a 2-edge and check if its orbit length equals the number of 2-edges.
# By this point, we know that D is likely a highly symmetric digraph,
# since all 2-edge centers share a common in and out degree
# (This is by no means a guarantee, see Frucht's graph). From testing,
# calculating the stabilizer and using the orbit-stabilizer
# theorem is usually must faster in this case, so we instead determine
# the stabilizer of a 2-edge.

for u in I[Centers[1]] do
if Position(O[Centers[1]], u) = 1 then
if Length(O[Centers[1]]) = 1 then
continue;
else
return (In * Out - Count) * Length(Centers) =
Order(Aut) / Order(Stabilizer(Aut,
[u,
Centers[1],
O[Centers[1]][2]],
OnTuples));
fi;
else
return (In * Out - Count) * Length(Centers) =
Order(Aut) / Order(Stabilizer(Aut,
[u,
Centers[1],
O[Centers[1]][1]],
OnTuples));
fi;
od;
end);
18 changes: 9 additions & 9 deletions tst/standard/prop.tst
Original file line number Diff line number Diff line change
Expand Up @@ -1738,22 +1738,22 @@ true
gap> IsEdgeTransitive(Digraph([[2], [3, 3, 3], []]));
Error, the argument <D> must be a digraph with no multiple edges,

# IsTwoEdgeTransitive
gap> IsTwoEdgeTransitive(DigraphByEdges([[1, 2], [2, 3], [3, 1]]));
# Is2EdgeTransitive
gap> Is2EdgeTransitive(DigraphByEdges([[1, 2], [2, 3], [3, 1]]));
true
gap> IsTwoEdgeTransitive(DigraphByEdges([[1, 2], [2, 3], [3, 1], [3, 4]]));
gap> Is2EdgeTransitive(DigraphByEdges([[1, 2], [2, 3], [3, 1], [3, 4]]));
false
gap> IsTwoEdgeTransitive(CompleteDigraph(4));
gap> Is2EdgeTransitive(CompleteDigraph(4));
true
gap> IsTwoEdgeTransitive(CycleDigraph(100));
gap> Is2EdgeTransitive(CycleDigraph(100));
true
gap> IsTwoEdgeTransitive(CompleteBipartiteDigraph(11, 23));
gap> Is2EdgeTransitive(CompleteBipartiteDigraph(11, 23));
false
gap> IsTwoEdgeTransitive(DigraphByEdges([[1, 2]]));
gap> Is2EdgeTransitive(DigraphByEdges([[1, 2]]));
true
gap> IsTwoEdgeTransitive(DigraphByEdges([]));
gap> Is2EdgeTransitive(DigraphByEdges([]));
true
gap> IsTwoEdgeTransitive(Digraph([[2], [3, 3, 3], []]));
gap> Is2EdgeTransitive(Digraph([[2], [3, 3, 3], []]));
Error, the argument <D> must be a digraph with no multiple edges,

# DigraphHasNoVertices and DigraphHasAVertex
Expand Down
4 changes: 2 additions & 2 deletions tst/testinstall.tst
Original file line number Diff line number Diff line change
Expand Up @@ -440,8 +440,8 @@ rec( distances := [ [ 0, 5 ], [ 5, 0 ] ],
gap> EdgeWeightedDigraphShortestPath(d, 1, 2);
[ [ 1, 2 ], [ 1 ] ]

# IsTwoEdgeTransitive
gap> IsTwoEdgeTransitive(DigraphByEdges([[1, 2], [2, 3], [3, 1]]));
# Is2EdgeTransitive
gap> Is2EdgeTransitive(DigraphByEdges([[1, 2], [2, 3], [3, 1]]));
true

# Issue 617: bug in DigraphRemoveEdge, wasn't removing edge labels
Expand Down
Loading