Start of topic | Skip to actions

Curry-Howard Isomorphism

Last time we talked about logic, type systems and the one-to-one correspondence between them.

We are focused on how we can use lambda calculus as a proof system. Recall the typing rules of the lambda calculus:


------------------------
\Gamma, x:t \vdash x: t

\Gamma e1: t1 -> t2 
\Gamma e2: t1
-----------------------
\Gamma \vdash e1 e2 : t2


\Gamma, x:t1 \vdash e: t2
-----------------------------------
\Gamma \vdash \lambda x.e: t1 -> t2

Examples

Logic:
A -> (B -> A)

proof:

\Bullet \vdash \lambda a. \lambda b. a

Logic:

A -> (A -> A)

proof:

\Bullet \vdash \lambda a. \lambda b. a
or
\Bullet \vdash \lambda a. \lambda b. b

The inhabitance of a proposition is the number of proofs. This is what we talked about before. If this type have no inhabitants than there is no proof. If there are 2 inhabitants like in the second example then there are 2 proofs.

The Curry-Howard isomorphism says that there is a way to go back from typed lambda terms (with arrows, products, sums, forall, etc...) to logic propositions (with implications, and, or, forall, etc...). We can get from:

\Gamma \vdash e : t  
to
|\Gamma| \models |t| (logic proposition)
and we can also go in the inverse direction.

Next time, we want to look into the difference between \Pi and \forall

FFT project discussion

The type of the fft function should be:

fft: \forall n. snat(n) -> list (2^n) -> list (2^n)
if we use m as the snat name then:
match m with
Zero ->
Succ n-> (l1,l2) = split l; merge (fft l1) (fft l2)
Note that l1 has length 2^n just like l2

The problem is that the type of split should be:

split: \forall n .snat(n) -> list (2^(n+1)) -> (list (2^n) * list (2^n))
which don't match the original implementation of split because this is not true when split is called recursively

split l = match l with
[] -> ([],[])
(x::y::xs) -> let (l1,l2) = split xs in (x::l1,y::l2)

A solution to this would be to use another function

spliteven : forall n. snat(n) -> list (2*n) -> list(n) * list(n)

and implement split as a function that only calls spliteven as follows:

split l = spliteven l

It has the correct type, but can we encode the power size?

Can we write a function mk that takes a nat n and returns an existentially quantified slist of size 2^n ?

mk: nat -> \exists slist (2^n)
The answer is Yes we can. Therefore it should be possible to encode the power size.

lets go back to the definition of spliteven

match l with
|[] -> ([],[])
|(x::y::xs) -> (l1,l2) se xs in (x::l1,y::l2)

Cherif and Angela should try this way of defining split and see if it works. In case it doesn't it will be a good situation to point out why we could not do that.


End of topic
Skip to actions | Back to top
Creative Commons LicenseThis work is licensed under a Creative Commons Attribution 2.5 License. Please follow our citation guidelines.