loom and graphs in clojure

86
Loom and Graphs in Clojure github.com/aysylu/loom Aysylu Greenberg @aysylu22; http://aysy.lu LispNYC, August 13 th 2013

Upload: aysylu-greenberg

Post on 11-May-2015

4.451 views

Category:

Technology


4 download

DESCRIPTION

Graph algorithms are cool and fascinating. We'll look at a graph algorithms and visualization library, Loom, which is written in Clojure. We will discuss the graph API, look at implementation of the algorithms and learn about the integration of Loom with Titanium, which allows us to run the algorithms on and visualize data in graph databases.

TRANSCRIPT

Page 1: Loom and Graphs in Clojure

Loom and Graphs in Clojure

github.com/aysylu/loom

Aysylu Greenberg @aysylu22; http://aysy.lu

LispNYC, August 13th 2013

Page 2: Loom and Graphs in Clojure

Overview

•  Loom's Graph API

•  Graph Algorithms in Loom

•  Titanium Loom

•  Single Static Assignment (SSA) Loom

Page 3: Loom and Graphs in Clojure

Overview

•  Loom's Graph API

•  Graph Algorithms in Loom

•  Titanium Loom

•  SSA Loom

Page 4: Loom and Graphs in Clojure

Loom's Graph API

•  Graph, Digraph, Weighted Graph

Page 5: Loom and Graphs in Clojure

Loom's Graph API

•  Graph, Digraph, Weighted Graph •  FlyGraph

Page 6: Loom and Graphs in Clojure

Loom's Graph API

•  Graph, Digraph, Weighted Graph •  FlyGraph o  read-only, ad-hoc

Page 7: Loom and Graphs in Clojure

Loom's Graph API

•  Graph, Digraph, Weighted Graph •  FlyGraph o  read-only, ad-hoc o  edges from nodes + successors

Page 8: Loom and Graphs in Clojure

Loom's Graph API

•  Graph, Digraph, Weighted Graph •  FlyGraph o  read-only, ad-hoc o  edges from nodes + successors o  nodes and edges from successors + start

Page 9: Loom and Graphs in Clojure

Loom's Graph API

•  Uses Clojure protocols (clojure.org/protocols)

Page 10: Loom and Graphs in Clojure

Loom's Graph API

•  Uses Clojure protocols (clojure.org/protocols) o  specification only, no implementation

Page 11: Loom and Graphs in Clojure

Loom's Graph API

•  Uses Clojure protocols (clojure.org/protocols) o  specification only, no implementation o  single type can implement multiple

protocols

Page 12: Loom and Graphs in Clojure

Loom's Graph API

•  Uses Clojure protocols (clojure.org/protocols) o  specification only, no implementation o  single type can implement multiple

protocols o  interfaces: design-time choice of the type

author, protocols: can be added to a type at runtime

Page 13: Loom and Graphs in Clojure

Loom's Graph API (defprotocol Graph (add-nodes* [g nodes] "Add nodes to graph g. See add-nodes” (add-edges* [g edges] "Add edges to graph g. See add-edges")

Page 14: Loom and Graphs in Clojure

Loom's Graph API (defprotocol Graph (add-nodes* [g nodes] "Add nodes to graph g. See add-nodes” (add-edges* [g edges] "Add edges to graph g. See add-edges”) (remove-nodes* [g nodes] "Remove nodes from graph g. See

remove-nodes”) (remove-edges* [g edges] "Removes edges from graph g. See

remove-edges”) (remove-all [g] "Removes all nodes and edges from graph g")

Page 15: Loom and Graphs in Clojure

Loom's Graph API (defprotocol Graph (add-nodes* [g nodes] "Add nodes to graph g. See add-nodes” (add-edges* [g edges] "Add edges to graph g. See add-edges” (remove-nodes* [g nodes] "Remove nodes from graph g. See

