Title: Verifying Compilers with Heifer
1Verifying Compilers with Heifer
- Edwin Westbrook
- advisor Aaron Stump
2Software is Everywhere
- We want this software to work!
cell phones
cars
airplanes
3What if Software Fails?
Mars rover frozen for three days on Mars
Therac-25 five people killed from overdoses of
radiation
MIM-104 Patriot missile failed to shoot down
scuds in first Iraq war
4Why Verify Compilers?
- Compilers are just another program
- Can be incorrect
- Cause other programs to be incorrect
- Everyone assumes compiler is correct
- Need to go through lots of assembly to even
notice a problem - Most of us could/would not do this
5Why Verify Compilers?
- Compilers are getting more complicated
- Vast research area, hundreds of papers per year
- Changing hardware e.g. multiple cores
- More prone to compiler bugs!
6How to Verify Compilers?
Parser
Code Generation
Internal representation
Optimization
7How to Verify Compilers?
Parser
Code Generation
Internal representation
Not changed much
Optimization
8How to Verify Compilers?
Parser
Code Generation
Internal representation
Not changed much
Source of most bugs
Optimization
9How to Verify Compilers?
- Optimization and code generation have same form
code
transform
transformed code
10How to Verify Compilers?
- Optimization and code generation have same form
code
Need to verify these are equivalent code
transform
transformed code
11How to Verify Compilers?
code
transform-is-correct
proof that transform(code) is equivalent to code
12How to Verify Compilers?
code
- Ensures transform is correct on any input
transform-is-correct
proof that transform(code) is equivalent to code
13How to Verify Compilers?
code
- Ensures transform is correct on any input
- Need not run at runtime no overhead
transform-is-correct
proof that transform(code) is equivalent to code
14What is Heifer?
- Functional no mutable data
- Strongly typed everything has an explicit type
no casts - Work in progress
15Basics of Heifer
- Data is made of constructors
- Given by user declarations
- Example natural numbers
0 nat succ nat -gt nat
3 represented as succ (succ (succ 0))
16Basics of Heifer
- Data is made of constructors
- Given by user declarations
- Example lists of natural numbers
nil list cons nat -gt list -gt list
0, 1 represented as cons 0 (cons (succ 0) nil)
17Basics of Heifer
- Functions work by pattern matching
plus x 0 x
plus x (succ y) succ (plus x y)
append nil L L
append L1 (cons x L2) cons x (append L1 L2)
18Basics of Heifer
- Functions work by pattern matching
plus x 0 x
Base case
plus x (succ y) succ (plus x y)
append nil L L
append L1 (cons x L2) cons x (append L1 L2)
19Basics of Heifer
- Functions work by pattern matching
plus x 0 x
Base case
plus x (succ y) succ (plus x y)
Recursive case
append nil L L
append L1 (cons x L2) cons x (append L1 L2)
20Lets Write a C Compiler
- Internal representation of C
plus c-expr -gt c-expr -gt c-expr times c-expr
-gt c-expr -gt c-expr int-lit int -gt c-expr
21Lets Write a C Compiler
- Internal representation of C
plus c-expr -gt c-expr -gt c-expr times c-expr
-gt c-expr -gt c-expr int-lit int -gt c-expr
x y 2
Represented as
plus (times y (int-lit (succ (succ 0))))
22Argument Names are Special
- Names can change when they do not clash
int z // global variable int foo (int x, int y)
return x y z
23Argument Names are Special
- Names can change when they do not clash
int z // global variable int foo (int v, int w)
return v w z
Same program
24Argument Names are Special
- Names can change when they do not clash
int z // global variable int foo (int z, int w)
return z w z
Different program name clash with global
variable z
25Argument Names are Special
- Heifer has special argument binding syntax
int foo (int x, int y) return x y 2
Represented as
c-func foo int lx.ly.plus x (times y )
26Argument Names are Special
- Heifer has special argument binding syntax
int foo (int x, int y) return x y 2
l binds argument names
Represented as
c-func foo int lx.ly.plus x (times y )
27Argument Names are Special
- Heifer has special argument binding syntax
int foo (int x, int y) return x y 2
l binds argument names
Represented as
c-func foo int lx.ly.plus x (times y )
Equivalent representation in Heifer
c-func foo int lv.lw.plus v (times w )
28Verifying Compilers with Heifer
int foo (int x, int y) return x y
(factorial 2)
fold-constants
29Verifying Compilers with Heifer
int foo (int x, int y) return x y
(factorial 2)
Constant expression
fold-constants
30Verifying Compilers with Heifer
int foo (int x, int y) return x y
(factorial 2)
Constant expression
fold-constants
int foo (int x, int y) return x y 2
31Verifying Compilers with Heifer
- Verifying constant folding
int foo (int x, int y) return x y
(factorial 2)
fold-constants-is-correct
32Verifying Compilers with Heifer
- Verifying constant folding
int foo (int x, int y) return x y
(factorial 2)
fold-constants-is-correct
Proof that code with is 2 is equivalent to code
with (factorial 2)
33Representing Proofs
- Proofs ensure that something is true
- Can make proofs only of true properties
- Example proofs that n lt m
- Data with type less-than n m is proof that nltm
- Can make proof with type less-than 2 4
- Cannot make proof with type less-than 4 2
34Representing Proofs
- Can define less-than n m as follows
less-than-base n less-than n (succ n)
less-than-ind n m less-than n m
-gt less-than n (succ m)
35Representing Proofs
- Can define less-than n m as follows
less-than-base n less-than n (succ n)
less-than-ind n m less-than n m
-gt less-than n (succ m)
Builds proof of n lt n1
36Representing Proofs
- Can define less-than n m as follows
less-than-base n less-than n (succ n)
less-than-ind n m less-than n m
-gt less-than n (succ m)
Builds proof of n lt n1
Takes proof of n lt m and builds proof of n lt m1
37Representing Proofs
- Can define less-than n m as follows
less-than-base n less-than n (succ n)
less-than-ind n m less-than n m
-gt less-than n (succ m)
Builds proof of n lt n1
Takes proof of n lt m and builds proof of n lt m1
Cannot make proofs with type less-than 4 2
38Conclusion
- Heifer supports compiler writing
- Special support for argument names
- Heifer supports compiler verification
- Verification programs output proofs
39Acknowledgements
- Ben Delaware
- implementation
- Fritz Heckel, Charlie Comstock, Morgan Deters,
Rob LeGrand, Bob Zimmermann - Comments and feedback on talk