• Stars
    star
    420
  • Rank 103,194 (Top 3 %)
  • Language
    Rust
  • License
    Apache License 2.0
  • Created about 4 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Datalog compiler embedded in Rust as a procedural macro

Crepe

github crates.io docs.rs build status

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.

Features

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

Example

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

use crepe::crepe;

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

    @output
    struct Reachable(i32, i32);

    Reachable(x, y) <- Edge(x, y);
    Reachable(x, z) <- Edge(x, y), Reachable(y, z);
}

fn main() {
    let mut runtime = Crepe::new();
    runtime.extend([Edge(1, 2), Edge(2, 3), Edge(3, 4), Edge(2, 5)]);

    let (reachable,) = runtime.run();
    for Reachable(x, y) in reachable {
        println!("node {} can reach node {}", x, y);
    }
}

Output:

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 MAX_PATH_LEN.

use crepe::crepe;

const MAX_PATH_LEN: u32 = 20;

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

    @output
    struct Walk(i32, i32, u32);

    @output
    struct NoWalk(i32, i32);

    struct Node(i32);

    Node(x) <- Edge(x, _, _);
    Node(x) <- Edge(_, x, _);

    Walk(x, x, 0) <- Node(x);
    Walk(x, z, len1 + len2) <-
        Edge(x, y, len1),
        Walk(y, z, len2),
        (len1 + len2 <= MAX_PATH_LEN);

    NoWalk(x, y) <- Node(x), Node(y), !Walk(x, y, _);
}

fn main() {
    let n = 256;
    let mut edges = Vec::new();
    for i in 0..n {
        for j in 0..n {
            if rand::random::<f32>() < 0.02 {
                edges.push(Edge(i, j, 5));
            }
        }
    }

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

Output:

Walk: 89203
NoWalk: 8207

Notes

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 benches/ directory. The benchmarks can be run using cargo bench.

This macro generates a Crepe 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.

Acknowledgements

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

More Repositories

1

bore

🕳 bore is a simple CLI tool for making tunnels to localhost
Rust
7,500
star
2

sshx

Fast, collaborative live terminal sharing over the web
Rust
4,118
star
3

rustpad

Efficient and minimal collaborative code editor, self-hosted, no database required
Rust
3,144
star
4

graphics-workshop

Learn computer graphics by writing GPU shaders!
GLSL
1,999
star
5

percival

📝 Web-based, reactive Datalog notebooks for data analysis and visualization
Rust
595
star
6

composing.studio

Collaborative music composition for everyone.
TypeScript
524
star
7

setwithfriends

🎮 A frictionless multiplayer web app that lets you play Set with friends
JavaScript
523
star
8

rpt

A physically-based path tracer
Rust
410
star
9

inline-sql

🪄 Inline SQL in any Python program
Python
407
star
10

fastseg

📸 PyTorch implementation of MobileNetV3 for real-time semantic segmentation, with pretrained weights & state-of-the-art performance
Python
334
star
11

classes.wtf

A course catalog with extremely fast full-text search
Go
294
star
12

redis-rope

🪢 A fast native data type for manipulating large strings in Redis
Zig
110
star
13

ukanren-rs

Rust implementation of µKanren, a featherweight relational programming language.
Rust
104
star
14

rushlight

Real-time collaborative code editing on your own infrastructure
TypeScript
95
star
15

dispict

Design a growing artistic exhibit of your own making, with semantic search powered by OpenAI CLIP
Svelte
62
star
16

library

Advanced algorithm and data structure library in C++
C++
55
star
17

char-rnn-keras

TensorFlow implementation of multi-layer recurrent neural networks for training and sampling from texts
Python
42
star
18

harmony

🎶 Generate four-part harmony following idiomatic voice-leading procedures with DP!
Python
42
star
19

ekzhang.github.io

Source code for my personal website
Svelte
27
star
20

wkspace

Competitive programming workspace in the cloud, with support for running and testing code
JavaScript
24
star
21

vae-cnn-mnist

Conditional variational autoencoder applied to EMNIST + an interactive demo to explore the latent space.
Jupyter Notebook
22
star
22

game-of-life

Conway's Game of Life simulator running in the browser, based on the HashLife algorithm (quadtrees + memoization)
Vue
21
star
23

aoc23-alpha

Advent of Code 2023 in 25 interesting language specimens, A-Z
Erlang
20
star
24

ekzhang.sty

My personal LaTeX template, with sensible formatting and commands
TeX
15
star
25

aoc21-alpha

Advent of Code 2021 in 25 different languages, alphabet soup edition
Crystal
13
star
26

sketching

Geometry processing for real-time pencil sketching
JavaScript
10
star
27

langevin-music

Noise-conditional score networks for music composition by annealed Langevin dynamics
Python
8
star
28

music-gen

Generate and play music with a recurrent neural network running in the browser!
JavaScript
7
star
29

cs262

Solutions to introductory distributed computing exercises
Rust
6
star
30

webgl-julia-viewer

Real-time Julia Set renderer right in your browser, accelerated with WebGL
TypeScript
6
star
31

market-game

Webapp for running estimation markets
JavaScript
6
star
32

warp-pastebin

Pastebin demo app, powered by warp
Rust
5
star
33

hydroelastics

Efficient contact dynamics simulation using a hydroelastic pressure field model
Julia
5
star
34

triangulate

Fast polygon triangulation in C++, compiled to WebAssembly with Emscripten
C++
4
star
35

julia-fractal

A multithreaded Julia fractal image plotter in C++.
C++
4
star
36

archax

Experiments in multi-architecture parallelism for deep learning with JAX
Python
3
star
37

ekzlib

Source code for the ekzlib website
TypeScript
2
star
38

gravity

JS canvas universal gravity simulator
JavaScript
2
star
39

gha-cross-rs

Fast Rust cross-compilation for every platform in GitHub Actions
Rust
2
star
40

zola-blog-starter

HTML
2
star
41

julia-viewer

Java
1
star
42

chess-aops

Holds code for chess in the AoPS Classroom
JavaScript
1
star
43

inflatable

Code for the paper "Limit Densities of Patterns in Permutation Inflations"
Python
1
star
44

homebrew-bore

Deprecated in favor of official Homebrew Core formula for bore
Ruby
1
star
45

super-tictactoe

Super Tic-Tac-Toe: web interface and Monte Carlo tree search (MCTS) algorithm
JavaScript
1
star
46

warp-react-template

Warp + React + 🐳
JavaScript
1
star
47

js-games

Collection of browser-based games for demo purposes, all <200 lines of code
JavaScript
1
star