{"id":13672024,"url":"https://github.com/ekzhang/crepe","last_synced_at":"2025-05-15T21:04:21.818Z","repository":{"id":43408549,"uuid":"291585790","full_name":"ekzhang/crepe","owner":"ekzhang","description":"Datalog compiler embedded in Rust as a procedural macro","archived":false,"fork":false,"pushed_at":"2024-03-05T08:40:05.000Z","size":74,"stargazers_count":469,"open_issues_count":5,"forks_count":16,"subscribers_count":13,"default_branch":"main","last_synced_at":"2025-04-08T01:39:36.439Z","etag":null,"topics":["datalog","logic-programming","rust","souffle","static-analysis","translator"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ekzhang.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE-APACHE","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":"2020-08-31T01:33:53.000Z","updated_at":"2025-04-01T07:20:51.000Z","dependencies_parsed_at":"2024-06-21T14:10:36.142Z","dependency_job_id":null,"html_url":"https://github.com/ekzhang/crepe","commit_stats":{"total_commits":59,"total_committers":4,"mean_commits":14.75,"dds":"0.15254237288135597","last_synced_commit":"9b97c66c8a2d175798c49a9fcecc06e771665c79"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ekzhang%2Fcrepe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ekzhang%2Fcrepe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ekzhang%2Fcrepe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ekzhang%2Fcrepe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ekzhang","download_url":"https://codeload.github.com/ekzhang/crepe/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254422754,"owners_count":22068678,"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":["datalog","logic-programming","rust","souffle","static-analysis","translator"],"created_at":"2024-08-02T09:01:24.569Z","updated_at":"2025-05-15T21:04:21.785Z","avatar_url":"https://github.com/ekzhang.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"# Crepe\n\n[\u003cimg alt=\"github\" src=\"https://img.shields.io/badge/github-ekzhang/crepe-8da0cb?style=for-the-badge\u0026labelColor=555555\u0026logo=github\" height=\"20\"\u003e](https://github.com/ekzhang/crepe)\n[\u003cimg alt=\"crates.io\" src=\"https://img.shields.io/crates/v/crepe.svg?style=for-the-badge\u0026color=fc8d62\u0026logo=rust\" height=\"20\"\u003e](https://crates.io/crates/crepe)\n[\u003cimg alt=\"docs.rs\" src=\"https://img.shields.io/badge/docs.rs-crepe-66c2a5?style=for-the-badge\u0026labelColor=555555\u0026logoColor=white\u0026logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K\" height=\"20\"\u003e](https://docs.rs/crepe)\n[\u003cimg alt=\"build status\" src=\"https://img.shields.io/github/actions/workflow/status/ekzhang/crepe/ci.yml?style=for-the-badge\" height=\"20\"\u003e](https://github.com/ekzhang/crepe/actions?query=branch%3Amain)\n\nCrepe is a library that allows you to write declarative logic programs in\nRust, with a [Datalog](https://en.wikipedia.org/wiki/Datalog)-like syntax.\nIt provides a procedural macro that generates efficient, safe code and\ninteroperates seamlessly with Rust programs.\n\n## Features\n\n- Semi-naive evaluation\n- Stratified negation\n- Automatic generation of indices for relations\n- Easily call Rust functions from within Datalog rules\n- Typesafe way to initialize `@input` relations\n- Very fast, compiled directly with the rest of your Rust code\n\n## Example\n\nThe program below computes the transitive closure of a directed graph. Note\nthe use of the `crepe!` macro.\n\n```rust\nuse crepe::crepe;\n\ncrepe! {\n    @input\n    struct Edge(i32, i32);\n\n    @output\n    struct Reachable(i32, i32);\n\n    Reachable(x, y) \u003c- Edge(x, y);\n    Reachable(x, z) \u003c- Edge(x, y), Reachable(y, z);\n}\n\nfn main() {\n    let mut runtime = Crepe::new();\n    runtime.extend([Edge(1, 2), Edge(2, 3), Edge(3, 4), Edge(2, 5)]);\n\n    let (reachable,) = runtime.run();\n    for Reachable(x, y) in reachable {\n        println!(\"node {} can reach node {}\", x, y);\n    }\n}\n```\n\nOutput:\n\n```\nnode 1 can reach node 2\nnode 1 can reach node 3\nnode 1 can reach node 4\nnode 1 can reach node 5\nnode 2 can reach node 3\nnode 2 can reach node 4\nnode 2 can reach node 5\nnode 3 can reach node 4\n```\n\nYou can do much more with Crepe. The next example shows how you can use\nstratified negation, Rust expression syntax, and semi-naive evaluation to find\nall paths in a weighted graph with length at most `MAX_PATH_LEN`.\n\n```rust\nuse crepe::crepe;\n\nconst MAX_PATH_LEN: u32 = 20;\n\ncrepe! {\n    @input\n    struct Edge(i32, i32, u32);\n\n    @output\n    struct Walk(i32, i32, u32);\n\n    @output\n    struct NoWalk(i32, i32);\n\n    struct Node(i32);\n\n    Node(x) \u003c- Edge(x, _, _);\n    Node(x) \u003c- Edge(_, x, _);\n\n    Walk(x, x, 0) \u003c- Node(x);\n    Walk(x, z, len1 + len2) \u003c-\n        Edge(x, y, len1),\n        Walk(y, z, len2),\n        (len1 + len2 \u003c= MAX_PATH_LEN);\n\n    NoWalk(x, y) \u003c- Node(x), Node(y), !Walk(x, y, _);\n}\n\nfn main() {\n    let n = 256;\n    let mut edges = Vec::new();\n    for i in 0..n {\n        for j in 0..n {\n            if rand::random::\u003cf32\u003e() \u003c 0.02 {\n                edges.push(Edge(i, j, 5));\n            }\n        }\n    }\n\n    let mut runtime = Crepe::new();\n    runtime.extend(edges);\n    let (walk, nowalk) = runtime.run();\n    println!(\"Walk: {}\", walk.len());\n    println!(\"NoWalk: {}\", nowalk.len());\n}\n```\n\nOutput:\n\n```\nWalk: 89203\nNoWalk: 8207\n```\n\n## Notes\n\nFrom initial testing, the generated code is very fast. Variants of transitive\nclosure for large graphs (~10\u003csup\u003e6\u003c/sup\u003e relations) run at comparable speed to\ncompiled [Souffle](https://souffle-lang.github.io/), and use a fraction of the\ncompilation time.\n\nFor benchmarks, see the [`benches/` directory](benches/).\nThe benchmarks can be run using `cargo bench`.\n\nThis macro generates a `Crepe` struct in the current module, as well as structs\nfor all of the declared relations. This means that to integrate Crepe inside a\nlarger program, you should put it in its own module with related code. See the\ndocumentation for more information.\n\n## Acknowledgements\n\nThis project was heavily inspired by [Souffle](https://souffle-lang.github.io/)\nand [Formulog](https://github.com/HarvardPL/formulog), which both use similar\nmodels of Datalog compilation for static analysis.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fekzhang%2Fcrepe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fekzhang%2Fcrepe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fekzhang%2Fcrepe/lists"}