SlideShare a Scribd company logo
1 of 86
Download to read offline
Loom and Graphs
in Clojure
github.com/aysylu/loom
Aysylu Greenberg
@aysylu22; http://aysy.lu
LispNYC, August 13th 2013
Overview
•  Loom's Graph API
•  Graph Algorithms in Loom
•  Titanium Loom
•  Single Static Assignment (SSA) Loom
Overview
•  Loom's Graph API
•  Graph Algorithms in Loom
•  Titanium Loom
•  SSA Loom
Loom's Graph API
•  Graph, Digraph, Weighted Graph
Loom's Graph API
•  Graph, Digraph, Weighted Graph
•  FlyGraph
Loom's Graph API
•  Graph, Digraph, Weighted Graph
•  FlyGraph
o  read-only, ad-hoc
Loom's Graph API
•  Graph, Digraph, Weighted Graph
•  FlyGraph
o  read-only, ad-hoc
o  edges from nodes + successors
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
Loom's Graph API
•  Uses Clojure protocols
(clojure.org/protocols)
Loom's Graph API
•  Uses Clojure protocols
(clojure.org/protocols)
o  specification only, no implementation
Loom's Graph API
•  Uses Clojure protocols
(clojure.org/protocols)
o  specification only, no implementation
o  single type can implement multiple
protocols
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
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")
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")
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")
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")
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"))
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")
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"))
Loom's Graph API
(defprotocol WeightedGraph
(weight [g] [g n1 n2] "Return weight of edge [n1 n2]
or (partial weight g)"))
Overview
•  Loom's Graph API
•  Graph Algorithms in Loom
•  Titanium Loom
•  SSA Loom
Graph Algorithms in Loom
•  DFS/BFS (+ bidirectional)
Graph Algorithms in Loom
•  DFS/BFS (+ bidirectional)
•  Topological Sort
Graph Algorithms in Loom
•  DFS/BFS (+ bidirectional)
•  Topological Sort
•  Single Source Shortest Path (Dijkstra, Bellman-Ford)
Graph Algorithms in Loom
•  DFS/BFS (+ bidirectional)
•  Topological Sort
•  Single Source Shortest Path (Dijkstra, Bellman-Ford)
•  Strongly Connected Components (Kosaraju)
Graph Algorithms in Loom
•  DFS/BFS (+ bidirectional)
•  Topological Sort
•  Single Source Shortest Path (Dijkstra, Bellman-Ford)
•  Strongly Connected Components (Kosaraju)
•  Density (edges/nodes)
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
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
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)
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)
Graph Algorithms: Bellman-Ford
A B C
D E
3 4
5
2
-8
Graph Algorithms: Bellman-Ford
CLRS Introduction to Algorithms
Graph Algorithms: Bellman-Ford
CLRS Introduction to Algorithms
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)]))
Graph Algorithms: Bellman-Ford
Graph Algorithms: Bellman-Ford
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)))
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)))
Graph Algorithms: Bellman-Ford
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)))
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))))
{}))])))
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."
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)]
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)]
Graph Algorithms: Bellman-Ford
(if (some (fn [[u v :as edge]]
(can-relax-edge? edge (wt g u v) costs))
edges)
false
Graph Algorithms: Bellman-Ford
[costs
(->> (keys paths)
;remove vertices that are unreachable from source
(remove
#(= Double/POSITIVE_INFINITY (get costs %)))
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))))
{}))])))
Overview
•  Loom's Graph API
•  Graph Algorithms
•  Titanium Loom
•  SSA Loom
Titanium Loom
•  Titanium by Clojurewerkz
(titanium.clojurewerkz.org)
Titanium Loom
•  Titanium by Clojurewerkz
(titanium.clojurewerkz.org)
•  Clojure graph library built on top of Aurelius
Titan (thinkaurelius.github.com/titan)
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
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
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"})
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)])
Titanium Loom
(view graph)
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)]
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)))
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))))))
Overview
•  Loom's Graph API
•  Graph Algorithms
•  Titanium Loom
•  SSA Loom
SSA Loom
•  Single Static Assignment (SSA) form
produced by core.async
SSA Loom
•  Single Static Assignment (SSA) form
produced by core.async
•  Generated by parse-to-state-machine
function
SSA Loom
(parse-to-state-machine
'[(if (> (+ x 1 2 y) 0)
(+ x 1)
(+ x 2))])
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}]}}]
SSA Loom
(def ssa
(->>
(parse-to-state-machine
'[(if (> (+ x 1 2 y) 0)
(+ x 1)
(+ x 2))])
second
:blocks))
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))
SSA Loom
(view (ssa->loom ssa ssa-nodes-fn ssa-edges-fn))
SSA Loom
(view (ssa->loom ssa ssa-nodes-fn ssa-edges-fn))
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))]
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)))
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})))
SSA Loom: Dataflow Analysis
•  For each basic block, solve system of
equations until reaching fixed point:
•  Use worklist approach
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})]
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)]
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)))))
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)))))]
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))))
SSA Loom: Dataflow Analysis
• Reaching definitions
SSA Loom: Dataflow Analysis
• Reaching definitions
• Liveness analysis (dead code elimination)
SSA Loom: Dataflow Analysis
• Reaching definitions
• Liveness analysis (dead code elimination)
• Available expressions
SSA Loom: Dataflow Analysis
• Reaching definitions
• Liveness analysis (dead code elimination)
• Available expressions
• Constant propagation
SSA Loom: Dataflow Analysis
• Reaching definitions
• Liveness analysis (dead code elimination)
• Available expressions
• Constant propagation
• Other Applications:
SSA Loom: Dataflow Analysis
• Reaching definitions
• Liveness analysis (dead code elimination)
• Available expressions
• Constant propagation
• Other Applications:
o  Erdős number
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)
My Experience
• Intuitive way to implement algorithms
functionally
• Some mental overhead of transforming data
structures
Open Questions
• How general should a graph API be?
Open Questions
• How general should a graph API be?
• How feature-rich should a graph API be?

