Mathematically: trivially the same.
In Lean: requires explicit coercions everywhere.
What it felt like
The struggle was real. A one-page math proof took weeks because:
Every "obvious" step needs to be spelled out
The type system finds corners of the argument you didn't think about
You can't hand-wave
An actual line in the paper:
..., which can be easily extended to all other 's, ...
This converts to 30 lines of code and 16 branches of sub-goals.
Part 3.5: Proving Program Correctness
Imagine We Implement an Addition Function
# pythondefadd(a, b):
return a + b
We protect it with some tests
# pythondefadd(a, b):
return a + b
assert add(1, 2) == 3# ✓assert add(5, 10) == 15# ✓
Surprise!
# pythondefadd(a, b):
return a + b
add("hello", " world") # "hello world"
add("1", "2") # "12" not 3
# add type checking to fix the issuedefadd(a: int, b: int):
return a + b
add("1", "2") # error: Argument 1 to "add" has incompatible type "str"; expected "int"
TypeScript (2012) — Microsoft essentially admitted JavaScript at scale was untenable
Python type hints (PEP 484, 2014) — the duck typing world started bolting types on
Rust (2015) — types as a memory safety guarantee
Same function in Lean
-- leandefadd(a b : Nat):= a + b
#eval add 12-- 3#eval add 510-- 15
Type check is strictly enforced by default
-- leandefadd(a b : Nat):= a + b
#eval add "hello""world"-- Application type mismatch: The argument-- "hello"-- has type-- String-- but is expected to have type-- Nat-- in the application-- add "hello"Lean 4
Proving correctness
-- leandefadd(a b : Nat):= a + b
theoremadd_correct(a b : Nat): add a b = a + b := byunfold add -- unfold the definition of addrfl-- left-hand side equals to right-hand side
This means the function is correct for all natural numbers! How many test cases could cover that?
Goal: Machine-checked soundness and completeness for all field elements and adversarial witnesses
Example: IsZero circuit
if input = 0 then 1 else 0
-- Circom original:-- inv <-- in != 0 ? 1/in : 0;-- out <== -in * inv + 1;-- in * out === 0;defmain(input : Expression (F p)) :=dolet inv ← witness fun env =>
if x ≠ 0then x⁻¹ else0letout <== -input * inv + 1
input * out === 0
return out
In Clean, You have to write proof for your circuit
defcircuit: FormalCircuit (F p) field field where
main
Spec input output :=
output = (if input = 0then1else0)
soundness := ...
completeness := ...
soundness := by
circuit_proof_start
simp only [id_eq, h_holds]
split_ifs with h_ifs
. simp only [h_ifs, zero_mul, neg_zero, zero_add]
. rw [neg_add_eq_zero]
have h1 := h_holds.lefthave h2 := h_holds.rightrw [h1] at h2
simp only [id_eq, mul_eq_zero] at h2
cases h2
case neg.inl hl => contradiction
case neg.inr hr =>
rw [neg_add_eq_zero] at hr
exact hr
completeness := by
circuit_proof_start
cases h_env with | introleftright =>
simp only [left, id_eq, ite_not, mul_ite, mul_zero] atrightsimp only [id_eq, right, left, ite_not, mul_ite, mul_zero, mul_eq_zero, true_and]
split_ifs <;> aesop
Field wrap-around bugs caught at compile time
ByteDecomposition requires this as a type-level assumption:
p_large_enough : Fact (p > 2^16 + 2^8)
Without it, the proof won't compile. You cannot deploy with a too-small prime by accident.
This is the class of bug that looks correct for small test values but wraps silently near p.
Formal verification, aided by AI, should be viewed not as totally new paradigm, but as a powerful accelerant of a trend and a paradigm that was already marching forward.
What is Taiwan doing in 1950? We are living in this world today now.
Promise: Understand math + CS
- Formal Verifications have been here since forever
- Think about next year.
- Anyone runs 20 agents for coding here?
Mario style stages
This server is hosted at Heinrich Heine University Düsseldorf.
Type checking on steroid
We'll unpack what does it mean to verify a program
We're going to see some cool projects here. They all demonstrate ideas on how we do things differently
This library is where if you want to check if Lean is practical or not for software development
A **zip bomb**, also known as a decompression bomb or "zip of death," is a malicious archive file designed to overwhelm a system's resources when decompressed, potentially causing crashes or system failures.
This hints where future security hotspot might be.
Vitalik has a point on being cautious to the words: "proven" and "correct". Treat them as marketing words.
Inputs and outputs are finite field elements. Integer mod p
Add formal verification in your toolbox that helps you check your intents.
Closing: Before Asimov, robot writers portrayed them like Frankenstein.
But Asimov pictured robots following rules. When humans invent tools, we add protections to prevent us from getting hurt.
Math proving is kind of that proof you need to craft software at scale with agents.