Projects
A description of my ongoing and past projects can be found below
Mixed-Precision Floating Point in Lean 4
ML training increasingly relies on narrow floating point formats (fp8, bf16) for performance, but their rounding and overflow behavior is subtle and poorly specified. Having these semantics mechanized in a proof assistant means we can eventually prove error bounds — e.g., that a mixed-precision matmul accumulation in fp8 --> fp32 stays within a known distance of the full-precision result. I contributed the complete mixed-precision floating point subsystem to TensorLib, Lean's library for verified numerical computing. My work adds IEEE 754 floating point formats across five PRs (~3,600 LOC), building up from the encoding layer through type promotion to mixed precision reasoning including:
-
Bit-exact encoders/decoders for float16, bfloat16, fp8_e4m3, fp8_e5m2, and
fp8_e3m4 — handling subnormal numbers, ±infinity, NaN propagation, and round-to-nearest-even
tie-breaking. Each encoder is verified against Google's
ml_dtypesreference implementation via compile-time#guardchecks (~200 across the codebase). -
A 16-dtype type promotion lattice — the
joinfunction that determines the result type when two different dtypes interact (e.g., what happens when you add an fp8 tensor to a float32 tensor). This includes lossless cast analysis, commutativity guarantees, and deliberate divergences from NumPy where NumPy gets it wrong (e.g.,join(e4m3, e3m4)returnsnonerather than silently overflowing). - Overflow saturation semantics for cross-dtype casts — inf/NaN handling, per-dtype integer saturation bounds, and unsigned wrapping behavior matching NumPy's casting rules.
-
Property-based testing using Lean 4's
Plausibleframework: round-trip correctness (encode → decode → encode), arithmetic commutativity for each fp format, join commutativity across all dtype pairs, and cast-round-trip verification. - Mixed-precision tensor operations — matmul, dot product, and element-wise arithmetic that correctly promote operands through the cast graph before computation.
- Error bounds- Mechanized a generic framework for worst-case error bounds in rounding operations, addition, and in multiplication.
Pint: A small trusted kernel with dependent intersections, unions, and index erasure
A compact, syntax-directed calculus equipped with a bidirectional type checker supporting dependent intersection and union types, subtyping, and explicit coercions. The system incorporates index and coercion erasure to ensure that program equivalence is preserved at runtime, while maintaining soundness and compatibility with an implicit, bidirectional checking discipline. Finally, we generalize the framework to a quantitative resource setting, following McBride’s graded type theory, allowing Pint’s irrelevance and erasure mechanisms to be expressed via graded quantities. This subsumes ad-hoc erasure techniques and enables principled, resource-aware typing within the calculus
Pint on the Rocqs
Aims to mechanize the complete Pint calculus in Rocq, including dependent intersection and union types, subtyping, and coercions. The project formalizes Pint within a small, verifiable kernel, quantifying proof size, isolating axioms, and ensuring that the trusted computing base remains minimal. In addition, we develop a domain-specific language (DSL) for embedding imperative and object-oriented programs into the mechanization, enabling practical program verification within the formalized system.
Composition of Sigma Protocols
TBD
Interactive Zero Knowledge Proofs for Quadratic Residues in EasyCrypt
Zero knowledge proofs (ZKP) have gained popularity recently due to their ability to protect data while also being efficient. Interractive ZKP's allow a prover to convince a verifier about the validy of some statement without revealing any meaningful information beyond the truth of the statement itself. In this project, we studied a Sigma-protocol for quadratic residues and formalized its security properties in the EasyCrypt proof assistant. We provided machine-checked proofs of completeness, soundness, and honest-verifier zero-knowledge within a game-based framework. A more detailed report can be found here
Row Level Security in Databases
This project implements Row-Level Security (RLS) for a SQLite database using Haskell and the LIO (Labeled IO) library for information-flow control. We model database tables as Haskell data types and associate each row with dynamically constructed DCLabels encoding secrecy and integrity policies. Security is implemented in a secure database layer that extends basic database operations with label-based checks, ensuring that data flows only when permitted by the canFlowTo relation. The system supports secure insertion, querying, and deletion of customer records, with multiple versions exploring role-based access control through labels representing administrators and regular users. Serialization and deserialization of labels enable persistent storage in SQLite, and prepared statements are used to safely interface between Haskell and SQL. This work demonstrates how fine-grained information-flow control using Haskell LIO can be used to enforce security policies in databases. Slides can be found 🎞 here