More Related Content

What's hot

Crystal Ball Event Prediction and Log Analysis with Hadoop MapReduce and Spark
Crystal Ball Event Prediction and Log Analysis with Hadoop MapReduce and SparkCrystal Ball Event Prediction and Log Analysis with Hadoop MapReduce and Spark
Crystal Ball Event Prediction and Log Analysis with Hadoop MapReduce and SparkJivan Nepali
 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Philip Schwarz
 
Value objects in JS - an ES7 work in progress
Value objects in JS - an ES7 work in progressValue objects in JS - an ES7 work in progress
Value objects in JS - an ES7 work in progressBrendan Eich
 
Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...Piotr Paradziński
 
JS Responsibilities
JS ResponsibilitiesJS Responsibilities
JS ResponsibilitiesBrendan Eich
 
Building Enigma with State Monad & Lens
Building Enigma with State Monad & LensBuilding Enigma with State Monad & Lens
Building Enigma with State Monad & LensTimothy Perrett
 
lecture 6
lecture 6lecture 6
lecture 6sajinsc
 
Configurable Pattern Matching Semantics in openCypher: Defining Levels of Nod...
Configurable Pattern Matching Semantics in openCypher: Defining Levels of Nod...Configurable Pattern Matching Semantics in openCypher: Defining Levels of Nod...
Configurable Pattern Matching Semantics in openCypher: Defining Levels of Nod...openCypher
 
Audio chord recognition using deep neural networks
Audio chord recognition using deep neural networksAudio chord recognition using deep neural networks
Audio chord recognition using deep neural networksbzamecnik
 
Mathematical preliminaries in Automata
Mathematical preliminaries in AutomataMathematical preliminaries in Automata
Mathematical preliminaries in AutomataMobeen Mustafa
 
Graph x pregel
Graph x pregelGraph x pregel
Graph x pregelSigmoid
 
Shape Safety in Tensor Programming is Easy for a Theorem Prover -SBTB 2021
Shape Safety in Tensor Programming is Easy for a Theorem Prover -SBTB 2021Shape Safety in Tensor Programming is Easy for a Theorem Prover -SBTB 2021
Shape Safety in Tensor Programming is Easy for a Theorem Prover -SBTB 2021Peng Cheng
 