remove-nodes”) (remove-edges* [g edges] "Removes edges from graph g. See

remove-edges”) (remove-all [g] "Removes all nodes and edges from graph g” (nodes [g] "Return a collection of the nodes in graph g”) (edges [g] "Edges in g. May return each edge twice in an undirected

graph")

Page 16: Loom and Graphs in Clojure

Loom's Graph API (defprotocol Graph (add-nodes* [g nodes] "Add nodes to graph g. See add-nodes” (add-edges* [g edges] "Add edges to graph g. See add-edges” (remove-nodes* [g nodes] "Remove nodes from graph g. See

remove-nodes”) (remove-edges* [g edges] "Removes edges from graph g. See

remove-edges”) (remove-all [g] "Removes all nodes and edges from graph g” (nodes [g] "Return a collection of the nodes in graph g”) (edges [g] "Edges in g. May return each edge twice in an undirected

graph”) (has-node? [g node] "Return true when node is in g”) (has-edge? [g n1 n2] "Return true when edge [n1 n2] is in g")

Page 17: Loom and Graphs in Clojure

Loom's Graph API (defprotocol Graph (add-nodes* [g nodes] "Add nodes to graph g. See add-nodes” (add-edges* [g edges] "Add edges to graph g. See add-edges” (remove-nodes* [g nodes] "Remove nodes from graph g. See

remove-nodes”) (remove-edges* [g edges] "Removes edges from graph g. See

remove-edges”) (remove-all [g] "Removes all nodes and edges from graph g” (nodes [g] "Return a collection of the nodes in graph g”) (edges [g] "Edges in g. May return each edge twice in an undirected

graph”) (has-node? [g node] "Return true when node is in g”) (has-edge? [g n1 n2] "Return true when edge [n1 n2] is in g”) (successors [g] [g node] "Return direct successors of node, or

(partial successors g)”) (out-degree [g node] "Return the number of direct successors of

node"))

Page 18: Loom and Graphs in Clojure

Loom's Graph API (defprotocol Digraph (predecessors [g] [g node] "Return direct

predecessors of node, or (partial predecessors g)”) (in-degree [g node] "Return the number direct

predecessors to node")

Page 19: Loom and Graphs in Clojure

Loom's Graph API (defprotocol Digraph (predecessors [g] [g node] "Return direct

predecessors of node, or (partial predecessors g)”) (in-degree [g node] "Return the number direct

predecessors to node”) (transpose [g] "Return a graph with all edges

reversed"))

Page 20: Loom and Graphs in Clojure

Loom's Graph API (defprotocol WeightedGraph (weight [g] [g n1 n2] "Return weight of edge [n1 n2]

or (partial weight g)"))

Page 21: Loom and Graphs in Clojure

Overview

•  Loom's Graph API

•  Graph Algorithms in Loom

•  Titanium Loom

•  SSA Loom

Page 22: Loom and Graphs in Clojure

Graph Algorithms in Loom •  DFS/BFS (+ bidirectional)

Page 23: Loom and Graphs in Clojure

Graph Algorithms in Loom •  DFS/BFS (+ bidirectional) •  Topological Sort

Page 24: Loom and Graphs in Clojure

Graph Algorithms in Loom •  DFS/BFS (+ bidirectional) •  Topological Sort •  Single Source Shortest Path (Dijkstra, Bellman-Ford)

Page 25: Loom and Graphs in Clojure

Graph Algorithms in Loom •  DFS/BFS (+ bidirectional) •  Topological Sort •  Single Source Shortest Path (Dijkstra, Bellman-Ford) •  Strongly Connected Components (Kosaraju)

Page 26: Loom and Graphs in Clojure

Graph Algorithms in Loom •  DFS/BFS (+ bidirectional) •  Topological Sort •  Single Source Shortest Path (Dijkstra, Bellman-Ford) •  Strongly Connected Components (Kosaraju) •  Density (edges/nodes)

Page 27: Loom and Graphs in Clojure

Graph Algorithms in Loom •  DFS/BFS (+ bidirectional) •  Topological Sort •  Single Source Shortest Path (Dijkstra, Bellman-Ford) •  Strongly Connected Components (Kosaraju) •  Density (edges/nodes) •  Loner nodes

Page 28: Loom and Graphs in Clojure

Graph Algorithms in Loom •  DFS/BFS (+ bidirectional) •  Topological Sort •  Single Source Shortest Path (Dijkstra, Bellman-Ford) •  Strongly Connected Components (Kosaraju) •  Density (edges/nodes) •  Loner nodes •  2 coloring

Page 29: Loom and Graphs in Clojure

Graph Algorithms in Loom •  DFS/BFS (+ bidirectional) •  Topological Sort •  Single Source Shortest Path (Dijkstra, Bellman-Ford) •  Strongly Connected Components (Kosaraju) •  Density (edges/nodes) •  Loner nodes •  2 coloring •  Max-Flow (Edmonds-Karp)

Page 30: Loom and Graphs in Clojure

Graph Algorithms in Loom •  DFS/BFS (+ bidirectional) •  Topological Sort •  Single Source Shortest Path (Dijkstra, Bellman-Ford) •  Strongly Connected Components (Kosaraju) •  Density (edges/nodes) •  Loner nodes •  2 coloring •  Max-Flow (Edmonds-Karp) •  alg-generic requires only successors + start (where

appropriate)

Page 31: Loom and Graphs in Clojure

Graph Algorithms: Bellman-Ford

A B C

D E

3 4

5

2

-8

Page 32: Loom and Graphs in Clojure

Graph Algorithms: Bellman-Ford

CLRS Introduction to Algorithms

Page 33: Loom and Graphs in Clojure

Graph Algorithms: Bellman-Ford

CLRS Introduction to Algorithms

Page 34: Loom and Graphs in Clojure

Graph Algorithms: Bellman-Ford (defn- init-estimates "Initializes path cost estimates and paths from source to all vertices, for

Bellman-Ford algorithm” [graph start] (let [nodes (disj (nodes graph) start)

path-costs {start 0} paths {start nil} infinities (repeat Double/POSITIVE_INFINITY) nils (repeat nil) init-costs (interleave nodes infinities) init-paths (interleave nodes nils)]

[(apply assoc path-costs init-costs) (apply assoc paths init-paths)]))

Page 35: Loom and Graphs in Clojure

Graph Algorithms: Bellman-Ford

Page 36: Loom and Graphs in Clojure

Graph Algorithms: Bellman-Ford

Page 37: Loom and Graphs in Clojure

Graph Algorithms: Bellman-Ford (defn- can-relax-edge? "Test for whether we can improve the shortest path to v found so far by

going through u.” [[u v :as edge] weight costs] (let [vd (get costs v)

ud (get costs u) sum (+ ud weight)]

(> vd sum)))

Page 38: Loom and Graphs in Clojure

Graph Algorithms: Bellman-Ford (defn- relax-edge "If there's a shorter path from s to v via u, update our map of

estimated path costs and map of paths from source to vertex v” [[u v :as edge] weight [costs paths :as estimates]] (let [ud (get costs u)

sum (+ ud weight)] (if (can-relax-edge? edge weight costs)

[(assoc costs v sum) (assoc paths v u)] estimates)))

Page 39: Loom and Graphs in Clojure

Graph Algorithms: Bellman-Ford

Page 40: Loom and Graphs in Clojure

Graph Algorithms: Bellman-Ford (defn- relax-edges "Performs edge relaxation on all edges in weighted directed graph” [g start estimates] (->> (edges g)

(reduce (fn [estimates [u v :as edge]] (relax-edge edge (wt g u v) estimates)) estimates)))

