From d829db6ff0250cae8d7d98880df6d96df2fa9dff Mon Sep 17 00:00:00 2001 From: Santiago Giner <70669841+SantiagoGiner@users.noreply.github.com> Date: Fri, 22 Jan 2021 16:39:01 -0400 Subject: [PATCH] Acyclic graph take (#601) ## Changes * Created the function AcyclicGraphTake which accepts a directed, acyclic graph and a list of two vertices, returning the intersection of the in-component of the first vertex (i.e. start vertex) with the out-component of the second vertex (i.e. end vertex). * Function definition, tests, and documentation are all provided. ## Error checking * The function checks for invalid inputs of the form of the graph not being directed and acyclic, the vertices not being part of the graph, incorrect argument count, among others. ## Examples 2021-01-22 2021-01-22 (1) --- .../Images/AcyclicGraphTakeInput.png | Bin 0 -> 26688 bytes .../Images/AcyclicGraphTakeOutput.png | Bin 0 -> 18564 bytes .../UtilityFunctions/AcyclicGraphTake.md | 21 ++++ Kernel/AcyclicGraphTake.m | 52 ++++++++++ README.md | 1 + Tests/AcyclicGraphTake.wlt | 95 ++++++++++++++++++ 6 files changed, 169 insertions(+) create mode 100644 Documentation/Images/AcyclicGraphTakeInput.png create mode 100644 Documentation/Images/AcyclicGraphTakeOutput.png create mode 100644 Documentation/SymbolsAndFunctions/UtilityFunctions/AcyclicGraphTake.md create mode 100644 Kernel/AcyclicGraphTake.m create mode 100644 Tests/AcyclicGraphTake.wlt diff --git a/Documentation/Images/AcyclicGraphTakeInput.png b/Documentation/Images/AcyclicGraphTakeInput.png new file mode 100644 index 0000000000000000000000000000000000000000..e05de3027f702206e21fbcfcdc8e45142c41e31d GIT binary patch literal 26688 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 HZ$JJYV0n-watEEDF?#ej`1VXE(iqeHZ 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 literal 0 HcmV?d00001 diff --git a/Documentation/SymbolsAndFunctions/UtilityFunctions/AcyclicGraphTake.md b/Documentation/SymbolsAndFunctions/UtilityFunctions/AcyclicGraphTake.md new file mode 100644 index 000000000..e03cb3e4f --- /dev/null +++ b/Documentation/SymbolsAndFunctions/UtilityFunctions/AcyclicGraphTake.md @@ -0,0 +1,21 @@ +###### [Symbols and Functions](/README.md#symbols-and-functions) > Utility Functions > + +# AcyclicGraphTake + +**`AcyclicGraphTake`** gives the intersectiom of the out-component of the first vertex +with the in-component of the second vertex: + +```wl +In[] := graph = BlockRandom[ + DirectedGraph[RandomGraph[{10, 10}], "Acyclic", VertexLabels -> Automatic], + RandomSeeding -> 2 +] +``` + + + +```wl +In[] := AcyclicGraphTake[graph, {1, 9}] +``` + + diff --git a/Kernel/AcyclicGraphTake.m b/Kernel/AcyclicGraphTake.m new file mode 100644 index 000000000..22fa843e8 --- /dev/null +++ b/Kernel/AcyclicGraphTake.m @@ -0,0 +1,52 @@ +Package["SetReplace`"] + +PackageImport["GeneralUtilities`"] + +PackageExport["AcyclicGraphTake"] + +(* Utility function to check for directed, acyclic graphs *) +dagQ[graph_] := AcyclicGraphQ[graph] && DirectedGraphQ[graph] && LoopFreeGraphQ[graph] + +(* Documentation *) +SetUsage @ " +AcyclicGraphTake[gr$, vrts$] gives the intersection in graph gr$ of the in-component of the first vertex in vrts$ \ +with the out-component of the second vertex in vrts$. +"; + +(* SyntaxInformation *) +SyntaxInformation[AcyclicGraphTake] = + {"ArgumentsPattern" -> {_, _}}; + +(* Argument count *) +AcyclicGraphTake[args___] := 0 /; + !Developer`CheckArgumentCount[AcyclicGraphTake[args], 2, 2] && False; + +(* main *) +expr : AcyclicGraphTake[graph_, vertices_] := ModuleScope[ + res = Catch[acyclicGraphTake[HoldForm @ expr, graph, vertices]]; + res /; res =!= $Failed +]; + +(* Normal form *) +acyclicGraphTake[_, graph_ ? dagQ, {startVertex_, endVertex_}] /; + VertexQ[graph, startVertex] && VertexQ[graph, endVertex] := ModuleScope[ + Subgraph[graph, Intersection[ + VertexInComponent[graph, endVertex], VertexOutComponent[graph, startVertex]]] +] + +(* Incorrect arguments messages *) +AcyclicGraphTake::invalidGraph = "The argument at position `1` in `2` should be a directed, acyclic graph."; +acyclicGraphTake[expr_, graph_ ? (Not @* dagQ), _] := + (Message[AcyclicGraphTake::invalidGraph, 1, HoldForm @ expr]; + Throw[$Failed]); + +AcyclicGraphTake::invalidVertexList = "The argument at position `1` in `2` should be a list of two vertices."; +acyclicGraphTake[expr_, _, Except[{_, _}]] := + (Message[AcyclicGraphTake::invalidVertexList, 2, HoldForm @ expr]; + Throw[$Failed]); + +AcyclicGraphTake::invalidVertex = "The argument `1` is not a valid vertex in `2`."; +acyclicGraphTake[expr_, graph_Graph, {startVertex_, endVertex_}] /; + (Not @ (VertexQ[graph, startVertex] && VertexQ[graph, endVertex])) := + (Message[AcyclicGraphTake::invalidVertex, If[VertexQ[graph, startVertex], endVertex, startVertex], HoldForm @ expr]; + Throw[$Failed]); diff --git a/README.md b/README.md index 7787eacc5..bdb1f38e0 100644 --- a/README.md +++ b/README.md @@ -203,6 +203,7 @@ ideas. So, if you are interested, please join! * [HypergraphPlot](Documentation/SymbolsAndFunctions/HypergraphPlot.md) * [RulePlot of WolframModel](Documentation/SymbolsAndFunctions/RulePlotOfWolframModel.md) * Utility Functions + * [AcyclicGraphTake](Documentation/SymbolsAndFunctions/UtilityFunctions/AcyclicGraphTake.md) * [IndexHypergraph](Documentation/SymbolsAndFunctions/UtilityFunctions/IndexHypergraph.md) * [IsomorphicHypergraphQ](Documentation/SymbolsAndFunctions/UtilityFunctions/IsomorphicHypergraphQ.md) * [HypergraphToGraph](Documentation/SymbolsAndFunctions/UtilityFunctions/HypergraphToGraph.md) diff --git a/Tests/AcyclicGraphTake.wlt b/Tests/AcyclicGraphTake.wlt new file mode 100644 index 000000000..14f68a607 --- /dev/null +++ b/Tests/AcyclicGraphTake.wlt @@ -0,0 +1,95 @@ +<| + "AcyclicGraphTake" -> <| + "init" -> ( + Attributes[Global`testUnevaluated] = {HoldAll}; + Global`testUnevaluated[args___] := SetReplace`PackageScope`testUnevaluated[VerificationTest, args]; + ), + "tests" -> { + (* Verification tests *) + VerificationTest[ + EdgeList[AcyclicGraphTake[Graph[{1 -> 2, 2 -> 3, 2 -> 4, 3 -> 4, 4 -> 5, 5 -> 6}], {2, 5}]], + EdgeList[Graph[{2 -> 3, 2 -> 4, 3 -> 4, 4 -> 5}]] + ], + + VerificationTest[ + EdgeList[AcyclicGraphTake[Graph[{1 -> 2, 2 -> 3, 3 -> 4, 4 -> 5}], {2, 5}]], + EdgeList[Graph[{2 -> 3, 3 -> 4, 4 -> 5}]] + ], + + VerificationTest[ + AcyclicGraphTake[Graph[{1 -> 2, 2 -> 3, 3 -> 4}], {1, 1}], + Graph[{1}, {}] + ], + + VerificationTest[ + EdgeList[AcyclicGraphTake[Graph[{1 -> 2, 2 -> 3, 4 -> 3}], {1, 4}]], + {} + ], + + (* unevaluated *) + + (* argument count *) + With[{ + dag = Graph[{1 -> 2, 2 -> 3}], + loopGraph = Graph[{1 -> 1, 1 -> 2}], + undirectedGraph = Graph[{1 <-> 2, 2 <-> 3}], + cyclicGraph = Graph[{1 -> 2, 2 -> 1}] + }, + { + testUnevaluated[ + AcyclicGraphTake[], + {AcyclicGraphTake::argrx} + ], + + testUnevaluated[ + AcyclicGraphTake[x], + {AcyclicGraphTake::argr} + ], + + (* first argument: graph *) + testUnevaluated[ + AcyclicGraphTake[x, ], + {AcyclicGraphTake::invalidGraph} + ], + + testUnevaluated[ + AcyclicGraphTake[loopGraph, x], + {AcyclicGraphTake::invalidGraph} + ], + + testUnevaluated[ + AcyclicGraphTake[undirectedGraph, x], + {AcyclicGraphTake::invalidGraph} + ], + + testUnevaluated[ + AcyclicGraphTake[cyclicGraph, x], + {AcyclicGraphTake::invalidGraph} + ], + + (* second argument: vertex list *) + testUnevaluated[ + AcyclicGraphTake[dag, x], + {AcyclicGraphTake::invalidVertexList} + ], + + testUnevaluated[ + AcyclicGraphTake[dag, {x, y, z}], + {AcyclicGraphTake::invalidVertexList} + ], + + testUnevaluated[ + AcyclicGraphTake[dag, {6, 1}], + {AcyclicGraphTake::invalidVertex} + ], + + testUnevaluated[ + AcyclicGraphTake[dag, {1, 6}], + {AcyclicGraphTake::invalidVertex} + ] + } + ] + }, + "options" -> <|"Parallel" -> False|> + |> +|>