RUSTing -- Partially Ordered Rust Programming Ruminations
RUSTing -- Partially Ordered Rust Programming RuminationsRUSTing -- Partially Ordered Rust Programming Ruminations
RUSTing -- Partially Ordered Rust Programming RuminationsAngelo Corsaro
 
Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Philip Schwarz
 
Computer graphics practical(jainam)
Computer graphics practical(jainam)Computer graphics practical(jainam)
Computer graphics practical(jainam)JAINAM KAPADIYA
 
Functional IO and Effects
Functional IO and EffectsFunctional IO and Effects
Functional IO and EffectsDylan Forciea
 

What's hot (17)

20180722 pyro
20180722 pyro20180722 pyro
20180722 pyro
 
Crystal Ball Event Prediction and Log Analysis with Hadoop MapReduce and Spark
Crystal Ball Event Prediction and Log Analysis with Hadoop MapReduce and SparkCrystal Ball Event Prediction and Log Analysis with Hadoop MapReduce and Spark
Crystal Ball Event Prediction and Log Analysis with Hadoop MapReduce and Spark
 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1
 
Value objects in JS - an ES7 work in progress
Value objects in JS - an ES7 work in progressValue objects in JS - an ES7 work in progress
Value objects in JS - an ES7 work in progress
 
Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...
 
JS Responsibilities
JS ResponsibilitiesJS Responsibilities
JS Responsibilities
 
Building Enigma with State Monad & Lens
Building Enigma with State Monad & LensBuilding Enigma with State Monad & Lens
Building Enigma with State Monad & Lens
 
lecture 6
lecture 6lecture 6
lecture 6
 
Configurable Pattern Matching Semantics in openCypher: Defining Levels of Nod...
Configurable Pattern Matching Semantics in openCypher: Defining Levels of Nod...Configurable Pattern Matching Semantics in openCypher: Defining Levels of Nod...
Configurable Pattern Matching Semantics in openCypher: Defining Levels of Nod...
 
Audio chord recognition using deep neural networks
Audio chord recognition using deep neural networksAudio chord recognition using deep neural networks
Audio chord recognition using deep neural networks
 
Mathematical preliminaries in Automata
Mathematical preliminaries in AutomataMathematical preliminaries in Automata
Mathematical preliminaries in Automata
 
Graph x pregel
Graph x pregelGraph x pregel
Graph x pregel
 
Shape Safety in Tensor Programming is Easy for a Theorem Prover -SBTB 2021
Shape Safety in Tensor Programming is Easy for a Theorem Prover -SBTB 2021Shape Safety in Tensor Programming is Easy for a Theorem Prover -SBTB 2021
Shape Safety in Tensor Programming is Easy for a Theorem Prover -SBTB 2021
 
RUSTing -- Partially Ordered Rust Programming Ruminations
RUSTing -- Partially Ordered Rust Programming RuminationsRUSTing -- Partially Ordered Rust Programming Ruminations
RUSTing -- Partially Ordered Rust Programming Ruminations
 
Sequence and Traverse - Part 3
Sequence and Traverse - Part 3Sequence and Traverse - Part 3
Sequence and Traverse - Part 3
 
Computer graphics practical(jainam)
Computer graphics practical(jainam)Computer graphics practical(jainam)
Computer graphics practical(jainam)
 
Functional IO and Effects
Functional IO and EffectsFunctional IO and Effects
Functional IO and Effects
 

Similar to Loom and Graphs in Clojure

Loom & Functional Graphs in Clojure @ LambdaConf 2015
Loom & Functional Graphs in Clojure @ LambdaConf 2015Loom & Functional Graphs in Clojure @ LambdaConf 2015
Loom & Functional Graphs in Clojure @ LambdaConf 2015Aysylu Greenberg
 
