Every step keeps the ownership graph acyclic, so some thread can always step.
A reusable Rocq library
Also used for multiparty session types (ICFP'22).
A guarantee that holds for every program, with no per-program proof effort. Example: data-race freedom in Rust.
You get the guarantee without knowing how it works.
Properties of the whole follow from properties of the parts.
The checker and its output are fast.
Deadlock freedom and verified concurrencysession types, locks, separation logic
Probabilistic programmingparadoxes, exact inference
Network verification and automataBoa, KATch, StacKAT, SERenum List { Nil, Cons(u32, Arc<Mutex<List>>) }
let x = Arc::new(Mutex::new(List::Nil));
*x.lock() = List::Cons(1, x.clone());
drop(x); // refcount is 1: never freed
Leak: the list points to itself.
fn swap(x: &Mutex<u32>, y: &Mutex<u32>) {
let mut gx = x.lock();
let mut gy = y.lock();
let tmp = *gx; *gx = *gy; *gy = tmp;
}
spawn(|| swap(x, y));
spawn(|| swap(y, x));
Deadlock: each thread holds one lock and waits for the other.
Both programs type-check.
Goal: type systems in which every well-typed program is free of deadlocks and leaks, with machine-checked proofs.
let c = fork(λc′.
let (c′, n) = receive(c′) in
let c′ = send(c′, n mod 2 == 0) in
close(c′))
let c = send(c, 3) in
let (c, b) = receive(c) in
close(c)
Type-checked ⇒ no deadlocks and no leaks.
What was missing: a machine-checked proof.
Every step keeps the ownership graph acyclic, so some thread can always step.
A reusable Rocq library
Also used for multiparty session types (ICFP'22).


Lock references are linear. The type specifies who must release the lock and who must free it.
No deadlocks, no leaks.

let (c1, c2) = new_chan () in
fork { let x = c2.recv() in
c2.send(x + 2) };
c1.send(40);
let y = c1.recv() in
assert(y = 42)
{ c ↣ !(x:τ)⟨v⟩{P}. p ∗ P[t/x] }
send c (v[t/x])
{ c ↣ p[t/x] }
Proved ⇒ the asserts hold
MiniActris: Actris rebuilt from one-shot channels, in under 1,000 lines of Rocq


c1, d1 := new_chan()
c2, d2 := new_chan()
fork { c1.recv(); d2.send(2) }
c2.recv(); d1.send(3)
Actris: verified, although it deadlocks.
LinearActris: verified programs are deadlock free and leak free.


With AI you can do this 10–100× faster now.
Question: Is the research now (or soon) easier and faster to do?
h = rand(Normal(1.7, 0.5)) if rand(Bernoulli(0.5)) observe(Normal(h, 0.1), 2.0) end
1.81 m
h = rand(Normal(170, 50)) if rand(Bernoulli(0.5)) observe(Normal(h, 10), 200) end
170.2 cm
Answer depends on units!
Fix: make the limit explicit with intervals.
Both programs give 1.70 m and 170 cm.
let x = gaussian(0, 1) in
…
if x < 0.8 then x < 0.1
else x < 2.0
let x = discrete(0.5398, 0.2483,
0.1891, 0.0228) in
…
if x < 2 then x < 1
else x < 3
Exact answer: P(true) = 0.7289



Maybe not? Scientists usually run their model on only one input. So we can specify the model in Lean and have AI figure out its value.
Maybe yes. We still want a good specification language.
Question: Is there a better approach by the time you finish it?
| State | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|
| classes | A | A | A | A | A |
| signatures | F,A,A | F,A,A | F,A,A | T,A,A | T,A,A |
| classes | A | A | A | B | B |
| signatures | F,A,A | F,B,A | F,B,A | T,B,B | T,B,B |
| classes | C | A | A | B | B |
Generic, but still fast

Still nice that one implementation works, and is fast, in general. But a lot of its value is subsumed now.
Question: Will the research still save human effort, or just tokens?
NetKAT: a network is a program, and questions about it are equivalences.
KATch: decision diagrams instead of packets. Orders of magnitude faster, and used in Google's NetKAT.







StacKAT adds a stack to NetKAT, for variable-length packet data.
push(v) · pop(v) ≡ 1 push(v) · pop(w) ≡ 0 (v ≠ w) push(a)* · pop(a)* ≡ push(a)* + pop(a)*
Equivalence is still decidable.




Does every concurrent run of a network system give the same result as some run that handles the requests one at a time?
Decidable, even with unboundedly many requests.



Question: Does the work complement or compete?
| Task | Correct |
|---|---|
| 2-digit addition | ≈ 100% |
| 4-digit addition | ≈ 25% |
| 5-digit addition | ≈ 9% |
| Writing a correct function | ≈ 0% |
Me: how far is this going to go?
Robbert: skeptical.
Me: I'm getting a little worried!
Feedback: you are crazy, GPT-4 can't even multiply 3-digit numbers.
They were right!
“Humans are incredibly stupid. Humans are even stupider than that at math.”
“Once civilization gets going, they fly to the moon in the blink of an eye.”
A whale brain is 6× larger.
Transistors switch a million times faster than neurons.
Nerve signals travel at about 100 m/s. Signals in a wire travel at about 200,000,000 m/s.
The laws of physics allow a lot more.
Selection pressure for mathematical ability has been very low.
We can do mathematics only because abilities such as pattern recognition also help us survive.
If mathematics had been useful for survival, we would be much better at it, with the same brains.
In chess, the gap between a grandmaster and a computer is enormous.
Mathematics is also a game with well-defined rules. Rocq and Lean show that it is a search problem.
In principle, brute force search proves every provable theorem. It just takes a long time.
GPT-4 is better than humans at natural language, just by predicting the next word.
It can't do mathematics yet: it was not trained for it the way AlphaZero was trained for chess.
LLMs don't need to be very smart: just a good enough heuristic to cut the branching factor of proof search.
Bear with me: let's pretend arguments work.
Yes, because answers can be checked. That is what makes reinforcement learning work.
Yes, at the level of ideas. The reasoning is in natural language; Lean checks afterwards.
Data, but no checker: writing. There is lots of text, but we can't check for good writing.
A checker, but no data: RL on math problems without pretraining doesn't work.






RollerCoaster Tycoon (1999): written in assembly by one person.
Reality check: I don't know what to work on.
But it is probably better to think about it.
Thank you.