A unified DSL for composing time-patterns across audio, visual, code-rewrite, and text media —
backed by egg equality saturation, forward-mode autodiff, and an optional Loro CRDT layer.
Status: v0.1.0 released. Core DSL, e-graph normalization, all four media adapters, and Python bindings are complete. JAX reverse-mode, full egglog Datalog rules, and live Loro collaboration are deferred to v0.2 — see
docs/roadmap.md.
The engine takes S-expression refrains — named, structured time-patterns — and:
- Parses them via a hand-rolled tokenizer + recursive-descent parser (
refrain-core, ~220 LOC, no external parser deps). - Normalizes the AST through
eggrewrite rules with anAstSizecost model (refrain-egraph). - Differentiates patterns using dual-number forward-mode autodiff plus an Ehrhard-Regnier differential combinator (
python/intensity_plane). - Emits to one of four pluggable adapters: audio (Strudel JSON / OSC), visual (deterministic PNG), code (Python / Rust source templates), or text (prose / bullets).
- Optionally syncs patterns across collaborators via Loro CRDT (
refrain-rhizome, opt-in--features rhizome).
(refrain melody-a
(territorialize (loop 4 (note C4 q)))
(deterritorialize (dy/dx intensity time))
(reterritorialize (quotient ~rotation ~transpose)))| Clause | Meaning |
|---|---|
territorialize |
structural decomposition of the pattern |
deterritorialize |
autodiff direction (Jacobian) |
reterritorialize |
recomposition under algebraic constraints |
The names are drawn from Deleuze and Guattari's Mille Plateaux (1980) as evocative labels for
concrete technical operations. See docs/philosophy.md for a plain-language
mapping. The implementation does not claim mathematical isomorphism with their philosophy.
Publication to crates.io and PyPI requires maintainer-supplied API tokens and is not automated in CI — see
docs/roadmap.md.
# Rust
cargo add refrain-core
# Python
pip install refrain-pyThe integration suite in
crates/refrain-adapters/tests/integration.rs
walks a canonical refrain through every adapter end-to-end and is the most useful executable
demonstration available in v0.1.0. Standalone runnable examples/ are planned for v0.2.
Run the full test suite:
cargo test --workspaceRun the Python tests:
pip install -e . --no-build-isolation # or: maturin develop
pytest python/tests/refrain-core tokenizes and parses S-expressions into a Refrain struct containing optional
territorialize, deterritorialize, and reterritorialize fields. The parser is entirely
hand-rolled (~220 LOC) with no external parser crate dependency.
refrain-egraph wraps egg 0.11. Rewrite rules simplify and normalize the AST; the
AstSize extraction cost model selects the smallest equivalent term. Full Datalog-style rules
(egglog) are deferred to v0.2 pending API stability.
python/intensity_plane provides forward-mode autodiff via dual numbers and an
Ehrhard-Regnier differential combinator. JAX-backed reverse-mode and GPU support land in v0.2.
Each adapter implements the RefrainAdapter trait:
pub trait RefrainAdapter: Send + Sync {
fn name(&self) -> &str;
fn emit(&self, refrain: &ExtractedRefrain, ctx: &EmitCtx) -> Result<Vec<u8>, AdapterErr>;
fn capabilities(&self) -> AdapterCaps;
}Built-ins: AudioAdapter (Strudel JSON + OSC via rosc), VisualAdapter (deterministic PNG
via the png crate), CodeAdapter (Python + Rust source templates), TextAdapter
(prose + bullets). Auto-registration via inventory::submit! is planned for v0.2 when
third-party adapters arrive.
refrain-rhizome provides the bridge data structure that maps between Loro causal ids and
e-class ids (a two-layer HashMap). The loro crate itself is not linked in v0.1.0; the
loro_integration module is intentionally empty pending Loro 1.0 stable. The feature is
opt-in (--features rhizome); live Loro wiring is deferred to v0.2.
| Crate | Role |
|---|---|
refrain-core |
DSL parser, AST, public API |
refrain-egraph |
egg-based rewrite engine and cost extraction |
refrain-rhizome |
Loro CRDT bridge (opt-in --features rhizome) |
refrain-ffi |
PyO3 boundary (JSON in v0.1; Arrow IPC deferred to v0.2) |
refrain-adapters |
RefrainAdapter trait + four built-in adapters |
python/intensity_plane |
forward-mode autodiff + cell-complex topology |
python/refrain_py |
high-level Python API |
| Component | Status |
|---|---|
refrain-core (DSL parser + AST) |
released (v0.1.0) |
refrain-egraph (egg-based normalization) |
released (v0.1.0) |
refrain-adapters (audio / visual / code / text) |
released (v0.1.0) |
refrain-ffi (PyO3 + Arrow IPC) |
scaffolded (Arrow zero-copy deferred to v0.2) |
python/intensity_plane (forward-mode autodiff) |
released (v0.1.0, pure Python) |
refrain-rhizome (Loro CRDT) |
bridge done; live wiring deferred to v0.2 |
| JAX reverse-mode + GPU | planned v0.2 |
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
