D.Dot.typing.type_eq
From D.Dot Require Import syn.
Set Implicit Arguments.
Unset Strict Implicit.
Implicit Types (L T U : ty) (v : vl) (e : tm) (d : dm) (ds : dms) (Γ : ctx).
Reserved Notation "|- T1 == T2" (at level 70, T1 at level 69).
Reserved Notation "|-K K1 == K2" (at level 70, K1 at level 69).
Inductive type_equiv : Equiv ty :=
| type_equiv_later_and T1 T2 :
|- TLater (TAnd T1 T2) == TAnd (TLater T1) (TLater T2)
| type_equiv_later_or T1 T2 :
|- TLater (TOr T1 T2) == TOr (TLater T1) (TLater T2)
| type_equiv_later_mu T :
|- TLater (TMu T) == TMu (TLater T)
(* Congruence closure *)
| type_equiv_top : |- TTop == TTop
| type_equiv_bot : |- TBot == TBot
| type_equiv_and T1 U1 T2 U2 : |- T1 == T2 → |- U1 == U2 → |- TAnd T1 U1 == TAnd T2 U2
| type_equiv_or T1 U1 T2 U2 : |- T1 == T2 → |- U1 == U2 → |- TOr T1 U1 == TOr T2 U2
| type_equiv_later T1 T2 : |- T1 == T2 → |- TLater T1 == TLater T2
| type_equiv_all S1 T1 S2 T2 : |- S1 == S2 → |- T1 == T2 → |- TAll S1 T1 == TAll S2 T2
| type_equiv_mu T1 T2 : |- T1 == T2 → |- TMu T1 == TMu T2
| type_equiv_vmem l T1 T2 : |- T1 == T2 → |- TVMem l T1 == TVMem l T2
| type_equiv_ktmem l K1 K2 : |-K K1 == K2 → |- kTTMem l K1 == kTTMem l K2
| type_equiv_ksel n p l : |- kTSel n p l == kTSel n p l
| type_equiv_prim b : |- TPrim b == TPrim b
| type_equiv_sing p : |- TSing p == TSing p
| type_equiv_lam T1 T2 : |- T1 == T2 → |- TLam T1 == TLam T2
| type_equiv_app T1 T2 p : |- T1 == T2 → |- TApp T1 p == TApp T2 p
| type_equiv_sym : Symmetric type_equiv
| type_equiv_trans : Transitive type_equiv
where "|- T1 == T2" := (type_equiv T1 T2)
with kind_equiv : Equiv kind :=
| kind_equiv_kintv L1 L2 U1 U2 : |- L1 == L2 → |- U1 == U2 → |-K kintv L1 U1 == kintv L2 U2
| kind_equiv_kpi S1 S2 K1 K2 : |- S1 == S2 → |-K K1 == K2 → |-K kpi S1 K1 == kpi S2 K2
| kind_equiv_sym : Symmetric kind_equiv
| kind_equiv_trans : Transitive kind_equiv
where "|-K K1 == K2" := (kind_equiv K1 K2).
(* XXX add extra HK-gDOT rules? *)
Scheme type_equiv_mut_ind := Induction for type_equiv Sort Prop
with kind_equiv_mut_ind := Induction for kind_equiv Sort Prop.
Combined Scheme type_kind_eq_mut_ind from type_equiv_mut_ind, kind_equiv_mut_ind.
Existing Instances type_equiv kind_equiv.
#[local] Hint Constructors type_equiv kind_equiv : core.
#[local] Remove Hints type_equiv_sym type_equiv_trans
kind_equiv_sym kind_equiv_trans : core.
Lemma type_equiv_refl' T : |- T == T
with kind_equiv_refl' K : |-K K == K.
Proof. all: [> destruct T | destruct K]; constructor; auto. Qed.
#[global] Instance type_equiv_refl : Reflexive type_equiv := type_equiv_refl'.
#[global] Instance kind_equiv_refl : Reflexive kind_equiv := kind_equiv_refl'.
Existing Instances type_equiv_sym type_equiv_trans kind_equiv_sym kind_equiv_trans.
#[global] Instance : Equivalence type_equiv := {}.
#[global] Instance : RewriteRelation type_equiv := {}.
Lemma type_equiv_laterN_and j U1 U2 :
|- iterate TLater j (TAnd U1 U2)
== TAnd (iterate TLater j U1) (iterate TLater j U2).
Proof. elim: j U1 U2 ⇒ [//|j IHj] U1 U2; rewrite !iterate_S; eauto 3 using type_equiv_trans. Qed.
(* etrans; last apply type_equiv_later_and. by constructor. *)
Lemma type_equiv_laterN_or j U1 U2 :
|- iterate TLater j (TOr U1 U2)
== TOr (iterate TLater j U1) (iterate TLater j U2).
Proof. elim: j U1 U2 ⇒ [//|j IHj] U1 U2; rewrite !iterate_S; eauto 3 using type_equiv_trans. Qed.
Lemma type_equiv_laterN_mu j U1 :
|- iterate TLater j (TMu U1)
== TMu (iterate TLater j U1).
Proof. elim: j U1 ⇒ [//|j IHj] U1; rewrite !iterate_S; eauto 3 using type_equiv_trans. Qed.
Set Implicit Arguments.
Unset Strict Implicit.
Implicit Types (L T U : ty) (v : vl) (e : tm) (d : dm) (ds : dms) (Γ : ctx).
Reserved Notation "|- T1 == T2" (at level 70, T1 at level 69).
Reserved Notation "|-K K1 == K2" (at level 70, K1 at level 69).
Inductive type_equiv : Equiv ty :=
| type_equiv_later_and T1 T2 :
|- TLater (TAnd T1 T2) == TAnd (TLater T1) (TLater T2)
| type_equiv_later_or T1 T2 :
|- TLater (TOr T1 T2) == TOr (TLater T1) (TLater T2)
| type_equiv_later_mu T :
|- TLater (TMu T) == TMu (TLater T)
(* Congruence closure *)
| type_equiv_top : |- TTop == TTop
| type_equiv_bot : |- TBot == TBot
| type_equiv_and T1 U1 T2 U2 : |- T1 == T2 → |- U1 == U2 → |- TAnd T1 U1 == TAnd T2 U2
| type_equiv_or T1 U1 T2 U2 : |- T1 == T2 → |- U1 == U2 → |- TOr T1 U1 == TOr T2 U2
| type_equiv_later T1 T2 : |- T1 == T2 → |- TLater T1 == TLater T2
| type_equiv_all S1 T1 S2 T2 : |- S1 == S2 → |- T1 == T2 → |- TAll S1 T1 == TAll S2 T2
| type_equiv_mu T1 T2 : |- T1 == T2 → |- TMu T1 == TMu T2
| type_equiv_vmem l T1 T2 : |- T1 == T2 → |- TVMem l T1 == TVMem l T2
| type_equiv_ktmem l K1 K2 : |-K K1 == K2 → |- kTTMem l K1 == kTTMem l K2
| type_equiv_ksel n p l : |- kTSel n p l == kTSel n p l
| type_equiv_prim b : |- TPrim b == TPrim b
| type_equiv_sing p : |- TSing p == TSing p
| type_equiv_lam T1 T2 : |- T1 == T2 → |- TLam T1 == TLam T2
| type_equiv_app T1 T2 p : |- T1 == T2 → |- TApp T1 p == TApp T2 p
| type_equiv_sym : Symmetric type_equiv
| type_equiv_trans : Transitive type_equiv
where "|- T1 == T2" := (type_equiv T1 T2)
with kind_equiv : Equiv kind :=
| kind_equiv_kintv L1 L2 U1 U2 : |- L1 == L2 → |- U1 == U2 → |-K kintv L1 U1 == kintv L2 U2
| kind_equiv_kpi S1 S2 K1 K2 : |- S1 == S2 → |-K K1 == K2 → |-K kpi S1 K1 == kpi S2 K2
| kind_equiv_sym : Symmetric kind_equiv
| kind_equiv_trans : Transitive kind_equiv
where "|-K K1 == K2" := (kind_equiv K1 K2).
(* XXX add extra HK-gDOT rules? *)
Scheme type_equiv_mut_ind := Induction for type_equiv Sort Prop
with kind_equiv_mut_ind := Induction for kind_equiv Sort Prop.
Combined Scheme type_kind_eq_mut_ind from type_equiv_mut_ind, kind_equiv_mut_ind.
Existing Instances type_equiv kind_equiv.
#[local] Hint Constructors type_equiv kind_equiv : core.
#[local] Remove Hints type_equiv_sym type_equiv_trans
kind_equiv_sym kind_equiv_trans : core.
Lemma type_equiv_refl' T : |- T == T
with kind_equiv_refl' K : |-K K == K.
Proof. all: [> destruct T | destruct K]; constructor; auto. Qed.
#[global] Instance type_equiv_refl : Reflexive type_equiv := type_equiv_refl'.
#[global] Instance kind_equiv_refl : Reflexive kind_equiv := kind_equiv_refl'.
Existing Instances type_equiv_sym type_equiv_trans kind_equiv_sym kind_equiv_trans.
#[global] Instance : Equivalence type_equiv := {}.
#[global] Instance : RewriteRelation type_equiv := {}.
Lemma type_equiv_laterN_and j U1 U2 :
|- iterate TLater j (TAnd U1 U2)
== TAnd (iterate TLater j U1) (iterate TLater j U2).
Proof. elim: j U1 U2 ⇒ [//|j IHj] U1 U2; rewrite !iterate_S; eauto 3 using type_equiv_trans. Qed.
(* etrans; last apply type_equiv_later_and. by constructor. *)
Lemma type_equiv_laterN_or j U1 U2 :
|- iterate TLater j (TOr U1 U2)
== TOr (iterate TLater j U1) (iterate TLater j U2).
Proof. elim: j U1 U2 ⇒ [//|j IHj] U1 U2; rewrite !iterate_S; eauto 3 using type_equiv_trans. Qed.
Lemma type_equiv_laterN_mu j U1 :
|- iterate TLater j (TMu U1)
== TMu (iterate TLater j U1).
Proof. elim: j U1 ⇒ [//|j IHj] U1; rewrite !iterate_S; eauto 3 using type_equiv_trans. Qed.