Page 41: Loom and Graphs in Clojure

Graph Algorithms: Bellman-Ford (defn bellman-ford

"Given a weighted, directed graph G = (V, E) with source start, the Bellman-Ford algorithm produces map of single source shortest paths and their costs if no negative-weight cycle that is reachable from the source exits, and false otherwise, indicating that no solution exists." [g start] (let [initial-estimates (init-estimates g start) ;relax-edges is calculated for all edges V-1 times [costs paths] (reduce (fn [estimates _] (relax-edges g start estimates)) initial-estimates (-> g nodes count dec range)) edges (edges g)] (if (some (fn [[u v :as edge]] (can-relax-edge? edge (wt g u v) costs)) edges) false [costs (->> (keys paths) ;remove vertices that are unreachable from source (remove #(= Double/POSITIVE_INFINITY (get costs %))) (reduce (fn [final-paths v] (assoc final-paths v ; follows the parent pointers ; to construct path from source to node v (loop [node v path ()] (if node (recur (get paths node) (cons node path)) path)))) {}))])))

Page 42: Loom and Graphs in Clojure

Graph Algorithms: Bellman-Ford (defn bellman-ford "Given a weighted, directed graph G = (V, E) with source start,

the Bellman-Ford algorithm produces map of single source shortest paths and their costs if no negative-weight cycle that is reachable from the source exits, and false otherwise, indicating that no solution exists."

Page 43: Loom and Graphs in Clojure

Graph Algorithms: Bellman-Ford [g start] (let [initial-estimates (init-estimates g start)

;relax-edges is calculated for all edges V-1 times [costs paths] (reduce (fn [estimates _] (relax-edges g start estimates)) initial-estimates (->> g (nodes) (count) (dec) (range))) edges (edges g)]

Page 44: Loom and Graphs in Clojure

Graph Algorithms: Bellman-Ford [g start] (let [initial-estimates (init-estimates g start)

;relax-edges is calculated for all edges V-1 times [costs paths] (reduce (fn [estimates _] (relax-edges g start estimates)) initial-estimates (->> g (nodes) (count) (dec) (range))) edges (edges g)]

Page 45: Loom and Graphs in Clojure

Graph Algorithms: Bellman-Ford (if (some (fn [[u v :as edge]] (can-relax-edge? edge (wt g u v) costs))

edges) false

Page 46: Loom and Graphs in Clojure

Graph Algorithms: Bellman-Ford [costs

(->> (keys paths) ;remove vertices that are unreachable from source (remove

#(= Double/POSITIVE_INFINITY (get costs %)))

Page 47: Loom and Graphs in Clojure

Graph Algorithms: Bellman-Ford [costs

(->> (keys paths) ;remove vertices that are unreachable from source (remove

#(= Double/POSITIVE_INFINITY (get costs %))) (reduce (fn [final-paths v] (assoc final-paths v ; follows the parent pointers

; to construct path from source to node v (loop [node v path ()] (if node (recur (get paths node) (cons node path)) path)))) {}))])))

Page 48: Loom and Graphs in Clojure

Overview

•  Loom's Graph API

•  Graph Algorithms

•  Titanium Loom

•  SSA Loom

Page 49: Loom and Graphs in Clojure

Titanium Loom

•  Titanium by Clojurewerkz (titanium.clojurewerkz.org)

Page 50: Loom and Graphs in Clojure

Titanium Loom

•  Titanium by Clojurewerkz (titanium.clojurewerkz.org)

•  Clojure graph library built on top of Aurelius Titan (thinkaurelius.github.com/titan)

Page 51: Loom and Graphs in Clojure

Titanium Loom

•  Titanium by Clojurewerkz (titanium.clojurewerkz.org)

•  Clojure graph library built on top of Aurelius Titan (thinkaurelius.github.com/titan)

•  Various storage backends: Cassandra, HBase, BerkeleyDB Java Edition

Page 52: Loom and Graphs in Clojure

Titanium Loom

•  Titanium by Clojurewerkz (titanium.clojurewerkz.org)

•  Clojure graph library built on top of Aurelius Titan (thinkaurelius.github.com/titan)

•  Various storage backends: Cassandra, HBase, BerkeleyDB Java Edition

•  No graph visualization

Page 53: Loom and Graphs in Clojure

Titanium Loom (let [in-mem-graph (tg/open {"storage.backend" "inmemory"})]

(tg/transact!

(let [

a (nodes/create! {:name "Node A"})

b (nodes/create! {:name "Node B"})

c (nodes/create! {:name "Node C"})

Page 54: Loom and Graphs in Clojure

Titanium Loom (let [in-mem-graph (tg/open {"storage.backend" "inmemory"})]

(tg/transact!

(let [

a (nodes/create! {:name "Node A"})

b (nodes/create! {:name "Node B"})

c (nodes/create! {:name "Node C"})

e1 (edges/connect! a "edge A->B" b)

e2 (edges/connect! b "edge B->C" c)

e3 (edges/connect! c "edge C->A” a)

graph (titanium->loom in-mem-graph)])

Page 55: Loom and Graphs in Clojure

Titanium Loom (view graph)

Page 56: Loom and Graphs in Clojure

Titanium Loom (defn titanium->loom "Converts titanium graph into Loom representation” ([titanium-graph & {:keys [node-fn edge-fn weight-fn]

:or {node-fn (nodes/get-all-vertices) edge-fn (map (juxt edges/tail-vertex edges/head-vertex) (edges/get-all-edges)) weight-fn (constantly 1)}}]

(let [nodes-set (set node-fn) edges-set (set edge-fn)]

Page 57: Loom and Graphs in Clojure

Titanium Loom (reify Graph (nodes [_] nodes-set) (edges [_] edges-set)

(has-node? [g node] (contains? (nodes g) node)) (has-edge? [g n1 n2] (contains? (edges g) [n1 n2])) (successors [g] (partial successors g)) (successors [g node] (filter (nodes g)

(seq (nodes/connected-out-vertices node)))) (out-degree [g node] (count (successors g node)))

Page 58: Loom and Graphs in Clojure

Titanium Loom (reify Graph (nodes [_] nodes-set) (edges [_] edges-set)

(has-node? [g node] (contains? (nodes g) node)) (has-edge? [g n1 n2] (contains? (edges g) [n1 n2])) (successors [g] (partial successors g)) (successors [g node] (filter (nodes g)

(seq (nodes/connected-out-vertices node)))) (out-degree [g node] (count (successors g node))) Digraph (predecessors [g] (partial predecessors g)) (predecessors [g node] (filter (nodes g) (seq (nodes/connected-in-vertices node)))) (in-degree [g node] (count (predecessors g node))) WeightedGraph (weight [g] (partial weight g)) (weight [g n1 n2] (weight-fn n1 n2))))))

Page 59: Loom and Graphs in Clojure

Overview

•  Loom's Graph API

•  Graph Algorithms

•  Titanium Loom

•  SSA Loom

Page 60: Loom and Graphs in Clojure

SSA Loom

•  Single Static Assignment (SSA) form produced by core.async

Page 61: Loom and Graphs in Clojure

SSA Loom

•  Single Static Assignment (SSA) form produced by core.async

•  Generated by parse-to-state-machine function

Page 62: Loom and Graphs in Clojure

SSA Loom (parse-to-state-machine '[(if (> (+ x 1 2 y) 0) (+ x 1) (+ x 2))])

Page 63: Loom and Graphs in Clojure

SSA Loom (parse-to-state-machine '[(if (> (+ x 1 2 y) 0) (+ x 1) (+ x 2))])

[inst_4938 {:current-block 76, :start-block 73, :block-catches {76 nil, 75 nil, 74 nil, 73 nil}, :blocks {76 [{:value :clojure.core.async.impl.ioc-macros/value, :id

inst_4937} {:value inst_4937, :id inst_4938}], 75 [{:refs [clojure.core/+ x 2], :id inst_4935} {:value inst_4935, :block 76, :id inst_4936}], 74 [{:refs [clojure.core/+ x 1], :id inst_4933} {:value inst_4933, :block 76, :id inst_4934}], 73 [{:refs [clojure.core/+ x 1 2 y], :id inst_4930} {:refs [clojure.core/> inst_4930 0], :id inst_4931} {:test inst_4931, :then-block 74, :else-block 75, :id

inst_4932}]}}]

Page 64: Loom and Graphs in Clojure

SSA Loom (def ssa (->> (parse-to-state-machine

'[(if (> (+ x 1 2 y) 0) (+ x 1) (+ x 2))]) second :blocks))

Page 65: Loom and Graphs in Clojure

SSA Loom {76 [{:value :clojure.core.async.impl.ioc-macros/

value, :id inst_4937} {:value inst_4937, :id inst_4938}], 75 [{:refs [clojure.core/+ x 2], :id inst_4935} {:value inst_4935, :block 76, :id inst_4936}], 74 [{:refs [clojure.core/+ x 1], :id inst_4933} {:value inst_4933, :block 76, :id inst_4934}], 73 [{:refs [clojure.core/+ x 1 2 y], :id inst_4930} {:refs [clojure.core/> inst_4930 0], :id

inst_4931} {:test inst_4931, :then-block 74, :else-block

75, :id inst_4932}]}}]

(def ssa (->> (parse-to-state-machine

'[(if (> (+ x 1 2 y) 0) (+ x 1) (+ x 2))]) second :blocks))

Page 66: Loom and Graphs in Clojure

SSA Loom (view (ssa->loom ssa ssa-nodes-fn ssa-edges-fn))

Page 67: Loom and Graphs in Clojure

SSA Loom (view (ssa->loom ssa ssa-nodes-fn ssa-edges-fn))

Page 68: Loom and Graphs in Clojure

SSA Loom (view (ssa->loom ssa ssa-nodes-fn ssa-edges-fn)) (defn ssa->loom "Converts the SSA form generated by core.async into Loom

representation.” ([ssa node-fn edge-fn] (let [nodes (delay (node-fn ssa))

edges (delay (edge-fn ssa))]

Page 69: Loom and Graphs in Clojure

SSA Loom (view (ssa->loom ssa ssa-nodes-fn ssa-edges-fn)) {:graph (reify Graph

(nodes [g] @nodes) (edges [g] @edges) (has-node? [g node] (contains? @nodes node)) (has-edge? [g n1 n2] (contains? @edges [n1 n2])) (successors [g] (partial successors g)) (successors [g node]

(->> @edges (filter (fn [[n1 n2]] (= n1 node))) (map second))) (out-degree [g node] (count (successors g node)))

Page 70: Loom and Graphs in Clojure

SSA Loom (view (ssa->loom ssa ssa-nodes-fn ssa-edges-fn)) Digraph

(predecessors [g] (partial predecessors g)) (predecessors [g node]

(->> @edges (filter (fn [[n1 n2]] (= n2 node))) (map first))) (in-degree [g node] (count (predecessors g node))))

:data ssa})))

Page 71: Loom and Graphs in Clojure

SSA Loom: Dataflow Analysis

•  For each basic block, solve system of equations until reaching fixed point:

•  Use worklist approach

Page 72: Loom and Graphs in Clojure

SSA Loom: Dataflow Analysis (defn dataflow-analysis "Performs dataflow analysis. Nodes have value nil initially.” [& {:keys [start graph join transfer]}] (let [start (cond

(set? start) start (coll? start) (set start) :else #{start})]

Page 73: Loom and Graphs in Clojure

SSA Loom: Dataflow Analysis (loop [out-values {}

[node & worklist] (into clojure.lang.PersistentQueue/EMPTY start) (let [in-value (join (mapv out-values (predecessors graph node)))

out (transfer node in-value) update? (not= out (get out-values node)) out-values (if update? (assoc out-values node out) out-values) worklist (if update? (into worklist (successors graph node)) worklist)]

Page 74: Loom and Graphs in Clojure

SSA Loom: Dataflow Analysis (loop [out-values {}

[node & worklist] (into clojure.lang.PersistentQueue/EMPTY start (let [in-value (join (mapv out-values (predecessors graph node)))

out (transfer node in-value) update? (not= out (get out-values node)) out-values (if update? (assoc out-values node out) out-values) worklist (if update? (into worklist (successors graph node)) worklist)]

(if (seq worklist) (recur out-values worklist) out-values)))))

Page 75: Loom and Graphs in Clojure

SSA Loom: Global Availability (defn global-cse [ssa] (let [{graph :graph node-data :data} (ssa->loom (:blocks ssa) ssa-nodes-fn ssa-edges-fn) start (:start-block ssa)] (letfn [(pure? [instr] (contains? instr :refs)) (global-cse-join [values] (if (seq values) (apply set/intersection values) #{})) (global-cse-transfer [node in-value] (into in-value (map :refs (filter pure? (node-data node)))))]

Page 76: Loom and Graphs in Clojure

SSA Loom: Global Availability (defn global-cse [ssa] (let [{graph :graph node-data :data} (ssa->loom (:blocks ssa) ssa-nodes-fn ssa-edges-fn) start (:start-block ssa)] (letfn [(pure? [instr] (contains? instr :refs)) (global-cse-join [values] (if (seq values) (apply set/intersection values) #{})) (global-cse-transfer [node in-value] (into in-value (map :refs (filter pure? (node-data node)))))] (dataflow-analysis :start start :graph graph :join global-cse-join :transfer global-cse-transfer))))

Page 77: Loom and Graphs in Clojure

SSA Loom: Dataflow Analysis

• Reaching definitions

Page 78: Loom and Graphs in Clojure

SSA Loom: Dataflow Analysis

• Reaching definitions • Liveness analysis (dead code elimination)

Page 79: Loom and Graphs in Clojure

SSA Loom: Dataflow Analysis

• Reaching definitions • Liveness analysis (dead code elimination) • Available expressions

Page 80: Loom and Graphs in Clojure

SSA Loom: Dataflow Analysis

• Reaching definitions • Liveness analysis (dead code elimination) • Available expressions • Constant propagation

Page 81: Loom and Graphs in Clojure

SSA Loom: Dataflow Analysis

• Reaching definitions • Liveness analysis (dead code elimination) • Available expressions • Constant propagation • Other Applications:

Page 82: Loom and Graphs in Clojure

SSA Loom: Dataflow Analysis

• Reaching definitions • Liveness analysis (dead code elimination) • Available expressions • Constant propagation • Other Applications:

o Erdős number

Page 83: Loom and Graphs in Clojure

SSA Loom: Dataflow Analysis

• Reaching definitions • Liveness analysis (dead code elimination) • Available expressions • Constant propagation • Other Applications:

o Erdős number o Spread of information in systems (e.g. taint)

Page 84: Loom and Graphs in Clojure

My Experience

•  Intuitive way to implement algorithms functionally

• Some mental overhead of transforming data structures

Page 85: Loom and Graphs in Clojure

Open Questions

• How general should a graph API be?

Page 86: Loom and Graphs in Clojure

Open Questions

• How general should a graph API be? • How feature-rich should a graph API be?