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

Add more implications (including some implications of falsity) #494

Merged
merged 3 commits into from
Nov 25, 2021
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
90 changes: 89 additions & 1 deletion doc/prop.xml
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,8 @@ false
<K>false</K> if it is not. A digraph is <E>empty</E> if it has no
edges.<P/>

<C>IsNullDigraph</C> is a synonym for <C>IsEmptyDigraph</C>.
<Ref Prop="IsNullDigraph"/> is a synonym for <Ref Prop="IsEmptyDigraph"/>.
See also <Ref Prop="IsNonemptyDigraph"/>.
<P/>

&MUTABLE_RECOMPUTED_PROP;
Expand All @@ -739,6 +740,93 @@ false]]></Example>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsNonemptyDigraph">
<ManSection>
<Prop Name="IsNonemptyDigraph" Arg="digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
Returns <K>true</K> if the digraph <A>digraph</A> is nonempty, and
<K>false</K> if it is not. A digraph is <E>nonempty</E> if it has at
least one edge.<P/>

See also <Ref Prop="IsEmptyDigraph"/>.
<P/>

&MUTABLE_RECOMPUTED_PROP;

<Example><![CDATA[
gap> D := Digraph([[], []]);
<immutable empty digraph with 2 vertices>
gap> IsNonemptyDigraph(D);
false
gap> D := Digraph([[], [1]]);
<immutable digraph with 2 vertices, 1 edge>
gap> IsNonemptyDigraph(D);
true]]></Example>
</Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="DigraphHasAVertex">
<ManSection>
<Prop Name="DigraphHasAVertex" Arg="digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
Returns <K>true</K> if the digraph <A>digraph</A> has at least one vertex,
and <K>false</K> if it does not.<P/>

See also <Ref Prop="DigraphHasNoVertices"/>.
<P/>

&MUTABLE_RECOMPUTED_PROP;

<Example><![CDATA[
gap> D := Digraph([]);
<immutable empty digraph with 0 vertices>
gap> DigraphHasAVertex(D);
false
gap> D := Digraph([[]]);
<immutable empty digraph with 1 vertex>
gap> DigraphHasAVertex(D);
true
gap> D := Digraph([[], [1]]);
<immutable digraph with 2 vertices, 1 edge>
gap> DigraphHasAVertex(D);
true]]></Example>
</Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="DigraphHasNoVertices">
<ManSection>
<Prop Name="DigraphHasNoVertices" Arg="digraph"/>
<Returns><K>true</K> or <K>false</K>.</Returns>
<Description>
Returns <K>true</K> if the digraph <A>digraph</A> is the unique digraph
with zero vertices, and <K>false</K> otherwise.<P/>

See also <Ref Prop="DigraphHasAVertex"/>.
<P/>

&MUTABLE_RECOMPUTED_PROP;

<Example><![CDATA[
gap> D := Digraph([]);
<immutable empty digraph with 0 vertices>
gap> DigraphHasNoVertices(D);
true
gap> D := Digraph([[]]);
<immutable empty digraph with 1 vertex>
gap> DigraphHasNoVertices(D);
false
gap> D := Digraph([[], [1]]);
<immutable digraph with 2 vertices, 1 edge>
gap> DigraphHasNoVertices(D);
false]]></Example>
</Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsEulerianDigraph">
<ManSection>
<Prop Name="IsEulerianDigraph" Arg="digraph"/>
Expand Down
6 changes: 6 additions & 0 deletions doc/z-chap5.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
<Chapter Label="Properties of digraphs"><Heading>Properties of digraphs</Heading>

<Section><Heading>Vertex properties</Heading>
<#Include Label="DigraphHasAVertex">
<#Include Label="DigraphHasNoVertices">
</Section>

