{"id":13687667,"url":"https://github.com/snowleopard/alga","last_synced_at":"2025-05-15T07:03:36.188Z","repository":{"id":37270298,"uuid":"75574031","full_name":"snowleopard/alga","owner":"snowleopard","description":"Algebraic graphs","archived":false,"fork":false,"pushed_at":"2024-05-19T22:27:47.000Z","size":2005,"stargazers_count":738,"open_issues_count":47,"forks_count":68,"subscribers_count":21,"default_branch":"main","last_synced_at":"2025-05-15T07:02:16.155Z","etag":null,"topics":["algebra","graph","haskell"],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/snowleopard.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS.md","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-12-05T00:30:03.000Z","updated_at":"2025-05-06T14:46:41.000Z","dependencies_parsed_at":"2022-08-02T12:07:00.180Z","dependency_job_id":"84f2aeea-242e-4a29-b2cb-ef5e907a594d","html_url":"https://github.com/snowleopard/alga","commit_stats":{"total_commits":493,"total_committers":33,"mean_commits":14.93939393939394,"dds":"0.16227180527383367","last_synced_commit":"aee5fa79a1ce53861c9a9bb770309dbf68a1bc9a"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snowleopard%2Falga","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snowleopard%2Falga/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snowleopard%2Falga/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snowleopard%2Falga/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/snowleopard","download_url":"https://codeload.github.com/snowleopard/alga/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254291961,"owners_count":22046424,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algebra","graph","haskell"],"created_at":"2024-08-02T15:00:58.352Z","updated_at":"2025-05-15T07:03:36.167Z","avatar_url":"https://github.com/snowleopard.png","language":"Haskell","funding_links":[],"categories":["Haskell"],"sub_categories":[],"readme":"# Algebraic graphs\n\n[![Hackage version](https://img.shields.io/hackage/v/algebraic-graphs.svg?label=Hackage)](https://hackage.haskell.org/package/algebraic-graphs) [![Build status](https://img.shields.io/github/actions/workflow/status/snowleopard/alga/ci.yml?branch=master)](https://github.com/snowleopard/alga/actions)\n\n**Alga** is a library for algebraic construction and manipulation of graphs in Haskell. See\n[this Haskell Symposium paper](https://github.com/snowleopard/alga-paper) and the\ncorresponding [talk](https://www.youtube.com/watch?v=EdQGLewU-8k) for the motivation\nbehind the library, the underlying theory and implementation details. There is also a\n[Haskell eXchange talk](https://skillsmatter.com/skillscasts/10635-algebraic-graphs),\nand a [tutorial](https://nobrakal.github.io/alga-tutorial) by Alexandre Moine.\n\n## Main idea\n\nConsider the following data type, which is defined in the top-level module\n[Algebra.Graph](http://hackage.haskell.org/package/algebraic-graphs/docs/Algebra-Graph.html)\nof the library:\n\n```haskell\ndata Graph a = Empty | Vertex a | Overlay (Graph a) (Graph a) | Connect (Graph a) (Graph a)\n```\n\nWe can give the following semantics to the constructors in terms of the pair **(V, E)** of graph *vertices* and *edges*:\n\n* `Empty` constructs the empty graph **(∅, ∅)**.\n* `Vertex x` constructs a graph containing a single vertex, i.e. **({x}, ∅)**.\n* `Overlay x y` overlays graphs **(Vx, Ex)** and **(Vy, Ey)** constructing **(Vx ∪ Vy, Ex ∪ Ey)**.\n* `Connect x y` connects graphs **(Vx, Ex)** and **(Vy, Ey)** constructing **(Vx ∪ Vy, Ex ∪ Ey ∪ Vx × Vy)**.\n\nAlternatively, we can give an algebraic semantics to the above graph construction primitives by defining the following\ntype class and specifying a set of laws for its instances (see module [Algebra.Graph.Class](http://hackage.haskell.org/package/algebraic-graphs/docs/Algebra-Graph-Class.html)):\n\n```haskell\nclass Graph g where\n    type Vertex g\n    empty   :: g\n    vertex  :: Vertex g -\u003e g\n    overlay :: g -\u003e g -\u003e g\n    connect :: g -\u003e g -\u003e g\n```\n\nThe laws of the type class are remarkably similar to those of a [semiring](https://en.wikipedia.org/wiki/Semiring),\nso we use `+` and `*` as convenient shortcuts for `overlay` and `connect`, respectively:\n\n* (`+`, `empty`) is an idempotent commutative monoid.\n* (`*`, `empty`) is a monoid.\n* `*` distributes over `+`, that is: `x * (y + z) == x * y + x * z` and `(x + y) * z == x * z + y * z`.\n* `*` can be decomposed: `x * y * z == x * y + x * z + y * z`.\n\nThis algebraic structure corresponds to *unlabelled directed graphs*: every expression represents a graph, and every\ngraph can be represented by an expression. Other types of graphs (e.g. undirected) can be obtained by modifying the\nabove set of laws. Algebraic graphs provide a convenient, safe and powerful interface for working with graphs in Haskell,\nand allow the application of equational reasoning for proving the correctness of graph algorithms.\n\nTo represent *non-empty graphs*, we can drop the `Empty` constructor -- see module\n[Algebra.Graph.NonEmpty](http://hackage.haskell.org/package/algebraic-graphs/docs/Algebra-Graph-NonEmpty.html).\n\nTo represent *edge-labelled graphs*, we can switch to the following data type, as\nexplained in my [Haskell eXchange 2018 talk](https://skillsmatter.com/skillscasts/12361-labelled-algebraic-graphs):\n\n```haskell\ndata Graph e a = Empty\n               | Vertex a\n               | Connect e (Graph e a) (Graph e a)\n```\n\nHere `e` is the type of edge labels. If `e` is a monoid `(\u003c+\u003e, zero)` then graph overlay can be recovered\nas `Connect zero`, and `\u003c+\u003e` corresponds to *parallel composition* of edge labels.\n\n## How fast is the library?\n\nAlga can handle graphs comprising millions of vertices and billions of edges in a matter of seconds, which is fast\nenough for many applications. We believe there is a lot of potential for improving the performance of the library, and\nthis is one of our top priorities. If you come across a performance issue when using the library, please let us know.\n\nSome preliminary benchmarks can be found [here](https://github.com/haskell-perf/graphs).\n\n## Blog posts\n\nThe development of the library has been documented in the series of blog posts:\n* Introduction: https://blogs.ncl.ac.uk/andreymokhov/an-algebra-of-graphs/\n* A few different flavours of the algebra: https://blogs.ncl.ac.uk/andreymokhov/graphs-a-la-carte/\n* Graphs in disguise or How to plan you holiday using Haskell: https://blogs.ncl.ac.uk/andreymokhov/graphs-in-disguise/\n* Old graphs from new types: https://blogs.ncl.ac.uk/andreymokhov/old-graphs-from-new-types/\n\n## Algebraic graphs in other languages\n\nAlgebraic graphs were implemented in a few other languages, including\n[Agda](http://github.com/algebraic-graphs/agda),\n[F#](https://github.com/algebraic-graphs/fsharp),\n[Scala](http://github.com/algebraic-graphs/scala) and\n[TypeScript](https://github.com/algebraic-graphs/typescript).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnowleopard%2Falga","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsnowleopard%2Falga","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnowleopard%2Falga/lists"}