Need help with crepe?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

224 Stars 10 Forks Other 49 Commits 4 Opened issues


Datalog compiler embedded in Rust as a procedural macro

Services available


Need anything else?

Contributors list

# 108,699
The Jul...
38 commits

Crepe   Latest Version

Crepe is a library that allows you to write declarative logic programs in Rust, with a Datalog-like syntax. It provides a procedural macro that generates efficient, safe code and interoperates seamlessly with Rust programs.


  • Semi-naive evaluation
  • Stratified negation
  • Automatic generation of indices for relations
  • Easily call Rust functions from within Datalog rules
  • Typesafe way to initialize
  • Very fast, compiled directly with the rest of your Rust code


The program below computes the transitive closure of a directed graph. Note the use of the

use crepe::crepe;

crepe! { @input struct Edge(i32, i32);

struct Reachable(i32, i32);

Reachable(x, y) 


node 1 can reach node 2
node 1 can reach node 3
node 1 can reach node 4
node 1 can reach node 5
node 2 can reach node 3
node 2 can reach node 4
node 2 can reach node 5
node 3 can reach node 4

You can do much more with Crepe. The next example shows how you can use stratified negation, Rust expression syntax, and semi-naive evaluation to find all paths in a weighted graph with length at most

use crepe::crepe;

const MAX_PATH_LEN: u32 = 20;

crepe! { @input struct Edge(i32, i32, u32);

struct Walk(i32, i32, u32);

struct NoWalk(i32, i32);

struct Node(i32);

Node(x) () < 0.02 {
            edges.push(Edge(i, j, 5));

let mut runtime = Crepe::new();
let (walk, nowalk) =;
println!("Walk: {}", walk.len());
println!("NoWalk: {}", nowalk.len());



Walk: 89203
NoWalk: 8207


From initial testing, the generated code is very fast. Variants of transitive closure for large graphs (~106 relations) run at comparable speed to compiled Souffle, and use a fraction of the compilation time.

For benchmarks, see the

directory. The benchmarks can be run using

cargo bench

This macro generates a

struct in the current module, as well as structs for all of the declared relations. This means that to integrate Crepe inside a larger program, you should put it in its own module with related code. See the documentation for more information.


This project was heavily inspired by Souffle and Formulog, which both use similar models of Datalog compilation for static analysis.

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.