<Section><Heading>Edge properties</Heading>
<#Include Label="DigraphHasLoops">
<#Include Label="IsAntisymmetricDigraph">
Expand All @@ -12,6 +17,7 @@
<#Include Label="IsFunctionalDigraph">
<#Include Label="IsPermutationDigraph">
<#Include Label="IsMultiDigraph">
<#Include Label="IsNonemptyDigraph">
<#Include Label="IsReflexiveDigraph">
<#Include Label="IsSymmetricDigraph">
<#Include Label="IsTournament">
Expand Down
20 changes: 10 additions & 10 deletions gap/attr.gi
Original file line number Diff line number Diff line change
Expand Up @@ -1080,7 +1080,7 @@ function(D)
# alter the answer for the diameter/girth if necessary. This function is
# called, if appropriate, by DigraphDiameter and DigraphUndirectedGirth.

if DigraphNrVertices(D) = 0 and IsImmutableDigraph(D) then
if DigraphHasNoVertices(D) and IsImmutableDigraph(D) then
SetDigraphDiameter(D, fail);
SetDigraphUndirectedGirth(D, infinity);
return rec(diameter := fail, girth := infinity);
Expand Down Expand Up @@ -1491,10 +1491,10 @@ end);

InstallMethod(DegreeMatrix, "for a digraph", [IsDigraph],
function(D)
if DigraphNrVertices(D) = 0 then
return [];
if DigraphHasAVertex(D) then
return DiagonalMat(OutDegrees(D));
fi;
return DiagonalMat(OutDegrees(D));
return [];
end);

