Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,38 @@
"tools": {
"dotnet-format": {
"version": "5.1.250801",
"commands": ["dotnet-format"],
"commands": [
"dotnet-format"
],
"rollForward": false
},
"dotnet-script": {
"version": "1.4.0",
"commands": ["dotnet-script"],
"commands": [
"dotnet-script"
],
"rollForward": false
},
"csharpier": {
"version": "0.29.2",
"commands": ["dotnet-csharpier"],
"commands": [
"dotnet-csharpier"
],
"rollForward": false
},
"husky": {
"version": "0.6.1",
"commands": ["husky"],
"commands": [
"husky"
],
"rollForward": false
},
"fantomas": {
"version": "6.3.16",
"commands": [
"fantomas"
],
"rollForward": false
}
}
}
}
32 changes: 12 additions & 20 deletions SharpGraph.Builder/Compiler.fs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
namespace SharpGraph.Builder

///
///
///
///<summary>
/// Compiler module to compiel expressions representing graphs into
/// graph objects.
///</summary>
module Compiler =
open SharpGraph
open Microsoft.FSharp.Collections
Expand Down Expand Up @@ -121,28 +122,19 @@ module Compiler =
| UnaryExp(e, op) -> HandleUnaryExp e op
| BinaryOperatorExp(op, e1, e2) -> BinaryOperatorExp op e1 e2

///
///
///

let Parse code =
System.Diagnostics.Debug.WriteLine("BEGIN PARSING")

match runParserOnString (pExpression .>> eof) () "Tokamak reaction stream" code with
match runParserOnString (pExpression .>> eof) () "Graph compile stream" code with
| Success(result, _, _) ->
System.Diagnostics.Debug.WriteLine("FINISH PARSING")
result
| Failure(msg, _, _) ->
System.Diagnostics.Debug.WriteLine("Error " + msg + "Reactor core containment failed!")
failwith msg

///<summary>
/// Compiles the given string into a Graph object.
///</summary>
///<param name="code">The input string to build the graph</param>
///<returns>Graph object</returns>
let Compile (text: string) =
let result = HandleExpression(Parse text)

System.Console.WriteLine(
"graph number of nodes "
+ string (result.GetNodes().Count)
+ " and edges: "
+ string (result.GetEdges().Count)
)

result
HandleExpression(Parse text)
2 changes: 1 addition & 1 deletion SharpGraph.Builder/SharpGraph.Builder.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PackageId>SharpGraphLib.Builder</PackageId>
<TargetFramework>net8.0</TargetFramework>
<PackageReadmeFile>README.md</PackageReadmeFile>
<Version>1.0.3</Version>
<Version>1.0.4</Version>
<Authors>Jonathan Hough</Authors>
<Company>Jonathan Hough</Company>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
Expand Down
7 changes: 0 additions & 7 deletions SharpGraph.Tests/test/CycleTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,6 @@
// Copyright Licensed under the MIT license.
// See LICENSE file in the samples root for full license information.
// </copyright>

using System;
// <copyright file="CycleTest.cs" company="Jonathan Hough">
// Copyright (C) 2023 Jonathan Hough.
// Copyright Licensed under the MIT license.
// See LICENSE file in the samples root for full license information.
// </copyright>
using Xunit;

namespace SharpGraph
Expand Down
60 changes: 60 additions & 0 deletions SharpGraph.Tests/test/GraphContractionTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// <copyright file="GraphContractionTest.cs" company="Jonathan Hough">
// Copyright (C) 2023 Jonathan Hough.
// Copyright Licensed under the MIT license.
// See LICENSE file in the samples root for full license information.
// </copyright>

using System;
using System.Collections.Generic;
using Xunit;

