Leo3: Rust Bindings for Lean4
Leo3 provides safe, ergonomic Rust bindings to the Lean4 theorem prover, inspired by PyO3's architecture for Python-Rust bindings.
Project Status
⚠️ Work in Progress - Leo3 is in early development. The core architecture is established, but many features are not yet implemented.
Architecture
Leo3 is organized as a workspace with multiple crates:
leo3/
├── leo3 # Main crate - high-level safe abstractions
├── leo3-ffi # Raw FFI bindings to Lean4's C API
├── leo3-build-config # Build-time Lean4 detection and configuration
├── leo3-macros # Procedural macro entry points
└── leo3-macros-backend # Procedural macro implementations
Design Philosophy
Leo3 follows PyO3's proven architecture patterns:
- Layered Abstraction: Clear separation between raw FFI, safe wrappers, and user-facing API
- Zero-Cost:
#[repr(transparent)]wrappers with compile-time safety - Lifetime Safety: The
Lean<'l>token ensures Lean runtime initialization at compile-time - Automatic Memory Management: Smart pointers handle reference counting
- Macro-Driven Ergonomics: Procedural macros reduce boilerplate
Core Concepts
The Lean<'l> Token
All Lean operations require a Lean<'l> token, proving the runtime is initialized:
use *;
Smart Pointers
Leo3 provides two primary smart pointer types:
LeanBound<'l, T>: Tied toLean<'l>lifetime, used for most operationsLeanRef<T>: Can cross initialization boundaries, useful for storage
Both handle reference counting automatically.
Type System
Lean types are wrapped in safe Rust types with automatic conversions:
use ;
// Strings
let s = new?;
let rust_str = to_str?;
// Natural numbers
let n = from_usize?;
let value = to_usize?;
// Signed integers (i8, i16, i32, i64, isize)
let rust_int: i32 = -42;
let lean_int = rust_int.into_lean?;
let back: i32 = from_lean?;
// Floating-point (f32, f64)
let rust_float: f64 = 3.14159;
let lean_float = rust_float.into_lean?;
let back: f64 = from_lean?;
// Option<T>
let rust_opt: = Some;
let lean_opt = rust_opt.into_lean?;
let back: = from_lean?;
// Result<T, E>
let rust_result: = Ok;
let lean_result = rust_result.into_lean?;
let back: = from_lean?;
// Arrays and vectors
let vec = vec!;
let lean_arr = vec.into_lean?;
let back: = from_lean?;
Installation
Note: Lean4 must be installed on your system. Leo3 will attempt to detect it via:
LEAN_HOMEorELAN_HOMEenvironment variableslakecommandelantoolchain managerleanin PATH
Add to your Cargo.toml:
[]
= "0.1.0"
Example Usage
use *;
Feature Flags
macros(default): Enable procedural macros (#[leanfn],#[leanclass], etc.)
Comparison with PyO3
Leo3 adapts PyO3's architecture for Lean4:
| PyO3 Concept | Leo3 Equivalent | Notes |
|---|---|---|
Python<'py> |
Lean<'l> |
Runtime initialization token |
Bound<'py, T> |
LeanBound<'l, T> |
Lifetime-bound smart pointer |
Py<T> |
LeanRef<T> |
Unbound smart pointer |
#[pyfunction] |
#[leanfn] |
Function export macro |
#[pyclass] |
#[leanclass] |
Class export macro (planned) |
PyObject |
lean_object |
Base object type |
| GIL | Lean runtime | No equivalent (Lean has no GIL) |
Key Differences from PyO3
- No GIL: Lean4 doesn't have a Global Interpreter Lock, simplifying thread safety
- Different Memory Model: Lean uses reference counting without generational GC
- Theorem Proving Focus: Leo3 will support proof objects and tactics
- Dependent Types: Future support for Lean's dependent type system
Roadmap
Completed ✅
-
#[leanfn]macro implementation - String parameter passing (String, &str ↔ LeanString)
- Unsigned integer conversions (u8, u16, u32, u64, usize ↔ UInt8, UInt16, UInt32, UInt64, USize)
- Array parameter passing (Vec ↔ LeanArray)
- Signed integer conversions (i8, i16, i32, i64, isize ↔ Int8, Int16, Int32, Int64, ISize)
- Floating-point conversions (f32, f64 ↔ LeanFloat)
- Option type conversions (Option ↔ LeanOption)
- Result type conversions (Result<T, E> ↔ LeanExcept)
In Progress 🚧
- Complete FFI bindings (more Lean API functions)
- Error handling improvements
Planned 📋
- IO monad support
-
#[leanclass]for Rust structs as Lean classes -
#[leanmodule]for module creation - Proof object support
- Tactic integration
- Environment and context management
- Async support
- Documentation generation
- Integration tests with actual Lean4
- CI/CD pipeline
- Example projects
Development
Building
# Build all crates
# Build specific crate
# Run tests
Testing
Currently, most tests are unit tests. Integration tests requiring a Lean4 installation will be added.
Contributing
Contributions are welcome! Areas that need work:
- Completing FFI bindings
- Implementing macro code generation
- Adding more type wrappers
- Documentation
- Examples
- Tests
Acknowledgments
License
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.