InstallMethod(LaplacianMatrix, "for a digraph", [IsDigraph],
Expand Down Expand Up @@ -1815,7 +1815,7 @@ function(D)
SetDigraphAddAllLoopsAttr(D, C);
SetIsReflexiveDigraph(C, true);
SetIsMultiDigraph(C, ismulti);
SetDigraphHasLoops(C, DigraphNrVertices(C) > 0);
SetDigraphHasLoops(C, DigraphHasAVertex(C));
fi;
return C;
end);
Expand Down Expand Up @@ -2264,7 +2264,7 @@ InstallMethod(UndirectedSpanningForest, "for a digraph by out-neighbours",
[IsDigraphByOutNeighboursRep],
function(D)
local C;
if DigraphNrVertices(D) = 0 then
if DigraphHasNoVertices(D) then
return fail;
fi;
C := MaximalSymmetricSubdigraph(D)!.OutNeighbours;
Expand Down Expand Up @@ -2293,9 +2293,9 @@ InstallMethod(UndirectedSpanningForestAttr, "for an immutable digraph",
InstallMethod(UndirectedSpanningTree, "for a mutable digraph",
[IsMutableDigraph],
function(D)
if DigraphNrVertices(D) = 0
or not IsStronglyConnectedDigraph(D)
or not IsConnectedDigraph(UndirectedSpanningForest(DigraphMutableCopy(D)))
if not (DigraphHasAVertex(D)
and IsStronglyConnectedDigraph(D)
and IsConnectedDigraph(UndirectedSpanningForest(DigraphMutableCopy(D))))
then
return fail;
fi;
Expand All @@ -2309,7 +2309,7 @@ InstallMethod(UndirectedSpanningTreeAttr, "for an immutable digraph",
[IsImmutableDigraph],
function(D)
local out;
if DigraphNrVertices(D) = 0
if DigraphHasNoVertices(D)
or not IsStronglyConnectedDigraph(D)
or (HasMaximalSymmetricSubdigraphAttr(D)
and not IsStronglyConnectedDigraph(MaximalSymmetricSubdigraph(D)))
Expand Down
2 changes: 1 addition & 1 deletion gap/digraph.gi
Original file line number Diff line number Diff line change
Expand Up @@ -1065,7 +1065,7 @@ p -> AsDigraph(AsTransformation(p)));
InstallMethod(AsBinaryRelation, "for a digraph", [IsDigraphByOutNeighboursRep],
function(D)
local rel;
if DigraphNrVertices(D) = 0 then
if DigraphHasNoVertices(D) then
ErrorNoReturn("the argument <D> must be a digraph with at least 1 ",
"vertex,");
elif IsMultiDigraph(D) then
Expand Down
2 changes: 1 addition & 1 deletion gap/grahom.gi
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ function(D, n)

# Only the null D with 0 vertices can be coloured with 0 colours
wilfwilson marked this conversation as resolved.
Show resolved Hide resolved
if n = 0 then
if DigraphNrVertices(D) = 0 then
if DigraphHasNoVertices(D) then
return IdentityTransformation;
fi;
return fail;
Expand Down
2 changes: 1 addition & 1 deletion gap/isomorph.gi
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ if DIGRAPHS_NautyAvailable then
colors);
colors := NautyColorData(colors);
fi;
if DigraphNrVertices(D) = 0 then
if DigraphHasNoVertices(D) then
# This circumvents Issue #17 in NautyTracesInterface, whereby a graph
# with 0 vertices causes a seg fault.
return [Group(()), ()];
Expand Down
50 changes: 50 additions & 0 deletions gap/prop.gd
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
# meaning it really has multiple edges!!
DeclareProperty("IsMultiDigraph", IsDigraph);

DeclareProperty("DigraphHasAVertex", IsDigraph);
DeclareProperty("DigraphHasNoVertices", IsDigraph);

DeclareProperty("DigraphHasLoops", IsDigraph);
DeclareProperty("IsAcyclicDigraph", IsDigraph);
DeclareProperty("IsAperiodicDigraph", IsDigraph);
Expand All @@ -32,6 +35,7 @@ DeclareProperty("IsUndirectedForest", IsDigraph);
DeclareProperty("IsEdgeTransitive", IsDigraph);
DeclareProperty("IsVertexTransitive", IsDigraph);
DeclareProperty("IsEmptyDigraph", IsDigraph);
DeclareProperty("IsNonemptyDigraph", IsDigraph);
DeclareProperty("IsEulerianDigraph", IsDigraph);
DeclareProperty("IsFunctionalDigraph", IsDigraph);
DeclareProperty("IsHamiltonianDigraph", IsDigraph);
Expand Down Expand Up @@ -98,3 +102,49 @@ InstallTrueMethod(IsSymmetricDigraph, IsCompleteDigraph);
InstallTrueMethod(IsSymmetricDigraph, IsDigraph and IsUndirectedForest);
InstallTrueMethod(IsTransitiveDigraph, IsTournament and IsAcyclicDigraph);
InstallTrueMethod(IsUndirectedForest, IsDigraph and IsUndirectedTree);

InstallTrueMethod(IsNonemptyDigraph, IsDigraph and DigraphHasLoops);
InstallTrueMethod(DigraphHasLoops, IsReflexiveDigraph and DigraphHasAVertex);
InstallTrueMethod(DigraphHasAVertex, IsDigraph and IsNonemptyDigraph);
InstallTrueMethod(DigraphHasAVertex, IsDigraph and IsDirectedTree);

# Implications that something is false

InstallTrueMethod(HasDigraphHasLoops, IsAcyclicDigraph);
InstallTrueMethod(HasDigraphHasLoops, IsTournament);
InstallTrueMethod(HasDigraphHasLoops, IsUndirectedForest);
InstallTrueMethod(HasDigraphHasLoops, IsDirectedTree);
InstallTrueMethod(HasDigraphHasLoops, IsEmptyDigraph);
InstallTrueMethod(HasDigraphHasLoops, IsCompleteDigraph and IsNonemptyDigraph);
InstallTrueMethod(HasDigraphHasLoops, IsBipartiteDigraph);

InstallTrueMethod(HasIsNonemptyDigraph, IsEmptyDigraph);
InstallTrueMethod(HasIsEmptyDigraph, IsNonemptyDigraph);
InstallTrueMethod(HasDigraphHasAVertex, DigraphHasNoVertices);
InstallTrueMethod(HasDigraphHasNoVertices, DigraphHasAVertex);

InstallTrueMethod(HasIsAcyclicDigraph, IsCompleteDigraph and IsNonemptyDigraph);
InstallTrueMethod(HasIsAcyclicDigraph, IsDigraph and DigraphHasLoops);
InstallTrueMethod(HasIsAcyclicDigraph,
IsStronglyConnectedDigraph and IsNonemptyDigraph);
InstallTrueMethod(HasIsAntisymmetricDigraph,
IsCompleteDigraph and IsNonemptyDigraph);
InstallTrueMethod(HasIsChainDigraph, IsDigraph and DigraphHasLoops);
InstallTrueMethod(HasIsChainDigraph, IsSymmetricDigraph and IsNonemptyDigraph);
InstallTrueMethod(HasIsCompleteDigraph, IsDigraph and DigraphHasLoops);
InstallTrueMethod(HasIsReflexiveDigraph,
IsAcyclicDigraph and DigraphHasAVertex);

InstallTrueMethod(HasIsSymmetricDigraph, IsDirectedTree and IsNonemptyDigraph);
InstallTrueMethod(HasIsSymmetricDigraph, IsTournament and IsNonemptyDigraph);
InstallTrueMethod(HasIsSymmetricDigraph,
IsAcyclicDigraph and IsNonemptyDigraph);

InstallTrueMethod(HasIsMultiDigraph, IsChainDigraph);
InstallTrueMethod(HasIsMultiDigraph, IsCompleteDigraph);
InstallTrueMethod(HasIsMultiDigraph, IsCompleteMultipartiteDigraph);
InstallTrueMethod(HasIsMultiDigraph, IsCycleDigraph);
InstallTrueMethod(HasIsMultiDigraph, IsEmptyDigraph);
InstallTrueMethod(HasIsMultiDigraph, IsFunctionalDigraph);
InstallTrueMethod(HasIsMultiDigraph, IsTournament);
InstallTrueMethod(HasIsMultiDigraph, IsUndirectedForest);
17 changes: 13 additions & 4 deletions gap/prop.gi
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#############################################################################
##
## prop.gi
## Copyright (C) 2014-19 James D. Mitchell
## Copyright (C) 2014-21 James D. Mitchell
##
## Licensing information can be found in the README file of this package.
##
Expand All @@ -13,12 +13,21 @@ InstallMethod(IsMultiDigraph, "for a digraph by out-neighbours",
[IsDigraphByOutNeighboursRep],
IS_MULTI_DIGRAPH);

InstallMethod(DigraphHasNoVertices, "for a digraph", [IsDigraph],
D -> not DigraphHasAVertex(D));

InstallMethod(DigraphHasAVertex, "for a digraph", [IsDigraph],
D -> DigraphNrVertices(D) > 0);

InstallMethod(IsNonemptyDigraph, "for a digraph", [IsDigraph],
D -> not IsEmptyDigraph(D));

InstallMethod(IsChainDigraph, "for a digraph", [IsDigraph],
D -> IsDirectedTree(D) and IsSubset([0, 1], OutDegreeSet(D)));

InstallMethod(IsCycleDigraph, "for a digraph", [IsDigraph],
function(D)
return DigraphNrVertices(D) > 0
return DigraphHasAVertex(D)
and DigraphNrEdges(D) = DigraphNrVertices(D)
and IsStronglyConnectedDigraph(D);
end);
Expand Down Expand Up @@ -384,8 +393,8 @@ D -> DigraphNrEdges(D) = 2 * (DigraphNrVertices(D) - 1)

InstallMethod(IsUndirectedForest, "for a digraph", [IsDigraph],
function(D)
if not IsSymmetricDigraph(D) or DigraphNrVertices(D) = 0
or IsMultiDigraph(D) then
if DigraphHasNoVertices(D) or not IsSymmetricDigraph(D) or IsMultiDigraph(D)
then
return false;
fi;
return ForAll(DigraphConnectedComponents(D).comps,
Expand Down
Loading