{"id":27168382,"url":"https://github.com/inconvergent/cl-grph","last_synced_at":"2026-01-21T11:06:57.695Z","repository":{"id":83601710,"uuid":"524364857","full_name":"inconvergent/cl-grph","owner":"inconvergent","description":"In-Memory Immutable Graph Structure with Datalog Query Language in Common Lisp","archived":false,"fork":false,"pushed_at":"2024-07-21T17:45:15.000Z","size":489,"stargazers_count":63,"open_issues_count":0,"forks_count":1,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-09T05:33:34.620Z","etag":null,"topics":["common-lisp","data-structures","datalog","functional-programming","generative-art","generattive","graph","immutable","incomplete","lisp","wip"],"latest_commit_sha":null,"homepage":"https://inconvergent.net","language":"Common Lisp","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/inconvergent.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-08-13T10:19:15.000Z","updated_at":"2025-01-19T22:23:07.000Z","dependencies_parsed_at":null,"dependency_job_id":"cdc58a1e-484c-414b-a179-4760939d5084","html_url":"https://github.com/inconvergent/cl-grph","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/inconvergent/cl-grph","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inconvergent%2Fcl-grph","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inconvergent%2Fcl-grph/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inconvergent%2Fcl-grph/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inconvergent%2Fcl-grph/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/inconvergent","download_url":"https://codeload.github.com/inconvergent/cl-grph/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inconvergent%2Fcl-grph/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28632313,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-21T04:47:28.174Z","status":"ssl_error","status_checked_at":"2026-01-21T04:47:22.943Z","response_time":86,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["common-lisp","data-structures","datalog","functional-programming","generative-art","generattive","graph","immutable","incomplete","lisp","wip"],"created_at":"2025-04-09T05:31:05.768Z","updated_at":"2026-01-21T11:06:57.678Z","avatar_url":"https://github.com/inconvergent.png","language":"Common Lisp","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GRPH\n\n\n## About\n\n`grph` is an in-memory immutable graph structure with\n[Datalog](https://en.wikipedia.org/wiki/Datalog) query language. The data\nstructure and interfaces are generic, but it is primarily intended to\nbe used in my generative art experiments.\n\nThe main features is that the graph data structure builds on\n[fset](https://fset.common-lisp.dev/) in order to be immutable. Furthermore, in\n`grph` the edge properties (`props`) is a native part of the graph itself.  The\ngraph topology is separated from the spatial data, and the spatial data is also\nimmutable. Having a separation between the graph and the spatial information\nmakes it easier to work with higher dimensional data.\n\nThere are many benefits to having immutable data structures; perhaps the most\ninteresting being that it makes it trivial to to create transactions.\n\nI have written about this library at\n\n - https://inconvergent.net/2023/datalog-to-svg/\n - https://inconvergent.net/2022/graph-data-structure-with-datalog-ql/\n - https://inconvergent.net/2023/lets-write-a-dsl/\n - (more to come)\n\n\n![Lines](img/lines.png)\n\n\n## Components\n\nThe `grph` system has three packages:\n\n1. `grph` contains the graph structure, as well as the query interface (Datalog\n   compiler).\n2. `xgrph` expands `grph` with spatial information.\n3. `grph/io` for exporting and importing graph data.\n\nSee the [docs folder](docs) for auomatically generated docs (incomplete).\n\n\n## Examples\n\nThe subset of Datalog currently supported in `grph` is the most basic pattern\nmatching using `and`, `or`, `not`, `or-join` and `not-join`. Rules/fixed-point\niteration is supported in `grph:rqry`. See examples.\n\nHere is a small example that demonstrates a few supported Datalog queries for a\nsmall graph:\n\nFurther examples and explanations are included in the [examples\nfolder](examples).\n\n```lisp\n(in-package :grph)\n\n(let ((g (ingest-edges (grph)\n         '((0 :A 1) (0 :C 1) (1 :A 0) (1 :A 2) (1 :A 3) (1 :C 0)\n           (2 :A 1) (3 :A 1) (3 :B 4) (3 :B 5) (3 :C 5) (3 :C 7)\n           (4 :B 3) (4 :B 5) (4 :E 5) (5 :B 3) (5 :B 4) (5 :C 3)\n           (7 :C 3)))))\n\n(veq:vpr (qry g :select (?x ?y)\n                :where (and (?x :a ?y) (?x :c ?y))))\n;\u003e '((1 0) (0 1))\n\n(veq:vpr (qry g :select (?x ?y)\n                :where (and (?x :c ?y)\n                            (not (or (?x :a 1) (?x :a 3))))))\n;\u003e '((7 3) (5 3))\n\n(let ((?x 5))\n  (veq:vpr (qry g :in ?x ; bind ?x to the \"outside\" value: 5\n                  :select ?y\n                  :where (or (?x :b ?y)\n                             (?x :a ?y)))))\n;\u003e '((3) (4))\n\n(veq:vpr (qry g :select ?r\n                :where (or-join ?r\n                         (and (?r :a ?a) (?a :b 5))\n                         (?r :c 0)\n                         (?r :e 5)))))\n;\u003e '((4) (1)))\n```\n\n![Hyper](img/hyper.png)\n\n\n## Dependencies\n\n  - [cl-veq](https://github.com/inconvergent/cl-veq). Must be installed from\n    the Github repo (not quicklisp).\n  - [fset](https://fset.common-lisp.dev/). Automatically installed via\n    quicklisp.\n  - [lparallel](https://lparallel.org/). Installed via quicklisp.\n  - [auxin](https://github.com/inconvergent/auxin). Some of the examples depend\n    on `auxin`. But the `grph` system does not require `auxin` directly.\n\n\n## Tests\n\nTests can be executed with `(asdf:test-system :grph)`. Or by executing\n`./run-tests.sh`.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finconvergent%2Fcl-grph","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finconvergent%2Fcl-grph","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finconvergent%2Fcl-grph/lists"}