Repository: dominikbraun/graph
Pull request #35 (2022-09-03 10:20:28)

Rename `Predecessors` to `PredecessorMap`
This makes the former Predecessors method consistent with the AdjacencyMap method.


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6970149..c4cac76 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,9 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 ## [0.10.0] - 2022-09-10
 
 ### Added
+* Added the `PredecessorMap` method for obtaining a map with all predecessors of each vertex.
 
-### Changed
-* Changed the `Predecessors` method signature and behavior towards returning a predecessor map containing all vertices.
+### Removed
+* Removed the `Predecessors` function. Use `PredecessorMap` instead and look up the respective vertex.
 
 ## [0.9.0] - 2022-08-17
 
diff --git a/directed.go b/directed.go
index adae072..c650c5e 100644
--- a/directed.go
+++ b/directed.go
@@ -127,7 +127,7 @@ func (d *directed[K, T]) AdjacencyMap() (map[K]map[K]Edge[K], error) {
 	return adjacencyMap, nil
 }
 
-func (d *directed[K, T]) Predecessors() (map[K]map[K]Edge[K], error) {
+func (d *directed[K, T]) PredecessorMap() (map[K]map[K]Edge[K], error) {
 	predecessors := make(map[K]map[K]Edge[K])
 
 	for vertexHash := range d.vertices {
diff --git a/graph.go b/graph.go
index ddf71f0..2bb7a5b 100644
--- a/graph.go
+++ b/graph.go
@@ -54,15 +54,15 @@ type Graph[K comparable, T any] interface {
 	// This design makes AdjacencyMap suitable for a wide variety of scenarios and demands.
 	AdjacencyMap() (map[K]map[K]Edge[K], error)
 
-	// Predecessors computes and returns a predecessors map containing all vertices in the graph.
+	// PredecessorMap computes and returns a predecessors map containing all vertices in the graph.
 	//
 	// The map layout is the same as for Adjacencies.
 	//
-	// For an undirected graph, Predecessors is the same as Adjacencies. For a directed graph,
-	// Predecessors is the complement of Adjacencies. This is because in a directed graph, only
+	// For an undirected graph, PredecessorMap is the same as AdjacencyMap. For a directed graph,
+	// PredecessorMap is the complement of AdjacencyMap. This is because in a directed graph, only
 	// vertices joined by an outgoing edge are considered adjacent to the current vertex, whereas
 	// predecessors are the vertices joined by an ingoing edge.
-	Predecessors() (map[K]map[K]Edge[K], error)
+	PredecessorMap() (map[K]map[K]Edge[K], error)
 }
 
 // Edge represents a graph edge with a source and target vertex as well as a weight, which has the
diff --git a/paths.go b/paths.go
index dbce8aa..d8d5ba6 100644
--- a/paths.go
+++ b/paths.go
@@ -34,9 +34,9 @@ func CreatesCycle[K comparable, T any](g Graph[K, T], source, target K) (bool, e
 		return true, nil
 	}
 
-	predecessors, err := g.Predecessors()
+	predecessorMap, err := g.PredecessorMap()
 	if err != nil {
-		return false, fmt.Errorf("failed to get predecessors: %w", err)
+		return false, fmt.Errorf("failed to get predecessor map: %w", err)
 	}
 
 	stack := make([]K, 0)
@@ -56,7 +56,7 @@ func CreatesCycle[K comparable, T any](g Graph[K, T], source, target K) (bool, e
 			}
 			visited[currentHash] = true
 
-			for adjacency := range predecessors[currentHash] {
+			for adjacency := range predecessorMap[currentHash] {
 				stack = append(stack, adjacency)
 			}
 		}
@@ -86,9 +86,9 @@ func ShortestPath[K comparable, T any](g Graph[K, T], source, target K) ([]K, er
 		return nil, fmt.Errorf("could not get adjacency map: %w", err)
 	}
 
-	predecessors, err := g.Predecessors()
+	predecessorMap, err := g.PredecessorMap()
 	if err != nil {
-		return nil, fmt.Errorf("failed to get predecessors: %w", err)
+		return nil, fmt.Errorf("failed to get predecessor map: %w", err)
 	}
 
 	for hash := range adjacencyMap {
@@ -105,7 +105,7 @@ func ShortestPath[K comparable, T any](g Graph[K, T], source, target K) ([]K, er
 		hasInfiniteWeight := math.IsInf(weights[vertex], 1)
 
 		if vertex == target {
-			targetPredecessors := predecessors[target]
+			targetPredecessors := predecessorMap[target]
 
 			if len(targetPredecessors) == 0 {
 				return nil, fmt.Errorf("vertex %v is not reachable from vertex %v", target, source)
diff --git a/undirected.go b/undirected.go
index 749abd7..381cfcf 100644
--- a/undirected.go
+++ b/undirected.go
@@ -130,7 +130,7 @@ func (u *undirected[K, T]) AdjacencyMap() (map[K]map[K]Edge[K], error) {
 	return adjacencyMap, nil
 }
 
-func (u *undirected[K, T]) Predecessors() (map[K]map[K]Edge[K], error) {
+func (u *undirected[K, T]) PredecessorMap() (map[K]map[K]Edge[K], error) {
 	return u.AdjacencyMap()
 }
 


Test patch:
diff --git a/directed_test.go b/directed_test.go
index 214d419..4d345f2 100644
--- a/directed_test.go
+++ b/directed_test.go
@@ -315,7 +315,7 @@ func TestDirected_AdjacencyList(t *testing.T) {
 	}
 }
 
-func TestDirected_Predecessors(t *testing.T) {
+func TestDirected_PredecessorMap(t *testing.T) {
 	tests := map[string]struct {
 		vertices []int
 		edges    []Edge[int]
@@ -377,7 +377,7 @@ func TestDirected_Predecessors(t *testing.T) {
 			}
 		}
 
-		predecessors, _ := graph.Predecessors()
+		predecessors, _ := graph.PredecessorMap()
 
 		for expectedVertex, expectedPredecessors := range test.expected {
 			predecessors, ok := predecessors[expectedVertex]
diff --git a/undirected_test.go b/undirected_test.go
index 1717c31..aab6378 100644
--- a/undirected_test.go
+++ b/undirected_test.go
@@ -269,7 +269,7 @@ func TestUndirected_Adjacencies(t *testing.T) {
 	}
 }
 
-func TestUndirected_Predecessors(t *testing.T) {
+func TestUndirected_PredecessorMap(t *testing.T) {
 	tests := map[string]struct {
 		vertices []int
 		edges    []Edge[int]
@@ -341,7 +341,7 @@ func TestUndirected_Predecessors(t *testing.T) {
 			}
 		}
 
-		predecessors, _ := graph.Predecessors()
+		predecessors, _ := graph.PredecessorMap()
 
 		for expectedVertex, expectedPredecessors := range test.expected {
 			predecessors, ok := predecessors[expectedVertex]