ABSTRACT GRAPH MACHINE: MODELING ORDERINGS IN ASYNCHRONOUS DISTRIBUTED-MEMORY...
ABSTRACT GRAPH MACHINE: MODELING ORDERINGS IN ASYNCHRONOUS DISTRIBUTED-MEMORY...ABSTRACT GRAPH MACHINE: MODELING ORDERINGS IN ASYNCHRONOUS DISTRIBUTED-MEMORY...
ABSTRACT GRAPH MACHINE: MODELING ORDERINGS IN ASYNCHRONOUS DISTRIBUTED-MEMORY...Thejaka Amila Kanewala, Ph.D.
 
[系列活動] Data exploration with modern R
[系列活動] Data exploration with modern R[系列活動] Data exploration with modern R
[系列活動] Data exploration with modern R台灣資料科學年會
 
DrawingML Subject: Shape Properties & Effects
DrawingML Subject: Shape Properties & EffectsDrawingML Subject: Shape Properties & Effects
DrawingML Subject: Shape Properties & EffectsShawn Villaron
 
A walk in graph databases v1.0
A walk in graph databases v1.0A walk in graph databases v1.0
A walk in graph databases v1.0Pierre De Wilde
 
141222 graphulo ingraphblas
141222 graphulo ingraphblas141222 graphulo ingraphblas
141222 graphulo ingraphblasMIT
 
141205 graphulo ingraphblas
141205 graphulo ingraphblas141205 graphulo ingraphblas
141205 graphulo ingraphblasgraphulo
 
La R Users Group Survey Of R Graphics
La R Users Group Survey Of R GraphicsLa R Users Group Survey Of R Graphics
La R Users Group Survey Of R Graphicsguest43ed8709
 
IGraph a tool to analyze your network
IGraph a tool to analyze your networkIGraph a tool to analyze your network
IGraph a tool to analyze your networkPushpendra Tiwari
 
Introductionto fp with groovy
Introductionto fp with groovyIntroductionto fp with groovy
Introductionto fp with groovyIsuru Samaraweera
 
Tech talk ggplot2
Tech talk   ggplot2Tech talk   ggplot2
Tech talk ggplot2jalle6
 
PART 4: GEOGRAPHIC SCRIPTING
PART 4: GEOGRAPHIC SCRIPTINGPART 4: GEOGRAPHIC SCRIPTING
PART 4: GEOGRAPHIC SCRIPTINGAndrea Antonello
 
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵Wanbok Choi
 

Similar to Loom and Graphs in Clojure (20)

Loom & Functional Graphs in Clojure @ LambdaConf 2015
Loom & Functional Graphs in Clojure @ LambdaConf 2015Loom & Functional Graphs in Clojure @ LambdaConf 2015
Loom & Functional Graphs in Clojure @ LambdaConf 2015
 
Loom at Clojure/West
Loom at Clojure/WestLoom at Clojure/West
Loom at Clojure/West
 
ABSTRACT GRAPH MACHINE: MODELING ORDERINGS IN ASYNCHRONOUS DISTRIBUTED-MEMORY...
ABSTRACT GRAPH MACHINE: MODELING ORDERINGS IN ASYNCHRONOUS DISTRIBUTED-MEMORY...ABSTRACT GRAPH MACHINE: MODELING ORDERINGS IN ASYNCHRONOUS DISTRIBUTED-MEMORY...
ABSTRACT GRAPH MACHINE: MODELING ORDERINGS IN ASYNCHRONOUS DISTRIBUTED-MEMORY...
 
[系列活動] Data exploration with modern R
[系列活動] Data exploration with modern R[系列活動] Data exploration with modern R
[系列活動] Data exploration with modern R
 
Twopi.1
Twopi.1Twopi.1
Twopi.1
 
DrawingML Subject: Shape Properties & Effects
DrawingML Subject: Shape Properties & EffectsDrawingML Subject: Shape Properties & Effects
DrawingML Subject: Shape Properties & Effects
 
A walk in graph databases v1.0
A walk in graph databases v1.0A walk in graph databases v1.0
A walk in graph databases v1.0
 
141222 graphulo ingraphblas
141222 graphulo ingraphblas141222 graphulo ingraphblas
141222 graphulo ingraphblas
 
