https://github.com/lamberta/graphael
Graph data structures and algorithms for Emacs Lisp
https://github.com/lamberta/graphael
emacs emacs-lisp
Last synced: 11 months ago
JSON representation
Graph data structures and algorithms for Emacs Lisp
- Host: GitHub
- URL: https://github.com/lamberta/graphael
- Owner: lamberta
- License: gpl-3.0
- Created: 2025-03-02T01:40:42.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-03-10T21:29:45.000Z (over 1 year ago)
- Last Synced: 2025-03-10T22:28:37.042Z (over 1 year ago)
- Topics: emacs, emacs-lisp
- Language: Emacs Lisp
- Homepage:
- Size: 70.3 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Graphael - Graph Library for Emacs
Graphael is an object-based graph data structure library for Emacs Lisp
that provides a useful API to create, manipulate, and analyze directed
graphs. Features include:
- UUID-based node and edge identification
- Directed graph representation with weighted edges
- Store arbitrary metadata on nodes and edges
- Efficient adjacency lookup with pre-computed indices
- Graph operations to merge, clone, and extract a subgraph
- Algorithms such as pathfinding, cycle detection, and topological sort
- Extensive test coverage and usage examples
## Install
Clone the repository:
```bash
$ git clone https://github.com/lamberta/graphael.git
```
Load the library in your Emacs Lisp project:
```elisp
(add-to-list 'load-path "/path/to/graphael")
(require 'graphael)
```
## Basic usage
### Create a graph and add nodes
```elisp
;; Create a new graph
(setq g (make-instance 'graph))
;; Add nodes
(setq node1 (graph-node-add g :label "Start"))
(setq node2 (graph-node-add g :label "Middle"))
(setq node3 (graph-node-add g :label "End"))
;; Add edges between nodes
(setq edge1 (graph-edge-add g :from node1 :to node2))
(setq edge2 (graph-edge-add g :from node2 :to node3 :weight 2.5))
;; Add metadata to nodes/edges
(graph-node-attr-put node1 :category "entry-point")
(graph-edge-attr-put edge2 :requires-permission t)
```
### Get node information
```elisp
;; Get a node by its ID
(setq retrieved-node (graph-node-get g (node-id node1)))
;; Get node properties
(node-label retrieved-node) ; => "Start"
(graph-node-attr-get retrieved-node :category) ; => "entry-point"
;; Get connected nodes (neighbors)
(graph-neighbors g (node-id node1)) ; => List of successor nodes
(graph-neighbors g (node-id node2) t) ; => List of predecessor nodes
```
## Advanced usage
### Find shortest path
```elisp
(cl-multiple-value-bind (path distance)
;; Use Dijkstra's algorithm
(graph-find-path-shortest g node1 node3)
(message "Length: %d nodes, Distance: %.1f" (length path) distance))
```
### Find path between nodes using A*
```elisp
;; Assume grid layout and set (x . y) coordinates for each node
(graph-node-attr-put node1 :coords '(0 . 0))
(graph-node-attr-put node2 :coords '(2 . 3))
(graph-node-attr-put node3 :coords '(5 . 3))
;; Create the Manhattan distance heuristic function
(let ((heuristic (graph-astar-manhattan-distance g
(lambda (node)
"Helper function to extract coordinates from a node"
(graph-node-attr-get node :coords)))))
(cl-multiple-value-bind (path distance)
(graph-find-path-astar g node1 node3 heuristic)
(message "Length: %d nodes, Distance: %.1f" (length path) distance)))
```
### Graph operations
```elisp
;; Create a copy of a graph
(setq g2 (graph-clone g))
;; Create a subgraph containing only specific nodes
(setq subgraph (graph-subgraph g2 (list node1 node2)))
;; Create a subgraph using a filter function
(setq filtered-graph (graph-subgraph g
(lambda (node)
(string-prefix-p "Start" (node-label node)))))
;; Merge two graphs (returns a new graph by default)
(setq merged-graph (graph-merge g g2))
;; Merge graphs in-place (modifies first graph)
(graph-merge g g2 t)
```
### Graph analysis
```elisp
;; Detect cycles in a graph
(when (graph-cycle-p g)
(message "Graph contains at least one cycle"))
;; Check if graph is connected
(graph-is-connected-p g)
;; Perform topological sort (for DAGs)
(graph-topological-sort g)
;; Get graph statistics
(graph-print-stats g)
```
### Transaction safety
```elisp
;; Execute multiple operations atomically
(with-graph-transaction (g)
(graph-node-remove g node1)
(graph-node-add g :label "Replacement"))
```
## Developer commands
Byte-compile Elisp files for compilation warnings:
```bash
$ make
```
Run tests:
```bash
$ make test
```
Use a different version of Emacs:
```bash
$ EMACS=/path/to/bin/emacs make test
```
## License
This project is licensed under the GNU General Public License v3.0 -
see the LICENSE file for details.