Formally Proving a Compiler Transformation Safe
Joachim Breitner
Haskell Symposium 2015
3 August 2015, Vancouver
PROGRAMMING PARADIGMS GROUP
1
Joachim
- Formally Proving
KIT –2015-09-03
University of the
State ofBreitner
Baden-Wuerttemberg
and a Compiler Transformation Safe
National Research Center of the Helmholtz Association
PROGRAMMING PARADIGMS GROUP
www.kit.edu
Short summary
I formally proved that
Call Arity is safe.
2
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
Short summary
I formally proved that
Call Arity is safe.
W
H
A
B
2
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
Short summary
I formally proved that
Call Arity is safe.
“What exactly have you shown?”
H
A
B
2
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
Short summary
I formally proved that
Call Arity is safe.
“What exactly have you shown?”
“H ow did you prove that?”
A
B
2
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
Short summary
I formally proved that
Call Arity is safe.
“What exactly have you shown?”
“H ow did you prove that?”
“A re you sure about this?”
B
2
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
Short summary
I formally proved that
Call Arity is safe.
“What exactly have you shown?”
“H ow did you prove that?”
“A re you sure about this?”
“B ut, . . . !”
2
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
What exactly is. . . Call Arity?
Call Arity is an arity analysis:
let fac 10 = id
fac x = ńy. fac (x+1) (y∗x)
in fac 0 1
3
2015-09-03
=⇒
Joachim Breitner - Formally Proving a Compiler Transformation Safe
let fac 10 y = y
fac x y = fac (x+1) (y∗x)
in fac 0 1
PROGRAMMING PARADIGMS GROUP
What exactly is. . . Call Arity?
Call Arity is an arity analysis:
let fac 10 = id
fac x = ńy. fac (x+1) (y∗x)
in fac 0 1
=⇒
let fac 10 y = y
fac x y = fac (x+1) (y∗x)
in fac 0 1
So far: Naive forward arity analysis, see Gill’s PhD thesis from 96
3
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
What exactly is. . . the problem?
Eta-expanding a thunk is tricky:
let thunk = f x
in . . .
4
2015-09-03
=⇒
Joachim Breitner - Formally Proving a Compiler Transformation Safe
let thunk y = f x y
in . . .
PROGRAMMING PARADIGMS GROUP
What exactly is. . . the problem?
Eta-expanding a thunk is tricky:
let thunk = f x
in . . .
=⇒
let thunk y = f x y
in . . .
Sharing can be lost!
4
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
What exactly is. . . the problem?
Eta-expanding a thunk is tricky:
let thunk = f x
in . . .
=⇒
let thunk y = f x y
in . . .
Sharing can be lost!
(unless “thunk” is used at most once in “. . . ”)
4
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
What exactly is. . . co-call cardinality analysis?
x
G0 (if p then x else y) = p
y
x
G0 (f x y) = f
y
5
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
What exactly is. . . Call Arity?
Call Arity
=
Arity analysis with co-call cardinality analysis
6
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
What exactly is. . . Call Arity?
Call Arity
=
Arity analysis with co-call cardinality analysis
Now foldl can be a good consumer in list-fusion!
6
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
What exactly is. . . “safe”?
Safety:
7
2015-09-03
It is safe for the compiler to apply the
transformation, i.e. the performance
will not degrade.
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
What exactly is. . . “safe”?
Safety:
It is safe for the compiler to apply the
transformation, i.e. the performance
will not degrade.
Yes, it is synonymous to “improvement”.
7
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
What exactly is. . . could possibly go wrong?
A bug in Call Arity
⇓
8
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
What exactly is. . . could possibly go wrong?
A bug in Call Arity
⇓
Too much eta-expansion
⇓
8
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
What exactly is. . . could possibly go wrong?
A bug in Call Arity
⇓
Too much eta-expansion
⇓
Loss of sharing
⇓
8
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
What exactly is. . . could possibly go wrong?
A bug in Call Arity
⇓
Too much eta-expansion
⇓
Loss of sharing
⇓
Work is duplicated
⇓
8
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
What exactly is. . . could possibly go wrong?
A bug in Call Arity
⇓
Too much eta-expansion
⇓
Loss of sharing
⇓
Work is duplicated
⇓
Allocation is increasing
8
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
What exactly is. . . could possibly go wrong?
A bug in Call Arity
⇓
Too much eta-expansion
⇓
Loss of sharing
⇓
Work is duplicated
⇓
Allocation is increasing
8
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
Theorem: Call Arity does not
increase the number
of allocations
PROGRAMMING PARADIGMS GROUP
What exactly is. . . could possibly go wrong?
A bug in Call Arity
No (such) bug
⇓
Too much eta-expansion
⇓
⇑
Loss of sharing
⇓
Work is duplicated
⇓
Allocation is increasing
8
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
Theorem: Call Arity does not
increase the number
of allocations
PROGRAMMING PARADIGMS GROUP
How did you prove that?
1st ingredient
Sufficiently detailed semantics:
Launchbury’s natural semantics for lazy evaluation.
Γ :e ⇓ ∆ :v
heap before
current expression
9
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
final value
heap afterwards
PROGRAMMING PARADIGMS GROUP
How did you prove that?
1st ingredient
Sufficiently detailed semantics:
Sestoft’s mark-1 virtual machine
( Γ , e , S ) ⇒ ( Γ0 , e0 , S 0 )
current heap
next stack
current expression
next expression
current stack next heap
9
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
How did you prove that?
2nd ingredient
Abstract view on what calls what:
Trace trees!
10
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
How did you prove that?
2nd ingredient
Abstract view on what calls what:
Trace trees!
T0 (if p then x else y) =
T0 (f x y) =
10
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
p
x
y
f
x
y
x
y
x
y
PROGRAMMING PARADIGMS GROUP
How did you prove that?
2nd ingredient
Abstract view on what calls what:
Trace trees!
T0 (if p then x else y) =
T0 (f x y) =
p
x
y
f
x
y
x
y
x
y
Co-call graphs approximates trace trees
It even is a Galois immersion.
10
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
How did you prove that?
3nd ingredient
A way to handle a large proof:
Refinement proofs
11
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
How did you prove that?
3nd ingredient
A way to handle a large proof:
Refinement proofs
Arity
Arity
Arity
analysis
analysis
analysis
impl.
approx.
impl.
+
+
+
←−−
←−−−−
←−− Call Arity
any
a
a co-call
cardinality
trace tree
graph
analysis
analysis
analysis
11
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
Are you sure?
Syntax (using Nominal logic)
Semantics (Launchbury, Sestoft, denotational)
Data types (Co-call graphs, trace trees)
... and of course the proofs
12
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
le
el
Is
ab =
λ
β
HO
L
∀
α
→
PROGRAMMING PARADIGMS GROUP
But. . .
The formalization gap!
13
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
But. . .
The formalization gap!
13
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
But. . .
The formalization gap!
13
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
But. . .
The formalization gap!
13
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
Bug #10176
let foo x = error ". . . "
in . . . case foo a b of . . .
⇓ Strictness analyzer
let foo x = error ". . . " -- Strictness: <L,U>b
in . . . case foo a b of . . .
⇓ Call Arity
let foo x y = error ". . . " y
in . . . case foo a b of . . .
-- Strictness: <L,U>b
⇓ Simplifier
let foo x y = error ". . . " y
in . . . case foo a of {}
14
2015-09-03
-- Strictness: <L,U>b
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
Conclusion
Yes, we can. . .
formally prove a compiler transformation to be safe.
15
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
Conclusion
Yes, we can. . .
formally prove a compiler transformation to be safe.
Increased the quality
Uncovered a bug missed by
tests.
Refactorable
when the code changes
Provides high assurance
15
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
Conclusion
Yes, we can. . .
formally prove a compiler transformation to be safe.
Increased the quality
Uncovered a bug missed by
tests.
Refactorable
when the code changes
Provides high assurance
15
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
Very tedious
Still only worth it in certain
domains?
Formalization gap
Is GHC the wrong target?
PROGRAMMING PARADIGMS GROUP
Thank you for your attention.
c CC-BY-NC-SA iScr34m http://fav.me/d3lhdq2
Minecraft image c CC0 CSITDMS https://pixabay.com/de/insel- strand- sandstrand- philippinen- 218578/
Island image c CC-BY-SA Sulfur https://commons.wikimedia.org/wiki/File:Hoan_Bridge.jpg
Bridge image c CC-BY-NC Randall Munroe https://what- if.xkcd.com/61/
Car drawing 16
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
Backup slide: How tedious, really?
[HOLCF-Nominal2]
ConstOn
Nominal-Utils
Vars
AList-Utils
AList-Utils-Nominal
AList-Utils-HOLCF
9 man-months
12,000 loc
1,200 lemmas
79 theories
Arity-Nominal
SestoftConf
ArityAnalysisStack
ArityStack
Substitution
ArityAnalysisSig
ArityAnalysisAbinds
SestoftGC
TrivialArityAnal
ArityAnalysisFixProps
ArityConsistent
AEnv
CoCallGraph-Nominal
EtaExpansion
Sestoft
TransformTools
ArityEtaExpansion
ArityAnalysisFix
CardinalityAnalysisSpec
Terms
CoCallAnalysisSig
AbstractTransform
CoCallAnalysisSpec
CoCallGraph
Env-Nominal
CardArityTransformSafe
Denotational
Env-Set-Cpo
TTree-HOLCF
Value-Nominal
HasESem
CoCallGraph-TTree
TTreeAnalysisSig
AnalBinds
Cardinality-Domain-Lists
HeapSemantics
CoCallImplTTree
Abstract-Denotational-Props
ArityAnalysisCorrDenotational
List-Interleavings
TTree
EvalHeap
AbstractDenotational
CoCallAnalysisImpl
Value
Cardinality-Domain
CoCallAritySig
CoCallFix
Set-Cpo
Env
Iterative
CardinalityAnalysisSig
ArityEtaExpansionSafe
Pointwise
HOLCF-Utils
Env-HOLCF
EtaExpansionSafe
ArityTransform
CoCallImplSafe
Nominal-HOLCF
CoCallAnalysisBinds
ArityAnalysisSpec
NoCardinalityAnalysis
ArityTransformSafe
Arity
HOLCF-Join
HOLCF-Join-Classes
CoCallImplTTreeSafe
TTreeImplCardinality
TTreeAnalysisSpec
TTreeImplCardinalitySafe
CallArityEnd2End
CallArityEnd2EndSafe
17
2015-09-03
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
Backup slide: That bug that was found
Call Arity initially would
eta-expand thunks in a
recursive group, as long as
the recursion is linear.
18
2015-09-03
foo a =
let go | a == "m"
= ń x. if x == 0
then 1
else x ∗ go (x-1)
| a == "p"
= ń x. if x == 0
then 0
else x + go (x-1)
in go 100
Joachim Breitner - Formally Proving a Compiler Transformation Safe
PROGRAMMING PARADIGMS GROUP
© Copyright 2026 Paperzz