namespace SharpGraph
{
public class GraphContractionTest
{
[Theory]
[InlineData(6, "1", "2", 5, 10, 4)]
[InlineData(10, "2", "6", 9, 36, 8)]
public void TestContractEdgeFromComplete(
uint totalNodeCount,
string nodeToKeep,
string nodeToRemove,
int expectedNumberOfNodes,
int expectedNumberOfEdges,
int expectedAdjacentToKeptNode
)
{
var edgeToRemove = new Edge(nodeToKeep, nodeToRemove);
var g = GraphGenerator.CreateComplete(totalNodeCount);
var h = g.ContractEdge(edgeToRemove, new Node(nodeToKeep));

Assert.Equal(expectedNumberOfNodes, h.GetNodes().Count);
Assert.Equal(expectedNumberOfEdges, h.GetEdges().Count);
Assert.Equal(expectedAdjacentToKeptNode, h.GetAdjacent(new Node(nodeToKeep)).Count);
}

[Fact]
public void TestContractionKeepsComponents()
{
var e1 = new Edge("1", "2");
var e2 = new Edge("2", "3");
var e3 = new Edge("2", "4");
var e4 = new Edge("5", "8");
var edges = new List<Edge> { e1, e2, e3, e4 };
var g = new Graph(edges);
foreach (var e in g.GetEdges())
{
g.AddComponent<EdgeDirection>(e);
}

var h = g.ContractEdge(e1, new Node("1"));

Assert.Equal(5, h.GetNodes().Count);
Assert.Equal(3, h.GetEdges().Count);
Assert.Equal(2, h.GetAdjacent(new Node("1")).Count);

// edge that was not updated should have kept the component
Assert.True(h.HasComponent<EdgeDirection>(e4));
}
}
}
2 changes: 1 addition & 1 deletion SharpGraph/SharpGraph.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<TargetFramework>net8.0</TargetFramework>
<PackageId>SharpGraphLib</PackageId>
<PackageReadmeFile>README.md</PackageReadmeFile>
<Version>1.0.3</Version>
<Version>1.0.4</Version>
<Authors>Jonathan Hough</Authors>
<Company>Jonathan Hough</Company>
</PropertyGroup>
Expand Down
84 changes: 84 additions & 0 deletions SharpGraph/src/core/Graph.Contraction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// <copyright file="Graph.Contraction.cs" company="Jonathan Hough">
// Copyright (C) 2023 Jonathan Hough.
// Copyright Licensed under the MIT license.
// See LICENSE file in the samples root for full license information.
// </copyright>

using System;
using System.Collections.Generic;

namespace SharpGraph
{
public partial class Graph
{
/// <summary>
/// Contracts the edge from the graph. This essentially removes the edge form the graph.
/// Incident edges will be reassigned to connect to the "keep" node, which is one of the
/// two nodes of the to-be-deleted edge.
/// Edges that previously connected to the to-be-deleted node, will be deleted, and new edges to
/// the to-be-kept node will be created.
/// For edges not incident with the edge that is to be deleted, the edges in the returned graph will
/// be copies, including any components.
/// </summary>
/// <param name="edge">Edge to be deleted.</param>
/// <param name="keep">Node of deleted edge to keep in output graph.</param>
/// <returns>Graph with edge removed.</returns>
public Graph ContractEdge(Edge edge, Node keep)
{
if (this.GetEdges().Contains(edge) == false)
{
throw new Exception("Edge does not exist on this graph.");
}

if (!edge.Nodes().Contains(keep))
{
throw new Exception(
"Node to keep does not exist in the edge ot remove. Cannot remove edge."
);
}

var removeNode = keep == edge.To() ? edge.From() : edge.To();
var incident = this.GetIncidentEdges(removeNode);
var toRemove = new HashSet<Edge>();
var newEdges = new HashSet<Edge>();
toRemove.Add(edge);
foreach (var e in incident)
{
if (toRemove.Contains(e))
{
continue;
}

if (!e.Nodes().Contains(keep))
{
if (removeNode == e.To())
{
toRemove.Add(e);
var rex = new Edge(keep, e.From());
newEdges.Add(rex);
}
else if (removeNode == e.From())
{
toRemove.Add(e);
var rex = new Edge(keep, e.To());
newEdges.Add(rex);
}
}
}

var g = this.Copy();
foreach (var deadEdge in toRemove)
{
g.RemoveEdge(deadEdge);
}

g.RemoveNode(removeNode);
foreach (var newEdge in newEdges)
{
g.AddEdge(newEdge);
}

return g;
}
}
}
6 changes: 3 additions & 3 deletions SharpGraph/src/core/Graph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ public bool RemoveNode(Node node)
if (incidentEdges != null)
{
this.edges.RemoveAll(e => incidentEdges.Contains(e));
incidentEdges.RemoveWhere(e => incidentEdges.Contains(e));
incidentEdges.RemoveWhere(e => e.Equals(e));
}

this.nodes.Remove(node);
Expand Down Expand Up @@ -407,13 +407,13 @@ public bool RemoveEdge(Edge edge)
var fromIncidentEdges = this.incidenceMap[f];
if (fromIncidentEdges != null)
{
fromIncidentEdges.RemoveWhere(e => e.Equals(edge));
int i = fromIncidentEdges.RemoveWhere(e => e.Equals(edge));
}

var toIncidentEdges = this.incidenceMap[t];
if (toIncidentEdges != null)
{
toIncidentEdges.RemoveWhere(e => e.Equals(edge));
int i = toIncidentEdges.RemoveWhere(e => e.Equals(edge));
}

this.edgeComponents.Remove(edge);
Expand Down
6 changes: 5 additions & 1 deletion SharpGraphProj.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@
"path": "."
}
],
"settings": {}
"settings": {
"files.associations": {
".fantomasignore": "ignore"
}
}
}
Loading