Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/7bridges-eu/corallo
A tiny graph library in Clojure.
https://github.com/7bridges-eu/corallo
clojure graph
Last synced: about 1 month ago
JSON representation
A tiny graph library in Clojure.
- Host: GitHub
- URL: https://github.com/7bridges-eu/corallo
- Owner: 7bridges-eu
- License: apache-2.0
- Created: 2019-04-12T12:09:11.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2019-05-13T11:10:27.000Z (over 5 years ago)
- Last Synced: 2024-09-30T08:04:31.296Z (about 2 months ago)
- Topics: clojure, graph
- Language: Clojure
- Size: 115 KB
- Stars: 19
- Watchers: 4
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# corallo
A tiny graph library that can be used both from Clojure and ClojureScript.
[![Clojars Project](https://img.shields.io/clojars/v/eu.7bridges/corallo.svg)](https://clojars.org/eu.7bridges/corallo)
## Rationale
`corallo` was born out of our need to handle and check dependencies in graphs
which describe processes containing tasks to be executed. It was deemed helpful
and independent enough to be extracted into and released as a library of its
own.## Usage
A graph in `corallo` is a Clojure map. For instance:
``` clojure
(def g {:vertexes {:a {:value "1" :in #{} :out #{:b}}
:b {:value "2" :in #{:a} :out #{:c}}
:c {:value "3" :in #{:b} :out #{:d}}
:d {:value "4" :in #{:c} :out #{}}}
:edges {[:a :b] {}
[:b :c] {}
[:c :d] {}}})
```You can manipulate the graph by adding vertexes:
``` clojure
user> (require '[corallo.graph :as graph])
user> (graph/add-vertex g :e "5")
{:vertexes {:a {:value "1", :in #{}, :out #{:b}},
:b {:value "2", :in #{:a}, :out #{:c}},
:c {:value "3", :in #{:b}, :out #{:d}},
:d {:value "4", :in #{:c}, :out #{}},
:e {:value "5", :in #{}, :out #{}}},
:edges {[:a :b] {}, [:b :c] {}, [:c :d] {}}}
```Or you can add an edge between two vertexes:
``` clojure
user> (-> (graph/add-vertex g :e "5")
(graph/add-edge :d :e))
{:vertexes {:a {:value "1", :in #{}, :out #{:b}},
:b {:value "2", :in #{:a}, :out #{:c}},
:c {:value "3", :in #{:b}, :out #{:d}},
:d {:value "4", :in #{:c}, :out #{:e}},
:e {:value "5", :in #{:d}, :out #{}}},
:edges {[:a :b] {}, [:b :c] {}, [:c :d] {}, [:d :e] {}}}
```You can set the value of a vertex after the graph has been created:
``` clojure
user> (graph/set-vertex-value g :a "0")
{:vertexes {:a {:value "0", :in #{}, :out #{:b}},
:b {:value "2", :in #{:a}, :out #{:c}},
:c {:value "3", :in #{:b}, :out #{:d}},
:d {:value "4", :in #{:c}, :out #{}}},
:edges {[:a :b] {}, [:b :c] {}, [:c :d] {}}}
```Or you can remove a vertex:
``` clojure
user> (graph/remove-vertex g :d)
{:vertexes {:a {:value "1", :in #{}, :out #{:b}},
:b {:value "2", :in #{:a}, :out #{:c}},
:c {:value "3", :in #{:b}, :out #{}}},
:edges {[:a :b] {}, [:b :c] {}}}
```The operations in `corallo.graph` leverage Clojure immutability, so they return
a new graph instead of modifying the original one.Edges can have properties:
``` clojure
user> (-> (graph/add-vertex g :e "5")
(graph/add-edge :d :e {:p1 "a property"}))
{:vertexes {:a {:value "1", :in #{}, :out #{:b}},
:b {:value "2", :in #{:a}, :out #{:c}},
:c {:value "3", :in #{:b}, :out #{:d}},
:d {:value "4", :in #{:c}, :out #{:e}},
:e {:value "5", :in #{:d}, :out #{}}},
:edges {[:a :b] {}, [:b :c] {}, [:c :d] {}, [:d :e] {:p1 "a property"}}}user> (-> (graph/add-vertex g :e "5")
(graph/add-edge :d :e)
(graph/set-edge-properties :a :b {:p1 "a property"}))
{:vertexes {:a {:value "1", :in #{}, :out #{:b}},
:b {:value "2", :in #{:a}, :out #{:c}},
:c {:value "3", :in #{:b}, :out #{:d}},
:d {:value "4", :in #{:c}, :out #{:e}},
:e {:value "5", :in #{:d}, :out #{}}},
:edges {[:a :b] {:p1 "a property"}, [:b :c] {}, [:c :d] {}, [:d :e] {}}}
```Like vertexes, edges can be removed from the graph:
``` clojure
user> (graph/remove-edge g :c :d)
{:vertexes {:a {:value "1", :in #{}, :out #{:b}},
:b {:value "2", :in #{:a}, :out #{:c}},
:c {:value "3", :in #{:b}, :out #{}},
:d {:value "4", :in #{}, :out #{}}},
:edges {[:a :b] {}, [:b :c] {}}}
```You can query the graph for information:
``` clojure
user> (graph/neighbors g :b)
#{:c :a}user> (graph/adjacent? g :a :c)
false
user> (graph/adjacent? g :b :c)
true
```The graph can be topologically sorted:
``` clojure
user> (require '[corallo.operations :as operations])
user> (operations/topo-sort g)
(:a :b :c :d)
```And you can verify if the graph is acyclic and complete:
``` clojure
user> (operations/acyclic-graph? g)
true
user> (-> (graph/add-edge g :d :a)
operations/acyclic-graph?)
falseuser> (operations/complete-graph? g)
true
user> (-> (graph/remove-edge g :b :c)
operations/complete-graph?)
false
```Finally, in a Clojure namespace the graph can be rendered as a PNG file thanks
to [tangle](https://github.com/Macroz/tangle):``` clojure
user> (require '[corallo.render :as render])
user> (render/graph->png g "/tmp/graph.png")
nil
```And this is the resulting image for the graph `g`:
Note that you can also get the byte array representing the graph image:
``` clojure
user> (render/graph->byte-array g)
[-119, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 86, 0,
0, 1, 105, 8, 2, 0, 0, 0, -119, 111, 72, 108, 0, 0, 0, 6, 98, 75, 71, 68, 0,
-1, 0, -1, 0, -1, -96, -67, -89, ...]
```## License
Copyright © 2019 7bridges s.r.l.Distributed under the Apache License 2.0.