From e28a2e6611d2696b512c1181cd775ba8a89d7c9d Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 30 Jan 2024 22:29:14 +0000 Subject: [PATCH 01/60] Add VerticesReachableFrom and IsOrderIdeal --- gap/oper.gd | 1 + gap/oper.gi | 54 +++++++++++++++++++++++++++++++++++++++++++ tst/standard/oper.tst | 21 +++++++++++++++++ 3 files changed, 76 insertions(+) diff --git a/gap/oper.gd b/gap/oper.gd index 5c1ea6046..c2bfd9fce 100644 --- a/gap/oper.gd +++ b/gap/oper.gd @@ -137,6 +137,7 @@ DeclareOperation("DigraphShortestDistance", [IsDigraph, IsList]); DeclareOperation("DigraphShortestPath", [IsDigraph, IsPosInt, IsPosInt]); DeclareOperation("DigraphShortestPathSpanningTree", [IsDigraph, IsPosInt]); DeclareOperation("VerticesReachableFrom", [IsDigraph, IsPosInt]); +DeclareOperation("VerticesReachableFrom", [IsDigraph, IsList]); DeclareOperation("Dominators", [IsDigraph, IsPosInt]); DeclareOperation("DominatorTree", [IsDigraph, IsPosInt]); diff --git a/gap/oper.gi b/gap/oper.gi index 5186a7d3f..b9c0ee466 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2043,6 +2043,60 @@ function(D, root) return visited; end); +InstallMethod(VerticesReachableFrom, "for a digraph and a list of vertices", +[IsDigraph, IsList], +function(D, roots) + local accessible_from_node, candidate, root, i, visited, visited_as_ints, N; + N := DigraphNrVertices(D); + visited := BlistList([1..N], []); + for root in roots do + if not(visited[root]) then + accessible_from_node := VerticesReachableFrom(D, root); + for candidate in accessible_from_node do + if not(visited[candidate]) then + visited[candidate] :=true; + fi; + od; + fi; + od; + + visited_as_ints := []; + + for i in [1..N] do + if visited[i] then; + Add(visited_as_ints, i); + fi; + od; + + return visited_as_ints; +end); + +InstallMethod(IsOrderIdeal, "for a digraph and a list of vertices", +[IsDigraph, IsList], +# Check if digraph represents a partial order +function(D, roots) + local reachable_vertices, N; + if not(IsPartialOrderDigraph(D)) then + ErrorNoReturn("the 1st element (a digraph) must be a partial order digraph"); + fi; + + N := Length(roots); + vertex_in_subset := BlistList([1..N], []); + reachable := VerticesReachableFrom(D, roots); + + for i in roots do + vertex_in_subset[i] := true; + od; + + for i in reachable_vertices do + if(not(vertex_in_subset[i])) then + return false; + fi; + od; + + return Length(reachable) == Length(reachable); +end); + InstallMethod(DominatorTree, "for a digraph and a vertex", [IsDigraph, IsPosInt], function(D, root) diff --git a/tst/standard/oper.tst b/tst/standard/oper.tst index 80086203b..9453bf0f1 100644 --- a/tst/standard/oper.tst +++ b/tst/standard/oper.tst @@ -2797,6 +2797,27 @@ gap> path := DigraphPath(D, 5, 5);; gap> IsDigraphPath(D, path); true +gap> D1 := CompleteDigraph(5); + +gap> D2 := CompleteDigraph(10); + +gap> VerticesReachableFrom(D1, [1]); +[ 1, 2, 3, 4, 5 ] +gap> VerticesReachableFrom(D1, [1,2]); +[ 1, 2, 3, 4, 5 ] +gap> VerticesReachableFrom(D2, [1]); +[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] +gap> D3 := CompleteDigraph(7); + +gap> D3_edges := [1..7]; +[ 1 .. 7 ] +gap> for i in D3_edges do +> D3 := DigraphRemoveEdge(D3, [1, i]); +> D3 := DigraphRemoveEdge(D3, [i, 1]); +> od; +gap> VerticesReachableFrom(D3, [1]); +[ ] + # DIGRAPHS_UnbindVariables gap> Unbind(C); gap> Unbind(D); From 591b69b2ad75a7cad1a5cf32907bef3b7f5dd434 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 30 Jan 2024 22:48:03 +0000 Subject: [PATCH 02/60] Unbind variables in oper.tst --- tst/standard/oper.tst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tst/standard/oper.tst b/tst/standard/oper.tst index 9453bf0f1..1028b80b5 100644 --- a/tst/standard/oper.tst +++ b/tst/standard/oper.tst @@ -2823,6 +2823,8 @@ gap> Unbind(C); gap> Unbind(D); gap> Unbind(D1); gap> Unbind(D2); +gap> Unbind(D3); +gap> Unbind(D3_edges); gap> Unbind(DD); gap> Unbind(G); gap> Unbind(G1); From 7bb968ae25372d819dc9d6503be85aa69f148ff2 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 30 Jan 2024 23:10:56 +0000 Subject: [PATCH 03/60] Add IsOrderIdeal --- gap/oper.gd | 1 + 1 file changed, 1 insertion(+) diff --git a/gap/oper.gd b/gap/oper.gd index c2bfd9fce..5594ea8c8 100644 --- a/gap/oper.gd +++ b/gap/oper.gd @@ -138,6 +138,7 @@ DeclareOperation("DigraphShortestPath", [IsDigraph, IsPosInt, IsPosInt]); DeclareOperation("DigraphShortestPathSpanningTree", [IsDigraph, IsPosInt]); DeclareOperation("VerticesReachableFrom", [IsDigraph, IsPosInt]); DeclareOperation("VerticesReachableFrom", [IsDigraph, IsList]); +DeclareOperation("IsOrderIdeal", [IsDigraph, IsList]); DeclareOperation("Dominators", [IsDigraph, IsPosInt]); DeclareOperation("DominatorTree", [IsDigraph, IsPosInt]); From 37feffc4adb5ae5cf33a6d30f47039c067880ad2 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Wed, 31 Jan 2024 03:17:25 +0000 Subject: [PATCH 04/60] Fix linting (maybe) --- gap/oper.gi | 8 ++++---- tst/standard/oper.tst | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/gap/oper.gi b/gap/oper.gi index b9c0ee466..3a743cd08 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2048,13 +2048,13 @@ InstallMethod(VerticesReachableFrom, "for a digraph and a list of vertices", function(D, roots) local accessible_from_node, candidate, root, i, visited, visited_as_ints, N; N := DigraphNrVertices(D); - visited := BlistList([1..N], []); + visited := BlistList([1 .. N], []); for root in roots do if not(visited[root]) then accessible_from_node := VerticesReachableFrom(D, root); for candidate in accessible_from_node do if not(visited[candidate]) then - visited[candidate] :=true; + visited[candidate] := true; fi; od; fi; @@ -2062,7 +2062,7 @@ function(D, roots) visited_as_ints := []; - for i in [1..N] do + for i in [1 .. N] do if visited[i] then; Add(visited_as_ints, i); fi; @@ -2081,7 +2081,7 @@ function(D, roots) fi; N := Length(roots); - vertex_in_subset := BlistList([1..N], []); + vertex_in_subset := BlistList([1 .. N], []); reachable := VerticesReachableFrom(D, roots); for i in roots do diff --git a/tst/standard/oper.tst b/tst/standard/oper.tst index 1028b80b5..10b427f90 100644 --- a/tst/standard/oper.tst +++ b/tst/standard/oper.tst @@ -2803,13 +2803,13 @@ gap> D2 := CompleteDigraph(10); gap> VerticesReachableFrom(D1, [1]); [ 1, 2, 3, 4, 5 ] -gap> VerticesReachableFrom(D1, [1,2]); +gap> VerticesReachableFrom(D1, [1, 2]); [ 1, 2, 3, 4, 5 ] gap> VerticesReachableFrom(D2, [1]); [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] gap> D3 := CompleteDigraph(7); -gap> D3_edges := [1..7]; +gap> D3_edges := [1 .. 7]; [ 1 .. 7 ] gap> for i in D3_edges do > D3 := DigraphRemoveEdge(D3, [1, i]); From 01dc63c1266c85454bf1632724b1da7aaf8231e3 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Wed, 31 Jan 2024 13:35:10 +0000 Subject: [PATCH 05/60] Fix syntax errors --- gap/oper.gi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gap/oper.gi b/gap/oper.gi index 3a743cd08..82e129469 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2075,7 +2075,7 @@ InstallMethod(IsOrderIdeal, "for a digraph and a list of vertices", [IsDigraph, IsList], # Check if digraph represents a partial order function(D, roots) - local reachable_vertices, N; + local reachable_vertices, vertex_in_subset, i, N; if not(IsPartialOrderDigraph(D)) then ErrorNoReturn("the 1st element (a digraph) must be a partial order digraph"); fi; @@ -2094,7 +2094,7 @@ function(D, roots) fi; od; - return Length(reachable) == Length(reachable); + return Length(reachable) = Length(roots); end); InstallMethod(DominatorTree, "for a digraph and a vertex", From 10d93af5e0f67efd9b1b73b49c5a8ce49f259866 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Wed, 31 Jan 2024 14:09:46 +0000 Subject: [PATCH 06/60] Change variable name --- gap/oper.gi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gap/oper.gi b/gap/oper.gi index 82e129469..0f05885eb 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2094,7 +2094,7 @@ function(D, roots) fi; od; - return Length(reachable) = Length(roots); + return Length(reachable_vertices) = Length(roots); end); InstallMethod(DominatorTree, "for a digraph and a vertex", From c998c753606be1020b6b5a03a7edf9ea2afd50ee Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Wed, 31 Jan 2024 14:13:14 +0000 Subject: [PATCH 07/60] Fix variable --- gap/oper.gi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gap/oper.gi b/gap/oper.gi index 0f05885eb..a40d82511 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2082,7 +2082,7 @@ function(D, roots) N := Length(roots); vertex_in_subset := BlistList([1 .. N], []); - reachable := VerticesReachableFrom(D, roots); + reachable_vertices := VerticesReachableFrom(D, roots); for i in roots do vertex_in_subset[i] := true; From c9b35d4699d5e5366c90db2acded1eb08d2cb984 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Wed, 31 Jan 2024 14:18:58 +0000 Subject: [PATCH 08/60] Fix test file --- tst/standard/oper.tst | 1 - 1 file changed, 1 deletion(-) diff --git a/tst/standard/oper.tst b/tst/standard/oper.tst index 10b427f90..4882d64c0 100644 --- a/tst/standard/oper.tst +++ b/tst/standard/oper.tst @@ -2796,7 +2796,6 @@ gap> D := Digraph([ gap> path := DigraphPath(D, 5, 5);; gap> IsDigraphPath(D, path); true - gap> D1 := CompleteDigraph(5); gap> D2 := CompleteDigraph(10); From 7f0bb1fa3bb4af577b9bee1bf2a3241207c993fe Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Wed, 31 Jan 2024 15:53:09 +0000 Subject: [PATCH 09/60] Add IsOrderIdeal test --- gap/oper.gi | 1 - tst/standard/oper.tst | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/gap/oper.gi b/gap/oper.gi index a40d82511..49967f9f1 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2083,7 +2083,6 @@ function(D, roots) N := Length(roots); vertex_in_subset := BlistList([1 .. N], []); reachable_vertices := VerticesReachableFrom(D, roots); - for i in roots do vertex_in_subset[i] := true; od; diff --git a/tst/standard/oper.tst b/tst/standard/oper.tst index 4882d64c0..96339aa58 100644 --- a/tst/standard/oper.tst +++ b/tst/standard/oper.tst @@ -2816,6 +2816,10 @@ gap> for i in D3_edges do > od; gap> VerticesReachableFrom(D3, [1]); [ ] +gap> TestPartialOrderDigraph := Digraph([[1, 3], [2, 3], [3]]); + +gap> IsOrderIdeal(TestPartialOrderDigraph, [ 1,2,3 ]); +true # DIGRAPHS_UnbindVariables gap> Unbind(C); @@ -2876,6 +2880,7 @@ gap> Unbind(tclosure); gap> Unbind(u1); gap> Unbind(u2); gap> Unbind(x); +gap> Unbind(IsPartialOrderDigraph); # gap> DIGRAPHS_StopTest(); From 40e0aa890d18856bd72f0078eafdcbfa9ec7619d Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Wed, 31 Jan 2024 16:01:09 +0000 Subject: [PATCH 10/60] Update tests to test IsOrderIdeal --- tst/standard/oper.tst | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tst/standard/oper.tst b/tst/standard/oper.tst index 96339aa58..e8339bcff 100644 --- a/tst/standard/oper.tst +++ b/tst/standard/oper.tst @@ -2820,6 +2820,16 @@ gap> TestPartialOrderDigraph := Digraph([[1, 3], [2, 3], [3]]); gap> IsOrderIdeal(TestPartialOrderDigraph, [ 1,2,3 ]); true +gap> TestPartialOrderDigraph2 := Digraph([[1, 3], [2, 3], [3]]); + +gap> TestUnion := DigraphDisjointUnion(TestPartialOrderDigraph, TestPartialOrderDigraph2); + +gap> IsOrderIdeal(TestUnion, [ 1,2,3 ]); +true +gap> IsOrderIdeal(TestUnion, [ 4,5,6 ]); +true +gap> IsOrderIdeal(TestUnion, [ 1,5,6 ]); +false # DIGRAPHS_UnbindVariables gap> Unbind(C); @@ -2880,7 +2890,7 @@ gap> Unbind(tclosure); gap> Unbind(u1); gap> Unbind(u2); gap> Unbind(x); -gap> Unbind(IsPartialOrderDigraph); +gap> Unbind(TestPartialOrderDigraph); # gap> DIGRAPHS_StopTest(); From 89a960bf70b2aa81a849ee36f29af2b429b0d8c7 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Wed, 31 Jan 2024 16:11:24 +0000 Subject: [PATCH 11/60] Add Documentation --- doc/oper.xml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/doc/oper.xml b/doc/oper.xml index 1bd1fc966..39922acbc 100644 --- a/doc/oper.xml +++ b/doc/oper.xml @@ -1395,6 +1395,38 @@ gap> VerticesReachableFrom(D, 5); ]]> + + + + A list. + + This operation returns a list of the vertices v, for which there exists + a non-trivial directed walk from any of the provided roots to vertex v in the digraph + digraph. See Section + for the definition of a non-trivial directed walk. +

+ + D := CompleteDigraph(5); + +gap> VerticesReachableFrom(D, [1]); +[ 2, 1, 3, 4, 5 ] +gap> VerticesReachableFrom(D, [3]); +[ 1, 2, 3, 4, 5 ] +gap> D := EmptyDigraph(5); + +gap> VerticesReachableFrom(D, [1,2,3,4]); +[ ] +gap> VerticesReachableFrom(D, [3,4,5,6]); +[ ] +gap> D := ChainDigraph(5); + +gap> VerticesReachableFrom(D, [3, 4]); +[ 4, 5 ] +]]> + + + <#/GAPDoc> From f7e373000aeb4c7bb8a7c0a085456304e0cfc92a Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Wed, 31 Jan 2024 16:13:44 +0000 Subject: [PATCH 12/60] Fix spacing in documentation --- doc/oper.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/oper.xml b/doc/oper.xml index 39922acbc..ff7e566b1 100644 --- a/doc/oper.xml +++ b/doc/oper.xml @@ -1415,9 +1415,9 @@ gap> VerticesReachableFrom(D, [3]); [ 1, 2, 3, 4, 5 ] gap> D := EmptyDigraph(5); -gap> VerticesReachableFrom(D, [1,2,3,4]); +gap> VerticesReachableFrom(D, [1, 2, 3, 4]); [ ] -gap> VerticesReachableFrom(D, [3,4,5,6]); +gap> VerticesReachableFrom(D, [3, 4, 5, 6]); [ ] gap> D := ChainDigraph(5); From 45e9adc360b6ddcfa525739f75ee28f563129c70 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Wed, 31 Jan 2024 16:15:13 +0000 Subject: [PATCH 13/60] Add spaces to test file --- tst/standard/oper.tst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tst/standard/oper.tst b/tst/standard/oper.tst index e8339bcff..76f982a65 100644 --- a/tst/standard/oper.tst +++ b/tst/standard/oper.tst @@ -2818,17 +2818,17 @@ gap> VerticesReachableFrom(D3, [1]); [ ] gap> TestPartialOrderDigraph := Digraph([[1, 3], [2, 3], [3]]); -gap> IsOrderIdeal(TestPartialOrderDigraph, [ 1,2,3 ]); +gap> IsOrderIdeal(TestPartialOrderDigraph, [ 1, 2, 3 ]); true gap> TestPartialOrderDigraph2 := Digraph([[1, 3], [2, 3], [3]]); gap> TestUnion := DigraphDisjointUnion(TestPartialOrderDigraph, TestPartialOrderDigraph2); -gap> IsOrderIdeal(TestUnion, [ 1,2,3 ]); +gap> IsOrderIdeal(TestUnion, [ 1, 2, 3 ]); true -gap> IsOrderIdeal(TestUnion, [ 4,5,6 ]); +gap> IsOrderIdeal(TestUnion, [ 4, 5, 6 ]); true -gap> IsOrderIdeal(TestUnion, [ 1,5,6 ]); +gap> IsOrderIdeal(TestUnion, [ 1, 5, 6 ]); false # DIGRAPHS_UnbindVariables From bf0d9b49564d3c396397f68b3dee85c5d9cd5883 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Wed, 31 Jan 2024 16:17:54 +0000 Subject: [PATCH 14/60] Fix formatting --- tst/standard/oper.tst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tst/standard/oper.tst b/tst/standard/oper.tst index 76f982a65..dc390770b 100644 --- a/tst/standard/oper.tst +++ b/tst/standard/oper.tst @@ -2818,17 +2818,17 @@ gap> VerticesReachableFrom(D3, [1]); [ ] gap> TestPartialOrderDigraph := Digraph([[1, 3], [2, 3], [3]]); -gap> IsOrderIdeal(TestPartialOrderDigraph, [ 1, 2, 3 ]); +gap> IsOrderIdeal(TestPartialOrderDigraph, [1, 2, 3]); true gap> TestPartialOrderDigraph2 := Digraph([[1, 3], [2, 3], [3]]); gap> TestUnion := DigraphDisjointUnion(TestPartialOrderDigraph, TestPartialOrderDigraph2); -gap> IsOrderIdeal(TestUnion, [ 1, 2, 3 ]); +gap> IsOrderIdeal(TestUnion, [1, 2, 3]); true -gap> IsOrderIdeal(TestUnion, [ 4, 5, 6 ]); +gap> IsOrderIdeal(TestUnion, [4, 5, 6]); true -gap> IsOrderIdeal(TestUnion, [ 1, 5, 6 ]); +gap> IsOrderIdeal(TestUnion, [1, 5, 6]); false # DIGRAPHS_UnbindVariables From 31f4c5d14e1d6efb1f951676f53f8665e88a2043 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Wed, 31 Jan 2024 16:26:25 +0000 Subject: [PATCH 15/60] Fix documentation examples --- doc/oper.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/oper.xml b/doc/oper.xml index ff7e566b1..435763c1e 100644 --- a/doc/oper.xml +++ b/doc/oper.xml @@ -1410,14 +1410,14 @@ gap> VerticesReachableFrom(D, 5); gap> D := CompleteDigraph(5); gap> VerticesReachableFrom(D, [1]); -[ 2, 1, 3, 4, 5 ] +[ 1, 2, 3, 4, 5 ] gap> VerticesReachableFrom(D, [3]); [ 1, 2, 3, 4, 5 ] gap> D := EmptyDigraph(5); gap> VerticesReachableFrom(D, [1, 2, 3, 4]); [ ] -gap> VerticesReachableFrom(D, [3, 4, 5, 6]); +gap> VerticesReachableFrom(D, [3, 4, 5]); [ ] gap> D := ChainDigraph(5); From c8b59e30a0a7abaa56a2cb5b3528e64c259d16f6 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Wed, 31 Jan 2024 16:34:33 +0000 Subject: [PATCH 16/60] Add IsOrderIdeal documentation --- doc/oper.xml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/doc/oper.xml b/doc/oper.xml index 435763c1e..c91e484f8 100644 --- a/doc/oper.xml +++ b/doc/oper.xml @@ -2289,3 +2289,30 @@ true <#/GAPDoc> + +<#GAPDoc Label="IsOrderIdeal"> + + + true or false. + + This function returns true if the specified subset is "downwards" closed, i.e. contains every node less than the given nodes. + + TestPartialOrderDigraph := Digraph([[1, 3], [2, 3], [3]]); + +gap> TestPartialOrderDigraph2 := Digraph([[1, 3], [2, 3], [3]]); + +gap> IsOrderIdeal(TestPartialOrderDigraph, [1, 2, 3]); +true +gap> TestUnion := DigraphDisjointUnion(TestPartialOrderDigraph, TestPartialOrderDigraph2); + +gap> IsOrderIdeal(TestUnion, [1, 2, 3]); +true +gap> IsOrderIdeal(TestUnion, [4, 5, 6]); +true +gap> IsOrderIdeal(TestUnion, [1, 5, 6]); +false +]]> + + +<#/GAPDoc> From 2b8cb5c3ee7ea33ddd776bb7a44ffe45c111ffc4 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 6 Feb 2024 15:08:37 +0000 Subject: [PATCH 17/60] Switch to bfs approach --- gap/oper.gi | 62 +++++++++++++++++++++++++---------------------------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/gap/oper.gi b/gap/oper.gi index 49967f9f1..db0b86878 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2003,44 +2003,40 @@ function(D, v) end); InstallMethod(VerticesReachableFrom, "for a digraph and a vertex", -[IsDigraph, IsPosInt], -function(D, root) +[IsDigraph, IsList], +function(D, roots) local N, index, current, succ, visited, prev, n, i, parent, have_visited_root; N := DigraphNrVertices(D); - if 0 = root or root > N then - ErrorNoReturn("the 2nd argument (root) is not a vertex of the 1st ", - "argument (a digraph)"); - fi; - index := ListWithIdenticalEntries(N, 0); - have_visited_root := false; - index[root] := 1; - current := root; - succ := OutNeighbours(D); - visited := []; - parent := []; - parent[root] := fail; - repeat - prev := current; - for i in [index[current] .. Length(succ[current])] do - n := succ[current][i]; - if n = root and not have_visited_root then - Add(visited, root); - have_visited_root := true; - elif index[n] = 0 then - Add(visited, n); - parent[n] := current; - index[current] := i + 1; - current := n; - index[current] := 1; - break; - fi; + visited := BlistList([1 .. N], []); + # if 0 = root or root > N then + # ErrorNoReturn("the 2nd argument (root) is not a vertex of the 1st ", + # "argument (a digraph)"); + # fi; + + queue := []; + for root in roots do + Add(queue, root) # TODO: Structure differently for complexity reasons + end; + + index = 0 + while index <= Length(queue) do + element = queue[index] + neighbours := OutNeighbors(element); + for neighbour in neighbours do + visited[neighbours] = 1; + Add(queue, neighbour); od; - if prev = current then - current := parent[current]; + index +=1; + od; + + visited_as_ints := []; + + for i in [1 .. N] do + if visited[i] then; + Add(visited_as_ints, i); fi; - until current = fail; - return visited; + od; end); InstallMethod(VerticesReachableFrom, "for a digraph and a list of vertices", From 65d371948a6ee0b1f8e2a501a08baaddf8baf68c Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 6 Feb 2024 15:14:24 +0000 Subject: [PATCH 18/60] Fix syntax --- gap/oper.gi | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gap/oper.gi b/gap/oper.gi index db0b86878..b361cc1cb 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2006,7 +2006,7 @@ InstallMethod(VerticesReachableFrom, "for a digraph and a vertex", [IsDigraph, IsList], function(D, roots) local N, index, current, succ, visited, prev, n, i, parent, - have_visited_root; + have_visited_root, queue, root; N := DigraphNrVertices(D); visited := BlistList([1 .. N], []); # if 0 = root or root > N then @@ -2016,7 +2016,7 @@ function(D, roots) queue := []; for root in roots do - Add(queue, root) # TODO: Structure differently for complexity reasons + Add(queue, root); # TODO: Structure differently for complexity reasons end; index = 0 @@ -2037,6 +2037,8 @@ function(D, roots) Add(visited_as_ints, i); fi; od; + + return visited_as_ints; end); InstallMethod(VerticesReachableFrom, "for a digraph and a list of vertices", From 9b0e994ac25ba5f2593ca0975efcc7be508628b3 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 6 Feb 2024 15:16:02 +0000 Subject: [PATCH 19/60] Fix other syntax error --- gap/oper.gi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gap/oper.gi b/gap/oper.gi index b361cc1cb..c5d490fc4 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2017,7 +2017,7 @@ function(D, roots) queue := []; for root in roots do Add(queue, root); # TODO: Structure differently for complexity reasons - end; + od; index = 0 while index <= Length(queue) do From e2fe1f56e802ce62d24feb1df90bccc6d13acbd8 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 6 Feb 2024 15:16:26 +0000 Subject: [PATCH 20/60] Fix syntax again --- gap/oper.gi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gap/oper.gi b/gap/oper.gi index c5d490fc4..af80bc997 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2019,7 +2019,7 @@ function(D, roots) Add(queue, root); # TODO: Structure differently for complexity reasons od; - index = 0 + index = 0; while index <= Length(queue) do element = queue[index] neighbours := OutNeighbors(element); From 017d6e3bb94aad48bce7075e882008cc38ddf94e Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 6 Feb 2024 15:17:36 +0000 Subject: [PATCH 21/60] Fix even more syntax errors --- gap/oper.gi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gap/oper.gi b/gap/oper.gi index af80bc997..5bff00599 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2006,7 +2006,7 @@ InstallMethod(VerticesReachableFrom, "for a digraph and a vertex", [IsDigraph, IsList], function(D, roots) local N, index, current, succ, visited, prev, n, i, parent, - have_visited_root, queue, root; + have_visited_root, queue, root, element; N := DigraphNrVertices(D); visited := BlistList([1 .. N], []); # if 0 = root or root > N then @@ -2019,9 +2019,9 @@ function(D, roots) Add(queue, root); # TODO: Structure differently for complexity reasons od; - index = 0; + index := 0; while index <= Length(queue) do - element = queue[index] + element := queue[index]; neighbours := OutNeighbors(element); for neighbour in neighbours do visited[neighbours] = 1; From 8ca9d552fb4a141e309a996a7d1a0a938251f330 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 6 Feb 2024 15:18:48 +0000 Subject: [PATCH 22/60] Fix syntax again again --- gap/oper.gi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gap/oper.gi b/gap/oper.gi index 5bff00599..9aa257db8 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2006,7 +2006,7 @@ InstallMethod(VerticesReachableFrom, "for a digraph and a vertex", [IsDigraph, IsList], function(D, roots) local N, index, current, succ, visited, prev, n, i, parent, - have_visited_root, queue, root, element; + have_visited_root, queue, root, element, neighbours, neighbour; N := DigraphNrVertices(D); visited := BlistList([1 .. N], []); # if 0 = root or root > N then @@ -2024,10 +2024,10 @@ function(D, roots) element := queue[index]; neighbours := OutNeighbors(element); for neighbour in neighbours do - visited[neighbours] = 1; + visited[neighbours] := 1; Add(queue, neighbour); od; - index +=1; + index := index + 1; od; visited_as_ints := []; From 5fb112ff7ca352a254f44085df6964bb06023bfc Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 6 Feb 2024 15:19:57 +0000 Subject: [PATCH 23/60] Add visited_as_ints to local variables --- gap/oper.gi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gap/oper.gi b/gap/oper.gi index 9aa257db8..ae2ca6060 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2006,7 +2006,7 @@ InstallMethod(VerticesReachableFrom, "for a digraph and a vertex", [IsDigraph, IsList], function(D, roots) local N, index, current, succ, visited, prev, n, i, parent, - have_visited_root, queue, root, element, neighbours, neighbour; + have_visited_root, queue, root, element, neighbours, neighbour, visited_as_ints; N := DigraphNrVertices(D); visited := BlistList([1 .. N], []); # if 0 = root or root > N then From 4166869fb98382f7994d5a621dff7040b8aefae0 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 6 Feb 2024 15:38:17 +0000 Subject: [PATCH 24/60] Fix incorrect OutNeighbours usage --- gap/oper.gi | 40 ++++++---------------------------------- 1 file changed, 6 insertions(+), 34 deletions(-) diff --git a/gap/oper.gi b/gap/oper.gi index ae2ca6060..ff7b5ed74 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2006,25 +2006,25 @@ InstallMethod(VerticesReachableFrom, "for a digraph and a vertex", [IsDigraph, IsList], function(D, roots) local N, index, current, succ, visited, prev, n, i, parent, - have_visited_root, queue, root, element, neighbours, neighbour, visited_as_ints; + have_visited_root, queue, root, element, neighbour, visited_as_ints, all_neighbors, node_neighbours; N := DigraphNrVertices(D); visited := BlistList([1 .. N], []); # if 0 = root or root > N then # ErrorNoReturn("the 2nd argument (root) is not a vertex of the 1st ", # "argument (a digraph)"); # fi; - + all_neighbors := OutNeighbors(D); queue := []; for root in roots do Add(queue, root); # TODO: Structure differently for complexity reasons od; - index := 0; + index := 1; while index <= Length(queue) do element := queue[index]; - neighbours := OutNeighbors(element); - for neighbour in neighbours do - visited[neighbours] := 1; + node_neighbours := all_neighbors[element]; + for neighbour in node_neighbours do + visited[neighbour] := 1; Add(queue, neighbour); od; index := index + 1; @@ -2041,34 +2041,6 @@ function(D, roots) return visited_as_ints; end); -InstallMethod(VerticesReachableFrom, "for a digraph and a list of vertices", -[IsDigraph, IsList], -function(D, roots) - local accessible_from_node, candidate, root, i, visited, visited_as_ints, N; - N := DigraphNrVertices(D); - visited := BlistList([1 .. N], []); - for root in roots do - if not(visited[root]) then - accessible_from_node := VerticesReachableFrom(D, root); - for candidate in accessible_from_node do - if not(visited[candidate]) then - visited[candidate] := true; - fi; - od; - fi; - od; - - visited_as_ints := []; - - for i in [1 .. N] do - if visited[i] then; - Add(visited_as_ints, i); - fi; - od; - - return visited_as_ints; -end); - InstallMethod(IsOrderIdeal, "for a digraph and a list of vertices", [IsDigraph, IsList], # Check if digraph represents a partial order From f5ba2405483d2ee74cd52d3092e916c9ec2e56e6 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 6 Feb 2024 15:42:55 +0000 Subject: [PATCH 25/60] Avoid infinite loop --- gap/oper.gi | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gap/oper.gi b/gap/oper.gi index ff7b5ed74..c44df9d4f 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2024,8 +2024,10 @@ function(D, roots) element := queue[index]; node_neighbours := all_neighbors[element]; for neighbour in node_neighbours do - visited[neighbour] := 1; - Add(queue, neighbour); + if not visited[neighbour] then; + visited[neighbour] := 1; + Add(queue, neighbour); + fi; od; index := index + 1; od; From 69dbf7bf4a9cf4c55d73c008e6e143217e448383 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 6 Feb 2024 15:50:42 +0000 Subject: [PATCH 26/60] Fix tests --- gap/oper.gi | 8 +++++++- tst/standard/oper.tst | 26 +++++++++++++------------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/gap/oper.gi b/gap/oper.gi index c44df9d4f..1d3fd6a3e 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2002,6 +2002,12 @@ function(D, v) return spanningtree; end); +InstallMethod(VerticesReachableFrom, "for a digraph and a vertex", +[IsDigraph, IsPosInt], +function(D, root) + return VerticesReachableFrom(D, [root]); +end); + InstallMethod(VerticesReachableFrom, "for a digraph and a vertex", [IsDigraph, IsList], function(D, roots) @@ -2025,7 +2031,7 @@ function(D, roots) node_neighbours := all_neighbors[element]; for neighbour in node_neighbours do if not visited[neighbour] then; - visited[neighbour] := 1; + visited[neighbour] := true; Add(queue, neighbour); fi; od; diff --git a/tst/standard/oper.tst b/tst/standard/oper.tst index dc390770b..d32a4cae4 100644 --- a/tst/standard/oper.tst +++ b/tst/standard/oper.tst @@ -1942,7 +1942,7 @@ gap> DigraphShortestPath(gr, 12, 5014); gap> D := CompleteDigraph(5); gap> VerticesReachableFrom(D, 1); -[ 2, 1, 3, 4, 5 ] +[ 1, 2, 3, 4, 5 ] gap> VerticesReachableFrom(D, 3); [ 1, 2, 3, 4, 5 ] gap> D := EmptyDigraph(5); @@ -1954,9 +1954,9 @@ gap> VerticesReachableFrom(D, 3); gap> D := CycleDigraph(4); gap> VerticesReachableFrom(D, 1); -[ 2, 3, 4, 1 ] +[ 1, 2, 3, 4 ] gap> VerticesReachableFrom(D, 3); -[ 4, 1, 2, 3 ] +[ 1, 2, 3, 4 ] gap> D := ChainDigraph(5); gap> VerticesReachableFrom(D, 1); @@ -1968,29 +1968,29 @@ gap> VerticesReachableFrom(D, 5); gap> D := Digraph([[2, 3, 5], [1, 6], [4, 6, 7], [7, 8], [4], [], [8, 6], []]); gap> VerticesReachableFrom(D, 1); -[ 2, 1, 6, 3, 4, 7, 8, 5 ] +[ 1, 2, 3, 4, 5, 6, 7, 8 ] gap> VerticesReachableFrom(D, 2); -[ 1, 2, 3, 4, 7, 8, 6, 5 ] +[ 1, 2, 3, 4, 5, 6, 7, 8 ] gap> VerticesReachableFrom(D, 3); -[ 4, 7, 8, 6 ] +[ 4, 6, 7, 8 ] gap> VerticesReachableFrom(D, 4); -[ 7, 8, 6 ] +[ 6, 7, 8 ] gap> VerticesReachableFrom(D, 5); -[ 4, 7, 8, 6 ] +[ 4, 6, 7, 8 ] gap> VerticesReachableFrom(D, 6); [ ] gap> VerticesReachableFrom(D, 7); -[ 8, 6 ] +[ 6, 8 ] gap> VerticesReachableFrom(D, 8); [ ] gap> D := Digraph([[1, 2, 3], [4], [1, 5], [], [2]]); gap> VerticesReachableFrom(D, 1); -[ 1, 2, 4, 3, 5 ] +[ 1, 2, 3, 4, 5 ] gap> VerticesReachableFrom(D, 2); [ 4 ] gap> VerticesReachableFrom(D, 3); -[ 1, 2, 4, 3, 5 ] +[ 1, 2, 3, 4, 5 ] gap> VerticesReachableFrom(D, 4); [ ] gap> VerticesReachableFrom(D, 5); @@ -1998,11 +1998,11 @@ gap> VerticesReachableFrom(D, 5); gap> D := Digraph(IsMutableDigraph, [[1, 2, 3], [4], [1, 5], [], [2]]); gap> VerticesReachableFrom(D, 1); -[ 1, 2, 4, 3, 5 ] +[ 1, 2, 3, 4, 5 ] gap> VerticesReachableFrom(D, 2); [ 4 ] gap> VerticesReachableFrom(D, 3); -[ 1, 2, 4, 3, 5 ] +[ 1, 2, 3, 4, 5 ] gap> VerticesReachableFrom(D, 4); [ ] gap> VerticesReachableFrom(D, 5); From 00c7d2e63cd25c523b16a5b23bc7853bbf21cfbb Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 6 Feb 2024 19:01:11 +0000 Subject: [PATCH 27/60] Fix formatting --- gap/oper.gi | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/gap/oper.gi b/gap/oper.gi index 1d3fd6a3e..e2c119c28 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2038,13 +2038,7 @@ function(D, roots) index := index + 1; od; - visited_as_ints := []; - - for i in [1 .. N] do - if visited[i] then; - Add(visited_as_ints, i); - fi; - od; + visited_as_ints := ListBlist([1 .. N], visited); return visited_as_ints; end); @@ -2054,7 +2048,7 @@ InstallMethod(IsOrderIdeal, "for a digraph and a list of vertices", # Check if digraph represents a partial order function(D, roots) local reachable_vertices, vertex_in_subset, i, N; - if not(IsPartialOrderDigraph(D)) then + if not IsPartialOrderDigraph(D) then ErrorNoReturn("the 1st element (a digraph) must be a partial order digraph"); fi; From c59722f885c46bcf32b6a13af8630ca342baca09 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 6 Feb 2024 19:39:58 +0000 Subject: [PATCH 28/60] Add non-partial-order digraph test --- tst/standard/oper.tst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tst/standard/oper.tst b/tst/standard/oper.tst index d32a4cae4..32b143235 100644 --- a/tst/standard/oper.tst +++ b/tst/standard/oper.tst @@ -2830,6 +2830,9 @@ gap> IsOrderIdeal(TestUnion, [4, 5, 6]); true gap> IsOrderIdeal(TestUnion, [1, 5, 6]); false +gap> D := CycleDigraph(5);; +gap> IsOrderIdeal(D, [1]); +Error, the 1st element (a digraph) must be a partial order digraph # DIGRAPHS_UnbindVariables gap> Unbind(C); From da0575dc0f014e7435fdb18b0e7359033f7ae9ba Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 6 Feb 2024 19:44:41 +0000 Subject: [PATCH 29/60] Add Error messages --- gap/oper.gi | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/gap/oper.gi b/gap/oper.gi index e2c119c28..51e593af8 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2005,6 +2005,11 @@ end); InstallMethod(VerticesReachableFrom, "for a digraph and a vertex", [IsDigraph, IsPosInt], function(D, root) + if 0 = root or root > N then + ErrorNoReturn("the 2nd argument (root) is not a vertex of the 1st ", + "argument (a digraph)"); + fi; + return VerticesReachableFrom(D, [root]); end); @@ -2015,10 +2020,13 @@ function(D, roots) have_visited_root, queue, root, element, neighbour, visited_as_ints, all_neighbors, node_neighbours; N := DigraphNrVertices(D); visited := BlistList([1 .. N], []); - # if 0 = root or root > N then - # ErrorNoReturn("the 2nd argument (root) is not a vertex of the 1st ", - # "argument (a digraph)"); - # fi; + for root in roots do + if 0 = root or root > N then + ErrorNoReturn("an element of the 2nd argument (roots) is not a vertex of the 1st ", + "argument (a digraph)"); + fi; + od; + all_neighbors := OutNeighbors(D); queue := []; for root in roots do From c0e9c5bf3e5dd9bd00571191a1944cd3811b5c6f Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 6 Feb 2024 19:58:04 +0000 Subject: [PATCH 30/60] Fix missing N --- gap/oper.gi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gap/oper.gi b/gap/oper.gi index 51e593af8..f5716f636 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2005,6 +2005,9 @@ end); InstallMethod(VerticesReachableFrom, "for a digraph and a vertex", [IsDigraph, IsPosInt], function(D, root) + local N; + N := DigraphNrVertices(root); + if 0 = root or root > N then ErrorNoReturn("the 2nd argument (root) is not a vertex of the 1st ", "argument (a digraph)"); From d29cb123debbc0fb744aa52cd1d8b2e3c070c150 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 6 Feb 2024 20:00:12 +0000 Subject: [PATCH 31/60] Fix misuse of DigraphNrVertices --- gap/oper.gi | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gap/oper.gi b/gap/oper.gi index f5716f636..0fc2ed6df 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2006,7 +2006,7 @@ InstallMethod(VerticesReachableFrom, "for a digraph and a vertex", [IsDigraph, IsPosInt], function(D, root) local N; - N := DigraphNrVertices(root); + N := DigraphNrVertices(D); if 0 = root or root > N then ErrorNoReturn("the 2nd argument (root) is not a vertex of the 1st ", @@ -2016,13 +2016,14 @@ function(D, root) return VerticesReachableFrom(D, [root]); end); -InstallMethod(VerticesReachableFrom, "for a digraph and a vertex", +InstallMethod(VerticesReachableFrom, "for a digraph and a list of vertices", [IsDigraph, IsList], function(D, roots) local N, index, current, succ, visited, prev, n, i, parent, have_visited_root, queue, root, element, neighbour, visited_as_ints, all_neighbors, node_neighbours; N := DigraphNrVertices(D); visited := BlistList([1 .. N], []); + for root in roots do if 0 = root or root > N then ErrorNoReturn("an element of the 2nd argument (roots) is not a vertex of the 1st ", From 40d8281cc506483a67d60c58768b738dfc0f0728 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 6 Feb 2024 20:02:58 +0000 Subject: [PATCH 32/60] Add error check for VerticesReachableFrom --- tst/standard/oper.tst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tst/standard/oper.tst b/tst/standard/oper.tst index 32b143235..3d634ded7 100644 --- a/tst/standard/oper.tst +++ b/tst/standard/oper.tst @@ -1951,6 +1951,8 @@ gap> VerticesReachableFrom(D, 1); [ ] gap> VerticesReachableFrom(D, 3); [ ] +gap> VerticesReachableFrom(D, 6); +Error, the 2nd argument (root) is not a vertex of the 1st argument (a digraph) gap> D := CycleDigraph(4); gap> VerticesReachableFrom(D, 1); From 607a7e747ed57c5d959d2e71235e2db13433ef27 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 6 Feb 2024 20:23:45 +0000 Subject: [PATCH 33/60] Fix BFS logic --- gap/oper.gi | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/gap/oper.gi b/gap/oper.gi index 0fc2ed6df..3212164a1 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2019,7 +2019,7 @@ end); InstallMethod(VerticesReachableFrom, "for a digraph and a list of vertices", [IsDigraph, IsList], function(D, roots) - local N, index, current, succ, visited, prev, n, i, parent, + local N, index, visited, prev, n, i, parent, queue_tail, have_visited_root, queue, root, element, neighbour, visited_as_ints, all_neighbors, node_neighbours; N := DigraphNrVertices(D); visited := BlistList([1 .. N], []); @@ -2032,19 +2032,23 @@ function(D, roots) od; all_neighbors := OutNeighbors(D); - queue := []; + queue := ListWithIdenticalEntries(N, -1); + queue_tail := 0; for root in roots do - Add(queue, root); # TODO: Structure differently for complexity reasons + queue_tail := queue_tail + 1; + queue[queue_tail] := root; od; + # reset index index := 1; - while index <= Length(queue) do + while index <= Length(queue) and queue[index] > 0 do element := queue[index]; node_neighbours := all_neighbors[element]; for neighbour in node_neighbours do if not visited[neighbour] then; visited[neighbour] := true; - Add(queue, neighbour); + queue_tail := queue_tail + 1; + queue[queue_tail] := neighbour; fi; od; index := index + 1; @@ -2072,7 +2076,7 @@ function(D, roots) od; for i in reachable_vertices do - if(not(vertex_in_subset[i])) then + if not vertex_in_subset[i] then return false; fi; od; From d196f978ef6756ec5b01fc228d33b1c3ee1b68f1 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 6 Feb 2024 20:30:55 +0000 Subject: [PATCH 34/60] Address formatting comments in oper.xml --- doc/oper.xml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/doc/oper.xml b/doc/oper.xml index c91e484f8..49d1ffb07 100644 --- a/doc/oper.xml +++ b/doc/oper.xml @@ -1397,13 +1397,13 @@ gap> VerticesReachableFrom(D, 5); - + A list. This operation returns a list of the vertices v, for which there exists - a non-trivial directed walk from any of the provided roots to vertex v in the digraph + a non-trivial directed walk from any of the elements of the provided list to vertex v in the digraph digraph. See Section - for the definition of a non-trivial directed walk. + for the definition of a non-trivial directed walk. The function will throw an error if the list provided contains entries that are not vertices of the digraph.

