Foundational Constraint Solving for Expressive Refinement Typing
Jam Kabeer Ali Khan, Petros Markopoulos, Nico Lehmann, Ranjit Jhala
cs.PL
Jul 14, 2026 · v1
cs.LO cs.SE
TL;DR
FLEX implements a foundational Constrained Horn Clause solver in Lean, encoding CHCs as propositions and discharging them via certifying tactics with kernel-checked proofs.
Abstract
SMT-based program verifiers are hamstrung by two problems: expressiveness, because predictable verification restricts to the boundaries of SMT decidability, and trust, because the solver is a large, unverified artifact whose soundness bugs may quietly compromise every tool built on it. We present FLEX, a foundational Constrained Horn Clause (CHC) solver implemented in LEAN, that reduces the trusted base to the kernel alone, and allows using LEAN's entire proof ecosystem to verify low-level systems code, via three contributions. First, FLEX encodes CHCs as plain LEAN propositions where the Horn variables are existentially bound predicates, and shows how to implement CHC solvers as tactics (meta-programs) that compute kernel checkable proofs of the CHC propositions. Second, we show how to implement two verified CHC generators in LEAN: a Floyd-Hoare style generator for an imperative language, and a refinement-type-based generator for a functional calculus, which can be composed with the solving tactics to yield the first end-to-end foundational CHC-based verifiers. Finally, we show how FLEX allows us to leapfrog the expressiveness limitations of SMT by unleashing LEAN's entire ecosystem of proof machinery to prove arbitrary functional correctness properties of various low-level Rust libraries using the FLUX refinement type checker, and demonstrate the viability of FLEX as a trustworthy CHC backend, by showing it automatically discharges 95.7% of the CHCs from FLUX's benchmark suite.
Problem
SMT-based program verifiers are limited by expressiveness (restricted to decidable theories) and trust (the solver is a large, unverified artifact whose soundness bugs compromise dependent tools).
Approach
FLEX encodes Constrained Horn Clauses as plain Lean propositions with existentially bound predicate variables, and implements CHC solvers as Lean tactics (zap and fix) that produce kernel-checkable proof terms. Two verified CHC generators are built in Lean: a Floyd-Hoare generator for an imperative language Imp, and a refinement-type generator for a functional calculus, composed with the solving tactics for end-to-end foundational verifiers. FLEX serves as a backend for the FLUX refinement type checker over Rust, tapping Lean automation like omega, grind, and bv_decide.
Results
FLEX (about 2700 lines of Lean, plus 1800 lines of Rust extending FLUX) automatically discharges 95.7% of the CHCs from FLUX's benchmark suite, and verifies functional correctness and memory safety of Rust libraries (sorting, ring buffer, hash table) beyond SMT-decidable specifications.
| Case study | Flux LoC | #CHCs | Spec LoC | Proof LoC |
|---|
| Sorting | 316 | 15 | 96 | 620 |
| RingBuffer | 257 | 10 | 75 | 501 |
| TickTock | 15 | 5 | — | 302 |
| HashTable | 562 | 22 | 245 | 1361 |
| All | 1250 | 52 | 416 | 2784 |
Case studies: verified Rust LoC, number of CHCs, spec LoC, proof LoC