LogRel.TypingProperties.PropertiesDefinition

LogRel.PropertiesDefinition: the high-level, abstract properties of conversion and typing, that we obtain as consequences of the logical relation.

From Coq Require Import CRelationClasses ssrbool.
From LogRel Require Import Utils Syntax.All GenericTyping Normalisation.

Section Properties.

  Context `{ta : tag}
    `{!WfContext ta} `{!WfType ta} `{!Typing ta} `{!ConvType ta} `{!ConvTerm ta} `{!ConvNeuConv ta}
    `{!RedType ta} `{!RedTerm ta}.

Typing is stable by substitution
  Class TypingSubst :=
  {
    ty_subst {Γ Δ σ A} :
      [|- Δ] -> [Δ |-s σ : Γ] ->
      [Γ |- A] -> [Δ |- A[σ]];
    tm_subst {Γ Δ σ A t} :
      [|- Δ] -> [Δ |-s σ : Γ] ->
      [Γ |- t : A] -> [Δ |- t[σ] : A[σ]];
    ty_conv_subst {Γ Δ σ σ' A B} :
      [|- Δ] -> [Δ |-s σ σ' : Γ] ->
      [Γ |- A B] -> [Δ |- A[σ] B[σ']];
    tm_conv_subst {Γ Δ σ σ' A t u} :
      [|- Δ] -> [Δ |-s σ σ' : Γ] ->
      [Γ |- t u : A] -> [Δ |- t[σ] u[σ'] : A[σ]] ;
  }.

  Class Strengthening :=
  {
  ty_str {Γ Δ A} (ρ : Γ Δ) :
    [|- Δ] ->
    [Γ |- Aρ] -> [Δ |- A];
  tm_str {Γ Δ A t} (ρ : Γ Δ) :
    [|- Δ] ->
    [Γ |- tρ : Aρ] -> [Δ |- t : A];
  ty_conv_str {Γ Δ A B} (ρ : Γ Δ) :
    [|- Δ] ->
    [Γ |- Aρ Bρ] -> [Δ |- A B];
  tm_conv_str {Γ Δ A t u} (ρ : Γ Δ) :
    [|- Δ] ->
    [Γ |- tρ uρ : Aρ] -> [Δ |- t u : A] ;
  }.

Reduction is complete for type conversion: if a type is convertible to a whnf, then it also reduces to a whnf.
  Class TypeReductionComplete :=
  {
    red_ty_complete_l (Γ : context) (T T' : term) :
      isType T ->
      [Γ |- T T'] ->
       T'', [Γ |- T' ⤳* T''] × isType T'' ;

    red_ty_complete_r (Γ : context) (T T' : term) :
      isType T' ->
      [Γ |- T T'] ->
       T'', [Γ |- T ⤳* T''] × isType T'' ;
  }.

  Definition type_hd_view (Γ : context) {T T' : term}
    (nfT : isType T) (nfT' : isType T') : Type :=

    match nfT, nfT' with
      | @UnivType s, @UnivType s' => s = s'
      | @ProdType A B, @ProdType A' B' => [Γ |- A' A] × [Γ,, A' |- B B']
      | NatType, NatType => True
      | EmptyType, EmptyType => True
      | NeType _, NeType _ => [Γ |- T T' : U]
      | @SigType A B, @SigType A' B' => [Γ |- A A'] × [Γ,, A |- B B']
      | @IdType A x y, @IdType A' x' y' => [Γ |- A A'], [Γ |- x x' : A] & [Γ |- y y' : A]]
| _, _ => False
    end.

Type constructors injectivity/no-confusion: two convertible whnf types must be the same head constructor, with convertible arguments.

  Class TypeConstructorsInj :=
  {
   ty_conv_inj (Γ : context) (T T' : term)
    (nfT : isType T) (nfT' : isType T') :
    [Γ |- T T'] ->
    type_hd_view Γ nfT nfT'
  }.

Similar notions for term constructors at positive types.

  Definition univ_hd_view (Γ : context) {T T' : term} (nfT : isType T) (nfT' : isType T') : Type :=
    match nfT, nfT' with
      | @UnivType s, @UnivType s' => False
      | @ProdType A B, @ProdType A' B' => [Γ |- A' A : U] × [Γ,, A' |- B B' : U]
      | NatType, NatType => True
      | EmptyType, EmptyType => True
      | NeType _, NeType _ => [Γ |- T T' : U]
      | @SigType A B, @SigType A' B' => [Γ |- A A' : U] × [Γ,, A |- B B' : U]
      | @IdType A x y, @IdType A' x' y' => [Γ |- A A' : U], [Γ |- x x' : A] & [Γ |- y y' : A]]
| _, _ => False
    end.

  Lemma univ_hd_view_irr {Γ T0 T0' T1 T1'}
    (nfT0 : isType T0) (nfT0' : isType T0') (nfT1 : isType T1) (nfT1' : isType T1') :
    T0 = T1 -> T0' = T1' -> univ_hd_view Γ nfT0 nfT0' -> univ_hd_view Γ nfT1 nfT1'.
  Proof.
    intros ??.
    enough (h : univ_hd_view Γ nfT0 nfT0' = univ_hd_view Γ nfT1 nfT1')
    by now rewrite h.
    subst; f_equal; apply isType_uniq.
  Qed.

  Definition nat_hd_view (Γ : context) {t t' : term} (nft : isNat t) (nft' : isNat t') : Type :=
  match nft, nft' with
    | ZeroNat, ZeroNat => True
    | @SuccNat u, @SuccNat u' => [Γ |- u u' : tNat]
    | NeNat _, NeNat _ => [Γ |- t t' : tNat ]
    | _, _ => False
  end.

  Lemma nat_hd_view_irr {Γ t0 t0' t1 t1'}
    (nft0 : isNat t0) (nft0' : isNat t0') (nft1 : isNat t1) (nft1' : isNat t1') :
    t0 = t1 -> t0' = t1' -> nat_hd_view Γ nft0 nft0' -> nat_hd_view Γ nft1 nft1'.
  Proof.
    intros ??.
    enough (h : nat_hd_view Γ nft0 nft0' = nat_hd_view Γ nft1 nft1')
    by now rewrite h.
    subst; f_equal; apply isNat_uniq.
  Qed.

  Definition id_hd_view (Γ : context) (A x x' : term) {t t' : term} (nft : isId t) (nft' : isId t') : Type :=
    match nft, nft' with
      | @ReflId A a, @ReflId A' a' => [Γ |- A A'] × [Γ |- a a' : A]
      | NeId _, NeId _ => [Γ |- t t' : tId A x x']
      | _, _ => False
    end.

  Lemma id_hd_view_irr {Γ A x y t0 t0' t1 t1'}
    (nft0 : isId t0) (nft0' : isId t0') (nft1 : isId t1) (nft1' : isId t1') :
    t0 = t1 -> t0' = t1' -> id_hd_view Γ A x y nft0 nft0' -> id_hd_view Γ A x y nft1 nft1'.
  Proof.
    intros ??.
    enough (h : id_hd_view Γ A x y nft0 nft0' = id_hd_view Γ A x y nft1 nft1')
    by now rewrite h.
    subst; f_equal; apply isId_uniq.
  Qed.

  Class TermConstructorsInj :=
  {
    univ_conv_inj (Γ : context) (T T' : term)
      (nfT : isType T) (nfT' : isType T') :
      [Γ |- T T' : U] ->
      univ_hd_view Γ nfT nfT' ;

    nat_conv_inj (Γ : context) (t t' : term)
      (nft : isNat t) (nft' : isNat t') :
      [Γ |- t t' : tNat] ->
      nat_hd_view Γ nft nft' ;

    (* empty_conv_inj (Γ : context) (t t' : term) :
      whne t -> whne t' ->
      Γ |- t t' : tEmpty ->
      Γ |- t ~ t' : tEmpty ; *)


    id_conv_inj (Γ : context) (A x y t t' : term)
      (nft : isId t) (nft' : isId t') :
      [Γ |- t t' : tId A x y] ->
      id_hd_view Γ A x y nft nft' ;

    (* neu_conv_inj (Γ : context) (A t t' : term) :
      whne A -> whne t -> whne t' ->
      Γ |- t t' : A ->
      Γ |- t ~ t' : A *)

  }.

Completeness of neutral conversion, at positive types or at all types

  Class ConvNeutralConvPos :=
  {
    conv_neu_conv_p Γ T n n' :
      whne n -> whne n' -> isPosType T ->
      [Γ |- n n' : T] ->
      [Γ |- n ~ n' : T]
  }.

  Class ConvNeutralConv :=
  {
    conv_neu_conv Γ T n n' :
      whne n -> whne n' ->
      [Γ |- n n' : T] ->
      [Γ |- n ~ n' : T]
  }.

Injectivity of neutral destructors

  Definition ne_view (Γ : context) (T : term) {n n' : term} (ne : whne n) (ne' : whne n') : Type :=
  match ne, ne' with
    | @whne_tRel v, @whne_tRel v' => T', v' = v, in_ctx Γ v T' & [Γ |- T' T] ]
    | @whne_tApp t u _, @whne_tApp t' u' _ => A B, [Γ |- t t' : tProd A B], [Γ |- u u' : A] & [Γ |- B[u..] T]]
| @whne_tNatElim P hz hs n _, @whne_tNatElim P' hz' hs' n' _ =>
       [Γ |- n n' : tNat],
        [Γ ,, tNat |- P P'],
        [Γ |- hz hz' : P[tZero..]],
        [Γ |- hs hs' : elimSuccHypTy P] &
        [Γ |- P[n..] T]]

    | @whne_tEmptyElim P e _, @whne_tEmptyElim P' e' _ =>
       [Γ ,, tEmpty |- P P'],
        [Γ |- e e' : tEmpty] &
        [Γ |- P[e..] T]]

    | @whne_tFst p _, @whne_tFst p' _ => A B, [Γ |- p p' : tSig A B] × [Γ |- A T]
    | @whne_tSnd p _, @whne_tSnd p' _ => A B, [Γ |- p p' : tSig A B] × [Γ |- B[(tFst p)..] T]
    | @whne_tIdElim A x P hr y e _, @whne_tIdElim A' x' P' hr' y' e' _ =>
       [Γ |- A A'],
        [Γ |- x x' : A],
        [Γ ,, A ,, tId A@wk1 Γ A x@wk1 Γ A (tRel 0) |- P P'],
        [Γ |- hr hr' : P[tRefl A x .: x..]],
        [Γ |- y y' : A],
        [Γ |- e e' : tId A x y] &
        [Γ |- P[e .: y..] T]]
| _, _ => False
  end.

  Class NeutralInj :=
  {
    neu_inj (Γ : context) (T t t' : term)
    (net : whne t) (net' : whne t') :
    [Γ |- t t' : T] ->
    ne_view Γ T net net'
  }.

Normalisation


  Class Normalisation :=
  {
    tm_norm {Γ A t} : [Γ |- t : A] -> normalising t ;
    ty_norm {Γ A} : [Γ |- A] -> normalising A ;
  }.

  Class DeepNormalisation :=
  {
    tm_dnorm {Γ A t} : [Γ |- t : A] -> dnorm_tm Γ A t ;
    ty_dnorm {Γ A} : [Γ |- A] -> dnorm_ty Γ A ;
  }.

  Context `{ta' : tag}
    `{!WfContext ta'} `{!WfType ta'} `{!Typing ta'} `{!ConvType ta'} `{!ConvTerm ta'}.

Implication between two different instances.


  Class ConvImplies := {
    ty_conv_compl Γ A A' : [Γ |-[ta] A A'] -> [Γ |-[ta'] A A'] ;
    tm_conv_compl Γ A t t' : [Γ |-[ta] t t' : A] -> [Γ |-[ta'] t t' : A] ;
  }.

  Class TypingImplies := {
    ty_compl Γ A : [Γ |-[ta] A] -> [Γ |-[ta'] A] ;
    tm_compl Γ A t : [Γ |-[ta] t : A] -> [Γ |-[ta'] t : A] ;
  }.

End Properties.

Arguments TypingSubst _ {_ _ _ _ _}.
Arguments Strengthening _ {_ _ _ _ _}.
Arguments TypeReductionComplete _ {_ _}.
Arguments TypeConstructorsInj _ {_ _}.
Arguments TermConstructorsInj _ {_ _}.
Arguments ConvNeutralConvPos _ {_ _}.
Arguments ConvNeutralConv _ {_ _}.
Arguments NeutralInj _ {_ _}.
Arguments Normalisation _ {_ _}.
Arguments DeepNormalisation _ {_ _}.
Arguments ConvImplies _ {_ _} _ {_ _}.
Arguments TypingImplies _ {_ _} _ {_ _}.