2. What's Twelf?
Twelf is a
dependently-typed
higher-order
logic programming language
and also a
proof assistant
useful for proofs about programming languages
4. What is a natural number?
N nat N is a natural number
• a judgment
• defined by inference rules
____________
z nat zero is a natural number
N nat if N is a natural number
____________
s(N) nat then N + 1 is a natural number
5. Inference rules
____________
z nat axiom
N nat premise(s)
____________
s(N) nat conclusion
capital N is implicitly for all
6. Examples
zero is a nat 2 is a nat
___________ z nat
z nat _____________
s(z) nat
_____________
s(s(z)) nat
derivations
8. Example?
s(s(xyzzy)) nat?
nope, there is no derivation
(can we prove it?)
9. What is addition?
___________
sum z N N 0+N=N
sum M N P if M + N = P
_____________
sum s(M) N s(P) then M + 1 + N = P + 1
10. Examples
sum 0 2 2 sum 0 3 3
__________ __________
sum 1 2 3 sum 1 3 4
__________ __________
sum 2 2 4 sum 2 3 5
__________
sum 3 3 6
__________
sum 4 3 7
11. Recap
o judgments are things for which we have proof
o judgments are defined by inference rules
o derivations are proofs of a judgment
o natural numbers and addition as judgments
next: proof search and logic programming
12. Searching for proof
__________
sum z N N
sum M N P
_____________
sum s(M) N s(P)
does sum 2 3 5 hold?
can we find a derivation?
13. Searching for proof
__________
sum z N N
sum M N P
_____________
sum s(M) N s(P)
does sum 2 3 5 hold?
can we find a derivation?
which rule(s) must the derivation end with?
14. Searching for proof
__________
sum z N N
sum M N P
_____________
sum s(M) N s(P)
does sum 2 3 5 hold?
can we find a derivation?
which rule(s) must the derivation end with?
sum 1 3 4
________
sum 2 3 5 ~ sum s(M) N s(P) [M = 1, N = 3, P = 4]
15. Searching for proof
__________
sum z N N
sum M N P
_____________
sum s(M) N s(P)
does sum 2 3 5 hold?
can we find a derivation?
which rule(s) must the derivation end with?
sum 0 3 3
________
sum 1 3 4 ~ sum s(M) N s(P) [M = 0, N = 3, P = 3]
________
sum 2 3 5 ~ sum s(M) N s(P) [M = 1, N = 3, P = 4]
16. Searching for proof
__________
sum z N N
sum M N P
_____________
sum s(M) N s(P)
does sum 2 3 5 hold?
can we find a derivation?
which rule(s) must the derivation end with?
________
sum 0 3 3 ~ sum z N N [N = 3]
________
sum 1 3 4 ~ sum s(M) N s(P) [M = 0, N = 3, P = 3]
________
sum 2 3 5 ~ sum s(M) N s(P) [M = 1, N = 3, P = 4]
17. Proof search with unification
__________
sum z N N
sum M N P
_____________
sum s(M) N s(P)
does sum 2 3 P hold for any P?
18. Proof search with unification
__________
sum z N N
sum M N P
_____________
sum s(M) N s(P)
does sum 2 3 P hold for any P?
sum 1 3 P'
_________
sum 2 3 P ~ sum s(M) N s(P') [M=1, N=3, P=s(P')]
need to invent fresh variable P'
19. Proof search with unification
__________
sum z N N
sum M N P
_____________
sum s(M) N s(P)
does sum 2 3 P hold for any P?
sum 0 3 P''
_________
sum 1 3 P' ~ sum s(M) N s(P'') [M=0, N=3, P'=s(P'')]
_________
sum 2 3 P ~ sum s(M) N s(P') [M=1, N=3, P=s(P')]
20. Proof search with unification
__________
sum z N N
sum M N P
_____________
sum s(M) N s(P)
does sum 2 3 P hold for any P?
_________
sum 0 3 P'' ~ sum z N N [N = 3 = P'']
_________
sum 1 3 P' ~ sum s(M) N s(P'') [M=0, N=3, P'=s(P'')]
_________
sum 2 3 P ~ sum s(M) N s(P') [M=1, N=3, P=s(P')]
21. Proof search with unification
__________
sum z N N
sum M N P
_____________
sum s(M) N s(P)
does sum 2 3 P hold for any P?
_________
sum 0 3 P'' ~ sum z N N [N = 3 = P'']
_________
sum 1 3 P' ~ sum s(M) N s(P'') [M=0, N=3, P'=s(P'')]
_________
sum 2 3 P ~ sum s(M) N s(P') [M=1, N=3, P=s(P')]
now substitute to find P = s(P') = s(s(P'')) = 5
22. Other modes
__________
sum z N N
sum M N P
_____________
sum s(M) N s(P)
sum 2 N 5?
23. Other modes
__________
sum z N N
sum M N P
_____________
sum s(M) N s(P)
sum 2 N 5?
_________
sum 0 N 3 ~ sum z N N [N = 3]
_________
sum 1 N 4 ~ sum s(M) N s(P) [M=0, P=3]
_________
sum 2 N 5 ~ sum s(M) N s(P) [M=1, P=4]
which args are inputs vs. outputs - mode
24. Branching, backtracking
__________
sum z N N
sum M N P
_____________
sum s(M) N s(P)
sum M N 2?
unifies with both rules
25. Branching, backtracking
__________
sum z N N
sum M N P
_____________
sum s(M) N s(P)
sum M N 2?
unifies with both rules
[M=2, N=0]
_________
[M=1, N=1] sum M'' N 0 ~ sum z N N
_________ ________
sum M' N 1 ~ sum z N N | sum M' N 1 ~ sum s(M'') N s(P)
[M=0, N=2]
________ ________
sum M N 2 ~ sum z N N | sum M N 2 ~ sum s(M') N s(P)
26. Recap
o interpret judgments as logic programs
o proof search gives rise to computation
o unification of terms containing variables
o viewing a judgment in different modes
o branching, backtracking
o sum as a logic program
next: representing judgments in Twelf
27. Representing syntax
____________
z nat
N nat
____________
s(N) nat
in OCaml:
type nat = Z | S of nat
in Twelf:
nat : type.
z : nat.
s : nat -> nat.
28. Representing derivations __________
sum z N N
sum M N P
_____________
sum s(M) N s(P)
in OCaml:
type sum =
Sum_z of nat
| Sum_s of nat * nat * nat * sum
29. Representing derivations __________
sum z N N
sum M N P
_____________
sum s(M) N s(P)
in OCaml:
type sum =
Sum_z of nat
| Sum_s of nat * nat * nat * sum
but what derivation does
Sum_s(1, 2, 3, Sum_z 4)
represent? type sum is not adequate
30. Dependent types __________
sum z N N
sum M N P
_____________
sum s(M) N s(P)
in Twelf:
sum : nat -> nat -> nat -> type.
sum_z : {N:nat} sum z N N.
sum_s : {M:nat} {N:nat} {P:nat}
sum M N P -> sum (s M) N (s P).
31. Dependent types __________
sum z N N
sum M N P
_____________
sum s(M) N s(P)
in Twelf:
sum : nat -> nat -> nat -> type.
sum_z : {N:nat} sum z N N.
sum_s : {M:nat} {N:nat} {P:nat}
sum M N P -> sum (s M) N (s P).
• type sum M N P is indexed by M N P
• dependent type (depends on terms)
• indices let us express invariant
• no inadequate terms
32. Dependent types __________
sum z N N
sum M N P
_____________
sum s(M) N s(P)
in Twelf:
sum : nat -> nat -> nat -> type.
sum_z : {N:nat} sum z N N.
sum_s : {M:nat} {N:nat} {P:nat}
sum M N P -> sum (s M) N (s P).
or (with implicit arguments):
sum_z : sum z N N.
sum_s : sum M N P -> sum (s M) N (s P).
33. Twelf types as logic programs
in Twelf:
sum : nat -> nat -> nat -> type.
sum_z : sum z N N.
sum_s : sum s(M) N s(P)
<- sum M N P.
in OCaml:
let rec sum : (nat * nat) -> nat = function
| Z, n -> n
| S m, n -> S (sum (m, n))
34. Recap
o represent syntax by datatypes
o represent derivations by datatypes
o want adequate representation
o OCaml type system is not rich enough
o need dependent types
o interpret Twelf datatypes as logic programs
next: logic programs as proofs
36. A theorem about addition
addition is commutative
M+N=N+M
but we have not said:
o sum is a function
if sum M N P and sum M N P' then P = P'
o sum is total
for all M, N there exists P where sum M N P
o we haven't even defined equality
38. A theorem about addition
addition is commutative
M+N=N+M
if sum M N P then sum N M P
39. A theorem about addition
addition is commutative
M+N=N+M
if sum M N P then sum N M P
if you give me a derivation of sum M N P
I will give you a derivation of sum N M P
40. A theorem about addition
addition is commutative
M+N=N+M
if sum M N P then sum N M P
if you give me a derivation of sum M N P
I will give you a derivation of sum N M P
function of type sum M N P -> sum N M P
Curry-Howard correspondence
41. Addition is commutative
proof outline:
• prove "right-handed" versions of sum rules
for all N, sum N z N
if sum M N P then sum M (s N) (s P)
• recurse down derivation of sum M N P
• build it back up using right-handed rules
42. sum : nat -> nat -> nat -> type.
Addition is commutative sum_z : sum z N N.
sum_s : sum M N P ->
sum (s M) N (s P).
sum_z' : {N} sum N z N -> type.
- : sum_z' z sum_z.
- : sum_z' (s N') (sum_s D)
<- sum_z' N' D.
sum_s' : sum M N P -> sum M (s N) (s P) -> type.
- : sum_s' sum_z sum_z.
- : sum_s' (sum_s D1) (sum_s D2)
<- sum_s' D1 D2.
43. sum : nat -> nat -> nat -> type.
Addition is commutative sum_z : sum z N N.
sum_s : sum M N P ->
sum (s M) N (s P).
sum_z' : {N} sum N z N -> type.
sum_s' : sum M N P -> sum M (s N) (s P) -> type.
sum_comm : sum M N P -> sum N M P -> type.
- : sum_comm sum_z D
<- sum_z' _ D.
- : sum_comm (sum_s D1) D3
<- sum_comm D1 D2
<- sum_s' D2 D3.
44. sum : nat -> nat -> nat -> type.
Totality sum_z : sum z N N.
sum_s : sum M N P ->
sum (s M) N (s P).
only a proof if function is total - succeeds on all inputs
totality = coverage + termination
sum_comm : sum M N P -> sum N M P -> type.
%mode sum_comm +D1 -D2.
- : sum_comm sum_z ...
- : sum_comm (sum_s D1) D3
<- sum_comm D1 D2
...
%total (D1) (sum_comm D1 D2).
45. Recap
o programs are proofs
o functions from derivations to derivations
o need adequacy of representation
o need totality
o write proofs as Twelf logic programs
o we proved that sum is commutative
next: proofs about programming languages
46. Programming languages
a tiny programming language:
N nat E1 exp E2 exp
________ ______________
nat(N) exp let x = E1 in E2 exp
E1 exp E2 exp
___________ x is a bound variable in E2
E1 + E2 exp
47. Representing PLs
N nat
________
nat(N) exp
E1 exp E2 exp
___________
E1 + E2 exp
in OCaml:
E1 exp E2 exp
type exp = ______________
| Var of string let x = E1 in E2 exp
| Nat of nat
| Plus of exp * exp
| Let of exp * string * exp
• no alpha-equivalence; choice of name matters
• must implement scope, substitution manually
• inadequate: what does Var "x" w/o Let represent?
48. Representing PLs
N nat
________
nat(N) exp
E1 exp E2 exp
___________
E1 + E2 exp
another try in OCaml:
E1 exp E2 exp
type exp = ______________
| Nat of nat let x = E1 in E2 exp
| Plus of exp * exp
| Let of exp * (exp -> exp)
• body of let is function that does substitution:
let x = 1 in x + 2 == Let (Nat 1, (fun x -> Plus (x, Nat 2))
• unbound var inadequacy goes away
• functions that branch on arg, or raise exception?
49. Representing PLs
N nat
________
nat(N) exp
E1 exp E2 exp
___________
E1 + E2 exp
in Twelf:
E1 exp E2 exp
exp : type. ______________
nat : nat -> exp. let x = E1 in E2 exp
plus : exp -> exp -> exp.
let : exp -> (exp -> exp) -> exp.
• body of let is function that does substitution:
let x = 1 in x + 2 == (let (nat 1) ([x] plus x (nat 2)))
• Twelf functions are very weak, just templates
• adequate, alpha-equivalence
50. Higher-order logic programming
count variables uses - e.g. count (let x = 1 in x + x) 2
count : exp -> nat -> type.
count_nat : count (nat _) z.
count_plus : count (plus E1 E2) C
<- count E1 C1
<- count E2 C2
<- sum C1 C2 C.
51. Higher-order logic programming
count : exp -> nat -> type.
count_let : count (let E1 E2) C
<- count E1 C1
<- ({x:exp}{d:count x (s z)} count (E2 x) C2)
<- sum C1 C2 C.
• { } indicates scoped axioms (just for enclosed goal)
• x is a fresh variable
• substitute E2's bound variable with x
• when we find x in E2 it gets a count of 1
52. Recap
• programming languages have scope and binding
• want a convenient way to work with it
• higher-order syntax representation
• higher-order logic programming
• only works because Twelf functions are weak
53. Twelf
this approach scales to realistic programming lanaguages:
semantics and type safety proof for Standard ML:
Lee, Crary, Harper
Toward a Mechanized Metatheory of Standard ML
http://www.cs.cmu.edu/~rwh/papers/tslf/full.pdf
formalized x86 arch. and type-safe assembly language:
Crary, Sarkar
Foundational Certified Code in a Metalogical Framework
http://www.cs.cmu.edu/~crary/papers/2005/mafcc.pdf