This file contains the syntactic typing judegment, as well as type preservation under substitution and progress and preservation proofs
Set Implicit Arguments.
Require Import Omega Logic List Classes.Morphisms.
Import List Notations.

Require Export CBPV.Terms CBPV.Base CBPV.Semantics.
Import CommaNotation.

Syntactic Typing Judement

Reserved Notation "Gamma ⊢ c : A" (at level 80, c at level 99).
Reserved Notation "Gamma ⊩ v : A" (at level 80, v at level 99).

Syntactic typing judgement using DeBrujin indices
Definition ctx (n: ) := fin n valtype.

Value Typing Judgement

Inductive value_typing {m: } (: ctx m) : value m valtype Type :=
| typeVar i : var_value i : i
| typeUnit: u : one
| typePair :
     : : pair : cross
| typeSum (b: bool) v:
     v : (if b then else ) inj b v : Sigma
| typeThunk c A:
     c : A thunk c : U A
where "Gamma ⊩ v : A" := (value_typing v A)

Computation Typing Judgement

with computation_typing {m: } (: ctx m) : comp m comptype Type :=
| typeCone: cu : cone
| typeLambda (c: comp (S m)) A B:
    A .: c : B ( lambda c : A B)
| typeLetin A B:
     : F A A .: : B $ ; : B
| typeRet v A:
     v : A ret v : F A
| typeApp c v A B:
     c : A B v : A c v : B
| typeTuple :
     : : tuple : Pi
| typeProj b c :
     c : Pi proj b c : (if b then else )
| typeForce v A:
     v : U A v! : A
| typeCaseZ v A: v : zero caseZ v : A
| typeCaseS v C:
     v : Sigma
    , : C
    , : C
     caseS v : C
| typeCaseP v c A B C:
     v : A * B
    B, A, c : C
     caseP v c : C
where "Gamma ⊢ c : A" := (@computation_typing _ c A).

Scheme value_typing_ind_2 := Minimality for value_typing Sort Prop
  with computation_typing_ind_2 := Minimality for computation_typing Sort Prop.

Scheme value_typing_ind_3 := Minimality for value_typing Sort Type
  with computation_typing_ind_3 := Minimality for computation_typing Sort Type.

Combined Scheme mutind_value_computation_typing from
         value_typing_ind_2, computation_typing_ind_2.

Scheme value_typing_ind_4 := Induction for value_typing Sort Prop
    with computation_typing_ind_4 := Induction for computation_typing Sort Prop.

Combined Scheme mutindt_value_computation_typing from
          value_typing_ind_4, computation_typing_ind_4.

Hint Constructors computation_typing value_typing.

Type judgement inversion
Ltac invt :=
  match goal with
  | [H: (_ cu : _) |- _] inv H
  | [H: (_ lambda _ : _) |- _] inv H
  | [H: (_ _ ! : _) |- _] inv H
  | [H: (_ $ _; _ : _) |- _] inv H
  | [H: (_ ret _ : _) |- _] inv H
  | [H: (_ app _ _ : _) |- _] inv H
  | [H: (_ tuple _ _ : _) |- _] inv H
  | [H: (_ proj _ _ : _) |- _] inv H
  | [H: (_ _ ! : _) |- _] inv H
  | [H: (_ proj _ _ : _) |- _] inv H
  | [H: (_ caseZ _ : _) |- _] inv H
  | [H: (_ caseS _ _ _ : _) |- _] inv H
  | [H: (_ caseP _ _ : _) |- _] inv H
  | [H: (_ var_value _ : _) |- _] inv H
  | [H: (_ u : _) |- _] inv H
  | [H: (_ pair _ _ : _) |- _] inv H
  | [H: (_ inj _ _ : _) |- _] inv H
  | [H: (_ <{ _ }> : _) |- _] inv H
  | [H: (_ _ : zero) |- _] inv H
  end.

Automation friendly version of the variable constructor
Lemma typeVar' n ( : ctx n) A i: i = A var_value i : A.
Proof. intros ; constructor. Qed.

Hint Resolve typeVar'.

Type Preservation under Substitution

Type preservation under renaming
Fixpoint value_typepres_renaming n v A (H: v : A) m (: fin n fin m) {struct H}:
  ( i, i = ( i)) v : A
with comp_typepres_renaming n c B (H: c : B) m (: fin n fin m) {struct H}:
  ( i, i = ( i)) c : B.
Proof.
  all: destruct H; cbn; intros; eauto; econstructor; eauto;
    eapply comp_typepres_renaming; eauto.
  all: auto_case.
Qed.


Type preservation under substitution
Fixpoint value_typepres_substitution n (: ctx n) v A (H: v : A) m (: fin n value m) {struct H}:
  ( i, i : i) v[] : A
with comp_typepres_substitution n (: ctx n) c B (H: c : B) m (: fin n value m) {struct H}:
  ( i, i : i) c[] : B.
Proof.
    all: destruct H; cbn; intros; eauto; econstructor; eauto.
    all: eapply comp_typepres_substitution; eauto.
    all: auto_case; repeat (eapply value_typepres_renaming); eauto.
Qed.


Preservation

Type preservation under beta reduction
Lemma typepres_beta {n: } (: fin n valtype) c v A B:
  A .: c : B v : A c[v..] : B.
Proof.
  intros ; eapply (comp_typepres_substitution ); intros []; cbn; eauto.
Qed.


Type preservation under primitive reduction
Lemma primitive_preservation {n} (c c': comp n) A:
  c c' c : A inhab ( c' : A).
Proof.
  destruct 1; intros ; repeat invt; try destruct b; constructor; eauto using typepres_beta.
  eapply comp_typepres_substitution; [eassumption |]; auto_case.
Qed.


Type preservation under reduction
Lemma preservation {n: } (c c': comp n) A:
  c > c' c : A inhab ( c' : A).
Proof.
  induction 1 in , A |-*; [ now apply primitive_preservation | idtac.. ];
    intros; invt; destruct (IHstep _ _ ); constructor; eauto.
Qed.


Lemma preservation_steps n (: ctx n)(c c': comp n) A:
     c : A c >* c' inhab ( c' : A).
Proof.
  induction 2; eauto using preservation.
  specialize (preservation H X) as []; eauto.
Qed.


Progress

Lemma progress (e: comp 0) (B: comptype) :
  null e : B ( e', e > e') nf e.
Proof with (left; eexists; eauto).
  enough (
       n e B, e : B
      (match n return ctx n Prop with 0 = null | _ _ False end)
      ( e', e > e') nf e
    ) by eauto.
  induction 1; destruct m; intuition; subst .
  1, 3, 5: destruct ...
  1 - 3: inv ; invt...
  all: inv ; try (destruct i)...
Qed.