diff --git a/doc/digraph.xml b/doc/digraph.xml index 05e578e11..faa5d8221 100644 --- a/doc/digraph.xml +++ b/doc/digraph.xml @@ -244,9 +244,9 @@ gap> gr := Digraph([1 .. 10], ReturnTrue); gap> Digraph("Diamond"); ]]> - The next example illustrates the uses of the fourth and fifth variants of - this constructor. The resulting digraph is a strongly regular graph, and - it is actually the point graph of the van Lint-Schrijver partial + The next example illustrates the uses of the variants of this constructor + involving functions. The resulting digraph is a strongly regular graph, + and it is actually the point graph of the van Lint-Schrijver partial geometry, . The algebraic description is taken from the seminal paper of Calderbank and Kantor . @@ -323,6 +323,8 @@ gap> D := DigraphByAdjacencyMatrix(IsMutableDigraph, <#GAPDoc Label="DigraphByEdges"> + A digraph. &STANDARD_FILT_TEXT; @@ -336,8 +338,15 @@ gap> D := DigraphByAdjacencyMatrix(IsMutableDigraph, then this function returns the digraph with n vertices and list list.

- See . + If labels is a duplicate-free list, and edges is a list of + pairs of elements from labels, then this function returns a digraph + with vertices [1 .. Length(labels)] and + Length(edges) edges. For each i in + [1 .. Length(edges)] there exists an edge given by the + pair at edges[i]. The vertices of the digraph will be labelled by + the elements of labels.

+ See . DigraphByEdges( > [[1, 3], [2, 1], [2, 3], [2, 5], [3, 6], @@ -351,6 +360,12 @@ gap> DigraphByEdges(IsMutableDigraph, > [[1, 3], [2, 1], [2, 3], [2, 5], [3, 6], > [4, 6], [5, 2], [5, 4], [5, 6], [6, 6]], 12); +gap> gr := DigraphByEdges( +> ["a", "b", "x", "y"], +> [["a", "x"], ["x", "b"]]); + +gap> IsIsomorphicDigraph(Digraph([[3], [], [2], []]), gr); +true ]]> diff --git a/gap/digraph.gd b/gap/digraph.gd index 46cb83d79..32d77c71c 100644 --- a/gap/digraph.gd +++ b/gap/digraph.gd @@ -90,6 +90,7 @@ DeclareOperation("DigraphByEdges", [IsFunction, IsList]); DeclareOperation("DigraphByEdges", [IsFunction, IsList, IsInt]); DeclareOperation("DigraphByEdges", [IsList]); DeclareOperation("DigraphByEdges", [IsList, IsInt]); +DeclareOperation("DigraphByEdges", [IsList, IsList]); DeclareConstructor("DigraphByInNeighboursCons", [IsDigraph, IsList]); DeclareConstructor("DigraphByInNeighboursConsNC", [IsDigraph, IsList]); diff --git a/gap/digraph.gi b/gap/digraph.gi index 337bfef4a..09837e173 100644 --- a/gap/digraph.gi +++ b/gap/digraph.gi @@ -969,6 +969,42 @@ InstallMethod(DigraphByEdges, "for a function, a list, and an integer", InstallMethod(DigraphByEdges, "for a function and a list", [IsFunction, IsList], DigraphByEdgesCons); +InstallMethod(DigraphByEdges, "for a list and a list", [IsList, IsList], +function(vertex_labels, edges) + local label_counts, duplicates, badpos, labels, D, nrverts; + + label_counts := Collected(vertex_labels); + duplicates := List(Filtered(label_counts, x -> x[2] > 1), x -> x[1]); + if not IsEmpty(duplicates) then + ErrorNoReturn(" contains duplicate labels: ", + duplicates, ","); + fi; + + # get first invalid edge - malformed + badpos := PositionProperty(edges, e -> not IsList(e) or Length(e) <> 2); + if badpos <> fail then + ErrorNoReturn("invalid edge ", edges[badpos], " in position ", badpos, + " in ; edges must be pairs of elements,"); + fi; + + # get first invalid edge - bad reference + labels := Set(vertex_labels); # set makes it faster to check containment + badpos := PositionProperty(edges, + e -> not (e[1] in labels and e[2] in labels)); + if badpos <> fail then + ErrorNoReturn("invalid edge ", edges[badpos], " in at position ", + badpos, "; edges must reference vertices from ", + vertex_labels, ","); + fi; + + nrverts := Length(vertex_labels); + D := DigraphByEdges(List(edges, + x -> [Position(vertex_labels, x[1]), + Position(vertex_labels, x[2])]), nrverts); + SetDigraphVertexLabels(D, vertex_labels); + return D; +end); + InstallMethod(DigraphByInNeighboursCons, "for IsMutableDigraph, and a list", [IsMutableDigraph, IsList], function(_, list) diff --git a/tst/standard/digraph.tst b/tst/standard/digraph.tst index 4c458f29e..2744a4a7e 100644 --- a/tst/standard/digraph.tst +++ b/tst/standard/digraph.tst @@ -332,6 +332,20 @@ Error, the 1st argument (list of edges) must be pairs of positive integers but\ gap> DigraphByEdges([12], 10); Error, the 1st argument (list of edges) must be a list of lists, but found int\ eger in position 1 +gap> DigraphByEdges(["a", "b"], [["a", "a"]]); + +gap> DigraphByEdges(["a", "b"], [["a", "a"], ["a", "a"]]); + +gap> D1 := DigraphByEdges([[1], -1, "abc", true], +> [[-1, [1]], ["abc", -1]]);; +gap> D2 := Digraph([[], [1], [2], []]);; +gap> IsIsomorphicDigraph(D1, D2); +true +gap> DigraphByEdges([1, 2], [[2, 3]]); +Error, invalid edge [ 2, 3 ] in at position +1; edges must reference vertices from [ 1, 2 ], +gap> DigraphByEdges([1, 1, 2], [1, 2]); +Error, contains duplicate labels: [ 1 ], # DigraphByAdjacencyMatrix (by an integer matrix)