From 0ecef0884673fb6f8043c02ffd39129b2c47dae4 Mon Sep 17 00:00:00 2001 From: Wilf Wilson Date: Wed, 16 Feb 2022 09:28:11 +0000 Subject: [PATCH 1/6] Cygwin CI: use windows-2019 explicitly (not windows-latest) --- .github/workflows/gap.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gap.yml b/.github/workflows/gap.yml index 8e10a3fc9..ddbb704a8 100644 --- a/.github/workflows/gap.yml +++ b/.github/workflows/gap.yml @@ -86,7 +86,7 @@ jobs: test-cygwin: name: "cygwin / GAP master" - runs-on: windows-latest + runs-on: windows-2019 if: ${{ !(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) }} env: CHERE_INVOKING: 1 From 7d7e3bc574ef48c837e3b9564742c0d0adb511c0 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Sun, 13 Mar 2022 22:55:57 +0100 Subject: [PATCH 2/6] Fix compatibility with grape When starting GAP with `-A`, then first loading digraphs and afterwards loading grape, the following error was produced: Error, variable `Vertices' is not bound to an operation at GAPROOT/lib/oper.g:940 called from ( ) called from read-eval loop at GAPROOT/pkg/grape-4.8.5/lib/grape.g:566 you can 'quit;' to quit to outer loop, or you can 'return;' to continue --- init.g | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init.g b/init.g index 58acdd12a..da5a0a1ba 100644 --- a/init.g +++ b/init.g @@ -32,7 +32,7 @@ if not IsBound(IsGraph) then IsGraph := ReturnFalse; fi; if not IsBound(Vertices) then - Vertices := IdFunc; + DeclareOperation("Vertices", [IsRecord]); fi; if not IsBound(Adjacency) then Adjacency := IdFunc; From eaf60ce67e24c300657f2fdc21456e54af010591 Mon Sep 17 00:00:00 2001 From: Wilf Wilson Date: Tue, 29 Mar 2022 12:16:30 +0100 Subject: [PATCH 3/6] Prepare for v1.5.1 release --- .VERSION | 2 +- CHANGELOG.md | 11 ++++++++++- PackageInfo.g | 12 ++++++------ VERSIONS | 3 ++- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/.VERSION b/.VERSION index bc80560fa..26ca59460 100644 --- a/.VERSION +++ b/.VERSION @@ -1 +1 @@ -1.5.0 +1.5.1 diff --git a/CHANGELOG.md b/CHANGELOG.md index ea6eba437..0721e6b27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,18 @@ # CHANGELOG – Digraphs package for GAP -Copyright © 2014-21 by Jan De Beule, Julius Jonušas, James D. Mitchell, +Copyright © 2014-22 by Jan De Beule, Julius Jonušas, James D. Mitchell, Wilf A. Wilson, Michael Young et al. Licensing information can be found in the `LICENSE` file. +## Version 1.5.1 (released 29/03/2022) + +This minor release contains several bugfixes and technical changes. This includes: + +* Bugfix: vertex labels are no longer wrongly retained when using `DigraphEdgeUnion`. This was reported by [Wilf A. Wilson][] in [Issue #496](https://github.com/digraphs/Digraphs/issues/496) and fixed by Joseph Edwards in [PR #507](https://github.com/digraphs/Digraphs/pull/507). +* Bugfix: a segfault could be caused by calling `OutNeighbours` with an inappropriate argument. This was reported by [Wilf A. Wilson][] in [Issue #518](https://github.com/digraphs/Digraphs/issues/518) and fixed by [James D. Mitchell][] in [PR #519](https://github.com/digraphs/Digraphs/pull/519). +* [Wilf A. Wilson][] improved the performance of `DigraphAddEdge` for digraphs without edge labels in [PR #509](https://github.com/digraphs/Digraphs/pull/509). +* [Max Horn][] changed the declaration of the variable `Vertices` to improve compatibility with Grape in [PR #530](https://github.com/digraphs/Digraphs/pull/530). + ## Version 1.5.0 (released 27/10/2021) This is a fairly major release of the Digraphs package, containing some bugfixes and several new features. diff --git a/PackageInfo.g b/PackageInfo.g index aa97bc319..3fe075a3c 100644 --- a/PackageInfo.g +++ b/PackageInfo.g @@ -1,7 +1,7 @@ ############################################################################# ## ## PackageInfo.g -## Copyright (C) 2015-21 James D. Mitchell +## Copyright (C) 2015-22 James D. Mitchell ## ## Licensing information can be found in the README.md file of this package. ## @@ -9,15 +9,15 @@ ## ## <#GAPDoc Label="PKGVERSIONDATA"> -## +## ## ## ## ## ## ## -## -## +## +## ## <#/GAPDoc> _STANDREWSMATHS := Concatenation(["Mathematical Institute, North Haugh, ", @@ -28,8 +28,8 @@ _STANDREWSCS := Concatenation(["Jack Cole Building, North Haugh, ", SetPackageInfo(rec( PackageName := "Digraphs", Subtitle := "Graphs, digraphs, and multidigraphs in GAP", -Version := "1.5.0", -Date := "27/10/2021", # dd/mm/yyyy format +Version := "1.5.1", +Date := "29/03/2022", # dd/mm/yyyy format License := "GPL-3.0-or-later", ArchiveFormats := ".tar.gz", diff --git a/VERSIONS b/VERSIONS index 22cee7c0f..d50da6177 100644 --- a/VERSIONS +++ b/VERSIONS @@ -1,13 +1,14 @@ ############################################################################# ## #W VERSIONS -#Y Copyright (C) 2015-21 James D. Mitchell +#Y Copyright (C) 2015-22 James D. Mitchell ## ## Licensing information can be found in the README.md file of this package. ## ############################################################################# ## +release 1.5.1 - 29/03/2022 release 1.5.0 - 27/10/2021 release 1.4.1 - 14/05/2021 release 1.4.0 - 27/01/2021 From bdd00fec7d276743d7864c505ea461d3aa5d78d8 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Tue, 29 Mar 2022 23:53:00 +0200 Subject: [PATCH 4/6] More fixes for loading grape after digraphs When loading digraphs before grape, then some code kept printing a warning saying "Grape is not loaded", even though grape was loaded. This patch fixes that. --- gap/grape.gi | 2 +- init.g | 2 +- read.g | 2 +- tst/standard/digraph.tst | 4 ++-- tst/standard/grape.tst | 8 ++++---- tst/testinstall.tst | 12 ++++++------ 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/gap/grape.gi b/gap/grape.gi index d4ec6f22d..3bdcd4421 100644 --- a/gap/grape.gi +++ b/gap/grape.gi @@ -132,7 +132,7 @@ function(D) "the Grape graph will have fewer\n#I edges than the original,"); fi; - if not DIGRAPHS_IsGrapeLoaded then + if not DIGRAPHS_IsGrapeLoaded() then Info(InfoWarning, 1, "Grape is not loaded,"); fi; diff --git a/init.g b/init.g index da5a0a1ba..8b02db573 100644 --- a/init.g +++ b/init.g @@ -25,7 +25,7 @@ if not IsBound(DIGRAPH_OUT_NBS) and fi; BindGlobal("DIGRAPHS_IsGrapeLoaded", - IsPackageMarkedForLoading("grape", "4.8.1")); + {} -> IsPackageMarkedForLoading("grape", "4.8.1")); # To avoid warnings when GRAPE is not loaded if not IsBound(IsGraph) then diff --git a/read.g b/read.g index c9a71258f..ce3a63a6f 100644 --- a/read.g +++ b/read.g @@ -8,7 +8,7 @@ ############################################################################# ## -if not DIGRAPHS_IsGrapeLoaded then +if not DIGRAPHS_IsGrapeLoaded() then Add(DIGRAPHS_OmitFromTests, "Graph("); fi; diff --git a/tst/standard/digraph.tst b/tst/standard/digraph.tst index 3ad78e781..642efba6a 100644 --- a/tst/standard/digraph.tst +++ b/tst/standard/digraph.tst @@ -211,7 +211,7 @@ gap> DigraphRange(gr); [ 2, 3, 2 ] gap> gr; -gap> if DIGRAPHS_IsGrapeLoaded then +gap> if DIGRAPHS_IsGrapeLoaded() then > g := Graph(gr); > if not Digraph(g) = gr then > Print("fail"); @@ -1627,7 +1627,7 @@ gap> MakeImmutable(D); # gap> D := NullDigraph(10); -gap> if DIGRAPHS_IsGrapeLoaded then +gap> if DIGRAPHS_IsGrapeLoaded() then > D := Graph(D); > if D <> rec( > adjacencies := [[]], diff --git a/tst/standard/grape.tst b/tst/standard/grape.tst index a121d7f68..ee7fca465 100644 --- a/tst/standard/grape.tst +++ b/tst/standard/grape.tst @@ -129,7 +129,7 @@ rec( adjacencies := [ [ 2, 4 ] ], group := Group([ (1,3), (1,2)(3,4) ]), schreierVector := [ -1, 2, 1, 2 ] ) # Digraph: copying group from Grape -gap> if DIGRAPHS_IsGrapeLoaded then +gap> if DIGRAPHS_IsGrapeLoaded() then > gr := Digraph(JohnsonGraph(5, 3)); > else > gr := JohnsonDigraph(5, 3); @@ -140,7 +140,7 @@ gap> HasDigraphGroup(gr); true gap> DigraphGroup(gr); Group([ (1,7,10,6,3)(2,8,4,9,5), (4,7)(5,8)(6,9) ]) -gap> if DIGRAPHS_IsGrapeLoaded then +gap> if DIGRAPHS_IsGrapeLoaded() then > gr := Digraph(CompleteGraph(Group((1, 2, 3), (1, 2)))); > else > gr := Digraph([[2, 3], [1, 3], [1, 2]]); @@ -150,7 +150,7 @@ gap> HasDigraphGroup(gr); true gap> DigraphGroup(gr); Group([ (1,2,3), (1,2) ]) -gap> if DIGRAPHS_IsGrapeLoaded then +gap> if DIGRAPHS_IsGrapeLoaded() then > gr := Digraph(Graph(Group([()]), > [1, 2, 3], > OnPoints, @@ -252,7 +252,7 @@ true # Graph gap> gr := Digraph([[2, 2], []]); -gap> if DIGRAPHS_IsGrapeLoaded then +gap> if DIGRAPHS_IsGrapeLoaded() then > Graph(gr); > fi; diff --git a/tst/testinstall.tst b/tst/testinstall.tst index db8b3d116..abbaad0e7 100644 --- a/tst/testinstall.tst +++ b/tst/testinstall.tst @@ -23,11 +23,11 @@ gap> OutNeighbours(gr); [ [ 8 ], [ 4, 5, 6, 8, 9 ], [ 2, 4, 5, 7, 10 ], [ 9 ], [ 1, 4, 6, 7, 9 ], [ 2, 3, 6, 7, 10 ], [ 3, 4, 5, 8, 9 ], [ 3, 4, 9, 10 ], [ 1, 2, 3, 5, 6, 9, 10 ], [ 2, 4, 5, 6, 9 ] ] -gap> not DIGRAPHS_IsGrapeLoaded -> or (DIGRAPHS_IsGrapeLoaded and Digraph(Graph(gr)) = gr); +gap> not DIGRAPHS_IsGrapeLoaded() +> or (DIGRAPHS_IsGrapeLoaded() and Digraph(Graph(gr)) = gr); true -gap> not DIGRAPHS_IsGrapeLoaded -> or (DIGRAPHS_IsGrapeLoaded and Graph(Digraph(Graph(gr))).adjacencies = +gap> not DIGRAPHS_IsGrapeLoaded() +> or (DIGRAPHS_IsGrapeLoaded() and Graph(Digraph(Graph(gr))).adjacencies = > Graph(gr).adjacencies); true gap> adj := [ @@ -38,8 +38,8 @@ gap> adj := [ > [1, 6, 8, 9, 11, 12, 13, 14], [2, 4, 7, 9, 10, 11, 13, 15, 16]];; gap> func := function(x, y) return y in adj[x]; end; function( x, y ) ... end -gap> not DIGRAPHS_IsGrapeLoaded or -> (DIGRAPHS_IsGrapeLoaded and +gap> not DIGRAPHS_IsGrapeLoaded() or +> (DIGRAPHS_IsGrapeLoaded() and > Digraph(Graph(Group(()), [1 .. 20], OnPoints, func, true)) = Digraph(adj)); true From ceb6c0d2d4cc8a76721e75c05a84d90ef1514f3e Mon Sep 17 00:00:00 2001 From: Wilf Wilson Date: Wed, 30 Mar 2022 10:37:58 +0100 Subject: [PATCH 5/6] Prepare for v1.5.2 release --- .VERSION | 2 +- CHANGELOG.md | 4 ++++ PackageInfo.g | 8 ++++---- VERSIONS | 1 + 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/.VERSION b/.VERSION index 26ca59460..4cda8f19e 100644 --- a/.VERSION +++ b/.VERSION @@ -1 +1 @@ -1.5.1 +1.5.2 diff --git a/CHANGELOG.md b/CHANGELOG.md index 0721e6b27..00b563dad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ Wilf A. Wilson, Michael Young et al. Licensing information can be found in the `LICENSE` file. +## Version 1.5.2 (released 30/03/2022) + +This is a very minor release containing technical changes for maintaining compatibility with other GAP packages. + ## Version 1.5.1 (released 29/03/2022) This minor release contains several bugfixes and technical changes. This includes: diff --git a/PackageInfo.g b/PackageInfo.g index 3fe075a3c..37e49dcc5 100644 --- a/PackageInfo.g +++ b/PackageInfo.g @@ -9,14 +9,14 @@ ## ## <#GAPDoc Label="PKGVERSIONDATA"> -## +## ## ## ## ## ## ## -## +## ## ## <#/GAPDoc> @@ -28,8 +28,8 @@ _STANDREWSCS := Concatenation(["Jack Cole Building, North Haugh, ", SetPackageInfo(rec( PackageName := "Digraphs", Subtitle := "Graphs, digraphs, and multidigraphs in GAP", -Version := "1.5.1", -Date := "29/03/2022", # dd/mm/yyyy format +Version := "1.5.2", +Date := "30/03/2022", # dd/mm/yyyy format License := "GPL-3.0-or-later", ArchiveFormats := ".tar.gz", diff --git a/VERSIONS b/VERSIONS index d50da6177..d37734bc2 100644 --- a/VERSIONS +++ b/VERSIONS @@ -8,6 +8,7 @@ ############################################################################# ## +release 1.5.2 - 30/03/2022 release 1.5.1 - 29/03/2022 release 1.5.0 - 27/10/2021 release 1.4.1 - 14/05/2021 From 69a6d9dd5f43afb0425e679c49fa7cb0db507fa2 Mon Sep 17 00:00:00 2001 From: Michael Young Date: Thu, 7 Apr 2022 18:21:00 +0100 Subject: [PATCH 6/6] Add DigraphRandomWalk with doc and tests --- doc/oper.xml | 30 ++++++++++++++++++++++++++++++ doc/z-chap4.xml | 1 + gap/oper.gd | 1 + gap/oper.gi | 35 +++++++++++++++++++++++++++++++++++ tst/standard/oper.tst | 30 ++++++++++++++++++++++++++++++ 5 files changed, 97 insertions(+) diff --git a/doc/oper.xml b/doc/oper.xml index 324951db2..f1c852436 100644 --- a/doc/oper.xml +++ b/doc/oper.xml @@ -1535,6 +1535,36 @@ gap> DigraphShortestPath(D, 1, 1); <#/GAPDoc> +<#GAPDoc Label="DigraphRandomWalk"> + + + A pair of lists. + + Returns a directed path corresponding to a random walk in the digraph + digraph, starting at vertex v and having length no more than + t. +

+ + A random walk is defined as follows. The path begins at v, and at + each step it follows a random edge leaving the current vertex. It continues + through the digraph in this way until it has traversed t edges, or + until it reaches a vertex with no out-edges (a sink) and therefore + cannot continue. +

+ + The output has the same form as that of . +

+ + D := Digraph([[1, 2], [3], [2, 4], [1], [2, 4]]); + +gap> DigraphRandomWalk(D, 1, 4); +[ [ 1, 2, 3, 2, 3 ], [ 2, 1, 1, 1 ] ] +]]> + + +<#/GAPDoc> + <#GAPDoc Label="IteratorOfPaths"> diff --git a/doc/z-chap4.xml b/doc/z-chap4.xml index 1524d671c..3689ed81d 100644 --- a/doc/z-chap4.xml +++ b/doc/z-chap4.xml @@ -68,6 +68,7 @@ <#Include Label="VerticesReachableFrom"> <#Include Label="DigraphPath"> <#Include Label="DigraphShortestPath"> + <#Include Label="DigraphRandomWalk"> <#Include Label="Dominators"> <#Include Label="DominatorTree"> <#Include Label="IteratorOfPaths"> diff --git a/gap/oper.gd b/gap/oper.gd index 45c48ea3c..5c1ea6046 100644 --- a/gap/oper.gd +++ b/gap/oper.gd @@ -125,6 +125,7 @@ DeclareOperation("IteratorOfPaths", [IsList, IsPosInt, IsPosInt]); DeclareOperation("IteratorOfPathsNC", [IsList, IsPosInt, IsPosInt]); DeclareOperation("IsReachable", [IsDigraph, IsPosInt, IsPosInt]); DeclareOperation("DigraphLongestDistanceFromVertex", [IsDigraph, IsPosInt]); +DeclareOperation("DigraphRandomWalk", [IsDigraph, IsPosInt, IsInt]); DeclareOperation("DigraphLayers", [IsDigraph, IsPosInt]); DeclareAttribute("DIGRAPHS_Layers", IsDigraph, "mutable"); diff --git a/gap/oper.gi b/gap/oper.gi index 2af8d27ac..b2426c308 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -1727,6 +1727,41 @@ function(D, v) return dist; end); +InstallMethod(DigraphRandomWalk, +"for a digraph, a pos int and a non-negative int", +[IsDigraph, IsPosInt, IsInt], +function(D, v, t) + local vertices, edge_indices, i, neighbours, index; + + # Check input + if v > DigraphNrVertices(D) then + ErrorNoReturn("the 2nd argument must be ", + "a vertex of the 1st argument ,"); + elif t < 0 then + ErrorNoReturn("the 3rd argument must be a non-negative int,"); + fi; + + # Prepare output lists + vertices := [v]; + edge_indices := []; + + # Iterate to desired length + for i in [1 .. t] do + neighbours := OutNeighboursOfVertex(D, v); + if IsEmpty(neighbours) then + break; # Sink: path ends here + fi; + # Follow a random edge + index := Random(1, Length(neighbours)); + v := neighbours[index]; + vertices[i + 1] := v; + edge_indices[i] := index; + od; + + # Format matches that of DigraphPath + return [vertices, edge_indices]; +end); + InstallMethod(DigraphLayers, "for a digraph, and a positive integer", [IsDigraph, IsPosInt], function(D, v) diff --git a/tst/standard/oper.tst b/tst/standard/oper.tst index 4c4aedf0a..5807a45d0 100644 --- a/tst/standard/oper.tst +++ b/tst/standard/oper.tst @@ -1443,6 +1443,36 @@ infinity gap> DigraphLongestDistanceFromVertex(gr, 16); Error, the 2nd argument must be a vertex of the 1st argument , +# DigraphRandomWalk +gap> gr := CompleteDigraph(5); + +gap> path := DigraphRandomWalk(gr, 1, 100);; +gap> Length(path[1]); +101 +gap> ForAll(path[1], i -> i in [1 .. 5]); +true +gap> Length(path[2]); +100 +gap> ForAll(path[2], i -> i in [1 .. 4]); +true +gap> gr := ChainDigraph(5); + +gap> DigraphRandomWalk(gr, 2, 100); +[ [ 2, 3, 4, 5 ], [ 1, 1, 1 ] ] +gap> DigraphRandomWalk(gr, 2, 2); +[ [ 2, 3, 4 ], [ 1, 1 ] ] +gap> DigraphRandomWalk(gr, 5, 100); +[ [ 5 ], [ ] ] +gap> gr := CompleteBipartiteDigraph(10, 8);; +gap> DigraphRandomWalk(gr, 3, 0); +[ [ 3 ], [ ] ] +gap> DigraphRandomWalk(gr, 19, 5); +Error, the 2nd argument must be a vertex of the 1st argument , +gap> DigraphRandomWalk(gr, 123, 5); +Error, the 2nd argument must be a vertex of the 1st argument , +gap> DigraphRandomWalk(gr, 3, -1); +Error, the 3rd argument must be a non-negative int, + # DigraphLayers gap> gr := CompleteDigraph(4);