Salt Systems Language: Z3 Theorem Proving in the Compiler
Salt Systems Language: Z3 Theorem Proving in the Compiler
Salt is a systems programming language designed to achieve performance parity with clang -O3 while providing mathematically verified safety through the integration of the Z3 SMT solver directly into the compiler. By moving formal verification from a separate toolchain into the core compilation process, Salt allows developers to define safety contracts that are proven at build time, eliminating the need for runtime checks when a proof is successful.
Integrated Formal Verification via Z3
Salt embeds the Z3 SMT solver from Microsoft Research to verify function preconditions (requires) and postconditions (ensures). This approach allows the compiler to prove whether a specific condition holds at every call site and return site.
- Zero-Cost Safety: When Z3 successfully proves a contract, the corresponding runtime check is elided entirely, resulting in zero instructions emitted.
- Counterexample Reporting: If Z3 finds a violation, the compiler reports concrete counterexample values to the developer.
- Fallback Mechanism: If the solver times out (with a 100ms limit per obligation), the compiler emits a safe runtime check as a fallback.
Memory Management and Performance
Salt eschews both garbage collection and a borrow checker in favor of an arena-based memory model. All allocations occur within a region, and the entire region is freed at once. The compiler verifies that no reference outlives its associated arena, preventing use-after-free and leak errors without the complexity of lifetime annotations.
Compiler Infrastructure
Salt utilizes MLIR (Multi-Level Intermediate Representation) for its code generation. The use of the affine dialect enables automatic loop tiling, allowing compute-heavy kernels—such as matrix multiplication—to run at parity with hand-tuned C code.
Performance Benchmarks
According to the project's benchmarks on Apple M4 hardware, Salt shows the following results compared to C (clang -O3):
- Compute-bound tasks: Matrix multiplication and Fibonacci sequences run at 0.9-1.0x the speed of C.
- Allocation-heavy workloads: Hashmaps and buffered writers see 2-10x performance gains due to the efficiency of arena allocation.
- Networking: Salt's echo server throughput matches that of C when using kqueue event loops.
Real-World Implementations
The language has been used to build several high-performance systems, all written in Salt:
- KeuOS: A microkernel featuring a 16-core SMP with Chase-Lev work-stealing, a preemptive scheduler, and a zero-trap socket API. It reports a context switch time of 487 cycles and an IPC ping-pong of 297 cycles.
- Basalt: A Llama 2 inference engine in approximately 600 lines of code, where every compute kernel carries a Z3 proof that array accesses are in bounds.
- Lettuce: A Redis-compatible in-memory data store that outperforms Redis in concurrency tests (1-100 clients) using zero-copy RESP parsing.
- FACET: A 2D rendering engine where every pixel write is Z3-verified to be within the framebuffer, achieving 457 fps.
Language Ergonomics and Tooling
Salt introduces several syntactic features to reduce boilerplate and improve readability:
- Pipe Operator: The
|>operator allows data to flow left-to-right, and|?>handles error propagation, replacing deeply nested function calls or verbose error handling. - F-Strings: Type-safe string formatting that avoids heap allocation and is checked at compile time.
- $ ext{sp}$ Package Manager: A Cargo-inspired manager that supports content-addressed caching and cross-package verification, ensuring that a library's Z3 contracts are verified against all downstream call sites.
Community Perspectives and Limitations
While the technical demonstrations are impressive, community feedback and the author's disclosures highlight several current limitations:
- Production Readiness: The author notes the project is currently "research-quality" and developed by a single individual. The standard library is incomplete, and Z3's support for strings and quantifiers is partial.
- Documentation: Some users have noted that the language specification lacks coherence and the project lacks a broad community of beta testers.
- Comparison to Existing Tools: Discussions have highlighted similar approaches in SPARK (a subset of Ada used in aerospace) and Verus (which augments Rust with Z3).
"The goal was to find out whether formal verification could be a compiler feature rather than a separate toolchain. The benchmarks say the compiler is fast enough... The kernel contracts catch real bugs."
— bneb-dev, Project Author