141205 graphulo ingraphblas
141205 graphulo ingraphblas141205 graphulo ingraphblas
141205 graphulo ingraphblas
 
Groovy
GroovyGroovy
Groovy
 
8150.graphs
8150.graphs8150.graphs
8150.graphs
 
Algorithms Design Assignment Help
Algorithms Design Assignment HelpAlgorithms Design Assignment Help
Algorithms Design Assignment Help
 
La R Users Group Survey Of R Graphics
La R Users Group Survey Of R GraphicsLa R Users Group Survey Of R Graphics
La R Users Group Survey Of R Graphics
 
Algorithms Design Exam Help
Algorithms Design Exam HelpAlgorithms Design Exam Help
Algorithms Design Exam Help
 
AfterGlow
AfterGlowAfterGlow
AfterGlow
 
IGraph a tool to analyze your network
IGraph a tool to analyze your networkIGraph a tool to analyze your network
IGraph a tool to analyze your network
 
Introductionto fp with groovy
Introductionto fp with groovyIntroductionto fp with groovy
Introductionto fp with groovy
 
Tech talk ggplot2
Tech talk   ggplot2Tech talk   ggplot2
Tech talk ggplot2
 
PART 4: GEOGRAPHIC SCRIPTING
PART 4: GEOGRAPHIC SCRIPTINGPART 4: GEOGRAPHIC SCRIPTING
PART 4: GEOGRAPHIC SCRIPTING
 
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
 

More from Aysylu Greenberg

Software Supply Chains for DevOps @ InfoQ Live 2021
Software Supply Chains for DevOps @ InfoQ Live 2021Software Supply Chains for DevOps @ InfoQ Live 2021
Software Supply Chains for DevOps @ InfoQ Live 2021Aysylu Greenberg
 
Binary Authorization in Kubernetes
Binary Authorization in KubernetesBinary Authorization in Kubernetes
Binary Authorization in KubernetesAysylu Greenberg
 
Software Supply Chain Management with Grafeas and Kritis
Software Supply Chain Management with Grafeas and KritisSoftware Supply Chain Management with Grafeas and Kritis
Software Supply Chain Management with Grafeas and KritisAysylu Greenberg
 
Software Supply Chain Observability with Grafeas and Kritis
Software Supply Chain Observability with Grafeas and KritisSoftware Supply Chain Observability with Grafeas and Kritis
Software Supply Chain Observability with Grafeas and KritisAysylu Greenberg
 
Software Supply Chain Management with Grafeas and Kritis
Software Supply Chain Management with Grafeas and KritisSoftware Supply Chain Management with Grafeas and Kritis
Software Supply Chain Management with Grafeas and KritisAysylu Greenberg
 
Zero Downtime Migrations at Scale
Zero Downtime Migrations at ScaleZero Downtime Migrations at Scale
Zero Downtime Migrations at ScaleAysylu Greenberg
 
Distributed systems in practice, in theory (ScaleConf Colombia)
Distributed systems in practice, in theory (ScaleConf Colombia)Distributed systems in practice, in theory (ScaleConf Colombia)
Distributed systems in practice, in theory (ScaleConf Colombia)Aysylu Greenberg
 
MesosCon Asia Keynote: Replacing a Jet Engine Mid-flight
MesosCon Asia Keynote: Replacing a Jet Engine Mid-flightMesosCon Asia Keynote: Replacing a Jet Engine Mid-flight
MesosCon Asia Keynote: Replacing a Jet Engine Mid-flightAysylu Greenberg
 
Distributed systems in practice, in theory (JAX London)
Distributed systems in practice, in theory (JAX London)Distributed systems in practice, in theory (JAX London)
Distributed systems in practice, in theory (JAX London)Aysylu Greenberg
 
Building A Distributed Build System at Google Scale (StrangeLoop 2016)
Building A Distributed Build System at Google Scale (StrangeLoop 2016)Building A Distributed Build System at Google Scale (StrangeLoop 2016)
Building A Distributed Build System at Google Scale (StrangeLoop 2016)Aysylu Greenberg
 
