TightTyping


Tight typing ⊢]


Set Implicit Arguments.

Require Import Coq.Program.Equality.
Require Import Definitions PreciseTyping.

Reserved Notation "G '⊢#' t ':' T" (at level 40, t at level 59).
Reserved Notation "G '⊢#' T '<:' U" (at level 40, T at level 59).

Tight typing is very similar to general typing, and could be obtained by replacing all occurrences of with #, except for the following:
  • in the type selection subtyping rules Sel-<: and <:-Sel (subtyp_sel1, subtyp_sel2) the premise is precise typing of a type declaration with equal bounds;
  • in the singleton subtyping rules Sngl-<: and <:-Sngl (subtyp_sngl_pq, and subtyp_sngl_qp) the premise is precise typing;
  • whenever a typing judgement in a premise extends the environment (for example, ty_all_intro_t), it is typed under general typing and not tight typing #.

Inductive ty_trm_t : ctx trm typ Prop :=

(x) = T
――――――――――
# x: T
| ty_var_t : x T,
    binds x T
     # tvar x : T

, x: T t^x: U^x
x fresh
――――――――――――――――――――――――
# lambda(T)t: (T)U
| ty_all_intro_t : t T U L,
    ( x, x \notin L
       & x ~ T open_trm x t : open_typ x U)
     # trm_val (λ(T) t) : ∀(T) U

# p: (S)T
# q: S
―――――――――――――――
p q: T^q
| ty_all_elim_t : p q S T,
     # trm_path p : ∀(S) T
     # trm_path q : S
     # trm_app p q : open_typ_p q T

z; , z: T^z ds^z :: T^z
z fresh
―――――――――――――――――――――――――――――――
# nu(T)ds :: mu(T)
| ty_new_intro_t : ds T L,
    ( z, z \notin L
      z; nil; & (z ~ open_typ z T) open_defs z ds :: open_typ z T)
     # trm_val (ν(T) ds) : μ T

# p: {a: T}
―――――――――――――
# p.a: T
| ty_new_elim_t : p a T,
     # trm_path p : typ_rcd {a T}
     # trm_path p a : T

# p.a: T
――――――――――――――
# p: {a: T}
| ty_rec_intro_t : p a T,
     # trm_path pa : T
     # trm_path p : typ_rcd { a T }

# t: T
, x: T u^x: U
x fresh
――――――――――――――――
# let t in u: U
| ty_let_t : t u T U L,
     # t : T
    ( x, x \notin L
       & x ~ T open_trm x u : U)
     # trm_let t u : U

# p: q.type
# q
―――――――――――――――
# p: T
| ty_sngl_t : p q T,
     # trm_path p : {{ q }}
     # trm_path q : T
     # trm_path p : T

# p.: T
――――――――――――――
# p: {a: T}
| ty_path_elim_t : p q a T,
     # trm_path p : {{ q }}
     # trm_path q a : T
     # trm_path p a : {{ qa }}

# p: T^p
――――――――――――
# p: mu(T)
| ty_rcd_intro_t : p T,
     # trm_path p : open_typ_p p T
     # trm_path p : μ T

# p: mu(T)
――――――――――――
# p: T^p
| ty_rec_elim_t : p T,
     # trm_path p : μ T
     # trm_path p : open_typ_p p T

# p: T
# p: U
――――――――――――
# p: T U
| ty_and_intro_t : p T U,
     # trm_path p : T
     # trm_path p : U
     # trm_path p : T U

# t: T
# T <: U
―――――――――――――
# t: U
| ty_sub_t : t T U,
     # t : T
     # T <: U
     # t : U
where "G '⊢#' t ':' T" := (ty_trm_t t T)

Tight subtyping # T <: U

with subtyp_t : ctx typ typ Prop :=

# T <: top
| subtyp_top_t: T,
     # T <:

# bot <: T
| subtyp_bot_t: T,
     # <: T

# T <: T
| subtyp_refl_t: T,
     # T <: T

# S <: T
# T <: U
―――――――――――――
# S <: U
| subtyp_trans_t: S T U,
     # S <: T
     # T <: U
     # S <: U

# T U <: T
| subtyp_and11_t: T U,
     # T U <: T

# T U <: U
| subtyp_and12_t: T U,
     # T U <: U

# S <: T
# S <: U
――――――――――――――――
# S <: T U
| subtyp_and2_t: S T U,
     # S <: T
     # S <: U
     # S <: T U

# T <: U
――――――――――――――――――――――
# {a: T} <: {a: U}
| subtyp_fld_t: T U a,
     # T <: U
     # typ_rcd {a T} <: typ_rcd {a U}

# <:
# <:
――――――――――――――――――――――――――――――――
# {A: ..} <: {A: ..}
| subtyp_typ_t: A,
     # <:
     # <:
     # typ_rcd { A >: <: } <: typ_rcd { A >: <: }

⊢!!! p: q.type
⊢!!! q: U
――――――――――――――――――――――――――――――――
# T <: [T[q/p,n]]
| subtyp_sngl_pq_t : p q T T' U,
     ⊢!!! p : {{ q }}
     ⊢!!! q : U
    repl_typ p q T T'
     # T <: T'

⊢!!! p: q.type
⊢!!! q: U
――――――――――――――――――――――――――――――――
# T <: [T[p/q,n]]
| subtyp_sngl_qp_t : p q T T' U,
     ⊢!!! p : {{ q }}
     ⊢!!! q : U
    repl_typ q p T T'
     # T <: T'

⊢!!! p: {A: T..T}
―――――――――――――――――――
# T <: p.A
| subtyp_sel2_t: p A T ,
     ⊢!!! p : typ_rcd { A >: T <: T }
     # T <: p A

⊢!!! p: {A: T..T}
―――――――――――――――――――
# p.A <: T
| subtyp_sel1_t: p A T,
     ⊢!!! p : typ_rcd { A >: T <: T }
     # pA <: T

# <:
, x: ^x <: ^x
x fresh
――――――――――――――――――――――――
# () <: ()
| subtyp_all_t: L,
     # <:
    ( x, x \notin L
        & x ~ open_typ x <: open_typ x )
     # ∀() <: ∀()
where "G '⊢#' T '<:' U" := (subtyp_t T U).

Hint Constructors ty_trm_t subtyp_t.

Scheme ts_ty_trm_mut_ts := Induction for ty_trm_t Sort Prop
with ts_subtyp_ts := Induction for subtyp_t Sort Prop.
Combined Scheme ts_mutind_ts from ts_ty_trm_mut_ts, ts_subtyp_ts.

Tight typing implies general typing.
Lemma tight_to_general:
  ( t T,
      # t : T
      t : T)
  ( S U,
      # S <: U
      S <: U).
Proof.
  apply ts_mutind_ts; intros; subst; eauto using precise_to_general3.
Qed.