Natural Deduction and the Calculus of Constructions
Recently I have been interested in the Calculus of Constructions and read the Wikipedia Page. Now, the content on this page is all well and good, but I have also been reading the lean theorem proving manual and have some confusion. I understand the broad idea of how CoC can be used to prove things: for example, in the below Lean code:
theorem t1 : ∀ (p q : Prop), p → q → p :=
λ (p q : Prop) (hp : p) (hq : q), hp
We have a proof that for propositions p, q , p → q → p by treating the proposition as a type, and constructing a term of the correct type. This is the Curry-Howard Isomorphism at play. Now consider this Lean snippet:
theorem t2 : p ∧ q → p := λ h : p ∧ q, and.elim_left h
Obviously, we are applying the left elimination rule for conjunction. The theorem proving manual goes on to define a bunch more elimination/introduction rules. These seem to be the inference rules of natural deduction. Now the Wikipedia page mentions that we can define conjunction like so:
A ∧ B = ∀ C : P. (A → B → C) → C
This makes a lot of sense when considering the introduction rule for conjunction: suppose we had a term a : A and also b : B. Then we could construct a term of the above type like so
λ f : (A → B → C), f a b
It seems like this is a "derivation" of the introduction rule for conjunction in natural deduction. However, I don't really see a way to do this for elimination (constructing a term of type p from one of p ∧ q) as in the above example. So it seems to me like lean is taking the rules of natural deduction as valid inference rules? I guess my overall question is what exactly the relationship between a proof calculus and type theory is. Actually, even more broadly, Wikipedia calls CoC a "type theory" while natural deduction is a "proof calculus." But it seems to be that these are similar concepts: CoC is a bunch of inference rules for typing things, but under Curry-Howard this is "the same" as proving things. Meanwhile in natural deduction, we also have inference rules used to prove things. So what exactly is the difference?
I'll apologize in advance since I recognize that this is probably a dumb question (I'm an undergraduate without much formal background in logic or type theory). Thanks for bearing with me.
Posted Jun 8, 2021, 9:11 AM UTC
If we define
p ∧ qasforall c. (p -> q -> c) -> c, you can implement left-elimination by instanciatingctop:elim_left p_and_q = p_and_q(const)(with the brackets as function application)where
const a b = ais equivalent to yourt1.Excuse the notation, I'm not a Lean programmer and I couldn't manage to copy-paste lambda's into the code-blocks easily!
Oh thanks, I'm not sure how I missed that!