digraph: add transpose

Change-Id: Idd6299fd7397840000139ce4fbea43a95ee76b1e
Reviewed-on: https://go-review.googlesource.com/c/tools/+/186797
Reviewed-by: Alan Donovan <adonovan@google.com>
Run-TryBot: Alan Donovan <adonovan@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/cmd/digraph/digraph.go b/cmd/digraph/digraph.go
index 73835d8..4c682c3 100644
--- a/cmd/digraph/digraph.go
+++ b/cmd/digraph/digraph.go
@@ -17,6 +17,8 @@
 		the set of all nodes
 	degree
 		the in-degree and out-degree of each node
+	transpose
+		the reverse of the input edges
 	preds <node> ...
 		the set of immediate predecessors of the specified nodes
 	succs <node> ...
@@ -101,6 +103,8 @@
 		the set of all nodes
 	degree
 		the in-degree and out-degree of each node
+	transpose
+		the reverse of the input edges
 	preds <node> ...
 		the set of immediate predecessors of the specified nodes
 	succs <node> ...
@@ -391,6 +395,21 @@
 			fmt.Fprintf(stdout, "%d\t%d\t%s\n", len(rev[label]), len(g[label]), label)
 		}
 
+	case "transpose":
+		if len(args) != 0 {
+			return fmt.Errorf("usage: digraph tranpose")
+		}
+		var revEdges []string
+		for node, succs := range g.transpose() {
+			for succ := range succs {
+				revEdges = append(revEdges, fmt.Sprintf("%s %s", node, succ))
+			}
+		}
+		sort.Strings(revEdges) // make output deterministic
+		for _, e := range revEdges {
+			fmt.Fprintln(stdout, e)
+		}
+
 	case "succs", "preds":
 		if len(args) == 0 {
 			return fmt.Errorf("usage: digraph %s <label> ...", cmd)
diff --git a/cmd/digraph/digraph_test.go b/cmd/digraph/digraph_test.go
index 0f99ac3..cf4d3b5 100644
--- a/cmd/digraph/digraph_test.go
+++ b/cmd/digraph/digraph_test.go
@@ -38,6 +38,7 @@
 	}{
 		{"nodes", g1, "nodes", nil, "belt\nhat\njacket\npants\nshirt\nshoes\nshorts\nsocks\nsweater\ntie\n"},
 		{"reverse", g1, "reverse", []string{"jacket"}, "jacket\nshirt\nsweater\n"},
+		{"transpose", g1, "transpose", nil, "belt pants\njacket sweater\npants shorts\nshoes pants\nshoes socks\nsweater shirt\ntie shirt\n"},
 		{"forward", g1, "forward", []string{"socks"}, "shoes\nsocks\n"},
 		{"forward multiple args", g1, "forward", []string{"socks", "sweater"}, "jacket\nshoes\nsocks\nsweater\n"},
 		{"scss", g2, "sccs", nil, "a\nb\nc d\n"},