DCOIOmega.typing

Require Import imports par geq conv syntax.

Module Type typing_sig
  (Import lattice : Lattice)
  (Import syntax : syntax_sig lattice)
  (Import par : par_sig lattice syntax)
  (Import ieq : geq_sig lattice syntax)
  (Import conv : conv_sig lattice syntax par ieq).

Definition context := list (T * tm).

Inductive lookup : nat -> context -> T -> tm -> Prop :=
  | here A Γ : lookup 0 ((, A) :: Γ) (A shift)
  | there n A Γ B :
      lookup n Γ A -> lookup (S n) (B :: Γ) (A shift).

Definition lookup_good_renaming ξ Γ Δ :=
  forall i A, lookup i Γ A -> exists ℓ0, lookup (ξ i) Δ ℓ0 Aξ /\ ℓ0 .

Derive Inversion lookup_inv with (forall i Γ A, lookup i Γ A).

Reserved Notation "Γ ⊢ a ; ℓ ∈ A" (at level 70).
Reserved Notation "⊢ Γ" (at level 70).

Definition c2e : context -> econtext := map (fun '(, _) => ).

Inductive Wt : context -> T -> tm -> tm -> Prop :=
| T_Var Γ ℓ0 i A :
   Γ ->
  lookup i Γ ℓ0 A ->
  ℓ0 ->
  (* ------ *)
  Γ (var_tm i) ; A

| T_Pi Γ i j ℓ0 A B :
  Γ A ; (tUniv i) ->
  ((ℓ0, A) :: Γ) B ; (tUniv j) ->
  (* --------------------- *)
  Γ (tPi ℓ0 A B) ; (tUniv (max i j))

| T_Abs Γ ℓ0 ℓ1 A a B i :
  Γ (tPi ℓ0 A B) ; ℓ1 (tUniv i) ->
  ((ℓ0, A) :: Γ) a ; B ->
  (* -------------------- *)
  Γ (tAbs ℓ0 a) ; (tPi ℓ0 A B)

| T_App Γ ℓ0 a A B b :
  Γ a ; (tPi ℓ0 A B) ->
  Γ b ; ℓ0 A ->
  (* -------------------- *)
  Γ (tApp a ℓ0 b) ; (B [ b.. ])

| T_Conv Γ ℓ0 a A B i :
  Γ a ; A ->
  Γ B ; ℓ0 (tUniv i) ->
  conv (c2e Γ) A B ->
  (* ----------- *)
  Γ a ; B

| T_Zero Γ :
   Γ ->
  (* --------- *)
  Γ tZero ; tNat

| T_Suc Γ a :
  Γ a ; tNat ->
  (* --------- *)
  Γ tSuc a ; tNat

| T_Ind Γ ℓ0 a b c A ℓA i :
  ℓ0 ->
  (ℓ0, tNat) :: Γ A ; ℓA tUniv i ->
  Γ a ; ℓ0 A [tZero..] ->
  (ℓ0, A) :: (ℓ0, tNat) :: Γ b ; ℓ0 A[tSuc (var_tm 0) .: S >> var_tm]S ->
  Γ c ; ℓ0 tNat ->
  (* ------------ *)
  Γ tInd ℓ0 a b c ; (A [c..])

| T_Nat Γ i :
   Γ ->
  (* ----------- *)
  Γ tNat ; tUniv i

| T_Univ Γ i :
   Γ ->
  (* ------------ *)
  Γ (tUniv i) ; (tUniv (S i))

| T_Void Γ i :
   Γ ->
  (* ------------ *)
  Γ tVoid ; tUniv i

| T_Absurd Γ ℓ0 ℓ1 i a A :
  Γ a ; ℓ0 tVoid ->
  Γ A ; ℓ1 tUniv i ->
  (* -------------- *)
  Γ tAbsurd a ; A

| T_Refl Γ a ℓ0 A:
  Γ a ; ℓ0 A ->
  (* ------ *)
  Γ tRefl ; (tEq ℓ0 a a)

| T_Eq Γ ℓ0 a b A i:
  ℓ0 ->
  Γ a ; ℓ0 A ->
  Γ b ; ℓ0 A ->
  (* ----------------------- *)
  Γ (tEq ℓ0 a b) ; (tUniv i)

| T_J Γ t a b p A i j C ℓp ℓT ℓ0 ℓ1:
  ℓ1 ℓ0 ->
  ℓp ->
  Γ a ; ℓ1 A ->
  Γ b ; ℓ1 A ->
  Γ A ; ℓT (tUniv j) ->
  (* Γ ⊢ a ; ℓ0 ∈ A -> *)
  Γ p ; ℓp (tEq ℓ0 a b) ->
  (* plug in a to show the admissibility lemma  *)
  (* note the usage of var 0 in the eq type *)
  ((ℓp, tEq ℓ0 (ren_tm shift a) (var_tm 0)) :: (ℓ1, A) :: Γ) C ; ℓ0 (tUniv i) ->
  Γ t ; (C [tRefl .: a ..]) ->
  Γ (tJ ℓp t p) ; (C [p .: b..])

| T_Sig Γ i j ℓ0 A B :
  Γ A ; (tUniv i) ->
  ((ℓ0, A) :: Γ) B ; (tUniv j) ->
  (* --------------------- *)
  Γ (tSig ℓ0 A B) ; (tUniv (max i j))

| T_Pack Γ ℓ0 a A b B ℓT i :
  Γ a ; ℓ0 A ->
  Γ b ; B[a..] ->
  Γ tSig ℓ0 A B ; ℓT tUniv i ->
  (* -------------------- *)
  Γ tPack ℓ0 a b ; tSig ℓ0 A B

| T_Let Γ ℓp ℓ0 a b ℓT A B C i j k :
  ℓp ->
  Γ A ; ℓT tUniv j ->
  (ℓ0, A) :: Γ B ; ℓT tUniv k ->
  Γ a ; ℓp tSig ℓ0 A B ->
  (ℓp, B) :: (ℓ0, A) :: Γ b ; C[(tPack ℓ0 (var_tm 1) (var_tm 0)) .: (shift >> shift >> var_tm)] ->
  (ℓp, tSig ℓ0 A B) :: Γ C ; ℓT tUniv i ->
  (* ----------------------- *)
  Γ tLet ℓ0 ℓp a b ; C[a ..]

| T_TT Γ :
   Γ ->
  (* --------------- *)
  Γ tTT ; tUnit

| T_Unit Γ i :
   Γ ->
  (* --------------- *)
  Γ tUnit ; tUniv i

| T_Seq Γ ℓ0 ℓC a b C i :
  ℓ0 ->
  Γ a ; ℓ0 tUnit ->
  Γ b ; C[tTT..] ->
  (ℓ0, tUnit) :: Γ C ; ℓC tUniv i ->
  (* --------------- *)
  Γ tSeq ℓ0 a b ; C[a..]

with Wff : context -> Prop :=
| Wff_nil :
(* ----------------- *)
   nil
| Wff_cons Γ ℓ0 A i :
   Γ ->
  Γ A ; tUniv i ->
(* ----------------- *)
   (ℓ0, A) :: Γ
where
  "Γ ⊢ a ; ℓ ∈ A" := (Wt Γ a A) and "⊢ Γ" := (Wff Γ).

#[export]Hint Constructors Wt Wff : wt.

Scheme wt_ind := Induction for Wt Sort Prop
    with wff_ind := Induction for Wff Sort Prop.

Combined Scheme wt_mutual from wt_ind, wff_ind.
End typing_sig.