true or false. - This function returns true if the specified subset is "downwards" closed, i.e. contains every node less than the given nodes. + This function returns true if the specified subset is "downwards" closed, i.e. contains every node less than the given nodes. + The function can only be used on digraphs satisfying IsPartialOrderDigraph and will throw an error if passed a digraph that is not a partial order digraph. TestPartialOrderDigraph := Digraph([[1, 3], [2, 3], [3]]); +gap> D1 := Digraph([[1, 3], [2, 3], [3]]); -gap> TestPartialOrderDigraph2 := Digraph([[1, 3], [2, 3], [3]]); -gap> IsOrderIdeal(TestPartialOrderDigraph, [1, 2, 3]); +gap> IsOrderIdeal(D, [1, 2, 3]); true -gap> TestUnion := DigraphDisjointUnion(TestPartialOrderDigraph, TestPartialOrderDigraph2); +gap> D2 := DigraphDisjointUnion(D, D); -gap> IsOrderIdeal(TestUnion, [1, 2, 3]); +gap> IsOrderIdeal(D2, [1, 2, 3]); true -gap> IsOrderIdeal(TestUnion, [4, 5, 6]); +gap> IsOrderIdeal(D2, [4, 5, 6]); true -gap> IsOrderIdeal(TestUnion, [1, 5, 6]); +gap> IsOrderIdeal(D2, [1, 5, 6]); false ]]> From 8bae38ded8e4691dbc8dff03234b3987de04a4d8 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 6 Feb 2024 20:37:35 +0000 Subject: [PATCH 35/60] Fix example ordering in oper.xml --- doc/oper.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/oper.xml b/doc/oper.xml index 49d1ffb07..8bc670ff2 100644 --- a/doc/oper.xml +++ b/doc/oper.xml @@ -1381,9 +1381,9 @@ gap> VerticesReachableFrom(D, 3); gap> D := CycleDigraph(4); gap> VerticesReachableFrom(D, 1); -[ 2, 3, 4, 1 ] +[ 1, 2, 3, 4 ] gap> VerticesReachableFrom(D, 3); -[ 4, 1, 2, 3 ] +[ 1, 2, 3, 4 ] gap> D := ChainDigraph(5); gap> VerticesReachableFrom(D, 1); From 40a2252a3dd42a880b2d6b8233f24a6525bbe843 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Wed, 7 Feb 2024 14:27:25 +0000 Subject: [PATCH 36/60] Make linter pass (hopefully) --- doc/oper.xml | 2 +- gap/oper.gi | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/oper.xml b/doc/oper.xml index 8bc670ff2..fb2bebecf 100644 --- a/doc/oper.xml +++ b/doc/oper.xml @@ -1369,7 +1369,7 @@ false gap> D := CompleteDigraph(5); gap> VerticesReachableFrom(D, 1); -[ 2, 1, 3, 4, 5 ] +[ 1, 2, 3, 4, 5 ] gap> VerticesReachableFrom(D, 3); [ 1, 2, 3, 4, 5 ] gap> D := EmptyDigraph(5); diff --git a/gap/oper.gi b/gap/oper.gi index 3212164a1..93710de3f 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2020,13 +2020,15 @@ InstallMethod(VerticesReachableFrom, "for a digraph and a list of vertices", [IsDigraph, IsList], function(D, roots) local N, index, visited, prev, n, i, parent, queue_tail, - have_visited_root, queue, root, element, neighbour, visited_as_ints, all_neighbors, node_neighbours; + have_visited_root, queue, root, element, neighbour, visited_as_ints, + all_neighbors, node_neighbours; N := DigraphNrVertices(D); visited := BlistList([1 .. N], []); for root in roots do if 0 = root or root > N then - ErrorNoReturn("an element of the 2nd argument (roots) is not a vertex of the 1st ", + ErrorNoReturn("an element of the 2nd argument ", + "(roots) is not a vertex of the 1st ", "argument (a digraph)"); fi; od; @@ -2053,7 +2055,7 @@ function(D, roots) od; index := index + 1; od; - + visited_as_ints := ListBlist([1 .. N], visited); return visited_as_ints; From a1dfdb1d6d612ea1f8fe0e7816ec809b74c2f85b Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Wed, 7 Feb 2024 14:28:48 +0000 Subject: [PATCH 37/60] Rename variable --- gap/oper.gi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gap/oper.gi b/gap/oper.gi index 93710de3f..13849d7c0 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2021,7 +2021,7 @@ InstallMethod(VerticesReachableFrom, "for a digraph and a list of vertices", function(D, roots) local N, index, visited, prev, n, i, parent, queue_tail, have_visited_root, queue, root, element, neighbour, visited_as_ints, - all_neighbors, node_neighbours; + graph_out_neighbors, node_neighbours; N := DigraphNrVertices(D); visited := BlistList([1 .. N], []); @@ -2033,7 +2033,7 @@ function(D, roots) fi; od; - all_neighbors := OutNeighbors(D); + graph_out_neighbors := OutNeighbors(D); queue := ListWithIdenticalEntries(N, -1); queue_tail := 0; for root in roots do @@ -2045,7 +2045,7 @@ function(D, roots) index := 1; while index <= Length(queue) and queue[index] > 0 do element := queue[index]; - node_neighbours := all_neighbors[element]; + node_neighbours := graph_out_neighbors[element]; for neighbour in node_neighbours do if not visited[neighbour] then; visited[neighbour] := true; From 646377f5bfc8651d1eb56ea694dd545512b90607 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Wed, 7 Feb 2024 14:30:53 +0000 Subject: [PATCH 38/60] Appease linter --- gap/oper.gi | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/gap/oper.gi b/gap/oper.gi index 13849d7c0..857fd1c51 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2019,9 +2019,10 @@ end); InstallMethod(VerticesReachableFrom, "for a digraph and a list of vertices", [IsDigraph, IsList], function(D, roots) - local N, index, visited, prev, n, i, parent, queue_tail, - have_visited_root, queue, root, element, neighbour, visited_as_ints, - graph_out_neighbors, node_neighbours; + local N, index, visited, queue_tail, queue, + root, element, neighbour, visited_as_ints, graph_out_neighbors, + node_neighbours; + N := DigraphNrVertices(D); visited := BlistList([1 .. N], []); @@ -2037,11 +2038,10 @@ function(D, roots) queue := ListWithIdenticalEntries(N, -1); queue_tail := 0; for root in roots do - queue_tail := queue_tail + 1; + queue_tail := queue_tail + 1; queue[queue_tail] := root; od; - # reset index index := 1; while index <= Length(queue) and queue[index] > 0 do element := queue[index]; @@ -2056,7 +2056,7 @@ function(D, roots) index := index + 1; od; - visited_as_ints := ListBlist([1 .. N], visited); + visited_as_ints := ListBlist([1 .. N], visited); return visited_as_ints; end); From feb0adb30091d960d4a1f2adf01fb6ae5bd5cad4 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Wed, 7 Feb 2024 14:33:42 +0000 Subject: [PATCH 39/60] Appease linter --- gap/oper.gi | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gap/oper.gi b/gap/oper.gi index 857fd1c51..b8096cf33 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2056,9 +2056,7 @@ function(D, roots) index := index + 1; od; - visited_as_ints := ListBlist([1 .. N], visited); - - return visited_as_ints; + return ListBlist([1 .. N], visited); end); InstallMethod(IsOrderIdeal, "for a digraph and a list of vertices", From a06d032c050c1176490b64558d684aebcd4ba5f0 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Wed, 7 Feb 2024 14:38:40 +0000 Subject: [PATCH 40/60] Appease linter v3 --- gap/oper.gi | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gap/oper.gi b/gap/oper.gi index b8096cf33..b0e113b7f 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2020,8 +2020,7 @@ InstallMethod(VerticesReachableFrom, "for a digraph and a list of vertices", [IsDigraph, IsList], function(D, roots) local N, index, visited, queue_tail, queue, - root, element, neighbour, visited_as_ints, graph_out_neighbors, - node_neighbours; + root, element, neighbour, graph_out_neighbors, node_neighbours; N := DigraphNrVertices(D); visited := BlistList([1 .. N], []); From 462606619abca420aaa1446b46c0be151282dd6f Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Wed, 7 Feb 2024 16:30:22 +0000 Subject: [PATCH 41/60] Add failure case for VerticesReachableFrom --- tst/standard/oper.tst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tst/standard/oper.tst b/tst/standard/oper.tst index 3d634ded7..b415c6109 100644 --- a/tst/standard/oper.tst +++ b/tst/standard/oper.tst @@ -2808,6 +2808,9 @@ gap> VerticesReachableFrom(D1, [1, 2]); [ 1, 2, 3, 4, 5 ] gap> VerticesReachableFrom(D2, [1]); [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] +gap> VerticesReachableFrom(D2, [1, 11]); +Error, an element of the 2nd argument (roots) is not a vertex of the 1st argum\ +ent (a digraph) gap> D3 := CompleteDigraph(7); gap> D3_edges := [1 .. 7]; From 3c7822760bb12c3e88fb463f6d2e43b7d978f74a Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Wed, 7 Feb 2024 16:46:44 +0000 Subject: [PATCH 42/60] Switch to a more efficient list implementation --- gap/oper.gi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gap/oper.gi b/gap/oper.gi index b0e113b7f..fa5f0e6f7 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2034,7 +2034,7 @@ function(D, roots) od; graph_out_neighbors := OutNeighbors(D); - queue := ListWithIdenticalEntries(N, -1); + queue := EmptyPlist(N); queue_tail := 0; for root in roots do queue_tail := queue_tail + 1; @@ -2042,7 +2042,7 @@ function(D, roots) od; index := 1; - while index <= Length(queue) and queue[index] > 0 do + while IsBound(queue[index]) do element := queue[index]; node_neighbours := graph_out_neighbors[element]; for neighbour in node_neighbours do From 3cc67e9d5e458e9b5a3d048701886558c4fe3f83 Mon Sep 17 00:00:00 2001 From: DanielPointon <30954660+DanielPointon@users.noreply.github.com> Date: Tue, 13 Feb 2024 20:30:36 +0000 Subject: [PATCH 43/60] Update doc/oper.xml Co-authored-by: James Mitchell --- doc/oper.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/oper.xml b/doc/oper.xml index fb2bebecf..cd465dc0f 100644 --- a/doc/oper.xml +++ b/doc/oper.xml @@ -1401,7 +1401,7 @@ gap> VerticesReachableFrom(D, 5); A list. This operation returns a list of the vertices v, for which there exists - a non-trivial directed walk from any of the elements of the provided list to vertex v in the digraph + a non-trivial directed walk from any of the vertices in list to vertex v in the digraph digraph. See Section for the definition of a non-trivial directed walk. The function will throw an error if the list provided contains entries that are not vertices of the digraph.

From 28577af6b8dd09c8e37a6326ed686879c019c6da Mon Sep 17 00:00:00 2001 From: DanielPointon <30954660+DanielPointon@users.noreply.github.com> Date: Tue, 13 Feb 2024 20:30:53 +0000 Subject: [PATCH 44/60] Update doc/oper.xml Co-authored-by: James Mitchell --- doc/oper.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/oper.xml b/doc/oper.xml index cd465dc0f..f8b53dc98 100644 --- a/doc/oper.xml +++ b/doc/oper.xml @@ -2296,7 +2296,7 @@ true true or false. This function returns true if the specified subset is "downwards" closed, i.e. contains every node less than the given nodes. - The function can only be used on digraphs satisfying IsPartialOrderDigraph and will throw an error if passed a digraph that is not a partial order digraph. + The function can only be used on digraphs satisfying and will throw an error if passed a digraph that is not a partial order digraph. D1 := Digraph([[1, 3], [2, 3], [3]]); From 6c715e649516155c97c82253bb8aa67c2908e9e6 Mon Sep 17 00:00:00 2001 From: DanielPointon <30954660+DanielPointon@users.noreply.github.com> Date: Tue, 13 Feb 2024 20:31:06 +0000 Subject: [PATCH 45/60] Update doc/oper.xml Co-authored-by: James Mitchell --- doc/oper.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/oper.xml b/doc/oper.xml index f8b53dc98..46ba27c67 100644 --- a/doc/oper.xml +++ b/doc/oper.xml @@ -1400,7 +1400,7 @@ gap> VerticesReachableFrom(D, 5); A list. - This operation returns a list of the vertices v, for which there exists + This operation returns a list of the vertices v, for which there exists a non-trivial directed walk from any of the vertices in list to vertex v in the digraph digraph. See Section for the definition of a non-trivial directed walk. The function will throw an error if the list provided contains entries that are not vertices of the digraph. From afc524f47aff29f1766a597018c12c30ebce32e1 Mon Sep 17 00:00:00 2001 From: DanielPointon <30954660+DanielPointon@users.noreply.github.com> Date: Tue, 13 Feb 2024 20:31:20 +0000 Subject: [PATCH 46/60] Update gap/oper.gi Co-authored-by: James Mitchell --- gap/oper.gi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gap/oper.gi b/gap/oper.gi index fa5f0e6f7..fe49349e7 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2026,7 +2026,7 @@ function(D, roots) visited := BlistList([1 .. N], []); for root in roots do - if 0 = root or root > N then + if not IsPosInt(N) or 0 = root or root > N then ErrorNoReturn("an element of the 2nd argument ", "(roots) is not a vertex of the 1st ", "argument (a digraph)"); From e1a7187c8d5a28b21e5b76dec6b88cbaf8867c95 Mon Sep 17 00:00:00 2001 From: DanielPointon <30954660+DanielPointon@users.noreply.github.com> Date: Tue, 13 Feb 2024 20:31:45 +0000 Subject: [PATCH 47/60] Update doc/oper.xml Co-authored-by: James Mitchell --- doc/oper.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/oper.xml b/doc/oper.xml index 46ba27c67..c21752c7f 100644 --- a/doc/oper.xml +++ b/doc/oper.xml @@ -2295,7 +2295,7 @@ true true or false. - This function returns true if the specified subset is "downwards" closed, i.e. contains every node less than the given nodes. + This function returns true if the specified subset is "downwards" closed, i.e. contains every vertex less than the given vertices. The function can only be used on digraphs satisfying and will throw an error if passed a digraph that is not a partial order digraph. Date: Tue, 13 Feb 2024 20:31:56 +0000 Subject: [PATCH 48/60] Update doc/oper.xml Co-authored-by: James Mitchell --- doc/oper.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/oper.xml b/doc/oper.xml index c21752c7f..5f96d7756 100644 --- a/doc/oper.xml +++ b/doc/oper.xml @@ -1402,7 +1402,7 @@ gap> VerticesReachableFrom(D, 5); This operation returns a list of the vertices v, for which there exists a non-trivial directed walk from any of the vertices in list to vertex v in the digraph - digraph. See Section + D. See Section for the definition of a non-trivial directed walk. The function will throw an error if the list provided contains entries that are not vertices of the digraph.

From e5d512b77bfa30266196d52385f3f1393ebc163a Mon Sep 17 00:00:00 2001 From: DanielPointon <30954660+DanielPointon@users.noreply.github.com> Date: Tue, 13 Feb 2024 20:32:16 +0000 Subject: [PATCH 49/60] Update gap/oper.gi Co-authored-by: James Mitchell --- gap/oper.gi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gap/oper.gi b/gap/oper.gi index fe49349e7..64a8f981c 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2064,7 +2064,7 @@ InstallMethod(IsOrderIdeal, "for a digraph and a list of vertices", function(D, roots) local reachable_vertices, vertex_in_subset, i, N; if not IsPartialOrderDigraph(D) then - ErrorNoReturn("the 1st element (a digraph) must be a partial order digraph"); + ErrorNoReturn("the 1st argument (a digraph) must be a partial order digraph"); fi; N := Length(roots); From a0851c1d9358cf5f76f2cee19d2b3bcceb092978 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 13 Feb 2024 20:34:40 +0000 Subject: [PATCH 50/60] Simplify function --- gap/oper.gi | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/gap/oper.gi b/gap/oper.gi index 64a8f981c..49b8e98d1 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2068,19 +2068,11 @@ function(D, roots) fi; N := Length(roots); - vertex_in_subset := BlistList([1 .. N], []); + vertex_in_subset := BlistList([1 .. N], roots); reachable_vertices := VerticesReachableFrom(D, roots); - for i in roots do - vertex_in_subset[i] := true; - od; - for i in reachable_vertices do - if not vertex_in_subset[i] then - return false; - fi; - od; + return Length(reachable_vertices) = Length(roots) and not ForAny(reachable_vertices, x -> vertex_in_subset[x]); - return Length(reachable_vertices) = Length(roots); end); InstallMethod(DominatorTree, "for a digraph and a vertex", From 4bb08a8a93b14b7a66b83beb09807c755f94897c Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 13 Feb 2024 20:35:47 +0000 Subject: [PATCH 51/60] Move lines after argument checking --- gap/oper.gi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gap/oper.gi b/gap/oper.gi index 49b8e98d1..b1a137198 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2022,9 +2022,6 @@ function(D, roots) local N, index, visited, queue_tail, queue, root, element, neighbour, graph_out_neighbors, node_neighbours; - N := DigraphNrVertices(D); - visited := BlistList([1 .. N], []); - for root in roots do if not IsPosInt(N) or 0 = root or root > N then ErrorNoReturn("an element of the 2nd argument ", @@ -2033,6 +2030,9 @@ function(D, roots) fi; od; + N := DigraphNrVertices(D); + visited := BlistList([1 .. N], []); + graph_out_neighbors := OutNeighbors(D); queue := EmptyPlist(N); queue_tail := 0; From e4cffe9f6a5f2ef0bc3ab8c88023003ffad1b7c6 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 13 Feb 2024 20:48:38 +0000 Subject: [PATCH 52/60] Move N back --- gap/oper.gi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gap/oper.gi b/gap/oper.gi index b1a137198..fb8d20328 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2022,6 +2022,8 @@ function(D, roots) local N, index, visited, queue_tail, queue, root, element, neighbour, graph_out_neighbors, node_neighbours; + N := DigraphNrVertices(D); + for root in roots do if not IsPosInt(N) or 0 = root or root > N then ErrorNoReturn("an element of the 2nd argument ", @@ -2030,7 +2032,6 @@ function(D, roots) fi; od; - N := DigraphNrVertices(D); visited := BlistList([1 .. N], []); graph_out_neighbors := OutNeighbors(D); From a4faf94569d602b51e422fa45934c8d29ddc69b0 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 13 Feb 2024 21:17:36 +0000 Subject: [PATCH 53/60] Fix test --- tst/standard/oper.tst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tst/standard/oper.tst b/tst/standard/oper.tst index b415c6109..476cb9f66 100644 --- a/tst/standard/oper.tst +++ b/tst/standard/oper.tst @@ -2837,7 +2837,7 @@ gap> IsOrderIdeal(TestUnion, [1, 5, 6]); false gap> D := CycleDigraph(5);; gap> IsOrderIdeal(D, [1]); -Error, the 1st element (a digraph) must be a partial order digraph +Error, the 1st argument (a digraph) must be a partial order digraph # DIGRAPHS_UnbindVariables gap> Unbind(C); From a1fd666e88f535de88843d502514d4c53de193a9 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 13 Feb 2024 21:36:49 +0000 Subject: [PATCH 54/60] fix error --- gap/oper.gi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gap/oper.gi b/gap/oper.gi index fb8d20328..76ea491cb 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2068,11 +2068,11 @@ function(D, roots) ErrorNoReturn("the 1st argument (a digraph) must be a partial order digraph"); fi; - N := Length(roots); + N := DigraphNrVertices(D); vertex_in_subset := BlistList([1 .. N], roots); reachable_vertices := VerticesReachableFrom(D, roots); - return Length(reachable_vertices) = Length(roots) and not ForAny(reachable_vertices, x -> vertex_in_subset[x]); + return Length(reachable_vertices) = Length(roots) and ForAll(reachable_vertices, x -> vertex_in_subset[x]); end); From 6ce6e99e42a18a1b6a20032e3877f84ad72a7e62 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 13 Feb 2024 21:39:17 +0000 Subject: [PATCH 55/60] appease linter --- gap/oper.gi | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gap/oper.gi b/gap/oper.gi index 76ea491cb..abdd3092a 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2063,7 +2063,7 @@ InstallMethod(IsOrderIdeal, "for a digraph and a list of vertices", [IsDigraph, IsList], # Check if digraph represents a partial order function(D, roots) - local reachable_vertices, vertex_in_subset, i, N; + local reachable_vertices, vertex_in_subset, N; if not IsPartialOrderDigraph(D) then ErrorNoReturn("the 1st argument (a digraph) must be a partial order digraph"); fi; @@ -2072,7 +2072,8 @@ function(D, roots) vertex_in_subset := BlistList([1 .. N], roots); reachable_vertices := VerticesReachableFrom(D, roots); - return Length(reachable_vertices) = Length(roots) and ForAll(reachable_vertices, x -> vertex_in_subset[x]); + return Length(reachable_vertices) = Length(roots) + and ForAll(reachable_vertices, x -> vertex_in_subset[x]); end); From 9a5b9f3f1d1a354436b407662508dcdd527c4aa2 Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 13 Feb 2024 21:40:28 +0000 Subject: [PATCH 56/60] Appease linter --- gap/oper.gi | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gap/oper.gi b/gap/oper.gi index abdd3092a..15bd30ac9 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2065,7 +2065,9 @@ InstallMethod(IsOrderIdeal, "for a digraph and a list of vertices", function(D, roots) local reachable_vertices, vertex_in_subset, N; if not IsPartialOrderDigraph(D) then - ErrorNoReturn("the 1st argument (a digraph) must be a partial order digraph"); + ErrorNoReturn( + "the 1st argument (a digraph) must be a partial order digraph" + ); fi; N := DigraphNrVertices(D); From 3d002daa660e1097c95ba359caf31c3e25e54efa Mon Sep 17 00:00:00 2001 From: Daniel Pointon Date: Tue, 13 Feb 2024 22:02:14 +0000 Subject: [PATCH 57/60] appease linter --- gap/oper.gi | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gap/oper.gi b/gap/oper.gi index 15bd30ac9..5b22febba 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2066,8 +2066,7 @@ function(D, roots) local reachable_vertices, vertex_in_subset, N; if not IsPartialOrderDigraph(D) then ErrorNoReturn( - "the 1st argument (a digraph) must be a partial order digraph" - ); + "the 1st argument (a digraph) must be a partial order digraph"); fi; N := DigraphNrVertices(D); From 6cae53f5bc72361b0ef64fc8015993c191f78b44 Mon Sep 17 00:00:00 2001 From: "James D. Mitchell" Date: Thu, 7 Mar 2024 10:47:21 +0000 Subject: [PATCH 58/60] Combine man sections for VerticesReachableFrom --- doc/oper.xml | 51 +++++++++++++++------------------------------------ 1 file changed, 15 insertions(+), 36 deletions(-) diff --git a/doc/oper.xml b/doc/oper.xml index 5f96d7756..d9121547d 100644 --- a/doc/oper.xml +++ b/doc/oper.xml @@ -1353,17 +1353,23 @@ false <#GAPDoc Label="VerticesReachableFrom"> + A list. - This operation returns a list of the vertices v, for which there exists - a non-trivial directed walk from vertex root to vertex v in the digraph + This operation returns a list of the vertices v, for which there + exists a non-trivial directed walk from the vertex root, or any of + the list of vertices list, to vertex v in the digraph digraph. See Section for the definition of a non-trivial directed walk.

- The method for VerticesReachableFrom has worst case complexity of O(m + - n) where m is the number of edges and n the number of - vertices in digraph. + The method for VerticesReachableFrom has worst case complexity of + O(m + n) where m is the number of edges and n the + number of vertices in digraph. +

+ + This function returns an error if root, or any vertex in list, + is not a vertices of digraph. D := CompleteDigraph(5); @@ -1378,6 +1384,10 @@ gap> VerticesReachableFrom(D, 1); [ ] gap> VerticesReachableFrom(D, 3); [ ] +gap> VerticesReachableFrom(D, [1, 2, 3, 4]); +[ ] +gap> VerticesReachableFrom(D, [3, 4, 5]); +[ ] gap> D := CycleDigraph(4); gap> VerticesReachableFrom(D, 1); @@ -1392,44 +1402,13 @@ gap> VerticesReachableFrom(D, 3); [ 4, 5 ] gap> VerticesReachableFrom(D, 5); [ ] -]]> - - - - - - A list. - - This operation returns a list of the vertices v, for which there exists - a non-trivial directed walk from any of the vertices in list to vertex v in the digraph - D. See Section - for the definition of a non-trivial directed walk. The function will throw an error if the list provided contains entries that are not vertices of the digraph. -

- - D := CompleteDigraph(5); - -gap> VerticesReachableFrom(D, [1]); -[ 1, 2, 3, 4, 5 ] -gap> VerticesReachableFrom(D, [3]); -[ 1, 2, 3, 4, 5 ] -gap> D := EmptyDigraph(5); - -gap> VerticesReachableFrom(D, [1, 2, 3, 4]); -[ ] -gap> VerticesReachableFrom(D, [3, 4, 5]); -[ ] -gap> D := ChainDigraph(5); - gap> VerticesReachableFrom(D, [3, 4]); [ 4, 5 ] ]]> - <#/GAPDoc> - <#GAPDoc Label="DigraphPath"> From 4929908dc70a1f56d3144e4634e0cb0417fe4885 Mon Sep 17 00:00:00 2001 From: DanielPointon <30954660+DanielPointon@users.noreply.github.com> Date: Mon, 11 Mar 2024 01:35:58 +0000 Subject: [PATCH 59/60] Switch to using Append() --- gap/oper.gi | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/gap/oper.gi b/gap/oper.gi index 5b22febba..4cb26c81b 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2036,11 +2036,9 @@ function(D, roots) graph_out_neighbors := OutNeighbors(D); queue := EmptyPlist(N); - queue_tail := 0; - for root in roots do - queue_tail := queue_tail + 1; - queue[queue_tail] := root; - od; + Append(queue, roots); + + queue_tail := Length(roots); index := 1; while IsBound(queue[index]) do From e17a6e7a7df0be6e94962f6cf56ba5fe82ca8030 Mon Sep 17 00:00:00 2001 From: James Mitchell Date: Mon, 11 Mar 2024 15:37:22 +0000 Subject: [PATCH 60/60] Apply suggestions from code review --- doc/oper.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/oper.xml b/doc/oper.xml index d9121547d..d60a391aa 100644 --- a/doc/oper.xml +++ b/doc/oper.xml @@ -2274,7 +2274,7 @@ true true or false. - This function returns true if the specified subset is "downwards" closed, i.e. contains every vertex less than the given vertices. + This function returns true if the specified subset is "downwards" closed, i.e. contains every vertex less than the given vertices in the order defined by D. The function can only be used on digraphs satisfying and will throw an error if passed a digraph that is not a partial order digraph.