Library CoqInCoq.Int_typ


Require Import Termes.
Require Import Conv.
Require Import Types.
Require Import Class.
Require Import Can.


  Inductive Int_K : Type :=
    | iK : s : skel, Can sInt_K
    | iT : Int_K.

  Definition intP := TList Int_K.

  Definition class_of_ik (ik : Int_K) :=
    match ik with
    | iK s _Knd s
    | iTTyp PROP
    end.

  Definition cls_of_int : intPcls := Tmap _ _ class_of_ik.

  Definition ext_ik (T : term) (ip : intP) (s : skel)
    (C : Can s) :=
    match cl_term T (cls_of_int ip) with
    | Knd _iK s C
    | _iT
    end.

  Definition int_cons (T : term) (ip : intP) (s : skel)
    (C : Can s) := TCs _ (ext_ik T ip s C) ip.

  Definition def_cons (T : term) (I : intP) : intP :=
    int_cons T I _ (default_can (cv_skel (cl_term T (cls_of_int I)))).

  Definition skel_int (t : term) (I : intP) :=
    typ_skel (cl_term t (cls_of_int I)).

  Lemma ins_in_cls :
    (c : class) (y : Int_K) (k : nat) (ipe ipf : intP),
   class_of_ik y = c
   TIns Int_K y k ipe ipfTIns _ c k (cls_of_int ipe) (cls_of_int ipf).
unfold cls_of_int in |- ×.
simple induction 1.
simple induction 1; simpl in |- *; auto with coc core arith datatypes.
Qed.

  Definition coerce_CR (s : skel) (i : Int_K) : Can s :=
    match i with
    | iK si Ci
        match EQ_skel si s with
        | left y
            match y in (_ = x) return (Can x) with
            | refl_equalCi
            end
        | _default_can s
        end
    | _default_can s
    end.

  Lemma is_can_coerce :
    s s' C, is_can s Cis_can s' (coerce_CR s' (iK s C)).
Proof.
simpl in |- *; intros.
elim (EQ_skel s s'); intros; auto with coc.
case a; trivial.
Qed.

Hint Resolve is_can_coerce: coc.

  Lemma extr_eq :
    (P : s : skel, Can sProp) (s : skel) (c : Can s),
   P s cP s (coerce_CR s (iK s c)).
Proof.
intros.
unfold coerce_CR in |- ×.
elim (EQ_skel s s).
intro Heq.
change
  ((fun s0 (e : s = s0) ⇒
    P s0 match e in (_ = x) return (Can x) with
         | refl_equalc
         end) s Heq) in |- ×.
case Heq; trivial.

simple induction 1; auto with coc core arith datatypes.
Qed.

  Lemma eq_can_extr :
    (s si : skel) (X Y : Can s),
   eq_can s X Yeq_can si (coerce_CR si (iK s X)) (coerce_CR si (iK s Y)).
unfold coerce_CR in |- ×.
intros.
elim (EQ_skel s si); auto with coc core arith datatypes.
intro Heq; case Heq; auto with coc core arith datatypes.
Qed.

  Hint Resolve eq_can_extr: coc.

  Inductive ik_eq : Int_KInt_KProp :=
    | eqi_K :
         (s : skel) (X Y : Can s),
        eq_can s X X
        eq_can s Y Yeq_can s X Yik_eq (iK s X) (iK s Y)
    | eqi_T : ik_eq iT iT.

  Hint Resolve eqi_K eqi_T: coc.

  Lemma iki_K :
    (s : skel) (C : Can s), eq_can s C Cik_eq (iK s C) (iK s C).
auto with coc core arith datatypes.
Qed.

  Hint Resolve iki_K: coc.

  Definition int_eq_can : intPintPProp := Tfor_all2 _ _ ik_eq.
  Definition int_inv (i : intP) := int_eq_can i i.

  Hint Unfold int_eq_can int_inv: coc.

  Lemma ins_int_inv :
    (e f : intP) (k : nat) (y : Int_K),
   TIns _ y k e fint_inv fint_inv e.
unfold int_inv, int_eq_can in |- ×.
simple induction 1; intros; auto with coc core arith datatypes.
inversion_clear H0; auto with coc core arith datatypes.

inversion_clear H2; auto with coc core arith datatypes.
Qed.

  Lemma int_inv_int_eq_can : i : intP, int_inv iint_eq_can i i.
auto with coc core arith datatypes.
Qed.

  Hint Resolve int_inv_int_eq_can: coc.

  Lemma int_eq_can_cls :
    i i' : intP, int_eq_can i i'cls_of_int i = cls_of_int i'.
unfold cls_of_int in |- ×.
simple induction 1; simpl in |- *; intros; auto with coc core arith datatypes.
inversion_clear H0; simpl in |- *; intros; elim H2;
 auto with coc core arith datatypes.
Qed.

  Fixpoint int_typ (T : term) : intP s : skel, Can s :=
    fun (ip : intP) (s : skel) ⇒
    match T with
    | Srt _default_can s
    | Ref ncoerce_CR s (Tnth_def _ (iK PROP sn) ip n)
    | Abs A t
        match cl_term A (cls_of_int ip) with
        | Knd _
            match s as x return (Can x) with
            | PROD s1 s2
                fun C : Can s1int_typ t (TCs _ (iK s1 C) ip) s2
            | PROPdefault_can PROP
            end
        | Typ _int_typ t (def_cons A ip) s
        | _default_can s
        end
    | App u v
        match cl_term v (cls_of_int ip) with
        | Trmint_typ u ip s
        | Typ svint_typ u ip (PROD sv s) (int_typ v ip sv)
        | _default_can s
        end
    | Prod A B
        match s as x return (Can x) with
        | PROP
            let s := cv_skel (cl_term A (cls_of_int ip)) in
            Pi s (int_typ A ip PROP)
              (fun Cint_typ B (int_cons A ip s C) PROP)
        | PROD s1 s2default_can (PROD s1 s2)
        end
    end.