QCon NYC: Distributed systems in practice, in theory
QCon NYC: Distributed systems in practice, in theoryQCon NYC: Distributed systems in practice, in theory
QCon NYC: Distributed systems in practice, in theoryAysylu Greenberg
 
Building a Distributed Build System at Google Scale
Building a Distributed Build System at Google ScaleBuilding a Distributed Build System at Google Scale
Building a Distributed Build System at Google ScaleAysylu Greenberg
 
Distributed systems in practice, in theory
Distributed systems in practice, in theoryDistributed systems in practice, in theory
Distributed systems in practice, in theoryAysylu Greenberg
 
Probabilistic Accuracy Bounds @ Papers We Love SF
Probabilistic Accuracy Bounds @ Papers We Love SFProbabilistic Accuracy Bounds @ Papers We Love SF
Probabilistic Accuracy Bounds @ Papers We Love SFAysylu Greenberg
 
Benchmarking (JAXLondon 2015)
Benchmarking (JAXLondon 2015)Benchmarking (JAXLondon 2015)
Benchmarking (JAXLondon 2015)Aysylu Greenberg
 
Benchmarking (DevNexus 2015)
Benchmarking (DevNexus 2015)Benchmarking (DevNexus 2015)
Benchmarking (DevNexus 2015)Aysylu Greenberg
 

More from Aysylu Greenberg (20)

Software Supply Chains for DevOps @ InfoQ Live 2021
Software Supply Chains for DevOps @ InfoQ Live 2021Software Supply Chains for DevOps @ InfoQ Live 2021
Software Supply Chains for DevOps @ InfoQ Live 2021
 
Binary Authorization in Kubernetes
Binary Authorization in KubernetesBinary Authorization in Kubernetes
Binary Authorization in Kubernetes
 
Software Supply Chain Management with Grafeas and Kritis
Software Supply Chain Management with Grafeas and KritisSoftware Supply Chain Management with Grafeas and Kritis
Software Supply Chain Management with Grafeas and Kritis
 
Software Supply Chain Observability with Grafeas and Kritis
Software Supply Chain Observability with Grafeas and KritisSoftware Supply Chain Observability with Grafeas and Kritis
Software Supply Chain Observability with Grafeas and Kritis
 
Software Supply Chain Management with Grafeas and Kritis
Software Supply Chain Management with Grafeas and KritisSoftware Supply Chain Management with Grafeas and Kritis
Software Supply Chain Management with Grafeas and Kritis
 
Zero Downtime Migrations at Scale
Zero Downtime Migrations at ScaleZero Downtime Migrations at Scale
Zero Downtime Migrations at Scale
 
Zero Downtime Migration
Zero Downtime MigrationZero Downtime Migration
Zero Downtime Migration
 
PWL Denver: Copysets
PWL Denver: CopysetsPWL Denver: Copysets
PWL Denver: Copysets
 
Distributed systems in practice, in theory (ScaleConf Colombia)
Distributed systems in practice, in theory (ScaleConf Colombia)Distributed systems in practice, in theory (ScaleConf Colombia)
Distributed systems in practice, in theory (ScaleConf Colombia)
 
MesosCon Asia Keynote: Replacing a Jet Engine Mid-flight
MesosCon Asia Keynote: Replacing a Jet Engine Mid-flightMesosCon Asia Keynote: Replacing a Jet Engine Mid-flight
MesosCon Asia Keynote: Replacing a Jet Engine Mid-flight
 
Distributed systems in practice, in theory (JAX London)
Distributed systems in practice, in theory (JAX London)Distributed systems in practice, in theory (JAX London)
Distributed systems in practice, in theory (JAX London)
 
Building A Distributed Build System at Google Scale (StrangeLoop 2016)
Building A Distributed Build System at Google Scale (StrangeLoop 2016)Building A Distributed Build System at Google Scale (StrangeLoop 2016)
Building A Distributed Build System at Google Scale (StrangeLoop 2016)
 
