The proof that typing derivations are unique in the simply-typed lambda calculus is trivial on paper. The proof that I am familiar with proceeds by complete induction on typing derivations. However, I am having trouble proving that typing derivations, represented via the type of typing derivations, are unique. Here, the predicate dec Γ x τ
is true if the variable x
has type τ
in environment Γ
. The typing predicate J
is defined as usual, simply reading off the typing rules for the simply-typed lambda calculus:
Inductive J (Γ : env) : term → type → Set :=
| tvar : ∀ x τ, dec Γ x τ → J γ (var x) τ
| tabs : ∀ τ₁ τ₂ e, J (τ₁ :: γ) e τ₂ → J γ (abs τ₁ e) (arr τ₁ τ₂)
| tapp : ∀ τ₁ τ₂ e₁ e₂, J γ e₁ (arr τ₁ τ₂) → J γ e₂ τ₁ → J γ (app e₁ e₂) τ₂.
I am having trouble exposing the structure of a term of type J
when proving that typing derivations are unique. For instance, I can induct on either d1
or d2
in the following lemma, but cannot induction on d1
then destruct d2
and conversely. The error message given by Coq (abstracting over terms leads to a term which is ill-typed) is slightly obscure, and the Coq wiki doesn't provide any help. For reference, this is the lemma that I am trying to prove:
Lemma unique_derivation : ∀ Γ e τ (d₁ d₂ : J Γ e τ), d₁ = d₂.
I have no problems when inducting on terms, for instance, when proving that the types are unique.
EDIT: I added the the minimal number of definitions necessary to state the result that I am having trouble with. In response to huitseeker's comment, the sort of J
was chosen because I wanted to reason about typing derivations as structured objects in order to perform operations like extraction and prove results like uniqueness, which I haven't done in Coq before.
In response to the first part of the comment, I can perform induction
on either d1
or d2
, but after performing induction
I cannot use destruct
, case
, or induction
on the remaining term. This means that I cannot expose the structure of both d1
and d2
in order to reason about both proof trees. The error that I receive when I attempt to do so, says that abstracting over the remaining terms leads to a term which is ill-typed.
Require Import Unicode.Utf8.
Require Import Utf8_core.
Require Import List.
Inductive type : Set :=
| tau : type
| arr : type → type → type.
Inductive term : Set :=
| var : nat → term
| abs : type → term → term
| app : term → term → term.
Definition dec (Γ : list type) x τ : Prop :=
nth_error γ x = Some τ.
Inductive J (Γ : list type) : term → type → Set :=
| tvar : ∀ x τ, dec Γ x τ → J Γ (var x) τ
| tabs : ∀ τ₁ τ₂ e, J (τ₁ :: Γ) e τ₂ → J Γ (abs τ₁ e) (arr τ₁ τ₂)
| tapp : ∀ τ₁ τ₂ e₁ e₂, J Γ e₁ (arr τ₁ τ₂) → J Γ e₂ τ₁ → J Γ (app e₁ e₂) τ₂.
Lemma derivations_unique : ∀ Γ e τ (d1 d2 : J Γ e τ), d1 = d2.
Proof. admit. Qed.
I've tried experimenting with dependent induction
and several results from the Coq.Logic
library, but without success. That derivations are unique seems like it should be an easy proposition to prove.
case
,destruct
or something else). Finally, are you sure about the sort ofJ
? Are you familiar with the notion of predicativity ? – Francois GSet
is predicative in Coq. My limited understanding indicates to me that this isn't the problem. I edited the original post to reflect the minimal development necessary to state the theorem, and tried to describe the problem that I'm having in more detail. – danportinJ
inSet
is right if you want to reason about them as first-class objects, say to prove their unicity. – Gilles 'SO- stop being evil'