QCon NYC: Distributed systems in practice, in theory
QCon NYC: Distributed systems in practice, in theoryQCon NYC: Distributed systems in practice, in theory
QCon NYC: Distributed systems in practice, in theory
 
Building a Distributed Build System at Google Scale
Building a Distributed Build System at Google ScaleBuilding a Distributed Build System at Google Scale
Building a Distributed Build System at Google Scale
 
(+ Loom (years 2))
(+ Loom (years 2))(+ Loom (years 2))
(+ Loom (years 2))
 
Distributed systems in practice, in theory
Distributed systems in practice, in theoryDistributed systems in practice, in theory
Distributed systems in practice, in theory
 
Probabilistic Accuracy Bounds @ Papers We Love SF
Probabilistic Accuracy Bounds @ Papers We Love SFProbabilistic Accuracy Bounds @ Papers We Love SF
Probabilistic Accuracy Bounds @ Papers We Love SF
 
Benchmarking (JAXLondon 2015)
Benchmarking (JAXLondon 2015)Benchmarking (JAXLondon 2015)
Benchmarking (JAXLondon 2015)
 
Benchmarking (DevNexus 2015)
Benchmarking (DevNexus 2015)Benchmarking (DevNexus 2015)
Benchmarking (DevNexus 2015)
 
Benchmarking (RICON 2014)
Benchmarking (RICON 2014)Benchmarking (RICON 2014)
Benchmarking (RICON 2014)
 

Recently uploaded

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 

Recently uploaded (20)

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 

Loom and Graphs in Clojure

  • 1. Loom and Graphs in Clojure github.com/aysylu/loom Aysylu Greenberg @aysylu22; http://aysy.lu LispNYC, August 13th 2013
  • 2. Overview •  Loom's Graph API •  Graph Algorithms in Loom •  Titanium Loom •  Single Static Assignment (SSA) Loom
  • 3. Overview •  Loom's Graph API •  Graph Algorithms in Loom •  Titanium Loom •  SSA Loom
  • 4. Loom's Graph API •  Graph, Digraph, Weighted Graph
  • 5. Loom's Graph API •  Graph, Digraph, Weighted Graph •  FlyGraph
  • 6. Loom's Graph API •  Graph, Digraph, Weighted Graph •  FlyGraph o  read-only, ad-hoc
  • 7. Loom's Graph API •  Graph, Digraph, Weighted Graph •  FlyGraph o  read-only, ad-hoc o  edges from nodes + successors
  • 8. 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
  • 9. Loom's Graph API •  Uses Clojure protocols (clojure.org/protocols)
  • 10. Loom's Graph API •  Uses Clojure protocols (clojure.org/protocols) o  specification only, no implementation
  • 11. Loom's Graph API •  Uses Clojure protocols (clojure.org/protocols) o  specification only, no implementation o  single type can implement multiple protocols
  • 12. 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
  • 13. 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")
  • 14. 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")
  • 15. 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")
  • 16. 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")
  • 17. 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"))
  • 18. 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")
  • 19. 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"))
  • 20. Loom's Graph API (defprotocol WeightedGraph (weight [g] [g n1 n2] "Return weight of edge [n1 n2] or (partial weight g)"))
  • 21. Overview •  Loom's Graph API •  Graph Algorithms in Loom •  Titanium Loom •  SSA Loom
  • 22. Graph Algorithms in Loom •  DFS/BFS (+ bidirectional)
  • 23. Graph Algorithms in Loom •  DFS/BFS (+ bidirectional) •  Topological Sort
  • 24. Graph Algorithms in Loom •  DFS/BFS (+ bidirectional) •  Topological Sort •  Single Source Shortest Path (Dijkstra, Bellman-Ford)
  • 25. Graph Algorithms in Loom •  DFS/BFS (+ bidirectional) •  Topological Sort •  Single Source Shortest Path (Dijkstra, Bellman-Ford) •  Strongly Connected Components (Kosaraju)
  • 26. Graph Algorithms in Loom •  DFS/BFS (+ bidirectional) •  Topological Sort •  Single Source Shortest Path (Dijkstra, Bellman-Ford) •  Strongly Connected Components (Kosaraju) •  Density (edges/nodes)
  • 27. 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
  • 28. 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
  • 29. 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)
  • 30. 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)
  • 31. Graph Algorithms: Bellman-Ford A B C D E 3 4 5 2 -8
  • 32. Graph Algorithms: Bellman-Ford CLRS Introduction to Algorithms
  • 33. Graph Algorithms: Bellman-Ford CLRS Introduction to Algorithms
  • 34. 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)]))
  • 37. 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)))
  • 38. 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)))
  • 40. 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)))
  • 41. 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)))) {}))])))
  • 42. 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."
  • 43. 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)]
  • 44. 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)]
  • 45. Graph Algorithms: Bellman-Ford (if (some (fn [[u v :as edge]] (can-relax-edge? edge (wt g u v) costs)) edges) false
  • 46. Graph Algorithms: Bellman-Ford [costs (->> (keys paths) ;remove vertices that are unreachable from source (remove #(= Double/POSITIVE_INFINITY (get costs %)))
  • 47. 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)))) {}))])))
  • 48. Overview •  Loom's Graph API •  Graph Algorithms •  Titanium Loom •  SSA Loom
  • 49. Titanium Loom •  Titanium by Clojurewerkz (titanium.clojurewerkz.org)
  • 50. Titanium Loom •  Titanium by Clojurewerkz (titanium.clojurewerkz.org) •  Clojure graph library built on top of Aurelius Titan (thinkaurelius.github.com/titan)
  • 51. 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
  • 52. 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
  • 53. 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"})
  • 54. 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)])
  • 56. 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)]
  • 57. 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)))
  • 58. 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))))))
  • 59. Overview •  Loom's Graph API •  Graph Algorithms •  Titanium Loom •  SSA Loom
  • 60. SSA Loom •  Single Static Assignment (SSA) form produced by core.async
  • 61. SSA Loom •  Single Static Assignment (SSA) form produced by core.async •  Generated by parse-to-state-machine function
  • 62. SSA Loom (parse-to-state-machine '[(if (> (+ x 1 2 y) 0) (+ x 1) (+ x 2))])
  • 63. 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}]}}]
  • 64. SSA Loom (def ssa (->> (parse-to-state-machine '[(if (> (+ x 1 2 y) 0) (+ x 1) (+ x 2))]) second :blocks))
  • 65. 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))
  • 66. SSA Loom (view (ssa->loom ssa ssa-nodes-fn ssa-edges-fn))
  • 67. SSA Loom (view (ssa->loom ssa ssa-nodes-fn ssa-edges-fn))
  • 68. 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))]
  • 69. 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)))
  • 70. 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})))
  • 71. SSA Loom: Dataflow Analysis •  For each basic block, solve system of equations until reaching fixed point: •  Use worklist approach
  • 72. 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})]
  • 73. 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)]
  • 74. 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)))))
  • 75. 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)))))]
  • 76. 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))))
  • 77. SSA Loom: Dataflow Analysis • Reaching definitions
  • 78. SSA Loom: Dataflow Analysis • Reaching definitions • Liveness analysis (dead code elimination)
  • 79. SSA Loom: Dataflow Analysis • Reaching definitions • Liveness analysis (dead code elimination) • Available expressions
  • 80. SSA Loom: Dataflow Analysis • Reaching definitions • Liveness analysis (dead code elimination) • Available expressions • Constant propagation
  • 81. SSA Loom: Dataflow Analysis • Reaching definitions • Liveness analysis (dead code elimination) • Available expressions • Constant propagation • Other Applications:
  • 82. SSA Loom: Dataflow Analysis • Reaching definitions • Liveness analysis (dead code elimination) • Available expressions • Constant propagation • Other Applications: o  Erdős number
  • 83. 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)
  • 84. My Experience • Intuitive way to implement algorithms functionally • Some mental overhead of transforming data structures
  • 85. Open Questions • How general should a graph API be?
  • 86. Open Questions • How general should a graph API be? • How feature-rich should a graph API be?